• 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 #include "common_utils.h"
21 
22 namespace OHOS {
23 namespace AAFwk {
24 
DataObsMgrInner()25 DataObsMgrInner::DataObsMgrInner() {}
26 
~DataObsMgrInner()27 DataObsMgrInner::~DataObsMgrInner() {}
28 
HandleRegisterObserver(const Uri & uri,sptr<IDataAbilityObserver> dataObserver)29 int DataObsMgrInner::HandleRegisterObserver(const Uri &uri, sptr<IDataAbilityObserver> dataObserver)
30 {
31     std::lock_guard<ffrt::mutex> lock(innerMutex_);
32 
33     auto [obsPair, flag] = observers_.try_emplace(uri.ToString(), std::list<sptr<IDataAbilityObserver>>());
34     if (!flag && obsPair->second.size() > OBS_NUM_MAX) {
35         HILOG_ERROR("The number of subscribers for this uri : %{public}s has reached the upper limit.",
36             CommonUtils::Anonymous(uri.ToString()).c_str());
37         return DATAOBS_SERVICE_OBS_LIMMIT;
38     }
39 
40     for (auto obs = obsPair->second.begin(); obs != obsPair->second.end(); obs++) {
41         if ((*obs)->AsObject() == dataObserver->AsObject()) {
42             HILOG_ERROR("the obs has registered on this uri : %{public}s",
43                 CommonUtils::Anonymous(uri.ToString()).c_str());
44             return OBS_EXIST;
45         }
46     }
47 
48     obsPair->second.push_back(dataObserver);
49 
50     AddObsDeathRecipient(dataObserver);
51 
52     return NO_ERROR;
53 }
54 
HandleUnregisterObserver(const Uri & uri,sptr<IDataAbilityObserver> dataObserver)55 int DataObsMgrInner::HandleUnregisterObserver(const Uri &uri, sptr<IDataAbilityObserver> dataObserver)
56 {
57     std::lock_guard<ffrt::mutex> lock(innerMutex_);
58 
59     auto obsPair = observers_.find(uri.ToString());
60     if (obsPair == observers_.end()) {
61         HILOG_WARN("no obs on this uri : %{public}s", CommonUtils::Anonymous(uri.ToString()).c_str());
62         return NO_OBS_FOR_URI;
63     }
64 
65     HILOG_DEBUG("obs num is %{public}zu on this uri : %{public}s", obsPair->second.size(),
66         CommonUtils::Anonymous(uri.ToString()).c_str());
67     auto obs = obsPair->second.begin();
68     for (; obs != obsPair->second.end(); obs++) {
69         if ((*obs)->AsObject() == dataObserver->AsObject()) {
70             break;
71         }
72     }
73     if (obs == obsPair->second.end()) {
74         HILOG_WARN("no obs on this uri : %{public}s", CommonUtils::Anonymous(uri.ToString()).c_str());
75         return NO_OBS_FOR_URI;
76     }
77     obsPair->second.remove(*obs);
78     if (obsPair->second.empty()) {
79         observers_.erase(obsPair);
80     }
81 
82     if (!HaveRegistered(dataObserver)) {
83         RemoveObsDeathRecipient(dataObserver->AsObject());
84     }
85 
86     return NO_ERROR;
87 }
88 
HandleNotifyChange(const Uri & uri)89 int DataObsMgrInner::HandleNotifyChange(const Uri &uri)
90 {
91     std::list<sptr<IDataAbilityObserver>> obsList;
92     std::lock_guard<ffrt::mutex> lock(innerMutex_);
93     {
94         auto obsPair = observers_.find(uri.ToString());
95         if (obsPair == observers_.end()) {
96             HILOG_DEBUG("there is no obs on the uri : %{public}s", CommonUtils::Anonymous(uri.ToString()).c_str());
97             return NO_OBS_FOR_URI;
98         }
99         obsList = obsPair->second;
100     }
101 
102     for (auto &obs : obsList) {
103         if (obs != nullptr) {
104             obs->OnChange();
105         }
106     }
107 
108     HILOG_DEBUG("called end on the uri : %{public}s,obs num: %{public}zu",
109         CommonUtils::Anonymous(uri.ToString()).c_str(), obsList.size());
110     return NO_ERROR;
111 }
112 
AddObsDeathRecipient(sptr<IDataAbilityObserver> dataObserver)113 void DataObsMgrInner::AddObsDeathRecipient(sptr<IDataAbilityObserver> dataObserver)
114 {
115     if ((dataObserver == nullptr) || dataObserver->AsObject() == nullptr) {
116         return;
117     }
118 
119     auto it = obsRecipient_.find(dataObserver->AsObject());
120     if (it != obsRecipient_.end()) {
121         HILOG_WARN("this death recipient has been added.");
122         return;
123     } else {
124         std::weak_ptr<DataObsMgrInner> thisWeakPtr(shared_from_this());
125         sptr<IRemoteObject::DeathRecipient> deathRecipient =
126             new DataObsCallbackRecipient([thisWeakPtr](const wptr<IRemoteObject> &remote) {
127                 auto dataObsMgrInner = thisWeakPtr.lock();
128                 if (dataObsMgrInner) {
129                     dataObsMgrInner->OnCallBackDied(remote);
130                 }
131             });
132         if (!dataObserver->AsObject()->AddDeathRecipient(deathRecipient)) {
133             HILOG_ERROR("AddDeathRecipient failed.");
134         }
135         obsRecipient_.emplace(dataObserver->AsObject(), deathRecipient);
136     }
137 }
138 
RemoveObsDeathRecipient(sptr<IRemoteObject> dataObserver)139 void DataObsMgrInner::RemoveObsDeathRecipient(sptr<IRemoteObject> dataObserver)
140 {
141     if (dataObserver == nullptr) {
142         return;
143     }
144 
145     auto it = obsRecipient_.find(dataObserver);
146     if (it != obsRecipient_.end()) {
147         it->first->RemoveDeathRecipient(it->second);
148         obsRecipient_.erase(it);
149         return;
150     }
151 }
152 
OnCallBackDied(const wptr<IRemoteObject> & remote)153 void DataObsMgrInner::OnCallBackDied(const wptr<IRemoteObject> &remote)
154 {
155     auto dataObserver = remote.promote();
156     if (dataObserver == nullptr) {
157         return;
158     }
159     std::lock_guard<ffrt::mutex> lock(innerMutex_);
160 
161     if (dataObserver == nullptr) {
162         HILOG_ERROR("dataObserver is nullptr.");
163         return;
164     }
165 
166     RemoveObs(dataObserver);
167 }
168 
RemoveObs(sptr<IRemoteObject> dataObserver)169 void DataObsMgrInner::RemoveObs(sptr<IRemoteObject> dataObserver)
170 {
171     for (auto iter = observers_.begin(); iter != observers_.end();) {
172         auto &obsList = iter->second;
173         for (auto it = obsList.begin(); it != obsList.end(); it++) {
174             if ((*it)->AsObject() == dataObserver) {
175                 HILOG_DEBUG("Erase an observer form list.");
176                 obsList.erase(it);
177                 break;
178             }
179         }
180         if (obsList.size() == 0) {
181             iter = observers_.erase(iter);
182         } else {
183             iter++;
184         }
185     }
186     RemoveObsDeathRecipient(dataObserver);
187 }
188 
HaveRegistered(sptr<IDataAbilityObserver> dataObserver)189 bool DataObsMgrInner::HaveRegistered(sptr<IDataAbilityObserver> dataObserver)
190 {
191     for (auto &[key, value] : observers_) {
192         auto obs = std::find(value.begin(), value.end(), dataObserver);
193         if (obs != value.end()) {
194             return true;
195         }
196     }
197     return false;
198 }
199 }  // namespace AAFwk
200 }  // namespace OHOS
201