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_task_mgr.h"
20 #include "running_form_info.h"
21
22 namespace OHOS {
23 namespace AppExecFwk {
SetDeathRecipient(const sptr<IRemoteObject> & callerToken,const sptr<IRemoteObject::DeathRecipient> & deathRecipient)24 void FormObserverRecord::SetDeathRecipient(const sptr<IRemoteObject> &callerToken,
25 const sptr<IRemoteObject::DeathRecipient> &deathRecipient)
26 {
27 HILOG_DEBUG("start");
28 if (callerToken == nullptr || deathRecipient == nullptr) {
29 HILOG_ERROR("The callerToken or the deathRecipient is empty");
30 return;
31 }
32 std::lock_guard<std::mutex> lock(deathRecipientsMutex_);
33 auto iter = deathRecipients_.find(callerToken);
34 if (iter == deathRecipients_.end()) {
35 deathRecipients_.emplace(callerToken, deathRecipient);
36 callerToken->AddDeathRecipient(deathRecipient);
37 } else {
38 HILOG_DEBUG("The deathRecipient has been added.");
39 }
40 }
41
SetFormAddObserver(const std::string bundleName,const sptr<IRemoteObject> & callerToken)42 ErrCode FormObserverRecord::SetFormAddObserver(const std::string bundleName, const sptr<IRemoteObject> &callerToken)
43 {
44 HILOG_DEBUG("start");
45 std::lock_guard<std::mutex> lock(formAddObserverMutex_);
46 auto iter = formAddObservers_.find(bundleName);
47 if (iter == formAddObservers_.end()) {
48 std::vector<sptr<IRemoteObject>> observers;
49 observers.emplace_back(callerToken);
50 formAddObservers_.emplace(bundleName, observers);
51 } else {
52 if (std::find(iter->second.begin(), iter->second.end(), callerToken) != iter->second.end()) {
53 HILOG_DEBUG("The observer has been added.");
54 return ERR_OK;
55 } else {
56 iter->second.emplace_back(callerToken);
57 }
58 }
59 SetDeathRecipient(callerToken, new (std::nothrow) FormObserverRecord::ClientDeathRecipient());
60 return ERR_OK;
61 }
62
SetFormRemoveObserver(const std::string bundleName,const sptr<IRemoteObject> & callerToken)63 ErrCode FormObserverRecord::SetFormRemoveObserver(const std::string bundleName, const sptr<IRemoteObject> &callerToken)
64 {
65 HILOG_DEBUG("start");
66 std::lock_guard<std::mutex> lock(formRemoveObserverMutex_);
67 auto iter = formRemoveObservers_.find(bundleName);
68 if (iter == formRemoveObservers_.end()) {
69 std::vector<sptr<IRemoteObject>> observers;
70 observers.emplace_back(callerToken);
71 formRemoveObservers_.emplace(bundleName, observers);
72 } else {
73 if (std::find(iter->second.begin(), iter->second.end(), callerToken) != iter->second.end()) {
74 HILOG_DEBUG("The observer has been added.");
75 return ERR_OK;
76 } else {
77 iter->second.emplace_back(callerToken);
78 }
79 }
80 SetDeathRecipient(callerToken, new (std::nothrow) FormObserverRecord::ClientDeathRecipient());
81 return ERR_OK;
82 }
83
onFormAdd(const std::string bundleName,RunningFormInfo & runningFormInfo)84 void FormObserverRecord::onFormAdd(const std::string bundleName, RunningFormInfo &runningFormInfo)
85 {
86 HILOG_DEBUG("start");
87 if (formAddObservers_.empty()) {
88 HILOG_DEBUG("No observer has been added.");
89 return;
90 }
91 std::lock_guard<std::mutex> lock(formAddObserverMutex_);
92 auto iter = formAddObservers_.find(bundleName);
93 if (iter != formAddObservers_.end()) {
94 for (auto callerToken : iter->second) {
95 FormTaskMgr::GetInstance().PostAddTaskToHost(bundleName, callerToken, runningFormInfo);
96 }
97 }
98 }
99
onFormRemove(const std::string bundleName,const RunningFormInfo runningFormInfo)100 void FormObserverRecord::onFormRemove(const std::string bundleName, const RunningFormInfo runningFormInfo)
101 {
102 HILOG_DEBUG("start");
103 if (formRemoveObservers_.empty()) {
104 HILOG_DEBUG("No observer has been added.");
105 return;
106 }
107
108 std::lock_guard<std::mutex> lock(formRemoveObserverMutex_);
109 auto iter = formRemoveObservers_.find(bundleName);
110 if (iter != formRemoveObservers_.end()) {
111 for (auto callerToken : iter->second) {
112 FormTaskMgr::GetInstance().PostRemoveTaskToHost(bundleName, callerToken, runningFormInfo);
113 }
114 }
115 }
116
CleanResource(const wptr<IRemoteObject> & remote)117 void FormObserverRecord::CleanResource(const wptr<IRemoteObject> &remote)
118 {
119 HILOG_DEBUG("start");
120
121 // Clean the formAddObservers_.
122 auto object = remote.promote();
123 if (object == nullptr) {
124 HILOG_ERROR("remote object is nullptr");
125 return;
126 }
127 std::lock_guard<std::mutex> lock(formAddObserverMutex_);
128 for (auto it = formAddObservers_.begin(); it != formAddObservers_.end();) {
129 auto& observer = it->second;
130 auto iter = std::find(observer.begin(), observer.end(), object);
131 if (iter != observer.end()) {
132 observer.erase(iter);
133 }
134 if (observer.empty()) {
135 it = formAddObservers_.erase(it);
136 } else {
137 ++it;
138 }
139 }
140
141 // Clean the formRemoveObservers_.
142 std::lock_guard<std::mutex> observerLock(formRemoveObserverMutex_);
143 for (auto it = formRemoveObservers_.begin(); it != formRemoveObservers_.end();) {
144 auto& observer = it->second;
145 auto iter = std::find(observer.begin(), observer.end(), object);
146 if (iter != observer.end()) {
147 observer.erase(iter);
148 }
149 if (observer.empty()) {
150 it = formRemoveObservers_.erase(it);
151 } else {
152 ++it;
153 }
154 }
155
156 std::lock_guard<std::mutex> deathLock(deathRecipientsMutex_);
157 auto iter = deathRecipients_.find(object);
158 if (iter != deathRecipients_.end()) {
159 auto deathRecipient = iter->second;
160 deathRecipients_.erase(iter);
161 object->RemoveDeathRecipient(deathRecipient);
162 }
163 }
164
OnRemoteDied(const wptr<IRemoteObject> & remote)165 void FormObserverRecord::ClientDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
166 {
167 HILOG_DEBUG("remote died");
168 FormObserverRecord::GetInstance().CleanResource(remote);
169 }
170 } // namespace AppExecFwk
171 } // namespace OHOS
172