diff --git a/services/time_manager/include/ntp_update_time.h b/services/time_manager/include/ntp_update_time.h index 6daa234..47f5aa7 100644 --- a/services/time_manager/include/ntp_update_time.h +++ b/services/time_manager/include/ntp_update_time.h @@ -42,6 +42,7 @@ private: void SubscriberNITZTimeChangeCommonEvent(); void StartTimer(); void SetSystemTime(); + bool ThreadSetSystemTime(); void RefreshNextTriggerTime(); bool CheckStatus(); bool IsNITZTimeInvalid(); diff --git a/services/time_manager/include/time_tick_notify.h b/services/time_manager/include/time_tick_notify.h index 105be8c..5ea05fe 100644 --- a/services/time_manager/include/time_tick_notify.h +++ b/services/time_manager/include/time_tick_notify.h @@ -17,21 +17,24 @@ #define TIME_TICK_NOTIFY_H #include +#include "timer.h" namespace OHOS { namespace MiscServices { class TimeTickNotify : public DelayedSingleton { - 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 diff --git a/services/time_manager/src/ntp_trusted_time.cpp b/services/time_manager/src/ntp_trusted_time.cpp index 3f2bca2..1b28605 100644 --- a/services/time_manager/src/ntp_trusted_time.cpp +++ b/services/time_manager/src/ntp_trusted_time.cpp @@ -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(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(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; + } } } diff --git a/services/time_manager/src/ntp_update_time.cpp b/services/time_manager/src/ntp_update_time.cpp index d561448..0fad895 100644 --- a/services/time_manager/src/ntp_update_time.cpp +++ b/services/time_manager/src/ntp_update_time.cpp @@ -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::GetInstance()->ForceRefresh(autoTimeInfo_.NTP_SERVER)) { + TIME_HILOGE(TIME_MODULE_SERVICE, "get ntp time failed."); + return false; + } + int64_t currentTime = DelayedSingleton::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::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; } diff --git a/services/time_manager/src/sntp_client.cpp b/services/time_manager/src/sntp_client.cpp index 249f83b..9d2ca85 100644 --- a/services/time_manager/src/sntp_client.cpp +++ b/services/time_manager/src/sntp_client.cpp @@ -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; diff --git a/services/time_manager/src/time_service.cpp b/services/time_manager/src/time_service.cpp index dc738c5..34c5cfc 100644 --- a/services/time_manager/src/time_service.cpp +++ b/services/time_manager/src/time_service.cpp @@ -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::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"); diff --git a/services/time_manager/src/time_tick_notify.cpp b/services/time_manager/src/time_tick_notify.cpp index 39843a0..bd949c4 100644 --- a/services/time_manager/src/time_tick_notify.cpp +++ b/services/time_manager/src/time_tick_notify.cpp @@ -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::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(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) diff --git a/services/timer/src/timer_manager.cpp b/services/timer/src/timer_manager.cpp index b7db6a9..7bcb98b 100644 --- a/services/timer/src/timer_manager.cpp +++ b/services/timer/src/timer_manager.cpp @@ -408,6 +408,7 @@ bool TimerManager::TriggerTimersLocked(std::vector> & 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(nowElapsed - alarm->expectedWhenElapsed) / alarm->repeatInterval;