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