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 <string> 17#include <cinttypes> 18#include <algorithm> 19 20#include "timer_proxy.h" 21#include "time_hilog.h" 22 23namespace OHOS { 24namespace MiscServices { 25using namespace std::chrono; 26using namespace OHOS::AppExecFwk; 27 28namespace { 29constexpr int MILLI_TO_SECOND = 1000; 30} 31 32IMPLEMENT_SINGLE_INSTANCE(TimerProxy) 33 34void TimerProxy::RemoveProxy(uint64_t timerNumber, int32_t uid) 35{ 36 std::lock_guard<std::mutex> lock(proxyMutex_); 37 auto itMap = proxyMap_.find(uid); 38 if (itMap != proxyMap_.end()) { 39 auto alarms = &itMap->second; 40 for (auto itAlarm = alarms->begin(); itAlarm != alarms->end();) { 41 if ((*itAlarm)->id == timerNumber) { 42 itAlarm = alarms->erase(itAlarm); 43 } else { 44 itAlarm++; 45 } 46 } 47 if (alarms->empty()) { 48 proxyMap_.erase(uid); 49 } 50 } 51} 52 53void TimerProxy::RemovePidProxy(uint64_t timerNumber, int pid) 54{ 55 std::lock_guard<std::mutex> lock(proxyPidMutex_); 56 auto itMap = proxyPidMap_.find(pid); 57 if (itMap != proxyPidMap_.end()) { 58 auto alarms = &itMap->second; 59 for (auto itAlarm = alarms->begin(); itAlarm != alarms->end();) { 60 if ((*itAlarm)->id == timerNumber) { 61 itAlarm = alarms->erase(itAlarm); 62 } else { 63 itAlarm++; 64 } 65 } 66 if (alarms->empty()) { 67 proxyPidMap_.erase(pid); 68 } 69 } 70} 71 72int32_t TimerProxy::CallbackAlarmIfNeed(const std::shared_ptr<TimerInfo> &alarm) 73{ 74 if (alarm == nullptr) { 75 TIME_HILOGE(TIME_MODULE_SERVICE, "callback alarm is nullptr!"); 76 return E_TIME_NULLPTR; 77 } 78 79 int uid = alarm->uid; 80 int pid = alarm->pid; 81 { 82 std::lock_guard<std::mutex> lock(proxyMutex_); 83 auto uidIt = proxyUids_.find(uid); 84 if (uidIt != proxyUids_.end()) { 85 TIME_HILOGD(TIME_MODULE_SERVICE, "Alarm is uid proxy!"); 86 auto itMap = proxyMap_.find(uid); 87 if (itMap == proxyMap_.end()) { 88 std::vector<std::shared_ptr<TimerInfo>> timeInfoVec; 89 timeInfoVec.push_back(alarm); 90 proxyMap_[uid] = timeInfoVec; 91 } else { 92 std::vector<std::shared_ptr<TimerInfo>> timeInfoVec = itMap->second; 93 timeInfoVec.push_back(alarm); 94 proxyMap_[uid] = timeInfoVec; 95 } 96 return E_TIME_OK; 97 } 98 } 99 { 100 std::lock_guard<std::mutex> lock(proxyPidMutex_); 101 auto pidIt = proxyPids_.find(pid); 102 if (pidIt != proxyPids_.end()) { 103 TIME_HILOGD(TIME_MODULE_SERVICE, "Alarm is pid proxy!"); 104 auto itMap = proxyPidMap_.find(pid); 105 if (itMap == proxyPidMap_.end()) { 106 std::vector<std::shared_ptr<TimerInfo>> timeInfoVec; 107 timeInfoVec.push_back(alarm); 108 proxyPidMap_[pid] = timeInfoVec; 109 } else { 110 std::vector<std::shared_ptr<TimerInfo>> timeInfoVec = itMap->second; 111 timeInfoVec.push_back(alarm); 112 proxyPidMap_[pid] = timeInfoVec; 113 } 114 return E_TIME_OK; 115 } 116 } 117 int32_t ret = alarm->callback(alarm->id); 118 TIME_SIMPLIFY_HILOGI(TIME_MODULE_SERVICE, "cb: %{public}" PRId64 " ret: %{public}d", 119 alarm->id, ret); 120 return ret; 121} 122 123bool TimerProxy::ProxyTimer(int32_t uid, bool isProxy, bool needRetrigger, 124 const std::chrono::steady_clock::time_point &now, 125 std::function<void(std::shared_ptr<TimerInfo> &alarm)> insertAlarmCallback) 126{ 127 TIME_HILOGD(TIME_MODULE_SERVICE, "start. uid=%{public}d, isProxy=%{public}u, needRetrigger=%{public}u", 128 uid, isProxy, needRetrigger); 129 std::lock_guard<std::mutex> lockProxy(proxyMutex_); 130 if (isProxy) { 131 UpdateProxyWhenElapsedForProxyUidMap(uid, now, insertAlarmCallback); 132 return true; 133 } 134 if (!RestoreProxyWhenElapsedForProxyUidMap(uid, now, insertAlarmCallback)) { 135 TIME_HILOGE(TIME_MODULE_SERVICE, "Uid: %{public}d doesn't exist in the proxy list." PRId64 "", uid); 136 return false; 137 } 138 139 if (!needRetrigger) { 140 TIME_HILOGI(TIME_MODULE_SERVICE, "ProxyTimer doesn't need retrigger, clear all callbacks!"); 141 proxyMap_.erase(uid); 142 return true; 143 } 144 auto itMap = proxyMap_.find(uid); 145 if (itMap != proxyMap_.end()) { 146 auto timeInfoVec = itMap->second; 147 for (const auto& alarm : timeInfoVec) { 148 if (!alarm->callback) { 149 TIME_HILOGE(TIME_MODULE_SERVICE, "ProxyTimer Callback is nullptr!"); 150 continue; 151 } 152 alarm->callback(alarm->id); 153 TIME_HILOGD(TIME_MODULE_SERVICE, "Shut down proxy, proxyUid: %{public}d, alarmId: %{public}" PRId64 "", 154 uid, alarm->id); 155 } 156 timeInfoVec.clear(); 157 proxyMap_.erase(uid); 158 } 159 return true; 160} 161 162bool TimerProxy::PidProxyTimer(int pid, bool isProxy, bool needRetrigger, 163 const std::chrono::steady_clock::time_point &now, 164 std::function<void(std::shared_ptr<TimerInfo> &alarm)> insertAlarmCallback) 165{ 166 TIME_HILOGD(TIME_MODULE_SERVICE, "start. pid=%{public}d, isProxy=%{public}u, needRetrigger=%{public}u", 167 pid, isProxy, needRetrigger); 168 169 std::lock_guard<std::mutex> lockProxy(proxyPidMutex_); 170 if (isProxy) { 171 UpdateProxyWhenElapsedForProxyPidMap(pid, now, insertAlarmCallback); 172 return true; 173 } 174 175 if (!RestoreProxyWhenElapsedForProxyPidMap(pid, now, insertAlarmCallback)) { 176 TIME_HILOGE(TIME_MODULE_SERVICE, "Pid: %{public}d doesn't exist in the proxy list." PRId64 "", pid); 177 return false; 178 } 179 180 if (!needRetrigger) { 181 TIME_HILOGI(TIME_MODULE_SERVICE, "ProxyTimer doesn't need retrigger, clear all callbacks!"); 182 proxyPidMap_.erase(pid); 183 return true; 184 } 185 186 auto itMap = proxyPidMap_.find(pid); 187 if (itMap != proxyPidMap_.end()) { 188 auto timeInfoVec = itMap->second; 189 for (const auto& alarm : timeInfoVec) { 190 if (!alarm->callback) { 191 TIME_HILOGE(TIME_MODULE_SERVICE, "ProxyTimer Callback is nullptr!"); 192 continue; 193 } 194 alarm->callback(alarm->id); 195 TIME_HILOGD(TIME_MODULE_SERVICE, "Shut down proxy, proxyPid: %{public}d, alarmId: %{public}" PRId64 "", 196 pid, alarm->id); 197 } 198 timeInfoVec.clear(); 199 proxyPidMap_.erase(pid); 200 } 201 return true; 202} 203 204bool TimerProxy::AdjustTimer(bool isAdjust, uint32_t interval, 205 const std::chrono::steady_clock::time_point &now, 206 std::function<void(AdjustTimerCallback adjustTimer)> updateTimerDeliveries) 207{ 208 std::lock_guard<std::mutex> lockProxy(adjustMutex_); 209 TIME_HILOGD(TIME_MODULE_SERVICE, "adjust timer state: %{public}d, interval: %{public}d", isAdjust, interval); 210 auto callback = [this, isAdjust, interval, now] (std::shared_ptr<TimerInfo> timer) { 211 if (timer == nullptr) { 212 TIME_HILOGE(TIME_MODULE_SERVICE, "adjust timer is nullptr!"); 213 return false; 214 } 215 return isAdjust ? UpdateAdjustWhenElapsed(now, interval, timer) : RestoreAdjustWhenElapsed(timer); 216 }; 217 updateTimerDeliveries(callback); 218 if (!isAdjust) { 219 adjustTimers_.clear(); 220 } 221 return true; 222} 223 224bool TimerProxy::UpdateAdjustWhenElapsed(const std::chrono::steady_clock::time_point &now, 225 uint32_t interval, std::shared_ptr<TimerInfo> &timer) 226{ 227 if (IsTimerExemption(timer)) { 228 TIME_HILOGD(TIME_MODULE_SERVICE, "adjust exemption timer bundleName: %{public}s", 229 timer->bundleName.c_str()); 230 return false; 231 } 232 TIME_HILOGD(TIME_MODULE_SERVICE, "adjust single time id: %{public}" PRId64 ", " 233 "uid: %{public}d, bundleName: %{public}s", 234 timer->id, timer->uid, timer->bundleName.c_str()); 235 adjustTimers_.push_back(timer); 236 return timer->AdjustTimer(now, interval); 237} 238 239bool TimerProxy::RestoreAdjustWhenElapsed(std::shared_ptr<TimerInfo> &timer) 240{ 241 auto it = std::find_if(adjustTimers_.begin(), 242 adjustTimers_.end(), 243 [&timer](const std::shared_ptr<TimerInfo> &compareTimer) { 244 return compareTimer->id == timer->id; 245 }); 246 if (it == adjustTimers_.end()) { 247 return false; 248 } 249 return timer->RestoreAdjustTimer(); 250} 251 252bool TimerProxy::SetTimerExemption(const std::unordered_set<std::string> &nameArr, bool isExemption) 253{ 254 std::lock_guard<std::mutex> lockProxy(adjustMutex_); 255 bool isChanged = false; 256 if (!isExemption) { 257 for (const auto &name : nameArr) { 258 adjustExemptionList_.erase(name); 259 } 260 return isChanged; 261 } 262 adjustExemptionList_.insert(nameArr.begin(), nameArr.end()); 263 return isChanged; 264} 265 266bool TimerProxy::IsTimerExemption(std::shared_ptr<TimerInfo> timer) 267{ 268 if (adjustExemptionList_.find(timer->bundleName) != adjustExemptionList_.end() 269 && timer->windowLength == milliseconds::zero()) { 270 return true; 271 } 272 return false; 273} 274 275void TimerProxy::ResetProxyMaps() 276{ 277 std::lock_guard<std::mutex> lock(proxyMutex_); 278 for (auto it = proxyMap_.begin(); it != proxyMap_.end(); it++) { 279 auto timeInfoVec = it->second; 280 for (const auto& alarm : timeInfoVec) { 281 if (!alarm->callback) { 282 TIME_HILOGE(TIME_MODULE_SERVICE, "Callback is nullptr!"); 283 continue; 284 } 285 alarm->callback(alarm->id); 286 TIME_HILOGD(TIME_MODULE_SERVICE, "Reset all proxy, proxyUid: %{public}d, alarmId: %{public}" PRId64 "", 287 it->first, alarm->id); 288 } 289 timeInfoVec.clear(); 290 } 291 proxyMap_.clear(); 292} 293 294void TimerProxy::ResetProxyPidMaps() 295{ 296 std::lock_guard<std::mutex> lock(proxyPidMutex_); 297 for (auto it = proxyPidMap_.begin(); it != proxyPidMap_.end(); it++) { 298 auto timeInfoVec = it->second; 299 for (const auto& alarm : timeInfoVec) { 300 if (!alarm->callback) { 301 TIME_HILOGE(TIME_MODULE_SERVICE, "Callback is nullptr!"); 302 continue; 303 } 304 alarm->callback(alarm->id); 305 TIME_HILOGD(TIME_MODULE_SERVICE, "Reset all proxy, proxyPid: %{public}d, alarmId: %{public}" PRId64 "", 306 it->first, alarm->id); 307 } 308 timeInfoVec.clear(); 309 } 310 proxyPidMap_.clear(); 311} 312 313bool TimerProxy::ResetAllProxy(const std::chrono::steady_clock::time_point &now, 314 std::function<void(std::shared_ptr<TimerInfo> &alarm)> insertAlarmCallback) 315{ 316 TIME_HILOGD(TIME_MODULE_SERVICE, "start"); 317 ResetProxyMaps(); 318 ResetAllProxyWhenElapsed(now, insertAlarmCallback); 319 ResetProxyPidMaps(); 320 ResetAllPidProxyWhenElapsed(now, insertAlarmCallback); 321 return true; 322} 323 324void TimerProxy::EraseTimerFromProxyUidMap(const uint64_t id, const uint32_t uid) 325{ 326 TIME_HILOGD(TIME_MODULE_SERVICE, "erase timer from proxy timer map, id=%{public}" PRId64 ", uid=%{public}u", 327 id, uid); 328 std::lock_guard<std::mutex> lock(proxyMutex_); 329 auto it = proxyUids_.find(uid); 330 if (it != proxyUids_.end()) { 331 it->second.erase(id); 332 } 333} 334 335void TimerProxy::EraseTimerFromProxyPidMap(const uint64_t id, const int pid) 336{ 337 TIME_HILOGD(TIME_MODULE_SERVICE, "erase timer from proxy timer map, id=%{public}" PRId64 ", pid=%{public}u", 338 id, pid); 339 std::lock_guard<std::mutex> lock(proxyPidMutex_); 340 auto it = proxyPids_.find(pid); 341 if (it != proxyPids_.end()) { 342 it->second.erase(id); 343 } 344} 345 346void TimerProxy::EraseAlarmItem( 347 const uint64_t id, std::unordered_map<uint64_t, std::shared_ptr<TimerInfo>> &idAlarmsMap) 348{ 349 auto itAlarms = idAlarmsMap.find(id); 350 if (itAlarms != idAlarmsMap.end()) { 351 TIME_HILOGD(TIME_MODULE_SERVICE, "timer already exists, id=%{public}" PRId64 "", id); 352 idAlarmsMap.erase(itAlarms); 353 } 354} 355 356void TimerProxy::RecordUidTimerMap(const std::shared_ptr<TimerInfo> &alarm, const bool isRebatched) 357{ 358 if (isRebatched) { 359 TIME_HILOGD(TIME_MODULE_SERVICE, "Record uid timer info map, isRebatched: %{public}d", isRebatched); 360 return; 361 } 362 if (alarm == nullptr) { 363 TIME_HILOGE(TIME_MODULE_SERVICE, "record uid timer map alarm is nullptr!"); 364 return; 365 } 366 367 std::lock_guard<std::mutex> lock(uidTimersMutex_); 368 auto it = uidTimersMap_.find(alarm->uid); 369 if (it == uidTimersMap_.end()) { 370 std::unordered_map<uint64_t, std::shared_ptr<TimerInfo>> idAlarmsMap; 371 idAlarmsMap.insert(std::make_pair(alarm->id, alarm)); 372 uidTimersMap_.insert(std::make_pair(alarm->uid, idAlarmsMap)); 373 return; 374 } 375 376 EraseAlarmItem(alarm->id, it->second); 377 it->second.insert(std::make_pair(alarm->id, alarm)); 378} 379 380void TimerProxy::RecordPidTimerMap(const std::shared_ptr<TimerInfo> &alarm, const bool isRebatched) 381{ 382 if (isRebatched) { 383 TIME_HILOGD(TIME_MODULE_SERVICE, "Record pid timer info map, isRebatched: %{public}d", isRebatched); 384 return; 385 } 386 if (alarm == nullptr) { 387 TIME_HILOGE(TIME_MODULE_SERVICE, "record pid timer map alarm is nullptr!"); 388 return; 389 } 390 391 std::lock_guard<std::mutex> lock(pidTimersMutex_); 392 auto it = pidTimersMap_.find(alarm->pid); 393 if (it == pidTimersMap_.end()) { 394 std::unordered_map<uint64_t, std::shared_ptr<TimerInfo>> idAlarmsMap; 395 idAlarmsMap.insert(std::make_pair(alarm->id, alarm)); 396 pidTimersMap_.insert(std::make_pair(alarm->pid, idAlarmsMap)); 397 return; 398 } 399 400 EraseAlarmItem(alarm->id, it->second); 401 it->second.insert(std::make_pair(alarm->id, alarm)); 402} 403 404void TimerProxy::RemoveUidTimerMap(const std::shared_ptr<TimerInfo> &alarm) 405{ 406 if (alarm == nullptr) { 407 TIME_HILOGE(TIME_MODULE_SERVICE, "remove uid timer map alarm is nullptr!"); 408 return; 409 } 410 411 std::lock_guard<std::mutex> lock(uidTimersMutex_); 412 auto it = uidTimersMap_.find(alarm->uid); 413 if (it == uidTimersMap_.end()) { 414 return; 415 } 416 417 EraseAlarmItem(alarm->id, it->second); 418 if (it->second.empty()) { 419 uidTimersMap_.erase(it); 420 } 421} 422 423void TimerProxy::RecordProxyUidTimerMap(const std::shared_ptr<TimerInfo> &alarm) 424{ 425 std::lock_guard<std::mutex> lock(proxyMutex_); 426 auto it = proxyUids_.find(alarm->uid); 427 if (it != proxyUids_.end()) { 428 it->second.insert(std::make_pair(alarm->id, alarm->whenElapsed)); 429 } else { 430 proxyUids_.insert(std::make_pair(alarm->uid, 431 std::unordered_map<uint64_t, std::chrono::steady_clock::time_point>{{alarm->id, alarm->whenElapsed}})); 432 } 433} 434 435void TimerProxy::RecordProxyPidTimerMap(const std::shared_ptr<TimerInfo> &alarm) 436{ 437 std::lock_guard<std::mutex> lock(proxyMutex_); 438 auto it = proxyPids_.find(alarm->pid); 439 if (it != proxyPids_.end()) { 440 it->second.insert(std::make_pair(alarm->id, alarm->whenElapsed)); 441 } else { 442 proxyPids_.insert(std::make_pair(alarm->pid, 443 std::unordered_map<uint64_t, std::chrono::steady_clock::time_point>{{alarm->id, alarm->whenElapsed}})); 444 } 445} 446 447void TimerProxy::RemovePidTimerMap(const std::shared_ptr<TimerInfo> &alarm) 448{ 449 if (alarm == nullptr) { 450 TIME_HILOGE(TIME_MODULE_SERVICE, "remove pid timer map alarm is nullptr!"); 451 return; 452 } 453 454 std::lock_guard<std::mutex> lock(pidTimersMutex_); 455 auto it = pidTimersMap_.find(alarm->pid); 456 if (it == pidTimersMap_.end()) { 457 return; 458 } 459 460 EraseAlarmItem(alarm->id, it->second); 461 if (it->second.empty()) { 462 pidTimersMap_.erase(it); 463 } 464} 465 466void TimerProxy::RemoveUidTimerMap(const uint64_t id) 467{ 468 std::lock_guard<std::mutex> lock(uidTimersMutex_); 469 for (auto itUidsTimer = uidTimersMap_.begin(); itUidsTimer!= uidTimersMap_.end(); ++itUidsTimer) { 470 for (auto itTimerId = itUidsTimer->second.begin(); itTimerId!= itUidsTimer->second.end(); ++itTimerId) { 471 if (itTimerId->first != id) { 472 continue; 473 } 474 475 itUidsTimer->second.erase(itTimerId); 476 if (itUidsTimer->second.empty()) { 477 uidTimersMap_.erase(itUidsTimer); 478 } 479 return; 480 } 481 } 482} 483 484void TimerProxy::RemovePidTimerMap(const uint64_t id) 485{ 486 std::lock_guard<std::mutex> lock(pidTimersMutex_); 487 for (auto itPidsTimer = pidTimersMap_.begin(); itPidsTimer!= pidTimersMap_.end(); ++itPidsTimer) { 488 for (auto itTimerId = itPidsTimer->second.begin(); itTimerId!= itPidsTimer->second.end(); ++itTimerId) { 489 if (itTimerId->first != id) { 490 continue; 491 } 492 493 itPidsTimer->second.erase(itTimerId); 494 if (itPidsTimer->second.empty()) { 495 pidTimersMap_.erase(itPidsTimer); 496 } 497 return; 498 } 499 } 500} 501 502bool TimerProxy::IsUidProxy(const int32_t uid) 503{ 504 std::lock_guard<std::mutex> lock(proxyMutex_); 505 auto it = proxyUids_.find(uid); 506 if (it == proxyUids_.end()) { 507 return false; 508 } 509 return true; 510} 511 512bool TimerProxy::IsPidProxy(const int32_t pid) 513{ 514 std::lock_guard<std::mutex> lock(proxyPidMutex_); 515 auto it = proxyPids_.find(pid); 516 if (it == proxyPids_.end()) { 517 return false; 518 } 519 return true; 520} 521 522// needs to acquire the lock `proxyMutex_` before calling this method 523void TimerProxy::UpdateProxyWhenElapsedForProxyUidMap(const int32_t uid, 524 const std::chrono::steady_clock::time_point &now, 525 std::function<void(std::shared_ptr<TimerInfo> &alarm)> insertAlarmCallback) 526{ 527 auto it = proxyUids_.find(uid); 528 if (it != proxyUids_.end()) { 529 TIME_HILOGD(TIME_MODULE_SERVICE, "uid is already proxy, uid: %{public}d", uid); 530 return; 531 } 532 533 std::lock_guard<std::mutex> lockUidTimers(uidTimersMutex_); 534 if (uidTimersMap_.find(uid) == uidTimersMap_.end()) { 535 TIME_HILOGD(TIME_MODULE_SERVICE, "uid timer info map not found, uid: %{public}d", uid); 536 std::unordered_map<uint64_t, std::chrono::steady_clock::time_point> timePointMap {}; 537 proxyUids_.insert(std::make_pair(uid, timePointMap)); 538 return; 539 } 540 541 std::unordered_map<uint64_t, std::chrono::steady_clock::time_point> timePointMap {}; 542 for (auto itUidTimersMap = uidTimersMap_.at(uid).begin(); itUidTimersMap!= uidTimersMap_.at(uid).end(); 543 ++itUidTimersMap) { 544 timePointMap.insert(std::make_pair(itUidTimersMap->first, itUidTimersMap->second->whenElapsed)); 545 itUidTimersMap->second->UpdateWhenElapsedFromNow(now, milliseconds(proxyDelayTime_)); 546 TIME_HILOGD(TIME_MODULE_SERVICE, "Update proxy WhenElapsed for proxy uid map. " 547 "uid= %{public}d, id=%{public}" PRId64 ", timer whenElapsed=%{public}lld, now=%{public}lld", 548 itUidTimersMap->second->uid, itUidTimersMap->second->id, 549 itUidTimersMap->second->whenElapsed.time_since_epoch().count(), 550 now.time_since_epoch().count()); 551 insertAlarmCallback(itUidTimersMap->second); 552 } 553 proxyUids_.insert(std::make_pair(uid, timePointMap)); 554} 555 556void TimerProxy::UpdateProxyWhenElapsedForProxyPidMap(int pid, 557 const std::chrono::steady_clock::time_point &now, 558 std::function<void(std::shared_ptr<TimerInfo> &alarm)> insertAlarmCallback) 559{ 560 auto it = proxyPids_.find(pid); 561 if (it != proxyPids_.end()) { 562 TIME_HILOGD(TIME_MODULE_SERVICE, "pid is already proxy, pid: %{public}d", pid); 563 return; 564 } 565 566 std::lock_guard<std::mutex> lockUidTimers(pidTimersMutex_); 567 if (pidTimersMap_.find(pid) == pidTimersMap_.end()) { 568 TIME_HILOGD(TIME_MODULE_SERVICE, "pid timer info map not found, pid: %{public}d", pid); 569 std::unordered_map<uint64_t, std::chrono::steady_clock::time_point> timePointMap {}; 570 proxyPids_.insert(std::make_pair(pid, timePointMap)); 571 return; 572 } 573 574 std::unordered_map<uint64_t, std::chrono::steady_clock::time_point> timePointMap {}; 575 for (auto itPidTimersMap = pidTimersMap_.at(pid).begin(); itPidTimersMap!= pidTimersMap_.at(pid).end(); 576 ++itPidTimersMap) { 577 timePointMap.insert(std::make_pair(itPidTimersMap->first, itPidTimersMap->second->whenElapsed)); 578 itPidTimersMap->second->UpdateWhenElapsedFromNow(now, milliseconds(proxyDelayTime_)); 579 TIME_HILOGD(TIME_MODULE_SERVICE, "Update proxy WhenElapsed for proxy pid map. " 580 "pid= %{public}d, id=%{public}" PRId64 ", timer whenElapsed=%{public}lld, now=%{public}lld", 581 itPidTimersMap->second->pid, itPidTimersMap->second->id, 582 itPidTimersMap->second->whenElapsed.time_since_epoch().count(), 583 now.time_since_epoch().count()); 584 insertAlarmCallback(itPidTimersMap->second); 585 } 586 proxyPids_.insert(std::make_pair(pid, timePointMap)); 587} 588 589bool TimerProxy::RestoreProxyWhenElapsedByUid(const int32_t uid, 590 const std::chrono::steady_clock::time_point &now, 591 std::function<void(std::shared_ptr<TimerInfo> &alarm)> insertAlarmCallback) 592{ 593 auto it = proxyUids_.find(uid); 594 if (it == proxyUids_.end()) { 595 TIME_HILOGD(TIME_MODULE_SERVICE, "Uid: %{public}d doesn't exist in the proxy list.", uid); 596 return false; 597 } 598 599 std::lock_guard<std::mutex> lockUidTimers(uidTimersMutex_); 600 if (uidTimersMap_.find(uid) == uidTimersMap_.end()) { 601 TIME_HILOGD(TIME_MODULE_SERVICE, "uid timer info map not found, just erase proxy map. uid: %{public}d", uid); 602 return true; 603 } 604 605 for (auto itProxyUids = proxyUids_.at(uid).begin(); itProxyUids != proxyUids_.at(uid).end(); ++itProxyUids) { 606 auto itTimerInfo = uidTimersMap_.at(uid).find(itProxyUids->first); 607 if (itTimerInfo == uidTimersMap_.at(uid).end()) { 608 continue; 609 } 610 if (itProxyUids->second > now + milliseconds(MILLI_TO_SECOND)) { 611 auto interval = std::chrono::duration_cast<std::chrono::nanoseconds>(itProxyUids->second - now); 612 itTimerInfo->second->UpdateWhenElapsedFromNow(now, interval); 613 } else { 614 itTimerInfo->second->UpdateWhenElapsedFromNow(now, milliseconds(MILLI_TO_SECOND)); 615 } 616 TIME_HILOGD(TIME_MODULE_SERVICE, "Restore proxy WhenElapsed by uid. " 617 "uid= %{public}d, id=%{public}" PRId64 ", timer whenElapsed=%{public}lld, now=%{public}lld", 618 itTimerInfo->second->uid, itTimerInfo->second->id, 619 itTimerInfo->second->whenElapsed.time_since_epoch().count(), 620 now.time_since_epoch().count()); 621 insertAlarmCallback(itTimerInfo->second); 622 } 623 624 return true; 625} 626 627bool TimerProxy::RestoreProxyWhenElapsedByPid(const int pid, 628 const std::chrono::steady_clock::time_point &now, 629 std::function<void(std::shared_ptr<TimerInfo> &alarm)> insertAlarmCallback) 630{ 631 auto it = proxyPids_.find(pid); 632 if (it == proxyPids_.end()) { 633 TIME_HILOGD(TIME_MODULE_SERVICE, "Pid: %{public}d doesn't exist in the proxy list.", pid); 634 return false; 635 } 636 std::lock_guard<std::mutex> lockPidTimers(pidTimersMutex_); 637 if (pidTimersMap_.find(pid) == pidTimersMap_.end()) { 638 TIME_HILOGD(TIME_MODULE_SERVICE, "pid timer info map not found, just erase proxy map. pid: %{public}d", pid); 639 return true; 640 } 641 for (auto itProxyPids = proxyPids_.at(pid).begin(); itProxyPids != proxyPids_.at(pid).end(); ++itProxyPids) { 642 auto itTimerInfo = pidTimersMap_.at(pid).find(itProxyPids->first); 643 if (itTimerInfo == pidTimersMap_.at(pid).end()) { 644 continue; 645 } 646 if (itProxyPids->second > now + milliseconds(MILLI_TO_SECOND)) { 647 auto interval = std::chrono::duration_cast<std::chrono::nanoseconds>(itProxyPids->second - now); 648 itTimerInfo->second->UpdateWhenElapsedFromNow(now, interval); 649 } else { 650 itTimerInfo->second->UpdateWhenElapsedFromNow(now, milliseconds(MILLI_TO_SECOND)); 651 } 652 TIME_HILOGD(TIME_MODULE_SERVICE, "Restore proxy WhenElapsed by pid. " 653 "pid= %{public}d, id=%{public}" PRId64 ", timer whenElapsed=%{public}lld, now=%{public}lld", 654 itTimerInfo->second->pid, itTimerInfo->second->id, 655 itTimerInfo->second->whenElapsed.time_since_epoch().count(), 656 now.time_since_epoch().count()); 657 insertAlarmCallback(itTimerInfo->second); 658 } 659 660 return true; 661} 662 663// needs to acquire the lock `proxyMutex_` before calling this method 664bool TimerProxy::RestoreProxyWhenElapsedForProxyUidMap(const int32_t uid, 665 const std::chrono::steady_clock::time_point &now, 666 std::function<void(std::shared_ptr<TimerInfo> &alarm)> insertAlarmCallback) 667{ 668 bool ret = RestoreProxyWhenElapsedByUid(uid, now, insertAlarmCallback); 669 if (ret) { 670 proxyUids_.erase(uid); 671 } 672 return ret; 673} 674 675bool TimerProxy::RestoreProxyWhenElapsedForProxyPidMap(const int pid, 676 const std::chrono::steady_clock::time_point &now, 677 std::function<void(std::shared_ptr<TimerInfo> &alarm)> insertAlarmCallback) 678{ 679 bool ret = RestoreProxyWhenElapsedByPid(pid, now, insertAlarmCallback); 680 if (ret) { 681 proxyPids_.erase(pid); 682 } 683 return ret; 684} 685 686 687void TimerProxy::ResetAllProxyWhenElapsed(const std::chrono::steady_clock::time_point &now, 688 std::function<void(std::shared_ptr<TimerInfo> &alarm)> insertAlarmCallback) 689{ 690 std::lock_guard<std::mutex> lockProxy(proxyMutex_); 691 for (auto it = proxyUids_.begin(); it != proxyUids_.end(); ++it) { 692 RestoreProxyWhenElapsedByUid(it->first, now, insertAlarmCallback); 693 } 694 proxyUids_.clear(); 695} 696 697void TimerProxy::ResetAllPidProxyWhenElapsed(const std::chrono::steady_clock::time_point &now, 698 std::function<void(std::shared_ptr<TimerInfo> &alarm)> insertAlarmCallback) 699{ 700 std::lock_guard<std::mutex> lockProxy(proxyPidMutex_); 701 for (auto it = proxyPids_.begin(); it != proxyPids_.end(); ++it) { 702 RestoreProxyWhenElapsedByPid(it->first, now, insertAlarmCallback); 703 } 704 proxyPids_.clear(); 705} 706 707bool TimerProxy::ShowProxyTimerInfo(int fd, const int64_t now) 708{ 709 TIME_HILOGD(TIME_MODULE_SERVICE, "start."); 710 std::lock_guard<std::mutex> lockProxy(proxyMutex_); 711 dprintf(fd, "current time %lld\n", now); 712 for (auto itProxyUids = proxyUids_.begin(); itProxyUids != proxyUids_.end(); ++itProxyUids) { 713 dprintf(fd, " - proxy uid = %lu\n", itProxyUids->first); 714 for (auto itTimerIdMap = itProxyUids->second.begin(); itTimerIdMap != itProxyUids->second.end(); 715 ++itTimerIdMap) { 716 dprintf(fd, " * save timer id = %llu\n", itTimerIdMap->first); 717 dprintf(fd, " * save timer whenElapsed = %lld\n", itTimerIdMap->second.time_since_epoch().count()); 718 } 719 } 720 std::lock_guard<std::mutex> lockPidProxy(proxyPidMutex_); 721 dprintf(fd, "current time %lld\n", now); 722 for (auto itProxyPids = proxyPids_.begin(); itProxyPids != proxyPids_.end(); ++itProxyPids) { 723 dprintf(fd, " - proxy pid = %lu\n", itProxyPids->first); 724 for (auto itTimerIdMap = itProxyPids->second.begin(); itTimerIdMap != itProxyPids->second.end(); 725 ++itTimerIdMap) { 726 dprintf(fd, " * save timer id = %llu\n", itTimerIdMap->first); 727 dprintf(fd, " * save timer whenElapsed = %lld\n", itTimerIdMap->second.time_since_epoch().count()); 728 } 729 } 730 TIME_HILOGD(TIME_MODULE_SERVICE, "end."); 731 return true; 732} 733 734bool TimerProxy::ShowUidTimerMapInfo(int fd, const int64_t now) 735{ 736 TIME_HILOGD(TIME_MODULE_SERVICE, "start."); 737 std::lock_guard<std::mutex> lockProxy(uidTimersMutex_); 738 dprintf(fd, "current time %lld\n", now); 739 for (auto itTimerInfoMap = uidTimersMap_.begin(); itTimerInfoMap != uidTimersMap_.end(); ++itTimerInfoMap) { 740 dprintf(fd, " - uid = %lu\n", itTimerInfoMap->first); 741 for (auto itTimerInfo = itTimerInfoMap->second.begin(); itTimerInfo != itTimerInfoMap->second.end(); 742 ++itTimerInfo) { 743 dprintf(fd, " * timer id = %llu\n", itTimerInfo->second->id); 744 dprintf(fd, " * timer whenElapsed = %lld\n", itTimerInfo->second->whenElapsed.time_since_epoch().count()); 745 } 746 } 747 TIME_HILOGD(TIME_MODULE_SERVICE, "end."); 748 return true; 749} 750 751bool TimerProxy::ShowPidTimerMapInfo(int fd, const int64_t now) 752{ 753 TIME_HILOGD(TIME_MODULE_SERVICE, "start."); 754 std::lock_guard<std::mutex> lockProxy(pidTimersMutex_); 755 dprintf(fd, "current time %lld\n", now); 756 for (auto itTimerInfoMap = pidTimersMap_.begin(); itTimerInfoMap != pidTimersMap_.end(); ++itTimerInfoMap) { 757 dprintf(fd, " - pid = %lu\n", itTimerInfoMap->first); 758 for (auto itTimerInfo = itTimerInfoMap->second.begin(); itTimerInfo != itTimerInfoMap->second.end(); 759 ++itTimerInfo) { 760 dprintf(fd, " * timer id = %llu\n", itTimerInfo->second->id); 761 dprintf(fd, " * timer whenElapsed = %lld\n", itTimerInfo->second->whenElapsed.time_since_epoch().count()); 762 } 763 } 764 TIME_HILOGD(TIME_MODULE_SERVICE, "end."); 765 return true; 766} 767 768 769void TimerProxy::ShowAdjustTimerInfo(int fd) 770{ 771 std::lock_guard<std::mutex> lockProxy(adjustMutex_); 772 dprintf(fd, "show adjust timer"); 773 for (auto timer : adjustTimers_) { 774 dprintf(fd, " * timer id = %lu\n", timer->id); 775 dprintf(fd, " * timer uid = %d\n\n", timer->uid); 776 dprintf(fd, " * timer bundleName = %s\n\n", timer->bundleName.c_str()); 777 dprintf(fd, " * timer originWhenElapsed = %lld\n\n", timer->originWhenElapsed); 778 dprintf(fd, " * timer whenElapsed = %lld\n\n", timer->whenElapsed); 779 dprintf(fd, " * timer originMaxWhenElapsed = %lld\n\n", timer->originMaxWhenElapsed); 780 dprintf(fd, " * timer maxWhenElapsed = %lld\n\n", timer->maxWhenElapsed); 781 } 782} 783 784bool TimerProxy::ShowProxyDelayTime(int fd) 785{ 786 TIME_HILOGD(TIME_MODULE_SERVICE, "start."); 787 dprintf(fd, "proxy delay time: %lld ms\n", proxyDelayTime_); 788 TIME_HILOGD(TIME_MODULE_SERVICE, "end."); 789 return true; 790} 791 792int64_t TimerProxy::GetProxyDelayTime() const 793{ 794 return proxyDelayTime_; 795} 796} // MiscServices 797} // OHOS