1cf69771bSopenharmony_ci/* 2cf69771bSopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd. 3cf69771bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4cf69771bSopenharmony_ci * you may not use this file except in compliance with the License. 5cf69771bSopenharmony_ci * You may obtain a copy of the License at 6cf69771bSopenharmony_ci * 7cf69771bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8cf69771bSopenharmony_ci * 9cf69771bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10cf69771bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11cf69771bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12cf69771bSopenharmony_ci * See the License for the specific language governing permissions and 13cf69771bSopenharmony_ci * limitations under the License. 14cf69771bSopenharmony_ci */ 15cf69771bSopenharmony_ci#include "time_system_ability.h" 16cf69771bSopenharmony_ci 17cf69771bSopenharmony_ci#include <chrono> 18cf69771bSopenharmony_ci#include <dirent.h> 19cf69771bSopenharmony_ci#include <fstream> 20cf69771bSopenharmony_ci#include <linux/rtc.h> 21cf69771bSopenharmony_ci#include <mutex> 22cf69771bSopenharmony_ci#include <sstream> 23cf69771bSopenharmony_ci#include <string> 24cf69771bSopenharmony_ci#include <sys/ioctl.h> 25cf69771bSopenharmony_ci#include <sys/time.h> 26cf69771bSopenharmony_ci#include <sys/timerfd.h> 27cf69771bSopenharmony_ci 28cf69771bSopenharmony_ci#include "iservice_registry.h" 29cf69771bSopenharmony_ci#include "ntp_update_time.h" 30cf69771bSopenharmony_ci#include "ntp_trusted_time.h" 31cf69771bSopenharmony_ci#include "pthread.h" 32cf69771bSopenharmony_ci#include "system_ability.h" 33cf69771bSopenharmony_ci#include "system_ability_definition.h" 34cf69771bSopenharmony_ci#include "time_common.h" 35cf69771bSopenharmony_ci#include "time_tick_notify.h" 36cf69771bSopenharmony_ci#include "time_zone_info.h" 37cf69771bSopenharmony_ci#include "timer_notify_callback.h" 38cf69771bSopenharmony_ci#include "timer_manager_interface.h" 39cf69771bSopenharmony_ci#include "timer_proxy.h" 40cf69771bSopenharmony_ci#include "timer_database.h" 41cf69771bSopenharmony_ci#include "time_file_utils.h" 42cf69771bSopenharmony_ci#include "common_event_manager.h" 43cf69771bSopenharmony_ci#include "common_event_support.h" 44cf69771bSopenharmony_ci#include "power_subscriber.h" 45cf69771bSopenharmony_ci#include "nitz_subscriber.h" 46cf69771bSopenharmony_ci#include "init_param.h" 47cf69771bSopenharmony_ci#include "parameters.h" 48cf69771bSopenharmony_ci#include "os_account.h" 49cf69771bSopenharmony_ci#include "os_account_manager.h" 50cf69771bSopenharmony_ci 51cf69771bSopenharmony_ciusing namespace std::chrono; 52cf69771bSopenharmony_ciusing namespace OHOS::EventFwk; 53cf69771bSopenharmony_ci 54cf69771bSopenharmony_cinamespace OHOS { 55cf69771bSopenharmony_cinamespace MiscServices { 56cf69771bSopenharmony_cinamespace { 57cf69771bSopenharmony_ci// Unit of measure conversion , BASE: second 58cf69771bSopenharmony_cistatic const int MILLI_TO_BASE = 1000LL; 59cf69771bSopenharmony_cistatic const int MICR_TO_BASE = 1000000LL; 60cf69771bSopenharmony_cistatic const int NANO_TO_BASE = 1000000000LL; 61cf69771bSopenharmony_cistatic const std::int32_t INIT_INTERVAL = 10L; 62cf69771bSopenharmony_cistatic const uint32_t TIMER_TYPE_REALTIME_MASK = 1 << 0; 63cf69771bSopenharmony_cistatic const uint32_t TIMER_TYPE_REALTIME_WAKEUP_MASK = 1 << 1; 64cf69771bSopenharmony_cistatic const uint32_t TIMER_TYPE_EXACT_MASK = 1 << 2; 65cf69771bSopenharmony_cistatic const uint32_t TIMER_TYPE_IDLE_MASK = 1 << 3; 66cf69771bSopenharmony_cistatic const uint32_t TIMER_TYPE_INEXACT_REMINDER_MASK = 1 << 4; 67cf69771bSopenharmony_ciconstexpr int32_t MILLI_TO_MICR = MICR_TO_BASE / MILLI_TO_BASE; 68cf69771bSopenharmony_ciconstexpr int32_t NANO_TO_MILLI = NANO_TO_BASE / MILLI_TO_BASE; 69cf69771bSopenharmony_ciconstexpr int32_t ONE_MILLI = 1000; 70cf69771bSopenharmony_ciconstexpr uint64_t TWO_MINUTES_TO_MILLI = 120000; 71cf69771bSopenharmony_cistatic const std::vector<std::string> ALL_DATA = { "timerId", "type", "flag", "windowLength", "interval", \ 72cf69771bSopenharmony_ci "uid", "bundleName", "wantAgent", "state", "triggerTime", \ 73cf69771bSopenharmony_ci "pid"}; 74cf69771bSopenharmony_ciconst std::string BOOTEVENT_PARAMETER = "bootevent.boot.completed"; 75cf69771bSopenharmony_ciconst std::string SUBSCRIBE_REMOVED = "UserRemoved"; 76cf69771bSopenharmony_ci} // namespace 77cf69771bSopenharmony_ci 78cf69771bSopenharmony_ciREGISTER_SYSTEM_ABILITY_BY_ID(TimeSystemAbility, TIME_SERVICE_ID, true); 79cf69771bSopenharmony_ci 80cf69771bSopenharmony_cistd::mutex TimeSystemAbility::instanceLock_; 81cf69771bSopenharmony_cisptr<TimeSystemAbility> TimeSystemAbility::instance_; 82cf69771bSopenharmony_ci 83cf69771bSopenharmony_ciclass UserRemovedSubscriber : public AccountSA::OsAccountSubscriber { 84cf69771bSopenharmony_cipublic: 85cf69771bSopenharmony_ci explicit UserRemovedSubscriber(const AccountSA::OsAccountSubscribeInfo &subscribeInfo) 86cf69771bSopenharmony_ci : AccountSA::OsAccountSubscriber(subscribeInfo) 87cf69771bSopenharmony_ci {} 88cf69771bSopenharmony_ci 89cf69771bSopenharmony_ci void OnAccountsChanged(const int &id) 90cf69771bSopenharmony_ci { 91cf69771bSopenharmony_ci TimerManager::GetInstance()->OnUserRemoved(id); 92cf69771bSopenharmony_ci } 93cf69771bSopenharmony_ci 94cf69771bSopenharmony_ci void OnAccountsSwitch(const int &newId, const int &oldId) {} 95cf69771bSopenharmony_ci}; 96cf69771bSopenharmony_ci 97cf69771bSopenharmony_ciTimeSystemAbility::TimeSystemAbility(int32_t systemAbilityId, bool runOnCreate) 98cf69771bSopenharmony_ci : SystemAbility(systemAbilityId, runOnCreate), state_(ServiceRunningState::STATE_NOT_START), 99cf69771bSopenharmony_ci rtcId(GetWallClockRtcId()) 100cf69771bSopenharmony_ci{ 101cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, " TimeSystemAbility Start."); 102cf69771bSopenharmony_ci} 103cf69771bSopenharmony_ci 104cf69771bSopenharmony_ciTimeSystemAbility::TimeSystemAbility() : state_(ServiceRunningState::STATE_NOT_START), rtcId(GetWallClockRtcId()) 105cf69771bSopenharmony_ci{ 106cf69771bSopenharmony_ci} 107cf69771bSopenharmony_ci 108cf69771bSopenharmony_ciTimeSystemAbility::~TimeSystemAbility(){}; 109cf69771bSopenharmony_ci 110cf69771bSopenharmony_cisptr<TimeSystemAbility> TimeSystemAbility::GetInstance() 111cf69771bSopenharmony_ci{ 112cf69771bSopenharmony_ci if (instance_ == nullptr) { 113cf69771bSopenharmony_ci std::lock_guard<std::mutex> autoLock(instanceLock_); 114cf69771bSopenharmony_ci if (instance_ == nullptr) { 115cf69771bSopenharmony_ci instance_ = new TimeSystemAbility; 116cf69771bSopenharmony_ci } 117cf69771bSopenharmony_ci } 118cf69771bSopenharmony_ci return instance_; 119cf69771bSopenharmony_ci} 120cf69771bSopenharmony_ci 121cf69771bSopenharmony_civoid TimeSystemAbility::InitDumpCmd() 122cf69771bSopenharmony_ci{ 123cf69771bSopenharmony_ci auto cmdTime = std::make_shared<TimeCmdParse>(std::vector<std::string>({ "-time" }), 124cf69771bSopenharmony_ci "dump current time info,include localtime,timezone info", 125cf69771bSopenharmony_ci [this](int fd, const std::vector<std::string> &input) { DumpAllTimeInfo(fd, input); }); 126cf69771bSopenharmony_ci TimeCmdDispatcher::GetInstance().RegisterCommand(cmdTime); 127cf69771bSopenharmony_ci 128cf69771bSopenharmony_ci auto cmdTimerAll = std::make_shared<TimeCmdParse>(std::vector<std::string>({ "-timer", "-a" }), 129cf69771bSopenharmony_ci "dump all timer info", [this](int fd, const std::vector<std::string> &input) { DumpTimerInfo(fd, input); }); 130cf69771bSopenharmony_ci TimeCmdDispatcher::GetInstance().RegisterCommand(cmdTimerAll); 131cf69771bSopenharmony_ci 132cf69771bSopenharmony_ci auto cmdTimerInfo = std::make_shared<TimeCmdParse>(std::vector<std::string>({ "-timer", "-i", "[n]" }), 133cf69771bSopenharmony_ci "dump the timer info with timer id", 134cf69771bSopenharmony_ci [this](int fd, const std::vector<std::string> &input) { DumpTimerInfoById(fd, input); }); 135cf69771bSopenharmony_ci TimeCmdDispatcher::GetInstance().RegisterCommand(cmdTimerInfo); 136cf69771bSopenharmony_ci 137cf69771bSopenharmony_ci auto cmdTimerTrigger = std::make_shared<TimeCmdParse>(std::vector<std::string>({ "-timer", "-s", "[n]" }), 138cf69771bSopenharmony_ci "dump current time info,include localtime,timezone info", 139cf69771bSopenharmony_ci [this](int fd, const std::vector<std::string> &input) { DumpTimerTriggerById(fd, input); }); 140cf69771bSopenharmony_ci TimeCmdDispatcher::GetInstance().RegisterCommand(cmdTimerTrigger); 141cf69771bSopenharmony_ci 142cf69771bSopenharmony_ci auto cmdTimerIdle = std::make_shared<TimeCmdParse>(std::vector<std::string>({ "-idle", "-a" }), 143cf69771bSopenharmony_ci "dump idle state and timer info, include pending delay timers and delayed info.", 144cf69771bSopenharmony_ci [this](int fd, const std::vector<std::string> &input) { DumpIdleTimerInfo(fd, input); }); 145cf69771bSopenharmony_ci TimeCmdDispatcher::GetInstance().RegisterCommand(cmdTimerIdle); 146cf69771bSopenharmony_ci 147cf69771bSopenharmony_ci auto cmdProxyTimer = std::make_shared<TimeCmdParse>(std::vector<std::string>({ "-ProxyTimer", "-l" }), 148cf69771bSopenharmony_ci "dump proxy timer info.", 149cf69771bSopenharmony_ci [this](int fd, const std::vector<std::string> &input) { DumpProxyTimerInfo(fd, input); }); 150cf69771bSopenharmony_ci TimeCmdDispatcher::GetInstance().RegisterCommand(cmdProxyTimer); 151cf69771bSopenharmony_ci 152cf69771bSopenharmony_ci auto cmdPidTimer = std::make_shared<TimeCmdParse>(std::vector<std::string>({ "-PidTimer", "-l" }), 153cf69771bSopenharmony_ci "dump pid timer map.", 154cf69771bSopenharmony_ci [this](int fd, const std::vector<std::string> &input) { DumpPidTimerMapInfo(fd, input); }); 155cf69771bSopenharmony_ci TimeCmdDispatcher::GetInstance().RegisterCommand(cmdPidTimer); 156cf69771bSopenharmony_ci 157cf69771bSopenharmony_ci auto cmdUidTimer = std::make_shared<TimeCmdParse>(std::vector<std::string>({ "-UidTimer", "-l" }), 158cf69771bSopenharmony_ci "dump uid timer map.", 159cf69771bSopenharmony_ci [this](int fd, const std::vector<std::string> &input) { DumpUidTimerMapInfo(fd, input); }); 160cf69771bSopenharmony_ci TimeCmdDispatcher::GetInstance().RegisterCommand(cmdUidTimer); 161cf69771bSopenharmony_ci 162cf69771bSopenharmony_ci auto cmdShowDelayTimer = std::make_shared<TimeCmdParse>(std::vector<std::string>({ "-ProxyDelayTime", "-l" }), 163cf69771bSopenharmony_ci "dump proxy delay time.", 164cf69771bSopenharmony_ci [this](int fd, const std::vector<std::string> &input) { DumpProxyDelayTime(fd, input); }); 165cf69771bSopenharmony_ci TimeCmdDispatcher::GetInstance().RegisterCommand(cmdShowDelayTimer); 166cf69771bSopenharmony_ci 167cf69771bSopenharmony_ci auto cmdAdjustTimer = std::make_shared<TimeCmdParse>(std::vector<std::string>({ "-adjust", "-a" }), 168cf69771bSopenharmony_ci "dump adjust time.", 169cf69771bSopenharmony_ci [this](int fd, const std::vector<std::string> &input) { DumpAdjustTime(fd, input); }); 170cf69771bSopenharmony_ci TimeCmdDispatcher::GetInstance().RegisterCommand(cmdAdjustTimer); 171cf69771bSopenharmony_ci} 172cf69771bSopenharmony_ci 173cf69771bSopenharmony_civoid TimeSystemAbility::OnStart() 174cf69771bSopenharmony_ci{ 175cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "TimeSystemAbility OnStart."); 176cf69771bSopenharmony_ci if (state_ == ServiceRunningState::STATE_RUNNING) { 177cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "TimeSystemAbility is already running."); 178cf69771bSopenharmony_ci return; 179cf69771bSopenharmony_ci } 180cf69771bSopenharmony_ci TimerManager::GetInstance(); 181cf69771bSopenharmony_ci TimeTickNotify::GetInstance().Init(); 182cf69771bSopenharmony_ci TimeZoneInfo::GetInstance().Init(); 183cf69771bSopenharmony_ci NtpUpdateTime::GetInstance().Init(); 184cf69771bSopenharmony_ci // This parameter is set to true by init only after all services have been started, 185cf69771bSopenharmony_ci // and is automatically set to false after shutdown. Otherwise it will not be modified. 186cf69771bSopenharmony_ci std::string bootCompleted = system::GetParameter(BOOTEVENT_PARAMETER, ""); 187cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "bootCompleted: %{public}s", bootCompleted.c_str()); 188cf69771bSopenharmony_ci if (bootCompleted != "true") { 189cf69771bSopenharmony_ci TimeDatabase::GetInstance().ClearDropOnReboot(); 190cf69771bSopenharmony_ci } 191cf69771bSopenharmony_ci AddSystemAbilityListener(ABILITY_MGR_SERVICE_ID); 192cf69771bSopenharmony_ci AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID); 193cf69771bSopenharmony_ci AddSystemAbilityListener(DEVICE_STANDBY_SERVICE_SYSTEM_ABILITY_ID); 194cf69771bSopenharmony_ci AddSystemAbilityListener(POWER_MANAGER_SERVICE_ID); 195cf69771bSopenharmony_ci AddSystemAbilityListener(COMM_NET_CONN_MANAGER_SYS_ABILITY_ID); 196cf69771bSopenharmony_ci AddSystemAbilityListener(SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN); 197cf69771bSopenharmony_ci InitDumpCmd(); 198cf69771bSopenharmony_ci if (Init() != ERR_OK) { 199cf69771bSopenharmony_ci auto callback = [this]() { 200cf69771bSopenharmony_ci sleep(INIT_INTERVAL); 201cf69771bSopenharmony_ci Init(); 202cf69771bSopenharmony_ci }; 203cf69771bSopenharmony_ci std::thread thread(callback); 204cf69771bSopenharmony_ci thread.detach(); 205cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "Init failed. Try again 10s later."); 206cf69771bSopenharmony_ci } 207cf69771bSopenharmony_ci} 208cf69771bSopenharmony_ci 209cf69771bSopenharmony_civoid TimeSystemAbility::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) 210cf69771bSopenharmony_ci{ 211cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "OnAddSystemAbility systemAbilityId:%{public}d added!", systemAbilityId); 212cf69771bSopenharmony_ci switch (systemAbilityId) { 213cf69771bSopenharmony_ci case COMMON_EVENT_SERVICE_ID: 214cf69771bSopenharmony_ci RegisterCommonEventSubscriber(); 215cf69771bSopenharmony_ci RemoveSystemAbilityListener(COMMON_EVENT_SERVICE_ID); 216cf69771bSopenharmony_ci break; 217cf69771bSopenharmony_ci case DEVICE_STANDBY_SERVICE_SYSTEM_ABILITY_ID: 218cf69771bSopenharmony_ci RegisterRSSDeathCallback(); 219cf69771bSopenharmony_ci break; 220cf69771bSopenharmony_ci case POWER_MANAGER_SERVICE_ID: 221cf69771bSopenharmony_ci RegisterPowerStateListener(); 222cf69771bSopenharmony_ci break; 223cf69771bSopenharmony_ci case COMM_NET_CONN_MANAGER_SYS_ABILITY_ID: 224cf69771bSopenharmony_ci NtpUpdateTime::GetInstance().MonitorNetwork(); 225cf69771bSopenharmony_ci break; 226cf69771bSopenharmony_ci case ABILITY_MGR_SERVICE_ID: 227cf69771bSopenharmony_ci RecoverTimer(); 228cf69771bSopenharmony_ci break; 229cf69771bSopenharmony_ci case SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN: 230cf69771bSopenharmony_ci RegisterOsAccountSubscriber(); 231cf69771bSopenharmony_ci break; 232cf69771bSopenharmony_ci default: 233cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "OnAddSystemAbility systemAbilityId is not valid, id is %{public}d", 234cf69771bSopenharmony_ci systemAbilityId); 235cf69771bSopenharmony_ci } 236cf69771bSopenharmony_ci} 237cf69771bSopenharmony_ci 238cf69771bSopenharmony_civoid TimeSystemAbility::RegisterScreenOnSubscriber() 239cf69771bSopenharmony_ci{ 240cf69771bSopenharmony_ci MatchingSkills matchingSkills; 241cf69771bSopenharmony_ci matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SCREEN_ON); 242cf69771bSopenharmony_ci CommonEventSubscribeInfo subscriberInfo(matchingSkills); 243cf69771bSopenharmony_ci std::shared_ptr<PowerSubscriber> subscriberPtr = std::make_shared<PowerSubscriber>(subscriberInfo); 244cf69771bSopenharmony_ci bool subscribeResult = CommonEventManager::SubscribeCommonEvent(subscriberPtr); 245cf69771bSopenharmony_ci if (!subscribeResult) { 246cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "Register COMMON_EVENT_SCREEN_ON failed"); 247cf69771bSopenharmony_ci } else { 248cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "Register COMMON_EVENT_SCREEN_ON success."); 249cf69771bSopenharmony_ci } 250cf69771bSopenharmony_ci} 251cf69771bSopenharmony_ci 252cf69771bSopenharmony_civoid TimeSystemAbility::RegisterNitzTimeSubscriber() 253cf69771bSopenharmony_ci{ 254cf69771bSopenharmony_ci MatchingSkills matchingNITZSkills; 255cf69771bSopenharmony_ci matchingNITZSkills.AddEvent(CommonEventSupport::COMMON_EVENT_NITZ_TIME_CHANGED); 256cf69771bSopenharmony_ci CommonEventSubscribeInfo subscriberNITZInfo(matchingNITZSkills); 257cf69771bSopenharmony_ci std::shared_ptr<NITZSubscriber> subscriberNITZPtr = std::make_shared<NITZSubscriber>(subscriberNITZInfo); 258cf69771bSopenharmony_ci bool subscribeNITZResult = CommonEventManager::SubscribeCommonEvent(subscriberNITZPtr); 259cf69771bSopenharmony_ci if (!subscribeNITZResult) { 260cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "Register COMMON_EVENT_NITZ_TIME_CHANGED failed"); 261cf69771bSopenharmony_ci } else { 262cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "Register COMMON_EVENT_NITZ_TIME_CHANGED success."); 263cf69771bSopenharmony_ci } 264cf69771bSopenharmony_ci} 265cf69771bSopenharmony_ci 266cf69771bSopenharmony_civoid TimeSystemAbility::RegisterCommonEventSubscriber() 267cf69771bSopenharmony_ci{ 268cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "RegisterCommonEventSubscriber Started"); 269cf69771bSopenharmony_ci bool subRes = TimeServiceNotify::GetInstance().RepublishEvents(); 270cf69771bSopenharmony_ci if (!subRes) { 271cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "failed to RegisterCommonEventSubscriber"); 272cf69771bSopenharmony_ci auto callback = [this]() { 273cf69771bSopenharmony_ci sleep(INIT_INTERVAL); 274cf69771bSopenharmony_ci TimeServiceNotify::GetInstance().RepublishEvents(); 275cf69771bSopenharmony_ci }; 276cf69771bSopenharmony_ci std::thread thread(callback); 277cf69771bSopenharmony_ci thread.detach(); 278cf69771bSopenharmony_ci } 279cf69771bSopenharmony_ci RegisterScreenOnSubscriber(); 280cf69771bSopenharmony_ci RegisterNitzTimeSubscriber(); 281cf69771bSopenharmony_ci} 282cf69771bSopenharmony_ci 283cf69771bSopenharmony_civoid TimeSystemAbility::RegisterOsAccountSubscriber() 284cf69771bSopenharmony_ci{ 285cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "RegisterOsAccountSubscriber Started"); 286cf69771bSopenharmony_ci AccountSA::OsAccountSubscribeInfo subscribeInfo(AccountSA::OS_ACCOUNT_SUBSCRIBE_TYPE::REMOVED, SUBSCRIBE_REMOVED); 287cf69771bSopenharmony_ci auto userChangedSubscriber = std::make_shared<UserRemovedSubscriber>(subscribeInfo); 288cf69771bSopenharmony_ci int err = AccountSA::OsAccountManager::SubscribeOsAccount(userChangedSubscriber); 289cf69771bSopenharmony_ci if (err != ERR_OK) { 290cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "Subscribe user removed event failed, errcode: %{public}d", err); 291cf69771bSopenharmony_ci } 292cf69771bSopenharmony_ci} 293cf69771bSopenharmony_ci 294cf69771bSopenharmony_ciint32_t TimeSystemAbility::Init() 295cf69771bSopenharmony_ci{ 296cf69771bSopenharmony_ci bool ret = Publish(TimeSystemAbility::GetInstance()); 297cf69771bSopenharmony_ci if (!ret) { 298cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "Init Failed."); 299cf69771bSopenharmony_ci return E_TIME_PUBLISH_FAIL; 300cf69771bSopenharmony_ci } 301cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "Init success."); 302cf69771bSopenharmony_ci state_ = ServiceRunningState::STATE_RUNNING; 303cf69771bSopenharmony_ci return ERR_OK; 304cf69771bSopenharmony_ci} 305cf69771bSopenharmony_ci 306cf69771bSopenharmony_civoid TimeSystemAbility::OnStop() 307cf69771bSopenharmony_ci{ 308cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "OnStop Started."); 309cf69771bSopenharmony_ci if (state_ != ServiceRunningState::STATE_RUNNING) { 310cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "state is running."); 311cf69771bSopenharmony_ci return; 312cf69771bSopenharmony_ci } 313cf69771bSopenharmony_ci TimeTickNotify::GetInstance().Stop(); 314cf69771bSopenharmony_ci state_ = ServiceRunningState::STATE_NOT_START; 315cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "OnStop End."); 316cf69771bSopenharmony_ci} 317cf69771bSopenharmony_ci 318cf69771bSopenharmony_civoid TimeSystemAbility::ParseTimerPara(const std::shared_ptr<ITimerInfo> &timerOptions, TimerPara ¶s) 319cf69771bSopenharmony_ci{ 320cf69771bSopenharmony_ci auto uIntType = static_cast<uint32_t>(timerOptions->type); 321cf69771bSopenharmony_ci auto disposable = timerOptions->disposable; 322cf69771bSopenharmony_ci bool isRealtime = (uIntType & TIMER_TYPE_REALTIME_MASK) > 0; 323cf69771bSopenharmony_ci bool isWakeup = (uIntType & TIMER_TYPE_REALTIME_WAKEUP_MASK) > 0; 324cf69771bSopenharmony_ci paras.windowLength = (uIntType & TIMER_TYPE_EXACT_MASK) > 0 ? 0 : -1; 325cf69771bSopenharmony_ci paras.flag = (uIntType & TIMER_TYPE_EXACT_MASK) > 0 ? 1 : 0; 326cf69771bSopenharmony_ci if (isRealtime && isWakeup) { 327cf69771bSopenharmony_ci paras.timerType = ITimerManager::TimerType::ELAPSED_REALTIME_WAKEUP; 328cf69771bSopenharmony_ci } else if (isRealtime) { 329cf69771bSopenharmony_ci paras.timerType = ITimerManager::TimerType::ELAPSED_REALTIME; 330cf69771bSopenharmony_ci } else if (isWakeup) { 331cf69771bSopenharmony_ci paras.timerType = ITimerManager::TimerType::RTC_WAKEUP; 332cf69771bSopenharmony_ci } else { 333cf69771bSopenharmony_ci paras.timerType = ITimerManager::TimerType::RTC; 334cf69771bSopenharmony_ci } 335cf69771bSopenharmony_ci if ((uIntType & TIMER_TYPE_IDLE_MASK) > 0) { 336cf69771bSopenharmony_ci paras.flag += ITimerManager::TimerFlag::IDLE_UNTIL; 337cf69771bSopenharmony_ci } 338cf69771bSopenharmony_ci if ((uIntType & TIMER_TYPE_INEXACT_REMINDER_MASK) > 0) { 339cf69771bSopenharmony_ci paras.flag += ITimerManager::TimerFlag::INEXACT_REMINDER; 340cf69771bSopenharmony_ci } 341cf69771bSopenharmony_ci if (disposable) { 342cf69771bSopenharmony_ci paras.flag += ITimerManager::TimerFlag::IS_DISPOSABLE; 343cf69771bSopenharmony_ci } 344cf69771bSopenharmony_ci paras.interval = timerOptions->repeat ? timerOptions->interval : 0; 345cf69771bSopenharmony_ci} 346cf69771bSopenharmony_ci 347cf69771bSopenharmony_ciint32_t TimeSystemAbility::CreateTimer(const std::shared_ptr<ITimerInfo> &timerOptions, sptr<IRemoteObject> &obj, 348cf69771bSopenharmony_ci uint64_t &timerId) 349cf69771bSopenharmony_ci{ 350cf69771bSopenharmony_ci if (obj == nullptr) { 351cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "Input nullptr."); 352cf69771bSopenharmony_ci return E_TIME_NULLPTR; 353cf69771bSopenharmony_ci } 354cf69771bSopenharmony_ci sptr<ITimerCallback> timerCallback = iface_cast<ITimerCallback>(obj); 355cf69771bSopenharmony_ci if (timerCallback == nullptr) { 356cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "ITimerCallback nullptr."); 357cf69771bSopenharmony_ci return E_TIME_NULLPTR; 358cf69771bSopenharmony_ci } 359cf69771bSopenharmony_ci struct TimerPara paras {}; 360cf69771bSopenharmony_ci ParseTimerPara(timerOptions, paras); 361cf69771bSopenharmony_ci auto timerManager = TimerManager::GetInstance(); 362cf69771bSopenharmony_ci if (timerManager == nullptr) { 363cf69771bSopenharmony_ci return E_TIME_NULLPTR; 364cf69771bSopenharmony_ci } 365cf69771bSopenharmony_ci auto callbackFunc = [timerCallback, timerOptions, timerManager](uint64_t id) -> int32_t { 366cf69771bSopenharmony_ci #ifdef POWER_MANAGER_ENABLE 367cf69771bSopenharmony_ci if (timerOptions->type == ITimerManager::TimerType::RTC_WAKEUP || 368cf69771bSopenharmony_ci timerOptions->type == ITimerManager::TimerType::ELAPSED_REALTIME_WAKEUP) { 369cf69771bSopenharmony_ci auto notifyCallback = TimerNotifyCallback::GetInstance(timerManager); 370cf69771bSopenharmony_ci return timerCallback->NotifyTimer(id, notifyCallback->AsObject()); 371cf69771bSopenharmony_ci } else { 372cf69771bSopenharmony_ci return timerCallback->NotifyTimer(id, nullptr); 373cf69771bSopenharmony_ci } 374cf69771bSopenharmony_ci #else 375cf69771bSopenharmony_ci return timerCallback->NotifyTimer(id, nullptr); 376cf69771bSopenharmony_ci #endif 377cf69771bSopenharmony_ci }; 378cf69771bSopenharmony_ci if ((static_cast<uint32_t>(paras.flag) & static_cast<uint32_t>(ITimerManager::TimerFlag::IDLE_UNTIL)) > 0 && 379cf69771bSopenharmony_ci !TimePermission::CheckProxyCallingPermission()) { 380cf69771bSopenharmony_ci TIME_HILOGW(TIME_MODULE_SERVICE, "App not support create idle timer."); 381cf69771bSopenharmony_ci paras.flag = 0; 382cf69771bSopenharmony_ci } 383cf69771bSopenharmony_ci auto type = DatabaseType::NOT_STORE; 384cf69771bSopenharmony_ci if (timerOptions->wantAgent != nullptr) { 385cf69771bSopenharmony_ci type = DatabaseType::STORE; 386cf69771bSopenharmony_ci } 387cf69771bSopenharmony_ci int uid = IPCSkeleton::GetCallingUid(); 388cf69771bSopenharmony_ci int pid = IPCSkeleton::GetCallingPid(); 389cf69771bSopenharmony_ci return timerManager->CreateTimer(paras, callbackFunc, timerOptions->wantAgent, 390cf69771bSopenharmony_ci uid, pid, timerId, type); 391cf69771bSopenharmony_ci} 392cf69771bSopenharmony_ci 393cf69771bSopenharmony_ciint32_t TimeSystemAbility::CreateTimer(TimerPara ¶s, std::function<int32_t (const uint64_t)> callback, 394cf69771bSopenharmony_ci uint64_t &timerId) 395cf69771bSopenharmony_ci{ 396cf69771bSopenharmony_ci auto timerManager = TimerManager::GetInstance(); 397cf69771bSopenharmony_ci if (timerManager == nullptr) { 398cf69771bSopenharmony_ci return E_TIME_NULLPTR; 399cf69771bSopenharmony_ci } 400cf69771bSopenharmony_ci return timerManager->CreateTimer(paras, std::move(callback), nullptr, 0, 0, timerId, NOT_STORE); 401cf69771bSopenharmony_ci} 402cf69771bSopenharmony_ci 403cf69771bSopenharmony_ciint32_t TimeSystemAbility::StartTimer(uint64_t timerId, uint64_t triggerTime) 404cf69771bSopenharmony_ci{ 405cf69771bSopenharmony_ci auto timerManager = TimerManager::GetInstance(); 406cf69771bSopenharmony_ci if (timerManager == nullptr) { 407cf69771bSopenharmony_ci return E_TIME_NULLPTR; 408cf69771bSopenharmony_ci } 409cf69771bSopenharmony_ci auto ret = timerManager->StartTimer(timerId, triggerTime); 410cf69771bSopenharmony_ci return ret; 411cf69771bSopenharmony_ci} 412cf69771bSopenharmony_ci 413cf69771bSopenharmony_ciint32_t TimeSystemAbility::StopTimer(uint64_t timerId) 414cf69771bSopenharmony_ci{ 415cf69771bSopenharmony_ci auto timerManager = TimerManager::GetInstance(); 416cf69771bSopenharmony_ci if (timerManager == nullptr) { 417cf69771bSopenharmony_ci return E_TIME_NULLPTR; 418cf69771bSopenharmony_ci } 419cf69771bSopenharmony_ci auto ret = timerManager->StopTimer(timerId); 420cf69771bSopenharmony_ci return ret; 421cf69771bSopenharmony_ci} 422cf69771bSopenharmony_ci 423cf69771bSopenharmony_ciint32_t TimeSystemAbility::DestroyTimer(uint64_t timerId, bool isAsync) 424cf69771bSopenharmony_ci{ 425cf69771bSopenharmony_ci auto timerManager = TimerManager::GetInstance(); 426cf69771bSopenharmony_ci if (timerManager == nullptr) { 427cf69771bSopenharmony_ci return E_TIME_NULLPTR; 428cf69771bSopenharmony_ci } 429cf69771bSopenharmony_ci auto ret = timerManager->DestroyTimer(timerId); 430cf69771bSopenharmony_ci return ret; 431cf69771bSopenharmony_ci} 432cf69771bSopenharmony_ci 433cf69771bSopenharmony_cibool TimeSystemAbility::IsValidTime(int64_t time) 434cf69771bSopenharmony_ci{ 435cf69771bSopenharmony_ci#if __SIZEOF_POINTER__ == 4 436cf69771bSopenharmony_ci if (time / MILLI_TO_BASE > LONG_MAX) { 437cf69771bSopenharmony_ci return false; 438cf69771bSopenharmony_ci } 439cf69771bSopenharmony_ci#endif 440cf69771bSopenharmony_ci return true; 441cf69771bSopenharmony_ci} 442cf69771bSopenharmony_ci 443cf69771bSopenharmony_cibool TimeSystemAbility::SetRealTime(int64_t time) 444cf69771bSopenharmony_ci{ 445cf69771bSopenharmony_ci if (!IsValidTime(time)) { 446cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "time is invalid: %{public}s", std::to_string(time).c_str()); 447cf69771bSopenharmony_ci return false; 448cf69771bSopenharmony_ci } 449cf69771bSopenharmony_ci sptr<TimeSystemAbility> instance = TimeSystemAbility::GetInstance(); 450cf69771bSopenharmony_ci int64_t beforeTime = 0; 451cf69771bSopenharmony_ci instance->GetWallTimeMs(beforeTime); 452cf69771bSopenharmony_ci int64_t bootTime = 0; 453cf69771bSopenharmony_ci instance->GetBootTimeMs(bootTime); 454cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, 455cf69771bSopenharmony_ci "Before Current Time: %{public}s" 456cf69771bSopenharmony_ci " Set time: %{public}s" 457cf69771bSopenharmony_ci " Difference: %{public}s" 458cf69771bSopenharmony_ci " uid:%{public}d pid:%{public}d ", 459cf69771bSopenharmony_ci std::to_string(beforeTime).c_str(), std::to_string(time).c_str(), std::to_string(time - bootTime).c_str(), 460cf69771bSopenharmony_ci IPCSkeleton::GetCallingUid(), IPCSkeleton::GetCallingPid()); 461cf69771bSopenharmony_ci if (time < 0) { 462cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "input param error %{public}" PRId64 "", time); 463cf69771bSopenharmony_ci return false; 464cf69771bSopenharmony_ci } 465cf69771bSopenharmony_ci int64_t currentTime = 0; 466cf69771bSopenharmony_ci if (GetWallTimeMs(currentTime) != ERR_OK) { 467cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "currentTime get failed"); 468cf69771bSopenharmony_ci return false; 469cf69771bSopenharmony_ci } 470cf69771bSopenharmony_ci struct timeval tv {}; 471cf69771bSopenharmony_ci tv.tv_sec = (time_t)(time / MILLI_TO_BASE); 472cf69771bSopenharmony_ci tv.tv_usec = (suseconds_t)((time % MILLI_TO_BASE) * MILLI_TO_MICR); 473cf69771bSopenharmony_ci int result = settimeofday(&tv, nullptr); 474cf69771bSopenharmony_ci if (result < 0) { 475cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "settimeofday time fail: %{public}d. error: %{public}s", result, 476cf69771bSopenharmony_ci strerror(errno)); 477cf69771bSopenharmony_ci return false; 478cf69771bSopenharmony_ci } 479cf69771bSopenharmony_ci auto ret = SetRtcTime(tv.tv_sec); 480cf69771bSopenharmony_ci if (ret == E_TIME_SET_RTC_FAILED) { 481cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "set rtc fail: %{public}d.", ret); 482cf69771bSopenharmony_ci return false; 483cf69771bSopenharmony_ci } 484cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "getting currentTime to milliseconds: %{public}" PRId64 "", currentTime); 485cf69771bSopenharmony_ci if (currentTime < (time - ONE_MILLI) || currentTime > (time + ONE_MILLI)) { 486cf69771bSopenharmony_ci TimeServiceNotify::GetInstance().PublishTimeChangeEvents(currentTime); 487cf69771bSopenharmony_ci } 488cf69771bSopenharmony_ci TimeTickNotify::GetInstance().PowerCallback(); 489cf69771bSopenharmony_ci return true; 490cf69771bSopenharmony_ci} 491cf69771bSopenharmony_ci 492cf69771bSopenharmony_ciint32_t TimeSystemAbility::SetTime(int64_t time, APIVersion apiVersion) 493cf69771bSopenharmony_ci{ 494cf69771bSopenharmony_ci if (!SetRealTime(time)) { 495cf69771bSopenharmony_ci return E_TIME_DEAL_FAILED; 496cf69771bSopenharmony_ci } 497cf69771bSopenharmony_ci return ERR_OK; 498cf69771bSopenharmony_ci} 499cf69771bSopenharmony_ci 500cf69771bSopenharmony_ciint TimeSystemAbility::Dump(int fd, const std::vector<std::u16string> &args) 501cf69771bSopenharmony_ci{ 502cf69771bSopenharmony_ci int uid = static_cast<int>(IPCSkeleton::GetCallingUid()); 503cf69771bSopenharmony_ci const int maxUid = 10000; 504cf69771bSopenharmony_ci if (uid > maxUid) { 505cf69771bSopenharmony_ci return E_TIME_DEAL_FAILED; 506cf69771bSopenharmony_ci } 507cf69771bSopenharmony_ci 508cf69771bSopenharmony_ci std::vector<std::string> argsStr; 509cf69771bSopenharmony_ci for (auto &item : args) { 510cf69771bSopenharmony_ci argsStr.emplace_back(Str16ToStr8(item)); 511cf69771bSopenharmony_ci } 512cf69771bSopenharmony_ci 513cf69771bSopenharmony_ci TimeCmdDispatcher::GetInstance().Dispatch(fd, argsStr); 514cf69771bSopenharmony_ci return ERR_OK; 515cf69771bSopenharmony_ci} 516cf69771bSopenharmony_ci 517cf69771bSopenharmony_civoid TimeSystemAbility::DumpAllTimeInfo(int fd, const std::vector<std::string> &input) 518cf69771bSopenharmony_ci{ 519cf69771bSopenharmony_ci dprintf(fd, "\n - dump all time info :\n"); 520cf69771bSopenharmony_ci struct timespec ts{}; 521cf69771bSopenharmony_ci struct tm timestr{}; 522cf69771bSopenharmony_ci char date_time[64]; 523cf69771bSopenharmony_ci if (GetTimeByClockId(CLOCK_BOOTTIME, ts)) { 524cf69771bSopenharmony_ci auto localTime = localtime_r(&ts.tv_sec, ×tr); 525cf69771bSopenharmony_ci if (localTime == nullptr) { 526cf69771bSopenharmony_ci return; 527cf69771bSopenharmony_ci } 528cf69771bSopenharmony_ci strftime(date_time, sizeof(date_time), "%Y-%m-%d %H:%M:%S", localTime); 529cf69771bSopenharmony_ci dprintf(fd, " * date time = %s\n", date_time); 530cf69771bSopenharmony_ci } else { 531cf69771bSopenharmony_ci dprintf(fd, " * dump date time error.\n"); 532cf69771bSopenharmony_ci } 533cf69771bSopenharmony_ci dprintf(fd, " - dump the time Zone:\n"); 534cf69771bSopenharmony_ci std::string timeZone; 535cf69771bSopenharmony_ci int32_t bRet = GetTimeZone(timeZone); 536cf69771bSopenharmony_ci if (bRet == ERR_OK) { 537cf69771bSopenharmony_ci dprintf(fd, " * time zone = %s\n", timeZone.c_str()); 538cf69771bSopenharmony_ci } else { 539cf69771bSopenharmony_ci dprintf(fd, " * dump time zone error,is %s\n", timeZone.c_str()); 540cf69771bSopenharmony_ci } 541cf69771bSopenharmony_ci} 542cf69771bSopenharmony_ci 543cf69771bSopenharmony_civoid TimeSystemAbility::DumpTimerInfo(int fd, const std::vector<std::string> &input) 544cf69771bSopenharmony_ci{ 545cf69771bSopenharmony_ci dprintf(fd, "\n - dump all timer info :\n"); 546cf69771bSopenharmony_ci auto timerManager = TimerManager::GetInstance(); 547cf69771bSopenharmony_ci if (timerManager == nullptr) { 548cf69771bSopenharmony_ci return; 549cf69771bSopenharmony_ci } 550cf69771bSopenharmony_ci timerManager->ShowTimerEntryMap(fd); 551cf69771bSopenharmony_ci} 552cf69771bSopenharmony_ci 553cf69771bSopenharmony_civoid TimeSystemAbility::DumpTimerInfoById(int fd, const std::vector<std::string> &input) 554cf69771bSopenharmony_ci{ 555cf69771bSopenharmony_ci dprintf(fd, "\n - dump the timer info with timer id:\n"); 556cf69771bSopenharmony_ci int paramNumPos = 2; 557cf69771bSopenharmony_ci auto timerManager = TimerManager::GetInstance(); 558cf69771bSopenharmony_ci if (timerManager == nullptr) { 559cf69771bSopenharmony_ci return; 560cf69771bSopenharmony_ci } 561cf69771bSopenharmony_ci timerManager->ShowTimerEntryById(fd, std::atoi(input.at(paramNumPos).c_str())); 562cf69771bSopenharmony_ci} 563cf69771bSopenharmony_ci 564cf69771bSopenharmony_civoid TimeSystemAbility::DumpTimerTriggerById(int fd, const std::vector<std::string> &input) 565cf69771bSopenharmony_ci{ 566cf69771bSopenharmony_ci dprintf(fd, "\n - dump timer trigger statics with timer id:\n"); 567cf69771bSopenharmony_ci int paramNumPos = 2; 568cf69771bSopenharmony_ci auto timerManager = TimerManager::GetInstance(); 569cf69771bSopenharmony_ci if (timerManager == nullptr) { 570cf69771bSopenharmony_ci return; 571cf69771bSopenharmony_ci } 572cf69771bSopenharmony_ci timerManager->ShowTimerTriggerById(fd, std::atoi(input.at(paramNumPos).c_str())); 573cf69771bSopenharmony_ci} 574cf69771bSopenharmony_ci 575cf69771bSopenharmony_civoid TimeSystemAbility::DumpIdleTimerInfo(int fd, const std::vector<std::string> &input) 576cf69771bSopenharmony_ci{ 577cf69771bSopenharmony_ci dprintf(fd, "\n - dump idle timer info :\n"); 578cf69771bSopenharmony_ci auto timerManager = TimerManager::GetInstance(); 579cf69771bSopenharmony_ci if (timerManager == nullptr) { 580cf69771bSopenharmony_ci return; 581cf69771bSopenharmony_ci } 582cf69771bSopenharmony_ci timerManager->ShowIdleTimerInfo(fd); 583cf69771bSopenharmony_ci} 584cf69771bSopenharmony_ci 585cf69771bSopenharmony_civoid TimeSystemAbility::DumpProxyTimerInfo(int fd, const std::vector<std::string> &input) 586cf69771bSopenharmony_ci{ 587cf69771bSopenharmony_ci dprintf(fd, "\n - dump proxy map:\n"); 588cf69771bSopenharmony_ci int64_t times; 589cf69771bSopenharmony_ci GetBootTimeNs(times); 590cf69771bSopenharmony_ci TimerProxy::GetInstance().ShowProxyTimerInfo(fd, times); 591cf69771bSopenharmony_ci} 592cf69771bSopenharmony_ci 593cf69771bSopenharmony_civoid TimeSystemAbility::DumpUidTimerMapInfo(int fd, const std::vector<std::string> &input) 594cf69771bSopenharmony_ci{ 595cf69771bSopenharmony_ci dprintf(fd, "\n - dump uid timer map:\n"); 596cf69771bSopenharmony_ci int64_t times; 597cf69771bSopenharmony_ci GetBootTimeNs(times); 598cf69771bSopenharmony_ci TimerProxy::GetInstance().ShowUidTimerMapInfo(fd, times); 599cf69771bSopenharmony_ci} 600cf69771bSopenharmony_ci 601cf69771bSopenharmony_civoid TimeSystemAbility::DumpProxyDelayTime(int fd, const std::vector<std::string> &input) 602cf69771bSopenharmony_ci{ 603cf69771bSopenharmony_ci dprintf(fd, "\n - dump proxy delay time:\n"); 604cf69771bSopenharmony_ci TimerProxy::GetInstance().ShowProxyDelayTime(fd); 605cf69771bSopenharmony_ci} 606cf69771bSopenharmony_ci 607cf69771bSopenharmony_civoid TimeSystemAbility::DumpPidTimerMapInfo(int fd, const std::vector<std::string> &input) 608cf69771bSopenharmony_ci{ 609cf69771bSopenharmony_ci dprintf(fd, "\n - dump pid timer map:\n"); 610cf69771bSopenharmony_ci int64_t times; 611cf69771bSopenharmony_ci GetBootTimeNs(times); 612cf69771bSopenharmony_ci TimerProxy::GetInstance().ShowPidTimerMapInfo(fd, times); 613cf69771bSopenharmony_ci} 614cf69771bSopenharmony_ci 615cf69771bSopenharmony_civoid TimeSystemAbility::DumpAdjustTime(int fd, const std::vector<std::string> &input) 616cf69771bSopenharmony_ci{ 617cf69771bSopenharmony_ci dprintf(fd, "\n - dump adjust timer info:\n"); 618cf69771bSopenharmony_ci TimerProxy::GetInstance().ShowAdjustTimerInfo(fd); 619cf69771bSopenharmony_ci} 620cf69771bSopenharmony_ci 621cf69771bSopenharmony_ciint TimeSystemAbility::SetRtcTime(time_t sec) 622cf69771bSopenharmony_ci{ 623cf69771bSopenharmony_ci struct rtc_time rtc {}; 624cf69771bSopenharmony_ci struct tm tm {}; 625cf69771bSopenharmony_ci struct tm *gmtime_res = nullptr; 626cf69771bSopenharmony_ci int fd = -1; 627cf69771bSopenharmony_ci int res; 628cf69771bSopenharmony_ci if (rtcId < 0) { 629cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "invalid rtc id: %{public}s:", strerror(ENODEV)); 630cf69771bSopenharmony_ci return E_TIME_SET_RTC_FAILED; 631cf69771bSopenharmony_ci } 632cf69771bSopenharmony_ci std::stringstream strs; 633cf69771bSopenharmony_ci strs << "/dev/rtc" << rtcId; 634cf69771bSopenharmony_ci auto rtcDev = strs.str(); 635cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "rtc_dev : %{public}s:", rtcDev.data()); 636cf69771bSopenharmony_ci auto rtcData = rtcDev.data(); 637cf69771bSopenharmony_ci fd = open(rtcData, O_RDWR); 638cf69771bSopenharmony_ci if (fd < 0) { 639cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "open failed %{public}s: %{public}s", rtcDev.data(), strerror(errno)); 640cf69771bSopenharmony_ci return E_TIME_SET_RTC_FAILED; 641cf69771bSopenharmony_ci } 642cf69771bSopenharmony_ci gmtime_res = gmtime_r(&sec, &tm); 643cf69771bSopenharmony_ci if (gmtime_res) { 644cf69771bSopenharmony_ci rtc.tm_sec = tm.tm_sec; 645cf69771bSopenharmony_ci rtc.tm_min = tm.tm_min; 646cf69771bSopenharmony_ci rtc.tm_hour = tm.tm_hour; 647cf69771bSopenharmony_ci rtc.tm_mday = tm.tm_mday; 648cf69771bSopenharmony_ci rtc.tm_mon = tm.tm_mon; 649cf69771bSopenharmony_ci rtc.tm_year = tm.tm_year; 650cf69771bSopenharmony_ci rtc.tm_wday = tm.tm_wday; 651cf69771bSopenharmony_ci rtc.tm_yday = tm.tm_yday; 652cf69771bSopenharmony_ci rtc.tm_isdst = tm.tm_isdst; 653cf69771bSopenharmony_ci res = ioctl(fd, RTC_SET_TIME, &rtc); 654cf69771bSopenharmony_ci if (res < 0) { 655cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "ioctl RTC_SET_TIME failed,errno: %{public}s, res: %{public}d", 656cf69771bSopenharmony_ci strerror(errno), res); 657cf69771bSopenharmony_ci } 658cf69771bSopenharmony_ci } else { 659cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "convert rtc time failed: %{public}s", strerror(errno)); 660cf69771bSopenharmony_ci res = E_TIME_SET_RTC_FAILED; 661cf69771bSopenharmony_ci } 662cf69771bSopenharmony_ci close(fd); 663cf69771bSopenharmony_ci return res; 664cf69771bSopenharmony_ci} 665cf69771bSopenharmony_ci 666cf69771bSopenharmony_cibool TimeSystemAbility::CheckRtc(const std::string &rtcPath, uint64_t rtcId) 667cf69771bSopenharmony_ci{ 668cf69771bSopenharmony_ci std::stringstream strs; 669cf69771bSopenharmony_ci strs << rtcPath << "/rtc" << rtcId << "/hctosys"; 670cf69771bSopenharmony_ci auto hctosys_path = strs.str(); 671cf69771bSopenharmony_ci 672cf69771bSopenharmony_ci std::fstream file(hctosys_path.data(), std::ios_base::in); 673cf69771bSopenharmony_ci if (file.is_open()) { 674cf69771bSopenharmony_ci return true; 675cf69771bSopenharmony_ci } else { 676cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "failed to open %{public}s", hctosys_path.data()); 677cf69771bSopenharmony_ci return false; 678cf69771bSopenharmony_ci } 679cf69771bSopenharmony_ci} 680cf69771bSopenharmony_ci 681cf69771bSopenharmony_ciint TimeSystemAbility::GetWallClockRtcId() 682cf69771bSopenharmony_ci{ 683cf69771bSopenharmony_ci std::string rtcPath = "/sys/class/rtc"; 684cf69771bSopenharmony_ci 685cf69771bSopenharmony_ci std::unique_ptr<DIR, int (*)(DIR *)> dir(opendir(rtcPath.c_str()), closedir); 686cf69771bSopenharmony_ci if (!dir.get()) { 687cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "failed to open %{public}s: %{public}s", rtcPath.c_str(), strerror(errno)); 688cf69771bSopenharmony_ci return -1; 689cf69771bSopenharmony_ci } 690cf69771bSopenharmony_ci 691cf69771bSopenharmony_ci struct dirent *dirent; 692cf69771bSopenharmony_ci std::string s = "rtc"; 693cf69771bSopenharmony_ci while (errno = 0, dirent = readdir(dir.get())) { 694cf69771bSopenharmony_ci std::string name(dirent->d_name); 695cf69771bSopenharmony_ci unsigned long rtcId = 0; 696cf69771bSopenharmony_ci auto index = name.find(s); 697cf69771bSopenharmony_ci if (index == std::string::npos) { 698cf69771bSopenharmony_ci continue; 699cf69771bSopenharmony_ci } else { 700cf69771bSopenharmony_ci auto rtcIdStr = name.substr(index + s.length()); 701cf69771bSopenharmony_ci rtcId = std::stoul(rtcIdStr); 702cf69771bSopenharmony_ci } 703cf69771bSopenharmony_ci if (CheckRtc(rtcPath, rtcId)) { 704cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "found wall clock rtc %{public}ld", rtcId); 705cf69771bSopenharmony_ci return rtcId; 706cf69771bSopenharmony_ci } 707cf69771bSopenharmony_ci } 708cf69771bSopenharmony_ci 709cf69771bSopenharmony_ci if (errno == 0) { 710cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "no wall clock rtc found"); 711cf69771bSopenharmony_ci } else { 712cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "failed to check rtc: %{public}s", strerror(errno)); 713cf69771bSopenharmony_ci } 714cf69771bSopenharmony_ci return -1; 715cf69771bSopenharmony_ci} 716cf69771bSopenharmony_ci 717cf69771bSopenharmony_ciint32_t TimeSystemAbility::SetTimeZone(const std::string &timeZoneId, APIVersion apiVersion) 718cf69771bSopenharmony_ci{ 719cf69771bSopenharmony_ci if (!TimeZoneInfo::GetInstance().SetTimezone(timeZoneId)) { 720cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "Set timezone failed :%{public}s", timeZoneId.c_str()); 721cf69771bSopenharmony_ci return E_TIME_DEAL_FAILED; 722cf69771bSopenharmony_ci } 723cf69771bSopenharmony_ci int64_t currentTime = 0; 724cf69771bSopenharmony_ci GetBootTimeMs(currentTime); 725cf69771bSopenharmony_ci TimeServiceNotify::GetInstance().PublishTimeZoneChangeEvents(currentTime); 726cf69771bSopenharmony_ci return ERR_OK; 727cf69771bSopenharmony_ci} 728cf69771bSopenharmony_ci 729cf69771bSopenharmony_ciint32_t TimeSystemAbility::GetTimeZone(std::string &timeZoneId) 730cf69771bSopenharmony_ci{ 731cf69771bSopenharmony_ci if (!TimeZoneInfo::GetInstance().GetTimezone(timeZoneId)) { 732cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "get timezone failed"); 733cf69771bSopenharmony_ci return E_TIME_DEAL_FAILED; 734cf69771bSopenharmony_ci } 735cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "Current timezone : %{public}s", timeZoneId.c_str()); 736cf69771bSopenharmony_ci return ERR_OK; 737cf69771bSopenharmony_ci} 738cf69771bSopenharmony_ci 739cf69771bSopenharmony_ciint32_t TimeSystemAbility::GetWallTimeMs(int64_t &time) 740cf69771bSopenharmony_ci{ 741cf69771bSopenharmony_ci struct timespec tv {}; 742cf69771bSopenharmony_ci if (GetTimeByClockId(CLOCK_REALTIME, tv)) { 743cf69771bSopenharmony_ci time = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI; 744cf69771bSopenharmony_ci return ERR_OK; 745cf69771bSopenharmony_ci } 746cf69771bSopenharmony_ci return E_TIME_DEAL_FAILED; 747cf69771bSopenharmony_ci} 748cf69771bSopenharmony_ci 749cf69771bSopenharmony_ciint32_t TimeSystemAbility::GetBootTimeMs(int64_t &time) 750cf69771bSopenharmony_ci{ 751cf69771bSopenharmony_ci struct timespec tv {}; 752cf69771bSopenharmony_ci if (GetTimeByClockId(CLOCK_BOOTTIME, tv)) { 753cf69771bSopenharmony_ci time = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI; 754cf69771bSopenharmony_ci return ERR_OK; 755cf69771bSopenharmony_ci } 756cf69771bSopenharmony_ci return E_TIME_DEAL_FAILED; 757cf69771bSopenharmony_ci} 758cf69771bSopenharmony_ci 759cf69771bSopenharmony_ciint32_t TimeSystemAbility::GetBootTimeNs(int64_t &time) 760cf69771bSopenharmony_ci{ 761cf69771bSopenharmony_ci struct timespec tv {}; 762cf69771bSopenharmony_ci if (GetTimeByClockId(CLOCK_BOOTTIME, tv)) { 763cf69771bSopenharmony_ci time = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec; 764cf69771bSopenharmony_ci return ERR_OK; 765cf69771bSopenharmony_ci } 766cf69771bSopenharmony_ci return E_TIME_DEAL_FAILED; 767cf69771bSopenharmony_ci} 768cf69771bSopenharmony_ci 769cf69771bSopenharmony_ciint32_t TimeSystemAbility::GetThreadTimeMs(int64_t &time) 770cf69771bSopenharmony_ci{ 771cf69771bSopenharmony_ci struct timespec tv {}; 772cf69771bSopenharmony_ci clockid_t cid; 773cf69771bSopenharmony_ci int ret = pthread_getcpuclockid(pthread_self(), &cid); 774cf69771bSopenharmony_ci if (ret != E_TIME_OK) { 775cf69771bSopenharmony_ci return E_TIME_PARAMETERS_INVALID; 776cf69771bSopenharmony_ci } 777cf69771bSopenharmony_ci if (GetTimeByClockId(cid, tv)) { 778cf69771bSopenharmony_ci time = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI; 779cf69771bSopenharmony_ci return ERR_OK; 780cf69771bSopenharmony_ci } 781cf69771bSopenharmony_ci return E_TIME_DEAL_FAILED; 782cf69771bSopenharmony_ci} 783cf69771bSopenharmony_ci 784cf69771bSopenharmony_ciint32_t TimeSystemAbility::GetThreadTimeNs(int64_t &time) 785cf69771bSopenharmony_ci{ 786cf69771bSopenharmony_ci struct timespec tv {}; 787cf69771bSopenharmony_ci clockid_t cid; 788cf69771bSopenharmony_ci int ret = pthread_getcpuclockid(pthread_self(), &cid); 789cf69771bSopenharmony_ci if (ret != E_TIME_OK) { 790cf69771bSopenharmony_ci return E_TIME_PARAMETERS_INVALID; 791cf69771bSopenharmony_ci } 792cf69771bSopenharmony_ci if (GetTimeByClockId(cid, tv)) { 793cf69771bSopenharmony_ci time = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec; 794cf69771bSopenharmony_ci return ERR_OK; 795cf69771bSopenharmony_ci } 796cf69771bSopenharmony_ci return E_TIME_DEAL_FAILED; 797cf69771bSopenharmony_ci} 798cf69771bSopenharmony_ci 799cf69771bSopenharmony_cibool TimeSystemAbility::GetTimeByClockId(clockid_t clockId, struct timespec &tv) 800cf69771bSopenharmony_ci{ 801cf69771bSopenharmony_ci if (clock_gettime(clockId, &tv) < 0) { 802cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "Failed clock_gettime."); 803cf69771bSopenharmony_ci return false; 804cf69771bSopenharmony_ci } 805cf69771bSopenharmony_ci return true; 806cf69771bSopenharmony_ci} 807cf69771bSopenharmony_ci 808cf69771bSopenharmony_cibool TimeSystemAbility::ProxyTimer(int32_t uid, bool isProxy, bool needRetrigger) 809cf69771bSopenharmony_ci{ 810cf69771bSopenharmony_ci if (!TimePermission::CheckProxyCallingPermission()) { 811cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "ProxyTimer permission check failed"); 812cf69771bSopenharmony_ci return E_TIME_NO_PERMISSION; 813cf69771bSopenharmony_ci } 814cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "ProxyTimer service start uid: %{public}d, isProxy: %{public}d", uid, isProxy); 815cf69771bSopenharmony_ci auto timerManager = TimerManager::GetInstance(); 816cf69771bSopenharmony_ci if (timerManager == nullptr) { 817cf69771bSopenharmony_ci return false; 818cf69771bSopenharmony_ci } 819cf69771bSopenharmony_ci return timerManager->ProxyTimer(uid, isProxy, needRetrigger); 820cf69771bSopenharmony_ci} 821cf69771bSopenharmony_ci 822cf69771bSopenharmony_ciint32_t TimeSystemAbility::AdjustTimer(bool isAdjust, uint32_t interval) 823cf69771bSopenharmony_ci{ 824cf69771bSopenharmony_ci auto timerManager = TimerManager::GetInstance(); 825cf69771bSopenharmony_ci if (timerManager == nullptr) { 826cf69771bSopenharmony_ci return E_TIME_NULLPTR; 827cf69771bSopenharmony_ci } 828cf69771bSopenharmony_ci if (!timerManager->AdjustTimer(isAdjust, interval)) { 829cf69771bSopenharmony_ci return E_TIME_NO_TIMER_ADJUST; 830cf69771bSopenharmony_ci } 831cf69771bSopenharmony_ci return E_TIME_OK; 832cf69771bSopenharmony_ci} 833cf69771bSopenharmony_ci 834cf69771bSopenharmony_cibool TimeSystemAbility::ProxyTimer(std::set<int> pidList, bool isProxy, bool needRetrigger) 835cf69771bSopenharmony_ci{ 836cf69771bSopenharmony_ci if (!TimePermission::CheckProxyCallingPermission()) { 837cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "ProxyTimer permission check failed"); 838cf69771bSopenharmony_ci return E_TIME_NO_PERMISSION; 839cf69771bSopenharmony_ci } 840cf69771bSopenharmony_ci auto timerManager = TimerManager::GetInstance(); 841cf69771bSopenharmony_ci if (timerManager == nullptr) { 842cf69771bSopenharmony_ci return false; 843cf69771bSopenharmony_ci } 844cf69771bSopenharmony_ci return timerManager->ProxyTimer(pidList, isProxy, needRetrigger); 845cf69771bSopenharmony_ci} 846cf69771bSopenharmony_ci 847cf69771bSopenharmony_ciint32_t TimeSystemAbility::SetTimerExemption(const std::unordered_set<std::string> &nameArr, bool isExemption) 848cf69771bSopenharmony_ci{ 849cf69771bSopenharmony_ci auto timerManager = TimerManager::GetInstance(); 850cf69771bSopenharmony_ci if (timerManager == nullptr) { 851cf69771bSopenharmony_ci return E_TIME_NULLPTR; 852cf69771bSopenharmony_ci } 853cf69771bSopenharmony_ci timerManager->SetTimerExemption(nameArr, isExemption); 854cf69771bSopenharmony_ci return E_TIME_OK; 855cf69771bSopenharmony_ci} 856cf69771bSopenharmony_ci 857cf69771bSopenharmony_cibool TimeSystemAbility::ResetAllProxy() 858cf69771bSopenharmony_ci{ 859cf69771bSopenharmony_ci if (!TimePermission::CheckProxyCallingPermission()) { 860cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "ResetAllProxy permission check failed"); 861cf69771bSopenharmony_ci return E_TIME_NO_PERMISSION; 862cf69771bSopenharmony_ci } 863cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "ResetAllProxy service"); 864cf69771bSopenharmony_ci auto timerManager = TimerManager::GetInstance(); 865cf69771bSopenharmony_ci if (timerManager == nullptr) { 866cf69771bSopenharmony_ci return false; 867cf69771bSopenharmony_ci } 868cf69771bSopenharmony_ci return timerManager->ResetAllProxy(); 869cf69771bSopenharmony_ci} 870cf69771bSopenharmony_ci 871cf69771bSopenharmony_ciint32_t TimeSystemAbility::GetNtpTimeMs(int64_t &time) 872cf69771bSopenharmony_ci{ 873cf69771bSopenharmony_ci auto ret = NtpUpdateTime::GetInstance().GetNtpTime(time); 874cf69771bSopenharmony_ci if (!ret) { 875cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "GetNtpTimeMs failed"); 876cf69771bSopenharmony_ci return E_TIME_NTP_UPDATE_FAILED; 877cf69771bSopenharmony_ci } 878cf69771bSopenharmony_ci return E_TIME_OK; 879cf69771bSopenharmony_ci} 880cf69771bSopenharmony_ci 881cf69771bSopenharmony_ciint32_t TimeSystemAbility::GetRealTimeMs(int64_t &time) 882cf69771bSopenharmony_ci{ 883cf69771bSopenharmony_ci auto ret = NtpUpdateTime::GetInstance().GetRealTime(time); 884cf69771bSopenharmony_ci if (!ret) { 885cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "GetRealTimeMs failed"); 886cf69771bSopenharmony_ci return E_TIME_NTP_NOT_UPDATE; 887cf69771bSopenharmony_ci } 888cf69771bSopenharmony_ci return E_TIME_OK; 889cf69771bSopenharmony_ci} 890cf69771bSopenharmony_ci 891cf69771bSopenharmony_civoid TimeSystemAbility::RSSSaDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object) 892cf69771bSopenharmony_ci{ 893cf69771bSopenharmony_ci auto timerManager = TimerManager::GetInstance(); 894cf69771bSopenharmony_ci if (timerManager == nullptr) { 895cf69771bSopenharmony_ci return; 896cf69771bSopenharmony_ci } 897cf69771bSopenharmony_ci timerManager->HandleRSSDeath(); 898cf69771bSopenharmony_ci} 899cf69771bSopenharmony_ci 900cf69771bSopenharmony_civoid TimeSystemAbility::RegisterRSSDeathCallback() 901cf69771bSopenharmony_ci{ 902cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "register rss death callback"); 903cf69771bSopenharmony_ci auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 904cf69771bSopenharmony_ci if (systemAbilityManager == nullptr) { 905cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_CLIENT, "Getting SystemAbilityManager failed."); 906cf69771bSopenharmony_ci return; 907cf69771bSopenharmony_ci } 908cf69771bSopenharmony_ci 909cf69771bSopenharmony_ci auto systemAbility = systemAbilityManager->GetSystemAbility(DEVICE_STANDBY_SERVICE_SYSTEM_ABILITY_ID); 910cf69771bSopenharmony_ci if (systemAbility == nullptr) { 911cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_CLIENT, "Get SystemAbility failed."); 912cf69771bSopenharmony_ci return; 913cf69771bSopenharmony_ci } 914cf69771bSopenharmony_ci 915cf69771bSopenharmony_ci if (deathRecipient_ == nullptr) { 916cf69771bSopenharmony_ci deathRecipient_ = new RSSSaDeathRecipient(); 917cf69771bSopenharmony_ci } 918cf69771bSopenharmony_ci 919cf69771bSopenharmony_ci systemAbility->AddDeathRecipient(deathRecipient_); 920cf69771bSopenharmony_ci} 921cf69771bSopenharmony_ci 922cf69771bSopenharmony_civoid TimeSystemAbility::TimePowerStateListener::OnSyncShutdown() 923cf69771bSopenharmony_ci{ 924cf69771bSopenharmony_ci // Clears `drop_on_reboot` table. 925cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "OnSyncShutdown"); 926cf69771bSopenharmony_ci TimeSystemAbility::GetInstance()->SetAutoReboot(); 927cf69771bSopenharmony_ci TimeDatabase::GetInstance().ClearDropOnReboot(); 928cf69771bSopenharmony_ci} 929cf69771bSopenharmony_ci 930cf69771bSopenharmony_civoid TimeSystemAbility::RegisterPowerStateListener() 931cf69771bSopenharmony_ci{ 932cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_CLIENT, "RegisterPowerStateListener"); 933cf69771bSopenharmony_ci auto& powerManagerClient = OHOS::PowerMgr::ShutdownClient::GetInstance(); 934cf69771bSopenharmony_ci sptr<OHOS::PowerMgr::ISyncShutdownCallback> syncShutdownCallback = new TimePowerStateListener(); 935cf69771bSopenharmony_ci if (!syncShutdownCallback) { 936cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "Get TimePowerStateListener failed."); 937cf69771bSopenharmony_ci return; 938cf69771bSopenharmony_ci } 939cf69771bSopenharmony_ci powerManagerClient.RegisterShutdownCallback(syncShutdownCallback, PowerMgr::ShutdownPriority::HIGH); 940cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_CLIENT, "RegisterPowerStateListener end"); 941cf69771bSopenharmony_ci} 942cf69771bSopenharmony_ci 943cf69771bSopenharmony_cibool TimeSystemAbility::RecoverTimer() 944cf69771bSopenharmony_ci{ 945cf69771bSopenharmony_ci auto database = TimeDatabase::GetInstance(); 946cf69771bSopenharmony_ci OHOS::NativeRdb::RdbPredicates holdRdbPredicates(HOLD_ON_REBOOT); 947cf69771bSopenharmony_ci auto holdResultSet = database.Query(holdRdbPredicates, ALL_DATA); 948cf69771bSopenharmony_ci if (holdResultSet == nullptr || holdResultSet->GoToFirstRow() != OHOS::NativeRdb::E_OK) { 949cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "hold result set is nullptr or go to first row failed"); 950cf69771bSopenharmony_ci } else { 951cf69771bSopenharmony_ci int count; 952cf69771bSopenharmony_ci holdResultSet->GetRowCount(count); 953cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "hold result rows count: %{public}d", count); 954cf69771bSopenharmony_ci RecoverTimerInner(holdResultSet); 955cf69771bSopenharmony_ci } 956cf69771bSopenharmony_ci if (holdResultSet != nullptr) { 957cf69771bSopenharmony_ci holdResultSet->Close(); 958cf69771bSopenharmony_ci } 959cf69771bSopenharmony_ci 960cf69771bSopenharmony_ci OHOS::NativeRdb::RdbPredicates dropRdbPredicates(DROP_ON_REBOOT); 961cf69771bSopenharmony_ci auto dropResultSet = database.Query(dropRdbPredicates, ALL_DATA); 962cf69771bSopenharmony_ci if (dropResultSet == nullptr || dropResultSet->GoToFirstRow() != OHOS::NativeRdb::E_OK) { 963cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "drop result set is nullptr or go to first row failed"); 964cf69771bSopenharmony_ci } else { 965cf69771bSopenharmony_ci int count; 966cf69771bSopenharmony_ci dropResultSet->GetRowCount(count); 967cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "drop result rows count: %{public}d", count); 968cf69771bSopenharmony_ci RecoverTimerInner(dropResultSet); 969cf69771bSopenharmony_ci } 970cf69771bSopenharmony_ci if (dropResultSet != nullptr) { 971cf69771bSopenharmony_ci dropResultSet->Close(); 972cf69771bSopenharmony_ci } 973cf69771bSopenharmony_ci return true; 974cf69771bSopenharmony_ci} 975cf69771bSopenharmony_ci 976cf69771bSopenharmony_civoid TimeSystemAbility::RecoverTimerInner(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet) 977cf69771bSopenharmony_ci{ 978cf69771bSopenharmony_ci auto timerManager = TimerManager::GetInstance(); 979cf69771bSopenharmony_ci if (timerManager == nullptr) { 980cf69771bSopenharmony_ci return; 981cf69771bSopenharmony_ci } 982cf69771bSopenharmony_ci do { 983cf69771bSopenharmony_ci auto timerId = static_cast<uint64_t>(GetLong(resultSet, 0)); 984cf69771bSopenharmony_ci auto timerInfo = std::make_shared<TimerEntry>(TimerEntry { 985cf69771bSopenharmony_ci // Line 0 is 'timerId' 986cf69771bSopenharmony_ci timerId, 987cf69771bSopenharmony_ci // Line 1 is 'type' 988cf69771bSopenharmony_ci GetInt(resultSet, 1), 989cf69771bSopenharmony_ci // Line 3 is 'windowLength' 990cf69771bSopenharmony_ci static_cast<uint64_t>(GetLong(resultSet, 3)), 991cf69771bSopenharmony_ci // Line 4 is 'interval' 992cf69771bSopenharmony_ci static_cast<uint64_t>(GetLong(resultSet, 4)), 993cf69771bSopenharmony_ci // Line 2 is 'flag' 994cf69771bSopenharmony_ci GetInt(resultSet, 2), 995cf69771bSopenharmony_ci // Callback can't recover. 996cf69771bSopenharmony_ci nullptr, 997cf69771bSopenharmony_ci // Line 7 is 'wantAgent' 998cf69771bSopenharmony_ci OHOS::AbilityRuntime::WantAgent::WantAgentHelper::FromString(GetString(resultSet, 7)), 999cf69771bSopenharmony_ci // Line 5 is 'uid' 1000cf69771bSopenharmony_ci GetInt(resultSet, 5), 1001cf69771bSopenharmony_ci // Line 10 is 'pid' 1002cf69771bSopenharmony_ci GetInt(resultSet, 10), 1003cf69771bSopenharmony_ci // Line 6 is 'bundleName' 1004cf69771bSopenharmony_ci GetString(resultSet, 6) 1005cf69771bSopenharmony_ci }); 1006cf69771bSopenharmony_ci if (timerInfo->wantAgent == nullptr) { 1007cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "wantAgent is nullptr, uid=%{public}d, id=%{public}" PRId64 "", 1008cf69771bSopenharmony_ci timerInfo->uid, timerInfo->id); 1009cf69771bSopenharmony_ci continue; 1010cf69771bSopenharmony_ci } 1011cf69771bSopenharmony_ci timerManager->ReCreateTimer(timerId, timerInfo); 1012cf69771bSopenharmony_ci // Line 8 is 'state' 1013cf69771bSopenharmony_ci auto state = static_cast<uint8_t>(GetInt(resultSet, 8)); 1014cf69771bSopenharmony_ci if (state == 1) { 1015cf69771bSopenharmony_ci // Line 9 is 'triggerTime' 1016cf69771bSopenharmony_ci auto triggerTime = static_cast<uint64_t>(GetLong(resultSet, 9)); 1017cf69771bSopenharmony_ci timerManager->StartTimer(timerId, triggerTime); 1018cf69771bSopenharmony_ci } 1019cf69771bSopenharmony_ci } while (resultSet->GoToNextRow() == OHOS::NativeRdb::E_OK); 1020cf69771bSopenharmony_ci} 1021cf69771bSopenharmony_ci 1022cf69771bSopenharmony_civoid TimeSystemAbility::SetAutoReboot() 1023cf69771bSopenharmony_ci{ 1024cf69771bSopenharmony_ci auto database = TimeDatabase::GetInstance(); 1025cf69771bSopenharmony_ci OHOS::NativeRdb::RdbPredicates holdRdbPredicates(HOLD_ON_REBOOT); 1026cf69771bSopenharmony_ci holdRdbPredicates.EqualTo("state", 1)->OrderByAsc("triggerTime"); 1027cf69771bSopenharmony_ci auto resultSet = database.Query(holdRdbPredicates, { "bundleName", "triggerTime" }); 1028cf69771bSopenharmony_ci if (resultSet == nullptr) { 1029cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "no need to set RTC"); 1030cf69771bSopenharmony_ci return; 1031cf69771bSopenharmony_ci } 1032cf69771bSopenharmony_ci int64_t currentTime = 0; 1033cf69771bSopenharmony_ci TimeSystemAbility::GetInstance()->GetWallTimeMs(currentTime); 1034cf69771bSopenharmony_ci auto bundleList = TimeFileUtils::GetBundleList(); 1035cf69771bSopenharmony_ci do { 1036cf69771bSopenharmony_ci auto bundleName = GetString(resultSet, 0); 1037cf69771bSopenharmony_ci uint64_t triggerTime = static_cast<uint64_t>(GetLong(resultSet, 1)); 1038cf69771bSopenharmony_ci if (triggerTime < static_cast<uint64_t>(currentTime)) { 1039cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, 1040cf69771bSopenharmony_ci "triggerTime: %{public}" PRIu64" currentTime: %{public}" PRId64"", triggerTime, currentTime); 1041cf69771bSopenharmony_ci continue; 1042cf69771bSopenharmony_ci } 1043cf69771bSopenharmony_ci if (bundleName == (bundleList.empty() ? "" : bundleList[0])) { 1044cf69771bSopenharmony_ci int tmfd = timerfd_create(CLOCK_POWEROFF_ALARM, TFD_NONBLOCK); 1045cf69771bSopenharmony_ci if (tmfd < 0) { 1046cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "timerfd_create error: %{public}s", strerror(errno)); 1047cf69771bSopenharmony_ci resultSet->Close(); 1048cf69771bSopenharmony_ci return; 1049cf69771bSopenharmony_ci } 1050cf69771bSopenharmony_ci if (static_cast<uint64_t>(currentTime) + TWO_MINUTES_TO_MILLI > triggerTime) { 1051cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "interval less than 2min"); 1052cf69771bSopenharmony_ci triggerTime = static_cast<uint64_t>(currentTime) + TWO_MINUTES_TO_MILLI; 1053cf69771bSopenharmony_ci } 1054cf69771bSopenharmony_ci struct itimerspec new_value; 1055cf69771bSopenharmony_ci std::chrono::nanoseconds nsec(triggerTime * MILLISECOND_TO_NANO); 1056cf69771bSopenharmony_ci auto second = std::chrono::duration_cast<std::chrono::seconds>(nsec); 1057cf69771bSopenharmony_ci new_value.it_value.tv_sec = second.count(); 1058cf69771bSopenharmony_ci new_value.it_value.tv_nsec = (nsec - second).count(); 1059cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "currentTime:%{public}" PRId64 ", second:%{public}" PRId64 "," 1060cf69771bSopenharmony_ci "nanosecond:%{public}" PRId64"", currentTime, static_cast<int64_t>(new_value.it_value.tv_sec), 1061cf69771bSopenharmony_ci static_cast<int64_t>(new_value.it_value.tv_nsec)); 1062cf69771bSopenharmony_ci int ret = timerfd_settime(tmfd, TFD_TIMER_ABSTIME, &new_value, nullptr); 1063cf69771bSopenharmony_ci if (ret < 0) { 1064cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "timerfd_settime error: %{public}s", strerror(errno)); 1065cf69771bSopenharmony_ci close(tmfd); 1066cf69771bSopenharmony_ci } 1067cf69771bSopenharmony_ci resultSet->Close(); 1068cf69771bSopenharmony_ci return; 1069cf69771bSopenharmony_ci } 1070cf69771bSopenharmony_ci } while (resultSet->GoToNextRow() == OHOS::NativeRdb::E_OK); 1071cf69771bSopenharmony_ci resultSet->Close(); 1072cf69771bSopenharmony_ci} 1073cf69771bSopenharmony_ci} // namespace MiscServices 1074cf69771bSopenharmony_ci} // namespace OHOS