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