1 /*
2 * Copyright (c) 2021-2022 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 "dataobs_mgr_inner.h"
16
17 #include "data_ability_observer_stub.h"
18 #include "dataobs_mgr_errors.h"
19 #include "hilog_wrapper.h"
20
21 namespace OHOS {
22 namespace AAFwk {
23 std::mutex DataObsMgrInner::innerMutex_;
24
DataObsMgrInner()25 DataObsMgrInner::DataObsMgrInner()
26 {
27 taskCount_.store(0);
28 }
29
~DataObsMgrInner()30 DataObsMgrInner::~DataObsMgrInner()
31 {
32 taskCount_.store(0);
33 }
34
SetHandler(const std::shared_ptr<EventHandler> & handler)35 void DataObsMgrInner::SetHandler(const std::shared_ptr<EventHandler> &handler)
36 {
37 handler_ = handler;
38 }
39
HandleRegisterObserver(const Uri & uri,const sptr<IDataAbilityObserver> & dataObserver)40 int DataObsMgrInner::HandleRegisterObserver(const Uri &uri, const sptr<IDataAbilityObserver> &dataObserver)
41 {
42 HILOG_INFO("DataObsMgrInner::HandleRegisterObserver called start");
43 std::lock_guard<std::mutex> lock_l(innerMutex_);
44
45 ObsListType obslist;
46 bool exist = GetObsListFromMap(uri, obslist);
47
48 auto obs = obslist.begin();
49 for (; obs != obslist.end(); obs++) {
50 if ((*obs)->AsObject() == dataObserver->AsObject()) {
51 HILOG_ERROR("DataObsMgrInner::HandleRegisterObserver the obs exist. no need to register.");
52 AtomicSubTaskCount();
53 return OBS_EXIST;
54 }
55 }
56
57 obslist.push_back(dataObserver);
58
59 AddObsDeathRecipient(dataObserver);
60
61 if (exist) {
62 obsmap_.erase(uri.ToString());
63 }
64
65 obsmap_.emplace(uri.ToString(), obslist);
66
67 AtomicSubTaskCount();
68
69 HILOG_INFO("DataObsMgrInner::HandleRegisterObserver called end");
70 return NO_ERROR;
71 }
72
HandleUnregisterObserver(const Uri & uri,const sptr<IDataAbilityObserver> & dataObserver)73 int DataObsMgrInner::HandleUnregisterObserver(const Uri &uri, const sptr<IDataAbilityObserver> &dataObserver)
74 {
75 HILOG_INFO("DataObsMgrInner::HandleUnregisterObserver called start");
76 std::lock_guard<std::mutex> lock_l(innerMutex_);
77
78 ObsListType obslist;
79 if (!GetObsListFromMap(uri, obslist)) {
80 AtomicSubTaskCount();
81 HILOG_ERROR("DataObsMgrInner::HandleUnregisterObserver there is no obs in the uri.");
82 return NO_OBS_FOR_URI;
83 }
84
85 HILOG_INFO("DataObsMgrInner::HandleUnregisterObserver obslist size is %{public}zu", obslist.size());
86 auto obs = obslist.begin();
87 for (; obs != obslist.end(); obs++) {
88 if ((*obs)->AsObject() == dataObserver->AsObject()) {
89 break;
90 }
91 }
92 if (obs == obslist.end()) {
93 AtomicSubTaskCount();
94 HILOG_ERROR("DataObsMgrInner::HandleUnregisterObserver the obs is not registered to the uri.");
95 return NO_OBS_FOR_URI;
96 }
97 sptr<IDataAbilityObserver> removeObs = *obs;
98 obslist.remove(removeObs);
99 obsmap_.erase(uri.ToString());
100 if (!obslist.empty()) {
101 obsmap_.emplace(uri.ToString(), obslist);
102 }
103
104 if (!ObsExistInMap(removeObs)) {
105 RemoveObsDeathRecipient(removeObs->AsObject());
106 }
107
108 AtomicSubTaskCount();
109 HILOG_INFO("DataObsMgrInner::HandleUnregisterObserver called end");
110 return NO_ERROR;
111 }
112
HandleNotifyChange(const Uri & uri)113 int DataObsMgrInner::HandleNotifyChange(const Uri &uri)
114 {
115 HILOG_INFO("DataObsMgrInner::HandleNotifyChange called start");
116 std::lock_guard<std::mutex> lock_l(innerMutex_);
117
118 ObsListType obslist;
119 if (!GetObsListFromMap(uri, obslist)) {
120 AtomicSubTaskCount();
121 HILOG_INFO("DataObsMgrInner::HandleNotifyChange there is no obs in the uri.");
122 return NO_OBS_FOR_URI;
123 }
124
125 for (auto obs : obslist) {
126 if (obs != nullptr) {
127 obs->OnChange();
128 }
129 }
130
131 AtomicSubTaskCount();
132 HILOG_INFO("DataObsMgrInner::HandleNotifyChange called end %{public}zu", obslist.size());
133 return NO_ERROR;
134 }
135
CheckNeedLimmit()136 bool DataObsMgrInner::CheckNeedLimmit()
137 {
138 return (taskCount_.load() >= taskCount_max_) ? true : false;
139 }
140
CheckRegisteFull(const Uri & uri)141 bool DataObsMgrInner::CheckRegisteFull(const Uri &uri)
142 {
143 std::lock_guard<std::mutex> lock_l(innerMutex_);
144
145 ObsListType obslist;
146 if (GetObsListFromMap(uri, obslist)) {
147 // The obs size for input uri has been lager than max.
148 if (obslist.size() >= obs_max_) {
149 return true;
150 }
151 }
152 return false;
153 }
154
AtomicAddTaskCount()155 void DataObsMgrInner::AtomicAddTaskCount()
156 {
157 taskCount_.fetch_add(1);
158 }
159
AtomicSubTaskCount()160 void DataObsMgrInner::AtomicSubTaskCount()
161 {
162 taskCount_.fetch_sub(1);
163 }
164
GetObsListFromMap(const Uri & uri,ObsListType & obslist)165 bool DataObsMgrInner::GetObsListFromMap(const Uri &uri, ObsListType &obslist)
166 {
167 auto it = obsmap_.find(uri.ToString());
168 if (it == obsmap_.end()) {
169 return false;
170 }
171
172 obslist = it->second;
173 return true;
174 }
175
AddObsDeathRecipient(const sptr<IDataAbilityObserver> & dataObserver)176 void DataObsMgrInner::AddObsDeathRecipient(const sptr<IDataAbilityObserver> &dataObserver)
177 {
178 if ((dataObserver == nullptr) || dataObserver->AsObject() == nullptr) {
179 return;
180 }
181
182 auto it = recipientMap_.find(dataObserver->AsObject());
183 if (it != recipientMap_.end()) {
184 HILOG_ERROR("%{public}s this death recipient has been added.", __func__);
185 return;
186 } else {
187 std::weak_ptr<DataObsMgrInner> thisWeakPtr(shared_from_this());
188 sptr<IRemoteObject::DeathRecipient> deathRecipient =
189 new DataObsCallbackRecipient([thisWeakPtr](const wptr<IRemoteObject> &remote) {
190 auto dataObsMgrInner = thisWeakPtr.lock();
191 if (dataObsMgrInner) {
192 dataObsMgrInner->OnCallBackDied(remote);
193 }
194 });
195 dataObserver->AsObject()->AddDeathRecipient(deathRecipient);
196 recipientMap_.emplace(dataObserver->AsObject(), deathRecipient);
197 }
198 }
199
RemoveObsDeathRecipient(const sptr<IRemoteObject> & dataObserver)200 void DataObsMgrInner::RemoveObsDeathRecipient(const sptr<IRemoteObject> &dataObserver)
201 {
202 if (dataObserver == nullptr) {
203 return;
204 }
205
206 auto it = recipientMap_.find(dataObserver);
207 if (it != recipientMap_.end()) {
208 it->first->RemoveDeathRecipient(it->second);
209 recipientMap_.erase(it);
210 return;
211 }
212 }
213
OnCallBackDied(const wptr<IRemoteObject> & remote)214 void DataObsMgrInner::OnCallBackDied(const wptr<IRemoteObject> &remote)
215 {
216 auto object = remote.promote();
217 if (object == nullptr) {
218 return;
219 }
220
221 if (handler_) {
222 auto task = [object, dataObsMgrInner = shared_from_this()]() {
223 dataObsMgrInner->HandleCallBackDiedTask(object);
224 };
225 handler_->PostTask(task);
226 }
227 }
228
HandleCallBackDiedTask(const sptr<IRemoteObject> & dataObserver)229 void DataObsMgrInner::HandleCallBackDiedTask(const sptr<IRemoteObject> &dataObserver)
230 {
231 HILOG_INFO("%{public}s,called", __func__);
232 std::lock_guard<std::mutex> lock_l(innerMutex_);
233
234 if (dataObserver == nullptr) {
235 HILOG_WARN("dataObserver is nullptr.");
236 return;
237 }
238
239 RemoveObsFromMap(dataObserver);
240 }
241
RemoveObsFromMap(const sptr<IRemoteObject> & dataObserver)242 void DataObsMgrInner::RemoveObsFromMap(const sptr<IRemoteObject> &dataObserver)
243 {
244 for (auto iter = obsmap_.begin(); iter != obsmap_.end();) {
245 auto &obsList = iter->second;
246 for (auto it = obsList.begin(); it != obsList.end(); it++) {
247 if ((*it)->AsObject() == dataObserver) {
248 HILOG_DEBUG("Erase an observer form list.");
249 obsList.erase(it);
250 break;
251 }
252 }
253 if (obsList.size() == 0) {
254 obsmap_.erase(iter++);
255 } else {
256 iter++;
257 }
258 }
259 RemoveObsDeathRecipient(dataObserver);
260 }
261
ObsExistInMap(const sptr<IDataAbilityObserver> & dataObserver)262 bool DataObsMgrInner::ObsExistInMap(const sptr<IDataAbilityObserver> &dataObserver)
263 {
264 for (auto &obsCallback : obsmap_) {
265 auto &obsList = obsCallback.second;
266 auto obs = std::find(obsList.begin(), obsList.end(), dataObserver);
267 if (obs != obsList.end()) {
268 return true;
269 }
270 }
271 return false;
272 }
273 } // namespace AAFwk
274 } // namespace OHOS
275