• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &param) {
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 &param : 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