• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022-2023 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 
16 #include "timer_manager.h"
17 
18 #include "time_file_utils.h"
19 #include "timer_proxy.h"
20 
21 #ifdef RDB_ENABLE
22 #include "rdb_errno.h"
23 #include "rdb_helper.h"
24 #include "rdb_open_callback.h"
25 #include "rdb_predicates.h"
26 #include "rdb_store.h"
27 #include "timer_database.h"
28 #endif
29 
30 #ifdef DEVICE_STANDBY_ENABLE
31 #include "allow_type.h"
32 #include "standby_service_client.h"
33 #endif
34 
35 #ifdef POWER_MANAGER_ENABLE
36 #include "time_system_ability.h"
37 #endif
38 
39 #ifdef MULTI_ACCOUNT_ENABLE
40 #include "os_account.h"
41 #include "os_account_manager.h"
42 #endif
43 
44 namespace OHOS {
45 namespace MiscServices {
46 using namespace std::chrono;
47 using namespace OHOS::AppExecFwk;
48 namespace {
49 constexpr uint32_t TIME_CHANGED_BITS = 16;
50 constexpr uint32_t TIME_CHANGED_MASK = 1 << TIME_CHANGED_BITS;
51 constexpr int64_t MAX_MILLISECOND = std::numeric_limits<int64_t>::max() / 1000000;
52 constexpr int ONE_THOUSAND = 1000;
53 constexpr float_t BATCH_WINDOW_COE = 0.75;
54 const auto ZERO_FUTURITY = seconds(0);
55 const auto MIN_INTERVAL_ONE_SECONDS = seconds(1);
56 const auto MAX_INTERVAL = hours(24 * 365);
57 const auto INTERVAL_HOUR = hours(1);
58 const auto INTERVAL_HALF_DAY = hours(12);
59 const auto MIN_FUZZABLE_INTERVAL = milliseconds(10000);
60 constexpr int NANO_TO_SECOND =  1000000000;
61 constexpr int WANTAGENT_CODE_ELEVEN = 11;
62 constexpr int WANT_RETRY_TIMES = 6;
63 constexpr int WANT_RETRY_INTERVAL = 1;
64 // an error code of ipc which means peer end is dead
65 constexpr int PEER_END_DEAD = 29189;
66 constexpr int TIMER_ALARM_COUNT = 50;
67 constexpr int MAX_TIMER_ALARM_COUNT = 100;
68 constexpr int TIMER_ALRAM_INTERVAL = 60;
69 constexpr int TIMER_COUNT_TOP_NUM = 5;
70 constexpr const char* AUTO_RESTORE_TIMER_APPS = "persist.time.auto_restore_timer_apps";
71 
72 #ifdef RDB_ENABLE
73 static const std::vector<std::string> ALL_DATA = { "timerId", "type", "flag", "windowLength", "interval", \
74                                                    "uid", "bundleName", "wantAgent", "state", "triggerTime" };
75 #endif
76 
77 #ifdef MULTI_ACCOUNT_ENABLE
78 constexpr int SYSTEM_USER_ID  = 0;
79 constexpr const char* TIMER_ACROSS_ACCOUNTS = "persist.time.timer_across_accounts";
80 #endif
81 
82 #ifdef POWER_MANAGER_ENABLE
83 constexpr int64_t USE_LOCK_ONE_SEC_IN_NANO = 1 * NANO_TO_SECOND;
84 constexpr int64_t USE_LOCK_TIME_IN_NANO = 2 * NANO_TO_SECOND;
85 constexpr int32_t NANO_TO_MILLI = 1000000;
86 constexpr int64_t ONE_HUNDRED_MILLI = 100000000; // 100ms
87 constexpr int POWER_RETRY_TIMES = 10;
88 constexpr int POWER_RETRY_INTERVAL = 10000;
89 #endif
90 
91 #ifdef DEVICE_STANDBY_ENABLE
92 constexpr int REASON_NATIVE_API = 0;
93 constexpr int REASON_APP_API = 1;
94 #endif
95 }
96 
97 std::mutex TimerManager::instanceLock_;
98 TimerManager* TimerManager::instance_ = nullptr;
99 
100 extern bool AddBatchLocked(std::vector<std::shared_ptr<Batch>> &list, const std::shared_ptr<Batch> &batch);
101 extern steady_clock::time_point MaxTriggerTime(steady_clock::time_point now,
102                                                steady_clock::time_point triggerAtTime,
103                                                milliseconds interval);
104 
TimerManager(std::shared_ptr<TimerHandler> impl)105 TimerManager::TimerManager(std::shared_ptr<TimerHandler> impl)
106     : random_ {static_cast<uint64_t>(time(nullptr))},
107       runFlag_ {true},
108       handler_ {std::move(impl)},
109       lastTimeChangeClockTime_ {system_clock::time_point::min()},
110       lastTimeChangeRealtime_ {steady_clock::time_point::min()},
111       lastTimerOutOfRangeTime_ {steady_clock::time_point::min()}
112 {
__anona49f3de50202null113     alarmThread_.reset(new std::thread([this] { this->TimerLooper(); }));
114 }
115 
GetInstance()116 TimerManager* TimerManager::GetInstance()
117 {
118     if (instance_ == nullptr) {
119         std::lock_guard<std::mutex> autoLock(instanceLock_);
120         if (instance_ == nullptr) {
121             auto impl = TimerHandler::Create();
122             if (impl == nullptr) {
123                 TIME_HILOGE(TIME_MODULE_SERVICE, "Create Timer handle failed");
124                 return nullptr;
125             }
126             instance_ = new TimerManager(impl);
127             std::vector<std::string> bundleList = TimeFileUtils::GetParameterList(AUTO_RESTORE_TIMER_APPS);
128             if (!bundleList.empty()) {
129                 NEED_RECOVER_ON_REBOOT = bundleList;
130             }
131         }
132     }
133     if (instance_ == nullptr) {
134         TIME_HILOGE(TIME_MODULE_SERVICE, "Create Timer manager failed");
135     }
136     return instance_;
137 }
138 
139 #ifdef RDB_ENABLE
GetInsertValues(std::shared_ptr<TimerEntry> timerInfo,TimerPara & paras)140 OHOS::NativeRdb::ValuesBucket GetInsertValues(std::shared_ptr<TimerEntry> timerInfo, TimerPara &paras)
141 {
142     OHOS::NativeRdb::ValuesBucket insertValues;
143     insertValues.PutLong("timerId", timerInfo->id);
144     insertValues.PutInt("type", paras.timerType);
145     insertValues.PutInt("flag", paras.flag);
146     insertValues.PutLong("windowLength", paras.windowLength);
147     insertValues.PutLong("interval", paras.interval);
148     insertValues.PutInt("uid", timerInfo->uid);
149     insertValues.PutString("bundleName", timerInfo->bundleName);
150     insertValues.PutString("wantAgent",
151         OHOS::AbilityRuntime::WantAgent::WantAgentHelper::ToString(timerInfo->wantAgent));
152     insertValues.PutInt("state", 0);
153     insertValues.PutLong("triggerTime", 0);
154     insertValues.PutInt("pid", timerInfo->pid);
155     insertValues.PutString("name", timerInfo->name);
156     return insertValues;
157 }
158 #endif
159 
160 // needs to acquire the lock `entryMapMutex_` before calling this method
AddTimerName(int uid,std::string name,uint64_t timerId)161 void TimerManager::AddTimerName(int uid, std::string name, uint64_t timerId)
162 {
163     if (timerNameMap_.find(uid) == timerNameMap_.end() || timerNameMap_[uid].find(name) == timerNameMap_[uid].end()) {
164         timerNameMap_[uid][name] = timerId;
165         TIME_HILOGD(TIME_MODULE_SERVICE, "record name: %{public}s id %{public}" PRId64 "", name.c_str(), timerId);
166         return;
167     }
168     auto oldTimerId = timerNameMap_[uid][name];
169     if (timerId != oldTimerId) {
170         bool needRecover =  false;
171         StopTimerInnerLocked(true, oldTimerId, needRecover);
172         UpdateOrDeleteDatabase(true, oldTimerId, needRecover);
173         timerNameMap_[uid][name] = timerId;
174         TIME_HILOGW(TIME_MODULE_SERVICE, "create %{public}" PRId64 " name: %{public}s in %{public}d already exist,"
175             "destory timer %{public}" PRId64 "", timerId, name.c_str(), uid, oldTimerId);
176     }
177     return;
178 }
179 
180 // needs to acquire the lock `entryMapMutex_` before calling this method
DeleteTimerName(int uid,std::string name,uint64_t timerId)181 void TimerManager::DeleteTimerName(int uid, std::string name, uint64_t timerId)
182 {
183     auto nameIter = timerNameMap_.find(uid);
184     if (nameIter == timerNameMap_.end()) {
185         TIME_HILOGE(TIME_MODULE_SERVICE, "NameMap has no uid %{public}d", uid);
186         return;
187     }
188     auto timerIter = nameIter->second.find(name);
189     if (timerIter == nameIter->second.end()) {
190         TIME_HILOGE(TIME_MODULE_SERVICE, "NameMap has no name:%{public}s uid: %{public}d", name.c_str(), uid);
191         return;
192     }
193     if (timerIter->second == timerId) {
194         timerNameMap_[uid].erase(timerIter);
195         return;
196     }
197     TIME_HILOGW(TIME_MODULE_SERVICE,
198         "timer %{public}" PRId64 " not exist in map, name:%{public}s uid%{public}d", timerId, name.c_str(), uid);
199 }
200 
CreateTimer(TimerPara & paras,std::function<int32_t (const uint64_t)> callback,std::shared_ptr<OHOS::AbilityRuntime::WantAgent::WantAgent> wantAgent,int uid,int pid,uint64_t & timerId,DatabaseType type)201 int32_t TimerManager::CreateTimer(TimerPara &paras,
202                                   std::function<int32_t (const uint64_t)> callback,
203                                   std::shared_ptr<OHOS::AbilityRuntime::WantAgent::WantAgent> wantAgent,
204                                   int uid,
205                                   int pid,
206                                   uint64_t &timerId,
207                                   DatabaseType type)
208 {
209     TIME_HILOGD(TIME_MODULE_SERVICE,
210                 "Create timer: %{public}d windowLength:%{public}" PRId64 "interval:%{public}" PRId64 "flag:%{public}u"
211                 "uid:%{public}d pid:%{public}d timerId:%{public}" PRId64 "", paras.timerType, paras.windowLength,
212                 paras.interval, paras.flag, IPCSkeleton::GetCallingUid(), IPCSkeleton::GetCallingPid(), timerId);
213     std::string bundleName = TimeFileUtils::GetBundleNameByTokenID(IPCSkeleton::GetCallingTokenID());
214     if (bundleName.empty()) {
215         bundleName = TimeFileUtils::GetNameByPid(IPCSkeleton::GetCallingPid());
216     }
217     auto timerName = paras.name;
218     std::shared_ptr<TimerEntry> timerInfo;
219     {
220         std::lock_guard<std::mutex> lock(entryMapMutex_);
221         while (timerId == 0) {
222             // random_() needs to be protected in a lock.
223             timerId = random_();
224         }
225         timerInfo = std::make_shared<TimerEntry>(TimerEntry {timerName, timerId, paras.timerType, paras.windowLength,
226             paras.interval, paras.flag, paras.autoRestore, std::move(callback), wantAgent, uid, pid, bundleName});
227         if (timerEntryMap_.find(timerId) == timerEntryMap_.end()) {
228             IncreaseTimerCount(uid);
229         }
230         timerEntryMap_.insert(std::make_pair(timerId, timerInfo));
231         if (timerName != "") {
232             AddTimerName(uid, timerName, timerId);
233         }
234     }
235     if (type == NOT_STORE) {
236         return E_TIME_OK;
237     }
238     auto tableName = (CheckNeedRecoverOnReboot(bundleName, paras.timerType, paras.autoRestore)
239                       ? HOLD_ON_REBOOT
240                       : DROP_ON_REBOOT);
241     #ifdef RDB_ENABLE
242     TimeDatabase::GetInstance().Insert(tableName, GetInsertValues(timerInfo, paras));
243     #else
244     CjsonHelper::GetInstance().Insert(tableName, timerInfo);
245     #endif
246     return E_TIME_OK;
247 }
248 
ReCreateTimer(uint64_t timerId,std::shared_ptr<TimerEntry> timerInfo)249 void TimerManager::ReCreateTimer(uint64_t timerId, std::shared_ptr<TimerEntry> timerInfo)
250 {
251     std::lock_guard<std::mutex> lock(entryMapMutex_);
252     timerEntryMap_.insert(std::make_pair(timerId, timerInfo));
253     if (timerInfo->name != "") {
254         AddTimerName(timerInfo->uid, timerInfo->name, timerId);
255     }
256     IncreaseTimerCount(timerInfo->uid);
257 }
258 
StartTimer(uint64_t timerId,uint64_t triggerTime)259 int32_t TimerManager::StartTimer(uint64_t timerId, uint64_t triggerTime)
260 {
261     std::shared_ptr<TimerEntry> timerInfo;
262     {
263         std::lock_guard<std::mutex> lock(entryMapMutex_);
264         auto it = timerEntryMap_.find(timerId);
265         if (it == timerEntryMap_.end()) {
266             TIME_HILOGE(TIME_MODULE_SERVICE, "Timer id not found: %{public}" PRId64 "", timerId);
267             return E_TIME_NOT_FOUND;
268         }
269         timerInfo = it->second;
270         TIME_HILOGI(TIME_MODULE_SERVICE,
271             "id: %{public}" PRIu64 " typ:%{public}d len: %{public}" PRId64 " int: %{public}" PRId64 " "
272             "flg :%{public}d trig: %{public}s uid:%{public}d pid:%{public}d",
273             timerId, timerInfo->type, timerInfo->windowLength, timerInfo->interval, timerInfo->flag,
274             std::to_string(triggerTime).c_str(), IPCSkeleton::GetCallingUid(), IPCSkeleton::GetCallingPid());
275         {
276             // To prevent the same ID from being started repeatedly,
277             // the later start overwrites the earlier start.
278             std::lock_guard<std::mutex> lock(mutex_);
279             RemoveLocked(timerId, false);
280         }
281         SetHandler(timerInfo->name, timerInfo->id, timerInfo->type, triggerTime, timerInfo->windowLength,
282             timerInfo->interval, timerInfo->flag, timerInfo->autoRestore, timerInfo->callback, timerInfo->wantAgent,
283             timerInfo->uid, timerInfo->pid, timerInfo->bundleName);
284     }
285     if (timerInfo->wantAgent) {
286         auto tableName = (CheckNeedRecoverOnReboot(timerInfo->bundleName, timerInfo->type, timerInfo->autoRestore)
287             ? HOLD_ON_REBOOT
288             : DROP_ON_REBOOT);
289         #ifdef RDB_ENABLE
290         OHOS::NativeRdb::ValuesBucket values;
291         values.PutInt("state", 1);
292         values.PutLong("triggerTime", static_cast<int64_t>(triggerTime));
293         OHOS::NativeRdb::RdbPredicates rdbPredicates(tableName);
294         rdbPredicates.EqualTo("state", 0)->And()->EqualTo("timerId", static_cast<int64_t>(timerId));
295         TimeDatabase::GetInstance().Update(values, rdbPredicates);
296         #else
297         CjsonHelper::GetInstance().UpdateTrigger(tableName, static_cast<int64_t>(timerId),
298             static_cast<int64_t>(triggerTime));
299         #endif
300     }
301     return E_TIME_OK;
302 }
303 
304 #ifndef RDB_ENABLE
StartTimerGroup(std::vector<std::pair<uint64_t,uint64_t>> timerVec,std::string tableName)305 int32_t TimerManager::StartTimerGroup(std::vector<std::pair<uint64_t, uint64_t>> timerVec, std::string tableName)
306 {
307     std::lock_guard<std::mutex> lock(entryMapMutex_);
308     for (auto iter = timerVec.begin(); iter != timerVec.end(); ++iter) {
309         uint64_t timerId = iter->first;
310         uint64_t triggerTime = iter->second;
311         std::shared_ptr<TimerEntry> timerInfo;
312         auto it = timerEntryMap_.find(timerId);
313         if (it == timerEntryMap_.end()) {
314             TIME_HILOGE(TIME_MODULE_SERVICE, "Timer id not found: %{public}" PRId64 "", timerId);
315             continue;
316         }
317         timerInfo = it->second;
318         TIME_HILOGI(TIME_MODULE_SERVICE,
319             "id: %{public}" PRIu64 " typ:%{public}d len: %{public}" PRId64 " int: %{public}" PRId64 " "
320             "flg :%{public}d trig: %{public}s uid:%{public}d pid:%{public}d",
321             timerId, timerInfo->type, timerInfo->windowLength, timerInfo->interval, timerInfo->flag,
322             std::to_string(triggerTime).c_str(), IPCSkeleton::GetCallingUid(), IPCSkeleton::GetCallingPid());
323         {
324             // To prevent the same ID from being started repeatedly,
325             // the later start overwrites the earlier start
326             std::lock_guard<std::mutex> lock(mutex_);
327             RemoveLocked(timerId, false);
328         }
329         SetHandler(timerInfo->name, timerInfo->id, timerInfo->type, triggerTime, timerInfo->windowLength,
330             timerInfo->interval, timerInfo->flag, timerInfo->autoRestore, timerInfo->callback, timerInfo->wantAgent,
331             timerInfo->uid, timerInfo->pid, timerInfo->bundleName);
332     }
333     CjsonHelper::GetInstance().UpdateTriggerGroup(tableName, timerVec);
334     return E_TIME_OK;
335 }
336 #endif
337 
IncreaseTimerCount(int uid)338 void TimerManager::IncreaseTimerCount(int uid)
339 {
340     auto it = std::find_if(timerCount_.begin(), timerCount_.end(),
341         [uid](const std::pair<int32_t, size_t>& pair) {
342             return pair.first == uid;
343         });
344     if (it == timerCount_.end()) {
345         timerCount_.push_back(std::make_pair(uid, 1));
346     } else {
347         it->second++;
348     }
349     CheckTimerCount();
350 }
351 
DecreaseTimerCount(int uid)352 void TimerManager::DecreaseTimerCount(int uid)
353 {
354     auto it = std::find_if(timerCount_.begin(), timerCount_.end(),
355         [uid](const std::pair<int32_t, size_t>& pair) {
356             return pair.first == uid;
357         });
358     if (it == timerCount_.end()) {
359         TIME_HILOGE(TIME_MODULE_SERVICE, "uid: %{public}d has no timer", uid);
360     } else {
361         it->second--;
362     }
363 }
364 
CheckTimerCount()365 void TimerManager::CheckTimerCount()
366 {
367     int count = static_cast<int>(timerEntryMap_.size());
368     if (count > (timerOutOfRangeTimes_ + 1) * TIMER_ALARM_COUNT) {
369         timerOutOfRangeTimes_ += 1;
370         TIME_HILOGI(TIME_MODULE_SERVICE, "%{public}d timer in system", count);
371         ShowTimerCountByUid(count);
372         lastTimerOutOfRangeTime_ = GetBootTimeNs();
373         return;
374     }
375     auto currentBootTime = GetBootTimeNs();
376     if (count > MAX_TIMER_ALARM_COUNT &&
377         currentBootTime - lastTimerOutOfRangeTime_ > std::chrono::minutes(TIMER_ALRAM_INTERVAL)) {
378         TIME_HILOGI(TIME_MODULE_SERVICE, "%{public}d timer in system", count);
379         ShowTimerCountByUid(count);
380         lastTimerOutOfRangeTime_ = currentBootTime;
381         return;
382     }
383 }
384 
ShowTimerCountByUid(int count)385 void TimerManager::ShowTimerCountByUid(int count)
386 {
387     std::string uidStr = "";
388     std::string countStr = "";
389     int uidArr[TIMER_COUNT_TOP_NUM];
390     int createTimerCountArr[TIMER_COUNT_TOP_NUM];
391     int startTimerCountArr[TIMER_COUNT_TOP_NUM];
392     auto size = static_cast<int>(timerCount_.size());
393     std::sort(timerCount_.begin(), timerCount_.end(),
394         [](const std::pair<int32_t, int32_t>& a, const std::pair<int32_t, int32_t>& b) {
395             return a.second > b.second;
396         });
397     auto limitedSize = (size > TIMER_COUNT_TOP_NUM) ? TIMER_COUNT_TOP_NUM : size;
398     int index = 0;
399     for (auto it = timerCount_.begin(); it != timerCount_.begin() + limitedSize; ++it) {
400         int uid = it->first;
401         int createTimerCount = it->second;
402         uidStr = uidStr + std::to_string(uid) + " ";
403         countStr = countStr + std::to_string(createTimerCount) + " ";
404         uidArr[index] = uid;
405         createTimerCountArr[index] = createTimerCount;
406         startTimerCountArr[index] = TimerProxy::GetInstance().CountUidTimerMapByUid(uid);
407         ++index;
408     }
409     TimerCountStaticReporter(count, uidArr, createTimerCountArr, startTimerCountArr);
410     TIME_HILOGI(TIME_MODULE_SERVICE, "Top uid:[%{public}s], nums:[%{public}s]", uidStr.c_str(), countStr.c_str());
411 }
412 
StopTimer(uint64_t timerId)413 int32_t TimerManager::StopTimer(uint64_t timerId)
414 {
415     return StopTimerInner(timerId, false);
416 }
417 
DestroyTimer(uint64_t timerId)418 int32_t TimerManager::DestroyTimer(uint64_t timerId)
419 {
420     return StopTimerInner(timerId, true);
421 }
422 
StopTimerInner(uint64_t timerNumber,bool needDestroy)423 int32_t TimerManager::StopTimerInner(uint64_t timerNumber, bool needDestroy)
424 {
425     TIME_HILOGI(TIME_MODULE_SERVICE, "id: %{public}" PRId64 ", needDestroy: %{public}d", timerNumber, needDestroy);
426     int32_t ret;
427     bool needRecover = false;
428     {
429         std::lock_guard<std::mutex> lock(entryMapMutex_);
430         ret = StopTimerInnerLocked(needDestroy, timerNumber, needRecover);
431     }
432     UpdateOrDeleteDatabase(needDestroy, timerNumber, needRecover);
433     return ret;
434 }
435 
436 // needs to acquire the lock `entryMapMutex_` before calling this method
StopTimerInnerLocked(bool needDestroy,uint64_t timerNumber,bool & needRecover)437 int32_t TimerManager::StopTimerInnerLocked(bool needDestroy, uint64_t timerNumber, bool &needRecover)
438 {
439     auto it = timerEntryMap_.find(timerNumber);
440     if (it == timerEntryMap_.end()) {
441         TIME_HILOGW(TIME_MODULE_SERVICE, "timer not exist");
442         return E_TIME_NOT_FOUND;
443     }
444     RemoveHandler(timerNumber);
445     TimerProxy::GetInstance().EraseTimerFromProxyTimerMap(timerNumber, it->second->uid, it->second->pid);
446     needRecover = CheckNeedRecoverOnReboot(it->second->bundleName, it->second->type, it->second->autoRestore);
447     if (needDestroy) {
448         auto uid = it->second->uid;
449         auto name = it->second->name;
450         timerEntryMap_.erase(it);
451         DecreaseTimerCount(uid);
452         if (name != "") {
453             DeleteTimerName(uid, name, timerNumber);
454         }
455     }
456     return E_TIME_OK;
457 }
458 
UpdateOrDeleteDatabase(bool needDestroy,uint64_t timerNumber,bool needRecover)459 void TimerManager::UpdateOrDeleteDatabase(bool needDestroy, uint64_t timerNumber, bool needRecover)
460 {
461     auto tableName = (needRecover ? HOLD_ON_REBOOT : DROP_ON_REBOOT);
462     if (needDestroy) {
463         #ifdef RDB_ENABLE
464         OHOS::NativeRdb::RdbPredicates rdbPredicatesDelete(tableName);
465         rdbPredicatesDelete.EqualTo("timerId", static_cast<int64_t>(timerNumber));
466         TimeDatabase::GetInstance().Delete(rdbPredicatesDelete);
467         #else
468         CjsonHelper::GetInstance().Delete(tableName, static_cast<int64_t>(timerNumber));
469         #endif
470     } else {
471         #ifdef RDB_ENABLE
472         OHOS::NativeRdb::ValuesBucket values;
473         values.PutInt("state", 0);
474         OHOS::NativeRdb::RdbPredicates rdbPredicates(tableName);
475         rdbPredicates.EqualTo("state", 1)->And()->EqualTo("timerId", static_cast<int64_t>(timerNumber));
476         TimeDatabase::GetInstance().Update(values, rdbPredicates);
477         #else
478         CjsonHelper::GetInstance().UpdateState(tableName, static_cast<int64_t>(timerNumber));
479         #endif
480     }
481 }
482 
SetHandler(std::string name,uint64_t id,int type,uint64_t triggerAtTime,int64_t windowLength,uint64_t interval,uint32_t flag,bool autoRestore,std::function<int32_t (const uint64_t)> callback,std::shared_ptr<OHOS::AbilityRuntime::WantAgent::WantAgent> wantAgent,int uid,int pid,const std::string & bundleName)483 void TimerManager::SetHandler(std::string name,
484                               uint64_t id,
485                               int type,
486                               uint64_t triggerAtTime,
487                               int64_t windowLength,
488                               uint64_t interval,
489                               uint32_t flag,
490                               bool autoRestore,
491                               std::function<int32_t (const uint64_t)> callback,
492                               std::shared_ptr<OHOS::AbilityRuntime::WantAgent::WantAgent> wantAgent,
493                               int uid,
494                               int pid,
495                               const std::string &bundleName)
496 {
497     auto windowLengthDuration = milliseconds(windowLength);
498     if (windowLengthDuration > INTERVAL_HALF_DAY) {
499         windowLengthDuration = INTERVAL_HOUR;
500     }
501     auto intervalDuration = milliseconds(interval > MAX_MILLISECOND ? MAX_MILLISECOND : interval);
502     if (intervalDuration > milliseconds::zero() && intervalDuration < MIN_INTERVAL_ONE_SECONDS) {
503         intervalDuration = MIN_INTERVAL_ONE_SECONDS;
504     } else if (intervalDuration > MAX_INTERVAL) {
505         intervalDuration = MAX_INTERVAL;
506     }
507 
508     auto nowElapsed = GetBootTimeNs();
509     auto when = milliseconds(triggerAtTime > MAX_MILLISECOND ? MAX_MILLISECOND : triggerAtTime);
510     auto nominalTrigger = ConvertToElapsed(when, type);
511     auto minTrigger = nowElapsed + ZERO_FUTURITY;
512     auto triggerElapsed = (nominalTrigger > minTrigger) ? nominalTrigger : minTrigger;
513 
514     steady_clock::time_point maxElapsed;
515     if (windowLengthDuration == milliseconds::zero()) {
516         maxElapsed = triggerElapsed;
517     } else if (windowLengthDuration < milliseconds::zero()) {
518         maxElapsed = MaxTriggerTime(nominalTrigger, triggerElapsed, intervalDuration);
519         windowLengthDuration = duration_cast<milliseconds>(maxElapsed - triggerElapsed);
520     } else {
521         maxElapsed = triggerElapsed + windowLengthDuration;
522     }
523     std::lock_guard<std::mutex> lockGuard(mutex_);
524     SetHandlerLocked(name,
525                      id,
526                      type,
527                      when,
528                      triggerElapsed,
529                      windowLengthDuration,
530                      maxElapsed,
531                      intervalDuration,
532                      std::move(callback),
533                      wantAgent,
534                      flag,
535                      autoRestore,
536                      uid,
537                      pid,
538                      bundleName);
539 }
540 
SetHandlerLocked(std::string name,uint64_t id,int type,std::chrono::milliseconds when,std::chrono::steady_clock::time_point whenElapsed,std::chrono::milliseconds windowLength,std::chrono::steady_clock::time_point maxWhen,std::chrono::milliseconds interval,std::function<int32_t (const uint64_t)> callback,const std::shared_ptr<OHOS::AbilityRuntime::WantAgent::WantAgent> & wantAgent,uint32_t flags,bool autoRestore,uint64_t callingUid,uint64_t callingPid,const std::string & bundleName)541 void TimerManager::SetHandlerLocked(std::string name, uint64_t id, int type,
542                                     std::chrono::milliseconds when,
543                                     std::chrono::steady_clock::time_point whenElapsed,
544                                     std::chrono::milliseconds windowLength,
545                                     std::chrono::steady_clock::time_point maxWhen,
546                                     std::chrono::milliseconds interval,
547                                     std::function<int32_t (const uint64_t)> callback,
548                                     const std::shared_ptr<OHOS::AbilityRuntime::WantAgent::WantAgent> &wantAgent,
549                                     uint32_t flags,
550                                     bool autoRestore,
551                                     uint64_t callingUid,
552                                     uint64_t callingPid,
553                                     const std::string &bundleName)
554 {
555     TIME_HILOGD(TIME_MODULE_SERVICE, "start id: %{public}" PRId64 "", id);
556     auto alarm = std::make_shared<TimerInfo>(name, id, type, when, whenElapsed, windowLength, maxWhen,
557                                              interval, std::move(callback), wantAgent, flags, autoRestore, callingUid,
558                                              callingPid, bundleName);
559     if (TimerProxy::GetInstance().IsProxy(alarm->uid, 0)) {
560         TIME_HILOGI(TIME_MODULE_SERVICE, "Timer already proxy, uid=%{public}" PRIu64 " id=%{public}" PRId64 "",
561             callingUid, alarm->id);
562         TimerProxy::GetInstance().RecordProxyTimerMap(alarm, false);
563         alarm->UpdateWhenElapsedFromNow(GetBootTimeNs(), milliseconds(TimerProxy::GetInstance().GetProxyDelayTime()));
564     }
565     if (TimerProxy::GetInstance().IsProxy(alarm->uid, alarm->pid)) {
566         TIME_HILOGI(TIME_MODULE_SERVICE, "Timer already proxy, pid=%{public}" PRIu64 " id=%{public}" PRId64 "",
567             callingPid, alarm->id);
568         TimerProxy::GetInstance().RecordProxyTimerMap(alarm, true);
569         alarm->UpdateWhenElapsedFromNow(GetBootTimeNs(), milliseconds(TimerProxy::GetInstance().GetProxyDelayTime()));
570     }
571 
572     SetHandlerLocked(alarm, false, false);
573     TIME_HILOGD(TIME_MODULE_SERVICE, "end");
574 }
575 
RemoveHandler(uint64_t id)576 void TimerManager::RemoveHandler(uint64_t id)
577 {
578     std::lock_guard<std::mutex> lock(mutex_);
579     RemoveLocked(id, true);
580     TimerProxy::GetInstance().RemoveUidTimerMap(id);
581 }
582 
583 // needs to acquire the lock `mutex_` before calling this method
RemoveLocked(uint64_t id,bool needReschedule)584 void TimerManager::RemoveLocked(uint64_t id, bool needReschedule)
585 {
586     auto whichAlarms = [id](const TimerInfo &timer) {
587         return timer.id == id;
588     };
589 
590     bool didRemove = false;
591     for (auto it = alarmBatches_.begin(); it != alarmBatches_.end();) {
592         auto batch = *it;
593         didRemove = batch->Remove(whichAlarms);
594         if (didRemove) {
595             TIME_HILOGI(TIME_MODULE_SERVICE, "remove id: %{public}" PRIu64 "", id);
596             it = alarmBatches_.erase(it);
597             if (batch->Size() != 0) {
598                 TIME_HILOGI(TIME_MODULE_SERVICE, "reorder batch");
599                 AddBatchLocked(alarmBatches_, batch);
600             }
601             break;
602         }
603         ++it;
604     }
605     pendingDelayTimers_.erase(remove_if(pendingDelayTimers_.begin(), pendingDelayTimers_.end(),
606         [id](const std::shared_ptr<TimerInfo> &timer) {
607             return timer->id == id;
608         }), pendingDelayTimers_.end());
609     delayedTimers_.erase(id);
610     if (mPendingIdleUntil_ != nullptr && id == mPendingIdleUntil_->id) {
611         TIME_HILOGI(TIME_MODULE_SERVICE, "Idle alarm removed");
612         mPendingIdleUntil_ = nullptr;
613         bool isAdjust = AdjustTimersBasedOnDeviceIdle();
614         delayedTimers_.clear();
615         for (const auto &pendingTimer : pendingDelayTimers_) {
616             TIME_HILOGI(TIME_MODULE_SERVICE, "Set timer from delay list, id=%{public}" PRId64 "", pendingTimer->id);
617             if (pendingTimer->whenElapsed <= GetBootTimeNs()) {
618                 // 2 means the time of performing task.
619                 pendingTimer->UpdateWhenElapsedFromNow(GetBootTimeNs(), milliseconds(2));
620             } else {
621                 pendingTimer->UpdateWhenElapsedFromNow(GetBootTimeNs(), pendingTimer->offset);
622             }
623             SetHandlerLocked(pendingTimer, false, false);
624         }
625         pendingDelayTimers_.clear();
626         if (isAdjust) {
627             ReBatchAllTimers();
628             return;
629         }
630     }
631 
632     if (needReschedule && didRemove) {
633         RescheduleKernelTimerLocked();
634     }
635 }
636 
637 // needs to acquire the lock `mutex_` before calling this method
SetHandlerLocked(std::shared_ptr<TimerInfo> alarm,bool rebatching,bool isRebatched)638 void TimerManager::SetHandlerLocked(std::shared_ptr<TimerInfo> alarm, bool rebatching, bool isRebatched)
639 {
640     TIME_HILOGD(TIME_MODULE_SERVICE, "start rebatching= %{public}d", rebatching);
641     TimerProxy::GetInstance().RecordUidTimerMap(alarm, isRebatched);
642 
643     if (!isRebatched && mPendingIdleUntil_ != nullptr && !CheckAllowWhileIdle(alarm)) {
644         TIME_HILOGI(TIME_MODULE_SERVICE, "Pending not-allowed alarm in idle state, id=%{public}" PRId64 "",
645             alarm->id);
646         alarm->offset = duration_cast<milliseconds>(alarm->whenElapsed - GetBootTimeNs());
647         pendingDelayTimers_.push_back(alarm);
648         return;
649     }
650     if (!rebatching) {
651         AdjustSingleTimer(alarm);
652     }
653     bool isAdjust = false;
654     if (!isRebatched && alarm->flags & static_cast<uint32_t>(IDLE_UNTIL)) {
655         TIME_HILOGI(TIME_MODULE_SERVICE, "Set idle timer, id=%{public}" PRId64 "", alarm->id);
656         mPendingIdleUntil_ = alarm;
657         isAdjust = AdjustTimersBasedOnDeviceIdle();
658     }
659     InsertAndBatchTimerLocked(std::move(alarm));
660     if (isAdjust) {
661         ReBatchAllTimers();
662         rebatching = true;
663     }
664     if (!rebatching) {
665         RescheduleKernelTimerLocked();
666     }
667 }
668 
669 // needs to acquire the lock `mutex_` before calling this method
ReBatchAllTimers()670 void TimerManager::ReBatchAllTimers()
671 {
672     auto oldSet = alarmBatches_;
673     alarmBatches_.clear();
674     auto nowElapsed = GetBootTimeNs();
675     for (const auto &batch : oldSet) {
676         auto n = batch->Size();
677         for (unsigned int i = 0; i < n; i++) {
678             ReAddTimerLocked(batch->Get(i), nowElapsed);
679         }
680     }
681     RescheduleKernelTimerLocked();
682 }
683 
ReAddTimerLocked(std::shared_ptr<TimerInfo> timer,std::chrono::steady_clock::time_point nowElapsed)684 void TimerManager::ReAddTimerLocked(std::shared_ptr<TimerInfo> timer,
685                                     std::chrono::steady_clock::time_point nowElapsed)
686 {
687     TIME_HILOGD(TIME_MODULE_SERVICE, "ReAddTimerLocked start. uid= %{public}d, id=%{public}" PRId64 ""
688         ", timer originMaxWhenElapsed=%{public}lld, whenElapsed=%{public}lld, now=%{public}lld",
689         timer->uid, timer->id, timer->originWhenElapsed.time_since_epoch().count(),
690         timer->whenElapsed.time_since_epoch().count(), GetBootTimeNs().time_since_epoch().count());
691     auto whenElapsed = ConvertToElapsed(timer->when, timer->type);
692     steady_clock::time_point maxElapsed;
693     if (timer->windowLength == milliseconds::zero()) {
694         maxElapsed = whenElapsed;
695     } else {
696         maxElapsed = (timer->windowLength > milliseconds::zero()) ?
697                      (whenElapsed + timer->windowLength) :
698                      MaxTriggerTime(nowElapsed, whenElapsed, timer->repeatInterval);
699     }
700     timer->whenElapsed = whenElapsed;
701     timer->maxWhenElapsed = maxElapsed;
702     SetHandlerLocked(timer, true, true);
703 }
704 
ConvertToElapsed(std::chrono::milliseconds when,int type)705 std::chrono::steady_clock::time_point TimerManager::ConvertToElapsed(std::chrono::milliseconds when, int type)
706 {
707     auto bootTimePoint = GetBootTimeNs();
708     if (type == RTC || type == RTC_WAKEUP) {
709         auto systemTimeNow = system_clock::now().time_since_epoch();
710         auto offset = when - systemTimeNow;
711         TIME_HILOGD(TIME_MODULE_SERVICE, "systemTimeNow : %{public}lld offset : %{public}lld",
712                     systemTimeNow.count(), offset.count());
713         return bootTimePoint + offset;
714     }
715     auto bootTimeNow = bootTimePoint.time_since_epoch();
716     auto offset = when - bootTimeNow;
717     TIME_HILOGD(TIME_MODULE_SERVICE, "bootTimeNow : %{public}lld offset : %{public}lld",
718                 bootTimeNow.count(), offset.count());
719     return bootTimePoint + offset;
720 }
721 
TimerLooper()722 void TimerManager::TimerLooper()
723 {
724     TIME_HILOGD(TIME_MODULE_SERVICE, "Start timer wait loop");
725     pthread_setname_np(pthread_self(), "timer_loop");
726     std::vector<std::shared_ptr<TimerInfo>> triggerList;
727     while (runFlag_) {
728         uint32_t result = handler_->WaitForAlarm();
729         auto nowRtc = std::chrono::system_clock::now();
730         auto nowElapsed = GetBootTimeNs();
731         triggerList.clear();
732 
733         if ((result & TIME_CHANGED_MASK) != 0) {
734             TIME_HILOGI(TIME_MODULE_SERVICE, "ret: %{public}u", result);
735             system_clock::time_point lastTimeChangeClockTime;
736             system_clock::time_point expectedClockTime;
737             std::lock_guard<std::mutex> lock(mutex_);
738             lastTimeChangeClockTime = lastTimeChangeClockTime_;
739             expectedClockTime = lastTimeChangeClockTime +
740                 (duration_cast<milliseconds>(nowElapsed.time_since_epoch()) -
741                 duration_cast<milliseconds>(lastTimeChangeRealtime_.time_since_epoch()));
742             if (lastTimeChangeClockTime == system_clock::time_point::min()
743                 || nowRtc < expectedClockTime
744                 || nowRtc > (expectedClockTime + milliseconds(ONE_THOUSAND))) {
745                 ReBatchAllTimers();
746                 lastTimeChangeClockTime_ = nowRtc;
747                 lastTimeChangeRealtime_ = nowElapsed;
748             }
749         }
750 
751         if (result != TIME_CHANGED_MASK) {
752             {
753                 std::lock_guard<std::mutex> lock(mutex_);
754                 TriggerTimersLocked(triggerList, nowElapsed);
755             }
756             // in this function, timeservice apply a runninglock from powermanager
757             // release mutex to prevent powermanager from using the interface of timeservice
758             // which may cause deadlock
759             DeliverTimersLocked(triggerList);
760             {
761                 std::lock_guard<std::mutex> lock(mutex_);
762                 RescheduleKernelTimerLocked();
763             }
764         }
765     }
766 }
767 
~TimerManager()768 TimerManager::~TimerManager()
769 {
770     if (alarmThread_ && alarmThread_->joinable()) {
771         runFlag_ = false;
772         alarmThread_->join();
773     }
774 }
775 
GetBootTimeNs()776 steady_clock::time_point TimerManager::GetBootTimeNs()
777 {
778     int64_t timeNow = -1;
779     struct timespec tv {};
780     if (clock_gettime(CLOCK_BOOTTIME, &tv) < 0) {
781         return steady_clock::now();
782     }
783     timeNow = tv.tv_sec * NANO_TO_SECOND + tv.tv_nsec;
784     steady_clock::time_point tp_epoch ((nanoseconds(timeNow)));
785     return tp_epoch;
786 }
787 
788 // needs to acquire the lock `mutex_` before calling this method
TriggerIdleTimer()789 void TimerManager::TriggerIdleTimer()
790 {
791     TIME_HILOGI(TIME_MODULE_SERVICE, "Idle alarm triggers");
792     mPendingIdleUntil_ = nullptr;
793     delayedTimers_.clear();
794     std::for_each(pendingDelayTimers_.begin(), pendingDelayTimers_.end(),
795         [this](const std::shared_ptr<TimerInfo> &pendingTimer) {
796             TIME_HILOGI(TIME_MODULE_SERVICE, "Set timer from delay list, id=%{public}" PRId64 "", pendingTimer->id);
797             if (pendingTimer->whenElapsed > GetBootTimeNs()) {
798                 pendingTimer->UpdateWhenElapsedFromNow(GetBootTimeNs(), pendingTimer->offset);
799             } else {
800                 // 2 means the time of performing task.
801                 pendingTimer->UpdateWhenElapsedFromNow(GetBootTimeNs(), milliseconds(2));
802             }
803             SetHandlerLocked(pendingTimer, false, false);
804         });
805     pendingDelayTimers_.clear();
806     ReBatchAllTimers();
807 }
808 
809 // needs to acquire the lock `mutex_` before calling this method
ProcTriggerTimer(std::shared_ptr<TimerInfo> & alarm,const std::chrono::steady_clock::time_point & nowElapsed)810 bool TimerManager::ProcTriggerTimer(std::shared_ptr<TimerInfo> &alarm,
811                                     const std::chrono::steady_clock::time_point &nowElapsed)
812 {
813     if (mPendingIdleUntil_ != nullptr && mPendingIdleUntil_->id == alarm->id) {
814         TriggerIdleTimer();
815     }
816     if (TimerProxy::GetInstance().IsProxy(alarm->uid, 0)
817         || TimerProxy::GetInstance().IsProxy(alarm->uid, alarm->pid)) {
818         alarm->UpdateWhenElapsedFromNow(nowElapsed, milliseconds(TimerProxy::GetInstance().GetProxyDelayTime()));
819         SetHandlerLocked(alarm, false, false);
820         return false;
821     } else {
822         HandleRepeatTimer(alarm, nowElapsed);
823         return true;
824     }
825 }
826 
827 // needs to acquire the lock `mutex_` before calling this method
TriggerTimersLocked(std::vector<std::shared_ptr<TimerInfo>> & triggerList,std::chrono::steady_clock::time_point nowElapsed)828 bool TimerManager::TriggerTimersLocked(std::vector<std::shared_ptr<TimerInfo>> &triggerList,
829                                        std::chrono::steady_clock::time_point nowElapsed)
830 {
831     bool hasWakeup = false;
832     TIME_HILOGD(TIME_MODULE_SERVICE, "current time %{public}lld", GetBootTimeNs().time_since_epoch().count());
833 
834     for (auto iter = alarmBatches_.begin(); iter != alarmBatches_.end();) {
835         if (*iter == nullptr) {
836             TIME_HILOGE(TIME_MODULE_SERVICE, "alarmBatches_ has nullptr");
837             iter = alarmBatches_.erase(iter);
838             continue;
839         }
840         if ((*iter)->GetStart() > nowElapsed) {
841             ++iter;
842             continue;
843         }
844         auto batch = *iter;
845         iter = alarmBatches_.erase(iter);
846         TIME_HILOGD(
847             TIME_MODULE_SERVICE, "batch size= %{public}d", static_cast<int>(alarmBatches_.size()));
848         const auto n = batch->Size();
849         for (unsigned int i = 0; i < n; ++i) {
850             auto alarm = batch->Get(i);
851             triggerList.push_back(alarm);
852             TIME_SIMPLIFY_HILOGW(TIME_MODULE_SERVICE, "uid: %{public}d id:%{public}" PRId64 " name:%{public}s"
853                 " wk:%{public}u",
854                 alarm->uid, alarm->id, alarm->bundleName.c_str(), alarm->wakeup);
855 
856             if (alarm->wakeup) {
857                 hasWakeup = true;
858             }
859         }
860     }
861     for (auto iter = triggerList.begin(); iter != triggerList.end();) {
862         auto alarm = *iter;
863         if (!ProcTriggerTimer(alarm, nowElapsed)) {
864             iter = triggerList.erase(iter);
865         } else {
866             ++iter;
867         }
868     }
869 
870     std::sort(triggerList.begin(), triggerList.end(),
871         [](const std::shared_ptr<TimerInfo> &l, const std::shared_ptr<TimerInfo> &r) {
872             return l->whenElapsed < r->whenElapsed;
873         });
874 
875     return hasWakeup;
876 }
877 
878 // needs to acquire the lock `mutex_` before calling this method
RescheduleKernelTimerLocked()879 void TimerManager::RescheduleKernelTimerLocked()
880 {
881     auto bootTime = GetBootTimeNs();
882     if (!alarmBatches_.empty()) {
883         auto firstWakeup = FindFirstWakeupBatchLocked();
884         auto firstBatch = alarmBatches_.front();
885         if (firstWakeup != nullptr) {
886             #ifdef POWER_MANAGER_ENABLE
887             HandleRunningLock(firstWakeup);
888             #endif
889             auto setTimePoint = firstWakeup->GetStart().time_since_epoch();
890             if (setTimePoint < bootTime.time_since_epoch() ||
891                 setTimePoint.count() != lastSetTime_[ELAPSED_REALTIME_WAKEUP]) {
892                 SetLocked(ELAPSED_REALTIME_WAKEUP, setTimePoint, bootTime);
893                 lastSetTime_[ELAPSED_REALTIME_WAKEUP] = setTimePoint.count();
894             }
895         }
896         if (firstBatch != firstWakeup) {
897             auto setTimePoint = firstBatch->GetStart().time_since_epoch();
898             if (setTimePoint < bootTime.time_since_epoch() || setTimePoint.count() != lastSetTime_[ELAPSED_REALTIME]) {
899                 SetLocked(ELAPSED_REALTIME, setTimePoint, bootTime);
900                 lastSetTime_[ELAPSED_REALTIME] = setTimePoint.count();
901             }
902         }
903     }
904 }
905 
906 // needs to acquire the lock `mutex_` before calling this method
FindFirstWakeupBatchLocked()907 std::shared_ptr<Batch> TimerManager::FindFirstWakeupBatchLocked()
908 {
909     auto it = std::find_if(alarmBatches_.begin(),
910                            alarmBatches_.end(),
911                            [](const std::shared_ptr<Batch> &batch) {
912                                return batch->HasWakeups();
913                            });
914     return (it != alarmBatches_.end()) ? *it : nullptr;
915 }
916 
SetLocked(int type,std::chrono::nanoseconds when,std::chrono::steady_clock::time_point bootTime)917 void TimerManager::SetLocked(int type, std::chrono::nanoseconds when, std::chrono::steady_clock::time_point bootTime)
918 {
919     if (when.count() <= 0) {
920         when = bootTime.time_since_epoch();
921     }
922     handler_->Set(static_cast<uint32_t>(type), when, bootTime);
923 }
924 
925 // needs to acquire the lock `mutex_` before calling this method
InsertAndBatchTimerLocked(std::shared_ptr<TimerInfo> alarm)926 void TimerManager::InsertAndBatchTimerLocked(std::shared_ptr<TimerInfo> alarm)
927 {
928     int64_t whichBatch = (alarm->flags & static_cast<uint32_t>(STANDALONE)) ?
929                          -1 :
930                          AttemptCoalesceLocked(alarm->whenElapsed, alarm->maxWhenElapsed);
931     TIME_SIMPLIFY_HILOGW(TIME_MODULE_SERVICE, "bat: %{public}" PRId64 " id:%{public}" PRIu64 " "
932                          "we:%{public}lld mwe:%{public}lld",
933                          whichBatch, alarm->id, alarm->whenElapsed.time_since_epoch().count(),
934                          alarm->maxWhenElapsed.time_since_epoch().count());
935     if (whichBatch < 0) {
936         AddBatchLocked(alarmBatches_, std::make_shared<Batch>(*alarm));
937     } else {
938         auto batch = alarmBatches_.at(whichBatch);
939         if (batch->Add(alarm)) {
940             alarmBatches_.erase(alarmBatches_.begin() + whichBatch);
941             AddBatchLocked(alarmBatches_, batch);
942         }
943     }
944 }
945 
946 // needs to acquire the lock `mutex_` before calling this method
AttemptCoalesceLocked(std::chrono::steady_clock::time_point whenElapsed,std::chrono::steady_clock::time_point maxWhen)947 int64_t TimerManager::AttemptCoalesceLocked(std::chrono::steady_clock::time_point whenElapsed,
948                                             std::chrono::steady_clock::time_point maxWhen)
949 {
950     auto it = std::find_if(alarmBatches_.begin(), alarmBatches_.end(),
951         [whenElapsed, maxWhen](const std::shared_ptr<Batch> &batch) {
952             return (batch->GetFlags() & static_cast<uint32_t>(STANDALONE)) == 0 &&
953                    (batch->CanHold(whenElapsed, maxWhen));
954         });
955     if (it != alarmBatches_.end()) {
956         return std::distance(alarmBatches_.begin(), it);
957     }
958     return -1;
959 }
960 
NotifyWantAgentRetry(std::shared_ptr<TimerInfo> timer)961 void TimerManager::NotifyWantAgentRetry(std::shared_ptr<TimerInfo> timer)
962 {
963     auto retryRegister = [timer]() {
964         for (int i = 0; i < WANT_RETRY_TIMES; i++) {
965             sleep(WANT_RETRY_INTERVAL << i);
966             if (TimerManager::GetInstance()->NotifyWantAgent(timer)) {
967                 return;
968             }
969             TIME_HILOGI(TIME_MODULE_SERVICE, "retry trigWA:times:%{public}d id=%{public}" PRId64 "", i, timer->id);
970         }
971     };
972     std::thread thread(retryRegister);
973     thread.detach();
974 }
975 
976 #ifdef MULTI_ACCOUNT_ENABLE
CheckUserIdForNotify(const std::shared_ptr<TimerInfo> & timer)977 int32_t TimerManager::CheckUserIdForNotify(const std::shared_ptr<TimerInfo> &timer)
978 {
979     auto bundleList = TimeFileUtils::GetParameterList(TIMER_ACROSS_ACCOUNTS);
980     if (!bundleList.empty() &&
981         std::find(bundleList.begin(), bundleList.end(), timer->bundleName) != bundleList.end()) {
982         return E_TIME_OK;
983     }
984     int userIdOfTimer = -1;
985     int foregroundUserId = -1;
986     int getLocalIdErr = AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(timer->uid, userIdOfTimer);
987     if (getLocalIdErr != ERR_OK) {
988         TIME_HILOGE(TIME_MODULE_SERVICE, "Get account id from uid failed, errcode: %{public}d", getLocalIdErr);
989         return E_TIME_ACCOUNT_ERROR;
990     }
991     int getForegroundIdErr = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(foregroundUserId);
992     if (getForegroundIdErr != ERR_OK) {
993         TIME_HILOGE(TIME_MODULE_SERVICE, "Get foreground account id failed, errcode: %{public}d", getForegroundIdErr);
994         return E_TIME_ACCOUNT_ERROR;
995     }
996     if (userIdOfTimer == foregroundUserId || userIdOfTimer == SYSTEM_USER_ID) {
997         return E_TIME_OK;
998     } else {
999         TIME_HILOGI(TIME_MODULE_SERVICE, "WA wait switch user, uid: %{public}d, timerId: %{public}" PRId64,
1000             timer->uid, timer->id);
1001         return E_TIME_ACCOUNT_NOT_MATCH;
1002     }
1003 }
1004 #endif
1005 
DeliverTimersLocked(const std::vector<std::shared_ptr<TimerInfo>> & triggerList)1006 void TimerManager::DeliverTimersLocked(const std::vector<std::shared_ptr<TimerInfo>> &triggerList)
1007 {
1008     auto wakeupNums = std::count_if(triggerList.begin(), triggerList.end(), [](auto timer) {return timer->wakeup;});
1009     if (wakeupNums > 0) {
1010         TimeServiceNotify::GetInstance().PublishTimerTriggerEvents();
1011     }
1012     for (const auto &timer : triggerList) {
1013         if (timer->wakeup) {
1014             #ifdef POWER_MANAGER_ENABLE
1015             AddRunningLock(USE_LOCK_ONE_SEC_IN_NANO);
1016             #endif
1017             TimerBehaviorReport(timer, false);
1018             StatisticReporter(wakeupNums, timer);
1019         }
1020         if (timer->callback) {
1021             if (TimerProxy::GetInstance().CallbackAlarmIfNeed(timer) == PEER_END_DEAD
1022                 && !timer->wantAgent) {
1023                 DestroyTimer(timer->id);
1024                 continue;
1025             }
1026         }
1027         if (timer->wantAgent) {
1028             if (!NotifyWantAgent(timer) &&
1029                 CheckNeedRecoverOnReboot(timer->bundleName, timer->type, timer->autoRestore)) {
1030                 NotifyWantAgentRetry(timer);
1031             }
1032             if (timer->repeatInterval != milliseconds::zero()) {
1033                 continue;
1034             }
1035             auto tableName = (CheckNeedRecoverOnReboot(timer->bundleName, timer->type, timer->autoRestore)
1036                               ? HOLD_ON_REBOOT
1037                               : DROP_ON_REBOOT);
1038             #ifdef RDB_ENABLE
1039             OHOS::NativeRdb::ValuesBucket values;
1040             values.PutInt("state", 0);
1041             OHOS::NativeRdb::RdbPredicates rdbPredicates(tableName);
1042             rdbPredicates.EqualTo("state", 1)
1043                 ->And()
1044                 ->EqualTo("timerId", static_cast<int64_t>(timer->id));
1045             TimeDatabase::GetInstance().Update(values, rdbPredicates);
1046             #else
1047             CjsonHelper::GetInstance().UpdateState(tableName, static_cast<int64_t>(timer->id));
1048             #endif
1049         }
1050         if (((timer->flags & static_cast<uint32_t>(IS_DISPOSABLE)) > 0) &&
1051             (timer->repeatInterval == milliseconds::zero())) {
1052             DestroyTimer(timer->id);
1053         }
1054     }
1055 }
1056 
GetWantString(int64_t timerId)1057 std::string GetWantString(int64_t timerId)
1058 {
1059     #ifdef RDB_ENABLE
1060     OHOS::NativeRdb::RdbPredicates holdRdbPredicates(HOLD_ON_REBOOT);
1061     holdRdbPredicates.EqualTo("timerId", timerId);
1062     auto holdResultSet = TimeDatabase::GetInstance().Query(holdRdbPredicates, ALL_DATA);
1063     if (holdResultSet == nullptr || holdResultSet->GoToFirstRow() != OHOS::NativeRdb::E_OK) {
1064         TIME_HILOGE(TIME_MODULE_SERVICE, "db query failed nullptr");
1065         if (holdResultSet != nullptr) {
1066             holdResultSet->Close();
1067         }
1068         return "";
1069     }
1070     // Line 7 is 'wantAgent'
1071     auto wantStr = GetString(holdResultSet, 7);
1072     holdResultSet->Close();
1073     #else
1074     auto wantStr = CjsonHelper::GetInstance().QueryWant(HOLD_ON_REBOOT, timerId);
1075     if (wantStr == "") {
1076         TIME_HILOGE(TIME_MODULE_SERVICE, "db query failed");
1077         return "";
1078     }
1079     #endif
1080     return wantStr;
1081 }
1082 
NotifyWantAgent(const std::shared_ptr<TimerInfo> & timer)1083 bool TimerManager::NotifyWantAgent(const std::shared_ptr<TimerInfo> &timer)
1084 {
1085     auto wantAgent = timer->wantAgent;
1086     std::shared_ptr<AAFwk::Want> want = OHOS::AbilityRuntime::WantAgent::WantAgentHelper::GetWant(wantAgent);
1087     if (want == nullptr) {
1088         #ifdef MULTI_ACCOUNT_ENABLE
1089         switch (CheckUserIdForNotify(timer)) {
1090             case E_TIME_ACCOUNT_NOT_MATCH:
1091                 // No need to retry.
1092                 return true;
1093             case E_TIME_ACCOUNT_ERROR:
1094                 TIME_HILOGE(TIME_MODULE_SERVICE, "want is nullptr, id=%{public}" PRId64 "", timer->id);
1095                 return false;
1096             default:
1097                 break;
1098         }
1099         #endif
1100         auto wantStr = GetWantString(static_cast<int64_t>(timer->id));
1101         if (wantStr == "") {
1102             return false;
1103         }
1104         wantAgent = OHOS::AbilityRuntime::WantAgent::WantAgentHelper::FromString(wantStr);
1105         #ifdef MULTI_ACCOUNT_ENABLE
1106         switch (CheckUserIdForNotify(timer)) {
1107             case E_TIME_ACCOUNT_NOT_MATCH:
1108                 TIME_HILOGI(TIME_MODULE_SERVICE, "user sw after FS, id=%{public}" PRId64 "", timer->id);
1109                 // No need to retry.
1110                 return true;
1111             case E_TIME_ACCOUNT_ERROR:
1112                 TIME_HILOGE(TIME_MODULE_SERVICE, "want is nullptr, id=%{public}" PRId64 "", timer->id);
1113                 return false;
1114             default:
1115                 break;
1116         }
1117         #endif
1118         want = OHOS::AbilityRuntime::WantAgent::WantAgentHelper::GetWant(wantAgent);
1119         if (want == nullptr) {
1120             TIME_HILOGE(TIME_MODULE_SERVICE, "want is nullptr, id=%{public}" PRId64 "", timer->id);
1121             return false;
1122         }
1123     }
1124     OHOS::AbilityRuntime::WantAgent::TriggerInfo paramsInfo("", nullptr, want, WANTAGENT_CODE_ELEVEN);
1125     auto code = AbilityRuntime::WantAgent::WantAgentHelper::TriggerWantAgent(wantAgent, nullptr, paramsInfo);
1126     TIME_SIMPLIFY_HILOGW(TIME_MODULE_SERVICE, "trigWA ret: %{public}d", code);
1127     if (code != ERR_OK) {
1128         auto extraInfo = "timer id:" + std::to_string(timer->id);
1129         TimeServiceFaultReporter(ReportEventCode::TIMER_WANTAGENT_FAULT_REPORT, code, timer->uid, timer->bundleName,
1130             extraInfo);
1131     }
1132     return code == ERR_OK;
1133 }
1134 
1135 // needs to acquire the lock `mutex_` before calling this method
UpdateTimersState(std::shared_ptr<TimerInfo> & alarm,bool needRetrigger)1136 void TimerManager::UpdateTimersState(std::shared_ptr<TimerInfo> &alarm, bool needRetrigger)
1137 {
1138     if (needRetrigger) {
1139         RemoveLocked(alarm->id, false);
1140         AdjustSingleTimerLocked(alarm);
1141         InsertAndBatchTimerLocked(alarm);
1142         RescheduleKernelTimerLocked();
1143     } else {
1144         RemoveLocked(alarm->id, true);
1145         TimerProxy::GetInstance().RemoveUidTimerMapLocked(alarm);
1146         bool needRecover = CheckNeedRecoverOnReboot(alarm->bundleName, alarm->type, alarm->autoRestore);
1147         UpdateOrDeleteDatabase(false, alarm->id, needRecover);
1148     }
1149 }
1150 
AdjustTimer(bool isAdjust,uint32_t interval,uint32_t delta)1151 bool TimerManager::AdjustTimer(bool isAdjust, uint32_t interval, uint32_t delta)
1152 {
1153     std::lock_guard<std::mutex> lock(mutex_);
1154     if (adjustPolicy_ == isAdjust && adjustInterval_ == interval && adjustDelta_ == delta) {
1155         TIME_HILOGI(TIME_MODULE_SERVICE, "already deal timer adjust, flag: %{public}d", isAdjust);
1156         return false;
1157     }
1158     std::chrono::steady_clock::time_point now = GetBootTimeNs();
1159     adjustPolicy_ = isAdjust;
1160     adjustInterval_ = interval;
1161     adjustDelta_ = delta;
1162     auto callback = [this] (AdjustTimerCallback adjustTimer) {
1163         bool isChanged = false;
1164         auto nowElapsed = GetBootTimeNs();
1165         for (const auto &batch : alarmBatches_) {
1166             if (!batch) {
1167                 continue;
1168             }
1169             auto n = batch->Size();
1170             for (unsigned int i = 0; i < n; i++) {
1171                 auto timer = batch->Get(i);
1172                 ReCalcuOriWhenElapsed(timer, nowElapsed);
1173                 isChanged = adjustTimer(timer) || isChanged;
1174             }
1175         }
1176         if (isChanged) {
1177             TIME_HILOGI(TIME_MODULE_SERVICE, "timer adjust executing, policy: %{public}d", adjustPolicy_);
1178             ReBatchAllTimers();
1179         }
1180     };
1181 
1182     return TimerProxy::GetInstance().AdjustTimer(isAdjust, interval, now, delta, callback);
1183 }
1184 
ProxyTimer(int32_t uid,std::set<int> pidList,bool isProxy,bool needRetrigger)1185 bool TimerManager::ProxyTimer(int32_t uid, std::set<int> pidList, bool isProxy, bool needRetrigger)
1186 {
1187     std::set<int> failurePid;
1188     std::lock_guard<std::mutex> lock(mutex_);
1189     if (pidList.size() == 0) {
1190         return TimerProxy::GetInstance().ProxyTimer(uid, 0, isProxy, needRetrigger, GetBootTimeNs(),
1191             [this] (std::shared_ptr<TimerInfo> &alarm, bool needRetrigger) {
1192                 UpdateTimersState(alarm, needRetrigger);
1193             });
1194     }
1195     for (std::set<int>::iterator pid = pidList.begin(); pid != pidList.end(); ++pid) {
1196         if (!TimerProxy::GetInstance().ProxyTimer(uid, *pid, isProxy, needRetrigger, GetBootTimeNs(),
1197             [this] (std::shared_ptr<TimerInfo> &alarm, bool needRetrigger) {
1198                 UpdateTimersState(alarm, needRetrigger);
1199             })) {
1200             failurePid.insert(*pid);
1201         }
1202     }
1203     return (failurePid.size() == 0);
1204 }
1205 
ReCalcuOriWhenElapsed(std::shared_ptr<TimerInfo> timer,std::chrono::steady_clock::time_point nowElapsed)1206 void TimerManager::ReCalcuOriWhenElapsed(std::shared_ptr<TimerInfo> timer,
1207                                          std::chrono::steady_clock::time_point nowElapsed)
1208 {
1209     if (adjustPolicy_) {
1210         return;
1211     }
1212     auto whenElapsed = ConvertToElapsed(timer->origWhen, timer->type);
1213     steady_clock::time_point maxElapsed;
1214     if (timer->windowLength == milliseconds::zero()) {
1215         maxElapsed = whenElapsed;
1216     } else {
1217         maxElapsed = (timer->windowLength > milliseconds::zero()) ?
1218                      (whenElapsed + timer->windowLength) :
1219                      MaxTriggerTime(nowElapsed, whenElapsed, timer->repeatInterval);
1220     }
1221     timer->originWhenElapsed = whenElapsed;
1222     timer->originMaxWhenElapsed = maxElapsed;
1223 }
1224 
SetTimerExemption(const std::unordered_set<std::string> & nameArr,bool isExemption)1225 void TimerManager::SetTimerExemption(const std::unordered_set<std::string> &nameArr, bool isExemption)
1226 {
1227     std::lock_guard<std::mutex> lock(mutex_);
1228     TimerProxy::GetInstance().SetTimerExemption(nameArr, isExemption);
1229 }
1230 
AdjustSingleTimer(std::shared_ptr<TimerInfo> timer)1231 bool TimerManager::AdjustSingleTimer(std::shared_ptr<TimerInfo> timer)
1232 {
1233     if (!adjustPolicy_ || TimerProxy::GetInstance().IsProxy(timer->uid, 0)
1234         || TimerProxy::GetInstance().IsProxy(timer->uid, timer->pid)) {
1235         return false;
1236     }
1237     return TimerProxy::GetInstance().AdjustTimer(adjustPolicy_, adjustInterval_, GetBootTimeNs(), adjustDelta_,
1238         [this, timer] (AdjustTimerCallback adjustTimer) { adjustTimer(timer); });
1239 }
1240 
1241 // needs to acquire the lock `proxyMutex_` before calling this method
AdjustSingleTimerLocked(std::shared_ptr<TimerInfo> timer)1242 bool TimerManager::AdjustSingleTimerLocked(std::shared_ptr<TimerInfo> timer)
1243 {
1244     if (!adjustPolicy_|| TimerProxy::GetInstance().IsProxyLocked(timer->uid, 0)
1245         || TimerProxy::GetInstance().IsProxyLocked(timer->uid, timer->pid)) {
1246         return false;
1247     }
1248     return TimerProxy::GetInstance().AdjustTimer(adjustPolicy_, adjustInterval_, GetBootTimeNs(), adjustDelta_,
1249         [this, timer] (AdjustTimerCallback adjustTimer) { adjustTimer(timer); });
1250 }
1251 
ResetAllProxy()1252 bool TimerManager::ResetAllProxy()
1253 {
1254     std::lock_guard<std::mutex> lock(mutex_);
1255     return TimerProxy::GetInstance().ResetAllProxy(GetBootTimeNs(),
1256         [this] (std::shared_ptr<TimerInfo> &alarm, bool needRetrigger) { UpdateTimersState(alarm, true); });
1257 }
1258 
CheckAllowWhileIdle(const std::shared_ptr<TimerInfo> & alarm)1259 bool TimerManager::CheckAllowWhileIdle(const std::shared_ptr<TimerInfo> &alarm)
1260 {
1261 #ifdef DEVICE_STANDBY_ENABLE
1262     if (TimePermission::CheckSystemUidCallingPermission(IPCSkeleton::GetCallingFullTokenID())) {
1263         std::vector<DevStandbyMgr::AllowInfo> restrictList;
1264         DevStandbyMgr::StandbyServiceClient::GetInstance().GetRestrictList(DevStandbyMgr::AllowType::TIMER,
1265             restrictList, REASON_APP_API);
1266         auto it = std::find_if(restrictList.begin(), restrictList.end(),
1267             [&alarm](const DevStandbyMgr::AllowInfo &allowInfo) { return allowInfo.GetName() == alarm->bundleName; });
1268         if (it != restrictList.end()) {
1269             return false;
1270         }
1271     }
1272 
1273     if (TimePermission::CheckProxyCallingPermission()) {
1274         pid_t pid = IPCSkeleton::GetCallingPid();
1275         std::string procName = TimeFileUtils::GetNameByPid(pid);
1276         if (alarm->flags & static_cast<uint32_t>(INEXACT_REMINDER)) {
1277             return false;
1278         }
1279         std::vector<DevStandbyMgr::AllowInfo> restrictList;
1280         DevStandbyMgr::StandbyServiceClient::GetInstance().GetRestrictList(DevStandbyMgr::AllowType::TIMER,
1281             restrictList, REASON_NATIVE_API);
1282         auto it = std::find_if(restrictList.begin(), restrictList.end(),
1283             [procName](const DevStandbyMgr::AllowInfo &allowInfo) { return allowInfo.GetName() == procName; });
1284         if (it != restrictList.end()) {
1285             return false;
1286         }
1287     }
1288 #endif
1289     return true;
1290 }
1291 
1292 // needs to acquire the lock `mutex_` before calling this method
AdjustDeliveryTimeBasedOnDeviceIdle(const std::shared_ptr<TimerInfo> & alarm)1293 bool TimerManager::AdjustDeliveryTimeBasedOnDeviceIdle(const std::shared_ptr<TimerInfo> &alarm)
1294 {
1295     TIME_HILOGD(TIME_MODULE_SERVICE, "start adjust timer, uid=%{public}d, id=%{public}" PRId64 "",
1296         alarm->uid, alarm->id);
1297     if (mPendingIdleUntil_ == alarm) {
1298         return false;
1299     }
1300     if (mPendingIdleUntil_ == nullptr) {
1301         auto itMap = delayedTimers_.find(alarm->id);
1302         if (itMap != delayedTimers_.end()) {
1303             std::chrono::milliseconds currentTime;
1304             if (alarm->type == RTC || alarm->type == RTC_WAKEUP) {
1305                 currentTime = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
1306             } else {
1307                 currentTime = duration_cast<milliseconds>(GetBootTimeNs().time_since_epoch());
1308             }
1309 
1310             if (alarm->origWhen > currentTime) {
1311                 auto offset = alarm->origWhen - currentTime;
1312                 return alarm->UpdateWhenElapsedFromNow(GetBootTimeNs(), offset);
1313             }
1314             // 2 means the time of performing task.
1315             return alarm->UpdateWhenElapsedFromNow(GetBootTimeNs(), milliseconds(2));
1316         }
1317         return false;
1318     }
1319 
1320     if (CheckAllowWhileIdle(alarm)) {
1321         TIME_HILOGD(TIME_MODULE_SERVICE, "Timer unrestricted, not adjust. id=%{public}" PRId64 "", alarm->id);
1322         return false;
1323     } else if (alarm->whenElapsed > mPendingIdleUntil_->whenElapsed) {
1324         TIME_HILOGD(TIME_MODULE_SERVICE, "Timer not allowed, not adjust. id=%{public}" PRId64 "", alarm->id);
1325         return false;
1326     } else {
1327         TIME_HILOGD(TIME_MODULE_SERVICE, "Timer not allowed, id=%{public}" PRId64 "", alarm->id);
1328         delayedTimers_[alarm->id] = alarm->whenElapsed;
1329         auto offset = ConvertToElapsed(mPendingIdleUntil_->when, mPendingIdleUntil_->type) - GetBootTimeNs();
1330         return alarm->UpdateWhenElapsedFromNow(GetBootTimeNs(), offset);
1331     }
1332 }
1333 
1334 // needs to acquire the lock `mutex_` before calling this method
AdjustTimersBasedOnDeviceIdle()1335 bool TimerManager::AdjustTimersBasedOnDeviceIdle()
1336 {
1337     TIME_HILOGD(TIME_MODULE_SERVICE, "start adjust alarmBatches_.size=%{public}d",
1338         static_cast<int>(alarmBatches_.size()));
1339     bool isAdjust = false;
1340     for (const auto &batch : alarmBatches_) {
1341         auto n = batch->Size();
1342         for (unsigned int i = 0; i < n; i++) {
1343             auto alarm = batch->Get(i);
1344             isAdjust = AdjustDeliveryTimeBasedOnDeviceIdle(alarm) || isAdjust;
1345         }
1346     }
1347     return isAdjust;
1348 }
1349 
1350 // needs to acquire the lock `mutex_` before calling this method
AddBatchLocked(std::vector<std::shared_ptr<Batch>> & list,const std::shared_ptr<Batch> & newBatch)1351 bool AddBatchLocked(std::vector<std::shared_ptr<Batch>> &list, const std::shared_ptr<Batch> &newBatch)
1352 {
1353     auto it = std::upper_bound(list.begin(),
1354                                list.end(),
1355                                newBatch,
1356                                [](const std::shared_ptr<Batch> &first, const std::shared_ptr<Batch> &second) {
1357                                    return first->GetStart() < second->GetStart();
1358                                });
1359     list.insert(it, newBatch);
1360     return it == list.begin();
1361 }
1362 
MaxTriggerTime(steady_clock::time_point now,steady_clock::time_point triggerAtTime,milliseconds interval)1363 steady_clock::time_point MaxTriggerTime(steady_clock::time_point now,
1364                                         steady_clock::time_point triggerAtTime,
1365                                         milliseconds interval)
1366 {
1367     milliseconds futurity = (interval == milliseconds::zero()) ?
1368                             (duration_cast<milliseconds>(triggerAtTime - now)) : interval;
1369     if (futurity < MIN_FUZZABLE_INTERVAL) {
1370         futurity = milliseconds::zero();
1371     }
1372     return triggerAtTime + milliseconds(static_cast<long>(BATCH_WINDOW_COE * futurity.count()));
1373 }
1374 
1375 #ifdef HIDUMPER_ENABLE
ShowTimerEntryMap(int fd)1376 bool TimerManager::ShowTimerEntryMap(int fd)
1377 {
1378     TIME_HILOGD(TIME_MODULE_SERVICE, "start");
1379     std::lock_guard<std::mutex> lock(entryMapMutex_);
1380     auto iter = timerEntryMap_.begin();
1381     for (; iter != timerEntryMap_.end(); iter++) {
1382         dprintf(fd, " - dump timer number   = %lu\n", iter->first);
1383         dprintf(fd, " * timer name          = %s\n", iter->second->name.c_str());
1384         dprintf(fd, " * timer id            = %lu\n", iter->second->id);
1385         dprintf(fd, " * timer type          = %d\n", iter->second->type);
1386         dprintf(fd, " * timer flag          = %u\n", iter->second->flag);
1387         dprintf(fd, " * timer window Length = %lld\n", iter->second->windowLength);
1388         dprintf(fd, " * timer interval      = %lu\n", iter->second->interval);
1389         dprintf(fd, " * timer uid           = %d\n\n", iter->second->uid);
1390     }
1391     TIME_HILOGD(TIME_MODULE_SERVICE, "end");
1392     return true;
1393 }
1394 
ShowTimerEntryById(int fd,uint64_t timerId)1395 bool TimerManager::ShowTimerEntryById(int fd, uint64_t timerId)
1396 {
1397     TIME_HILOGD(TIME_MODULE_SERVICE, "start");
1398     std::lock_guard<std::mutex> lock(entryMapMutex_);
1399     auto iter = timerEntryMap_.find(timerId);
1400     if (iter == timerEntryMap_.end()) {
1401         TIME_HILOGD(TIME_MODULE_SERVICE, "end");
1402         return false;
1403     } else {
1404         dprintf(fd, " - dump timer number   = %lu\n", iter->first);
1405         dprintf(fd, " * timer id            = %lu\n", iter->second->id);
1406         dprintf(fd, " * timer type          = %d\n", iter->second->type);
1407         dprintf(fd, " * timer window Length = %lld\n", iter->second->windowLength);
1408         dprintf(fd, " * timer interval      = %lu\n", iter->second->interval);
1409         dprintf(fd, " * timer uid           = %d\n\n", iter->second->uid);
1410     }
1411     TIME_HILOGD(TIME_MODULE_SERVICE, "end");
1412     return true;
1413 }
1414 
ShowTimerTriggerById(int fd,uint64_t timerId)1415 bool TimerManager::ShowTimerTriggerById(int fd, uint64_t timerId)
1416 {
1417     TIME_HILOGD(TIME_MODULE_SERVICE, "start");
1418     std::lock_guard<std::mutex> lock(mutex_);
1419     for (size_t i = 0; i < alarmBatches_.size(); i++) {
1420         for (size_t j = 0; j < alarmBatches_[i]->Size(); j++) {
1421             if (alarmBatches_[i]->Get(j)->id == timerId) {
1422                 dprintf(fd, " - dump timer id   = %lu\n", alarmBatches_[i]->Get(j)->id);
1423                 dprintf(fd, " * timer trigger   = %lld\n", alarmBatches_[i]->Get(j)->origWhen);
1424             }
1425         }
1426     }
1427     TIME_HILOGD(TIME_MODULE_SERVICE, "end");
1428     return true;
1429 }
1430 
ShowIdleTimerInfo(int fd)1431 bool TimerManager::ShowIdleTimerInfo(int fd)
1432 {
1433     TIME_HILOGD(TIME_MODULE_SERVICE, "start");
1434     std::lock_guard<std::mutex> lock(mutex_);
1435     dprintf(fd, " - dump idle state         = %d\n", (mPendingIdleUntil_ != nullptr));
1436     if (mPendingIdleUntil_ != nullptr) {
1437         dprintf(fd, " - dump idle timer id  = %lu\n", mPendingIdleUntil_->id);
1438         dprintf(fd, " * timer type          = %d\n", mPendingIdleUntil_->type);
1439         dprintf(fd, " * timer flag          = %u\n", mPendingIdleUntil_->flags);
1440         dprintf(fd, " * timer window Length = %lu\n", mPendingIdleUntil_->windowLength);
1441         dprintf(fd, " * timer interval      = %lu\n", mPendingIdleUntil_->repeatInterval);
1442         dprintf(fd, " * timer whenElapsed   = %lu\n", mPendingIdleUntil_->whenElapsed);
1443         dprintf(fd, " * timer uid           = %d\n\n", mPendingIdleUntil_->uid);
1444     }
1445     for (const auto &pendingTimer : pendingDelayTimers_) {
1446         dprintf(fd, " - dump pending delay timer id  = %lu\n", pendingTimer->id);
1447         dprintf(fd, " * timer type          = %d\n", pendingTimer->type);
1448         dprintf(fd, " * timer flag          = %u\n", pendingTimer->flags);
1449         dprintf(fd, " * timer window Length = %lu\n", pendingTimer->windowLength);
1450         dprintf(fd, " * timer interval      = %lu\n", pendingTimer->repeatInterval);
1451         dprintf(fd, " * timer whenElapsed   = %lu\n", pendingTimer->whenElapsed);
1452         dprintf(fd, " * timer uid           = %d\n\n", pendingTimer->uid);
1453     }
1454     for (const auto &delayedTimer : delayedTimers_) {
1455         dprintf(fd, " - dump delayed timer id = %lu\n", delayedTimer.first);
1456         dprintf(fd, " * timer whenElapsed     = %lu\n", delayedTimer.second);
1457     }
1458     TIME_HILOGD(TIME_MODULE_SERVICE, "end");
1459     return true;
1460 }
1461 #endif
1462 
1463 #ifdef MULTI_ACCOUNT_ENABLE
OnUserRemoved(int userId)1464 void TimerManager::OnUserRemoved(int userId)
1465 {
1466     TIME_HILOGI(TIME_MODULE_SERVICE, "Removed userId: %{public}d", userId);
1467     std::vector<std::shared_ptr<TimerEntry>> removeList;
1468     {
1469         std::lock_guard<std::mutex> lock(entryMapMutex_);
1470         for (auto it = timerEntryMap_.begin(); it != timerEntryMap_.end(); ++it) {
1471             int userIdOfTimer = -1;
1472             AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(it->second->uid, userIdOfTimer);
1473             if (userId == userIdOfTimer) {
1474                 removeList.push_back(it->second);
1475             }
1476         }
1477     }
1478     for (auto it = removeList.begin(); it != removeList.end(); ++it) {
1479         DestroyTimer((*it)->id);
1480     }
1481 }
1482 #endif
1483 
OnPackageRemoved(int uid)1484 void TimerManager::OnPackageRemoved(int uid)
1485 {
1486     TIME_HILOGI(TIME_MODULE_SERVICE, "Removed uid: %{public}d", uid);
1487     std::vector<std::shared_ptr<TimerEntry>> removeList;
1488     {
1489         std::lock_guard<std::mutex> lock(entryMapMutex_);
1490         for (auto it = timerEntryMap_.begin(); it != timerEntryMap_.end(); ++it) {
1491             if (it->second->uid == uid) {
1492                 removeList.push_back(it->second);
1493             }
1494         }
1495     }
1496     for (auto it = removeList.begin(); it != removeList.end(); ++it) {
1497         DestroyTimer((*it)->id);
1498     }
1499 }
1500 
HandleRSSDeath()1501 void TimerManager::HandleRSSDeath()
1502 {
1503     TIME_HILOGI(TIME_MODULE_CLIENT, "RSSSaDeathRecipient died");
1504     uint64_t id = 0;
1505     {
1506         std::lock_guard <std::mutex> lock(mutex_);
1507         if (mPendingIdleUntil_ != nullptr) {
1508             id = mPendingIdleUntil_->id;
1509         } else {
1510             return;
1511         }
1512     }
1513     StopTimerInner(id, true);
1514 }
1515 
HandleRepeatTimer(const std::shared_ptr<TimerInfo> & timer,std::chrono::steady_clock::time_point nowElapsed)1516 void TimerManager::HandleRepeatTimer(
1517     const std::shared_ptr<TimerInfo> &timer, std::chrono::steady_clock::time_point nowElapsed)
1518 {
1519     if (timer->repeatInterval > milliseconds::zero()) {
1520         uint64_t count = 1 + static_cast<uint64_t>(
1521             duration_cast<milliseconds>(nowElapsed - timer->whenElapsed) / timer->repeatInterval);
1522         auto delta = count * timer->repeatInterval;
1523         steady_clock::time_point nextElapsed = timer->whenElapsed + delta;
1524         steady_clock::time_point nextMaxElapsed = (timer->windowLength == milliseconds::zero()) ?
1525                                                   nextElapsed :
1526                                                   MaxTriggerTime(nowElapsed, nextElapsed, timer->repeatInterval);
1527         SetHandlerLocked(timer->name, timer->id, timer->type, timer->when + delta, nextElapsed, timer->windowLength,
1528             nextMaxElapsed, timer->repeatInterval, timer->callback, timer->wantAgent, timer->flags, timer->autoRestore,
1529             timer->uid, timer->pid, timer->bundleName);
1530     } else {
1531         TimerProxy::GetInstance().RemoveUidTimerMap(timer);
1532     }
1533 }
1534 
CheckNeedRecoverOnReboot(std::string bundleName,int type,bool autoRestore)1535 inline bool TimerManager::CheckNeedRecoverOnReboot(std::string bundleName, int type, bool autoRestore)
1536 {
1537     return ((std::find(NEED_RECOVER_ON_REBOOT.begin(), NEED_RECOVER_ON_REBOOT.end(), bundleName) !=
1538         NEED_RECOVER_ON_REBOOT.end() && (type == RTC || type == RTC_WAKEUP)) || autoRestore);
1539 }
1540 
1541 #ifdef POWER_MANAGER_ENABLE
1542 // needs to acquire the lock `mutex_` before calling this method
HandleRunningLock(const std::shared_ptr<Batch> & firstWakeup)1543 void TimerManager::HandleRunningLock(const std::shared_ptr<Batch> &firstWakeup)
1544 {
1545     auto currentTime = duration_cast<nanoseconds>(GetBootTimeNs().time_since_epoch()).count();
1546     auto nextTimerOffset =
1547         duration_cast<nanoseconds>(firstWakeup->GetStart().time_since_epoch()).count() - currentTime;
1548     auto lockOffset = currentTime - lockExpiredTime_;
1549     if (nextTimerOffset > 0 && nextTimerOffset <= USE_LOCK_TIME_IN_NANO &&
1550         ((lockOffset < 0 && std::abs(lockOffset) <= nextTimerOffset) || lockOffset >= 0)) {
1551         auto firstAlarm = firstWakeup->Get(0);
1552         if (firstAlarm == nullptr) {
1553             TIME_HILOGI(TIME_MODULE_SERVICE, "first alarm is null");
1554             return;
1555         }
1556         auto holdLockTime = nextTimerOffset + ONE_HUNDRED_MILLI;
1557         TIME_HILOGI(TIME_MODULE_SERVICE, "runningLock time:%{public}" PRIu64 ", timerId:%{public}"
1558                     PRIu64", uid:%{public}d  bundleName=%{public}s", static_cast<uint64_t>(holdLockTime),
1559                     firstAlarm->id, firstAlarm->uid, firstAlarm->bundleName.c_str());
1560         lockExpiredTime_ = currentTime + holdLockTime;
1561         AddRunningLock(holdLockTime);
1562     }
1563 }
1564 
AddRunningLockRetry(long long holdLockTime)1565 void TimerManager::AddRunningLockRetry(long long holdLockTime)
1566 {
1567     auto retryRegister = [this, holdLockTime]() {
1568         for (int i = 0; i < POWER_RETRY_TIMES; i++) {
1569             usleep(POWER_RETRY_INTERVAL);
1570             runningLock_->Lock(static_cast<int32_t>(holdLockTime / NANO_TO_MILLI));
1571             if (runningLock_->IsUsed()) {
1572                 return;
1573             }
1574         }
1575     };
1576     std::thread thread(retryRegister);
1577     thread.detach();
1578 }
1579 
AddRunningLock(long long holdLockTime)1580 void TimerManager::AddRunningLock(long long holdLockTime)
1581 {
1582     if (runningLock_ == nullptr) {
1583         std::lock_guard<std::mutex> lock(runningLockMutex_);
1584         if (runningLock_ == nullptr) {
1585             TIME_HILOGI(TIME_MODULE_SERVICE, "runningLock is nullptr, create runningLock");
1586             runningLock_ = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock("timeServiceRunningLock",
1587                 PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND_NOTIFICATION);
1588         }
1589     }
1590     if (runningLock_ != nullptr) {
1591         runningLock_->Lock(static_cast<int32_t>(holdLockTime / NANO_TO_MILLI));
1592         if (!runningLock_->IsUsed()) {
1593             AddRunningLockRetry(holdLockTime);
1594         }
1595     }
1596 }
1597 #endif
1598 } // MiscServices
1599 } // OHOS