• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "time_system_ability.h"
16 
17 #include <cerrno>
18 #include <chrono>
19 #include <climits>
20 #include <cstdio>
21 #include <cstring>
22 #include <ctime>
23 #include <dirent.h>
24 #include <fcntl.h>
25 #include <fstream>
26 #include <linux/rtc.h>
27 #include <mutex>
28 #include <singleton.h>
29 #include <sstream>
30 #include <string>
31 #include <sys/ioctl.h>
32 #include <sys/socket.h>
33 #include <sys/time.h>
34 #include <sys/types.h>
35 #include <unistd.h>
36 
37 #include "iservice_registry.h"
38 #include "ntp_update_time.h"
39 #include "pthread.h"
40 #include "system_ability.h"
41 #include "system_ability_definition.h"
42 #include "time_common.h"
43 #include "time_tick_notify.h"
44 #include "time_zone_info.h"
45 
46 using namespace std::chrono;
47 
48 namespace OHOS {
49 namespace MiscServices {
50 namespace {
51 // Unit of measure conversion , BASE: second
52 static const int MILLI_TO_BASE = 1000LL;
53 static const int MICR_TO_BASE = 1000000LL;
54 static const int NANO_TO_BASE = 1000000000LL;
55 static const std::int32_t INIT_INTERVAL = 10000L;
56 static const uint32_t TIMER_TYPE_REALTIME_MASK = 1 << 0;
57 static const uint32_t TIMER_TYPE_REALTIME_WAKEUP_MASK = 1 << 1;
58 static const uint32_t TIMER_TYPE_EXACT_MASK = 1 << 2;
59 constexpr int32_t MILLI_TO_MICR = MICR_TO_BASE / MILLI_TO_BASE;
60 constexpr int32_t NANO_TO_MILLI = NANO_TO_BASE / MILLI_TO_BASE;
61 constexpr int32_t ONE_MILLI = 1000;
62 }
63 
64 REGISTER_SYSTEM_ABILITY_BY_ID(TimeSystemAbility, TIME_SERVICE_ID, true);
65 
66 std::mutex TimeSystemAbility::instanceLock_;
67 sptr<TimeSystemAbility> TimeSystemAbility::instance_;
68 std::shared_ptr<AppExecFwk::EventHandler> TimeSystemAbility::serviceHandler_ = nullptr;
69 std::shared_ptr<TimerManager> TimeSystemAbility::timerManagerHandler_  = nullptr;
70 
TimeSystemAbility(int32_t systemAbilityId,bool runOnCreate)71 TimeSystemAbility::TimeSystemAbility(int32_t systemAbilityId, bool runOnCreate)
72     : SystemAbility(systemAbilityId, runOnCreate),
73       state_(ServiceRunningState::STATE_NOT_START),
74       rtcId(GetWallClockRtcId())
75 {
76     TIME_HILOGI(TIME_MODULE_SERVICE, " TimeService Start.");
77 }
78 
TimeSystemAbility()79 TimeSystemAbility::TimeSystemAbility()
80     :state_(ServiceRunningState::STATE_NOT_START), rtcId(GetWallClockRtcId())
81 {
82 }
83 
~TimeSystemAbility()84 TimeSystemAbility::~TimeSystemAbility() {};
85 
GetInstance()86 sptr<TimeSystemAbility> TimeSystemAbility::GetInstance()
87 {
88     if (instance_ == nullptr) {
89         std::lock_guard<std::mutex> autoLock(instanceLock_);
90         if (instance_ == nullptr) {
91             instance_ = new TimeSystemAbility;
92         }
93     }
94     return instance_;
95 }
96 
InitDumpCmd()97 void TimeSystemAbility::InitDumpCmd()
98 {
99     auto cmdTime = std::make_shared<TimeCmdParse>(std::vector<std::string>({ "-time" }),
100         "dump current time info,include localtime,timezone info",
101         [this](int fd, const std::vector<std::string> &input) { DumpAllTimeInfo(fd, input); });
102     TimeCmdDispatcher::GetInstance().RegisterCommand(cmdTime);
103 
104     auto cmdTimerAll = std::make_shared<TimeCmdParse>(std::vector<std::string>({ "-timer", "-a" }),
105         "dump all timer info", [this](int fd, const std::vector<std::string> &input) { DumpTimerInfo(fd, input); });
106     TimeCmdDispatcher::GetInstance().RegisterCommand(cmdTimerAll);
107 
108     auto cmdTimerInfo = std::make_shared<TimeCmdParse>(std::vector<std::string>({ "-timer", "-i", "[n]" }),
109         "dump the timer info with timer id",
110         [this](int fd, const std::vector<std::string> &input) { DumpTimerInfoById(fd, input); });
111     TimeCmdDispatcher::GetInstance().RegisterCommand(cmdTimerInfo);
112 
113     auto cmdTimerTrigger = std::make_shared<TimeCmdParse>(std::vector<std::string>({ "-timer", "-s", "[n]" }),
114         "dump current time info,include localtime,timezone info",
115         [this](int fd, const std::vector<std::string> &input) { DumpTimerTriggerById(fd, input); });
116     TimeCmdDispatcher::GetInstance().RegisterCommand(cmdTimerTrigger);
117 }
118 
OnStart()119 void TimeSystemAbility::OnStart()
120 {
121     TIME_HILOGI(TIME_MODULE_SERVICE, " TimeService OnStart.");
122     if (state_ == ServiceRunningState::STATE_RUNNING) {
123         TIME_HILOGE(TIME_MODULE_SERVICE, " TimeService is already running.");
124         return;
125     }
126 
127     InitServiceHandler();
128     InitTimerHandler();
129     DelayedSingleton<TimeTickNotify>::GetInstance()->Init();
130     DelayedSingleton<TimeZoneInfo>::GetInstance()->Init();
131     DelayedSingleton<NtpUpdateTime>::GetInstance()->Init();
132     AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
133     InitDumpCmd();
134     TIME_HILOGI(TIME_MODULE_SERVICE, "Start TimeService success.");
135     if (Init() != ERR_OK) {
136         auto callback = [this]() { Init(); };
137         serviceHandler_->PostTask(callback, INIT_INTERVAL);
138         TIME_HILOGE(TIME_MODULE_SERVICE, "Init failed. Try again 10s later.");
139         return;
140     }
141 }
142 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)143 void TimeSystemAbility::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
144 {
145     TIME_HILOGI(TIME_MODULE_SERVICE, "OnAddSystemAbility systemAbilityId:%{public}d added!", systemAbilityId);
146     if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
147         RegisterSubscriber();
148     } else {
149         TIME_HILOGE(TIME_MODULE_SERVICE, "OnAddSystemAbility systemAbilityId is not COMMON_EVENT_SERVICE_ID");
150         return;
151     }
152 }
153 
RegisterSubscriber()154 void TimeSystemAbility::RegisterSubscriber()
155 {
156     TIME_HILOGI(TIME_MODULE_SERVICE, "RegisterSubscriber Started");
157     bool subRes = DelayedSingleton<TimeServiceNotify>::GetInstance()->RepublishEvents();
158     if (!subRes) {
159         TIME_HILOGE(TIME_MODULE_SERVICE, "failed to RegisterSubscriber");
160         auto callback = [this]() { DelayedSingleton<TimeServiceNotify>::GetInstance()->RepublishEvents(); };
161         serviceHandler_->PostTask(callback, "time_service_subscriber_retry", INIT_INTERVAL);
162     } else {
163         TIME_HILOGI(TIME_MODULE_SERVICE, "RegisterSubscriber success.");
164     }
165 }
166 
Init()167 int32_t TimeSystemAbility::Init()
168 {
169     bool ret = Publish(TimeSystemAbility::GetInstance());
170     if (!ret) {
171         TIME_HILOGE(TIME_MODULE_SERVICE, "Init Failed.");
172         return E_TIME_PUBLISH_FAIL;
173     }
174     TIME_HILOGI(TIME_MODULE_SERVICE, "Init Success.");
175     state_ = ServiceRunningState::STATE_RUNNING;
176     return ERR_OK;
177 }
178 
OnStop()179 void TimeSystemAbility::OnStop()
180 {
181     TIME_HILOGI(TIME_MODULE_SERVICE, "OnStop Started.");
182     if (state_ != ServiceRunningState::STATE_RUNNING) {
183         return;
184     }
185     serviceHandler_ = nullptr;
186     DelayedSingleton<TimeTickNotify>::GetInstance()->Stop();
187     state_ = ServiceRunningState::STATE_NOT_START;
188     TIME_HILOGI(TIME_MODULE_SERVICE, "OnStop End.");
189 }
190 
InitServiceHandler()191 void TimeSystemAbility::InitServiceHandler()
192 {
193     TIME_HILOGI(TIME_MODULE_SERVICE, "InitServiceHandler started.");
194     if (serviceHandler_ != nullptr) {
195         TIME_HILOGE(TIME_MODULE_SERVICE, " Already init.");
196         return;
197     }
198     std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create(TIME_SERVICE_NAME);
199     serviceHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
200     TIME_HILOGI(TIME_MODULE_SERVICE, "InitServiceHandler Succeeded.");
201 }
202 
InitTimerHandler()203 void TimeSystemAbility::InitTimerHandler()
204 {
205     TIME_HILOGI(TIME_MODULE_SERVICE, "Init Timer started.");
206     if (timerManagerHandler_ != nullptr) {
207         TIME_HILOGE(TIME_MODULE_SERVICE, " Already init.");
208         return;
209     }
210     timerManagerHandler_ = TimerManager::Create();
211 }
212 
ParseTimerPara(std::shared_ptr<ITimerInfo> timerOptions,TimerPara & paras)213 void TimeSystemAbility::ParseTimerPara(std::shared_ptr<ITimerInfo> timerOptions, TimerPara &paras)
214 {
215     auto uIntType = static_cast<uint32_t>(timerOptions->type);
216     bool isRealtime = (uIntType & TIMER_TYPE_REALTIME_MASK) > 0 ? true : false;
217     bool isWakeup = (uIntType & TIMER_TYPE_REALTIME_WAKEUP_MASK) > 0 ? true : false;
218     paras.windowLength = (uIntType & TIMER_TYPE_EXACT_MASK) > 0 ? 0 : -1;
219     paras.flag = 0;
220     if (isRealtime && isWakeup) {
221         paras.timerType = ITimerManager::TimerType::ELAPSED_REALTIME_WAKEUP;
222     } else if (isRealtime) {
223         paras.timerType = ITimerManager::TimerType::ELAPSED_REALTIME;
224     } else if (isWakeup) {
225         paras.timerType = ITimerManager::TimerType::RTC_WAKEUP;
226     } else {
227         paras.timerType = ITimerManager::TimerType::RTC;
228     }
229     paras.interval = timerOptions->repeat ? timerOptions->interval : 0;
230     return;
231 }
232 
CreateTimer(const std::shared_ptr<ITimerInfo> & timerOptions,sptr<IRemoteObject> & obj,uint64_t & timerId)233 int32_t TimeSystemAbility::CreateTimer(const std::shared_ptr<ITimerInfo> &timerOptions, sptr<IRemoteObject> &obj,
234     uint64_t &timerId)
235 {
236     int uid = IPCSkeleton::GetCallingUid();
237     if (obj == nullptr) {
238         TIME_HILOGE(TIME_MODULE_SERVICE, "Input nullptr.");
239         return E_TIME_NULLPTR;
240     }
241     struct TimerPara paras {};
242     ParseTimerPara(timerOptions, paras);
243     sptr<ITimerCallback> timerCallback = iface_cast<ITimerCallback>(obj);
244     if (timerCallback == nullptr) {
245         TIME_HILOGE(TIME_MODULE_SERVICE, "ITimerCallback nullptr.");
246         return E_TIME_NULLPTR;
247     }
248     TIME_HILOGI(TIME_MODULE_SERVICE, "Start create timer.");
249     auto callbackFunc = [timerCallback](uint64_t id) {
250         timerCallback->NotifyTimer(id, nullptr);
251     };
252     int64_t triggerTime = 0;
253     GetWallTimeMs(triggerTime);
254     StatisticReporter(IPCSkeleton::GetCallingPid(), uid, timerOptions->type, triggerTime, timerOptions->interval);
255     if (timerManagerHandler_ == nullptr) {
256         TIME_HILOGE(TIME_MODULE_SERVICE, "Timer manager nullptr.");
257         timerManagerHandler_ = TimerManager::Create();
258         if (timerManagerHandler_ == nullptr) {
259             TIME_HILOGE(TIME_MODULE_SERVICE, "Redo Timer manager Init Failed.");
260             return E_TIME_NULLPTR;
261         }
262     }
263     return timerManagerHandler_->CreateTimer(paras, callbackFunc, timerOptions->wantAgent, uid, timerId);
264 }
265 
CreateTimer(TimerPara & paras,std::function<void (const uint64_t)> Callback,uint64_t & timerId)266 int32_t TimeSystemAbility::CreateTimer(
267     TimerPara &paras, std::function<void(const uint64_t)> Callback, uint64_t &timerId)
268 {
269     if (timerManagerHandler_ == nullptr) {
270         TIME_HILOGE(TIME_MODULE_SERVICE, "Timer manager nullptr.");
271         timerManagerHandler_ = TimerManager::Create();
272         if (timerManagerHandler_ == nullptr) {
273             TIME_HILOGE(TIME_MODULE_SERVICE, "Redo Timer manager Init Failed.");
274             return E_TIME_NULLPTR;
275         }
276     }
277     return timerManagerHandler_->CreateTimer(paras, Callback, nullptr, 0, timerId);
278 }
279 
StartTimer(uint64_t timerId,uint64_t triggerTimes)280 int32_t TimeSystemAbility::StartTimer(uint64_t timerId, uint64_t triggerTimes)
281 {
282     if (timerManagerHandler_ == nullptr) {
283         TIME_HILOGE(TIME_MODULE_SERVICE, "Timer manager nullptr.");
284         timerManagerHandler_ = TimerManager::Create();
285         if (timerManagerHandler_ == nullptr) {
286             TIME_HILOGE(TIME_MODULE_SERVICE, "Redo Timer manager Init Failed.");
287             return false;
288         }
289     }
290     auto ret = timerManagerHandler_->StartTimer(timerId, triggerTimes);
291     if (ret != E_TIME_OK) {
292         TIME_HILOGE(TIME_MODULE_SERVICE, "TimerId Not found.");
293     }
294     return ret;
295 }
296 
StopTimer(uint64_t timerId)297 int32_t TimeSystemAbility::StopTimer(uint64_t timerId)
298 {
299     if (timerManagerHandler_ == nullptr) {
300         TIME_HILOGE(TIME_MODULE_SERVICE, "Timer manager nullptr.");
301         timerManagerHandler_ = TimerManager::Create();
302         if (timerManagerHandler_ == nullptr) {
303             TIME_HILOGE(TIME_MODULE_SERVICE, "Redo Timer manager Init Failed.");
304             return false;
305         }
306     }
307     auto ret = timerManagerHandler_->StopTimer(timerId);
308     if (ret != E_TIME_OK) {
309         TIME_HILOGE(TIME_MODULE_SERVICE, "TimerId Not found.");
310     }
311     return ret;
312 }
313 
DestroyTimer(uint64_t timerId)314 int32_t TimeSystemAbility::DestroyTimer(uint64_t timerId)
315 {
316     if (timerManagerHandler_ == nullptr) {
317         TIME_HILOGE(TIME_MODULE_SERVICE, "Timer manager nullptr.");
318         timerManagerHandler_ = TimerManager::Create();
319         if (timerManagerHandler_ == nullptr) {
320             TIME_HILOGE(TIME_MODULE_SERVICE, "Redo Timer manager Init Failed.");
321             return false;
322         }
323     }
324     auto ret = timerManagerHandler_->DestroyTimer(timerId);
325     if (ret != E_TIME_OK) {
326         TIME_HILOGE(TIME_MODULE_SERVICE, "TimerId Not found.");
327     }
328     return ret;
329 }
330 
SetRealTime(int64_t time)331 bool TimeSystemAbility::SetRealTime(int64_t time)
332 {
333     TIME_HILOGI(TIME_MODULE_SERVICE, "Setting time of day to milliseconds: %{public}" PRId64 "", time);
334     if (time < 0 || time / 1000LL >= LLONG_MAX) {
335         TIME_HILOGE(TIME_MODULE_SERVICE, "input param error");
336         return false;
337     }
338     int64_t currentTime = 0;
339     if (GetWallTimeMs(currentTime) != ERR_OK) {
340         TIME_HILOGE(TIME_MODULE_SERVICE, "currentTime get failed");
341         return false;
342     }
343     struct timeval tv {};
344     tv.tv_sec = (time_t) (time / MILLI_TO_BASE);
345     tv.tv_usec = (suseconds_t)((time % MILLI_TO_BASE) * MILLI_TO_MICR);
346 
347     int result = settimeofday(&tv, NULL);
348     if (result < 0) {
349         TIME_HILOGE(TIME_MODULE_SERVICE, "settimeofday time fail: %{public}d.", result);
350         return false;
351     }
352     auto ret = SetRtcTime(tv.tv_sec);
353     if (ret == E_TIME_SET_RTC_FAILED) {
354         TIME_HILOGE(TIME_MODULE_SERVICE, "set rtc fail: %{public}d.", ret);
355         return false;
356     }
357     TIME_HILOGD(TIME_MODULE_SERVICE, "getting currentTime to milliseconds: %{public}" PRId64 "", currentTime);
358     if (currentTime < (time - ONE_MILLI) || currentTime > (time + ONE_MILLI)) {
359         DelayedSingleton<TimeServiceNotify>::GetInstance()->PublishTimeChangeEvents(currentTime);
360     }
361     return true;
362 }
363 
SetTime(int64_t time,APIVersion apiVersion)364 int32_t TimeSystemAbility::SetTime(int64_t time, APIVersion apiVersion)
365 {
366     if (!SetRealTime(time)) {
367         return E_TIME_DEAL_FAILED;
368     }
369     return ERR_OK;
370 }
371 
Dump(int fd,const std::vector<std::u16string> & args)372 int TimeSystemAbility::Dump(int fd, const std::vector<std::u16string> &args)
373 {
374     int uid = static_cast<int>(IPCSkeleton::GetCallingUid());
375     const int maxUid = 10000;
376     if (uid > maxUid) {
377         return E_TIME_DEAL_FAILED;
378     }
379 
380     std::vector<std::string> argsStr;
381     for (auto &item : args) {
382         argsStr.emplace_back(Str16ToStr8(item));
383     }
384 
385     TimeCmdDispatcher::GetInstance().Dispatch(fd, argsStr);
386     return ERR_OK;
387 }
388 
DumpAllTimeInfo(int fd,const std::vector<std::string> & input)389 void TimeSystemAbility::DumpAllTimeInfo(int fd, const std::vector<std::string> &input)
390 {
391     dprintf(fd, "\n - dump all time info :\n");
392     struct timespec ts;
393     struct tm timestr;
394     char date_time[64];
395     if (GetTimeByClockid(CLOCK_BOOTTIME, ts)) {
396         strftime(date_time, sizeof(date_time), "%Y-%m-%d %H:%M:%S", localtime_r(&ts.tv_sec, &timestr));
397         dprintf(fd, " * date time = %s\n", date_time);
398     } else {
399         dprintf(fd, " * dump date time error.\n");
400     }
401     dprintf(fd, " - dump the time Zone:\n");
402     std::string timeZone = "";
403     int32_t bRet = GetTimeZone(timeZone);
404     if (bRet == ERR_OK) {
405         dprintf(fd, " * time zone = %s\n", timeZone.c_str());
406     } else {
407         dprintf(fd, " * dump time zone error,is %s\n", timeZone.c_str());
408     }
409 }
410 
DumpTimerInfo(int fd,const std::vector<std::string> & input)411 void TimeSystemAbility::DumpTimerInfo(int fd, const std::vector<std::string> &input)
412 {
413     dprintf(fd, "\n - dump all timer info :\n");
414     if (timerManagerHandler_ == nullptr) {
415         TIME_HILOGE(TIME_MODULE_SERVICE, "Timer manager nullptr.");
416         timerManagerHandler_ = TimerManager::Create();
417         if (timerManagerHandler_ == nullptr) {
418             TIME_HILOGE(TIME_MODULE_SERVICE, "Redo Timer manager Init Failed.");
419             return;
420         }
421     }
422     timerManagerHandler_->ShowtimerEntryMap(fd);
423 }
424 
DumpTimerInfoById(int fd,const std::vector<std::string> & input)425 void TimeSystemAbility::DumpTimerInfoById(int fd, const std::vector<std::string> &input)
426 {
427     dprintf(fd, "\n - dump the timer info with timer id:\n");
428     if (timerManagerHandler_ == nullptr) {
429         TIME_HILOGE(TIME_MODULE_SERVICE, "Timer manager nullptr.");
430         timerManagerHandler_ = TimerManager::Create();
431         if (timerManagerHandler_ == nullptr) {
432             TIME_HILOGE(TIME_MODULE_SERVICE, "Redo Timer manager Init Failed.");
433             return;
434         }
435     }
436     int paramNumPos = 2;
437     timerManagerHandler_->ShowTimerEntryById(fd, std::atoi(input.at(paramNumPos).c_str()));
438 }
439 
DumpTimerTriggerById(int fd,const std::vector<std::string> & input)440 void TimeSystemAbility::DumpTimerTriggerById(int fd, const std::vector<std::string> &input)
441 {
442     dprintf(fd, "\n - dump timer trigger statics with timer id:\n");
443     if (timerManagerHandler_ == nullptr) {
444         TIME_HILOGE(TIME_MODULE_SERVICE, "Timer manager nullptr.");
445         timerManagerHandler_ = TimerManager::Create();
446         if (timerManagerHandler_ == nullptr) {
447             TIME_HILOGE(TIME_MODULE_SERVICE, "Redo Timer manager Init Failed.");
448             return;
449         }
450     }
451     int paramNumPos = 2;
452     timerManagerHandler_->ShowTimerTriggerById(fd, std::atoi(input.at(paramNumPos).c_str()));
453 }
454 
SetRtcTime(time_t sec)455 int TimeSystemAbility::SetRtcTime(time_t sec)
456 {
457     struct rtc_time rtc {};
458     struct tm tm {};
459     struct tm *gmtime_res = nullptr;
460     int fd = -1;
461     int res;
462     if (rtcId < 0) {
463         TIME_HILOGE(TIME_MODULE_SERVICE, "invalid rtc id: %{public}s:", strerror(ENODEV));
464         return E_TIME_SET_RTC_FAILED;
465     }
466     std::stringstream strs;
467     strs << "/dev/rtc" << rtcId;
468     auto rtcDev = strs.str();
469     TIME_HILOGI(TIME_MODULE_SERVICE, "rtc_dev : %{public}s:", rtcDev.data());
470     auto rtcData = rtcDev.data();
471     fd = open(rtcData, O_RDWR);
472     if (fd < 0) {
473         TIME_HILOGE(TIME_MODULE_SERVICE, "open failed %{public}s: %{public}s", rtcDev.data(), strerror(errno));
474         return E_TIME_SET_RTC_FAILED;
475     }
476 
477     gmtime_res = gmtime_r(&sec, &tm);
478     if (gmtime_res) {
479         rtc.tm_sec = tm.tm_sec;
480         rtc.tm_min = tm.tm_min;
481         rtc.tm_hour = tm.tm_hour;
482         rtc.tm_mday = tm.tm_mday;
483         rtc.tm_mon = tm.tm_mon;
484         rtc.tm_year = tm.tm_year;
485         rtc.tm_wday = tm.tm_wday;
486         rtc.tm_yday = tm.tm_yday;
487         rtc.tm_isdst = tm.tm_isdst;
488         res = ioctl(fd, RTC_SET_TIME, &rtc);
489         if (res < 0) {
490             TIME_HILOGE(TIME_MODULE_SERVICE, "ioctl RTC_SET_TIME failed: %{public}s", strerror(errno));
491         }
492     } else {
493         TIME_HILOGE(TIME_MODULE_SERVICE, "convert rtc time failed: %{public}s", strerror(errno));
494         res = E_TIME_SET_RTC_FAILED;
495     }
496     close(fd);
497     return res;
498 }
499 
CheckRtc(const std::string & rtcPath,uint64_t rtcId)500 bool TimeSystemAbility::CheckRtc(const std::string &rtcPath, uint64_t rtcId)
501 {
502     std::stringstream strs;
503     strs << rtcPath << "/rtc" << rtcId << "/hctosys";
504     auto hctosysPath = strs.str();
505 
506     std::fstream file(hctosysPath.data(), std::ios_base::in);
507     if (file.is_open()) {
508         return true;
509     } else {
510         TIME_HILOGE(TIME_MODULE_SERVICE, "failed to open %{public}s", hctosysPath.data());
511         return false;
512     }
513     return true;
514 }
515 
GetWallClockRtcId()516 int TimeSystemAbility::GetWallClockRtcId()
517 {
518     std::string rtcPath = "/sys/class/rtc";
519 
520     std::unique_ptr<DIR, int(*)(DIR*)> dir(opendir(rtcPath.c_str()), closedir);
521     if (!dir.get()) {
522         TIME_HILOGE(TIME_MODULE_SERVICE, "failed to open %{public}s: %{public}s", rtcPath.c_str(), strerror(errno));
523         return -1;
524     }
525 
526     struct dirent *dirent;
527     std::string s = "rtc";
528     while (errno = 0, dirent = readdir(dir.get())) {
529         std::string name(dirent->d_name);
530         unsigned long rtcId = 0;
531         auto index = name.find(s);
532         if (index == std::string::npos) {
533             continue;
534         } else {
535             auto rtcIdStr = name.substr(index + s.length());
536             rtcId = std::stoul(rtcIdStr);
537         }
538         if (CheckRtc(rtcPath, rtcId)) {
539             TIME_HILOGD(TIME_MODULE_SERVICE, "found wall clock rtc %{public}ld", rtcId);
540             return rtcId;
541         }
542     }
543 
544     if (errno == 0) {
545         TIME_HILOGE(TIME_MODULE_SERVICE, "no wall clock rtc found");
546     } else {
547         TIME_HILOGE(TIME_MODULE_SERVICE, "failed to check rtc: %{public}s", strerror(errno));
548     }
549     return -1;
550 }
551 
SetTimeZone(const std::string & timeZoneId,APIVersion apiVersion)552 int32_t TimeSystemAbility::SetTimeZone(const std::string &timeZoneId, APIVersion apiVersion)
553 {
554     if (!DelayedSingleton<TimeZoneInfo>::GetInstance()->SetTimezone(timeZoneId)) {
555         TIME_HILOGE(TIME_MODULE_SERVICE, "Set timezone failed :%{public}s", timeZoneId.c_str());
556         return E_TIME_DEAL_FAILED;
557     }
558     int64_t currentTime = 0;
559     GetBootTimeMs(currentTime);
560     DelayedSingleton<TimeServiceNotify>::GetInstance()->PublishTimeZoneChangeEvents(currentTime);
561     return ERR_OK;
562 }
563 
GetTimeZone(std::string & timeZoneId)564 int32_t TimeSystemAbility::GetTimeZone(std::string &timeZoneId)
565 {
566     if (!DelayedSingleton<TimeZoneInfo>::GetInstance()->GetTimezone(timeZoneId)) {
567         TIME_HILOGE(TIME_MODULE_SERVICE, "get timezone failed.");
568         return E_TIME_DEAL_FAILED;
569     }
570     TIME_HILOGD(TIME_MODULE_SERVICE, "Current timezone : %{public}s", timeZoneId.c_str());
571     return ERR_OK;
572 }
573 
GetWallTimeMs(int64_t & times)574 int32_t TimeSystemAbility::GetWallTimeMs(int64_t &times)
575 {
576     struct timespec tv {};
577     if (GetTimeByClockid(CLOCK_REALTIME, tv)) {
578         times = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI;
579         return ERR_OK;
580     }
581     return  E_TIME_DEAL_FAILED;
582 }
583 
GetWallTimeNs(int64_t & times)584 int32_t TimeSystemAbility::GetWallTimeNs(int64_t &times)
585 {
586     struct timespec tv {};
587     if (GetTimeByClockid(CLOCK_REALTIME, tv)) {
588         times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec;
589         return ERR_OK;
590     }
591     return  E_TIME_DEAL_FAILED;
592 }
593 
GetBootTimeMs(int64_t & times)594 int32_t TimeSystemAbility::GetBootTimeMs(int64_t &times)
595 {
596     struct timespec tv {};
597     if (GetTimeByClockid(CLOCK_BOOTTIME, tv)) {
598         times = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI;
599         return ERR_OK;
600     }
601     return  E_TIME_DEAL_FAILED;
602 }
603 
GetBootTimeNs(int64_t & times)604 int32_t TimeSystemAbility::GetBootTimeNs(int64_t &times)
605 {
606     struct timespec tv {};
607     if (GetTimeByClockid(CLOCK_BOOTTIME, tv)) {
608         times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec;
609         return ERR_OK;
610     }
611     return  E_TIME_DEAL_FAILED;
612 }
613 
GetMonotonicTimeMs(int64_t & times)614 int32_t TimeSystemAbility::GetMonotonicTimeMs(int64_t &times)
615 {
616     struct timespec tv {};
617     if (GetTimeByClockid(CLOCK_MONOTONIC, tv)) {
618         times = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI;
619         return ERR_OK;
620     }
621     return  E_TIME_DEAL_FAILED;
622 }
623 
GetMonotonicTimeNs(int64_t & times)624 int32_t TimeSystemAbility::GetMonotonicTimeNs(int64_t &times)
625 {
626     struct timespec tv {};
627     if (GetTimeByClockid(CLOCK_MONOTONIC, tv)) {
628         times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec;
629         return ERR_OK;
630     }
631     return  E_TIME_DEAL_FAILED;
632 }
633 
GetThreadTimeMs(int64_t & times)634 int32_t TimeSystemAbility::GetThreadTimeMs(int64_t &times)
635 {
636     struct timespec tv {};
637     int ret;
638     clockid_t cid;
639     ret = pthread_getcpuclockid(pthread_self(), &cid);
640     if (ret != 0) {
641         return E_TIME_PARAMETERS_INVALID;
642     }
643 
644     if (GetTimeByClockid(cid, tv)) {
645         times = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI;
646         return ERR_OK;
647     }
648     return  E_TIME_DEAL_FAILED;
649 }
650 
GetThreadTimeNs(int64_t & times)651 int32_t TimeSystemAbility::GetThreadTimeNs(int64_t &times)
652 {
653     struct timespec tv {};
654     int ret;
655     clockid_t cid;
656     ret = pthread_getcpuclockid(pthread_self(), &cid);
657     if (ret != 0) {
658         return E_TIME_PARAMETERS_INVALID;
659     }
660 
661     if (GetTimeByClockid(cid, tv)) {
662         times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec;
663         return ERR_OK;
664     }
665     return  E_TIME_DEAL_FAILED;
666 }
667 
GetTimeByClockid(clockid_t clockId,struct timespec & tv)668 bool TimeSystemAbility::GetTimeByClockid(clockid_t clockId, struct timespec &tv)
669 {
670     if (clock_gettime(clockId, &tv) < 0) {
671         TIME_HILOGE(TIME_MODULE_SERVICE, "Failed clock_gettime.");
672         return false;
673     }
674     return true;
675 }
676 
ProxyTimer(int32_t uid,bool isProxy,bool needRetrigger)677 bool TimeSystemAbility::ProxyTimer(int32_t uid, bool isProxy, bool needRetrigger)
678 {
679     if (!DelayedSingleton<TimePermission>::GetInstance()->CheckProxyCallingPermission()) {
680         TIME_HILOGE(TIME_MODULE_SERVICE, "ProxyTimer permission check failed");
681         return E_TIME_NO_PERMISSION;
682     }
683     TIME_HILOGD(TIME_MODULE_SERVICE, "ProxyTimer service start uid: %{public}d, isProxy: %{public}d",
684         uid, isProxy);
685     if (timerManagerHandler_ == nullptr) {
686         TIME_HILOGI(TIME_MODULE_SERVICE, "ProxyTimer manager nullptr.");
687         timerManagerHandler_ = TimerManager::Create();
688         if (timerManagerHandler_ == nullptr) {
689             TIME_HILOGE(TIME_MODULE_SERVICE, "Proxytimer manager init failed.");
690             return false;
691         }
692     }
693     return timerManagerHandler_->ProxyTimer(uid, isProxy, needRetrigger);
694 }
695 
ResetAllProxy()696 bool TimeSystemAbility::ResetAllProxy()
697 {
698     if (!DelayedSingleton<TimePermission>::GetInstance()->CheckProxyCallingPermission()) {
699         TIME_HILOGE(TIME_MODULE_SERVICE, "ResetAllProxy permission check failed");
700         return E_TIME_NO_PERMISSION;
701     }
702     TIME_HILOGD(TIME_MODULE_SERVICE, "ResetAllProxy service");
703     if (timerManagerHandler_ == nullptr) {
704         timerManagerHandler_ = TimerManager::Create();
705         if (timerManagerHandler_ == nullptr) {
706             TIME_HILOGE(TIME_MODULE_SERVICE, "ResetAllProxy timer manager init failed");
707             return false;
708         }
709     }
710     return timerManagerHandler_->ResetAllProxy();
711 }
712 } // namespace MiscServices
713 } // namespace OHOS