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