1 /*
2 * Copyright (c) 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 "form_observer_record.h"
17
18 #include "fms_log_wrapper.h"
19 #include "form_mgr_errors.h"
20 #include "form_task_mgr.h"
21 #include "running_form_info.h"
22
23 namespace OHOS {
24 namespace AppExecFwk {
SetDeathRecipient(const sptr<IRemoteObject> & callerToken,const sptr<IRemoteObject::DeathRecipient> & deathRecipient)25 void FormObserverRecord::SetDeathRecipient(const sptr<IRemoteObject> &callerToken,
26 const sptr<IRemoteObject::DeathRecipient> &deathRecipient)
27 {
28 HILOG_DEBUG("start");
29 if (callerToken == nullptr || deathRecipient == nullptr) {
30 HILOG_ERROR("empty callerToken or deathRecipient");
31 return;
32 }
33 std::lock_guard<std::mutex> lock(deathRecipientsMutex_);
34 auto iter = deathRecipients_.find(callerToken);
35 if (iter == deathRecipients_.end()) {
36 deathRecipients_.emplace(callerToken, deathRecipient);
37 callerToken->AddDeathRecipient(deathRecipient);
38 } else {
39 HILOG_DEBUG("The deathRecipient has been added");
40 }
41 }
42
SetFormAddObserver(const std::string bundleName,const sptr<IRemoteObject> & callerToken)43 ErrCode FormObserverRecord::SetFormAddObserver(const std::string bundleName, const sptr<IRemoteObject> &callerToken)
44 {
45 HILOG_DEBUG("start");
46 std::lock_guard<std::mutex> lock(formAddObserverMutex_);
47 auto iter = formAddObservers_.find(bundleName);
48 if (iter == formAddObservers_.end()) {
49 std::vector<sptr<IRemoteObject>> observers;
50 observers.emplace_back(callerToken);
51 formAddObservers_.emplace(bundleName, observers);
52 } else {
53 if (std::find(iter->second.begin(), iter->second.end(), callerToken) != iter->second.end()) {
54 HILOG_DEBUG("observer added");
55 return ERR_OK;
56 } else {
57 iter->second.emplace_back(callerToken);
58 }
59 }
60 SetDeathRecipient(callerToken, new (std::nothrow) FormObserverRecord::ClientDeathRecipient());
61 return ERR_OK;
62 }
63
SetFormRemoveObserver(const std::string bundleName,const sptr<IRemoteObject> & callerToken)64 ErrCode FormObserverRecord::SetFormRemoveObserver(const std::string bundleName, const sptr<IRemoteObject> &callerToken)
65 {
66 HILOG_DEBUG("start");
67 std::lock_guard<std::mutex> lock(formRemoveObserverMutex_);
68 auto iter = formRemoveObservers_.find(bundleName);
69 if (iter == formRemoveObservers_.end()) {
70 std::vector<sptr<IRemoteObject>> observers;
71 observers.emplace_back(callerToken);
72 formRemoveObservers_.emplace(bundleName, observers);
73 } else {
74 if (std::find(iter->second.begin(), iter->second.end(), callerToken) != iter->second.end()) {
75 HILOG_DEBUG("The observer has been added");
76 return ERR_OK;
77 } else {
78 iter->second.emplace_back(callerToken);
79 }
80 }
81 SetDeathRecipient(callerToken, new (std::nothrow) FormObserverRecord::ClientDeathRecipient());
82 return ERR_OK;
83 }
84
onFormAdd(const std::string bundleName,RunningFormInfo & runningFormInfo)85 void FormObserverRecord::onFormAdd(const std::string bundleName, RunningFormInfo &runningFormInfo)
86 {
87 HILOG_DEBUG("start");
88 if (formAddObservers_.empty()) {
89 HILOG_DEBUG("No observer has been added");
90 return;
91 }
92 std::lock_guard<std::mutex> lock(formAddObserverMutex_);
93 auto iter = formAddObservers_.find(bundleName);
94 if (iter != formAddObservers_.end()) {
95 for (auto callerToken : iter->second) {
96 FormTaskMgr::GetInstance().PostAddTaskToHost(bundleName, callerToken, runningFormInfo);
97 }
98 }
99 }
100
onFormRemove(const std::string bundleName,const RunningFormInfo runningFormInfo)101 void FormObserverRecord::onFormRemove(const std::string bundleName, const RunningFormInfo runningFormInfo)
102 {
103 HILOG_DEBUG("start");
104 if (formRemoveObservers_.empty()) {
105 HILOG_DEBUG("No observer has been added");
106 return;
107 }
108
109 std::lock_guard<std::mutex> lock(formRemoveObserverMutex_);
110 auto iter = formRemoveObservers_.find(bundleName);
111 if (iter != formRemoveObservers_.end()) {
112 for (auto callerToken : iter->second) {
113 FormTaskMgr::GetInstance().PostRemoveTaskToHost(bundleName, callerToken, runningFormInfo);
114 }
115 }
116 }
117
CleanResource(const wptr<IRemoteObject> & remote)118 void FormObserverRecord::CleanResource(const wptr<IRemoteObject> &remote)
119 {
120 HILOG_DEBUG("start");
121
122 // Clean the formAddObservers_.
123 auto object = remote.promote();
124 if (object == nullptr) {
125 HILOG_ERROR("null remoteObject");
126 return;
127 }
128 std::lock_guard<std::mutex> lock(formAddObserverMutex_);
129 for (auto it = formAddObservers_.begin(); it != formAddObservers_.end();) {
130 auto& observer = it->second;
131 auto iter = std::find(observer.begin(), observer.end(), object);
132 if (iter != observer.end()) {
133 observer.erase(iter);
134 }
135 if (observer.empty()) {
136 it = formAddObservers_.erase(it);
137 } else {
138 ++it;
139 }
140 }
141
142 // Clean the formRemoveObservers_.
143 std::lock_guard<std::mutex> observerLock(formRemoveObserverMutex_);
144 for (auto it = formRemoveObservers_.begin(); it != formRemoveObservers_.end();) {
145 auto& observer = it->second;
146 auto iter = std::find(observer.begin(), observer.end(), object);
147 if (iter != observer.end()) {
148 observer.erase(iter);
149 }
150 if (observer.empty()) {
151 it = formRemoveObservers_.erase(it);
152 } else {
153 ++it;
154 }
155 }
156
157 // Clean the formEventObservers_.
158 ClearDeathRemoteObserver(remote);
159
160 std::lock_guard<std::mutex> deathLock(deathRecipientsMutex_);
161 auto iter = deathRecipients_.find(object);
162 if (iter != deathRecipients_.end()) {
163 auto deathRecipient = iter->second;
164 deathRecipients_.erase(iter);
165 object->RemoveDeathRecipient(deathRecipient);
166 }
167 HILOG_DEBUG("end");
168 }
169
OnRemoteDied(const wptr<IRemoteObject> & remote)170 void FormObserverRecord::ClientDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
171 {
172 HILOG_DEBUG("remote died");
173 FormObserverRecord::GetInstance().CleanResource(remote);
174 }
HandleFormEvent(const std::string & bundleName,const std::string & formEventType,RunningFormInfo & runningFormInfo)175 void FormObserverRecord::HandleFormEvent(
176 const std::string &bundleName, const std::string &formEventType, RunningFormInfo &runningFormInfo)
177 {
178 HILOG_DEBUG("call");
179 if (formEventType.empty()) {
180 HILOG_ERROR("empty inputString");
181 return;
182 }
183
184 auto eventId = ConvertToFormEventId(formEventType);
185 if (eventId == FormEventId::FORM_EVENT_NON) {
186 HILOG_ERROR("Input event type error");
187 return;
188 }
189
190 std::unique_lock<std::mutex> lock(formEventObserversMutex_);
191 auto observerVec = formEventObservers_.find(bundleName);
192 if (observerVec == formEventObservers_.end()) {
193 HILOG_ERROR("The current package does not have an observer");
194 return;
195 }
196
197 for (const auto &iter : observerVec->second) {
198 if (iter.IsFollowEvents(eventId) && iter.GetRemote() != nullptr) {
199 NotifyFormEvent(iter, eventId, runningFormInfo, formEventType);
200 }
201 }
202 }
203
ConvertToFormEventId(const std::string & formEventType)204 FormEventId FormObserverRecord::ConvertToFormEventId(const std::string &formEventType)
205 {
206 HILOG_DEBUG("call");
207
208 auto iter = formEventMap.find(formEventType);
209 if (iter != formEventMap.end()) {
210 return iter->second;
211 }
212
213 return FormEventId::FORM_EVENT_NON;
214 }
215
NotifyFormEvent(const FormObserverRecordInner & recordInner,FormEventId formEventId,RunningFormInfo & runningFormInfo,const std::string & formEventType)216 void FormObserverRecord::NotifyFormEvent(const FormObserverRecordInner &recordInner,
217 FormEventId formEventId, RunningFormInfo &runningFormInfo, const std::string &formEventType)
218 {
219 HILOG_DEBUG("call");
220 switch (formEventId) {
221 case FormEventId::FORM_EVENT_CALL :
222 case FormEventId::FORM_EVENT_MESSAGE :
223 case FormEventId::FORM_EVENT_ROUTER :
224 FormTaskMgr::GetInstance().PostFormClickEventToHost(
225 recordInner.BindHostBundle(), formEventType, recordInner.GetRemote(), runningFormInfo);
226 break;
227 case FormEventId::FORM_EVENT_FORM_ADD :
228 break;
229 case FormEventId::FORM_EVENT_FORM_REMOVE :
230 break;
231 default :
232 HILOG_ERROR("Type mismatchy");
233 break;
234 }
235 }
236
SetFormEventObserver(const std::string & bundleName,const std::string & formEventType,const sptr<IRemoteObject> & callerToken)237 ErrCode FormObserverRecord::SetFormEventObserver(
238 const std::string &bundleName, const std::string &formEventType, const sptr<IRemoteObject> &callerToken)
239 {
240 HILOG_DEBUG("call");
241 if (callerToken == nullptr) {
242 HILOG_ERROR("null CallerToken");
243 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
244 }
245
246 // Bundle name allows empty input, representing listening to all applications.
247 if (formEventType.empty()) {
248 HILOG_ERROR("empty inputString");
249 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
250 }
251
252 auto eventId = ConvertToFormEventId(formEventType);
253 if (eventId == FormEventId::FORM_EVENT_NON) {
254 HILOG_ERROR("Input event type error");
255 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
256 }
257
258 return SetFormEventObserverLocked(bundleName, eventId, callerToken);
259 }
260
RemoveFormEventObserver(const std::string & bundleName,const std::string & formEventType,const sptr<IRemoteObject> & callerToken)261 ErrCode FormObserverRecord::RemoveFormEventObserver(
262 const std::string &bundleName, const std::string &formEventType, const sptr<IRemoteObject> &callerToken)
263 {
264 HILOG_DEBUG("call");
265 if (formEventType.empty()) {
266 HILOG_ERROR("empty inputString");
267 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
268 }
269
270 if (callerToken == nullptr) {
271 HILOG_ERROR("empty callerTokenParameter");
272 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
273 }
274
275 auto eventId = ConvertToFormEventId(formEventType);
276 if (eventId == FormEventId::FORM_EVENT_NON) {
277 HILOG_ERROR("Input event type error");
278 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
279 }
280
281 return RemoveFormEventObserverLocked(bundleName, eventId, callerToken);
282 }
283
SetFormEventObserverLocked(const std::string & bundleName,FormEventId eventId,const sptr<IRemoteObject> & callerToken)284 ErrCode FormObserverRecord::SetFormEventObserverLocked(
285 const std::string &bundleName, FormEventId eventId, const sptr<IRemoteObject> &callerToken)
286 {
287 HILOG_DEBUG("call");
288 FormObserverRecordInner recordInner(callerToken);
289 recordInner.PushEvent(eventId);
290 recordInner.SetBindHostBundle(bundleName);
291
292 sptr<IRemoteObject::DeathRecipient> deathRecipient = new (std::nothrow) FormObserverRecord::ClientDeathRecipient();
293 if (deathRecipient == nullptr) {
294 HILOG_ERROR("Create death recipient error");
295 return ERR_APPEXECFWK_FORM_COMMON_CODE;
296 }
297
298 // Place parameter verification on the previous layer.
299 std::unique_lock<std::mutex> formLock(formEventObserversMutex_);
300 auto observerVec = formEventObservers_.find(bundleName);
301 if (observerVec == formEventObservers_.end()) {
302 std::vector<FormObserverRecordInner> observerVec {recordInner};
303 formEventObservers_.emplace(bundleName, observerVec);
304 SetDeathRecipient(recordInner.GetRemote(), deathRecipient);
305 return ERR_OK;
306 }
307
308 auto recordInnerIter = std::find(observerVec->second.begin(), observerVec->second.end(), recordInner);
309 if (recordInnerIter != observerVec->second.end()) {
310 recordInnerIter->PushEvent(eventId);
311 return ERR_OK;
312 }
313
314 // Not find
315 observerVec->second.emplace_back(recordInner);
316 SetDeathRecipient(recordInner.GetRemote(), deathRecipient);
317 return ERR_OK;
318 }
319
RemoveFormEventObserverLocked(const std::string & bundleName,FormEventId formEventType,const sptr<IRemoteObject> & callerToken)320 ErrCode FormObserverRecord::RemoveFormEventObserverLocked(
321 const std::string &bundleName, FormEventId formEventType, const sptr<IRemoteObject> &callerToken)
322 {
323 // Place parameter verification on the previous layer.
324 HILOG_DEBUG("call");
325 std::unique_lock<std::mutex> formLock(formEventObserversMutex_);
326 auto observerVec = formEventObservers_.find(bundleName);
327 if (observerVec == formEventObservers_.end()) {
328 HILOG_ERROR("invalid bundleKey");
329 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
330 }
331
332 FormObserverRecordInner recordInner(callerToken);
333 recordInner.PushEvent(formEventType);
334 recordInner.SetBindHostBundle(bundleName);
335
336 auto recordInnerIter = std::find(observerVec->second.begin(), observerVec->second.end(), recordInner);
337 if (recordInnerIter == observerVec->second.end()) {
338 HILOG_ERROR("invalid caller");
339 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
340 }
341
342 if (recordInnerIter->IsFollowEvents(formEventType)) {
343 recordInnerIter->RemoveEvent(formEventType);
344 }
345
346 // Check if the event container is empty
347 if (recordInnerIter->NonFollowEvents()) {
348 observerVec->second.erase(recordInnerIter);
349 }
350
351 return ERR_OK;
352 }
353
ClearDeathRemoteObserver(const wptr<IRemoteObject> & remote)354 void FormObserverRecord::ClearDeathRemoteObserver(const wptr<IRemoteObject> &remote)
355 {
356 HILOG_DEBUG("call");
357 auto object = remote.promote();
358 if (object == nullptr) {
359 HILOG_ERROR("null remoteObject");
360 return;
361 }
362 std::lock_guard<std::mutex> formEventLock(formEventObserversMutex_);
363 for (auto it = formEventObservers_.begin(); it != formEventObservers_.end();) {
364 auto& observer = it->second;
365 auto iter = std::find_if(observer.begin(), observer.end(), [remote, object](auto &item) {
366 return object == item.GetRemote();
367 });
368 if (iter != observer.end()) {
369 observer.erase(iter);
370 }
371 if (observer.empty()) {
372 it = formEventObservers_.erase(it);
373 } else {
374 ++it;
375 }
376 }
377 }
378
IsFollowEvents(FormEventId type) const379 bool FormObserverRecordInner::IsFollowEvents(FormEventId type) const
380 {
381 return std::find(eventGroup_.begin(), eventGroup_.end(), type) != eventGroup_.end();
382 }
383
PushEvent(FormEventId type)384 void FormObserverRecordInner::PushEvent(FormEventId type)
385 {
386 if (!IsFollowEvents(type)) {
387 eventGroup_.emplace_back(type);
388 }
389 }
390
RemoveEvent(FormEventId type)391 void FormObserverRecordInner::RemoveEvent(FormEventId type)
392 {
393 auto iter = std::find(eventGroup_.begin(), eventGroup_.end(), type);
394 if (iter != eventGroup_.end()) {
395 eventGroup_.erase(iter);
396 }
397 }
398 } // namespace AppExecFwk
399 } // namespace OHOS
400