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