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