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 ¶s)
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 ¶s,
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