!100 修改定时器和网络状态不好时时间时区同步问题

Merge pull request !100 from liulinna/master
This commit is contained in:
openharmony_ci
2022-03-21 03:21:23 +00:00
committed by Gitee
8 changed files with 115 additions and 87 deletions
@@ -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
+15 -3
View File
@@ -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;
}
}
}
+48 -16
View File
@@ -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;
}
+22 -32
View File
@@ -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");
+22 -25
View File
@@ -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)
+1
View File
@@ -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;