1 /*
2 * Copyright (c) 2025-2025 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 #include "suspend_manager_base_observer.h"
16 #include "suspend_state_observer_base_recipient.h"
17 #include "suspend_manager_base_log.h"
18
19 namespace OHOS {
20 namespace ResourceSchedule {
IMPLEMENT_SINGLE_INSTANCE(SuspendManagerBaseObserver)21 IMPLEMENT_SINGLE_INSTANCE(SuspendManagerBaseObserver)
22
23 void SuspendManagerBaseObserver::OnObserverDied(const wptr<IRemoteObject> &remote)
24 {
25 SUSPEND_MSG_LOGI("Suspend manager OnObserverDied called");
26 auto object = remote.promote();
27 if (object == nullptr) {
28 SUSPEND_MSG_LOGE("observer nullptr.");
29 return;
30 }
31 sptr<ISuspendStateObserverBase> observer = iface_cast<ISuspendStateObserverBase>(object);
32 int32_t ret = UnregisterSuspendObserverInner(observer);
33 if (ret != ERR_OK) {
34 SUSPEND_MSG_LOGE("Unregister suspend observer failed in OnObserverDied");
35 }
36
37 ret = RemoveObserverDeathRecipient(observer);
38 if (ret != ERR_OK) {
39 SUSPEND_MSG_LOGE("Remove observer death recipient failed.");
40 }
41 }
42
AddObserverDeathRecipient(const sptr<ISuspendStateObserverBase> & observer)43 int32_t SuspendManagerBaseObserver::AddObserverDeathRecipient(const sptr<ISuspendStateObserverBase> &observer)
44 {
45 SUSPEND_MSG_LOGD("Add observer death recipient begin.");
46 if (observer == nullptr || observer->AsObject() == nullptr) {
47 SUSPEND_MSG_LOGE("The param observer is nullptr.");
48 return ERR_INVALID_VALUE;
49 }
50
51 std::lock_guard<std::mutex> lock(recipientMapLock_);
52 auto it = recipientMap_.find(observer->AsObject());
53 if (it != recipientMap_.end()) {
54 SUSPEND_MSG_LOGI("This death recipient has been added.");
55 return ERR_OK;
56 }
57
58 sptr<IRemoteObject::DeathRecipient> deathRecipient =
59 new SuspendStateObserverBaseRecipient([this](const wptr<IRemoteObject> &remote) {
60 this->OnObserverDied(remote);
61 });
62 if (deathRecipient == nullptr) {
63 SUSPEND_MSG_LOGE("create death recipient ptr failed");
64 return ERR_INVALID_VALUE;
65 }
66 if (!observer->AsObject()->AddDeathRecipient(deathRecipient)) {
67 SUSPEND_MSG_LOGE("AddDeathRecipient failed.");
68 return ERR_INVALID_OPERATION;
69 }
70
71 recipientMap_.emplace(observer->AsObject(), deathRecipient);
72 SUSPEND_MSG_LOGI("Add death recipient succeed.");
73 return ERR_OK;
74 }
75
RemoveObserverDeathRecipient(const sptr<ISuspendStateObserverBase> & observer)76 int32_t SuspendManagerBaseObserver::RemoveObserverDeathRecipient(const sptr<ISuspendStateObserverBase> &observer)
77 {
78 SUSPEND_MSG_LOGD("Remove observer death recipient begin.");
79 if (observer == nullptr || observer->AsObject() == nullptr) {
80 SUSPEND_MSG_LOGE("The param observer is nullptr.");
81 return ERR_INVALID_VALUE;
82 }
83
84 std::lock_guard<std::mutex> lock(recipientMapLock_);
85 auto it = recipientMap_.find(observer->AsObject());
86 if (it != recipientMap_.end()) {
87 it->first->RemoveDeathRecipient(it->second);
88 recipientMap_.erase(it);
89 SUSPEND_MSG_LOGI("Remove death recipient succeed.");
90 return ERR_OK;
91 }
92
93 SUSPEND_MSG_LOGW("Observer not found in observer death recipient.");
94 return ERR_OK;
95 }
96
RegisterSuspendObserver(const sptr<ISuspendStateObserverBase> & observer)97 int32_t SuspendManagerBaseObserver::RegisterSuspendObserver(const sptr<ISuspendStateObserverBase> &observer)
98 {
99 int32_t ret = RegisterSuspendObserverInner(observer);
100 if (ret != ERR_OK) {
101 SUSPEND_MSG_LOGE("Register suspend observer inner error.");
102 return ret;
103 }
104
105 ret = AddObserverDeathRecipient(observer);
106 if (ret != ERR_OK) {
107 SUSPEND_MSG_LOGE("Add observer death recipient failed.");
108 UnregisterSuspendObserverInner(observer);
109 return ret;
110 }
111 SUSPEND_MSG_LOGI("BaseObserver register succ, size:%{public}u.", (uint32_t)suspendObservers_.size());
112 return ERR_OK;
113 }
114
UnregisterSuspendObserver(const sptr<ISuspendStateObserverBase> & observer)115 int32_t SuspendManagerBaseObserver::UnregisterSuspendObserver(const sptr<ISuspendStateObserverBase> &observer)
116 {
117 int32_t ret = UnregisterSuspendObserverInner(observer);
118 if (ret != ERR_OK) {
119 SUSPEND_MSG_LOGE("Unregister suspend observer inner error.");
120 return ret;
121 }
122
123 ret = RemoveObserverDeathRecipient(observer);
124 if (ret != ERR_OK) {
125 SUSPEND_MSG_LOGE("Remove observer death recipient failed.");
126 RegisterSuspendObserverInner(observer);
127 return ret;
128 }
129 SUSPEND_MSG_LOGI("BaseObserver unregister succ, size:%{public}u.", (uint32_t)suspendObservers_.size());
130 return ERR_OK;
131 }
132
RegisterSuspendObserverInner(const sptr<ISuspendStateObserverBase> & observer)133 int32_t SuspendManagerBaseObserver::RegisterSuspendObserverInner(const sptr<ISuspendStateObserverBase> &observer)
134 {
135 SUSPEND_MSG_LOGI("BaseObserver RegisterSuspendObserverInner.");
136 if (observer == nullptr) {
137 SUSPEND_MSG_LOGE("Register suspend observer error: observer is null.");
138 return ERR_INVALID_VALUE;
139 }
140
141 std::lock_guard<std::mutex> lock(suspendObserverLock_);
142 auto it = std::find_if(suspendObservers_.begin(), suspendObservers_.end(),
143 [&observer](const sptr<ISuspendStateObserverBase> &item) {
144 return (item && item->AsObject() == observer->AsObject());
145 });
146 if (it != suspendObservers_.end()) {
147 SUSPEND_MSG_LOGW("Register error: observer already exist.");
148 return ERR_OK;
149 }
150 suspendObservers_.push_back(observer);
151 return ERR_OK;
152 }
153
UnregisterSuspendObserverInner(const sptr<ISuspendStateObserverBase> & observer)154 int32_t SuspendManagerBaseObserver::UnregisterSuspendObserverInner(const sptr<ISuspendStateObserverBase> &observer)
155 {
156 SUSPEND_MSG_LOGI("BaseObserver UnregisterSuspendObserverInner.");
157 if (observer == nullptr) {
158 SUSPEND_MSG_LOGE("Unregister suspend observer error: observer is null.");
159 return ERR_INVALID_VALUE;
160 }
161
162 std::lock_guard<std::mutex> lock(suspendObserverLock_);
163 auto it = std::find_if(suspendObservers_.begin(), suspendObservers_.end(),
164 [&observer](const sptr<ISuspendStateObserverBase> &item) {
165 return (item && item->AsObject() == observer->AsObject());
166 });
167 if (it == suspendObservers_.end()) {
168 SUSPEND_MSG_LOGW("Suspend observer not register.");
169 return ERR_OK;
170 }
171 suspendObservers_.erase(it);
172 return ERR_OK;
173 }
174
175 std::unordered_map<uint32_t, std::function<void(std::vector<sptr<ISuspendStateObserverBase>>::iterator,
176 const int32_t, const std::vector<int32_t>&)>> SuspendManagerBaseObserver::updateSuspendCbMap_ = {
177 {
178 static_cast<uint32_t>(States::ACTIVE_STATE),
179 [](std::vector<sptr<ISuspendStateObserverBase>>::iterator iter, const int32_t uid,
__anon3c3f9d650402() 180 const std::vector<int32_t> &pidList) {
181 return (*iter)->OnActive(pidList, uid);
182 }
183 },
184 {
185 static_cast<uint32_t>(States::DOZE_STATE),
186 [](std::vector<sptr<ISuspendStateObserverBase>>::iterator iter, const int32_t uid,
__anon3c3f9d650502() 187 const std::vector<int32_t> &pidList) {
188 return (*iter)->OnDoze(pidList, uid);
189 }
190 },
191 {
192 static_cast<uint32_t>(States::FROZEN_STATE),
193 [](std::vector<sptr<ISuspendStateObserverBase>>::iterator iter, const int32_t uid,
__anon3c3f9d650602() 194 const std::vector<int32_t> &pidList) {
195 return (*iter)->OnFrozen(pidList, uid);
196 }
197 },
198 };
199
UpdateSuspendObserver(const States state,const int32_t uid,const std::vector<int32_t> & pidList)200 int32_t SuspendManagerBaseObserver::UpdateSuspendObserver(const States state, const int32_t uid,
201 const std::vector<int32_t> &pidList)
202 {
203 auto cbIt = updateSuspendCbMap_.find(static_cast<uint32_t>(state));
204 if (cbIt == updateSuspendCbMap_.end()) {
205 SUSPEND_MSG_LOGE("Update suspend observer state error: %{public}u.", static_cast<uint32_t>(state));
206 return ERR_INVALID_VALUE;
207 }
208
209 std::lock_guard<std::mutex> lock(suspendObserverLock_);
210 if (suspendObservers_.empty()) {
211 SUSPEND_MSG_LOGD("BaseObserver Update observer null.");
212 return ERR_OK;
213 }
214 for (auto iter = suspendObservers_.begin(); iter != suspendObservers_.end(); ++iter) {
215 cbIt->second(iter, uid, pidList);
216 }
217
218 SUSPEND_MSG_LOGD("BaseObserver UpdateSuspendObserver for state: %{public}u, uid: %{public}d.", cbIt->first, uid);
219 return ERR_OK;
220 }
221 } // namespace ResourceSchedule
222 } // namespace OHOS