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