From 5f3a6fb0c7d8f617bb6837934837d49ba0899ebe Mon Sep 17 00:00:00 2001 From: li_junsong Date: Mon, 12 Aug 2024 14:08:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EJS=E6=8E=A5=E5=8F=A3getNtpTim?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: li_junsong --- framework/js/napi/common/include/napi_utils.h | 2 + framework/js/napi/common/src/napi_utils.cpp | 4 ++ .../include/napi_system_date_time.h | 2 + .../src/napi_system_date_time.cpp | 52 ++++++++++++++++++ .../inner_api/include/time_service_client.h | 10 ++++ .../include/time_service_interface.h | 10 ++++ .../inner_api/src/time_service_client.cpp | 12 +++++ .../base/time_service_ipc_interface_code.h | 1 + .../inner_api_include/time_service_proxy.h | 1 + services/ipc/proxy/time_service_proxy.cpp | 19 +++++++ services/ipc/stub/time_service_stub.cpp | 26 ++++++++- services/ipc/stub/time_service_stub.h | 1 + services/time/include/ntp_trusted_time.h | 3 ++ services/time/include/ntp_update_time.h | 4 +- services/time/src/ntp_trusted_time.cpp | 22 +++++++- services/time/src/ntp_update_time.cpp | 54 ++++++++++++------- services/time/src/sntp_client.cpp | 6 +-- services/time_blocklist.txt | 3 -- services/time_system_ability.cpp | 10 ++++ services/time_system_ability.h | 1 + services/timer/src/timer_manager.cpp | 3 -- .../permission/SystemDateTimeGet.test.js | 25 +++++++++ .../service_test/src/time_client_test.cpp | 14 +++-- .../service_test/src/time_service_test.cpp | 35 +++++++++++- utils/native/include/time_common.h | 1 + 25 files changed, 282 insertions(+), 39 deletions(-) delete mode 100644 services/time_blocklist.txt diff --git a/framework/js/napi/common/include/napi_utils.h b/framework/js/napi/common/include/napi_utils.h index 05461e15..244ddc3a 100644 --- a/framework/js/napi/common/include/napi_utils.h +++ b/framework/js/napi/common/include/napi_utils.h @@ -104,6 +104,8 @@ enum JsErrorCode : int32_t { PERMISSION_ERROR = 201, SYSTEM_APP_ERROR = 202, PARAMETER_ERROR = 401, + NTP_UPDATE_ERROR = 13000001, + NTP_NOT_UPDATE_ERROR = 13000002, }; struct CallbackPromiseInfo { diff --git a/framework/js/napi/common/src/napi_utils.cpp b/framework/js/napi/common/src/napi_utils.cpp index 5fff4139..a05f680c 100644 --- a/framework/js/napi/common/src/napi_utils.cpp +++ b/framework/js/napi/common/src/napi_utils.cpp @@ -34,6 +34,10 @@ int32_t NapiUtils::ConvertErrorCode(int32_t timeErrorCode) return JsErrorCode::PERMISSION_ERROR; case MiscServices::E_TIME_PARAMETERS_INVALID: return JsErrorCode::PARAMETER_ERROR; + case MiscServices::E_TIME_NTP_UPDATE_FAILED: + return JsErrorCode::NTP_UPDATE_ERROR; + case MiscServices::E_TIME_NTP_NOT_UPDATE: + return JsErrorCode::NTP_NOT_UPDATE_ERROR; default: return JsErrorCode::ERROR; } diff --git a/framework/js/napi/system_date_time/include/napi_system_date_time.h b/framework/js/napi/system_date_time/include/napi_system_date_time.h index cd86ae74..b89dd7de 100644 --- a/framework/js/napi/system_date_time/include/napi_system_date_time.h +++ b/framework/js/napi/system_date_time/include/napi_system_date_time.h @@ -43,6 +43,8 @@ private: static napi_value GetTime(napi_env env, napi_callback_info info); static napi_value GetUptime(napi_env env, napi_callback_info info); static napi_value GetTimezoneSync(napi_env env, napi_callback_info info); + static napi_value UpdateNtpTime(napi_env env, napi_callback_info info); + static napi_value GetNtpTime(napi_env env, napi_callback_info info); static int32_t GetTimezone(std::string &timezone); static int32_t GetDeviceTime(clockid_t clockId, bool isNano, int64_t &time); diff --git a/framework/js/napi/system_date_time/src/napi_system_date_time.cpp b/framework/js/napi/system_date_time/src/napi_system_date_time.cpp index c1bffe86..c3c3232d 100644 --- a/framework/js/napi/system_date_time/src/napi_system_date_time.cpp +++ b/framework/js/napi/system_date_time/src/napi_system_date_time.cpp @@ -51,6 +51,8 @@ napi_value NapiSystemDateTime::SystemDateTimeInit(napi_env env, napi_value expor DECLARE_NAPI_STATIC_FUNCTION("getRealActiveTime", GetRealActiveTime), DECLARE_NAPI_STATIC_FUNCTION("getRealTime", GetRealTime), DECLARE_NAPI_STATIC_FUNCTION("getTime", GetTime), + DECLARE_NAPI_STATIC_FUNCTION("updateNtpTime", UpdateNtpTime), + DECLARE_NAPI_STATIC_FUNCTION("getNtpTime", GetNtpTime), DECLARE_NAPI_STATIC_FUNCTION("setDate", SetDate), DECLARE_NAPI_STATIC_FUNCTION("getDate", GetDate), DECLARE_NAPI_STATIC_FUNCTION("setTimezone", SetTimezone), @@ -451,6 +453,56 @@ napi_value NapiSystemDateTime::GetTimezoneSync(napi_env env, napi_callback_info return NapiWork::SyncEnqueue(env, getTimezoneContext, "GetTimezone", executor, complete); } +napi_value NapiSystemDateTime::UpdateNtpTime(napi_env env, napi_callback_info info) +{ + struct UpdateNtpTime : public ContextBase { + int64_t time = 0; + }; + auto *updateNtpTimeContext = new UpdateNtpTime(); + auto inputParser = [env, updateNtpTimeContext](size_t argc, napi_value *argv) { + updateNtpTimeContext->status = napi_ok; + }; + updateNtpTimeContext->GetCbInfo(env, info, inputParser); + + auto executor = [updateNtpTimeContext]() { + int32_t innerCode = TimeServiceClient::GetInstance()->GetNtpTimeMs(updateNtpTimeContext->time); + if (innerCode != JsErrorCode::ERROR_OK) { + updateNtpTimeContext->errCode = innerCode; + updateNtpTimeContext->status = napi_generic_failure; + } + }; + auto complete = [env](napi_value &output) { + output = NapiUtils::GetUndefinedValue(env); + }; + return NapiWork::AsyncEnqueue(env, updateNtpTimeContext, "UpdateNtpTime", executor, complete); +} + +napi_value NapiSystemDateTime::GetNtpTime(napi_env env, napi_callback_info info) +{ + struct GetNtpTimeContext : public ContextBase { + int64_t time = 0; + }; + auto *getNtpTimeContext = new GetNtpTimeContext(); + auto inputParser = [env, getNtpTimeContext](size_t argc, napi_value *argv) { + getNtpTimeContext->status = napi_ok; + }; + getNtpTimeContext->GetCbInfo(env, info, inputParser); + + auto executor = [getNtpTimeContext]() { + int32_t innerCode = TimeServiceClient::GetInstance()->GetRealTimeMs(getNtpTimeContext->time); + if (innerCode != JsErrorCode::ERROR_OK) { + getNtpTimeContext->errCode = innerCode; + getNtpTimeContext->status = napi_generic_failure; + } + }; + auto complete = [getNtpTimeContext](napi_value &output) { + getNtpTimeContext->status = napi_create_int64(getNtpTimeContext->env, getNtpTimeContext->time, &output); + CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getNtpTimeContext, + "convert native object to javascript object failed", JsErrorCode::ERROR); + }; + return NapiWork::SyncEnqueue(env, getNtpTimeContext, "GetNtpTime", executor, complete); +} + int32_t NapiSystemDateTime::GetDeviceTime(clockid_t clockId, bool isNano, int64_t &time) { struct timespec tv {}; diff --git a/interfaces/inner_api/include/time_service_client.h b/interfaces/inner_api/include/time_service_client.h index 6191210a..80849bcf 100644 --- a/interfaces/inner_api/include/time_service_client.h +++ b/interfaces/inner_api/include/time_service_client.h @@ -411,6 +411,16 @@ public: * @return int32_t return error code. */ TIME_API int32_t GetNtpTimeMs(int64_t &time); + + /** + * @brief GetRealTimeMs + * + * Obtain the wall time based on the last ntp time. + * + * @param time the wall time(the UTC time from 1970 0H:0M:0S) in milliseconds. + * @return int32_t return error code. + */ + TIME_API int32_t GetRealTimeMs(int64_t &time); private: class TimeSaDeathRecipient : public IRemoteObject::DeathRecipient { public: diff --git a/interfaces/inner_api/include/time_service_interface.h b/interfaces/inner_api/include/time_service_interface.h index 2696155c..d0ff32ac 100644 --- a/interfaces/inner_api/include/time_service_interface.h +++ b/interfaces/inner_api/include/time_service_interface.h @@ -203,6 +203,16 @@ public: */ virtual int32_t GetNtpTimeMs(int64_t &time) = 0; + /** + * @brief GetRealTimeMs + * + * Obtain the wall time calculated based on the last NTP time. + * + * @param time the wall time(the UTC time from 1970 0H:0M:0S) in milliseconds. + * @return int32_t return error code. + */ + virtual int32_t GetRealTimeMs(int64_t &time) = 0; + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.time.ITimeService"); }; } // namespace MiscServices diff --git a/interfaces/inner_api/src/time_service_client.cpp b/interfaces/inner_api/src/time_service_client.cpp index 10d02d59..7cb6112b 100644 --- a/interfaces/inner_api/src/time_service_client.cpp +++ b/interfaces/inner_api/src/time_service_client.cpp @@ -778,6 +778,18 @@ int32_t TimeServiceClient::GetNtpTimeMs(int64_t &time) return proxy->GetNtpTimeMs(time); } +int32_t TimeServiceClient::GetRealTimeMs(int64_t &time) +{ + if (!ConnectService()) { + return E_TIME_SA_DIED; + } + auto proxy = GetProxy(); + if (proxy == nullptr) { + return E_TIME_NULLPTR; + } + return proxy->GetRealTimeMs(time); +} + sptr TimeServiceClient::GetProxy() { std::lock_guard autoLock(proxyLock_); diff --git a/services/ipc/base/time_service_ipc_interface_code.h b/services/ipc/base/time_service_ipc_interface_code.h index c30f6b04..51ad766f 100644 --- a/services/ipc/base/time_service_ipc_interface_code.h +++ b/services/ipc/base/time_service_ipc_interface_code.h @@ -41,6 +41,7 @@ enum class TimeServiceIpcInterfaceCode { ADJUST_TIMER, SET_TIMER_EXEMPTION, GET_NTP_TIME_MILLI, + GET_REAL_TIME_MILLI, }; } // namespace MiscServices } // namespace OHOS diff --git a/services/ipc/proxy/inner_api_include/time_service_proxy.h b/services/ipc/proxy/inner_api_include/time_service_proxy.h index 62035b43..ab4d233c 100644 --- a/services/ipc/proxy/inner_api_include/time_service_proxy.h +++ b/services/ipc/proxy/inner_api_include/time_service_proxy.h @@ -50,6 +50,7 @@ public: int32_t SetTimerExemption(const std::unordered_set &nameArr, bool isExemption) override; bool ResetAllProxy() override; int32_t GetNtpTimeMs(int64_t &time) override; + int32_t GetRealTimeMs(int64_t &time) override; private: static inline BrokerDelegator delegator_; diff --git a/services/ipc/proxy/time_service_proxy.cpp b/services/ipc/proxy/time_service_proxy.cpp index 18af7b5d..90f174e6 100644 --- a/services/ipc/proxy/time_service_proxy.cpp +++ b/services/ipc/proxy/time_service_proxy.cpp @@ -507,5 +507,24 @@ int32_t TimeServiceProxy::GetNtpTimeMs(int64_t &time) time = reply.ReadInt64(); return result; } + +int32_t TimeServiceProxy::GetRealTimeMs(int64_t &time) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor"); + return E_TIME_WRITE_PARCEL_ERROR; + } + int32_t result = Remote()->SendRequest( + static_cast(TimeServiceIpcInterfaceCode::GET_REAL_TIME_MILLI), data, reply, option); + if (result != ERR_NONE) { + TIME_HILOGE(TIME_MODULE_CLIENT, "GetRealTimeMs failed, error code is: %{public}d", result); + return result; + } + time = reply.ReadInt64(); + return result; +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/services/ipc/stub/time_service_stub.cpp b/services/ipc/stub/time_service_stub.cpp index f897b60c..495e0396 100644 --- a/services/ipc/stub/time_service_stub.cpp +++ b/services/ipc/stub/time_service_stub.cpp @@ -76,6 +76,8 @@ TimeServiceStub::TimeServiceStub() [this] (MessageParcel &data, MessageParcel &reply) -> int32_t { return OnAllProxyReset(data, reply); } }, { TimeServiceIpcInterfaceCode::GET_NTP_TIME_MILLI, [this] (MessageParcel &data, MessageParcel &reply) -> int32_t { return OnGetNtpTimeMs(data, reply); } }, + { TimeServiceIpcInterfaceCode::GET_REAL_TIME_MILLI, + [this] (MessageParcel &data, MessageParcel &reply) -> int32_t { return OnGetRealTimeMs(data, reply); } }, }; } @@ -99,7 +101,7 @@ int32_t TimeServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, Mes TIME_HILOGD(TIME_MODULE_SERVICE, "CallingPid = %{public}d, CallingUid = %{public}d, code = %{public}u", p, p1, code); if (code >= static_cast(TimeServiceIpcInterfaceCode::SET_TIME) && - code <= static_cast(TimeServiceIpcInterfaceCode::GET_NTP_TIME_MILLI)) { + code <= static_cast(TimeServiceIpcInterfaceCode::GET_REAL_TIME_MILLI)) { auto itFunc = memberFuncMap_.find(static_cast(code)); if (itFunc != memberFuncMap_.end()) { auto memberFunc = itFunc->second; @@ -496,7 +498,27 @@ int32_t TimeServiceStub::OnGetNtpTimeMs(MessageParcel &data, MessageParcel &repl return ret; } if (!reply.WriteUint64(time)) { - TIME_HILOGE(TIME_MODULE_SERVICE, "Failed to write timerId"); + TIME_HILOGE(TIME_MODULE_SERVICE, "Failed to write NTP time"); + return E_TIME_WRITE_PARCEL_ERROR; + } + TIME_HILOGD(TIME_MODULE_SERVICE, "end."); + return ERR_OK; +} + +int32_t TimeServiceStub::OnGetRealTimeMs(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "start."); + if (!TimePermission::CheckSystemUidCallingPermission(IPCSkeleton::GetCallingFullTokenID())) { + TIME_HILOGE(TIME_MODULE_SERVICE, "not system applications"); + return E_TIME_NOT_SYSTEM_APP; + } + int64_t time = 0; + auto ret = GetRealTimeMs(time); + if (ret != E_TIME_OK) { + return ret; + } + if (!reply.WriteUint64(time)) { + TIME_HILOGE(TIME_MODULE_SERVICE, "Failed to write NTP time"); return E_TIME_WRITE_PARCEL_ERROR; } TIME_HILOGD(TIME_MODULE_SERVICE, "end."); diff --git a/services/ipc/stub/time_service_stub.h b/services/ipc/stub/time_service_stub.h index a98992cf..887e7bb6 100644 --- a/services/ipc/stub/time_service_stub.h +++ b/services/ipc/stub/time_service_stub.h @@ -59,6 +59,7 @@ private: int32_t OnSetTimerExemption(MessageParcel &data, MessageParcel &reply); int32_t OnAllProxyReset(MessageParcel &data, MessageParcel &reply); int32_t OnGetNtpTimeMs(MessageParcel &data, MessageParcel &reply); + int32_t OnGetRealTimeMs(MessageParcel &data, MessageParcel &reply); std::map memberFuncMap_; }; } // namespace MiscServices diff --git a/services/time/include/ntp_trusted_time.h b/services/time/include/ntp_trusted_time.h index b6452ee0..521ce626 100644 --- a/services/time/include/ntp_trusted_time.h +++ b/services/time/include/ntp_trusted_time.h @@ -35,6 +35,7 @@ public: int64_t GetCacheAge(); int64_t CurrentTimeMillis(); int64_t ElapsedRealtimeMillis(); + std::chrono::steady_clock::time_point GetBootTimeNs(); class TimeResult : std::enable_shared_from_this { public: TimeResult(); @@ -47,7 +48,9 @@ public: void Clear(); private: + // Calculated network time from NTP server. int64_t mTimeMillis; + // Boot time when getting time from NTP server. int64_t mElapsedRealtimeMillis; int64_t mCertaintyMillis; }; diff --git a/services/time/include/ntp_update_time.h b/services/time/include/ntp_update_time.h index 3db46708..cf4aa221 100644 --- a/services/time/include/ntp_update_time.h +++ b/services/time/include/ntp_update_time.h @@ -33,6 +33,7 @@ class NtpUpdateTime { public: static NtpUpdateTime &GetInstance(); static bool GetNtpTime(int64_t &time); + static bool GetRealTime(int64_t &time); static void SetSystemTime(); void RefreshNetworkTimeByTimer(uint64_t timerId); void UpdateNITZSetTime(); @@ -44,7 +45,8 @@ public: private: NtpUpdateTime(); - static bool GetNtpTimeInner(); + static bool GetNtpTimeInner(uint64_t interval); + static bool GetRealTimeInner(int64_t &time); static void ChangeNtpServerCallback(const char *key, const char *value, void *context); static std::vector SplitNtpAddrs(const std::string &ntpStr); void StartTimer(); diff --git a/services/time/src/ntp_trusted_time.cpp b/services/time/src/ntp_trusted_time.cpp index f7b42137..f109da1d 100644 --- a/services/time/src/ntp_trusted_time.cpp +++ b/services/time/src/ntp_trusted_time.cpp @@ -31,6 +31,7 @@ namespace { constexpr int64_t TIME_RESULT_UNINITED = -1; constexpr int64_t HALF = 2; constexpr int32_t RETRY_TIMES = 2; +const int NANO_TO_SECOND = 1000000000; } // namespace NtpTrustedTime &NtpTrustedTime::GetInstance() @@ -92,6 +93,19 @@ int64_t NtpTrustedTime::GetCacheAge() } } +std::chrono::steady_clock::time_point NtpTrustedTime::GetBootTimeNs() +{ + int64_t timeNow = -1; + struct timespec tv {}; + if (clock_gettime(CLOCK_BOOTTIME, &tv) < 0) { + return std::chrono::steady_clock::now(); + } + timeNow = tv.tv_sec * NANO_TO_SECOND + tv.tv_nsec; + std::chrono::steady_clock::time_point tp_epoch ((std::chrono::nanoseconds(timeNow))); + return tp_epoch; +} + + int64_t NtpTrustedTime::TimeResult::GetTimeMillis() { return mTimeMillis; @@ -104,13 +118,17 @@ int64_t NtpTrustedTime::TimeResult::GetElapsedRealtimeMillis() int64_t NtpTrustedTime::TimeResult::CurrentTimeMillis() { + if (mTimeMillis == 0 || mElapsedRealtimeMillis == 0) { + TIME_HILOGD(TIME_MODULE_SERVICE, "Missing authoritative time source"); + return TIME_RESULT_UNINITED; + } return mTimeMillis + GetAgeMillis(); } int64_t NtpTrustedTime::TimeResult::GetAgeMillis() { - return std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()) - .count() - this->mElapsedRealtimeMillis; + return std::chrono::duration_cast( + NtpTrustedTime::GetInstance().GetBootTimeNs().time_since_epoch()).count() - this->mElapsedRealtimeMillis; } NtpTrustedTime::TimeResult::TimeResult() diff --git a/services/time/src/ntp_update_time.cpp b/services/time/src/ntp_update_time.cpp index 6bea2729..b7e0298a 100644 --- a/services/time/src/ntp_update_time.cpp +++ b/services/time/src/ntp_update_time.cpp @@ -45,7 +45,7 @@ const std::string AUTO_TIME_SYSTEM_PARAMETER = "persist.time.auto_time"; const std::string AUTO_TIME_STATUS_ON = "ON"; const std::string AUTO_TIME_STATUS_OFF = "OFF"; constexpr uint64_t TWO_SECONDS = 2000; -constexpr uint64_t ONE_MINUTES = 60000; +constexpr uint64_t ONE_HOUR = 3600000; constexpr int32_t RETRY_TIMES = 3; constexpr uint32_t RETRY_INTERVAL = 1; const std::string DEFAULT_NTP_SERVER = "1.cn.pool.ntp.org"; @@ -188,8 +188,21 @@ std::vector NtpUpdateTime::SplitNtpAddrs(const std::string &ntpStr) return ntpList; } -bool NtpUpdateTime::GetNtpTimeInner() +bool NtpUpdateTime::GetNtpTimeInner(uint64_t interval) { + // Determine the time interval between two NTP requests sent. + int64_t curBootTime = std::chrono::duration_cast( + NtpTrustedTime::GetInstance().GetBootTimeNs().time_since_epoch()).count(); + uint64_t bootTime = static_cast(curBootTime); + auto lastBootTime = NtpTrustedTime::GetInstance().ElapsedRealtimeMillis(); + // If the time interval is too small, do not send NTP requests. + if ((lastBootTime > 0) && (bootTime - static_cast(lastBootTime) <= interval)) { + TIME_HILOGI(TIME_MODULE_SERVICE, + "ntp updated within %{public}" PRId64 ", bootTime: %{public}" PRId64 ", lastBootTime: %{public}" PRId64 "", + interval, bootTime, lastBootTime); + return true; + } + bool ret = false; std::vector ntpSpecList = SplitNtpAddrs(autoTimeInfo_.ntpServerSpec); std::vector ntpList = SplitNtpAddrs(autoTimeInfo_.ntpServer); @@ -204,32 +217,35 @@ bool NtpUpdateTime::GetNtpTimeInner() return ret; } -bool NtpUpdateTime::GetNtpTime(int64_t &time) +bool NtpUpdateTime::GetRealTimeInner(int64_t &time) +{ + time = NtpTrustedTime::GetInstance().CurrentTimeMillis(); + if (time <= 0) { + TIME_HILOGE(TIME_MODULE_SERVICE, "current time is invalid: %{public}" PRId64 "", time); + return false; + } + return true; +} + +bool NtpUpdateTime::GetRealTime(int64_t &time) { std::lock_guard autoLock(requestMutex_); + return GetRealTimeInner(time); +} - int64_t curBootTime = std::chrono::duration_cast( - std::chrono::steady_clock::now().time_since_epoch()).count(); - uint64_t bootTime = static_cast(curBootTime); - auto lastBootTime = NtpTrustedTime::GetInstance().ElapsedRealtimeMillis(); - if ((lastBootTime > 0) && (bootTime - static_cast(lastBootTime) <= ONE_MINUTES)) { - TIME_HILOGI(TIME_MODULE_SERVICE, - "ntp updated in 1min, bootTime: %{public}" PRId64 ", lastBootTime: %{public}" PRId64 "", - bootTime, lastBootTime); - time = NtpTrustedTime::GetInstance().CurrentTimeMillis(); - return true; - } +bool NtpUpdateTime::GetNtpTime(int64_t &time) +{ + std::lock_guard autoLock(requestMutex_); - if (!GetNtpTimeInner()) { + if (!GetNtpTimeInner(ONE_HOUR)) { TIME_HILOGE(TIME_MODULE_SERVICE, "get ntp time failed."); return false; } - time = NtpTrustedTime::GetInstance().CurrentTimeMillis(); - if (time <= 0) { - TIME_HILOGE(TIME_MODULE_SERVICE, "current time is invalid: %{public}" PRId64 "", time); + if (!GetRealTimeInner(time)) { return false; } + if (autoTimeInfo_.status == AUTO_TIME_STATUS_ON) { TimeSystemAbility::GetInstance()->SetTime(time); } @@ -248,7 +264,7 @@ void NtpUpdateTime::SetSystemTime() return; } - if (!GetNtpTimeInner()) { + if (!GetNtpTimeInner(ONE_HOUR)) { TIME_HILOGE(TIME_MODULE_SERVICE, "get ntp time failed."); requestMutex_.unlock(); return; diff --git a/services/time/src/sntp_client.cpp b/services/time/src/sntp_client.cpp index 6aca053c..a13f2832 100644 --- a/services/time/src/sntp_client.cpp +++ b/services/time/src/sntp_client.cpp @@ -14,6 +14,7 @@ */ #include "sntp_client.h" +#include "ntp_trusted_time.h" #include #include @@ -261,9 +262,8 @@ void SNTPClient::ReceivedMessage(char *buffer) int64_t _roundTripDelay = (_receiveClient - _originClient) - (_transmitServer - _receiveServer); mRoundTripTime = _roundTripDelay; mNtpTime = ConvertNtpToStamp(_ntpTs) + _clockOffset; - mNtpTimeReference = - std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()) - .count(); + mNtpTimeReference = std::chrono::duration_cast( + NtpTrustedTime::GetInstance().GetBootTimeNs().time_since_epoch()).count(); SetClockOffset(_clockOffset); TIME_HILOGI(TIME_MODULE_SERVICE, "_originClient:%{public}s, _receiveServer:%{public}s, _transmitServer:%{public}s," "_receiveClient:%{public}s", std::to_string(_originClient).c_str(), diff --git a/services/time_blocklist.txt b/services/time_blocklist.txt deleted file mode 100644 index 427b4249..00000000 --- a/services/time_blocklist.txt +++ /dev/null @@ -1,3 +0,0 @@ -[integer] -src:*/services/dfx/src/time_cmd_dispatcher.cpp -src:*/services/dfx/src/time_cmd_parse.cpp \ No newline at end of file diff --git a/services/time_system_ability.cpp b/services/time_system_ability.cpp index bcdc3d82..460825de 100644 --- a/services/time_system_ability.cpp +++ b/services/time_system_ability.cpp @@ -895,6 +895,16 @@ int32_t TimeSystemAbility::GetNtpTimeMs(int64_t &time) return E_TIME_OK; } +int32_t TimeSystemAbility::GetRealTimeMs(int64_t &time) +{ + auto ret = NtpUpdateTime::GetInstance().GetRealTime(time); + if (!ret) { + TIME_HILOGE(TIME_MODULE_SERVICE, "GetRealTimeMs failed"); + return E_TIME_NTP_NOT_UPDATE; + } + return E_TIME_OK; +} + void TimeSystemAbility::RSSSaDeathRecipient::OnRemoteDied(const wptr &object) { auto timerManager = TimerManager::GetInstance(); diff --git a/services/time_system_ability.h b/services/time_system_ability.h index 5a17ce2c..11ecd976 100644 --- a/services/time_system_ability.h +++ b/services/time_system_ability.h @@ -74,6 +74,7 @@ public: int32_t SetTimerExemption(const std::unordered_set &nameArr, bool isExemption) override; bool ResetAllProxy() override; int32_t GetNtpTimeMs(int64_t &time) override; + int32_t GetRealTimeMs(int64_t &time) override; int Dump(int fd, const std::vector &args) override; void DumpAllTimeInfo(int fd, const std::vector &input); void DumpTimerInfo(int fd, const std::vector &input); diff --git a/services/timer/src/timer_manager.cpp b/services/timer/src/timer_manager.cpp index 92c000ea..d9635dcb 100644 --- a/services/timer/src/timer_manager.cpp +++ b/services/timer/src/timer_manager.cpp @@ -577,9 +577,6 @@ void TimerManager::TimerLooper() std::lock_guard lock(mutex_); RescheduleKernelTimerLocked(); } - } else { - std::lock_guard lock(mutex_); - RescheduleKernelTimerLocked(); } } } diff --git a/test/unittest/js_test/permission/SystemDateTimeGet.test.js b/test/unittest/js_test/permission/SystemDateTimeGet.test.js index 405b0205..daf9c92a 100644 --- a/test/unittest/js_test/permission/SystemDateTimeGet.test.js +++ b/test/unittest/js_test/permission/SystemDateTimeGet.test.js @@ -798,4 +798,29 @@ describe('SystemDateTimeGetTest', function () { done(); console.log('testGetTimezoneSync001 end'); }) + + /** + * @tc.number: TestUpdateAndGetNtpTime001 + * @tc.name: TestUpdateAndGetNtpTime001 + * @tc.desc: test getNtpTime. + * @tc.size: MediumTest + * @tc.type: Function + * @tc.level: Level 1 + * @tc.require: + */ + it('testUpdateAndGetNtpTime001', 0, async function (done) { + console.log("testUpdateAndGetNtpTime001 start"); + try { + systemDateTime.getNtpTime(); + } catch (err) { + expect(err.code).assertEqual(-1); + } + const nowTime = new Date().getTime(); + await systemDateTime.updateNtpTime(); + const milliTime = systemDateTime.getNtpTime(); + console.log('Get ntp time is ' + milliTime); + expect(typeof (milliTime) === 'number' && milliTime >= nowTime).assertTrue(); + console.log('testUpdateAndGetNtpTime001 end'); + done(); + }) }) \ No newline at end of file diff --git a/test/unittest/service_test/src/time_client_test.cpp b/test/unittest/service_test/src/time_client_test.cpp index e6794e48..3e6c79b4 100644 --- a/test/unittest/service_test/src/time_client_test.cpp +++ b/test/unittest/service_test/src/time_client_test.cpp @@ -156,8 +156,12 @@ void TimeClientTest::TearDown(void) void TestNtpThread(const char *name) { int64_t time; - auto errCode = TimeServiceClient::GetInstance()->GetNtpTimeMs(time); - EXPECT_EQ(errCode, TimeError::E_TIME_OK); + auto errCodeNtpTime = TimeServiceClient::GetInstance()->GetNtpTimeMs(time); + EXPECT_EQ(errCodeNtpTime, TimeError::E_TIME_OK); + int64_t time_later; + auto errCodeRealTime = TimeServiceClient::GetInstance()->GetRealTimeMs(time_later); + EXPECT_EQ(errCodeRealTime, TimeError::E_TIME_OK); + EXPECT_GT(time_later, time); } /** @@ -191,11 +195,11 @@ HWTEST_F(TimeClientTest, GetNtpTimeMs001, TestSize.Level1) } /** -* @tc.name: GetNtpTimeMs002 -* @tc.desc: get ntp time. +* @tc.name: GetNtpTimeMsAndGetRealTimeMs001 +* @tc.desc: get ntp time and get real time. * @tc.type: FUNC */ -HWTEST_F(TimeClientTest, GetNtpTimeMs002, TestSize.Level1) +HWTEST_F(TimeClientTest, GetNtpTimeMsAndGetRealTimeMs001, TestSize.Level1) { std::thread thread1(TestNtpThread, "thread1"); std::thread thread2(TestNtpThread, "thread2"); diff --git a/test/unittest/service_test/src/time_service_test.cpp b/test/unittest/service_test/src/time_service_test.cpp index 1595eb8a..799c94f3 100644 --- a/test/unittest/service_test/src/time_service_test.cpp +++ b/test/unittest/service_test/src/time_service_test.cpp @@ -31,6 +31,7 @@ #include "timer_call_back.h" #include "time_common.h" #include "power_subscriber.h" +#include "ntp_update_time.h" #define private public #define protected public @@ -54,6 +55,7 @@ const int32_t RESERVED_UID = 99999; std::set RESERVED_PIDLIST = {1111, 2222}; const std::string NETWORK_TIME_STATUS_OFF = "OFF"; const std::string NETWORK_TIME_STATUS_ON = "ON"; +const std::string AUTO_TIME_STATUS_ON = "ON"; uint64_t g_idleTimerId = 0; const uint64_t TIMER_ID = 88888; const int UID = 999998; @@ -198,6 +200,14 @@ void TimeServiceTest::DestroyIdleTimer() TimeServiceClient::GetInstance()->DestroyTimerV9(g_idleTimerId); } +void TestNtpThread(const char *name) +{ + { + std::lock_guard autoLock(NtpUpdateTime::requestMutex_); + } + NtpUpdateTime::SetSystemTime(); +} + /** * @tc.name: ProxyTimer001. * @tc.desc: proxy timer. @@ -934,7 +944,7 @@ HWTEST_F(TimeServiceTest, NtpTrustedTime001, TestSize.Level0) errCode = ntpTrustedTime->GetCacheAge(); EXPECT_EQ(errCode, INT_MAX); - ntpTrustedTime->mTimeResult = std::make_shared(0, 0, 0); + ntpTrustedTime->mTimeResult = std::make_shared(1, 1, 0); int64_t time = ntpTrustedTime->CurrentTimeMillis(); EXPECT_GT(time, 0); int64_t cacheAge = ntpTrustedTime->GetCacheAge(); @@ -985,6 +995,29 @@ HWTEST_F(TimeServiceTest, PowerSubscriber002, TestSize.Level0) EXPECT_NE(timerId, TimeTickNotify::GetInstance().timerId_); } +/** +* @tc.name: SetSystemTime001 +* @tc.desc: get ntp time. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, SetSystemTime001, TestSize.Level1) +{ + NtpUpdateTime::GetInstance().Init(); + std::string tmp = NtpUpdateTime::autoTimeInfo_.status; + NtpUpdateTime::autoTimeInfo_.status = AUTO_TIME_STATUS_ON; + + std::thread thread1(TestNtpThread, "thread1"); + std::thread thread2(TestNtpThread, "thread2"); + std::thread thread3(TestNtpThread, "thread3"); + std::thread thread4(TestNtpThread, "thread4"); + thread1.join(); + thread2.join(); + thread3.join(); + thread4.join(); + + NtpUpdateTime::autoTimeInfo_.status = tmp; +} + /** * @tc.name: Batch001. * @tc.desc: test Batch. diff --git a/utils/native/include/time_common.h b/utils/native/include/time_common.h index 3a334522..d7bbd02f 100644 --- a/utils/native/include/time_common.h +++ b/utils/native/include/time_common.h @@ -54,6 +54,7 @@ enum TimeError { E_TIME_NOT_SYSTEM_APP, E_TIME_NO_TIMER_ADJUST, E_TIME_NTP_UPDATE_FAILED, + E_TIME_NTP_NOT_UPDATE, }; enum DatabaseType { -- Gitee