mirror of
https://github.com/openharmony/miscservices_time.git
synced 2026-07-19 12:02:04 -04:00
!100 修改定时器和网络状态不好时时间时区同步问题
Merge pull request !100 from liulinna/master
This commit is contained in:
@@ -42,6 +42,7 @@ private:
|
||||
void SubscriberNITZTimeChangeCommonEvent();
|
||||
void StartTimer();
|
||||
void SetSystemTime();
|
||||
bool ThreadSetSystemTime();
|
||||
void RefreshNextTriggerTime();
|
||||
bool CheckStatus();
|
||||
bool IsNITZTimeInvalid();
|
||||
|
||||
@@ -17,21 +17,24 @@
|
||||
#define TIME_TICK_NOTIFY_H
|
||||
|
||||
#include <singleton.h>
|
||||
#include "timer.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
class TimeTickNotify : public DelayedSingleton<TimeTickNotify> {
|
||||
DECLARE_DELAYED_SINGLETON(TimeTickNotify);
|
||||
public:
|
||||
TimeTickNotify();
|
||||
~TimeTickNotify();
|
||||
DISALLOW_COPY_AND_MOVE(TimeTickNotify);
|
||||
void Init();
|
||||
void Callback(const uint64_t timerid);
|
||||
void Callback();
|
||||
void Stop();
|
||||
private:
|
||||
void StartTimer();
|
||||
void RefreshNextTriggerTime();
|
||||
uint64_t GetMillisecondsFromUTC(uint64_t UTCtimeNano);
|
||||
uint64_t timerId_;
|
||||
Utils::Timer timer_;
|
||||
uint32_t timerId_;
|
||||
uint64_t nextTriggerTime_;
|
||||
};
|
||||
} // MiscServices
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace OHOS {
|
||||
namespace MiscServices {
|
||||
namespace {
|
||||
constexpr int64_t INVALID_MILLIS = -1;
|
||||
constexpr int64_t HALF = 2;
|
||||
}
|
||||
|
||||
NtpTrustedTime::NtpTrustedTime() {}
|
||||
@@ -40,14 +41,25 @@ bool NtpTrustedTime::ForceRefresh(std::string ntpServer)
|
||||
if (mTimeResult != nullptr) {
|
||||
mTimeResult->Clear();
|
||||
}
|
||||
int64_t ntpCertainty = client.getRoundTripTime() / 2;
|
||||
int64_t ntpCertainty = client.getRoundTripTime() / HALF;
|
||||
mTimeResult = std::make_shared<TimeResult>(client.getNtpTIme(), client.getNtpTimeReference(), ntpCertainty);
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Get Ntp time result");
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "true end.");
|
||||
return true;
|
||||
} else {
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "false end.");
|
||||
return false;
|
||||
if (client.RequestTime(ntpServer)) {
|
||||
if (mTimeResult != nullptr) {
|
||||
mTimeResult->Clear();
|
||||
}
|
||||
int64_t ntpCertnR = client.getRoundTripTime() / HALF;
|
||||
mTimeResult = std::make_shared<TimeResult>(client.getNtpTIme(), client.getNtpTimeReference(), ntpCertnR);
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Re Get Ntp time result");
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Re true end.");
|
||||
return true;
|
||||
} else {
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "false end.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,13 +32,15 @@ using namespace std::chrono;
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
namespace {
|
||||
constexpr uint64_t NANO_TO_MILESECOND = 1000000;
|
||||
constexpr uint64_t NANO_TO_MILLISECOND = 1000000;
|
||||
constexpr uint64_t DAY_TO_MILLISECOND = 86400000;
|
||||
constexpr uint64_t MINUTES_TO_SECOND = 60;
|
||||
const std::string AUTOTIME_FILE_PATH = "/data/misc/zoneinfo/autotime.json";
|
||||
const std::string NETWORK_TIME_STATUS_ON = "ON";
|
||||
const std::string NETWORK_TIME_STATUS_OFF = "OFF";
|
||||
const std::string NTP_CN_SERVER = "1.cn.pool.ntp.org";
|
||||
const std::string NTP_CN_SERVER = "ntp.aliyun.com";
|
||||
const int64_t INVALID_TIMES = -1;
|
||||
const int MAX_RETRY = 10;
|
||||
}
|
||||
|
||||
NtpUpdateTime::NtpUpdateTime() {};
|
||||
@@ -62,13 +64,24 @@ void NtpUpdateTime::Init()
|
||||
}
|
||||
}
|
||||
if (autoTimeInfo_.status == NETWORK_TIME_STATUS_ON) {
|
||||
SetSystemTime();
|
||||
std::thread([this] {
|
||||
for (int i = 0; i < MAX_RETRY; i++) {
|
||||
if (!this->ThreadSetSystemTime()) {
|
||||
TIME_HILOGE(TIME_MODULE_SERVICE, "thread set ntp time failed, retry");
|
||||
std::this_thread::sleep_for(seconds(MINUTES_TO_SECOND));
|
||||
} else {
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "thread set ntp time success");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}).detach();
|
||||
}
|
||||
|
||||
int32_t timerType = ITimerManager::TimerType::ELAPSED_REALTIME;
|
||||
auto callback = [this](uint64_t id) {
|
||||
this->RefreshNetworkTimeByTimer(id);
|
||||
};
|
||||
timerId_ = TimeService::GetInstance()->CreateTimer(timerType, 0, 0, 0, callback);
|
||||
timerId_ = TimeService::GetInstance()->CreateTimer(timerType, 0, DAY_TO_MILLISECOND, 0, callback);
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Ntp update timerId: %{public}" PRId64 "", timerId_);
|
||||
RefreshNextTriggerTime();
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Ntp update triggertime: %{public}" PRId64 "", nextTriggerTime_);
|
||||
@@ -103,20 +116,13 @@ void NtpUpdateTime::RefreshNetworkTimeByTimer(const uint64_t timerId)
|
||||
}
|
||||
SetSystemTime();
|
||||
SaveAutoTimeInfoToFile(autoTimeInfo_);
|
||||
timerId_ = timerId;
|
||||
RefreshNextTriggerTime();
|
||||
auto startFunc = [this]() {
|
||||
this->StartTimer();
|
||||
};
|
||||
std::thread startTimerThread(startFunc);
|
||||
startTimerThread.detach();
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Ntp update triggertime: %{public}" PRId64 "", nextTriggerTime_);
|
||||
}
|
||||
|
||||
void NtpUpdateTime::UpdateNITZSetTime()
|
||||
{
|
||||
auto BootTimeNano = steady_clock::now().time_since_epoch().count();
|
||||
auto BootTimeMilli = BootTimeNano / NANO_TO_MILESECOND;
|
||||
auto BootTimeMilli = BootTimeNano / NANO_TO_MILLISECOND;
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "nitz time changed.");
|
||||
nitzUpdateTimeMili_ = BootTimeMilli;
|
||||
}
|
||||
@@ -147,12 +153,38 @@ void NtpUpdateTime::SetSystemTime()
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "end.");
|
||||
}
|
||||
|
||||
bool NtpUpdateTime::ThreadSetSystemTime()
|
||||
{
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "start.");
|
||||
if (!DelayedSingleton<NtpTrustedTime>::GetInstance()->ForceRefresh(autoTimeInfo_.NTP_SERVER)) {
|
||||
TIME_HILOGE(TIME_MODULE_SERVICE, "get ntp time failed.");
|
||||
return false;
|
||||
}
|
||||
int64_t currentTime = DelayedSingleton<NtpTrustedTime>::GetInstance()->CurrentTimeMillis();
|
||||
if (currentTime == INVALID_TIMES) {
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Ntp update time failed");
|
||||
return false;
|
||||
}
|
||||
if (currentTime <= 0) {
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "current time invalid.");
|
||||
return false;
|
||||
}
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Ntp UTC Time: %{public}" PRId64 "", currentTime);
|
||||
auto timeOffsetMs = DelayedSingleton<TimeZoneInfo>::GetInstance()->GetCurrentOffsetMs();
|
||||
currentTime = currentTime + timeOffsetMs;
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Ntp UTC+TIMEZONE tTime: %{public}" PRId64 "", currentTime);
|
||||
TimeService::GetInstance()->SetTime(currentTime);
|
||||
autoTimeInfo_.lastUpdateTime = currentTime;
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Ntp update currentTime: %{public}" PRId64 "", currentTime);
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "end.");
|
||||
return true;
|
||||
}
|
||||
|
||||
void NtpUpdateTime::RefreshNextTriggerTime()
|
||||
{
|
||||
auto BootTimeNano = steady_clock::now().time_since_epoch().count();
|
||||
auto BootTimeMilli = BootTimeNano / NANO_TO_MILESECOND;
|
||||
nextTriggerTime_ = BootTimeMilli + DAY_TO_MILLISECOND;
|
||||
return;
|
||||
auto BootTimeMilli = BootTimeNano / NANO_TO_MILLISECOND;
|
||||
nextTriggerTime_ = BootTimeMilli + DAY_TO_MILLISECOND;
|
||||
}
|
||||
|
||||
void NtpUpdateTime::UpdateStatusOff()
|
||||
@@ -190,7 +222,7 @@ bool NtpUpdateTime::CheckStatus()
|
||||
bool NtpUpdateTime::IsNITZTimeInvalid()
|
||||
{
|
||||
auto BootTimeNano = steady_clock::now().time_since_epoch().count();
|
||||
auto BootTimeMilli = BootTimeNano / NANO_TO_MILESECOND;
|
||||
auto BootTimeMilli = BootTimeNano / NANO_TO_MILLISECOND;
|
||||
return (BootTimeMilli - nitzUpdateTimeMili_) < DAY_TO_MILLISECOND;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,12 +44,12 @@ namespace {
|
||||
constexpr int INDEX_TWO = 2;
|
||||
constexpr int INDEX_THREE = 3;
|
||||
constexpr int INDEX_FOUR = 4;
|
||||
constexpr int TIME_OUT = 5;
|
||||
constexpr int TIME_OUT = 10;
|
||||
constexpr unsigned char MODE_THREE = 3;
|
||||
constexpr unsigned char VERSION_THREE = 3;
|
||||
constexpr double TEN_TO_MINUS_SIX_POWER = 1.0e-6;
|
||||
constexpr double TEN_TO_SIX_POWER = 1.0e6;
|
||||
constexpr int NTP_PORT = 123;
|
||||
char const *NTP_PORT = "123";
|
||||
constexpr int NTP_MSG_OFFSET_ROOT_DELAY = 4;
|
||||
constexpr int NTP_MSG_OFFSET_ROOT_DISPERSION = 8;
|
||||
constexpr int NTP_MSG_OFFSET_REFERENCE_IDENTIFIER = 12;
|
||||
@@ -68,44 +68,34 @@ bool SNTPClient::RequestTime(std::string host)
|
||||
{
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "start.");
|
||||
int iResult;
|
||||
struct sockaddr_in RecvAddr;
|
||||
unsigned short Port = NTP_PORT;
|
||||
int BufLen = NTP_PACKAGE_SIZE;
|
||||
|
||||
// Create a socket for sending data
|
||||
int SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (SendSocket == 0) {
|
||||
TIME_HILOGE(TIME_MODULE_SERVICE, "socket failed with error: %{public}d", 0);
|
||||
struct addrinfo hints = {0}, *addrs;
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_protocol = IPPROTO_UDP;
|
||||
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "RequestTime1.");
|
||||
int status = getaddrinfo(host.c_str(), NTP_PORT, &hints, &addrs);
|
||||
if (status != 0) {
|
||||
TIME_HILOGE(TIME_MODULE_SERVICE, "getaddrinfo failed");
|
||||
return false;
|
||||
}
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "RequestTime1.");
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "RequestTime2.");
|
||||
// Create a socket for sending data
|
||||
int SendSocket = socket(addrs->ai_family, addrs->ai_socktype, addrs->ai_protocol);
|
||||
if (SendSocket == 0) {
|
||||
TIME_HILOGE(TIME_MODULE_SERVICE, "create socket failed");
|
||||
return false;
|
||||
}
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "RequestTime3.");
|
||||
// Set send and recv function timeout
|
||||
struct timeval timeout = {TIME_OUT, 0};
|
||||
setsockopt(SendSocket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(struct timeval));
|
||||
setsockopt(SendSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));
|
||||
|
||||
struct hostent* hostV;
|
||||
if ((hostV = gethostbyname(host.c_str())) == nullptr) {
|
||||
// More descriptive error message
|
||||
TIME_HILOGE(TIME_MODULE_SERVICE, "Get host by name %{public}s but get nullptr.", host.c_str());
|
||||
return false;
|
||||
}
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "RequestTime2.");
|
||||
errno_t ret = memset_s((char*)& RecvAddr, sizeof(RecvAddr), 0, sizeof(RecvAddr));
|
||||
if (ret != EOK) {
|
||||
TIME_HILOGE(TIME_MODULE_SERVICE, "memcpy_s failed, err = %d\n", ret);
|
||||
return false;
|
||||
}
|
||||
RecvAddr.sin_family = AF_INET;
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "RequestTime3.");
|
||||
ret = memcpy_s((char*)& RecvAddr.sin_addr.s_addr, hostV->h_length, (char*)hostV->h_addr, hostV->h_length);
|
||||
if (ret != EOK) {
|
||||
TIME_HILOGE(TIME_MODULE_SERVICE, "memcpy_s failed, err = %d\n", ret);
|
||||
return false;
|
||||
}
|
||||
RecvAddr.sin_port = htons(Port);
|
||||
if (connect(SendSocket, (struct sockaddr*) & RecvAddr, sizeof(RecvAddr)) < 0) {
|
||||
TIME_HILOGE(TIME_MODULE_SERVICE, "Connect socket failed with host: %{public}s", host.c_str());
|
||||
if (connect(SendSocket, addrs->ai_addr, addrs->ai_addrlen) < 0) {
|
||||
TIME_HILOGE(TIME_MODULE_SERVICE, "socket connect failed");
|
||||
return false;
|
||||
}
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "RequestTime4.");
|
||||
@@ -355,7 +345,7 @@ unsigned int SNTPClient::GetNtpField32(int offset, char* buffer)
|
||||
errno_t retValue = memcpy_s(&milliseconds, sizeof(int), valueRx, sizeof(int));
|
||||
if (retValue != EOK) {
|
||||
TIME_HILOGE(TIME_MODULE_SERVICE, "memcpy_s failed, err = %d\n", retValue);
|
||||
return false; // 返回失败
|
||||
return false;
|
||||
}
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "end.");
|
||||
return milliseconds;
|
||||
|
||||
@@ -306,14 +306,6 @@ bool TimeService::DestroyTimer(uint64_t timerId)
|
||||
|
||||
int32_t TimeService::SetTime(const int64_t time)
|
||||
{
|
||||
pid_t uid = IPCSkeleton::GetCallingUid();
|
||||
if (uid != 0) {
|
||||
auto hasPerm = DelayedSingleton<TimePermission>::GetInstance()->CheckCallingPermission(uid, setTimePermName_);
|
||||
if (!hasPerm) {
|
||||
TIME_HILOGE(TIME_MODULE_SERVICE, "Permission check failed, uid : %{public}d", uid);
|
||||
return E_TIME_NO_PERMISSION;
|
||||
}
|
||||
}
|
||||
TIME_HILOGI(TIME_MODULE_SERVICE, "Setting time of day to milliseconds: %{public}" PRId64 "", time);
|
||||
if (time < 0 || time / 1000LL >= LONG_MAX) {
|
||||
TIME_HILOGE(TIME_MODULE_SERVICE, "input param error");
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
#include "time_service_notify.h"
|
||||
#include "timer_manager_interface.h"
|
||||
#include "time_service.h"
|
||||
#include "common_timer_errors.h"
|
||||
#include "time_tick_notify.h"
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
namespace OHOS {
|
||||
@@ -28,38 +30,41 @@ namespace MiscServices {
|
||||
namespace {
|
||||
constexpr uint64_t MINUTE_TO_MILLISECOND = 60000;
|
||||
constexpr uint64_t MICRO_TO_MILESECOND = 1000;
|
||||
constexpr uint64_t NANO_TO_MILESECOND = 1000000;
|
||||
}
|
||||
TimeTickNotify::TimeTickNotify() {};
|
||||
|
||||
TimeTickNotify::TimeTickNotify() : timer_("TickTimer") {};
|
||||
TimeTickNotify::~TimeTickNotify() {};
|
||||
|
||||
void TimeTickNotify::Init()
|
||||
{
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Tick notify start.");
|
||||
int32_t timerType = ITimerManager::TimerType::ELAPSED_REALTIME;
|
||||
auto callback = [this](uint64_t id) {
|
||||
this->Callback(id);
|
||||
|
||||
uint32_t ret = timer_.Setup();
|
||||
if (ret != Utils::TIMER_ERR_OK) {
|
||||
TIME_HILOGE(TIME_MODULE_SERVICE, "Timer Setup failed: %{public}d", ret);
|
||||
return;
|
||||
}
|
||||
auto callback = [this]() {
|
||||
this->Callback();
|
||||
};
|
||||
timerId_ = TimeService::GetInstance()->CreateTimer(timerType, 0, 0, 0, callback);
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Tick notify timerId: %{public}" PRId64 "", timerId_);
|
||||
RefreshNextTriggerTime();
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Tick notify triggertime: %{public}" PRId64 "", nextTriggerTime_);
|
||||
TimeService::GetInstance()->StartTimer(timerId_, nextTriggerTime_);
|
||||
timerId_ = timer_.Register(callback, nextTriggerTime_);
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Tick timer ID: %{public}d", timerId_);
|
||||
}
|
||||
|
||||
void TimeTickNotify::Callback(const uint64_t timerId)
|
||||
void TimeTickNotify::Callback()
|
||||
{
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Tick notify timerId: %{public}" PRId64 "", timerId);
|
||||
auto currentTime = steady_clock::now().time_since_epoch().count();
|
||||
DelayedSingleton<TimeServiceNotify>::GetInstance()->PublishTimeTickEvents(currentTime);
|
||||
timerId_ = timerId;
|
||||
timer_.Unregister(timerId_);
|
||||
RefreshNextTriggerTime();
|
||||
auto startFunc = [this]() {
|
||||
this->StartTimer();
|
||||
auto callback = [this]() {
|
||||
this->Callback();
|
||||
};
|
||||
std::thread startTimerThread(startFunc);
|
||||
startTimerThread.detach();
|
||||
timerId_ = timer_.Register(callback, nextTriggerTime_);
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Tick notify triggertime: %{public}" PRId64 "", nextTriggerTime_);
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Tick timer ID: %{public}d", timerId_);
|
||||
}
|
||||
|
||||
void TimeTickNotify::RefreshNextTriggerTime()
|
||||
@@ -69,22 +74,14 @@ void TimeTickNotify::RefreshNextTriggerTime()
|
||||
TIME_HILOGI(TIME_MODULE_SERVICE, "Time now: %{public}s", asctime(tblock));
|
||||
auto UTCTimeMicro = duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "Time Now Mirc: %{public}" PRId64 "", UTCTimeMicro);
|
||||
auto BootTimeNano = steady_clock::now().time_since_epoch().count();
|
||||
auto BootTimeMilli = BootTimeNano / NANO_TO_MILESECOND;
|
||||
auto timeMilliseconds = GetMillisecondsFromUTC(UTCTimeMicro);
|
||||
nextTriggerTime_ = BootTimeMilli + (MINUTE_TO_MILLISECOND - timeMilliseconds);
|
||||
return ;
|
||||
}
|
||||
|
||||
void TimeTickNotify::StartTimer()
|
||||
{
|
||||
TimeService::GetInstance()->StartTimer(timerId_, nextTriggerTime_);
|
||||
nextTriggerTime_ = MINUTE_TO_MILLISECOND - timeMilliseconds;
|
||||
}
|
||||
|
||||
void TimeTickNotify::Stop()
|
||||
{
|
||||
TIME_HILOGD(TIME_MODULE_SERVICE, "start.");
|
||||
TimeService::GetInstance()->DestroyTimer(timerId_);
|
||||
timer_.Shutdown();
|
||||
}
|
||||
|
||||
uint64_t TimeTickNotify::GetMillisecondsFromUTC(uint64_t UTCtimeMicro)
|
||||
|
||||
@@ -408,6 +408,7 @@ bool TimerManager::TriggerTimersLocked(std::vector<std::shared_ptr<TimerInfo>> &
|
||||
auto alarm = batch->Get(i);
|
||||
alarm->count = 1;
|
||||
triggerList.push_back(alarm);
|
||||
TIME_HILOGI(TIME_MODULE_SERVICE, "alarm uid= %{public}d", alarm->uid);
|
||||
if (alarm->repeatInterval > milliseconds::zero()) {
|
||||
alarm->count += duration_cast<milliseconds>(nowElapsed -
|
||||
alarm->expectedWhenElapsed) / alarm->repeatInterval;
|
||||
|
||||
Reference in New Issue
Block a user