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 MLOG_TAG "SendableMediaLibraryNapiUtils"
16
17 #include "sendable_medialibrary_napi_utils.h"
18
19 #include "basic/result_set.h"
20 #include "datashare_predicates.h"
21 #include "location_column.h"
22 #include "ipc_skeleton.h"
23 #include "js_proxy.h"
24 #include "sendable_photo_album_napi.h"
25 #include "sendable_fetch_file_result_napi.h"
26 #include "sendable_photo_access_helper_napi.h"
27 #include "media_device_column.h"
28 #include "media_file_uri.h"
29 #include "media_file_utils.h"
30 #include "media_library_napi.h"
31 #include "medialibrary_client_errno.h"
32 #include "medialibrary_db_const.h"
33 #include "medialibrary_errno.h"
34 #include "medialibrary_napi_utils.h"
35 #include "medialibrary_tracer.h"
36 #include "medialibrary_type_const.h"
37 #include "photo_album_napi.h"
38 #include "photo_map_column.h"
39 #include "smart_album_napi.h"
40 #include "tokenid_kit.h"
41 #include "userfile_client.h"
42 #include "vision_album_column.h"
43 #include "vision_column.h"
44 #include "vision_face_tag_column.h"
45 #include "vision_pose_column.h"
46 #include "vision_image_face_column.h"
47 #include "userfile_manager_types.h"
48
49 using namespace std;
50 using namespace OHOS::DataShare;
51
52 namespace OHOS {
53 namespace Media {
54 static const string EMPTY_STRING = "";
55 using json = nlohmann::json;
56 using SendablePAHAsyncContext = SendablePhotoAccessHelperAsyncContext;
57 using SendablePANAsyncContext = SendablePhotoAlbumNapiAsyncContext;
58 using SendableFAAsyncContext = SendableFileAssetAsyncContext;
59
GetUInt32(napi_env env,napi_value arg,uint32_t & value)60 napi_status SendableMediaLibraryNapiUtils::GetUInt32(napi_env env, napi_value arg, uint32_t &value)
61 {
62 napi_valuetype valueType = napi_undefined;
63 CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
64 CHECK_COND_RET(valueType == napi_number, napi_number_expected, "Type is not as expected number");
65 CHECK_STATUS_RET(napi_get_value_uint32(env, arg, &value), "Failed to get uint32 value");
66 return napi_ok;
67 }
68
GetInt32(napi_env env,napi_value arg,int32_t & value)69 napi_status SendableMediaLibraryNapiUtils::GetInt32(napi_env env, napi_value arg, int32_t &value)
70 {
71 napi_valuetype valueType = napi_undefined;
72 CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
73 CHECK_COND_RET(valueType == napi_number, napi_number_expected, "Type is not as expected number");
74 CHECK_STATUS_RET(napi_get_value_int32(env, arg, &value), "Failed to get int32 value");
75 return napi_ok;
76 }
77
GetParamBool(napi_env env,napi_value arg,bool & value)78 napi_status SendableMediaLibraryNapiUtils::GetParamBool(napi_env env, napi_value arg, bool &value)
79 {
80 napi_valuetype valueType = napi_undefined;
81 CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
82 CHECK_COND_RET(valueType == napi_boolean, napi_boolean_expected, "Type is not as expected boolean");
83 CHECK_STATUS_RET(napi_get_value_bool(env, arg, &value), "Failed to get param");
84 return napi_ok;
85 }
86
GetParamFunction(napi_env env,napi_value arg,napi_ref & callbackRef)87 napi_status SendableMediaLibraryNapiUtils::GetParamFunction(napi_env env, napi_value arg, napi_ref &callbackRef)
88 {
89 napi_valuetype valueType = napi_undefined;
90 CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
91 CHECK_COND_RET(valueType == napi_function, napi_function_expected, "Type is not as expected function");
92 CHECK_STATUS_RET(napi_create_reference(env, arg, NAPI_INIT_REF_COUNT, &callbackRef), "Failed to make callbackref");
93 return napi_ok;
94 }
95
GetParamStr(napi_env env,napi_value arg,const size_t size,string & result)96 static napi_status GetParamStr(napi_env env, napi_value arg, const size_t size, string &result)
97 {
98 size_t res = 0;
99 unique_ptr<char[]> buffer = make_unique<char[]>(size);
100 CHECK_COND_RET(buffer != nullptr, napi_invalid_arg, "Failed to alloc buffer for parameter");
101 napi_valuetype valueType = napi_undefined;
102 CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
103 CHECK_COND_RET(valueType == napi_string, napi_string_expected, "Type is not as expected string");
104 CHECK_STATUS_RET(napi_get_value_string_utf8(env, arg, buffer.get(), size, &res), "Failed to get string value");
105 result = string(buffer.get());
106 return napi_ok;
107 }
108
GetParamStringWithLength(napi_env env,napi_value arg,int32_t maxLen,string & result)109 napi_status SendableMediaLibraryNapiUtils::GetParamStringWithLength(napi_env env, napi_value arg, int32_t maxLen,
110 string &result)
111 {
112 CHECK_STATUS_RET(GetParamStr(env, arg, maxLen, result), "Failed to get string parameter");
113 return napi_ok;
114 }
115
GetParamStringPathMax(napi_env env,napi_value arg,string & result)116 napi_status SendableMediaLibraryNapiUtils::GetParamStringPathMax(napi_env env, napi_value arg, string &result)
117 {
118 CHECK_STATUS_RET(GetParamStr(env, arg, PATH_MAX, result), "Failed to get string parameter");
119 return napi_ok;
120 }
121
GetProperty(napi_env env,const napi_value arg,const string & propName,string & propValue)122 napi_status SendableMediaLibraryNapiUtils::GetProperty(napi_env env, const napi_value arg, const string &propName,
123 string &propValue)
124 {
125 bool present = false;
126 napi_value property = nullptr;
127 CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present),
128 "Failed to check property name");
129 if (present) {
130 CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property), "Failed to get property");
131 CHECK_STATUS_RET(GetParamStringPathMax(env, property, propValue), "Failed to get string buffer");
132 }
133 return napi_ok;
134 }
135
GetStringArray(napi_env env,napi_value arg,vector<string> & array)136 napi_status SendableMediaLibraryNapiUtils::GetStringArray(napi_env env, napi_value arg, vector<string> &array)
137 {
138 bool isArray = false;
139 uint32_t len = 0;
140 CHECK_STATUS_RET(napi_is_array(env, arg, &isArray), "Failed to check array type");
141 CHECK_COND_RET(isArray, napi_array_expected, "Expected array type");
142 CHECK_STATUS_RET(napi_get_array_length(env, arg, &len), "Failed to get array length");
143 for (uint32_t i = 0; i < len; i++) {
144 napi_value item = nullptr;
145 string val;
146 CHECK_STATUS_RET(napi_get_element(env, arg, i, &item), "Failed to get array item");
147 CHECK_STATUS_RET(GetParamStringPathMax(env, item, val), "Failed to get string buffer");
148 array.push_back(val);
149 }
150 return napi_ok;
151 }
152
GetArrayProperty(napi_env env,napi_value arg,const string & propName,vector<string> & array)153 napi_status SendableMediaLibraryNapiUtils::GetArrayProperty(napi_env env, napi_value arg, const string &propName,
154 vector<string> &array)
155 {
156 bool present = false;
157 CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present), "Failed to check property name");
158 if (present) {
159 napi_value property = nullptr;
160 CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property),
161 "Failed to get selectionArgs property");
162 GetStringArray(env, property, array);
163 }
164 return napi_ok;
165 }
166
HasCallback(napi_env env,const size_t argc,const napi_value argv[],bool & isCallback)167 napi_status SendableMediaLibraryNapiUtils::HasCallback(napi_env env, const size_t argc, const napi_value argv[],
168 bool &isCallback)
169 {
170 isCallback = false;
171 if (argc < ARGS_ONE) {
172 return napi_ok;
173 }
174 napi_valuetype valueType = napi_undefined;
175 CHECK_STATUS_RET(napi_typeof(env, argv[argc - 1], &valueType), "Failed to get type");
176 isCallback = (valueType == napi_function);
177 return napi_ok;
178 }
179
hasFetchOpt(napi_env env,const napi_value arg,bool & hasFetchOpt)180 napi_status SendableMediaLibraryNapiUtils::hasFetchOpt(napi_env env, const napi_value arg, bool &hasFetchOpt)
181 {
182 hasFetchOpt = false;
183 napi_valuetype valueType = napi_undefined;
184 CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
185 if (valueType != napi_object) {
186 hasFetchOpt = false;
187 return napi_ok;
188 }
189 CHECK_STATUS_RET(napi_has_named_property(env, arg, "selections", &hasFetchOpt),
190 "Failed to get property selections");
191 return napi_ok;
192 }
193
GetMediaTypeFromUri(const string & uri)194 MediaType SendableMediaLibraryNapiUtils::GetMediaTypeFromUri(const string &uri)
195 {
196 if (uri.find(MEDIALIBRARY_IMAGE_URI) != string::npos) {
197 return MediaType::MEDIA_TYPE_IMAGE;
198 } else if (uri.find(MEDIALIBRARY_VIDEO_URI) != string::npos) {
199 return MediaType::MEDIA_TYPE_VIDEO;
200 } else if (uri.find(MEDIALIBRARY_AUDIO_URI) != string::npos) {
201 return MediaType::MEDIA_TYPE_AUDIO;
202 } else if (uri.find(MEDIALIBRARY_FILE_URI) != string::npos) {
203 return MediaType::MEDIA_TYPE_FILE;
204 }
205 return MediaType::MEDIA_TYPE_ALL;
206 }
207
HandleSpecialDateTypePredicate(const OperationItem & item,vector<OperationItem> & operations,const FetchOptionType & fetchOptType)208 static bool HandleSpecialDateTypePredicate(const OperationItem &item,
209 vector<OperationItem> &operations, const FetchOptionType &fetchOptType)
210 {
211 constexpr int32_t FIELD_IDX = 0;
212 constexpr int32_t VALUE_IDX = 1;
213 vector<string>dateTypes = { MEDIA_DATA_DB_DATE_ADDED, MEDIA_DATA_DB_DATE_TRASHED, MEDIA_DATA_DB_DATE_MODIFIED,
214 MEDIA_DATA_DB_DATE_TAKEN };
215 string dateType = item.GetSingle(FIELD_IDX);
216 auto it = find(dateTypes.begin(), dateTypes.end(), dateType);
217 if (it != dateTypes.end() && item.operation != DataShare::ORDER_BY_ASC &&
218 item.operation != DataShare::ORDER_BY_DESC) {
219 dateType += "_s";
220 operations.push_back({ item.operation, { dateType, static_cast<double>(item.GetSingle(VALUE_IDX)) } });
221 return true;
222 }
223 if (DATE_TRANSITION_MAP.count(dateType) != 0) {
224 dateType = DATE_TRANSITION_MAP.at(dateType);
225 operations.push_back({ item.operation, { dateType, static_cast<double>(item.GetSingle(VALUE_IDX)) } });
226 return true;
227 }
228 return false;
229 }
230
231 template <class AsyncContext>
HandleSpecialPredicate(AsyncContext & context,shared_ptr<DataShareAbsPredicates> & predicate,const FetchOptionType & fetchOptType)232 bool SendableMediaLibraryNapiUtils::HandleSpecialPredicate(AsyncContext &context,
233 shared_ptr<DataShareAbsPredicates> &predicate, const FetchOptionType &fetchOptType)
234 {
235 constexpr int32_t FIELD_IDX = 0;
236 constexpr int32_t VALUE_IDX = 1;
237 vector<OperationItem> operations;
238 auto &items = predicate->GetOperationList();
239 for (auto &item : items) {
240 if (item.singleParams.empty()) {
241 operations.push_back(item);
242 continue;
243 }
244 if (HandleSpecialDateTypePredicate(item, operations, fetchOptType)) {
245 continue;
246 }
247 // change uri ->file id
248 // get networkid
249 // replace networkid with file id
250 if (static_cast<string>(item.GetSingle(FIELD_IDX)) == DEVICE_DB_NETWORK_ID) {
251 if (item.operation != DataShare::EQUAL_TO || static_cast<string>(item.GetSingle(VALUE_IDX)).empty()) {
252 NAPI_ERR_LOG("DEVICE_DB_NETWORK_ID predicates not support %{public}d", item.operation);
253 return false;
254 }
255 context->networkId = static_cast<string>(item.GetSingle(VALUE_IDX));
256 continue;
257 }
258 if (static_cast<string>(item.GetSingle(FIELD_IDX)) == MEDIA_DATA_DB_URI) {
259 if (item.operation != DataShare::EQUAL_TO) {
260 NAPI_ERR_LOG("MEDIA_DATA_DB_URI predicates not support %{public}d", item.operation);
261 return false;
262 }
263 string uri = static_cast<string>(item.GetSingle(VALUE_IDX));
264 MediaFileUri::RemoveAllFragment(uri);
265 MediaFileUri fileUri(uri);
266 context->uri = uri;
267 if ((fetchOptType != ALBUM_FETCH_OPT) && (!fileUri.IsApi10())) {
268 fileUri = MediaFileUri(MediaFileUtils::GetRealUriFromVirtualUri(uri));
269 }
270 context->networkId = fileUri.GetNetworkId();
271 string field = (fetchOptType == ALBUM_FETCH_OPT) ? PhotoAlbumColumns::ALBUM_ID : MEDIA_DATA_DB_ID;
272 operations.push_back({ item.operation, { field, fileUri.GetFileId() } });
273 continue;
274 }
275 if (static_cast<string>(item.GetSingle(FIELD_IDX)) == PENDING_STATUS) {
276 // do not query pending files below API11
277 continue;
278 }
279 if (LOCATION_PARAM_MAP.find(static_cast<string>(item.GetSingle(FIELD_IDX))) != LOCATION_PARAM_MAP.end()) {
280 continue;
281 }
282 operations.push_back(item);
283 }
284 context->predicates = DataSharePredicates(move(operations));
285 return true;
286 }
287
288 template <class AsyncContext>
GetLocationPredicate(AsyncContext & context,shared_ptr<DataShareAbsPredicates> & predicate)289 bool SendableMediaLibraryNapiUtils::GetLocationPredicate(AsyncContext &context,
290 shared_ptr<DataShareAbsPredicates> &predicate)
291 {
292 constexpr int32_t FIELD_IDX = 0;
293 constexpr int32_t VALUE_IDX = 1;
294 map<string, string> locationMap;
295 auto &items = predicate->GetOperationList();
296 for (auto &item : items) {
297 if (item.singleParams.empty()) {
298 continue;
299 }
300 if (LOCATION_PARAM_MAP.find(static_cast<string>(item.GetSingle(FIELD_IDX))) != LOCATION_PARAM_MAP.end()) {
301 if (item.operation != DataShare::EQUAL_TO) {
302 NAPI_ERR_LOG("location predicates not support %{public}d", item.operation);
303 return false;
304 }
305 string param = static_cast<string>(item.GetSingle(FIELD_IDX));
306 string value = static_cast<string>(item.GetSingle(VALUE_IDX));
307 locationMap.insert(make_pair(param, value));
308 if (param == DIAMETER) {
309 continue;
310 }
311 if (LOCATION_PARAM_MAP.at(param).second == DataShare::GREATER_THAN_OR_EQUAL_TO) {
312 context->predicates.GreaterThanOrEqualTo(LOCATION_PARAM_MAP.at(param).first, value);
313 continue;
314 }
315 if (LOCATION_PARAM_MAP.at(param).second == DataShare::LESS_THAN) {
316 context->predicates.LessThan(LOCATION_PARAM_MAP.at(param).first, value);
317 continue;
318 }
319 if (LOCATION_PARAM_MAP.at(param).second == DataShare::EQUAL_TO) {
320 context->predicates.EqualTo(LOCATION_PARAM_MAP.at(param).first, value);
321 continue;
322 }
323 }
324 }
325
326 if (locationMap.count(DIAMETER) == 1 && locationMap.count(START_LATITUDE) == 1
327 && locationMap.count(START_LONGITUDE) == 1) {
328 // 0.5:Used for rounding down
329 string latitudeIndex = "round((latitude - " + locationMap.at(START_LATITUDE) + ") / " +
330 locationMap.at(DIAMETER) + " - 0.5)";
331 string longitudeIndex = "round((longitude - " + locationMap.at(START_LONGITUDE) + ") / " +
332 locationMap.at(DIAMETER) + " - 0.5)";
333 string albumName = LATITUDE + "||'_'||" + LONGITUDE + "||'_'||" + latitudeIndex + "||'_'||" +
334 longitudeIndex + " AS " + ALBUM_NAME;
335 context->fetchColumn.push_back(albumName);
336 string locationGroup = latitudeIndex + "," + longitudeIndex;
337 context->predicates.GroupBy({ locationGroup });
338 }
339 return true;
340 }
341
342 template <class AsyncContext>
GetFetchOption(napi_env env,napi_value arg,const FetchOptionType & fetchOptType,AsyncContext & context)343 napi_status SendableMediaLibraryNapiUtils::GetFetchOption(napi_env env, napi_value arg,
344 const FetchOptionType &fetchOptType, AsyncContext &context)
345 {
346 // Parse the argument into fetchOption if any
347 CHECK_STATUS_RET(GetPredicate(env, arg, "predicates", context, fetchOptType), "invalid predicate");
348 CHECK_STATUS_RET(GetArrayProperty(env, arg, "fetchColumns", context->fetchColumn),
349 "Failed to parse fetchColumn");
350 return napi_ok;
351 }
352
353 template <class AsyncContext>
GetAlbumFetchOption(napi_env env,napi_value arg,const FetchOptionType & fetchOptType,AsyncContext & context)354 napi_status SendableMediaLibraryNapiUtils::GetAlbumFetchOption(napi_env env, napi_value arg,
355 const FetchOptionType &fetchOptType, AsyncContext &context)
356 {
357 // Parse the argument into AlbumFetchOption if any
358 CHECK_STATUS_RET(GetPredicate(env, arg, "predicates", context, fetchOptType), "invalid predicate");
359 return napi_ok;
360 }
361
362 template <class AsyncContext>
GetPredicate(napi_env env,const napi_value arg,const string & propName,AsyncContext & context,const FetchOptionType & fetchOptType)363 napi_status SendableMediaLibraryNapiUtils::GetPredicate(napi_env env, const napi_value arg, const string &propName,
364 AsyncContext &context, const FetchOptionType &fetchOptType)
365 {
366 bool present = false;
367 napi_value property = nullptr;
368 CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present),
369 "Failed to check property name");
370 if (present) {
371 CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property), "Failed to get property");
372 JSProxy::JSProxy<DataShareAbsPredicates> *jsProxy = nullptr;
373 napi_unwrap(env, property, reinterpret_cast<void **>(&jsProxy));
374 if (jsProxy == nullptr) {
375 NAPI_ERR_LOG("jsProxy is invalid");
376 return napi_invalid_arg;
377 }
378 shared_ptr<DataShareAbsPredicates> predicate = jsProxy->GetInstance();
379 CHECK_COND_RET(HandleSpecialPredicate(context, predicate, fetchOptType) == TRUE, napi_invalid_arg,
380 "invalid predicate");
381 CHECK_COND_RET(GetLocationPredicate(context, predicate) == TRUE, napi_invalid_arg, "invalid predicate");
382 }
383 return napi_ok;
384 }
385
386 template <class AsyncContext>
ParseAssetFetchOptCallback(napi_env env,napi_callback_info info,AsyncContext & context)387 napi_status SendableMediaLibraryNapiUtils::ParseAssetFetchOptCallback(napi_env env, napi_callback_info info,
388 AsyncContext &context)
389 {
390 constexpr size_t minArgs = ARGS_ONE;
391 constexpr size_t maxArgs = ARGS_TWO;
392 CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
393 "Failed to get object info");
394 CHECK_STATUS_RET(GetFetchOption(env, context->argv[PARAM0], ASSET_FETCH_OPT, context),
395 "Failed to get fetch option");
396 return napi_ok;
397 }
398
399 template <class AsyncContext>
ParseAlbumFetchOptCallback(napi_env env,napi_callback_info info,AsyncContext & context)400 napi_status SendableMediaLibraryNapiUtils::ParseAlbumFetchOptCallback(napi_env env, napi_callback_info info,
401 AsyncContext &context)
402 {
403 constexpr size_t minArgs = ARGS_ONE;
404 constexpr size_t maxArgs = ARGS_TWO;
405 CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
406 "Failed to get object info");
407 // Parse the argument into fetchOption if any
408 CHECK_STATUS_RET(GetPredicate(env, context->argv[PARAM0], "predicates", context, ALBUM_FETCH_OPT),
409 "invalid predicate");
410 context->predicates.And()->NotEqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::HIDDEN));
411 return napi_ok;
412 }
413
414 template <class AsyncContext>
UpdateMediaTypeSelections(AsyncContext * context)415 void SendableMediaLibraryNapiUtils::UpdateMediaTypeSelections(AsyncContext *context)
416 {
417 constexpr int FIRST_MEDIA_TYPE = 0;
418 constexpr int SECOND_MEDIA_TYPE = 1;
419 if ((context->mediaTypes.size() != ARGS_ONE) && (context->mediaTypes.size() != ARGS_TWO)) {
420 return;
421 }
422 DataShare::DataSharePredicates &predicates = context->predicates;
423 predicates.BeginWrap();
424 predicates.EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, (int)context->mediaTypes[FIRST_MEDIA_TYPE]);
425 if (context->mediaTypes.size() == ARGS_TWO) {
426 predicates.Or()->EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, (int)context->mediaTypes[SECOND_MEDIA_TYPE]);
427 }
428 predicates.EndWrap();
429 }
430
431 template <class AsyncContext>
AsyncContextSetObjectInfo(napi_env env,napi_callback_info info,AsyncContext & asyncContext,const size_t minArgs,const size_t maxArgs)432 napi_status SendableMediaLibraryNapiUtils::AsyncContextSetObjectInfo(napi_env env, napi_callback_info info,
433 AsyncContext &asyncContext, const size_t minArgs, const size_t maxArgs)
434 {
435 napi_value thisVar = nullptr;
436 asyncContext->argc = maxArgs;
437 CHECK_STATUS_RET(napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), &thisVar,
438 nullptr), "Failed to get cb info");
439 CHECK_COND_RET(((asyncContext->argc >= minArgs) && (asyncContext->argc <= maxArgs)), napi_invalid_arg,
440 "Number of args is invalid");
441 if (minArgs > 0) {
442 CHECK_COND_RET(asyncContext->argv[ARGS_ZERO] != nullptr, napi_invalid_arg, "Argument list is empty");
443 }
444 CHECK_STATUS_RET(napi_unwrap_sendable(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo)),
445 "Failed to unwrap thisVar");
446 CHECK_COND_RET(asyncContext->objectInfo != nullptr, napi_invalid_arg, "Failed to get object info");
447 CHECK_STATUS_RET(GetParamCallback(env, asyncContext), "Failed to get callback param!");
448 return napi_ok;
449 }
450
451 template <class AsyncContext>
AsyncContextGetArgs(napi_env env,napi_callback_info info,AsyncContext & asyncContext,const size_t minArgs,const size_t maxArgs)452 napi_status SendableMediaLibraryNapiUtils::AsyncContextGetArgs(napi_env env, napi_callback_info info,
453 AsyncContext &asyncContext, const size_t minArgs, const size_t maxArgs)
454 {
455 asyncContext->argc = maxArgs;
456 CHECK_STATUS_RET(napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), nullptr,
457 nullptr), "Failed to get cb info");
458 CHECK_COND_RET(asyncContext->argc >= minArgs && asyncContext->argc <= maxArgs, napi_invalid_arg,
459 "Number of args is invalid");
460 if (minArgs > 0) {
461 CHECK_COND_RET(asyncContext->argv[ARGS_ZERO] != nullptr, napi_invalid_arg, "Argument list is empty");
462 }
463 CHECK_STATUS_RET(GetParamCallback(env, asyncContext), "Failed to get callback param");
464 return napi_ok;
465 }
466
467 template <class AsyncContext>
GetParamCallback(napi_env env,AsyncContext & context)468 napi_status SendableMediaLibraryNapiUtils::GetParamCallback(napi_env env, AsyncContext &context)
469 {
470 /* Parse the last argument into callbackref if any */
471 bool isCallback = false;
472 CHECK_STATUS_RET(HasCallback(env, context->argc, context->argv, isCallback), "Failed to check callback");
473 if (isCallback) {
474 CHECK_STATUS_RET(GetParamFunction(env, context->argv[context->argc - 1], context->callbackRef),
475 "Failed to get callback");
476 }
477 return napi_ok;
478 }
479
480 template <class AsyncContext>
ParseArgsBoolCallBack(napi_env env,napi_callback_info info,AsyncContext & context,bool & param)481 napi_status SendableMediaLibraryNapiUtils::ParseArgsBoolCallBack(napi_env env, napi_callback_info info,
482 AsyncContext &context,
483 bool ¶m)
484 {
485 constexpr size_t minArgs = ARGS_ONE;
486 constexpr size_t maxArgs = ARGS_TWO;
487 CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
488 "Failed to get object info");
489
490 /* Parse the first argument into param */
491 CHECK_STATUS_RET(GetParamBool(env, context->argv[ARGS_ZERO], param), "Failed to get parameter");
492 return napi_ok;
493 }
494
495 template <class AsyncContext>
ParseArgsStringCallback(napi_env env,napi_callback_info info,AsyncContext & context,string & param)496 napi_status SendableMediaLibraryNapiUtils::ParseArgsStringCallback(napi_env env, napi_callback_info info,
497 AsyncContext &context, string ¶m)
498 {
499 constexpr size_t minArgs = ARGS_ONE;
500 constexpr size_t maxArgs = ARGS_TWO;
501 CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
502 "Failed to get object info");
503
504 CHECK_STATUS_RET(GetParamStringPathMax(env, context->argv[ARGS_ZERO], param), "Failed to get string argument");
505 return napi_ok;
506 }
507
508 template <class AsyncContext>
ParseArgsStringArrayCallback(napi_env env,napi_callback_info info,AsyncContext & context,vector<string> & array)509 napi_status SendableMediaLibraryNapiUtils::ParseArgsStringArrayCallback(napi_env env, napi_callback_info info,
510 AsyncContext &context, vector<string> &array)
511 {
512 constexpr size_t minArgs = ARGS_ONE;
513 constexpr size_t maxArgs = ARGS_TWO;
514 CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
515 "Failed to get object info");
516
517 CHECK_STATUS_RET(GetStringArray(env, context->argv[ARGS_ZERO], array), "Failed to get string array");
518 CHECK_STATUS_RET(GetParamCallback(env, context), "Failed to get callback");
519 return napi_ok;
520 }
521
522 template <class AsyncContext>
ParseArgsNumberCallback(napi_env env,napi_callback_info info,AsyncContext & context,int32_t & value)523 napi_status SendableMediaLibraryNapiUtils::ParseArgsNumberCallback(napi_env env, napi_callback_info info,
524 AsyncContext &context, int32_t &value)
525 {
526 constexpr size_t minArgs = ARGS_ONE;
527 constexpr size_t maxArgs = ARGS_TWO;
528 CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
529 "Failed to get object info");
530
531 CHECK_STATUS_RET(GetInt32(env, context->argv[ARGS_ZERO], value), "Failed to get number argument");
532 return napi_ok;
533 }
534
535 template <class AsyncContext>
ParseArgsOnlyCallBack(napi_env env,napi_callback_info info,AsyncContext & context)536 napi_status SendableMediaLibraryNapiUtils::ParseArgsOnlyCallBack(napi_env env, napi_callback_info info,
537 AsyncContext &context)
538 {
539 constexpr size_t minArgs = ARGS_ZERO;
540 constexpr size_t maxArgs = ARGS_ONE;
541 CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
542 "Failed to get object info");
543 return napi_ok;
544 }
545
GetAssetType(MediaType type)546 AssetType SendableMediaLibraryNapiUtils::GetAssetType(MediaType type)
547 {
548 AssetType result;
549
550 switch (type) {
551 case MEDIA_TYPE_AUDIO:
552 result = ASSET_AUDIO;
553 break;
554 case MEDIA_TYPE_VIDEO:
555 result = ASSET_VIDEO;
556 break;
557 case MEDIA_TYPE_IMAGE:
558 result = ASSET_IMAGE;
559 break;
560 case MEDIA_TYPE_MEDIA:
561 result = ASSET_MEDIA;
562 break;
563 default:
564 result = ASSET_NONE;
565 break;
566 }
567
568 return result;
569 }
570
AppendFetchOptionSelection(string & selection,const string & newCondition)571 void SendableMediaLibraryNapiUtils::AppendFetchOptionSelection(string &selection, const string &newCondition)
572 {
573 if (!newCondition.empty()) {
574 if (!selection.empty()) {
575 selection = "(" + selection + ") AND " + newCondition;
576 } else {
577 selection = newCondition;
578 }
579 }
580 }
581
TransErrorCode(const string & Name,shared_ptr<DataShare::DataShareResultSet> resultSet)582 int SendableMediaLibraryNapiUtils::TransErrorCode(const string &Name,
583 shared_ptr<DataShare::DataShareResultSet> resultSet)
584 {
585 NAPI_ERR_LOG("interface: %{public}s, server return nullptr", Name.c_str());
586 // Query can't return errorcode, so assume nullptr as permission deny
587 if (resultSet == nullptr) {
588 return JS_ERR_PERMISSION_DENIED;
589 }
590 return ERR_DEFAULT;
591 }
592
TransErrorCode(const string & Name,int error)593 int SendableMediaLibraryNapiUtils::TransErrorCode(const string &Name, int error)
594 {
595 NAPI_ERR_LOG("interface: %{public}s, server errcode:%{public}d ", Name.c_str(), error);
596 // Transfer Server error to napi error code
597 if (error <= E_COMMON_START && error >= E_COMMON_END) {
598 error = JS_INNER_FAIL;
599 } else if (trans2JsError.count(error)) {
600 error = trans2JsError.at(error);
601 }
602 return error;
603 }
604
HandleError(napi_env env,int error,napi_value & errorObj,const string & Name)605 void SendableMediaLibraryNapiUtils::HandleError(napi_env env, int error, napi_value &errorObj, const string &Name)
606 {
607 if (error == ERR_DEFAULT) {
608 return;
609 }
610
611 string errMsg = "System inner fail";
612 int originalError = error;
613 if (jsErrMap.count(error) > 0) {
614 errMsg = jsErrMap.at(error);
615 } else {
616 error = JS_INNER_FAIL;
617 }
618 CreateNapiErrorObject(env, errorObj, error, errMsg);
619 errMsg = Name + " " + errMsg;
620 NAPI_ERR_LOG("Error: %{public}s, js errcode:%{public}d ", errMsg.c_str(), originalError);
621 }
622
CreateNapiErrorObject(napi_env env,napi_value & errorObj,const int32_t errCode,const string errMsg)623 void SendableMediaLibraryNapiUtils::CreateNapiErrorObject(napi_env env, napi_value &errorObj, const int32_t errCode,
624 const string errMsg)
625 {
626 napi_status statusError;
627 napi_value napiErrorCode = nullptr;
628 napi_value napiErrorMsg = nullptr;
629 statusError = napi_create_string_utf8(env, to_string(errCode).c_str(), NAPI_AUTO_LENGTH, &napiErrorCode);
630 if (statusError == napi_ok) {
631 statusError = napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &napiErrorMsg);
632 if (statusError == napi_ok) {
633 statusError = napi_create_error(env, napiErrorCode, napiErrorMsg, &errorObj);
634 if (statusError == napi_ok) {
635 NAPI_DEBUG_LOG("napi_create_error success");
636 }
637 }
638 }
639 }
640
InvokeJSAsyncMethod(napi_env env,napi_deferred deferred,napi_ref callbackRef,napi_async_work work,const SendableJSAsyncContextOutput & asyncContext)641 void SendableMediaLibraryNapiUtils::InvokeJSAsyncMethod(napi_env env, napi_deferred deferred, napi_ref callbackRef,
642 napi_async_work work, const SendableJSAsyncContextOutput &asyncContext)
643 {
644 MediaLibraryTracer tracer;
645 tracer.Start("InvokeJSAsyncMethod");
646
647 napi_value retVal;
648 napi_value callback = nullptr;
649
650 /* Deferred is used when JS Callback method expects a promise value */
651 if (deferred) {
652 if (asyncContext.status) {
653 napi_resolve_deferred(env, deferred, asyncContext.data);
654 } else {
655 napi_reject_deferred(env, deferred, asyncContext.error);
656 }
657 } else {
658 napi_value result[ARGS_TWO];
659 result[PARAM0] = asyncContext.error;
660 result[PARAM1] = asyncContext.data;
661 napi_get_reference_value(env, callbackRef, &callback);
662 napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
663 napi_delete_reference(env, callbackRef);
664 }
665 napi_delete_async_work(env, work);
666 }
667
668 template <class AsyncContext>
NapiCreateAsyncWork(napi_env env,unique_ptr<AsyncContext> & asyncContext,const string & resourceName,void (* execute)(napi_env,void *),void (* complete)(napi_env,napi_status,void *))669 napi_value SendableMediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr<AsyncContext> &asyncContext,
670 const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *))
671 {
672 napi_value result = nullptr;
673 napi_value resource = nullptr;
674 NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
675 NAPI_CREATE_RESOURCE_NAME(env, resource, resourceName.c_str(), asyncContext);
676
677 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, execute, complete,
678 static_cast<void *>(asyncContext.get()), &asyncContext->work));
679 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated));
680 asyncContext.release();
681
682 return result;
683 }
684
ToUTF8String(napi_env env,napi_value value)685 tuple<bool, unique_ptr<char[]>, size_t> SendableMediaLibraryNapiUtils::ToUTF8String(napi_env env, napi_value value)
686 {
687 size_t strLen = 0;
688 napi_status status = napi_get_value_string_utf8(env, value, nullptr, -1, &strLen);
689 if (status != napi_ok) {
690 NAPI_ERR_LOG("ToUTF8String get fail, %{public}d", status);
691 return { false, nullptr, 0 };
692 }
693
694 size_t bufLen = strLen + 1;
695 unique_ptr<char[]> str = make_unique<char[]>(bufLen);
696 if (str == nullptr) {
697 NAPI_ERR_LOG("ToUTF8String get memory fail");
698 return { false, nullptr, 0 };
699 }
700 status = napi_get_value_string_utf8(env, value, str.get(), bufLen, &strLen);
701 return make_tuple(status == napi_ok, move(str), strLen);
702 }
703
IsExistsByPropertyName(napi_env env,napi_value jsObject,const char * propertyName)704 bool SendableMediaLibraryNapiUtils::IsExistsByPropertyName(napi_env env, napi_value jsObject, const char *propertyName)
705 {
706 bool result = false;
707 if (napi_has_named_property(env, jsObject, propertyName, &result) == napi_ok) {
708 return result;
709 } else {
710 NAPI_ERR_LOG("IsExistsByPropertyName not exist %{public}s", propertyName);
711 return false;
712 }
713 }
714
GetPropertyValueByName(napi_env env,napi_value jsObject,const char * propertyName)715 napi_value SendableMediaLibraryNapiUtils::GetPropertyValueByName(napi_env env, napi_value jsObject,
716 const char *propertyName)
717 {
718 napi_value value = nullptr;
719 if (IsExistsByPropertyName(env, jsObject, propertyName) == false) {
720 NAPI_ERR_LOG("GetPropertyValueByName not exist %{public}s", propertyName);
721 return nullptr;
722 }
723 if (napi_get_named_property(env, jsObject, propertyName, &value) != napi_ok) {
724 NAPI_ERR_LOG("GetPropertyValueByName get fail %{public}s", propertyName);
725 return nullptr;
726 }
727 return value;
728 }
729
CheckJSArgsTypeAsFunc(napi_env env,napi_value arg)730 bool SendableMediaLibraryNapiUtils::CheckJSArgsTypeAsFunc(napi_env env, napi_value arg)
731 {
732 napi_valuetype valueType = napi_undefined;
733 napi_typeof(env, arg, &valueType);
734 return (valueType == napi_function);
735 }
736
IsArrayForNapiValue(napi_env env,napi_value param,uint32_t & arraySize)737 bool SendableMediaLibraryNapiUtils::IsArrayForNapiValue(napi_env env, napi_value param, uint32_t &arraySize)
738 {
739 bool isArray = false;
740 arraySize = 0;
741 if ((napi_is_array(env, param, &isArray) != napi_ok) || (isArray == false)) {
742 return false;
743 }
744 if (napi_get_array_length(env, param, &arraySize) != napi_ok) {
745 return false;
746 }
747 return true;
748 }
749
GetInt32Arg(napi_env env,napi_value arg,int32_t & value)750 napi_value SendableMediaLibraryNapiUtils::GetInt32Arg(napi_env env, napi_value arg, int32_t &value)
751 {
752 napi_valuetype valueType = napi_undefined;
753 CHECK_ARGS(env, napi_typeof(env, arg, &valueType), JS_INNER_FAIL);
754 if (valueType != napi_number) {
755 NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID);
756 return nullptr;
757 }
758 CHECK_ARGS(env, napi_get_value_int32(env, arg, &value), JS_INNER_FAIL);
759
760 napi_value result = nullptr;
761 CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
762 return result;
763 }
764
UriAppendKeyValue(string & uri,const string & key,const string & value)765 void SendableMediaLibraryNapiUtils::UriAppendKeyValue(string &uri, const string &key, const string &value)
766 {
767 string uriKey = key + '=';
768 if (uri.find(uriKey) != string::npos) {
769 return;
770 }
771
772 char queryMark = (uri.find('?') == string::npos) ? '?' : '&';
773 string append = queryMark + key + '=' + value;
774
775 size_t posJ = uri.find('#');
776 if (posJ == string::npos) {
777 uri += append;
778 } else {
779 uri.insert(posJ, append);
780 }
781 }
782
AddAssetColumns(napi_env env,vector<string> & fetchColumn,function<bool (const string & columnName)> isValidColumn,std::set<std::string> & validFetchColumns,const PhotoAlbumSubType subType)783 napi_value SendableMediaLibraryNapiUtils::AddAssetColumns(napi_env env, vector<string> &fetchColumn,
784 function<bool(const string &columnName)> isValidColumn, std::set<std::string>& validFetchColumns,
785 const PhotoAlbumSubType subType)
786 {
787 switch (subType) {
788 case PhotoAlbumSubType::FAVORITE:
789 validFetchColumns.insert(MediaColumn::MEDIA_IS_FAV);
790 break;
791 case PhotoAlbumSubType::VIDEO:
792 validFetchColumns.insert(MediaColumn::MEDIA_TYPE);
793 break;
794 case PhotoAlbumSubType::HIDDEN:
795 validFetchColumns.insert(MediaColumn::MEDIA_HIDDEN);
796 break;
797 case PhotoAlbumSubType::TRASH:
798 validFetchColumns.insert(MediaColumn::MEDIA_DATE_TRASHED);
799 break;
800 case PhotoAlbumSubType::SCREENSHOT:
801 case PhotoAlbumSubType::CAMERA:
802 validFetchColumns.insert(PhotoColumn::PHOTO_SUBTYPE);
803 break;
804 default:
805 break;
806 }
807 for (const auto &column : fetchColumn) {
808 if (column == PENDING_STATUS) {
809 validFetchColumns.insert(MediaColumn::MEDIA_TIME_PENDING);
810 } else if (isValidColumn(column)) {
811 validFetchColumns.insert(column);
812 } else if (column == MEDIA_DATA_DB_URI) {
813 continue;
814 } else if (DATE_TRANSITION_MAP.count(column) != 0) {
815 validFetchColumns.insert(DATE_TRANSITION_MAP.at(column));
816 } else {
817 NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID);
818 return nullptr;
819 }
820 }
821 fetchColumn.assign(validFetchColumns.begin(), validFetchColumns.end());
822
823 napi_value result = nullptr;
824 CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
825 return result;
826 }
827
AddDefaultAssetColumns(napi_env env,vector<string> & fetchColumn,function<bool (const string & columnName)> isValidColumn,NapiAssetType assetType,const PhotoAlbumSubType subType)828 napi_value SendableMediaLibraryNapiUtils::AddDefaultAssetColumns(napi_env env, vector<string> &fetchColumn,
829 function<bool(const string &columnName)> isValidColumn, NapiAssetType assetType,
830 const PhotoAlbumSubType subType)
831 {
832 auto validFetchColumns = MediaColumn::DEFAULT_FETCH_COLUMNS;
833 if (assetType == TYPE_PHOTO) {
834 validFetchColumns.insert(
835 PhotoColumn::DEFAULT_FETCH_COLUMNS.begin(), PhotoColumn::DEFAULT_FETCH_COLUMNS.end());
836 }
837 return AddAssetColumns(env, fetchColumn, isValidColumn, validFetchColumns, subType);
838 }
839
SetDefaultPredicatesCondition(DataSharePredicates & predicates,const int32_t dateTrashed,const bool isHidden,const int32_t timePending,const bool isTemp)840 inline void SetDefaultPredicatesCondition(DataSharePredicates &predicates, const int32_t dateTrashed,
841 const bool isHidden, const int32_t timePending, const bool isTemp)
842 {
843 predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, to_string(dateTrashed));
844 predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, to_string(isHidden));
845 predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, to_string(timePending));
846 predicates.EqualTo(PhotoColumn::PHOTO_IS_TEMP, to_string(isTemp));
847 predicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL,
848 to_string(static_cast<int32_t>(BurstCoverLevelType::COVER)));
849 }
850
GetUserAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates,const bool hiddenOnly)851 int32_t SendableMediaLibraryNapiUtils::GetUserAlbumPredicates(
852 const int32_t albumId, DataSharePredicates &predicates, const bool hiddenOnly)
853 {
854 predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(albumId));
855 SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
856 return E_SUCCESS;
857 }
858
GetPortraitAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates)859 int32_t SendableMediaLibraryNapiUtils::GetPortraitAlbumPredicates(const int32_t albumId,
860 DataSharePredicates &predicates)
861 {
862 string onClause = MediaColumn::MEDIA_ID + " = " + PhotoMap::ASSET_ID;
863 vector<string> clauses = { onClause };
864 predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On(clauses);
865 onClause = ALBUM_ID + " = " + PhotoMap::ALBUM_ID;
866 clauses = { onClause };
867 predicates.InnerJoin(ANALYSIS_ALBUM_TABLE)->On(clauses);
868 string tempTable = "(SELECT " + GROUP_TAG + " FROM " + ANALYSIS_ALBUM_TABLE + " WHERE " + ALBUM_ID + " = " +
869 to_string(albumId) + ") ag";
870 onClause = "ag." + GROUP_TAG + " = " + ANALYSIS_ALBUM_TABLE + "." + GROUP_TAG;
871 clauses = { onClause };
872 predicates.InnerJoin(tempTable)->On(clauses);
873 SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
874 predicates.Distinct();
875 return E_SUCCESS;
876 }
877
GetAnalysisAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates)878 int32_t SendableMediaLibraryNapiUtils::GetAnalysisAlbumPredicates(const int32_t albumId,
879 DataSharePredicates &predicates)
880 {
881 string onClause = MediaColumn::MEDIA_ID + " = " + PhotoMap::ASSET_ID;
882 predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On({ onClause });
883 predicates.EqualTo(PhotoMap::ALBUM_ID, to_string(albumId));
884 SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
885 return E_SUCCESS;
886 }
887
IsFeaturedSinglePortraitAlbum(std::string albumName,DataShare::DataSharePredicates & predicates)888 bool SendableMediaLibraryNapiUtils::IsFeaturedSinglePortraitAlbum(
889 std::string albumName, DataShare::DataSharePredicates &predicates)
890 {
891 bool isFeaturedSinglePortrait = false;
892 int portraitAlbumId = 0;
893 if (albumName.compare(to_string(portraitAlbumId)) != 0) {
894 return isFeaturedSinglePortrait;
895 }
896
897 DataSharePredicates featuredSinglePortraitPredicates;
898 std::vector<OperationItem> operationList = predicates.GetOperationList();
899 for (auto& operationItem : operationList) {
900 switch (operationItem.operation) {
901 case OHOS::DataShare::OperationType::LIKE : {
902 std::string field = std::get<string>(operationItem.singleParams[0]);
903 std::string value = std::get<string>(operationItem.singleParams[1]);
904 if (field.compare("FeaturedSinglePortrait") == 0 && value.compare("true") == 0) {
905 isFeaturedSinglePortrait = true;
906 } else {
907 featuredSinglePortraitPredicates.Like(field, value);
908 }
909 break;
910 }
911 case OHOS::DataShare::OperationType::ORDER_BY_DESC : {
912 featuredSinglePortraitPredicates.OrderByDesc(operationItem.GetSingle(0));
913 break;
914 }
915 case OHOS::DataShare::OperationType::LIMIT : {
916 featuredSinglePortraitPredicates.Limit(operationItem.GetSingle(0), operationItem.GetSingle(1));
917 break;
918 }
919 default: {
920 break;
921 }
922 }
923 }
924
925 if (isFeaturedSinglePortrait) {
926 predicates = featuredSinglePortraitPredicates;
927 }
928 return isFeaturedSinglePortrait;
929 }
930
GetFeaturedSinglePortraitAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates)931 int32_t SendableMediaLibraryNapiUtils::GetFeaturedSinglePortraitAlbumPredicates(
932 const int32_t albumId, DataSharePredicates &predicates)
933 {
934 string onClause = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID + " = " +
935 ANALYSIS_PHOTO_MAP_TABLE + "." + PhotoMap::ASSET_ID;
936 predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On({ onClause });
937
938 constexpr int32_t minSize = 224;
939 string imgHeightColumn = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_HEIGHT;
940 string imgWidthColumn = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_WIDTH;
941 string imgFaceHeightColumn = VISION_IMAGE_FACE_TABLE + "." + SCALE_HEIGHT;
942 string imgFaceWidthColumn = VISION_IMAGE_FACE_TABLE + "." + SCALE_WIDTH;
943 string imgFaceHeightClause = "( " + imgFaceHeightColumn + " > " + to_string(minSize) +
944 " OR ( " + imgFaceHeightColumn + " <= 1.0 " + " AND " + imgFaceHeightColumn + " * " + imgHeightColumn +
945 " > " + to_string(minSize) + " ) )";
946 string imgFaceWidthClause = "( " + imgFaceWidthColumn + " > " + to_string(minSize) +
947 " OR ( " + imgFaceWidthColumn + " <= 1.0 " + " AND " + imgFaceWidthColumn + " * " + imgWidthColumn +
948 " > " + to_string(minSize) + " ) )";
949 string imgFaceOcclusionClause = "( " + VISION_IMAGE_FACE_TABLE + "." + FACE_OCCLUSION + " != 1 OR " +
950 VISION_IMAGE_FACE_TABLE + "." + FACE_OCCLUSION + " IS NULL )";
951 string portraitRotationLimit = "BETWEEN -30 AND 30";
952 onClause = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID + " = " + VISION_IMAGE_FACE_TABLE + "." +
953 MediaColumn::MEDIA_ID + " AND " + VISION_IMAGE_FACE_TABLE + "." + TOTAL_FACES + " = 1 AND " +
954 imgFaceHeightClause + " AND " + imgFaceWidthClause + " AND " + imgFaceOcclusionClause + " AND " +
955 VISION_IMAGE_FACE_TABLE + "." + PITCH + " " + portraitRotationLimit + " AND " +
956 VISION_IMAGE_FACE_TABLE + "." + YAW + " " + portraitRotationLimit + " AND " +
957 VISION_IMAGE_FACE_TABLE + "." + ROLL + " " + portraitRotationLimit;
958 predicates.InnerJoin(VISION_IMAGE_FACE_TABLE)->On({ onClause });
959
960 string portraitType = "IN ( 1, 2 )";
961 onClause = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID + " = " + VISION_POSE_TABLE + "." +
962 MediaColumn::MEDIA_ID + " AND " + VISION_POSE_TABLE + "." + POSE_TYPE + " " + portraitType;
963 predicates.InnerJoin(VISION_POSE_TABLE)->On({ onClause });
964
965 predicates.EqualTo(PhotoMap::ALBUM_ID, to_string(albumId));
966 SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
967 return E_SUCCESS;
968 }
969
GetAllLocationPredicates(DataSharePredicates & predicates)970 int32_t SendableMediaLibraryNapiUtils::GetAllLocationPredicates(DataSharePredicates &predicates)
971 {
972 SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
973 predicates.And()->NotEqualTo(PhotoColumn::PHOTO_LATITUDE, to_string(0));
974 predicates.And()->NotEqualTo(PhotoColumn::PHOTO_LONGITUDE, to_string(0));
975 return E_SUCCESS;
976 }
977
GetFavoritePredicates(DataSharePredicates & predicates,const bool hiddenOnly)978 static int32_t GetFavoritePredicates(DataSharePredicates &predicates, const bool hiddenOnly)
979 {
980 predicates.BeginWrap();
981 constexpr int32_t IS_FAVORITE = 1;
982 predicates.EqualTo(MediaColumn::MEDIA_IS_FAV, to_string(IS_FAVORITE));
983 SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
984 predicates.EndWrap();
985 return E_SUCCESS;
986 }
987
GetVideoPredicates(DataSharePredicates & predicates,const bool hiddenOnly)988 static int32_t GetVideoPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
989 {
990 predicates.BeginWrap();
991 predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_VIDEO));
992 SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
993 predicates.EndWrap();
994 return E_SUCCESS;
995 }
996
GetHiddenPredicates(DataSharePredicates & predicates)997 static int32_t GetHiddenPredicates(DataSharePredicates &predicates)
998 {
999 predicates.BeginWrap();
1000 SetDefaultPredicatesCondition(predicates, 0, 1, 0, false);
1001 predicates.EndWrap();
1002 return E_SUCCESS;
1003 }
1004
GetTrashPredicates(DataSharePredicates & predicates)1005 static int32_t GetTrashPredicates(DataSharePredicates &predicates)
1006 {
1007 predicates.BeginWrap();
1008 predicates.GreaterThan(MediaColumn::MEDIA_DATE_TRASHED, to_string(0));
1009 predicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL,
1010 to_string(static_cast<int32_t>(BurstCoverLevelType::COVER)));
1011 predicates.EndWrap();
1012 return E_SUCCESS;
1013 }
1014
GetScreenshotPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1015 static int32_t GetScreenshotPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1016 {
1017 predicates.BeginWrap();
1018 predicates.EqualTo(PhotoColumn::PHOTO_SUBTYPE, to_string(static_cast<int32_t>(PhotoSubType::SCREENSHOT)));
1019 SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1020 predicates.EndWrap();
1021 return E_SUCCESS;
1022 }
1023
GetCameraPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1024 static int32_t GetCameraPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1025 {
1026 predicates.BeginWrap();
1027 predicates.EqualTo(PhotoColumn::PHOTO_SUBTYPE, to_string(static_cast<int32_t>(PhotoSubType::CAMERA)));
1028 SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1029 predicates.EndWrap();
1030 return E_SUCCESS;
1031 }
1032
GetAllImagesPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1033 static int32_t GetAllImagesPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1034 {
1035 predicates.BeginWrap();
1036 predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_IMAGE));
1037 SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1038 predicates.EndWrap();
1039 return E_SUCCESS;
1040 }
1041
GetCloudEnhancementPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1042 static int32_t GetCloudEnhancementPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1043 {
1044 predicates.BeginWrap();
1045 predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_IMAGE));
1046 predicates.EqualTo(PhotoColumn::PHOTO_STRONG_ASSOCIATION,
1047 to_string(static_cast<int32_t>(StrongAssociationType::CLOUD_ENHANCEMENT)));
1048 SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1049 predicates.EndWrap();
1050 return E_SUCCESS;
1051 }
1052
GetSourceAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates,const bool hiddenOnly)1053 int32_t SendableMediaLibraryNapiUtils::GetSourceAlbumPredicates(const int32_t albumId, DataSharePredicates &predicates,
1054 const bool hiddenOnly)
1055 {
1056 predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(albumId));
1057 predicates.EqualTo(PhotoColumn::PHOTO_SYNC_STATUS, to_string(static_cast<int32_t>(SyncStatusType::TYPE_VISIBLE)));
1058 SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1059 return E_SUCCESS;
1060 }
1061
GetSystemAlbumPredicates(const PhotoAlbumSubType subType,DataSharePredicates & predicates,const bool hiddenOnly)1062 int32_t SendableMediaLibraryNapiUtils::GetSystemAlbumPredicates(const PhotoAlbumSubType subType,
1063 DataSharePredicates &predicates, const bool hiddenOnly)
1064 {
1065 switch (subType) {
1066 case PhotoAlbumSubType::FAVORITE: {
1067 return GetFavoritePredicates(predicates, hiddenOnly);
1068 }
1069 case PhotoAlbumSubType::VIDEO: {
1070 return GetVideoPredicates(predicates, hiddenOnly);
1071 }
1072 case PhotoAlbumSubType::HIDDEN: {
1073 return GetHiddenPredicates(predicates);
1074 }
1075 case PhotoAlbumSubType::TRASH: {
1076 return GetTrashPredicates(predicates);
1077 }
1078 case PhotoAlbumSubType::SCREENSHOT: {
1079 return GetScreenshotPredicates(predicates, hiddenOnly);
1080 }
1081 case PhotoAlbumSubType::CAMERA: {
1082 return GetCameraPredicates(predicates, hiddenOnly);
1083 }
1084 case PhotoAlbumSubType::IMAGE: {
1085 return GetAllImagesPredicates(predicates, hiddenOnly);
1086 }
1087 case PhotoAlbumSubType::CLOUD_ENHANCEMENT: {
1088 return GetCloudEnhancementPredicates(predicates, hiddenOnly);
1089 }
1090 default: {
1091 NAPI_ERR_LOG("Unsupported photo album subtype: %{public}d", subType);
1092 return E_INVALID_ARGUMENTS;
1093 }
1094 }
1095 }
1096
CreateValueByIndex(napi_env env,int32_t index,string name,shared_ptr<NativeRdb::ResultSet> & resultSet,const shared_ptr<FileAsset> & asset)1097 napi_value SendableMediaLibraryNapiUtils::CreateValueByIndex(napi_env env, int32_t index, string name,
1098 shared_ptr<NativeRdb::ResultSet> &resultSet, const shared_ptr<FileAsset> &asset)
1099 {
1100 int status;
1101 int integerVal = 0;
1102 string stringVal = "";
1103 int64_t longVal = 0;
1104 double doubleVal = 0.0;
1105 napi_value value = nullptr;
1106 auto dataType = SendableMediaLibraryNapiUtils::GetTypeMap().at(name);
1107 switch (dataType.first) {
1108 case TYPE_STRING:
1109 status = resultSet->GetString(index, stringVal);
1110 napi_create_string_utf8(env, stringVal.c_str(), NAPI_AUTO_LENGTH, &value);
1111 asset->GetMemberMap().emplace(name, stringVal);
1112 break;
1113 case TYPE_INT32:
1114 status = resultSet->GetInt(index, integerVal);
1115 napi_create_int32(env, integerVal, &value);
1116 asset->GetMemberMap().emplace(name, integerVal);
1117 break;
1118 case TYPE_INT64:
1119 status = resultSet->GetLong(index, longVal);
1120 napi_create_int64(env, longVal, &value);
1121 asset->GetMemberMap().emplace(name, longVal);
1122 break;
1123 case TYPE_DOUBLE:
1124 status = resultSet->GetDouble(index, doubleVal);
1125 napi_create_double(env, doubleVal, &value);
1126 asset->GetMemberMap().emplace(name, doubleVal);
1127 break;
1128 default:
1129 NAPI_ERR_LOG("not match dataType %{public}d", dataType.first);
1130 break;
1131 }
1132
1133 return value;
1134 }
1135
handleTimeInfo(napi_env env,const std::string & name,napi_value result,int32_t index,const std::shared_ptr<NativeRdb::ResultSet> & resultSet)1136 void SendableMediaLibraryNapiUtils::handleTimeInfo(napi_env env, const std::string& name, napi_value result,
1137 int32_t index, const std::shared_ptr<NativeRdb::ResultSet>& resultSet)
1138 {
1139 if (TIME_COLUMN.count(name) == 0) {
1140 return;
1141 }
1142 int64_t longVal = 0;
1143 int status;
1144 napi_value value = nullptr;
1145 status = resultSet->GetLong(index, longVal);
1146 int64_t modifieldValue = longVal / 1000;
1147 napi_create_int64(env, modifieldValue, &value);
1148 auto dataType = SendableMediaLibraryNapiUtils::GetTimeTypeMap().at(name);
1149 napi_set_named_property(env, result, dataType.second.c_str(), value);
1150 }
1151
handleThumbnailReady(napi_env env,const std::string & name,napi_value result,int32_t index,const std::shared_ptr<NativeRdb::ResultSet> & resultSet)1152 static void handleThumbnailReady(napi_env env, const std::string& name, napi_value result, int32_t index,
1153 const std::shared_ptr<NativeRdb::ResultSet>& resultSet)
1154 {
1155 if (name != "thumbnail_ready") {
1156 return;
1157 }
1158 int64_t longVal = 0;
1159 int status;
1160 napi_value value = nullptr;
1161 status = resultSet->GetLong(index, longVal);
1162 bool resultVal = longVal > 0;
1163 napi_create_int32(env, resultVal, &value);
1164 napi_set_named_property(env, result, "thumbnailReady", value);
1165 }
1166
GetNextRowObject(napi_env env,shared_ptr<NativeRdb::ResultSet> & resultSet)1167 napi_value SendableMediaLibraryNapiUtils::GetNextRowObject(napi_env env,
1168 shared_ptr<NativeRdb::ResultSet> &resultSet)
1169 {
1170 if (resultSet == nullptr) {
1171 NAPI_ERR_LOG("GetNextRowObject fail, result is nullptr");
1172 return nullptr;
1173 }
1174 vector<string> columnNames;
1175 resultSet->GetAllColumnNames(columnNames);
1176
1177 napi_value result = nullptr;
1178 napi_create_object(env, &result);
1179
1180 napi_value value = nullptr;
1181 int32_t index = -1;
1182 auto fileAsset = make_shared<FileAsset>();
1183 for (const auto &name : columnNames) {
1184 index++;
1185
1186 // Check if the column name exists in the type map
1187 if (SendableMediaLibraryNapiUtils::GetTypeMap().count(name) == 0) {
1188 continue;
1189 }
1190 value = SendableMediaLibraryNapiUtils::CreateValueByIndex(env, index, name, resultSet, fileAsset);
1191 auto dataType = SendableMediaLibraryNapiUtils::GetTypeMap().at(name);
1192 napi_set_named_property(env, result, dataType.second.c_str(), value);
1193 handleTimeInfo(env, name, result, index, resultSet);
1194 handleThumbnailReady(env, name, result, index, resultSet);
1195 }
1196
1197 if (fileAsset->GetDisplayName().empty() && fileAsset->GetPath().empty()) {
1198 return result;
1199 }
1200 string extrUri = MediaFileUtils::GetExtraUri(fileAsset->GetDisplayName(), fileAsset->GetPath(), false);
1201 MediaFileUri fileUri(fileAsset->GetMediaType(), to_string(fileAsset->GetId()), "", MEDIA_API_VERSION_V10, extrUri);
1202 fileAsset->SetUri(move(fileUri.ToString()));
1203 napi_create_string_utf8(env, fileAsset->GetUri().c_str(), NAPI_AUTO_LENGTH, &value);
1204 napi_set_named_property(env, result, MEDIA_DATA_DB_URI.c_str(), value);
1205 return result;
1206 }
1207
IsSystemApp()1208 bool SendableMediaLibraryNapiUtils::IsSystemApp()
1209 {
1210 static bool isSys = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetSelfTokenID());
1211 return isSys;
1212 }
1213
SendableNapiScopeHandler(napi_env env)1214 SendableNapiScopeHandler::SendableNapiScopeHandler(napi_env env): env_(env)
1215 {
1216 napi_status status = napi_open_handle_scope(env_, &scope_);
1217 if (status != napi_ok) {
1218 NAPI_ERR_LOG("Open Handler scope failed, status %{public}d", status);
1219 isValid_ = false;
1220 } else {
1221 isValid_ = true;
1222 }
1223 }
1224
~SendableNapiScopeHandler()1225 SendableNapiScopeHandler::~SendableNapiScopeHandler()
1226 {
1227 if (isValid_) {
1228 napi_status status = napi_close_handle_scope(env_, scope_);
1229 if (status != napi_ok) {
1230 NAPI_ERR_LOG("Close Handler scope failed, status %{public}d", status);
1231 }
1232 }
1233 }
1234
IsValid()1235 bool SendableNapiScopeHandler::IsValid()
1236 {
1237 return isValid_;
1238 }
1239
GetNapiValueArray(napi_env env,napi_value arg,vector<napi_value> & values)1240 napi_value SendableMediaLibraryNapiUtils::GetNapiValueArray(napi_env env, napi_value arg, vector<napi_value> &values)
1241 {
1242 bool isArray = false;
1243 CHECK_ARGS(env, napi_is_array(env, arg, &isArray), OHOS_INVALID_PARAM_CODE);
1244 if (!isArray) {
1245 NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, "Failed to check array type");
1246 return nullptr;
1247 }
1248
1249 uint32_t len = 0;
1250 CHECK_ARGS(env, napi_get_array_length(env, arg, &len), JS_INNER_FAIL);
1251 if (len == 0) {
1252 napi_value result = nullptr;
1253 CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
1254 return result;
1255 }
1256
1257 for (uint32_t i = 0; i < len; i++) {
1258 napi_value value = nullptr;
1259 CHECK_ARGS(env, napi_get_element(env, arg, i, &value), JS_INNER_FAIL);
1260 if (value == nullptr) {
1261 NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, "Failed to get element");
1262 return nullptr;
1263 }
1264 values.push_back(value);
1265 }
1266
1267 napi_value result = nullptr;
1268 CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
1269 return result;
1270 }
1271
GetStringArray(napi_env env,vector<napi_value> & napiValues,vector<string> & values)1272 napi_value SendableMediaLibraryNapiUtils::GetStringArray(napi_env env, vector<napi_value> &napiValues,
1273 vector<string> &values)
1274 {
1275 napi_valuetype valueType = napi_undefined;
1276 unique_ptr<char[]> buffer = make_unique<char[]>(PATH_MAX);
1277 for (const auto &napiValue : napiValues) {
1278 CHECK_ARGS(env, napi_typeof(env, napiValue, &valueType), JS_ERR_PARAMETER_INVALID);
1279 CHECK_COND(env, valueType == napi_string, JS_ERR_PARAMETER_INVALID);
1280
1281 size_t res = 0;
1282 CHECK_ARGS(
1283 env, napi_get_value_string_utf8(env, napiValue, buffer.get(), PATH_MAX, &res), JS_ERR_PARAMETER_INVALID);
1284 values.emplace_back(buffer.get());
1285 }
1286 napi_value ret = nullptr;
1287 CHECK_ARGS(env, napi_get_boolean(env, true, &ret), JS_INNER_FAIL);
1288 return ret;
1289 }
1290
1291 template <class AsyncContext>
ParsePredicates(napi_env env,const napi_value arg,AsyncContext & context,const FetchOptionType & fetchOptType)1292 napi_status SendableMediaLibraryNapiUtils::ParsePredicates(napi_env env, const napi_value arg,
1293 AsyncContext &context, const FetchOptionType &fetchOptType)
1294 {
1295 JSProxy::JSProxy<DataShareAbsPredicates> *jsProxy = nullptr;
1296 napi_unwrap(env, arg, reinterpret_cast<void **>(&jsProxy));
1297 if (jsProxy == nullptr) {
1298 NAPI_ERR_LOG("jsProxy is invalid");
1299 return napi_invalid_arg;
1300 }
1301 shared_ptr<DataShareAbsPredicates> predicate = jsProxy->GetInstance();
1302 CHECK_COND_RET(HandleSpecialPredicate(context, predicate, fetchOptType) == TRUE,
1303 napi_invalid_arg, "invalid predicate");
1304 CHECK_COND_RET(GetLocationPredicate(context, predicate) == TRUE, napi_invalid_arg, "invalid predicate");
1305 return napi_ok;
1306 }
1307
1308 template bool SendableMediaLibraryNapiUtils::HandleSpecialPredicate<unique_ptr<SendablePAHAsyncContext>>(
1309 unique_ptr<SendablePAHAsyncContext> &context, shared_ptr<DataShareAbsPredicates> &predicate,
1310 const FetchOptionType &fetchOptType);
1311
1312 template napi_status SendableMediaLibraryNapiUtils::GetFetchOption<unique_ptr<SendablePAHAsyncContext>>(
1313 napi_env env, napi_value arg, const FetchOptionType &fetchOptType,
1314 unique_ptr<SendablePAHAsyncContext> &context);
1315
1316 template napi_status SendableMediaLibraryNapiUtils::GetFetchOption<unique_ptr<SendablePANAsyncContext>>(
1317 napi_env env, napi_value arg, const FetchOptionType &fetchOptType,
1318 unique_ptr<SendablePANAsyncContext> &context);
1319
1320 template napi_status SendableMediaLibraryNapiUtils::GetAlbumFetchOption<unique_ptr<SendablePANAsyncContext>>(
1321 napi_env env, napi_value arg, const FetchOptionType &fetchOptType,
1322 unique_ptr<SendablePANAsyncContext> &context);
1323
1324 template napi_status SendableMediaLibraryNapiUtils::GetPredicate<unique_ptr<SendablePAHAsyncContext>>(
1325 napi_env env, const napi_value arg, const string &propName,
1326 unique_ptr<SendablePAHAsyncContext> &context, const FetchOptionType &fetchOptType);
1327
1328 template napi_status SendableMediaLibraryNapiUtils::ParseArgsStringArrayCallback<unique_ptr<SendablePAHAsyncContext>>(
1329 napi_env env, napi_callback_info info,
1330 unique_ptr<SendablePAHAsyncContext> &context, vector<string> &array);
1331
1332 template napi_status SendableMediaLibraryNapiUtils::GetParamCallback<unique_ptr<SendablePANAsyncContext>>(
1333 napi_env env, unique_ptr<SendablePANAsyncContext> &context);
1334
1335 template napi_status SendableMediaLibraryNapiUtils::GetParamCallback<unique_ptr<SendablePAHAsyncContext>>(
1336 napi_env env, unique_ptr<SendablePAHAsyncContext> &context);
1337
1338 template napi_status SendableMediaLibraryNapiUtils::GetParamCallback<unique_ptr<SendablePhotoAccessHelperInitContext>>(
1339 napi_env env, unique_ptr<SendablePhotoAccessHelperInitContext> &context);
1340
1341 template napi_status SendableMediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<SendableFAAsyncContext>>(
1342 napi_env env, napi_callback_info info, unique_ptr<SendableFAAsyncContext> &context, string ¶m);
1343
1344 template napi_status SendableMediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<SendablePANAsyncContext>>(
1345 napi_env env, napi_callback_info info,
1346 unique_ptr<SendablePANAsyncContext> &context, string ¶m);
1347
1348 template napi_status SendableMediaLibraryNapiUtils::ParseArgsBoolCallBack<unique_ptr<SendableFAAsyncContext>>(
1349 napi_env env, napi_callback_info info, unique_ptr<SendableFAAsyncContext> &context, bool ¶m);
1350
1351 template napi_status SendableMediaLibraryNapiUtils::AsyncContextSetObjectInfo<unique_ptr<SendablePAHAsyncContext>>(
1352 napi_env env, napi_callback_info info, unique_ptr<SendablePAHAsyncContext> &asyncContext,
1353 const size_t minArgs, const size_t maxArgs);
1354
1355 template napi_status SendableMediaLibraryNapiUtils::AsyncContextSetObjectInfo<unique_ptr<SendableFAAsyncContext>>(
1356 napi_env env, napi_callback_info info, unique_ptr<SendableFAAsyncContext> &asyncContext,
1357 const size_t minArgs, const size_t maxArgs);
1358
1359 template napi_status SendableMediaLibraryNapiUtils::AsyncContextSetObjectInfo<unique_ptr<SendablePANAsyncContext>>(
1360 napi_env env, napi_callback_info info, unique_ptr<SendablePANAsyncContext> &asyncContext,
1361 const size_t minArgs, const size_t maxArgs);
1362
1363 template napi_value SendableMediaLibraryNapiUtils::NapiCreateAsyncWork<SendablePAHAsyncContext>(
1364 napi_env env, unique_ptr<SendablePAHAsyncContext> &asyncContext, const string &resourceName,
1365 void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1366
1367 template napi_value SendableMediaLibraryNapiUtils::NapiCreateAsyncWork<SendablePhotoAccessHelperInitContext>(
1368 napi_env env, unique_ptr<SendablePhotoAccessHelperInitContext> &asyncContext, const string &resourceName,
1369 void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1370
1371 template napi_value SendableMediaLibraryNapiUtils::NapiCreateAsyncWork<SendableFAAsyncContext>(napi_env env,
1372 unique_ptr<SendableFAAsyncContext> &asyncContext, const string &resourceName,
1373 void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1374
1375 template napi_value SendableMediaLibraryNapiUtils::NapiCreateAsyncWork<SendablePANAsyncContext>(
1376 napi_env env, unique_ptr<SendablePANAsyncContext> &asyncContext, const string &resourceName,
1377 void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1378
1379 template napi_status SendableMediaLibraryNapiUtils::ParseArgsNumberCallback<unique_ptr<SendableFAAsyncContext>>(
1380 napi_env env, napi_callback_info info, unique_ptr<SendableFAAsyncContext> &context, int32_t &value);
1381
1382 template napi_status SendableMediaLibraryNapiUtils::ParseArgsOnlyCallBack<unique_ptr<SendableFAAsyncContext>>(
1383 napi_env env, napi_callback_info info, unique_ptr<SendableFAAsyncContext> &context);
1384
1385 template napi_status SendableMediaLibraryNapiUtils::ParsePredicates<unique_ptr<SendablePAHAsyncContext>>(
1386 napi_env env, const napi_value arg, unique_ptr<SendablePAHAsyncContext> &context,
1387 const FetchOptionType &fetchOptType);
1388
1389 } // namespace Media
1390 } // namespace OHOS
1391