1 /*
2 * Copyright (C) 2023-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 <cinttypes>
17
18 #include "timer_proxy.h"
19
20 namespace OHOS {
21 namespace MiscServices {
22 using namespace std::chrono;
23 using namespace OHOS::AppExecFwk;
24
25 namespace {
26 constexpr int MILLI_TO_SECOND = 1000;
27 constexpr int UID_PROXY_OFFSET = 32;
28 }
29
IMPLEMENT_SINGLE_INSTANCE(TimerProxy)30 IMPLEMENT_SINGLE_INSTANCE(TimerProxy)
31
32 uint64_t GetProxyKey(int uid, int pid)
33 {
34 uint64_t key = (static_cast<uint64_t>(uid) << UID_PROXY_OFFSET) | static_cast<uint64_t>(pid);
35 return key;
36 }
37
ParseProxyKey(uint64_t key)38 std::pair<int, int> ParseProxyKey(uint64_t key)
39 {
40 auto uid = static_cast<uint32_t>(key >> UID_PROXY_OFFSET);
41 auto pid = key & ((static_cast<uint64_t>(1) << UID_PROXY_OFFSET) - 1);
42 return std::make_pair(uid, pid);
43 }
44
CallbackAlarmIfNeed(const std::shared_ptr<TimerInfo> & alarm)45 int32_t TimerProxy::CallbackAlarmIfNeed(const std::shared_ptr<TimerInfo> &alarm)
46 {
47 if (alarm == nullptr) {
48 TIME_HILOGE(TIME_MODULE_SERVICE, "callback alarm is nullptr!");
49 return E_TIME_NULLPTR;
50 }
51 int32_t ret = alarm->callback(alarm->id);
52 TIME_SIMPLIFY_HILOGW(TIME_MODULE_SERVICE, "cb: %{public}" PRId64 " ret: %{public}d",
53 alarm->id, ret);
54 return ret;
55 }
56
ProxyTimer(int32_t uid,int pid,bool isProxy,bool needRetrigger,const std::chrono::steady_clock::time_point & now,std::function<void (std::shared_ptr<TimerInfo> & alarm,bool needRetrigger)> insertAlarmCallback)57 bool TimerProxy::ProxyTimer(int32_t uid, int pid, bool isProxy, bool needRetrigger,
58 const std::chrono::steady_clock::time_point &now,
59 std::function<void(std::shared_ptr<TimerInfo> &alarm, bool needRetrigger)> insertAlarmCallback)
60 {
61 TIME_HILOGD(TIME_MODULE_SERVICE, "start. pid=%{public}d, isProxy=%{public}u, needRetrigger=%{public}u",
62 pid, isProxy, needRetrigger);
63
64 std::lock_guard<std::mutex> lockProxy(proxyMutex_);
65 if (isProxy) {
66 UpdateProxyWhenElapsedForProxyTimers(uid, pid, now, insertAlarmCallback, needRetrigger);
67 return true;
68 }
69
70 if (!RestoreProxyWhenElapsedForProxyTimers(uid, pid, now, insertAlarmCallback, needRetrigger)) {
71 TIME_HILOGE(TIME_MODULE_SERVICE, "Pid: %{public}d doesn't exist in the proxy list" PRId64 "", pid);
72 return false;
73 }
74 return true;
75 }
76
AdjustTimer(bool isAdjust,uint32_t interval,const std::chrono::steady_clock::time_point & now,uint32_t delta,std::function<void (AdjustTimerCallback adjustTimer)> updateTimerDeliveries)77 bool TimerProxy::AdjustTimer(bool isAdjust, uint32_t interval,
78 const std::chrono::steady_clock::time_point &now, uint32_t delta,
79 std::function<void(AdjustTimerCallback adjustTimer)> updateTimerDeliveries)
80 {
81 std::lock_guard<std::mutex> lockProxy(adjustMutex_);
82 TIME_HILOGD(TIME_MODULE_SERVICE, "adjust timer state: %{public}d, interval: %{public}d, delta: %{public}d",
83 isAdjust, interval, delta);
84 auto callback = [=] (std::shared_ptr<TimerInfo> timer) {
85 if (timer == nullptr) {
86 TIME_HILOGE(TIME_MODULE_SERVICE, "adjust timer is nullptr!");
87 return false;
88 }
89 bool isOverdue = (now > timer->originWhenElapsed);
90 if (isAdjust && !isOverdue) {
91 return UpdateAdjustWhenElapsed(now, interval, delta, timer);
92 }
93 return RestoreAdjustWhenElapsed(timer);
94 };
95 updateTimerDeliveries(callback);
96 if (!isAdjust) {
97 adjustTimers_.clear();
98 }
99 return true;
100 }
101
UpdateAdjustWhenElapsed(const std::chrono::steady_clock::time_point & now,uint32_t interval,uint32_t delta,std::shared_ptr<TimerInfo> & timer)102 bool TimerProxy::UpdateAdjustWhenElapsed(const std::chrono::steady_clock::time_point &now,
103 uint32_t interval, uint32_t delta, std::shared_ptr<TimerInfo> &timer)
104 {
105 if (IsTimerExemption(timer)) {
106 TIME_HILOGD(TIME_MODULE_SERVICE, "adjust exemption timer bundleName: %{public}s",
107 timer->bundleName.c_str());
108 return false;
109 }
110 TIME_HILOGD(TIME_MODULE_SERVICE, "adjust single time id: %{public}" PRId64 ", "
111 "uid: %{public}d, bundleName: %{public}s",
112 timer->id, timer->uid, timer->bundleName.c_str());
113 adjustTimers_.push_back(timer);
114 return timer->AdjustTimer(now, interval, delta);
115 }
116
RestoreAdjustWhenElapsed(std::shared_ptr<TimerInfo> & timer)117 bool TimerProxy::RestoreAdjustWhenElapsed(std::shared_ptr<TimerInfo> &timer)
118 {
119 auto it = std::find_if(adjustTimers_.begin(),
120 adjustTimers_.end(),
121 [&timer](const std::shared_ptr<TimerInfo> &compareTimer) {
122 return compareTimer->id == timer->id;
123 });
124 if (it == adjustTimers_.end()) {
125 return false;
126 }
127 return timer->RestoreAdjustTimer();
128 }
129
SetTimerExemption(const std::unordered_set<std::string> & nameArr,bool isExemption)130 bool TimerProxy::SetTimerExemption(const std::unordered_set<std::string> &nameArr, bool isExemption)
131 {
132 std::lock_guard<std::mutex> lockProxy(adjustMutex_);
133 bool isChanged = false;
134 if (!isExemption) {
135 for (const auto &name : nameArr) {
136 adjustExemptionList_.erase(name);
137 }
138 return isChanged;
139 }
140 adjustExemptionList_.insert(nameArr.begin(), nameArr.end());
141 return isChanged;
142 }
143
IsTimerExemption(std::shared_ptr<TimerInfo> timer)144 bool TimerProxy::IsTimerExemption(std::shared_ptr<TimerInfo> timer)
145 {
146 auto key = timer->bundleName + "|" + timer->name;
147 TIME_HILOGD(TIME_MODULE_SERVICE, "key is: %{public}s", key.c_str());
148 if ((adjustExemptionList_.find(timer->bundleName) != adjustExemptionList_.end()
149 || adjustExemptionList_.find(key) != adjustExemptionList_.end())
150 && timer->windowLength == milliseconds::zero()) {
151 return true;
152 }
153 return false;
154 }
155
ResetAllProxy(const std::chrono::steady_clock::time_point & now,std::function<void (std::shared_ptr<TimerInfo> & alarm,bool needRetrigger)> insertAlarmCallback)156 bool TimerProxy::ResetAllProxy(const std::chrono::steady_clock::time_point &now,
157 std::function<void(std::shared_ptr<TimerInfo> &alarm, bool needRetrigger)> insertAlarmCallback)
158 {
159 TIME_HILOGD(TIME_MODULE_SERVICE, "start");
160 ResetAllProxyWhenElapsed(now, insertAlarmCallback);
161 return true;
162 }
163
EraseTimerFromProxyTimerMap(const uint64_t id,const int uid,const int pid)164 void TimerProxy::EraseTimerFromProxyTimerMap(const uint64_t id, const int uid, const int pid)
165 {
166 TIME_HILOGD(TIME_MODULE_SERVICE, "erase timer from proxy timer map, id=%{public}" PRId64 ", pid=%{public}u",
167 id, pid);
168 std::lock_guard<std::mutex> lock(proxyMutex_);
169 uint64_t key = GetProxyKey(uid, pid);
170 auto it = proxyTimers_.find(key);
171 if (it != proxyTimers_.end()) {
172 it->second.erase(std::remove_if(it->second.begin(), it->second.end(),
173 [id](uint64_t timerId) { return timerId == id; }), it->second.end());
174 }
175 }
176
EraseAlarmItem(const uint64_t id,std::unordered_map<uint64_t,std::shared_ptr<TimerInfo>> & idAlarmsMap)177 void TimerProxy::EraseAlarmItem(
178 const uint64_t id, std::unordered_map<uint64_t, std::shared_ptr<TimerInfo>> &idAlarmsMap)
179 {
180 auto itAlarms = idAlarmsMap.find(id);
181 if (itAlarms != idAlarmsMap.end()) {
182 TIME_HILOGD(TIME_MODULE_SERVICE, "timer already exists, id=%{public}" PRId64 "", id);
183 idAlarmsMap.erase(itAlarms);
184 }
185 }
186
CountUidTimerMapByUid(int32_t uid)187 int32_t TimerProxy::CountUidTimerMapByUid(int32_t uid)
188 {
189 std::lock_guard<std::mutex> lock(uidTimersMutex_);
190 auto it = uidTimersMap_.find(uid);
191 if (it == uidTimersMap_.end()) {
192 return 0;
193 }
194 return it->second.size();
195 }
196
RecordUidTimerMap(const std::shared_ptr<TimerInfo> & alarm,const bool isRebatched)197 void TimerProxy::RecordUidTimerMap(const std::shared_ptr<TimerInfo> &alarm, const bool isRebatched)
198 {
199 if (isRebatched) {
200 TIME_HILOGD(TIME_MODULE_SERVICE, "Record uid timer info map, isRebatched: %{public}d", isRebatched);
201 return;
202 }
203 if (alarm == nullptr) {
204 TIME_HILOGE(TIME_MODULE_SERVICE, "record uid timer map alarm is nullptr!");
205 return;
206 }
207
208 std::lock_guard<std::mutex> lock(uidTimersMutex_);
209 auto it = uidTimersMap_.find(alarm->uid);
210 if (it == uidTimersMap_.end()) {
211 std::unordered_map<uint64_t, std::shared_ptr<TimerInfo>> idAlarmsMap;
212 idAlarmsMap.insert(std::make_pair(alarm->id, alarm));
213 uidTimersMap_.insert(std::make_pair(alarm->uid, idAlarmsMap));
214 return;
215 }
216
217 EraseAlarmItem(alarm->id, it->second);
218 it->second.insert(std::make_pair(alarm->id, alarm));
219 }
220
RemoveUidTimerMap(const std::shared_ptr<TimerInfo> & alarm)221 void TimerProxy::RemoveUidTimerMap(const std::shared_ptr<TimerInfo> &alarm)
222 {
223 if (alarm == nullptr) {
224 TIME_HILOGE(TIME_MODULE_SERVICE, "remove uid timer map alarm is nullptr!");
225 return;
226 }
227
228 std::lock_guard<std::mutex> lock(uidTimersMutex_);
229 auto it = uidTimersMap_.find(alarm->uid);
230 if (it == uidTimersMap_.end()) {
231 return;
232 }
233
234 EraseAlarmItem(alarm->id, it->second);
235 if (it->second.empty()) {
236 uidTimersMap_.erase(it);
237 }
238 }
239
RemoveUidTimerMapLocked(const std::shared_ptr<TimerInfo> & alarm)240 void TimerProxy::RemoveUidTimerMapLocked(const std::shared_ptr<TimerInfo> &alarm)
241 {
242 if (alarm == nullptr) {
243 TIME_HILOGE(TIME_MODULE_SERVICE, "remove uid timer map alarm is nullptr!");
244 return;
245 }
246 auto it = uidTimersMap_.find(alarm->uid);
247 if (it == uidTimersMap_.end()) {
248 return;
249 }
250 EraseAlarmItem(alarm->id, it->second);
251 if (it->second.empty()) {
252 uidTimersMap_.erase(it);
253 }
254 }
255
RecordProxyTimerMap(const std::shared_ptr<TimerInfo> & alarm,bool isPid)256 void TimerProxy::RecordProxyTimerMap(const std::shared_ptr<TimerInfo> &alarm, bool isPid)
257 {
258 std::lock_guard<std::mutex> lock(proxyMutex_);
259 auto uid = alarm->uid;
260 auto pid = alarm->pid;
261 uint64_t key;
262 if (isPid) {
263 key = GetProxyKey(uid, pid);
264 } else {
265 key = GetProxyKey(uid, 0);
266 }
267 auto it = proxyTimers_.find(key);
268 if (it != proxyTimers_.end()) {
269 proxyTimers_[key].push_back(alarm->id);
270 } else {
271 proxyTimers_.insert(std::make_pair(key, std::vector<uint64_t>{alarm->id}));
272 }
273 }
274
RemoveUidTimerMap(const uint64_t id)275 void TimerProxy::RemoveUidTimerMap(const uint64_t id)
276 {
277 std::lock_guard<std::mutex> lock(uidTimersMutex_);
278 for (auto itUidsTimer = uidTimersMap_.begin(); itUidsTimer!= uidTimersMap_.end(); ++itUidsTimer) {
279 for (auto itTimerId = itUidsTimer->second.begin(); itTimerId!= itUidsTimer->second.end(); ++itTimerId) {
280 if (itTimerId->first != id) {
281 continue;
282 }
283
284 itUidsTimer->second.erase(itTimerId);
285 if (itUidsTimer->second.empty()) {
286 uidTimersMap_.erase(itUidsTimer);
287 }
288 return;
289 }
290 }
291 }
292
IsProxy(const int32_t uid,const int32_t pid)293 bool TimerProxy::IsProxy(const int32_t uid, const int32_t pid)
294 {
295 std::lock_guard<std::mutex> lock(proxyMutex_);
296 uint64_t key = GetProxyKey(uid, pid);
297 auto it = proxyTimers_.find(key);
298 if (it == proxyTimers_.end()) {
299 return false;
300 }
301 return true;
302 }
303
304 // needs to acquire the lock `proxyMutex_` before calling this method
IsProxyLocked(const int32_t uid,const int32_t pid)305 bool TimerProxy::IsProxyLocked(const int32_t uid, const int32_t pid)
306 {
307 uint64_t key = GetProxyKey(uid, pid);
308 auto it = proxyTimers_.find(key);
309 if (it == proxyTimers_.end()) {
310 return false;
311 }
312 return true;
313 }
314
UpdateProxyWhenElapsedForProxyTimers(int32_t uid,int pid,const std::chrono::steady_clock::time_point & now,std::function<void (std::shared_ptr<TimerInfo> & alarm,bool needRetrigger)> insertAlarmCallback,bool needRetrigger)315 void TimerProxy::UpdateProxyWhenElapsedForProxyTimers(int32_t uid, int pid,
316 const std::chrono::steady_clock::time_point &now,
317 std::function<void(std::shared_ptr<TimerInfo> &alarm, bool needRetrigger)> insertAlarmCallback,
318 bool needRetrigger)
319 {
320 uint64_t key = GetProxyKey(uid, pid);
321 auto it = proxyTimers_.find(key);
322 if (it != proxyTimers_.end()) {
323 TIME_HILOGD(TIME_MODULE_SERVICE, "uid:%{public}d pid: %{public}d is already proxy", uid, pid);
324 return;
325 }
326 std::lock_guard<std::mutex> lockUidTimers(uidTimersMutex_);
327 std::vector<uint64_t> timerList;
328 auto itUidTimersMap = uidTimersMap_.find(uid);
329 if (itUidTimersMap == uidTimersMap_.end()) {
330 TIME_HILOGD(TIME_MODULE_SERVICE, "uid: %{public}d in map not found", uid);
331 proxyTimers_[key] = timerList;
332 return;
333 }
334
335 for (auto itTimerInfo = itUidTimersMap->second.begin(); itTimerInfo!= itUidTimersMap->second.end();
336 ++itTimerInfo) {
337 if (pid == 0 || pid == itTimerInfo->second->pid) {
338 itTimerInfo->second->originProxyWhenElapsed = itTimerInfo->second->whenElapsed;
339 if (!needRetrigger) {
340 insertAlarmCallback(itTimerInfo->second, false);
341 break;
342 }
343 itTimerInfo->second->UpdateWhenElapsedFromNow(now, milliseconds(proxyDelayTime_));
344 TIME_HILOGD(TIME_MODULE_SERVICE, "Update proxy WhenElapsed for proxy pid map. "
345 "pid= %{public}d, id=%{public}" PRId64 ", timer whenElapsed=%{public}lld, now=%{public}lld",
346 itTimerInfo->second->pid, itTimerInfo->second->id,
347 itTimerInfo->second->whenElapsed.time_since_epoch().count(),
348 now.time_since_epoch().count());
349 insertAlarmCallback(itTimerInfo->second, true);
350 timerList.push_back(itTimerInfo->first);
351 }
352 }
353 proxyTimers_[key] = timerList;
354 }
355
RestoreProxyWhenElapsed(const int uid,const int pid,const std::chrono::steady_clock::time_point & now,std::function<void (std::shared_ptr<TimerInfo> & alarm,bool needRetrigger)> insertAlarmCallback,bool needRetrigger)356 bool TimerProxy::RestoreProxyWhenElapsed(const int uid, const int pid,
357 const std::chrono::steady_clock::time_point &now,
358 std::function<void(std::shared_ptr<TimerInfo> &alarm, bool needRetrigger)> insertAlarmCallback,
359 bool needRetrigger)
360 {
361 uint64_t key = GetProxyKey(uid, pid);
362 auto itProxy = proxyTimers_.find(key);
363 if (itProxy == proxyTimers_.end()) {
364 TIME_HILOGD(TIME_MODULE_SERVICE, "uid:%{public}d pid:%{public}d not in proxy", uid, pid);
365 return false;
366 }
367 std::lock_guard<std::mutex> lockPidTimers(uidTimersMutex_);
368 auto itTimer = uidTimersMap_.find(uid);
369 if (uidTimersMap_.find(uid) == uidTimersMap_.end()) {
370 TIME_HILOGD(TIME_MODULE_SERVICE, "uid:%{public}d timer info not found, erase proxy map", uid);
371 return true;
372 }
373
374 for (auto elem : itProxy->second) {
375 auto itTimerInfo = itTimer->second.find(elem);
376 if (itTimerInfo == itTimer->second.end()) {
377 continue;
378 }
379 auto originTriggerTime = itTimerInfo->second->originProxyWhenElapsed;
380 if (originTriggerTime > now + milliseconds(MILLI_TO_SECOND)) {
381 auto interval = std::chrono::duration_cast<std::chrono::nanoseconds>(originTriggerTime - now);
382 itTimerInfo->second->UpdateWhenElapsedFromNow(now, interval);
383 } else {
384 itTimerInfo->second->UpdateWhenElapsedFromNow(now, milliseconds(MILLI_TO_SECOND));
385 }
386 TIME_HILOGD(TIME_MODULE_SERVICE, "Restore proxy WhenElapsed by pid"
387 "pid= %{public}d, id=%{public}" PRId64 ", timer whenElapsed=%{public}lld, now=%{public}lld",
388 itTimerInfo->second->pid, itTimerInfo->second->id,
389 itTimerInfo->second->whenElapsed.time_since_epoch().count(),
390 now.time_since_epoch().count());
391 insertAlarmCallback(itTimerInfo->second, needRetrigger);
392 }
393 return true;
394 }
395
RestoreProxyWhenElapsedForProxyTimers(const int uid,const int pid,const std::chrono::steady_clock::time_point & now,std::function<void (std::shared_ptr<TimerInfo> & alarm,bool needRetrigger)> insertAlarmCallback,bool needRetrigger)396 bool TimerProxy::RestoreProxyWhenElapsedForProxyTimers(const int uid, const int pid,
397 const std::chrono::steady_clock::time_point &now,
398 std::function<void(std::shared_ptr<TimerInfo> &alarm, bool needRetrigger)> insertAlarmCallback,
399 bool needRetrigger)
400 {
401 uint64_t key = GetProxyKey(uid, pid);
402 bool ret = RestoreProxyWhenElapsed(uid, pid, now, insertAlarmCallback, needRetrigger);
403 if (ret) {
404 proxyTimers_.erase(key);
405 }
406 return ret;
407 }
408
ResetAllProxyWhenElapsed(const std::chrono::steady_clock::time_point & now,std::function<void (std::shared_ptr<TimerInfo> & alarm,bool needRetrigger)> insertAlarmCallback)409 void TimerProxy::ResetAllProxyWhenElapsed(const std::chrono::steady_clock::time_point &now,
410 std::function<void(std::shared_ptr<TimerInfo> &alarm, bool needRetrigger)> insertAlarmCallback)
411 {
412 std::lock_guard<std::mutex> lockProxy(proxyMutex_);
413 for (auto it = proxyTimers_.begin(); it != proxyTimers_.end(); ++it) {
414 auto resPair = ParseProxyKey(it->first);
415 RestoreProxyWhenElapsed(resPair.first, resPair.second, now, insertAlarmCallback, true);
416 }
417 proxyTimers_.clear();
418 }
419
420 #ifdef HIDUMPER_ENABLE
ShowProxyTimerInfo(int fd,const int64_t now)421 bool TimerProxy::ShowProxyTimerInfo(int fd, const int64_t now)
422 {
423 TIME_HILOGD(TIME_MODULE_SERVICE, "start");
424 std::lock_guard<std::mutex> lockPidProxy(proxyMutex_);
425 dprintf(fd, "current time %lld\n", now);
426 for (auto itProxyPids = proxyTimers_.begin(); itProxyPids != proxyTimers_.end(); ++itProxyPids) {
427 auto resPair = ParseProxyKey(itProxyPids->first);
428 dprintf(fd, " - proxy uid = %lu pid = %lu\n", resPair.first, resPair.second);
429 for (auto elem : itProxyPids->second) {
430 dprintf(fd, " * save timer id = %llu\n", elem);
431 }
432 }
433 TIME_HILOGD(TIME_MODULE_SERVICE, "end");
434 return true;
435 }
436
ShowUidTimerMapInfo(int fd,const int64_t now)437 bool TimerProxy::ShowUidTimerMapInfo(int fd, const int64_t now)
438 {
439 TIME_HILOGD(TIME_MODULE_SERVICE, "start");
440 std::lock_guard<std::mutex> lockProxy(uidTimersMutex_);
441 dprintf(fd, "current time %lld\n", now);
442 for (auto itTimerInfoMap = uidTimersMap_.begin(); itTimerInfoMap != uidTimersMap_.end(); ++itTimerInfoMap) {
443 dprintf(fd, " - uid = %lu\n", itTimerInfoMap->first);
444 for (auto itTimerInfo = itTimerInfoMap->second.begin(); itTimerInfo != itTimerInfoMap->second.end();
445 ++itTimerInfo) {
446 dprintf(fd, " * timer id = %llu\n", itTimerInfo->second->id);
447 dprintf(fd, " * timer whenElapsed = %lld\n", itTimerInfo->second->whenElapsed.time_since_epoch().count());
448 }
449 }
450 TIME_HILOGD(TIME_MODULE_SERVICE, "end");
451 return true;
452 }
453
ShowAdjustTimerInfo(int fd)454 void TimerProxy::ShowAdjustTimerInfo(int fd)
455 {
456 std::lock_guard<std::mutex> lockProxy(adjustMutex_);
457 dprintf(fd, "show adjust timer");
458 for (auto timer : adjustTimers_) {
459 dprintf(fd, " * timer id = %lu\n", timer->id);
460 dprintf(fd, " * timer uid = %d\n\n", timer->uid);
461 dprintf(fd, " * timer bundleName = %s\n\n", timer->bundleName.c_str());
462 dprintf(fd, " * timer originWhenElapsed = %lld\n\n", timer->originWhenElapsed);
463 dprintf(fd, " * timer whenElapsed = %lld\n\n", timer->whenElapsed);
464 dprintf(fd, " * timer originMaxWhenElapsed = %lld\n\n", timer->originMaxWhenElapsed);
465 dprintf(fd, " * timer maxWhenElapsed = %lld\n\n", timer->maxWhenElapsed);
466 }
467 }
468
ShowProxyDelayTime(int fd)469 bool TimerProxy::ShowProxyDelayTime(int fd)
470 {
471 TIME_HILOGD(TIME_MODULE_SERVICE, "start");
472 dprintf(fd, "proxy delay time: %lld ms\n", proxyDelayTime_);
473 TIME_HILOGD(TIME_MODULE_SERVICE, "end");
474 return true;
475 }
476 #endif
477
GetProxyDelayTime() const478 int64_t TimerProxy::GetProxyDelayTime() const
479 {
480 return proxyDelayTime_;
481 }
482 } // MiscServices
483 } // OHOS
484