• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #define LOG_TAG "DataShareHelper"
16 
17 #include "datashare_helper.h"
18 #include "datashare_helper_impl.h"
19 
20 #include "adaptor.h"
21 #include "concurrent_map.h"
22 #include "data_ability_observer_interface.h"
23 #include "data_ability_observer_stub.h"
24 #include "dataobs_mgr_client.h"
25 #include "datashare_errno.h"
26 #include "datashare_log.h"
27 #include "datashare_string_utils.h"
28 
29 namespace OHOS {
30 namespace DataShare {
31 using namespace AppExecFwk;
32 namespace {
33 static constexpr const char *DATA_SHARE_PREFIX = "datashare:///";
34 static constexpr const char *FILE_PREFIX = "file://";
35 } // namespace
36 class ObserverImpl : public AAFwk::DataAbilityObserverStub {
37 public:
ObserverImpl(const std::shared_ptr<DataShareObserver> dataShareObserver)38     explicit ObserverImpl(const std::shared_ptr<DataShareObserver> dataShareObserver)
39         : dataShareObserver_(dataShareObserver){};
40     void OnChange();
41     void OnChangeExt(const AAFwk::ChangeInfo &info);
42     static DataShareObserver::ChangeInfo ConvertInfo(const AAFwk::ChangeInfo &info);
43     static AAFwk::ChangeInfo ConvertInfo(const DataShareObserver::ChangeInfo &info);
44     static sptr<ObserverImpl> GetObserver(const Uri& uri, const std::shared_ptr<DataShareObserver> &observer);
45     static bool FindObserver(const Uri& uri, const std::shared_ptr<DataShareObserver> &observer);
46     static bool DeleteObserver(const Uri& uri, const std::shared_ptr<DataShareObserver> &observer);
47 private:
48     struct ObserverParam {
49         sptr<ObserverImpl> obs_;
50         std::list<Uri> uris_;
51     };
52     std::shared_ptr<DataShareObserver> dataShareObserver_;
53     static ConcurrentMap<DataShareObserver *, ObserverParam> observers_;
54 };
55 
56 ConcurrentMap<DataShareObserver *, ObserverImpl::ObserverParam> ObserverImpl::observers_;
57 
TransferUriPrefix(const std::string & originPrefix,const std::string & replacedPrefix,const std::string & originUriStr)58 std::string DataShareHelper::TransferUriPrefix(const std::string &originPrefix, const std::string &replacedPrefix,
59     const std::string &originUriStr)
60 {
61     if (originUriStr.find(originPrefix) != 0) {
62         return originUriStr;
63     }
64     return replacedPrefix + originUriStr.substr(originPrefix.length());
65 }
66 
67 /**
68  * @brief You can use this method to specify the Uri of the data to operate and set the binding relationship
69  * between the ability using the Data template (data share for short) and the associated client process in
70  * a DataShareHelper instance.
71  *
72  * @param token Indicates the System token.
73  * @param strUri Indicates the database table or disk file to operate.
74  *
75  * @return Returns the created DataShareHelper instance.
76  */
Creator(const sptr<IRemoteObject> & token,const std::string & strUri,const std::string & extUri,const int waitTime,bool isSystem)77 std::shared_ptr<DataShareHelper> DataShareHelper::Creator(const sptr<IRemoteObject> &token, const std::string &strUri,
78     const std::string &extUri, const int waitTime, bool isSystem)
79 {
80     DISTRIBUTED_DATA_HITRACE(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__));
81     if (token == nullptr) {
82         LOG_ERROR("token == nullptr");
83         return nullptr;
84     }
85 
86     std::string replacedUriStr = TransferUriPrefix(FILE_PREFIX, DATA_SHARE_PREFIX, strUri);
87     Uri uri(replacedUriStr);
88     std::shared_ptr<DataShareHelper> helper = nullptr;
89     if (uri.GetQuery().find("Proxy=true") != std::string::npos) {
90         auto result = CreateServiceHelper(extUri, "", isSystem);
91         if (result != nullptr && GetSilentProxyStatus(strUri, isSystem) == E_OK) {
92             return result;
93         }
94         if (extUri.empty()) {
95             return nullptr;
96         }
97         Uri ext(extUri);
98         helper = CreateExtHelper(ext, token, waitTime, isSystem);
99     } else {
100         helper = CreateExtHelper(uri, token, waitTime, isSystem);
101     }
102     return helper;
103 }
104 
Creator(const string & strUri,const CreateOptions & options,const std::string & bundleName,const int waitTime,bool isSystem)105 std::shared_ptr<DataShareHelper> DataShareHelper::Creator(const string &strUri, const CreateOptions &options,
106     const std::string &bundleName, const int waitTime, bool isSystem)
107 {
108     DISTRIBUTED_DATA_HITRACE(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__));
109     Uri uri(strUri);
110     if (!options.isProxy_ && options.token_ == nullptr) {
111         LOG_ERROR("token is nullptr");
112         return nullptr;
113     }
114     return options.isProxy_ ? CreateServiceHelper("", bundleName, isSystem)
115         : CreateExtHelper(uri, options.token_, waitTime, isSystem);
116 }
117 
Create(const sptr<IRemoteObject> & token,const std::string & strUri,const std::string & extUri,const int waitTime)118 std::pair<int, std::shared_ptr<DataShareHelper>> DataShareHelper::Create(const sptr<IRemoteObject> &token,
119     const std::string &strUri, const std::string &extUri, const int waitTime)
120 {
121     DISTRIBUTED_DATA_HITRACE(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__));
122     if (token == nullptr) {
123         LOG_ERROR("Create helper failed, err: %{public}d", E_TOKEN_EMPTY);
124         return std::make_pair(E_TOKEN_EMPTY, nullptr);
125     }
126     Uri uri(strUri);
127     if (IsProxy(uri)) {
128         auto [ret, helper] = CreateProxyHelper(strUri, extUri);
129         if (helper != nullptr) {
130             return std::make_pair(E_OK, helper);
131         }
132         if (ret == E_BMS_NOT_READY) {
133             LOG_ERROR("BMS not ready, uri:%{publish}s", DataShareStringUtils::Change(strUri).c_str());
134             return std::make_pair(E_DATA_SHARE_NOT_READY, nullptr);
135         }
136         if (ret == E_BUNDLE_NAME_NOT_EXIST) {
137             LOG_ERROR("BundleName not exist, uri:%{publish}s", DataShareStringUtils::Change(strUri).c_str());
138             return std::make_pair(E_BUNDLE_NAME_NOT_EXIST, nullptr);
139         }
140         if (extUri.empty()) {
141             LOG_ERROR("Ext uri empty, err: %{public}d", E_EXT_URI_INVALID);
142             return std::make_pair(E_EXT_URI_INVALID, nullptr);
143         }
144         uri = Uri(extUri);
145     }
146     // this create func is inner api, do not check system permission
147     auto helper = CreateExtHelper(uri, token, waitTime, false);
148     if (helper != nullptr) {
149         return std::make_pair(E_OK, helper);
150     }
151     return std::make_pair(E_ERROR, nullptr);
152 }
153 
CreateServiceHelper(const std::string & extUri,const std::string & bundleName,bool isSystem)154 std::shared_ptr<DataShareHelper> DataShareHelper::CreateServiceHelper(const std::string &extUri,
155     const std::string &bundleName, bool isSystem)
156 {
157     auto manager = DataShareManagerImpl::GetInstance();
158     if (manager == nullptr) {
159         LOG_ERROR("Manager is nullptr");
160         return nullptr;
161     }
162     manager->SetBundleName(bundleName);
163     if (DataShareManagerImpl::GetServiceProxy() == nullptr) {
164         LOG_ERROR("Service proxy is nullptr.");
165         return nullptr;
166     }
167     return std::make_shared<DataShareHelperImpl>(extUri, isSystem);
168 }
169 
GetSilentProxyStatus(const std::string & uri,bool isSystem)170 int DataShareHelper::GetSilentProxyStatus(const std::string &uri, bool isSystem)
171 {
172     auto proxy = DataShareManagerImpl::GetServiceProxy();
173     if (proxy == nullptr) {
174         LOG_ERROR("Service proxy is nullptr.");
175         return E_ERROR;
176     }
177     DataShareServiceProxy::SetSystem(isSystem);
178     auto res = proxy->GetSilentProxyStatus(uri);
179     DataShareServiceProxy::CleanSystem();
180     return res;
181 }
182 
CreateExtHelper(Uri & uri,const sptr<IRemoteObject> & token,const int waitTime,bool isSystem)183 std::shared_ptr<DataShareHelper> DataShareHelper::CreateExtHelper(Uri &uri, const sptr<IRemoteObject> &token,
184     const int waitTime, bool isSystem)
185 {
186     if (uri.GetQuery().find("appIndex=") != std::string::npos) {
187         LOG_ERROR("ExtHelper do not support appIndex. Uri:%{public}s",
188             DataShareStringUtils::Anonymous(uri.ToString()).c_str());
189         return nullptr;
190     }
191     sptr<DataShareConnection> connection = new (std::nothrow) DataShareConnection(uri, token, waitTime);
192     if (connection == nullptr) {
193         LOG_ERROR("Create DataShareConnection failed.");
194         return nullptr;
195     }
196     auto dataShareConnection =
197         std::shared_ptr<DataShareConnection>(connection.GetRefPtr(), [holder = connection](const auto *) {
198             holder->SetConnectInvalid();
199             holder->DisconnectDataShareExtAbility();
200         });
201     auto manager = DataShareManagerImpl::GetInstance();
202     if (manager == nullptr) {
203         LOG_ERROR("Manager is nullptr");
204         return nullptr;
205     }
206     manager->SetCallCount(__FUNCTION__, uri.ToString());
207     if (dataShareConnection->GetDataShareProxy(uri, token) == nullptr) {
208         LOG_ERROR("connect failed");
209         return nullptr;
210     }
211     return std::make_shared<DataShareHelperImpl>(uri, token, dataShareConnection, isSystem);
212 }
213 
214 /**
215  * Registers an observer to DataObsMgr specified by the given Uri.
216  *
217  * @param uri, Indicates the path of the data to operate.
218  * @param dataObserver, Indicates the DataShareObserver object.
219  * @param isDescendants, Indicates the Whether to note the change of descendants.
220  */
RegisterObserverExt(const Uri & uri,std::shared_ptr<DataShareObserver> dataObserver,bool isDescendants,bool isSystem)221 void DataShareHelper::RegisterObserverExt(const Uri &uri, std::shared_ptr<DataShareObserver> dataObserver,
222     bool isDescendants, bool isSystem)
223 {
224     if (dataObserver == nullptr) {
225         LOG_ERROR("dataObserver is nullptr");
226         return;
227     }
228     auto obsMgrClient = OHOS::AAFwk::DataObsMgrClient::GetInstance();
229     if (obsMgrClient == nullptr) {
230         LOG_ERROR("get DataObsMgrClient failed");
231         return;
232     }
233     sptr<ObserverImpl> obs = ObserverImpl::GetObserver(uri, dataObserver);
234     if (obs == nullptr) {
235         LOG_ERROR("new ObserverImpl failed");
236         return;
237     }
238     ErrCode ret = obsMgrClient->RegisterObserverExt(uri, obs, isDescendants);
239     if (ret != ERR_OK) {
240         ObserverImpl::DeleteObserver(uri, dataObserver);
241     }
242     LOG_INFO("Register observerExt, ret:%{public}d, uri:%{public}s",
243         ret, DataShareStringUtils::Anonymous(uri.ToString()).c_str());
244 }
245 
246 /**
247  * Deregisters an observer used for DataObsMgr specified by the given Uri.
248  *
249  * @param uri, Indicates the path of the data to operate.
250  * @param dataObserver, Indicates the DataShareObserver object.
251  */
UnregisterObserverExt(const Uri & uri,std::shared_ptr<DataShareObserver> dataObserver,bool isSystem)252 void DataShareHelper::UnregisterObserverExt(const Uri &uri, std::shared_ptr<DataShareObserver> dataObserver,
253     bool isSystem)
254 {
255     if (dataObserver == nullptr) {
256         LOG_ERROR("dataObserver is nullptr");
257         return;
258     }
259     auto obsMgrClient = OHOS::AAFwk::DataObsMgrClient::GetInstance();
260     if (obsMgrClient == nullptr) {
261         LOG_ERROR("get DataObsMgrClient failed");
262         return;
263     }
264 
265     if (!ObserverImpl::FindObserver(uri, dataObserver)) {
266         LOG_ERROR("observer not exit!");
267         return;
268     }
269 
270     sptr<ObserverImpl> obs = ObserverImpl::GetObserver(uri, dataObserver);
271     if (obs == nullptr) {
272         LOG_ERROR("new ObserverImpl failed");
273         return;
274     }
275     ErrCode ret = obsMgrClient->UnregisterObserverExt(uri, obs);
276     LOG_INFO("Unregister observerExt, ret:%{public}d, uri:%{public}s",
277         ret, DataShareStringUtils::Anonymous(uri.ToString()).c_str());
278     if (ret != ERR_OK) {
279         return;
280     }
281     ObserverImpl::DeleteObserver(uri, dataObserver);
282 }
283 
284 /**
285  * Notifies the registered observers of a change to the data resource specified by Uris.
286  *
287  * @param changeInfo Indicates the info of the data to operate.
288  */
NotifyChangeExt(const DataShareObserver::ChangeInfo & changeInfo,bool isSystem)289 void DataShareHelper::NotifyChangeExt(const DataShareObserver::ChangeInfo &changeInfo, bool isSystem)
290 {
291     auto obsMgrClient = OHOS::AAFwk::DataObsMgrClient::GetInstance();
292     if (obsMgrClient == nullptr) {
293         LOG_ERROR("get DataObsMgrClient failed");
294         return;
295     }
296 
297     ErrCode ret = obsMgrClient->NotifyChangeExt(ObserverImpl::ConvertInfo(changeInfo));
298     LOG_INFO("Notify changeExt, ret:%{public}d", ret);
299 }
300 
OnChange()301 void ObserverImpl::OnChange() {}
302 
OnChangeExt(const AAFwk::ChangeInfo & info)303 void ObserverImpl::OnChangeExt(const AAFwk::ChangeInfo &info)
304 {
305     dataShareObserver_->OnChange(ConvertInfo(info));
306 }
307 
ConvertInfo(const AAFwk::ChangeInfo & info)308 DataShareObserver::ChangeInfo ObserverImpl::ConvertInfo(const AAFwk::ChangeInfo &info)
309 {
310     DataShareObserver::ChangeInfo changeInfo;
311     changeInfo.changeType_ = static_cast<const DataShareObserver::ChangeType>(info.changeType_);
312     changeInfo.uris_ = std::move(info.uris_);
313     changeInfo.data_ = info.data_;
314     changeInfo.size_ = info.size_;
315     changeInfo.valueBuckets_ = std::move(info.valueBuckets_);
316     return changeInfo;
317 }
318 
ConvertInfo(const DataShareObserver::ChangeInfo & info)319 AAFwk::ChangeInfo ObserverImpl::ConvertInfo(const DataShareObserver::ChangeInfo &info)
320 {
321     AAFwk::ChangeInfo changeInfo;
322     changeInfo.changeType_ = static_cast<const AAFwk::ChangeInfo::ChangeType>(info.changeType_);
323     changeInfo.uris_ = std::move(info.uris_);
324     changeInfo.data_ = const_cast<void*>(info.data_);
325     changeInfo.size_ = info.size_;
326     changeInfo.valueBuckets_ =std::move(info.valueBuckets_);
327     return changeInfo;
328 }
329 
GetObserver(const Uri & uri,const std::shared_ptr<DataShareObserver> & observer)330 sptr<ObserverImpl> ObserverImpl::GetObserver(const Uri& uri, const std::shared_ptr<DataShareObserver> &observer)
331 {
332     sptr<ObserverImpl> result = nullptr;
333     observers_.Compute(observer.get(), [&result, &uri, &observer](const auto &key, auto &value) {
334         if (value.obs_ == nullptr) {
335             value.obs_ = new (std::nothrow) ObserverImpl(observer);
336             value.uris_.push_back(uri);
337         } else {
338             auto it = std::find(value.uris_.begin(), value.uris_.end(), uri);
339             if (it == value.uris_.end()) {
340                 value.uris_.push_back(uri);
341             }
342         }
343 
344         result = value.obs_;
345         return result != nullptr;
346     });
347 
348     return result;
349 }
350 
FindObserver(const Uri & uri,const std::shared_ptr<DataShareObserver> & observer)351 bool ObserverImpl::FindObserver(const Uri& uri, const std::shared_ptr<DataShareObserver> &observer)
352 {
353     auto result = observers_.Find(observer.get());
354     if (result.first) {
355         auto it = std::find(result.second.uris_.begin(), result.second.uris_.end(), uri);
356         if (it == result.second.uris_.end()) {
357             return false;
358         }
359     }
360     return result.first;
361 }
362 
DeleteObserver(const Uri & uri,const std::shared_ptr<DataShareObserver> & observer)363 bool ObserverImpl::DeleteObserver(const Uri& uri, const std::shared_ptr<DataShareObserver> &observer)
364 {
365     return observers_.ComputeIfPresent(observer.get(), [&uri](auto &key, auto &value) {
366         value.uris_.remove_if([&uri](const auto &value) {
367             return uri == value;
368         });
369         return !value.uris_.empty();
370     });
371 }
372 
SetSilentSwitch(Uri & uri,bool enable,bool isSystem)373 int DataShareHelper::SetSilentSwitch(Uri &uri, bool enable, bool isSystem)
374 {
375     auto proxy = DataShareManagerImpl::GetServiceProxy();
376     if (proxy == nullptr) {
377         LOG_ERROR("proxy is nullptr");
378         return DATA_SHARE_ERROR;
379     }
380     DataShareServiceProxy::SetSystem(isSystem);
381     auto res = proxy->SetSilentSwitch(uri, enable);
382     DataShareServiceProxy::CleanSystem();
383     return res;
384 }
385 
IsProxy(Uri & uri)386 bool DataShareHelper::IsProxy(Uri &uri)
387 {
388     return (uri.GetQuery().find("Proxy=true") != std::string::npos || uri.GetScheme() == "datashareproxy");
389 }
390 
CreateProxyHelper(const std::string & strUri,const std::string & extUri)391 std::pair<int, std::shared_ptr<DataShareHelper>> DataShareHelper::CreateProxyHelper(const std::string &strUri,
392     const std::string &extUri)
393 {
394     int ret = GetSilentProxyStatus(strUri, false);
395     auto helper = ret == E_OK ? CreateServiceHelper(extUri) : nullptr;
396     return std::make_pair(ret, helper);
397 }
398 
InsertEx(Uri & uri,const DataShareValuesBucket & value)399 std::pair<int32_t, int32_t> DataShareHelper::InsertEx(Uri &uri, const DataShareValuesBucket &value)
400 {
401     return std::make_pair(0, 0);
402 }
403 
DeleteEx(Uri & uri,const DataSharePredicates & predicates)404 std::pair<int32_t, int32_t> DataShareHelper::DeleteEx(Uri &uri, const DataSharePredicates &predicates)
405 {
406     return std::make_pair(0, 0);
407 }
408 
UpdateEx(Uri & uri,const DataSharePredicates & predicates,const DataShareValuesBucket & value)409 std::pair<int32_t, int32_t> DataShareHelper::UpdateEx(Uri &uri, const DataSharePredicates &predicates,
410     const DataShareValuesBucket &value)
411 {
412     return std::make_pair(0, 0);
413 }
414 
UserDefineFunc(MessageParcel & data,MessageParcel & reply,MessageOption & option)415 int32_t DataShareHelper::UserDefineFunc(MessageParcel &data, MessageParcel &reply, MessageOption &option)
416 {
417     return 0;
418 }
419 } // namespace DataShare
420 } // namespace OHOS