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 ¶s)129 OHOS::NativeRdb::ValuesBucket GetInsertValues(std::shared_ptr<TimerEntry> timerInfo, TimerPara ¶s)
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 ¶s, 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 ¶s,
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