• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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