1 /*
2 * Copyright (c) 2021-2024 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 <thread>
17 #include "dataobs_mgr_client.h"
18
19 #include "common_utils.h"
20 #include "dataobs_mgr_interface.h"
21 #include "datashare_log.h"
22 #include "hilog_tag_wrapper.h"
23 #include "if_system_ability_manager.h"
24 #include "iservice_registry.h"
25 #include "system_ability_definition.h"
26 #include "system_ability_status_change_stub.h"
27
28 namespace OHOS {
29 namespace AAFwk {
30 std::mutex DataObsMgrClient::mutex_;
31 constexpr const int32_t RETRY_MAX_TIMES = 100;
32 constexpr const int64_t RETRY_SLEEP_TIME_MILLISECOND = 1; // 1ms
33 using namespace DataShare;
34
35 class DataObsMgrClient::SystemAbilityStatusChangeListener
36 : public SystemAbilityStatusChangeStub {
37 public:
SystemAbilityStatusChangeListener()38 SystemAbilityStatusChangeListener()
39 {
40 }
41 ~SystemAbilityStatusChangeListener() = default;
42 void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override;
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)43 void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override
44 {
45 }
46 };
47
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)48 void DataObsMgrClient::SystemAbilityStatusChangeListener::OnAddSystemAbility(
49 int32_t systemAbilityId, const std::string &deviceId)
50 {
51 TAG_LOGI(AAFwkTag::DBOBSMGR, "called");
52 if (systemAbilityId != DATAOBS_MGR_SERVICE_SA_ID) {
53 return;
54 }
55 GetInstance()->ReRegister();
56 }
57
GetInstance()58 std::shared_ptr<DataObsMgrClient> DataObsMgrClient::GetInstance()
59 {
60 static std::shared_ptr<DataObsMgrClient> proxy = std::make_shared<DataObsMgrClient>();
61 return proxy;
62 }
63
DataObsMgrClient()64 DataObsMgrClient::DataObsMgrClient()
65 {
66 callback_ = new SystemAbilityStatusChangeListener();
67 }
68
~DataObsMgrClient()69 DataObsMgrClient::~DataObsMgrClient()
70 {
71 if (dataObsManger_ != nullptr) {
72 dataObsManger_->AsObject()->RemoveDeathRecipient(deathRecipient_);
73 }
74 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
75 if (systemManager == nullptr) {
76 TAG_LOGE(AAFwkTag::DBOBSMGR, "null systemmgr");
77 return;
78 }
79 auto res = systemManager->UnSubscribeSystemAbility(DATAOBS_MGR_SERVICE_SA_ID, callback_);
80 if (res != 0) {
81 TAG_LOGE(AAFwkTag::DBOBSMGR, "UnSubscribeSystemAbility failed, errCode is %{public}d.", res);
82 systemManager->UnSubscribeSystemAbility(DATAOBS_MGR_SERVICE_SA_ID, callback_);
83 }
84
85 int32_t retryTimes = 0;
86 while ((callback_ != nullptr) && (callback_->GetSptrRefCount() > 1) && (retryTimes < RETRY_MAX_TIMES)) {
87 retryTimes++;
88 std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_SLEEP_TIME_MILLISECOND));
89 }
90
91 if ((callback_ != nullptr) && (callback_->GetSptrRefCount() > 1)) {
92 TAG_LOGE(AAFwkTag::DBOBSMGR, "Callback has other in use: %{public}d.", callback_->GetSptrRefCount());
93 }
94 }
95
96 /**
97 * Registers an observer to DataObsMgr specified by the given Uri.
98 *
99 * @param uri, Indicates the path of the data to operate.
100 * @param dataObserver, Indicates the IDataAbilityObserver object.
101 *
102 * @return Returns ERR_OK on success, others on failure.
103 */
RegisterObserver(const Uri & uri,sptr<IDataAbilityObserver> dataObserver,int userId,DataObsOption opt)104 ErrCode DataObsMgrClient::RegisterObserver(const Uri &uri, sptr<IDataAbilityObserver> dataObserver, int userId,
105 DataObsOption opt)
106 {
107 auto [errCode, dataObsManger] = GetObsMgr();
108 if (errCode != SUCCESS) {
109 LOG_ERROR("Failed to get ObsMgr, errCode: %{public}d.", errCode);
110 return DATAOBS_SERVICE_NOT_CONNECTED;
111 }
112 auto status = dataObsManger->RegisterObserver(uri, dataObserver, userId, opt);
113 if (status != NO_ERROR) {
114 return status;
115 }
116 observers_.Compute(dataObserver, [&uri, userId](const auto &key, auto &value) {
117 value.emplace_back(uri, userId);
118 return true;
119 });
120 return status;
121 }
122
RegisterObserverFromExtension(const Uri & uri,sptr<IDataAbilityObserver> dataObserver,int userId,DataObsOption opt)123 ErrCode DataObsMgrClient::RegisterObserverFromExtension(const Uri &uri, sptr<IDataAbilityObserver> dataObserver,
124 int userId, DataObsOption opt)
125 {
126 auto [errCode, dataObsManger] = GetObsMgr();
127 if (errCode != SUCCESS) {
128 LOG_ERROR("Failed to get ObsMgr, errCode: %{public}d.", errCode);
129 return DATAOBS_SERVICE_NOT_CONNECTED;
130 }
131 auto status = dataObsManger->RegisterObserverFromExtension(uri, dataObserver, userId, opt);
132 if (status != NO_ERROR) {
133 return status;
134 }
135 uint32_t firstCallerTokenID = opt.FirstCallerTokenID();
136 observers_.Compute(dataObserver, [&uri, userId, firstCallerTokenID](const auto &key, auto &value) {
137 ObserverInfo info(uri, userId);
138 info.isExtension = true;
139 info.firstCallerTokenID = firstCallerTokenID;
140 value.emplace_back(uri, userId);
141 return true;
142 });
143 return status;
144 }
145
146 /**
147 * Deregisters an observer used for DataObsMgr specified by the given Uri.
148 *
149 * @param uri, Indicates the path of the data to operate.
150 * @param dataObserver, Indicates the IDataAbilityObserver object.
151 *
152 * @return Returns ERR_OK on success, others on failure.
153 */
UnregisterObserver(const Uri & uri,sptr<IDataAbilityObserver> dataObserver,int userId,DataObsOption opt)154 ErrCode DataObsMgrClient::UnregisterObserver(const Uri &uri, sptr<IDataAbilityObserver> dataObserver, int userId,
155 DataObsOption opt)
156 {
157 auto [errCode, dataObsManger] = GetObsMgr();
158 if (errCode != SUCCESS) {
159 return DATAOBS_SERVICE_NOT_CONNECTED;
160 }
161 auto status = dataObsManger->UnregisterObserver(uri, dataObserver, userId, opt);
162 if (status != NO_ERROR) {
163 return status;
164 }
165 observers_.Compute(dataObserver, [&uri, userId](const auto &key, auto &value) {
166 value.remove_if([&uri, userId](const auto &val) {
167 return uri == val.uri && userId == val.userId;
168 });
169 return !value.empty();
170 });
171 return status;
172 }
173
174 /**
175 * Notifies the registered observers of a change to the data resource specified by Uri.
176 *
177 * @param uri, Indicates the path of the data to operate.
178 *
179 * @return Returns ERR_OK on success, others on failure.
180 */
NotifyChange(const Uri & uri,int userId,DataObsOption opt)181 ErrCode DataObsMgrClient::NotifyChange(const Uri &uri, int userId, DataObsOption opt)
182 {
183 auto [errCode, dataObsManger] = GetObsMgr();
184 if (errCode != SUCCESS) {
185 return DATAOBS_SERVICE_NOT_CONNECTED;
186 }
187 return dataObsManger->NotifyChange(uri, userId, opt);
188 }
189
190 /**
191 * Notifies the registered observers of a change to the data resource specified by Uri.
192 *
193 * @param uri, Indicates the path of the data to operate.
194 *
195 * @return Returns ERR_OK on success, others on failure.
196 */
NotifyChangeFromExtension(const Uri & uri,int userId,DataObsOption opt)197 ErrCode DataObsMgrClient::NotifyChangeFromExtension(const Uri &uri, int userId, DataObsOption opt)
198 {
199 auto [errCode, dataObsManger] = GetObsMgr();
200 if (errCode != SUCCESS) {
201 return DATAOBS_SERVICE_NOT_CONNECTED;
202 }
203 return dataObsManger->NotifyChangeFromExtension(uri, userId, opt);
204 }
205
CheckTrusts(uint32_t consumerToken,uint32_t providerToken)206 ErrCode DataObsMgrClient::CheckTrusts(uint32_t consumerToken, uint32_t providerToken)
207 {
208 auto [errCode, dataObsManger] = GetObsMgr();
209 if (errCode != SUCCESS) {
210 return DATAOBS_SERVICE_NOT_CONNECTED;
211 }
212 return dataObsManger->CheckTrusts(consumerToken, providerToken);
213 }
214
215 /**
216 * Connect dataobs manager service.
217 *
218 * @return Returns SUCCESS on success, others on failure.
219 */
GetObsMgr()220 __attribute__ ((no_sanitize("cfi"))) std::pair<Status, sptr<IDataObsMgr>> DataObsMgrClient::GetObsMgr()
221 {
222 std::lock_guard<std::mutex> lock(mutex_);
223
224 if (dataObsManger_ != nullptr) {
225 return std::make_pair(SUCCESS, dataObsManger_);
226 }
227
228 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
229 if (systemManager == nullptr) {
230 TAG_LOGE(AAFwkTag::DBOBSMGR, "registry failed");
231 return std::make_pair(GET_DATAOBS_SERVICE_FAILED, nullptr);
232 }
233
234 auto remoteObject = systemManager->CheckSystemAbility(DATAOBS_MGR_SERVICE_SA_ID);
235 if (remoteObject == nullptr) {
236 TAG_LOGE(AAFwkTag::DBOBSMGR, "systemAbility failed");
237 return std::make_pair(GET_DATAOBS_SERVICE_FAILED, nullptr);
238 }
239
240 dataObsManger_ = iface_cast<IDataObsMgr>(remoteObject);
241 if (dataObsManger_ == nullptr) {
242 TAG_LOGE(AAFwkTag::DBOBSMGR, "iDataObsMgr failed");
243 return std::make_pair(GET_DATAOBS_SERVICE_FAILED, nullptr);
244 }
245 if (deathRecipient_ == nullptr) {
246 deathRecipient_ = new (std::nothrow) ServiceDeathRecipient(GetInstance());
247 }
248 dataObsManger_->AsObject()->AddDeathRecipient(deathRecipient_);
249 return std::make_pair(SUCCESS, dataObsManger_);
250 }
251
RegisterObserverExt(const Uri & uri,sptr<IDataAbilityObserver> dataObserver,bool isDescendants,DataObsOption opt)252 Status DataObsMgrClient::RegisterObserverExt(const Uri &uri, sptr<IDataAbilityObserver> dataObserver,
253 bool isDescendants, DataObsOption opt)
254 {
255 auto [errCode, dataObsManger] = GetObsMgr();
256 if (errCode != SUCCESS) {
257 return DATAOBS_SERVICE_NOT_CONNECTED;
258 }
259 auto status = dataObsManger->RegisterObserverExt(uri, dataObserver, isDescendants, opt);
260 if (status != SUCCESS) {
261 return status;
262 }
263 observerExts_.Compute(dataObserver, [&uri, isDescendants](const auto &key, auto &value) {
264 value.emplace_back(uri, isDescendants);
265 return true;
266 });
267 return status;
268 }
269
UnregisterObserverExt(const Uri & uri,sptr<IDataAbilityObserver> dataObserver,DataObsOption opt)270 Status DataObsMgrClient::UnregisterObserverExt(const Uri &uri, sptr<IDataAbilityObserver> dataObserver,
271 DataObsOption opt)
272 {
273 auto [errCode, dataObsManger] = GetObsMgr();
274 if (errCode != SUCCESS) {
275 return DATAOBS_SERVICE_NOT_CONNECTED;
276 }
277 auto status = dataObsManger->UnregisterObserverExt(uri, dataObserver);
278 if (status != SUCCESS) {
279 return status;
280 }
281 observerExts_.Compute(dataObserver, [&uri](const auto &key, auto &value) {
282 value.remove_if([&uri](const auto ¶m) {
283 return uri == param.uri;
284 });
285 return !value.empty();
286 });
287 return status;
288 }
289
UnregisterObserverExt(sptr<IDataAbilityObserver> dataObserver,DataObsOption opt)290 Status DataObsMgrClient::UnregisterObserverExt(sptr<IDataAbilityObserver> dataObserver, DataObsOption opt)
291 {
292 auto [errCode, dataObsManger] = GetObsMgr();
293 if (errCode != SUCCESS) {
294 return DATAOBS_SERVICE_NOT_CONNECTED;
295 }
296 auto status = dataObsManger->UnregisterObserverExt(dataObserver, opt);
297 if (status != SUCCESS) {
298 return status;
299 }
300 observerExts_.Erase(dataObserver);
301 return status;
302 }
303
NotifyChangeExt(const ChangeInfo & changeInfo,DataObsOption opt)304 Status DataObsMgrClient::NotifyChangeExt(const ChangeInfo &changeInfo, DataObsOption opt)
305 {
306 auto [errCode, dataObsManger] = GetObsMgr();
307 if (errCode != SUCCESS) {
308 return DATAOBS_SERVICE_NOT_CONNECTED;
309 }
310 return dataObsManger->NotifyChangeExt(changeInfo, opt);
311 }
312
NotifyProcessObserver(const std::string & key,const sptr<IRemoteObject> & observer,DataObsOption opt)313 Status DataObsMgrClient::NotifyProcessObserver(const std::string &key, const sptr<IRemoteObject> &observer,
314 DataObsOption opt)
315 {
316 if (key.empty() || observer == nullptr) {
317 TAG_LOGE(AAFwkTag::DBOBSMGR, "Null observer, key:%{public}s", key.c_str());
318 return INVALID_PARAM;
319 }
320 auto [errCode, dataObsManger] = GetObsMgr();
321 if (errCode != SUCCESS) {
322 return DATAOBS_SERVICE_NOT_CONNECTED;
323 }
324 return dataObsManger->NotifyProcessObserver(key, observer, opt);
325 }
326
ResetService()327 void DataObsMgrClient::ResetService()
328 {
329 std::lock_guard<std::mutex> lock(mutex_);
330 dataObsManger_ = nullptr;
331 }
332
OnRemoteDied()333 void DataObsMgrClient::OnRemoteDied()
334 {
335 std::this_thread::sleep_for(std::chrono::seconds(RESUB_INTERVAL));
336 ResetService();
337 auto [errCode, dataObsManger] = GetObsMgr();
338 if (errCode != SUCCESS) {
339 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
340 if (systemManager == nullptr) {
341 TAG_LOGE(AAFwkTag::DBOBSMGR, "null systemmgr");
342 return;
343 }
344 systemManager->SubscribeSystemAbility(DATAOBS_MGR_SERVICE_SA_ID, callback_);
345 return;
346 }
347 ReRegister();
348 }
349
ReRegister()350 void DataObsMgrClient::ReRegister()
351 {
352 decltype(observers_) observers(std::move(observers_));
353 observers_.Clear();
354 observers.ForEach([this](const auto &key, const auto &value) {
355 for (const auto &val : value) {
356 int32_t ret;
357 if (val.isExtension) {
358 DataObsOption opt;
359 opt.SetFirstCallerTokenID(val.firstCallerTokenID);
360 ret = RegisterObserverFromExtension(val.uri, key, val.userId, opt);
361 } else {
362 ret = RegisterObserver(val.uri, key, val.userId);
363 }
364 if (ret != SUCCESS) {
365 LOG_ERROR("RegisterObserver failed, uri:%{public}s, ret:%{public}d, isExtension %{public}d",
366 CommonUtils::Anonymous(val.uri.ToString()).c_str(), ret, val.isExtension);
367 }
368 }
369 return false;
370 });
371
372 decltype(observerExts_) observerExts(std::move(observerExts_));
373 observerExts_.Clear();
374 observerExts.ForEach([this](const auto &key, const auto &value) {
375 for (const auto ¶m : value) {
376 auto ret = RegisterObserverExt(param.uri, key, param.isDescendants);
377 if (ret != SUCCESS) {
378 LOG_ERROR(
379 "RegisterObserverExt failed, param.uri:%{public}s, ret:%{public}d, param.isDescendants:%{public}d",
380 CommonUtils::Anonymous(param.uri.ToString()).c_str(), ret, param.isDescendants
381 );
382 }
383 }
384 return false;
385 });
386 }
387 } // namespace AAFwk
388 } // namespace OHOS
389