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 "data_ability_helper.h"
17 #include "abs_shared_result_set.h"
18 #include "datashare_helper.h"
19 #include "hilog_tag_wrapper.h"
20 #include "hitrace_meter.h"
21 #include "rdb_data_ability_utils.h"
22 
23 namespace OHOS {
24 namespace AppExecFwk {
25 using namespace OHOS::RdbDataAbilityAdapter;
DataAbilityHelper(const std::shared_ptr<DataAbilityHelperImpl> & helperImpl)26 DataAbilityHelper::DataAbilityHelper(const std::shared_ptr<DataAbilityHelperImpl> &helperImpl)
27 {
28     dataAbilityHelperImpl_ = helperImpl;
29 }
30 
DataAbilityHelper(const std::shared_ptr<DataShare::DataShareHelper> & dataShareHelper)31 DataAbilityHelper::DataAbilityHelper(const std::shared_ptr<DataShare::DataShareHelper> &dataShareHelper)
32 {
33     dataShareHelper_ = dataShareHelper;
34 }
35 
36 /**
37  * @brief Creates a DataAbilityHelper instance without specifying the Uri based on the given Context.
38  *
39  * @param context Indicates the Context object on OHOS.
40  *
41  * @return Returns the created DataAbilityHelper instance where Uri is not specified.
42  */
Creator(const std::shared_ptr<Context> context)43 std::shared_ptr<DataAbilityHelper> DataAbilityHelper::Creator(const std::shared_ptr<Context> context)
44 {
45     TAG_LOGI(AAFwkTag::DATA_ABILITY, "Creator with context");
46     DataAbilityHelper *ptrDataAbilityHelper = nullptr;
47     std::shared_ptr<DataAbilityHelperImpl> dataAbilityHelperImpl = DataAbilityHelperImpl::Creator(context);
48     if (dataAbilityHelperImpl) {
49         ptrDataAbilityHelper = new DataAbilityHelper(dataAbilityHelperImpl);
50     }
51     return std::shared_ptr<DataAbilityHelper>(ptrDataAbilityHelper);
52 }
53 
54 /**
55  * @brief Creates a DataAbilityHelper instance with the Uri specified based on the given Context.
56  *
57  * @param context Indicates the Context object on OHOS.
58  * @param uri Indicates the database table or disk file to operate.
59  *
60  * @return Returns the created DataAbilityHelper instance with a specified Uri.
61  */
Creator(const std::shared_ptr<Context> context,const std::shared_ptr<Uri> & uri)62 std::shared_ptr<DataAbilityHelper> DataAbilityHelper::Creator(
63     const std::shared_ptr<Context> context, const std::shared_ptr<Uri> &uri)
64 {
65     TAG_LOGI(AAFwkTag::DATA_ABILITY, "Creator with context & uri");
66     if (!context || !uri) {
67         TAG_LOGE(AAFwkTag::DATA_ABILITY, "invalid param");
68         return nullptr;
69     }
70     auto sharedPtrDataAbilityHelper = DataAbilityHelper::Creator(context, uri, false);
71     if (sharedPtrDataAbilityHelper) {
72         return sharedPtrDataAbilityHelper;
73     }
74 
75     TAG_LOGI(AAFwkTag::DATA_ABILITY, "Creator failed");
76     Uri dataShareUri("");
77     if (!DataAbilityHelper::TransferScheme(*uri, dataShareUri)) {
78         return nullptr;
79     }
80     DataAbilityHelper *ptrDataAbilityHelper = nullptr;
81     auto dataShareHelper = DataShare::DataShareHelper::Creator(context->GetToken(), dataShareUri.ToString());
82     if (dataShareHelper) {
83         ptrDataAbilityHelper = new DataAbilityHelper(dataShareHelper);
84     }
85     TAG_LOGD(AAFwkTag::DATA_ABILITY, "end");
86     return std::shared_ptr<DataAbilityHelper>(ptrDataAbilityHelper);
87 }
88 
89 /**
90  * @brief Creates a DataAbilityHelper instance with the Uri specified based on the given Context.
91  *
92  * @param context Indicates the Context object on OHOS.
93  * @param uri Indicates the database table or disk file to operate.
94  *
95  * @return Returns the created DataAbilityHelper instance with a specified Uri.
96  */
Creator(const std::shared_ptr<OHOS::AbilityRuntime::Context> context,const std::shared_ptr<Uri> & uri)97 std::shared_ptr<DataAbilityHelper> DataAbilityHelper::Creator(
98     const std::shared_ptr<OHOS::AbilityRuntime::Context> context, const std::shared_ptr<Uri> &uri)
99 {
100     TAG_LOGI(AAFwkTag::DATA_ABILITY, "Creator with ability runtime context & uri");
101     if (!context || !uri) {
102         TAG_LOGE(AAFwkTag::DATA_ABILITY, "invalid param");
103         return nullptr;
104     }
105     auto sharedPtrDataAbilityHelper = DataAbilityHelper::Creator(context, uri, false);
106     if (sharedPtrDataAbilityHelper) {
107         return sharedPtrDataAbilityHelper;
108     }
109 
110     TAG_LOGI(AAFwkTag::DATA_ABILITY, "Creator failed");
111     Uri dataShareUri("");
112     if (!DataAbilityHelper::TransferScheme(*uri, dataShareUri)) {
113         return nullptr;
114     }
115     DataAbilityHelper *ptrDataAbilityHelper = nullptr;
116     auto dataShareHelper = DataShare::DataShareHelper::Creator(context->GetToken(), dataShareUri.ToString());
117     if (dataShareHelper) {
118         ptrDataAbilityHelper = new DataAbilityHelper(dataShareHelper);
119     }
120     return std::shared_ptr<DataAbilityHelper>(ptrDataAbilityHelper);
121 }
122 
123 /**
124  * @brief You can use this method to specify the Uri of the data to operate and set the binding relationship
125  * between the ability using the Data template (Data ability for short) and the associated client process in
126  * a DataAbilityHelper instance.
127  *
128  * @param context Indicates the Context object on OHOS.
129  * @param uri Indicates the database table or disk file to operate.
130  * @param tryBind Specifies whether the exit of the corresponding Data ability process causes the exit of the
131  * client process.
132  *
133  * @return Returns the created DataAbilityHelper instance.
134  */
Creator(const std::shared_ptr<Context> context,const std::shared_ptr<Uri> & uri,const bool tryBind)135 std::shared_ptr<DataAbilityHelper> DataAbilityHelper::Creator(
136     const std::shared_ptr<Context> context, const std::shared_ptr<Uri> &uri, const bool tryBind)
137 {
138     TAG_LOGI(AAFwkTag::DATA_ABILITY, "Creator with context & uri & tryBind");
139     DataAbilityHelper *ptrDataAbilityHelper = nullptr;
140     auto dataAbilityHelperImpl = DataAbilityHelperImpl::Creator(context, uri, tryBind);
141     if (dataAbilityHelperImpl) {
142         ptrDataAbilityHelper = new DataAbilityHelper(dataAbilityHelperImpl);
143     }
144     return std::shared_ptr<DataAbilityHelper>(ptrDataAbilityHelper);
145 }
146 
147 /**
148  * @brief You can use this method to specify the Uri of the data to operate and set the binding relationship
149  * between the ability using the Data template (Data ability for short) and the associated client process in
150  * a DataAbilityHelper instance.
151  *
152  * @param context Indicates the Context object on OHOS.
153  * @param uri Indicates the database table or disk file to operate.
154  * @param tryBind Specifies whether the exit of the corresponding Data ability process causes the exit of the
155  * client process.
156  *
157  * @return Returns the created DataAbilityHelper instance.
158  */
Creator(const std::shared_ptr<OHOS::AbilityRuntime::Context> context,const std::shared_ptr<Uri> & uri,const bool tryBind)159 std::shared_ptr<DataAbilityHelper> DataAbilityHelper::Creator(
160     const std::shared_ptr<OHOS::AbilityRuntime::Context> context, const std::shared_ptr<Uri> &uri, const bool tryBind)
161 {
162     TAG_LOGI(
163         AAFwkTag::DATA_ABILITY, "Creator with ability runtime context & uri & tryBind");
164     DataAbilityHelper *ptrDataAbilityHelper = nullptr;
165     auto dataAbilityHelperImpl = DataAbilityHelperImpl::Creator(context, uri, tryBind);
166     if (dataAbilityHelperImpl) {
167         ptrDataAbilityHelper = new DataAbilityHelper(dataAbilityHelperImpl);
168     }
169     return std::shared_ptr<DataAbilityHelper>(ptrDataAbilityHelper);
170 }
171 
172 /**
173  * @brief Creates a DataAbilityHelper instance without specifying the Uri based.
174  *
175  * @param token Indicates the System token.
176  *
177  * @return Returns the created DataAbilityHelper instance where Uri is not specified.
178  */
Creator(const sptr<IRemoteObject> token)179 std::shared_ptr<DataAbilityHelper> DataAbilityHelper::Creator(const sptr<IRemoteObject> token)
180 {
181     TAG_LOGI(AAFwkTag::DATA_ABILITY, "Creator with token");
182     DataAbilityHelper *ptrDataAbilityHelper = nullptr;
183     auto dataAbilityHelperImpl = DataAbilityHelperImpl::Creator(token);
184     if (dataAbilityHelperImpl) {
185         ptrDataAbilityHelper = new DataAbilityHelper(dataAbilityHelperImpl);
186     }
187     return std::shared_ptr<DataAbilityHelper>(ptrDataAbilityHelper);
188 }
189 
190 /**
191  * @brief You can use this method to specify the Uri of the data to operate and set the binding relationship
192  * between the ability using the Data template (Data ability for short) and the associated client process in
193  * a DataAbilityHelper instance.
194  *
195  * @param token Indicates the System token.
196  * @param uri Indicates the database table or disk file to operate.
197  *
198  * @return Returns the created DataAbilityHelper instance.
199  */
Creator(const sptr<IRemoteObject> token,const std::shared_ptr<Uri> & uri)200 std::shared_ptr<DataAbilityHelper> DataAbilityHelper::Creator(
201     const sptr<IRemoteObject> token, const std::shared_ptr<Uri> &uri)
202 {
203     TAG_LOGI(AAFwkTag::DATA_ABILITY, "Creator with token & uri");
204     if (!token || !uri) {
205         TAG_LOGE(AAFwkTag::DATA_ABILITY, "invalid param");
206         return nullptr;
207     }
208     DataAbilityHelper *ptrDataAbilityHelper = nullptr;
209     auto dataAbilityHelperImpl = DataAbilityHelperImpl::Creator(token, uri);
210     if (dataAbilityHelperImpl) {
211         ptrDataAbilityHelper = new DataAbilityHelper(dataAbilityHelperImpl);
212     } else {
213         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Creator failed");
214         Uri dataShareUri("");
215         if (!DataAbilityHelper::TransferScheme(*uri, dataShareUri)) {
216             return nullptr;
217         }
218         auto dataShareHelper = DataShare::DataShareHelper::Creator(token, dataShareUri.ToString());
219         if (dataShareHelper) {
220             ptrDataAbilityHelper = new DataAbilityHelper(dataShareHelper);
221         }
222     }
223     return std::shared_ptr<DataAbilityHelper>(ptrDataAbilityHelper);
224 }
225 
226 /**
227  * @brief Releases the client resource of the Data ability.
228  * You should call this method to releases client resource after the data operations are complete.
229  *
230  * @return Returns true if the resource is successfully released; returns false otherwise.
231  */
Release()232 bool DataAbilityHelper::Release()
233 {
234     TAG_LOGI(AAFwkTag::DATA_ABILITY, "called");
235     bool ret = false;
236     if (dataAbilityHelperImpl_) {
237         TAG_LOGI(AAFwkTag::DATA_ABILITY, "DataAbilityHelperImpl Release");
238         ret = dataAbilityHelperImpl_->Release();
239     }
240     if (dataShareHelper_) {
241         TAG_LOGI(AAFwkTag::DATA_ABILITY, "DataShareHelper Release");
242         ret = dataShareHelper_->Release();
243         dataShareHelper_.reset();
244     }
245     return ret;
246 }
247 
248 /**
249  * @brief Obtains the MIME types of files supported.
250  *
251  * @param uri Indicates the path of the files to obtain.
252  * @param mimeTypeFilter Indicates the MIME types of the files to obtain. This parameter cannot be null.
253  *
254  * @return Returns the matched MIME types. If there is no match, null is returned.
255  */
GetFileTypes(Uri & uri,const std::string & mimeTypeFilter)256 std::vector<std::string> DataAbilityHelper::GetFileTypes(Uri &uri, const std::string &mimeTypeFilter)
257 {
258     HITRACE_METER_NAME(HITRACE_TAG_DISTRIBUTEDDATA, __PRETTY_FUNCTION__);
259     TAG_LOGI(AAFwkTag::DATA_ABILITY, "called");
260     std::vector<std::string> matchedMIMEs;
261     auto dataAbilityHelperImpl = GetDataAbilityHelperImpl();
262     if (dataAbilityHelperImpl) {
263         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Ability GetFileTypes");
264         matchedMIMEs = dataAbilityHelperImpl->GetFileTypes(uri, mimeTypeFilter);
265     }
266     auto dataShareHelper = GetDataShareHelper();
267     if (dataShareHelper) {
268         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Share GetFileTypes");
269         Uri dataShareUri("");
270         if (TransferScheme(uri, dataShareUri)) {
271             matchedMIMEs = dataShareHelper->GetFileTypes(dataShareUri, mimeTypeFilter);
272         }
273     }
274     return matchedMIMEs;
275 }
276 
277 /**
278  * @brief Opens a file in a specified remote path.
279  *
280  * @param uri Indicates the path of the file to open.
281  * @param mode Indicates the file open mode, which can be "r" for read-only access, "w" for write-only access
282  * (erasing whatever data is currently in the file), "wt" for write access that truncates any existing file,
283  * "wa" for write-only access to append to any existing data, "rw" for read and write access on any existing data,
284  *  or "rwt" for read and write access that truncates any existing file.
285  *
286  * @return Returns the file descriptor.
287  */
OpenFile(Uri & uri,const std::string & mode)288 int DataAbilityHelper::OpenFile(Uri &uri, const std::string &mode)
289 {
290     TAG_LOGI(AAFwkTag::DATA_ABILITY, "called");
291     int fd = -1;
292     auto dataAbilityHelperImpl = GetDataAbilityHelperImpl();
293     if (dataAbilityHelperImpl) {
294         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Ability OpenFile");
295         fd = dataAbilityHelperImpl->OpenFile(uri, mode);
296     }
297     auto dataShareHelper = GetDataShareHelper();
298     if (dataShareHelper) {
299         if (callFromJs_) {
300             TAG_LOGE(AAFwkTag::DATA_ABILITY, "Share no this interface");
301         } else {
302             TAG_LOGI(AAFwkTag::DATA_ABILITY, "Share OpenFile");
303             Uri dataShareUri("");
304             if (TransferScheme(uri, dataShareUri)) {
305                 fd = dataShareHelper->OpenFile(dataShareUri, mode);
306             }
307         }
308     }
309     return fd;
310 }
311 
312 /**
313  * @brief This is like openFile, open a file that need to be able to return sub-sections of files,often assets
314  * inside of their .hap.
315  *
316  * @param uri Indicates the path of the file to open.
317  * @param mode Indicates the file open mode, which can be "r" for read-only access, "w" for write-only access
318  * (erasing whatever data is currently in the file), "wt" for write access that truncates any existing file,
319  * "wa" for write-only access to append to any existing data, "rw" for read and write access on any existing
320  * data, or "rwt" for read and write access that truncates any existing file.
321  *
322  * @return Returns the RawFileDescriptor object containing file descriptor.
323  */
OpenRawFile(Uri & uri,const std::string & mode)324 int DataAbilityHelper::OpenRawFile(Uri &uri, const std::string &mode)
325 {
326     TAG_LOGI(AAFwkTag::DATA_ABILITY, "called");
327     int fd = -1;
328     auto dataAbilityHelperImpl = GetDataAbilityHelperImpl();
329     if (dataAbilityHelperImpl) {
330         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Ability OpenRawFile");
331         fd = dataAbilityHelperImpl->OpenRawFile(uri, mode);
332     }
333     auto dataShareHelper = GetDataShareHelper();
334     if (dataShareHelper) {
335         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Share OpenFile");
336         Uri dataShareUri("");
337         if (TransferScheme(uri, dataShareUri)) {
338             fd = dataShareHelper->OpenRawFile(dataShareUri, mode);
339         }
340     }
341     return fd;
342 }
343 
344 /**
345  * @brief Inserts a single data record into the database.
346  *
347  * @param uri Indicates the path of the data to operate.
348  * @param value Indicates the data record to insert. If this parameter is null, a blank row will be inserted.
349  *
350  * @return Returns the index of the inserted data record.
351  */
Insert(Uri & uri,const NativeRdb::ValuesBucket & value)352 int DataAbilityHelper::Insert(Uri &uri, const NativeRdb::ValuesBucket &value)
353 {
354     HITRACE_METER_NAME(HITRACE_TAG_DISTRIBUTEDDATA, __PRETTY_FUNCTION__);
355     TAG_LOGI(AAFwkTag::DATA_ABILITY, "called");
356     int index = -1;
357     auto dataAbilityHelperImpl = GetDataAbilityHelperImpl();
358     if (dataAbilityHelperImpl) {
359         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Ability Insert");
360         index = dataAbilityHelperImpl->Insert(uri, value);
361     }
362     auto dataShareHelper = GetDataShareHelper();
363     if (dataShareHelper) {
364         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Share Insert");
365         DataShare::DataShareValuesBucket dataShareValue = RdbDataAbilityUtils::ToDataShareValuesBucket(value);
366         Uri dataShareUri("");
367         if (TransferScheme(uri, dataShareUri)) {
368             index = dataShareHelper->Insert(dataShareUri, dataShareValue);
369         }
370     }
371     return index;
372 }
373 
Call(const Uri & uri,const std::string & method,const std::string & arg,const AppExecFwk::PacMap & pacMap)374 std::shared_ptr<AppExecFwk::PacMap> DataAbilityHelper::Call(
375     const Uri &uri, const std::string &method, const std::string &arg, const AppExecFwk::PacMap &pacMap)
376 {
377     std::shared_ptr<AppExecFwk::PacMap> result = nullptr;
378     TAG_LOGI(AAFwkTag::DATA_ABILITY, "called");
379     auto dataAbilityHelperImpl = GetDataAbilityHelperImpl();
380     if (dataAbilityHelperImpl) {
381         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Ability Call");
382         result = dataAbilityHelperImpl->Call(uri, method, arg, pacMap);
383     }
384     if (dataShareHelper_) {
385         TAG_LOGE(AAFwkTag::DATA_ABILITY, "Share no Call");
386     }
387     return result;
388 }
389 
390 /**
391  * @brief Updates data records in the database.
392  *
393  * @param uri Indicates the path of data to update.
394  * @param value Indicates the data to update. This parameter can be null.
395  * @param predicates Indicates filter criteria. You should define the processing logic when this parameter is null.
396  *
397  * @return Returns the number of data records updated.
398  */
Update(Uri & uri,const NativeRdb::ValuesBucket & value,const NativeRdb::DataAbilityPredicates & predicates)399 int DataAbilityHelper::Update(
400     Uri &uri, const NativeRdb::ValuesBucket &value, const NativeRdb::DataAbilityPredicates &predicates)
401 {
402     HITRACE_METER_NAME(HITRACE_TAG_DISTRIBUTEDDATA, __PRETTY_FUNCTION__);
403     TAG_LOGI(AAFwkTag::DATA_ABILITY, "called");
404     int index = -1;
405     auto dataAbilityHelperImpl = GetDataAbilityHelperImpl();
406     if (dataAbilityHelperImpl) {
407         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Ability Update");
408         index = dataAbilityHelperImpl->Update(uri, value, predicates);
409     }
410     auto dataShareHelper = GetDataShareHelper();
411     if (dataShareHelper) {
412         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Share Update");
413         DataShare::DataShareValuesBucket dataShareValue = RdbDataAbilityUtils::ToDataShareValuesBucket(value);
414         DataShare::DataSharePredicates dataSharePredicates = RdbDataAbilityUtils::ToDataSharePredicates(predicates);
415         Uri dataShareUri("");
416         if (TransferScheme(uri, dataShareUri)) {
417             index = dataShareHelper->Update(dataShareUri, dataSharePredicates, dataShareValue);
418         }
419     }
420     return index;
421 }
422 
423 /**
424  * @brief Deletes one or more data records from the database.
425  *
426  * @param uri Indicates the path of the data to operate.
427  * @param predicates Indicates filter criteria. You should define the processing logic when this parameter is null.
428  *
429  * @return Returns the number of data records deleted.
430  */
Delete(Uri & uri,const NativeRdb::DataAbilityPredicates & predicates)431 int DataAbilityHelper::Delete(Uri &uri, const NativeRdb::DataAbilityPredicates &predicates)
432 {
433     HITRACE_METER_NAME(HITRACE_TAG_DISTRIBUTEDDATA, __PRETTY_FUNCTION__);
434     TAG_LOGI(AAFwkTag::DATA_ABILITY, "called");
435     int index = -1;
436     auto dataAbilityHelperImpl = GetDataAbilityHelperImpl();
437     if (dataAbilityHelperImpl) {
438         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Ability Delete");
439         return dataAbilityHelperImpl->Delete(uri, predicates);
440     }
441     auto dataShareHelper = GetDataShareHelper();
442     if (dataShareHelper) {
443         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Share Delete");
444         DataShare::DataSharePredicates dataSharePredicates = RdbDataAbilityUtils::ToDataSharePredicates(predicates);
445         Uri dataShareUri("");
446         if (TransferScheme(uri, dataShareUri)) {
447             index = dataShareHelper->Delete(dataShareUri, dataSharePredicates);
448         }
449     }
450     return index;
451 }
452 
453 /**
454  * @brief Deletes one or more data records from the database.
455  *
456  * @param uri Indicates the path of data to query.
457  * @param columns Indicates the columns to query. If this parameter is null, all columns are queried.
458  * @param predicates Indicates filter criteria. You should define the processing logic when this parameter is null.
459  *
460  * @return Returns the query result.
461  */
Query(Uri & uri,std::vector<std::string> & columns,const NativeRdb::DataAbilityPredicates & predicates)462 std::shared_ptr<NativeRdb::AbsSharedResultSet> DataAbilityHelper::Query(
463     Uri &uri, std::vector<std::string> &columns, const NativeRdb::DataAbilityPredicates &predicates)
464 {
465     HITRACE_METER_NAME(HITRACE_TAG_DISTRIBUTEDDATA, __PRETTY_FUNCTION__);
466     TAG_LOGD(AAFwkTag::DATA_ABILITY, "called");
467     std::shared_ptr<NativeRdb::AbsSharedResultSet> resultSet = nullptr;
468     auto dataAbilityHelperImpl = GetDataAbilityHelperImpl();
469     if (dataAbilityHelperImpl) {
470         TAG_LOGD(AAFwkTag::DATA_ABILITY, "Ability Query");
471         return dataAbilityHelperImpl->Query(uri, columns, predicates);
472     }
473     auto dataShareHelper = GetDataShareHelper();
474     if (dataShareHelper) {
475         TAG_LOGD(AAFwkTag::DATA_ABILITY, "Share Query");
476         DataShare::DataSharePredicates dataSharePredicates = RdbDataAbilityUtils::ToDataSharePredicates(predicates);
477         Uri dataShareUri("");
478         if (TransferScheme(uri, dataShareUri)) {
479             std::shared_ptr<DataShare::DataShareResultSet> dataShareResultSet
480                 = dataShareHelper->Query(dataShareUri, dataSharePredicates, columns);
481             if (!dataShareResultSet) {
482                 TAG_LOGE(AAFwkTag::DATA_ABILITY, "null dataShareResultSet");
483                 return nullptr;
484             }
485             resultSet = RdbDataAbilityUtils::ToAbsSharedResultSet(dataShareResultSet);
486             if (!resultSet) {
487                 TAG_LOGE(AAFwkTag::DATA_ABILITY, "Transfer to AbsSharedResultSet failed");
488             }
489         }
490     }
491     return resultSet;
492 }
493 
494 /**
495  * @brief Obtains the MIME type matching the data specified by the URI of the Data ability. This method should be
496  * implemented by a Data ability. Data abilities supports general data types, including text, HTML, and JPEG.
497  *
498  * @param uri Indicates the URI of the data.
499  *
500  * @return Returns the MIME type that matches the data specified by uri.
501  */
GetType(Uri & uri)502 std::string DataAbilityHelper::GetType(Uri &uri)
503 {
504     HITRACE_METER_NAME(HITRACE_TAG_DISTRIBUTEDDATA, __PRETTY_FUNCTION__);
505     TAG_LOGI(AAFwkTag::DATA_ABILITY, "called");
506     std::string type;
507     auto dataAbilityHelperImpl = GetDataAbilityHelperImpl();
508     if (dataAbilityHelperImpl) {
509         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Ability GetType");
510         type = dataAbilityHelperImpl->GetType(uri);
511     }
512     auto dataShareHelper = GetDataShareHelper();
513     if (dataShareHelper) {
514         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Share GetType");
515         Uri dataShareUri("");
516         if (TransferScheme(uri, dataShareUri)) {
517             type = dataShareHelper->GetType(dataShareUri);
518         }
519     }
520     return type;
521 }
522 
523 /**
524  * @brief Reloads data in the database.
525  *
526  * @param uri Indicates the position where the data is to reload. This parameter is mandatory.
527  * @param extras Indicates the PacMap object containing the additional parameters to be passed in this call. This
528  * parameter can be null. If a custom Sequenceable object is put in the PacMap object and will be transferred across
529  * processes, you must call BasePacMap.setClassLoader(ClassLoader) to set a class loader for the custom object.
530  *
531  * @return Returns true if the data is successfully reloaded; returns false otherwise.
532  */
Reload(Uri & uri,const PacMap & extras)533 bool DataAbilityHelper::Reload(Uri &uri, const PacMap &extras)
534 {
535     TAG_LOGI(AAFwkTag::DATA_ABILITY, "called");
536     bool ret = false;
537     auto dataAbilityHelperImpl = GetDataAbilityHelperImpl();
538     if (dataAbilityHelperImpl) {
539         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Ability Reload");
540         ret = dataAbilityHelperImpl->Reload(uri, extras);
541     }
542     if (dataShareHelper_) {
543         TAG_LOGE(AAFwkTag::DATA_ABILITY, "Share no Reload");
544     }
545     return ret;
546 }
547 
548 /**
549  * @brief Inserts multiple data records into the database.
550  *
551  * @param uri Indicates the path of the data to operate.
552  * @param values Indicates the data records to insert.
553  *
554  * @return Returns the number of data records inserted.
555  */
BatchInsert(Uri & uri,const std::vector<NativeRdb::ValuesBucket> & values)556 int DataAbilityHelper::BatchInsert(Uri &uri, const std::vector<NativeRdb::ValuesBucket> &values)
557 {
558     HITRACE_METER_NAME(HITRACE_TAG_DISTRIBUTEDDATA, __PRETTY_FUNCTION__);
559     TAG_LOGI(AAFwkTag::DATA_ABILITY, "called");
560     int ret = -1;
561     auto dataAbilityHelperImpl = GetDataAbilityHelperImpl();
562     if (dataAbilityHelperImpl) {
563         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Ability BatchInsert");
564         ret = dataAbilityHelperImpl->BatchInsert(uri, values);
565     }
566     auto dataShareHelper = GetDataShareHelper();
567     if (dataShareHelper) {
568         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Share BatchInsert");
569         std::vector<DataShare::DataShareValuesBucket> dataShareValues;
570         for (auto value : values) {
571             DataShare::DataShareValuesBucket dataShareValue = RdbDataAbilityUtils::ToDataShareValuesBucket(value);
572             dataShareValues.push_back(dataShareValue);
573         }
574         Uri dataShareUri("");
575         if (TransferScheme(uri, dataShareUri)) {
576             ret = dataShareHelper->BatchInsert(dataShareUri, dataShareValues);
577         }
578     }
579     return ret;
580 }
581 
582 /**
583  * @brief Registers an observer to DataObsMgr specified by the given Uri.
584  *
585  * @param uri, Indicates the path of the data to operate.
586  * @param dataObserver, Indicates the IDataAbilityObserver object.
587  */
RegisterObserver(const Uri & uri,const sptr<AAFwk::IDataAbilityObserver> & dataObserver)588 void DataAbilityHelper::RegisterObserver(const Uri &uri, const sptr<AAFwk::IDataAbilityObserver> &dataObserver)
589 {
590     TAG_LOGI(AAFwkTag::DATA_ABILITY, "called");
591     auto dataAbilityHelperImpl = GetDataAbilityHelperImpl();
592     if (dataAbilityHelperImpl) {
593         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Ability RegisterObserver");
594         dataAbilityHelperImpl->RegisterObserver(uri, dataObserver);
595     }
596     auto dataShareHelper = GetDataShareHelper();
597     if (dataShareHelper) {
598         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Share RegisterObserver");
599         Uri dataShareUri("");
600         if (TransferScheme(uri, dataShareUri)) {
601             dataShareHelper->RegisterObserver(dataShareUri, dataObserver);
602         }
603     }
604 }
605 
606 /**
607  * @brief Deregisters an observer used for DataObsMgr specified by the given Uri.
608  *
609  * @param uri, Indicates the path of the data to operate.
610  * @param dataObserver, Indicates the IDataAbilityObserver object.
611  */
UnregisterObserver(const Uri & uri,const sptr<AAFwk::IDataAbilityObserver> & dataObserver)612 void DataAbilityHelper::UnregisterObserver(const Uri &uri, const sptr<AAFwk::IDataAbilityObserver> &dataObserver)
613 {
614     TAG_LOGI(AAFwkTag::DATA_ABILITY, "called");
615     auto dataAbilityHelperImpl = GetDataAbilityHelperImpl();
616     if (dataAbilityHelperImpl) {
617         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Ability UnregisterObserver");
618         dataAbilityHelperImpl->UnregisterObserver(uri, dataObserver);
619     }
620     auto dataShareHelper = GetDataShareHelper();
621     if (dataShareHelper) {
622         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Share UnregisterObserver");
623         Uri dataShareUri("");
624         if (TransferScheme(uri, dataShareUri)) {
625             dataShareHelper->UnregisterObserver(dataShareUri, dataObserver);
626         }
627     }
628 }
629 
630 /**
631  * @brief Notifies the registered observers of a change to the data resource specified by Uri.
632  *
633  * @param uri, Indicates the path of the data to operate.
634  */
NotifyChange(const Uri & uri)635 void DataAbilityHelper::NotifyChange(const Uri &uri)
636 {
637     HITRACE_METER_NAME(HITRACE_TAG_DISTRIBUTEDDATA, __PRETTY_FUNCTION__);
638     TAG_LOGI(AAFwkTag::DATA_ABILITY, "called");
639     auto dataAbilityHelperImpl = GetDataAbilityHelperImpl();
640     if (dataAbilityHelperImpl) {
641         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Ability NotifyChange");
642         dataAbilityHelperImpl->NotifyChange(uri);
643     }
644     auto dataShareHelper = GetDataShareHelper();
645     if (dataShareHelper) {
646         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Share NotifyChange");
647         Uri dataShareUri("");
648         if (TransferScheme(uri, dataShareUri)) {
649             dataShareHelper->NotifyChange(dataShareUri);
650         }
651     }
652 }
653 
654 /**
655  * @brief Converts the given uri that refer to the Data ability into a normalized URI. A normalized URI can be used
656  * across devices, persisted, backed up, and restored. It can refer to the same item in the Data ability even if the
657  * context has changed. If you implement URI normalization for a Data ability, you must also implement
658  * denormalizeUri(ohos.utils.net.Uri) to enable URI denormalization. After this feature is enabled, URIs passed to any
659  * method that is called on the Data ability must require normalization verification and denormalization. The default
660  * implementation of this method returns null, indicating that this Data ability does not support URI normalization.
661  *
662  * @param uri Indicates the Uri object to normalize.
663  *
664  * @return Returns the normalized Uri object if the Data ability supports URI normalization; returns null otherwise.
665  */
NormalizeUri(Uri & uri)666 Uri DataAbilityHelper::NormalizeUri(Uri &uri)
667 {
668     HITRACE_METER_NAME(HITRACE_TAG_DISTRIBUTEDDATA, __PRETTY_FUNCTION__);
669     TAG_LOGI(AAFwkTag::DATA_ABILITY, "called");
670     Uri urivalue("");
671     auto dataAbilityHelperImpl = GetDataAbilityHelperImpl();
672     if (dataAbilityHelperImpl) {
673         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Ability NormalizeUri");
674         urivalue = dataAbilityHelperImpl->NormalizeUri(uri);
675     }
676     auto dataShareHelper = GetDataShareHelper();
677     if (dataShareHelper) {
678         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Share NormalizeUri");
679         Uri dataShareUri("");
680         if (TransferScheme(uri, dataShareUri)) {
681             urivalue = dataShareHelper->NormalizeUri(dataShareUri);
682         }
683     }
684     return urivalue;
685 }
686 
687 /**
688  * @brief Converts the given normalized uri generated by normalizeUri(ohos.utils.net.Uri) into a denormalized one.
689  * The default implementation of this method returns the original URI passed to it.
690  *
691  * @param uri uri Indicates the Uri object to denormalize.
692  *
693  * @return Returns the denormalized Uri object if the denormalization is successful; returns the original Uri passed to
694  * this method if there is nothing to do; returns null if the data identified by the original Uri cannot be found in the
695  * current environment.
696  */
DenormalizeUri(Uri & uri)697 Uri DataAbilityHelper::DenormalizeUri(Uri &uri)
698 {
699     HITRACE_METER_NAME(HITRACE_TAG_DISTRIBUTEDDATA, __PRETTY_FUNCTION__);
700     TAG_LOGI(AAFwkTag::DATA_ABILITY, "called");
701     Uri urivalue("");
702     auto dataAbilityHelperImpl = GetDataAbilityHelperImpl();
703     if (dataAbilityHelperImpl) {
704         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Ability DenormalizeUri");
705         urivalue = dataAbilityHelperImpl->DenormalizeUri(uri);
706     }
707     auto dataShareHelper = GetDataShareHelper();
708     if (dataShareHelper) {
709         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Share DenormalizeUri");
710         Uri dataShareUri("");
711         if (TransferScheme(uri, dataShareUri)) {
712             urivalue = dataShareHelper->DenormalizeUri(dataShareUri);
713         }
714     }
715     return urivalue;
716 }
717 
ExecuteBatch(const Uri & uri,const std::vector<std::shared_ptr<DataAbilityOperation>> & operations)718 std::vector<std::shared_ptr<DataAbilityResult>> DataAbilityHelper::ExecuteBatch(
719     const Uri &uri, const std::vector<std::shared_ptr<DataAbilityOperation>> &operations)
720 {
721     TAG_LOGI(AAFwkTag::DATA_ABILITY, "called");
722     std::vector<std::shared_ptr<DataAbilityResult>> results;
723     auto dataAbilityHelperImpl = GetDataAbilityHelperImpl();
724     if (dataAbilityHelperImpl) {
725         TAG_LOGI(AAFwkTag::DATA_ABILITY, "Ability ExecuteBatch");
726         results = dataAbilityHelperImpl->ExecuteBatch(uri, operations);
727     }
728     if (dataShareHelper_) {
729         TAG_LOGE(AAFwkTag::DATA_ABILITY, "Share no ExecuteBatch");
730     }
731     return results;
732 }
733 
TransferScheme(const Uri & uri,Uri & dataShareUri)734 bool DataAbilityHelper::TransferScheme(const Uri &uri, Uri &dataShareUri)
735 {
736     const std::string dataAbilityScheme = "dataability";
737     const std::string dataShareScheme = "datashare";
738     const std::string fileScheme = "file";
739     const std::string dataSharePrefix = "datashare:///";
740     const std::string filePrefix = "file://";
741 
742     Uri inputUri = uri;
743     if (inputUri.GetScheme() == dataShareScheme) {
744         dataShareUri = Uri(inputUri.ToString());
745         TAG_LOGI(AAFwkTag::DATA_ABILITY, "data share uri: %{public}s no need transfer",
746             inputUri.ToString().c_str());
747         return true;
748     }
749 
750     if (inputUri.GetScheme() == dataAbilityScheme) {
751         string uriStr = inputUri.ToString();
752         uriStr.replace(0, dataAbilityScheme.length(), dataShareScheme);
753         dataShareUri = Uri(uriStr);
754         TAG_LOGI(AAFwkTag::DATA_ABILITY, "ability uri: %{public}s transfer to share uri: %{public}s",
755             inputUri.ToString().c_str(), dataShareUri.ToString().c_str());
756         return true;
757     }
758 
759     if (inputUri.GetScheme() == fileScheme) {
760         string uriStr = inputUri.ToString();
761         uriStr.replace(0, filePrefix.length(), dataSharePrefix);
762         dataShareUri = Uri(uriStr);
763         TAG_LOGD(AAFwkTag::DATA_ABILITY, "file uri: %{public}s transfer to share uri: %{public}s",
764             inputUri.ToString().c_str(), dataShareUri.ToString().c_str());
765         return true;
766     }
767 
768     TAG_LOGE(AAFwkTag::DATA_ABILITY, "invalid param, uri: %{private}s", inputUri.ToString().c_str());
769     return false;
770 }
771 
SetCallFromJs()772 void DataAbilityHelper::SetCallFromJs()
773 {
774     callFromJs_ = true;
775 }
776 }  // namespace AppExecFwk
777 }  // namespace OHOS
778 
779