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