• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #define 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,vector<OperationItem> operations)232 bool SendableMediaLibraryNapiUtils::HandleSpecialPredicate(AsyncContext &context,
233     shared_ptr<DataShareAbsPredicates> &predicate, const FetchOptionType &fetchOptType,
234     vector<OperationItem> operations)
235 {
236     constexpr int32_t FIELD_IDX = 0;
237     constexpr int32_t VALUE_IDX = 1;
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,vector<OperationItem> operations)343 napi_status SendableMediaLibraryNapiUtils::GetFetchOption(napi_env env, napi_value arg,
344     const FetchOptionType &fetchOptType, AsyncContext &context, vector<OperationItem> operations)
345 {
346     // Parse the argument into fetchOption if any
347     CHECK_STATUS_RET(GetPredicate(env, arg, "predicates", context, fetchOptType, move(operations)),
348         "invalid predicate");
349     CHECK_STATUS_RET(GetArrayProperty(env, arg, "fetchColumns", context->fetchColumn),
350         "Failed to parse fetchColumn");
351     return napi_ok;
352 }
353 
354 template <class AsyncContext>
GetAlbumFetchOption(napi_env env,napi_value arg,const FetchOptionType & fetchOptType,AsyncContext & context)355 napi_status SendableMediaLibraryNapiUtils::GetAlbumFetchOption(napi_env env, napi_value arg,
356     const FetchOptionType &fetchOptType, AsyncContext &context)
357 {
358     // Parse the argument into AlbumFetchOption if any
359     CHECK_STATUS_RET(GetPredicate(env, arg, "predicates", context, fetchOptType), "invalid predicate");
360     return napi_ok;
361 }
362 
363 template <class AsyncContext>
GetPredicate(napi_env env,const napi_value arg,const string & propName,AsyncContext & context,const FetchOptionType & fetchOptType,vector<OperationItem> operations)364 napi_status SendableMediaLibraryNapiUtils::GetPredicate(napi_env env, const napi_value arg, const string &propName,
365     AsyncContext &context, const FetchOptionType &fetchOptType, vector<OperationItem> operations)
366 {
367     bool present = false;
368     napi_value property = nullptr;
369     CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present),
370         "Failed to check property name");
371     if (present) {
372         CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property), "Failed to get property");
373         JSProxy::JSProxy<DataShareAbsPredicates> *jsProxy = nullptr;
374         napi_unwrap(env, property, reinterpret_cast<void **>(&jsProxy));
375         if (jsProxy == nullptr) {
376             NAPI_ERR_LOG("jsProxy is invalid");
377             return napi_invalid_arg;
378         }
379         shared_ptr<DataShareAbsPredicates> predicate = jsProxy->GetInstance();
380         CHECK_COND_RET(HandleSpecialPredicate(context, predicate, fetchOptType, move(operations)) == TRUE,
381             napi_invalid_arg, "invalid predicate");
382         CHECK_COND_RET(GetLocationPredicate(context, predicate) == TRUE, napi_invalid_arg, "invalid predicate");
383     }
384     return napi_ok;
385 }
386 
387 template <class AsyncContext>
ParseAssetFetchOptCallback(napi_env env,napi_callback_info info,AsyncContext & context)388 napi_status SendableMediaLibraryNapiUtils::ParseAssetFetchOptCallback(napi_env env, napi_callback_info info,
389     AsyncContext &context)
390 {
391     constexpr size_t minArgs = ARGS_ONE;
392     constexpr size_t maxArgs = ARGS_TWO;
393     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
394         "Failed to get object info");
395     CHECK_STATUS_RET(GetFetchOption(env, context->argv[PARAM0], ASSET_FETCH_OPT, context),
396         "Failed to get fetch option");
397     return napi_ok;
398 }
399 
400 template <class AsyncContext>
ParseAlbumFetchOptCallback(napi_env env,napi_callback_info info,AsyncContext & context)401 napi_status SendableMediaLibraryNapiUtils::ParseAlbumFetchOptCallback(napi_env env, napi_callback_info info,
402     AsyncContext &context)
403 {
404     constexpr size_t minArgs = ARGS_ONE;
405     constexpr size_t maxArgs = ARGS_TWO;
406     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
407         "Failed to get object info");
408     // Parse the argument into fetchOption if any
409     CHECK_STATUS_RET(GetPredicate(env, context->argv[PARAM0], "predicates", context, ALBUM_FETCH_OPT),
410         "invalid predicate");
411     context->predicates.And()->NotEqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::HIDDEN));
412     return napi_ok;
413 }
414 
415 template <class AsyncContext>
UpdateMediaTypeSelections(AsyncContext * context)416 void SendableMediaLibraryNapiUtils::UpdateMediaTypeSelections(AsyncContext *context)
417 {
418     constexpr int FIRST_MEDIA_TYPE = 0;
419     constexpr int SECOND_MEDIA_TYPE = 1;
420     if ((context->mediaTypes.size() != ARGS_ONE) && (context->mediaTypes.size() != ARGS_TWO)) {
421         return;
422     }
423     DataShare::DataSharePredicates &predicates = context->predicates;
424     predicates.BeginWrap();
425     predicates.EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, (int)context->mediaTypes[FIRST_MEDIA_TYPE]);
426     if (context->mediaTypes.size() == ARGS_TWO) {
427         predicates.Or()->EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, (int)context->mediaTypes[SECOND_MEDIA_TYPE]);
428     }
429     predicates.EndWrap();
430 }
431 
432 template <class AsyncContext>
AsyncContextSetObjectInfo(napi_env env,napi_callback_info info,AsyncContext & asyncContext,const size_t minArgs,const size_t maxArgs)433 napi_status SendableMediaLibraryNapiUtils::AsyncContextSetObjectInfo(napi_env env, napi_callback_info info,
434     AsyncContext &asyncContext, const size_t minArgs, const size_t maxArgs)
435 {
436     napi_value thisVar = nullptr;
437     asyncContext->argc = maxArgs;
438     CHECK_STATUS_RET(napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), &thisVar,
439         nullptr), "Failed to get cb info");
440     CHECK_COND_RET(((asyncContext->argc >= minArgs) && (asyncContext->argc <= maxArgs)), napi_invalid_arg,
441         "Number of args is invalid");
442     if (minArgs > 0) {
443         CHECK_COND_RET(asyncContext->argv[ARGS_ZERO] != nullptr, napi_invalid_arg, "Argument list is empty");
444     }
445     CHECK_STATUS_RET(napi_unwrap_sendable(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo)),
446         "Failed to unwrap thisVar");
447     CHECK_COND_RET(asyncContext->objectInfo != nullptr, napi_invalid_arg, "Failed to get object info");
448     CHECK_STATUS_RET(GetParamCallback(env, asyncContext), "Failed to get callback param!");
449     return napi_ok;
450 }
451 
452 template <class AsyncContext>
AsyncContextGetArgs(napi_env env,napi_callback_info info,AsyncContext & asyncContext,const size_t minArgs,const size_t maxArgs)453 napi_status SendableMediaLibraryNapiUtils::AsyncContextGetArgs(napi_env env, napi_callback_info info,
454     AsyncContext &asyncContext, const size_t minArgs, const size_t maxArgs)
455 {
456     asyncContext->argc = maxArgs;
457     CHECK_STATUS_RET(napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), nullptr,
458         nullptr), "Failed to get cb info");
459     CHECK_COND_RET(asyncContext->argc >= minArgs && asyncContext->argc <= maxArgs, napi_invalid_arg,
460         "Number of args is invalid");
461     if (minArgs > 0) {
462         CHECK_COND_RET(asyncContext->argv[ARGS_ZERO] != nullptr, napi_invalid_arg, "Argument list is empty");
463     }
464     CHECK_STATUS_RET(GetParamCallback(env, asyncContext), "Failed to get callback param");
465     return napi_ok;
466 }
467 
468 template <class AsyncContext>
GetParamCallback(napi_env env,AsyncContext & context)469 napi_status SendableMediaLibraryNapiUtils::GetParamCallback(napi_env env, AsyncContext &context)
470 {
471     /* Parse the last argument into callbackref if any */
472     bool isCallback = false;
473     CHECK_STATUS_RET(HasCallback(env, context->argc, context->argv, isCallback), "Failed to check callback");
474     if (isCallback) {
475         CHECK_STATUS_RET(GetParamFunction(env, context->argv[context->argc - 1], context->callbackRef),
476             "Failed to get callback");
477     }
478     return napi_ok;
479 }
480 
481 template <class AsyncContext>
ParseArgsBoolCallBack(napi_env env,napi_callback_info info,AsyncContext & context,bool & param)482 napi_status SendableMediaLibraryNapiUtils::ParseArgsBoolCallBack(napi_env env, napi_callback_info info,
483     AsyncContext &context,
484     bool &param)
485 {
486     constexpr size_t minArgs = ARGS_ONE;
487     constexpr size_t maxArgs = ARGS_TWO;
488     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
489         "Failed to get object info");
490 
491     /* Parse the first argument into param */
492     CHECK_STATUS_RET(GetParamBool(env, context->argv[ARGS_ZERO], param), "Failed to get parameter");
493     return napi_ok;
494 }
495 
496 template <class AsyncContext>
ParseArgsStringCallback(napi_env env,napi_callback_info info,AsyncContext & context,string & param)497 napi_status SendableMediaLibraryNapiUtils::ParseArgsStringCallback(napi_env env, napi_callback_info info,
498     AsyncContext &context, string &param)
499 {
500     constexpr size_t minArgs = ARGS_ONE;
501     constexpr size_t maxArgs = ARGS_TWO;
502     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
503         "Failed to get object info");
504 
505     CHECK_STATUS_RET(GetParamStringPathMax(env, context->argv[ARGS_ZERO], param), "Failed to get string argument");
506     return napi_ok;
507 }
508 
509 template <class AsyncContext>
ParseArgsStringArrayCallback(napi_env env,napi_callback_info info,AsyncContext & context,vector<string> & array)510 napi_status SendableMediaLibraryNapiUtils::ParseArgsStringArrayCallback(napi_env env, napi_callback_info info,
511     AsyncContext &context, vector<string> &array)
512 {
513     constexpr size_t minArgs = ARGS_ONE;
514     constexpr size_t maxArgs = ARGS_TWO;
515     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
516         "Failed to get object info");
517 
518     CHECK_STATUS_RET(GetStringArray(env, context->argv[ARGS_ZERO], array), "Failed to get string array");
519     CHECK_STATUS_RET(GetParamCallback(env, context), "Failed to get callback");
520     return napi_ok;
521 }
522 
523 template <class AsyncContext>
ParseArgsNumberCallback(napi_env env,napi_callback_info info,AsyncContext & context,int32_t & value)524 napi_status SendableMediaLibraryNapiUtils::ParseArgsNumberCallback(napi_env env, napi_callback_info info,
525     AsyncContext &context, int32_t &value)
526 {
527     constexpr size_t minArgs = ARGS_ONE;
528     constexpr size_t maxArgs = ARGS_TWO;
529     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
530         "Failed to get object info");
531 
532     CHECK_STATUS_RET(GetInt32(env, context->argv[ARGS_ZERO], value), "Failed to get number argument");
533     return napi_ok;
534 }
535 
536 template <class AsyncContext>
ParseArgsOnlyCallBack(napi_env env,napi_callback_info info,AsyncContext & context)537 napi_status SendableMediaLibraryNapiUtils::ParseArgsOnlyCallBack(napi_env env, napi_callback_info info,
538     AsyncContext &context)
539 {
540     constexpr size_t minArgs = ARGS_ZERO;
541     constexpr size_t maxArgs = ARGS_ONE;
542     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
543         "Failed to get object info");
544     return napi_ok;
545 }
546 
GetAssetType(MediaType type)547 AssetType SendableMediaLibraryNapiUtils::GetAssetType(MediaType type)
548 {
549     AssetType result;
550 
551     switch (type) {
552         case MEDIA_TYPE_AUDIO:
553             result = ASSET_AUDIO;
554             break;
555         case MEDIA_TYPE_VIDEO:
556             result = ASSET_VIDEO;
557             break;
558         case MEDIA_TYPE_IMAGE:
559             result = ASSET_IMAGE;
560             break;
561         case MEDIA_TYPE_MEDIA:
562             result = ASSET_MEDIA;
563             break;
564         default:
565             result = ASSET_NONE;
566             break;
567     }
568 
569     return result;
570 }
571 
AppendFetchOptionSelection(string & selection,const string & newCondition)572 void SendableMediaLibraryNapiUtils::AppendFetchOptionSelection(string &selection, const string &newCondition)
573 {
574     if (!newCondition.empty()) {
575         if (!selection.empty()) {
576             selection = "(" + selection + ") AND " + newCondition;
577         } else {
578             selection = newCondition;
579         }
580     }
581 }
582 
TransErrorCode(const string & Name,shared_ptr<DataShare::DataShareResultSet> resultSet)583 int SendableMediaLibraryNapiUtils::TransErrorCode(const string &Name,
584     shared_ptr<DataShare::DataShareResultSet> resultSet)
585 {
586     NAPI_ERR_LOG("interface: %{public}s, server return nullptr", Name.c_str());
587     // Query can't return errorcode, so assume nullptr as permission deny
588     if (resultSet == nullptr) {
589         return JS_ERR_PERMISSION_DENIED;
590     }
591     return ERR_DEFAULT;
592 }
593 
TransErrorCode(const string & Name,int error)594 int SendableMediaLibraryNapiUtils::TransErrorCode(const string &Name, int error)
595 {
596     NAPI_ERR_LOG("interface: %{public}s, server errcode:%{public}d ", Name.c_str(), error);
597     // Transfer Server error to napi error code
598     if (error <= E_COMMON_START && error >= E_COMMON_END) {
599         error = JS_INNER_FAIL;
600     } else if (trans2JsError.count(error)) {
601         error = trans2JsError.at(error);
602     }
603     return error;
604 }
605 
HandleError(napi_env env,int error,napi_value & errorObj,const string & Name)606 void SendableMediaLibraryNapiUtils::HandleError(napi_env env, int error, napi_value &errorObj, const string &Name)
607 {
608     if (error == ERR_DEFAULT) {
609         return;
610     }
611 
612     string errMsg = "System inner fail";
613     int originalError = error;
614     if (jsErrMap.count(error) > 0) {
615         errMsg = jsErrMap.at(error);
616     } else {
617         error = JS_INNER_FAIL;
618     }
619     CreateNapiErrorObject(env, errorObj, error, errMsg);
620     errMsg = Name + " " + errMsg;
621     NAPI_ERR_LOG("Error: %{public}s, js errcode:%{public}d ", errMsg.c_str(), originalError);
622 }
623 
CreateNapiErrorObject(napi_env env,napi_value & errorObj,const int32_t errCode,const string errMsg)624 void SendableMediaLibraryNapiUtils::CreateNapiErrorObject(napi_env env, napi_value &errorObj, const int32_t errCode,
625     const string errMsg)
626 {
627     napi_status statusError;
628     napi_value napiErrorCode = nullptr;
629     napi_value napiErrorMsg = nullptr;
630     statusError = napi_create_string_utf8(env, to_string(errCode).c_str(), NAPI_AUTO_LENGTH, &napiErrorCode);
631     if (statusError == napi_ok) {
632         statusError = napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &napiErrorMsg);
633         if (statusError == napi_ok) {
634             statusError = napi_create_error(env, napiErrorCode, napiErrorMsg, &errorObj);
635             if (statusError == napi_ok) {
636                 NAPI_DEBUG_LOG("napi_create_error success");
637             }
638         }
639     }
640 }
641 
InvokeJSAsyncMethod(napi_env env,napi_deferred deferred,napi_ref callbackRef,napi_async_work work,const SendableJSAsyncContextOutput & asyncContext)642 void SendableMediaLibraryNapiUtils::InvokeJSAsyncMethod(napi_env env, napi_deferred deferred, napi_ref callbackRef,
643     napi_async_work work, const SendableJSAsyncContextOutput &asyncContext)
644 {
645     MediaLibraryTracer tracer;
646     tracer.Start("InvokeJSAsyncMethod");
647 
648     napi_value retVal;
649     napi_value callback = nullptr;
650 
651     /* Deferred is used when JS Callback method expects a promise value */
652     if (deferred) {
653         if (asyncContext.status) {
654             napi_resolve_deferred(env, deferred, asyncContext.data);
655         } else {
656             napi_reject_deferred(env, deferred, asyncContext.error);
657         }
658     } else {
659         napi_value result[ARGS_TWO];
660         result[PARAM0] = asyncContext.error;
661         result[PARAM1] = asyncContext.data;
662         napi_get_reference_value(env, callbackRef, &callback);
663         napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
664         napi_delete_reference(env, callbackRef);
665     }
666     napi_delete_async_work(env, work);
667 }
668 
669 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 *))670 napi_value SendableMediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr<AsyncContext> &asyncContext,
671     const string &resourceName,  void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *))
672 {
673     napi_value result = nullptr;
674     napi_value resource = nullptr;
675     NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
676     NAPI_CREATE_RESOURCE_NAME(env, resource, resourceName.c_str(), asyncContext);
677 
678     NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, execute, complete,
679         static_cast<void *>(asyncContext.get()), &asyncContext->work));
680     NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated));
681     asyncContext.release();
682 
683     return result;
684 }
685 
ToUTF8String(napi_env env,napi_value value)686 tuple<bool, unique_ptr<char[]>, size_t> SendableMediaLibraryNapiUtils::ToUTF8String(napi_env env, napi_value value)
687 {
688     size_t strLen = 0;
689     napi_status status = napi_get_value_string_utf8(env, value, nullptr, -1, &strLen);
690     if (status != napi_ok) {
691         NAPI_ERR_LOG("ToUTF8String get fail, %{public}d", status);
692         return { false, nullptr, 0 };
693     }
694 
695     size_t bufLen = strLen + 1;
696     unique_ptr<char[]> str = make_unique<char[]>(bufLen);
697     if (str == nullptr) {
698         NAPI_ERR_LOG("ToUTF8String get memory fail");
699         return { false, nullptr, 0 };
700     }
701     status = napi_get_value_string_utf8(env, value, str.get(), bufLen, &strLen);
702     return make_tuple(status == napi_ok, move(str), strLen);
703 }
704 
IsExistsByPropertyName(napi_env env,napi_value jsObject,const char * propertyName)705 bool SendableMediaLibraryNapiUtils::IsExistsByPropertyName(napi_env env, napi_value jsObject, const char *propertyName)
706 {
707     bool result = false;
708     if (napi_has_named_property(env, jsObject, propertyName, &result) == napi_ok) {
709         return result;
710     } else {
711         NAPI_ERR_LOG("IsExistsByPropertyName not exist %{public}s", propertyName);
712         return false;
713     }
714 }
715 
GetPropertyValueByName(napi_env env,napi_value jsObject,const char * propertyName)716 napi_value SendableMediaLibraryNapiUtils::GetPropertyValueByName(napi_env env, napi_value jsObject,
717     const char *propertyName)
718 {
719     napi_value value = nullptr;
720     if (IsExistsByPropertyName(env, jsObject, propertyName) == false) {
721         NAPI_ERR_LOG("GetPropertyValueByName not exist %{public}s", propertyName);
722         return nullptr;
723     }
724     if (napi_get_named_property(env, jsObject, propertyName, &value) != napi_ok) {
725         NAPI_ERR_LOG("GetPropertyValueByName get fail %{public}s", propertyName);
726         return nullptr;
727     }
728     return value;
729 }
730 
CheckJSArgsTypeAsFunc(napi_env env,napi_value arg)731 bool SendableMediaLibraryNapiUtils::CheckJSArgsTypeAsFunc(napi_env env, napi_value arg)
732 {
733     napi_valuetype valueType = napi_undefined;
734     napi_typeof(env, arg, &valueType);
735     return (valueType == napi_function);
736 }
737 
IsArrayForNapiValue(napi_env env,napi_value param,uint32_t & arraySize)738 bool SendableMediaLibraryNapiUtils::IsArrayForNapiValue(napi_env env, napi_value param, uint32_t &arraySize)
739 {
740     bool isArray = false;
741     arraySize = 0;
742     if ((napi_is_array(env, param, &isArray) != napi_ok) || (isArray == false)) {
743         return false;
744     }
745     if (napi_get_array_length(env, param, &arraySize) != napi_ok) {
746         return false;
747     }
748     return true;
749 }
750 
GetInt32Arg(napi_env env,napi_value arg,int32_t & value)751 napi_value SendableMediaLibraryNapiUtils::GetInt32Arg(napi_env env, napi_value arg, int32_t &value)
752 {
753     napi_valuetype valueType = napi_undefined;
754     CHECK_ARGS(env, napi_typeof(env, arg, &valueType), JS_INNER_FAIL);
755     if (valueType != napi_number) {
756         NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID);
757         return nullptr;
758     }
759     CHECK_ARGS(env, napi_get_value_int32(env, arg, &value), JS_INNER_FAIL);
760 
761     napi_value result = nullptr;
762     CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
763     return result;
764 }
765 
UriAppendKeyValue(string & uri,const string & key,const string & value)766 void SendableMediaLibraryNapiUtils::UriAppendKeyValue(string &uri, const string &key, const string &value)
767 {
768     string uriKey = key + '=';
769     if (uri.find(uriKey) != string::npos) {
770         return;
771     }
772 
773     char queryMark = (uri.find('?') == string::npos) ? '?' : '&';
774     string append = queryMark + key + '=' + value;
775 
776     size_t posJ = uri.find('#');
777     if (posJ == string::npos) {
778         uri += append;
779     } else {
780         uri.insert(posJ, append);
781     }
782 }
783 
AddAssetColumns(napi_env env,vector<string> & fetchColumn,function<bool (const string & columnName)> isValidColumn,std::set<std::string> & validFetchColumns,const PhotoAlbumSubType subType)784 napi_value SendableMediaLibraryNapiUtils::AddAssetColumns(napi_env env, vector<string> &fetchColumn,
785     function<bool(const string &columnName)> isValidColumn, std::set<std::string>& validFetchColumns,
786     const PhotoAlbumSubType subType)
787 {
788     switch (subType) {
789         case PhotoAlbumSubType::FAVORITE:
790             validFetchColumns.insert(MediaColumn::MEDIA_IS_FAV);
791             break;
792         case PhotoAlbumSubType::VIDEO:
793             validFetchColumns.insert(MediaColumn::MEDIA_TYPE);
794             break;
795         case PhotoAlbumSubType::HIDDEN:
796             validFetchColumns.insert(MediaColumn::MEDIA_HIDDEN);
797             break;
798         case PhotoAlbumSubType::TRASH:
799             validFetchColumns.insert(MediaColumn::MEDIA_DATE_TRASHED);
800             break;
801         case PhotoAlbumSubType::SCREENSHOT:
802         case PhotoAlbumSubType::CAMERA:
803             validFetchColumns.insert(PhotoColumn::PHOTO_SUBTYPE);
804             break;
805         default:
806             break;
807     }
808     for (const auto &column : fetchColumn) {
809         if (column == PENDING_STATUS) {
810             validFetchColumns.insert(MediaColumn::MEDIA_TIME_PENDING);
811         } else if (isValidColumn(column)) {
812             validFetchColumns.insert(column);
813         } else if (column == MEDIA_DATA_DB_URI) {
814             continue;
815         } else if (DATE_TRANSITION_MAP.count(column) != 0) {
816             validFetchColumns.insert(DATE_TRANSITION_MAP.at(column));
817         } else {
818             NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID);
819             return nullptr;
820         }
821     }
822     fetchColumn.assign(validFetchColumns.begin(), validFetchColumns.end());
823 
824     napi_value result = nullptr;
825     CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
826     return result;
827 }
828 
AddDefaultAssetColumns(napi_env env,vector<string> & fetchColumn,function<bool (const string & columnName)> isValidColumn,NapiAssetType assetType,const PhotoAlbumSubType subType)829 napi_value SendableMediaLibraryNapiUtils::AddDefaultAssetColumns(napi_env env, vector<string> &fetchColumn,
830     function<bool(const string &columnName)> isValidColumn, NapiAssetType assetType,
831     const PhotoAlbumSubType subType)
832 {
833     auto validFetchColumns = MediaColumn::DEFAULT_FETCH_COLUMNS;
834     if (assetType == TYPE_PHOTO) {
835         validFetchColumns.insert(
836             PhotoColumn::DEFAULT_FETCH_COLUMNS.begin(), PhotoColumn::DEFAULT_FETCH_COLUMNS.end());
837     }
838     return AddAssetColumns(env, fetchColumn, isValidColumn, validFetchColumns, subType);
839 }
840 
SetDefaultPredicatesCondition(DataSharePredicates & predicates,const int32_t dateTrashed,const bool isHidden,const int32_t timePending,const bool isTemp)841 inline void SetDefaultPredicatesCondition(DataSharePredicates &predicates, const int32_t dateTrashed,
842     const bool isHidden, const int32_t timePending, const bool isTemp)
843 {
844     predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, to_string(dateTrashed));
845     predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, to_string(isHidden));
846     predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, to_string(timePending));
847     predicates.EqualTo(PhotoColumn::PHOTO_IS_TEMP, to_string(isTemp));
848     predicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL,
849         to_string(static_cast<int32_t>(BurstCoverLevelType::COVER)));
850 }
851 
GetUserAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates,const bool hiddenOnly)852 int32_t SendableMediaLibraryNapiUtils::GetUserAlbumPredicates(
853     const int32_t albumId, DataSharePredicates &predicates, const bool hiddenOnly)
854 {
855     predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(albumId));
856     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
857     return E_SUCCESS;
858 }
859 
GetPortraitAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates)860 int32_t SendableMediaLibraryNapiUtils::GetPortraitAlbumPredicates(const int32_t albumId,
861     DataSharePredicates &predicates)
862 {
863     string onClause = MediaColumn::MEDIA_ID + " = " + PhotoMap::ASSET_ID;
864     vector<string> clauses = { onClause };
865     predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On(clauses);
866     onClause = ALBUM_ID + " = " + PhotoMap::ALBUM_ID;
867     clauses = { onClause };
868     predicates.InnerJoin(ANALYSIS_ALBUM_TABLE)->On(clauses);
869     string tempTable = "(SELECT " + GROUP_TAG + " FROM " + ANALYSIS_ALBUM_TABLE + " WHERE " + ALBUM_ID + " = " +
870         to_string(albumId) + ") ag";
871     onClause = "ag." + GROUP_TAG + " = " + ANALYSIS_ALBUM_TABLE + "." + GROUP_TAG;
872     clauses = { onClause };
873     predicates.InnerJoin(tempTable)->On(clauses);
874     SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
875     predicates.Distinct();
876     return E_SUCCESS;
877 }
878 
GetAnalysisAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates)879 int32_t SendableMediaLibraryNapiUtils::GetAnalysisAlbumPredicates(const int32_t albumId,
880     DataSharePredicates &predicates)
881 {
882     string onClause = MediaColumn::MEDIA_ID + " = " + PhotoMap::ASSET_ID;
883     predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On({ onClause });
884     predicates.EqualTo(PhotoMap::ALBUM_ID, to_string(albumId));
885     SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
886     return E_SUCCESS;
887 }
888 
IsFeaturedSinglePortraitAlbum(std::string albumName,DataShare::DataSharePredicates & predicates)889 bool SendableMediaLibraryNapiUtils::IsFeaturedSinglePortraitAlbum(
890     std::string albumName, DataShare::DataSharePredicates &predicates)
891 {
892     bool isFeaturedSinglePortrait = false;
893     int portraitAlbumId = 0;
894     if (albumName.compare(to_string(portraitAlbumId)) != 0) {
895         return isFeaturedSinglePortrait;
896     }
897 
898     DataSharePredicates featuredSinglePortraitPredicates;
899     std::vector<OperationItem> operationList = predicates.GetOperationList();
900     for (auto& operationItem : operationList) {
901         switch (operationItem.operation) {
902             case OHOS::DataShare::OperationType::LIKE : {
903                 std::string field = std::get<string>(operationItem.singleParams[0]);
904                 std::string value = std::get<string>(operationItem.singleParams[1]);
905                 if (field.compare("FeaturedSinglePortrait") == 0 && value.compare("true") == 0) {
906                     isFeaturedSinglePortrait = true;
907                 } else {
908                     featuredSinglePortraitPredicates.Like(field, value);
909                 }
910                 break;
911             }
912             case OHOS::DataShare::OperationType::ORDER_BY_DESC : {
913                 featuredSinglePortraitPredicates.OrderByDesc(operationItem.GetSingle(0));
914                 break;
915             }
916             case OHOS::DataShare::OperationType::LIMIT : {
917                 featuredSinglePortraitPredicates.Limit(operationItem.GetSingle(0), operationItem.GetSingle(1));
918                 break;
919             }
920             default: {
921                 break;
922             }
923         }
924     }
925 
926     if (isFeaturedSinglePortrait) {
927         predicates = featuredSinglePortraitPredicates;
928     }
929     return isFeaturedSinglePortrait;
930 }
931 
GetFeaturedSinglePortraitAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates)932 int32_t SendableMediaLibraryNapiUtils::GetFeaturedSinglePortraitAlbumPredicates(
933     const int32_t albumId, DataSharePredicates &predicates)
934 {
935     string onClause = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID + " = " +
936         ANALYSIS_PHOTO_MAP_TABLE + "." + PhotoMap::ASSET_ID;
937     predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On({ onClause });
938 
939     constexpr int32_t minSize = 224;
940     string imgHeightColumn = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_HEIGHT;
941     string imgWidthColumn = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_WIDTH;
942     string imgFaceHeightColumn = VISION_IMAGE_FACE_TABLE + "." + SCALE_HEIGHT;
943     string imgFaceWidthColumn = VISION_IMAGE_FACE_TABLE + "." + SCALE_WIDTH;
944     string imgFaceHeightClause = "( " + imgFaceHeightColumn + " > " + to_string(minSize) +
945         " OR ( " + imgFaceHeightColumn + " <= 1.0 " + " AND " + imgFaceHeightColumn + " * " + imgHeightColumn +
946         " > " + to_string(minSize) + " ) )";
947     string imgFaceWidthClause = "( " + imgFaceWidthColumn + " > " + to_string(minSize) +
948         " OR ( " + imgFaceWidthColumn + " <= 1.0 " + " AND " + imgFaceWidthColumn + " * " + imgWidthColumn +
949         " > " + to_string(minSize) + " ) )";
950     string imgFaceOcclusionClause = "( " + VISION_IMAGE_FACE_TABLE + "." + FACE_OCCLUSION + " != 1 OR " +
951         VISION_IMAGE_FACE_TABLE + "." + FACE_OCCLUSION + " IS NULL )";
952     string portraitRotationLimit = "BETWEEN -30 AND 30";
953     onClause = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID + " = " + VISION_IMAGE_FACE_TABLE + "." +
954         MediaColumn::MEDIA_ID + " AND " + VISION_IMAGE_FACE_TABLE + "." + TOTAL_FACES + " = 1 AND " +
955         imgFaceHeightClause + " AND " + imgFaceWidthClause + " AND " + imgFaceOcclusionClause + " AND " +
956         VISION_IMAGE_FACE_TABLE + "." + PITCH + " " + portraitRotationLimit + " AND " +
957         VISION_IMAGE_FACE_TABLE + "." + YAW + " " + portraitRotationLimit + " AND " +
958         VISION_IMAGE_FACE_TABLE + "." + ROLL + " " + portraitRotationLimit;
959     predicates.InnerJoin(VISION_IMAGE_FACE_TABLE)->On({ onClause });
960 
961     string portraitType = "IN ( 1, 2 )";
962     onClause = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID + " = " + VISION_POSE_TABLE + "." +
963         MediaColumn::MEDIA_ID + " AND " + VISION_POSE_TABLE + "." + POSE_TYPE + " " + portraitType;
964     predicates.InnerJoin(VISION_POSE_TABLE)->On({ onClause });
965 
966     predicates.EqualTo(PhotoMap::ALBUM_ID, to_string(albumId));
967     SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
968     return E_SUCCESS;
969 }
970 
GetAllLocationPredicates(DataSharePredicates & predicates)971 int32_t SendableMediaLibraryNapiUtils::GetAllLocationPredicates(DataSharePredicates &predicates)
972 {
973     SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
974     predicates.And()->NotEqualTo(PhotoColumn::PHOTO_LATITUDE, to_string(0));
975     predicates.And()->NotEqualTo(PhotoColumn::PHOTO_LONGITUDE, to_string(0));
976     return E_SUCCESS;
977 }
978 
GetFavoritePredicates(DataSharePredicates & predicates,const bool hiddenOnly)979 static int32_t GetFavoritePredicates(DataSharePredicates &predicates, const bool hiddenOnly)
980 {
981     predicates.BeginWrap();
982     constexpr int32_t IS_FAVORITE = 1;
983     predicates.EqualTo(MediaColumn::MEDIA_IS_FAV, to_string(IS_FAVORITE));
984     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
985     predicates.EndWrap();
986     return E_SUCCESS;
987 }
988 
GetVideoPredicates(DataSharePredicates & predicates,const bool hiddenOnly)989 static int32_t GetVideoPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
990 {
991     predicates.BeginWrap();
992     predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_VIDEO));
993     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
994     predicates.EndWrap();
995     return E_SUCCESS;
996 }
997 
GetHiddenPredicates(DataSharePredicates & predicates)998 static int32_t GetHiddenPredicates(DataSharePredicates &predicates)
999 {
1000     predicates.BeginWrap();
1001     SetDefaultPredicatesCondition(predicates, 0, 1, 0, false);
1002     predicates.EndWrap();
1003     return E_SUCCESS;
1004 }
1005 
GetTrashPredicates(DataSharePredicates & predicates)1006 static int32_t GetTrashPredicates(DataSharePredicates &predicates)
1007 {
1008     predicates.BeginWrap();
1009     predicates.GreaterThan(MediaColumn::MEDIA_DATE_TRASHED, to_string(0));
1010     predicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL,
1011         to_string(static_cast<int32_t>(BurstCoverLevelType::COVER)));
1012     predicates.EndWrap();
1013     return E_SUCCESS;
1014 }
1015 
GetScreenshotPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1016 static int32_t GetScreenshotPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1017 {
1018     predicates.BeginWrap();
1019     predicates.EqualTo(PhotoColumn::PHOTO_SUBTYPE, to_string(static_cast<int32_t>(PhotoSubType::SCREENSHOT)));
1020     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1021     predicates.EndWrap();
1022     return E_SUCCESS;
1023 }
1024 
GetCameraPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1025 static int32_t GetCameraPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1026 {
1027     predicates.BeginWrap();
1028     predicates.EqualTo(PhotoColumn::PHOTO_SUBTYPE, to_string(static_cast<int32_t>(PhotoSubType::CAMERA)));
1029     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1030     predicates.EndWrap();
1031     return E_SUCCESS;
1032 }
1033 
GetAllImagesPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1034 static int32_t GetAllImagesPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1035 {
1036     predicates.BeginWrap();
1037     predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_IMAGE));
1038     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1039     predicates.EndWrap();
1040     return E_SUCCESS;
1041 }
1042 
GetCloudEnhancementPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1043 static int32_t GetCloudEnhancementPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1044 {
1045     predicates.BeginWrap();
1046     predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_IMAGE));
1047     predicates.EqualTo(PhotoColumn::PHOTO_STRONG_ASSOCIATION,
1048         to_string(static_cast<int32_t>(StrongAssociationType::CLOUD_ENHANCEMENT)));
1049     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1050     predicates.EndWrap();
1051     return E_SUCCESS;
1052 }
1053 
GetSourceAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates,const bool hiddenOnly)1054 int32_t SendableMediaLibraryNapiUtils::GetSourceAlbumPredicates(const int32_t albumId, DataSharePredicates &predicates,
1055     const bool hiddenOnly)
1056 {
1057     predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(albumId));
1058     predicates.EqualTo(PhotoColumn::PHOTO_SYNC_STATUS, to_string(static_cast<int32_t>(SyncStatusType::TYPE_VISIBLE)));
1059     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1060     return E_SUCCESS;
1061 }
1062 
GetSystemAlbumPredicates(const PhotoAlbumSubType subType,DataSharePredicates & predicates,const bool hiddenOnly)1063 int32_t SendableMediaLibraryNapiUtils::GetSystemAlbumPredicates(const PhotoAlbumSubType subType,
1064     DataSharePredicates &predicates, const bool hiddenOnly)
1065 {
1066     switch (subType) {
1067         case PhotoAlbumSubType::FAVORITE: {
1068             return GetFavoritePredicates(predicates, hiddenOnly);
1069         }
1070         case PhotoAlbumSubType::VIDEO: {
1071             return GetVideoPredicates(predicates, hiddenOnly);
1072         }
1073         case PhotoAlbumSubType::HIDDEN: {
1074             return GetHiddenPredicates(predicates);
1075         }
1076         case PhotoAlbumSubType::TRASH: {
1077             return GetTrashPredicates(predicates);
1078         }
1079         case PhotoAlbumSubType::SCREENSHOT: {
1080             return GetScreenshotPredicates(predicates, hiddenOnly);
1081         }
1082         case PhotoAlbumSubType::CAMERA: {
1083             return GetCameraPredicates(predicates, hiddenOnly);
1084         }
1085         case PhotoAlbumSubType::IMAGE: {
1086             return GetAllImagesPredicates(predicates, hiddenOnly);
1087         }
1088         case PhotoAlbumSubType::CLOUD_ENHANCEMENT: {
1089             return GetCloudEnhancementPredicates(predicates, hiddenOnly);
1090         }
1091         default: {
1092             NAPI_ERR_LOG("Unsupported photo album subtype: %{public}d", subType);
1093             return E_INVALID_ARGUMENTS;
1094         }
1095     }
1096 }
1097 
CreateValueByIndex(napi_env env,int32_t index,string name,shared_ptr<NativeRdb::ResultSet> & resultSet,const shared_ptr<FileAsset> & asset)1098 napi_value SendableMediaLibraryNapiUtils::CreateValueByIndex(napi_env env, int32_t index, string name,
1099     shared_ptr<NativeRdb::ResultSet> &resultSet, const shared_ptr<FileAsset> &asset)
1100 {
1101     int status;
1102     int integerVal = 0;
1103     string stringVal = "";
1104     int64_t longVal = 0;
1105     double doubleVal = 0.0;
1106     napi_value value = nullptr;
1107     auto dataType = SendableMediaLibraryNapiUtils::GetTypeMap().at(name);
1108     switch (dataType.first) {
1109         case TYPE_STRING:
1110             status = resultSet->GetString(index, stringVal);
1111             napi_create_string_utf8(env, stringVal.c_str(), NAPI_AUTO_LENGTH, &value);
1112             asset->GetMemberMap().emplace(name, stringVal);
1113             break;
1114         case TYPE_INT32:
1115             status = resultSet->GetInt(index, integerVal);
1116             napi_create_int32(env, integerVal, &value);
1117             asset->GetMemberMap().emplace(name, integerVal);
1118             break;
1119         case TYPE_INT64:
1120             status = resultSet->GetLong(index, longVal);
1121             napi_create_int64(env, longVal, &value);
1122             asset->GetMemberMap().emplace(name, longVal);
1123             break;
1124         case TYPE_DOUBLE:
1125             status = resultSet->GetDouble(index, doubleVal);
1126             napi_create_double(env, doubleVal, &value);
1127             asset->GetMemberMap().emplace(name, doubleVal);
1128             break;
1129         default:
1130             NAPI_ERR_LOG("not match dataType %{public}d", dataType.first);
1131             break;
1132     }
1133 
1134     return value;
1135 }
1136 
handleTimeInfo(napi_env env,const std::string & name,napi_value result,int32_t index,const std::shared_ptr<NativeRdb::ResultSet> & resultSet)1137 void SendableMediaLibraryNapiUtils::handleTimeInfo(napi_env env, const std::string& name, napi_value result,
1138     int32_t index, const std::shared_ptr<NativeRdb::ResultSet>& resultSet)
1139 {
1140     if (TIME_COLUMN.count(name) == 0) {
1141         return;
1142     }
1143     int64_t longVal = 0;
1144     int status;
1145     napi_value value = nullptr;
1146     status = resultSet->GetLong(index, longVal);
1147     int64_t modifieldValue = longVal / 1000;
1148     napi_create_int64(env, modifieldValue, &value);
1149     auto dataType = SendableMediaLibraryNapiUtils::GetTimeTypeMap().at(name);
1150     napi_set_named_property(env, result, dataType.second.c_str(), value);
1151 }
1152 
handleThumbnailReady(napi_env env,const std::string & name,napi_value result,int32_t index,const std::shared_ptr<NativeRdb::ResultSet> & resultSet)1153 static void handleThumbnailReady(napi_env env, const std::string& name, napi_value result, int32_t index,
1154     const std::shared_ptr<NativeRdb::ResultSet>& resultSet)
1155 {
1156     if (name != "thumbnail_ready") {
1157         return;
1158     }
1159     int64_t longVal = 0;
1160     int status;
1161     napi_value value = nullptr;
1162     status = resultSet->GetLong(index, longVal);
1163     bool resultVal = longVal > 0;
1164     napi_create_int32(env, resultVal, &value);
1165     napi_set_named_property(env, result, "thumbnailReady", value);
1166 }
1167 
GetNextRowObject(napi_env env,shared_ptr<NativeRdb::ResultSet> & resultSet)1168 napi_value SendableMediaLibraryNapiUtils::GetNextRowObject(napi_env env,
1169     shared_ptr<NativeRdb::ResultSet> &resultSet)
1170 {
1171     if (resultSet == nullptr) {
1172         NAPI_ERR_LOG("GetNextRowObject fail, result is nullptr");
1173         return nullptr;
1174     }
1175     vector<string> columnNames;
1176     resultSet->GetAllColumnNames(columnNames);
1177 
1178     napi_value result = nullptr;
1179     napi_create_object(env, &result);
1180 
1181     napi_value value = nullptr;
1182     int32_t index = -1;
1183     auto fileAsset = make_shared<FileAsset>();
1184     for (const auto &name : columnNames) {
1185         index++;
1186 
1187         // Check if the column name exists in the type map
1188         if (SendableMediaLibraryNapiUtils::GetTypeMap().count(name) == 0) {
1189             continue;
1190         }
1191         value = SendableMediaLibraryNapiUtils::CreateValueByIndex(env, index, name, resultSet, fileAsset);
1192         auto dataType = SendableMediaLibraryNapiUtils::GetTypeMap().at(name);
1193         napi_set_named_property(env, result, dataType.second.c_str(), value);
1194         handleTimeInfo(env, name, result, index, resultSet);
1195         handleThumbnailReady(env, name, result, index, resultSet);
1196     }
1197 
1198     if (fileAsset->GetDisplayName().empty() && fileAsset->GetPath().empty()) {
1199         return result;
1200     }
1201     string extrUri = MediaFileUtils::GetExtraUri(fileAsset->GetDisplayName(), fileAsset->GetPath(), false);
1202     MediaFileUri fileUri(fileAsset->GetMediaType(), to_string(fileAsset->GetId()), "", MEDIA_API_VERSION_V10, extrUri);
1203     fileAsset->SetUri(move(fileUri.ToString()));
1204     napi_create_string_utf8(env, fileAsset->GetUri().c_str(), NAPI_AUTO_LENGTH, &value);
1205     napi_set_named_property(env, result, MEDIA_DATA_DB_URI.c_str(), value);
1206     return result;
1207 }
1208 
IsSystemApp()1209 bool SendableMediaLibraryNapiUtils::IsSystemApp()
1210 {
1211     static bool isSys = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetSelfTokenID());
1212     return isSys;
1213 }
1214 
SendableNapiScopeHandler(napi_env env)1215 SendableNapiScopeHandler::SendableNapiScopeHandler(napi_env env): env_(env)
1216 {
1217     napi_status status = napi_open_handle_scope(env_, &scope_);
1218     if (status != napi_ok) {
1219         NAPI_ERR_LOG("Open Handler scope failed, status %{public}d", status);
1220         isValid_ = false;
1221     } else {
1222         isValid_ = true;
1223     }
1224 }
1225 
~SendableNapiScopeHandler()1226 SendableNapiScopeHandler::~SendableNapiScopeHandler()
1227 {
1228     if (isValid_) {
1229         napi_status status = napi_close_handle_scope(env_, scope_);
1230         if (status != napi_ok) {
1231             NAPI_ERR_LOG("Close Handler scope failed, status %{public}d", status);
1232         }
1233     }
1234 }
1235 
IsValid()1236 bool SendableNapiScopeHandler::IsValid()
1237 {
1238     return isValid_;
1239 }
1240 
GetNapiValueArray(napi_env env,napi_value arg,vector<napi_value> & values)1241 napi_value SendableMediaLibraryNapiUtils::GetNapiValueArray(napi_env env, napi_value arg, vector<napi_value> &values)
1242 {
1243     bool isArray = false;
1244     CHECK_ARGS(env, napi_is_array(env, arg, &isArray), OHOS_INVALID_PARAM_CODE);
1245     if (!isArray) {
1246         NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, "Failed to check array type");
1247         return nullptr;
1248     }
1249 
1250     uint32_t len = 0;
1251     CHECK_ARGS(env, napi_get_array_length(env, arg, &len), JS_INNER_FAIL);
1252     if (len == 0) {
1253         napi_value result = nullptr;
1254         CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
1255         return result;
1256     }
1257 
1258     for (uint32_t i = 0; i < len; i++) {
1259         napi_value value = nullptr;
1260         CHECK_ARGS(env, napi_get_element(env, arg, i, &value), JS_INNER_FAIL);
1261         if (value == nullptr) {
1262             NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, "Failed to get element");
1263             return nullptr;
1264         }
1265         values.push_back(value);
1266     }
1267 
1268     napi_value result = nullptr;
1269     CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
1270     return result;
1271 }
1272 
GetStringArray(napi_env env,vector<napi_value> & napiValues,vector<string> & values)1273 napi_value SendableMediaLibraryNapiUtils::GetStringArray(napi_env env, vector<napi_value> &napiValues,
1274     vector<string> &values)
1275 {
1276     napi_valuetype valueType = napi_undefined;
1277     unique_ptr<char[]> buffer = make_unique<char[]>(PATH_MAX);
1278     for (const auto &napiValue : napiValues) {
1279         CHECK_ARGS(env, napi_typeof(env, napiValue, &valueType), JS_ERR_PARAMETER_INVALID);
1280         CHECK_COND(env, valueType == napi_string, JS_ERR_PARAMETER_INVALID);
1281 
1282         size_t res = 0;
1283         CHECK_ARGS(
1284             env, napi_get_value_string_utf8(env, napiValue, buffer.get(), PATH_MAX, &res), JS_ERR_PARAMETER_INVALID);
1285         values.emplace_back(buffer.get());
1286     }
1287     napi_value ret = nullptr;
1288     CHECK_ARGS(env, napi_get_boolean(env, true, &ret), JS_INNER_FAIL);
1289     return ret;
1290 }
1291 
1292 template <class AsyncContext>
ParsePredicates(napi_env env,const napi_value arg,AsyncContext & context,const FetchOptionType & fetchOptType)1293 napi_status SendableMediaLibraryNapiUtils::ParsePredicates(napi_env env, const napi_value arg,
1294     AsyncContext &context, const FetchOptionType &fetchOptType)
1295 {
1296     JSProxy::JSProxy<DataShareAbsPredicates> *jsProxy = nullptr;
1297     napi_unwrap(env, arg, reinterpret_cast<void **>(&jsProxy));
1298     if (jsProxy == nullptr) {
1299         NAPI_ERR_LOG("jsProxy is invalid");
1300         return napi_invalid_arg;
1301     }
1302     shared_ptr<DataShareAbsPredicates> predicate = jsProxy->GetInstance();
1303     CHECK_COND_RET(HandleSpecialPredicate(context, predicate, fetchOptType) == TRUE,
1304         napi_invalid_arg, "invalid predicate");
1305     CHECK_COND_RET(GetLocationPredicate(context, predicate) == TRUE, napi_invalid_arg, "invalid predicate");
1306     return napi_ok;
1307 }
1308 
1309 template bool SendableMediaLibraryNapiUtils::HandleSpecialPredicate<unique_ptr<SendablePAHAsyncContext>>(
1310     unique_ptr<SendablePAHAsyncContext> &context, shared_ptr<DataShareAbsPredicates> &predicate,
1311     const FetchOptionType &fetchOptType, vector<OperationItem> operations);
1312 
1313 template napi_status SendableMediaLibraryNapiUtils::GetFetchOption<unique_ptr<SendablePAHAsyncContext>>(napi_env env,
1314     napi_value arg, const FetchOptionType &fetchOptType, unique_ptr<SendablePAHAsyncContext> &context,
1315     vector<OperationItem> operations);
1316 
1317 template napi_status SendableMediaLibraryNapiUtils::GetFetchOption<unique_ptr<SendablePANAsyncContext>>(napi_env env,
1318     napi_value arg, const FetchOptionType &fetchOptType, unique_ptr<SendablePANAsyncContext> &context,
1319     vector<OperationItem> operations);
1320 
1321 template napi_status SendableMediaLibraryNapiUtils::GetAlbumFetchOption<unique_ptr<SendablePANAsyncContext>>(
1322     napi_env env, napi_value arg, const FetchOptionType &fetchOptType,
1323     unique_ptr<SendablePANAsyncContext> &context);
1324 
1325 template napi_status SendableMediaLibraryNapiUtils::GetPredicate<unique_ptr<SendablePAHAsyncContext>>(napi_env env,
1326     const napi_value arg, const string &propName, unique_ptr<SendablePAHAsyncContext> &context,
1327     const FetchOptionType &fetchOptType, vector<OperationItem> operations);
1328 
1329 template napi_status SendableMediaLibraryNapiUtils::ParseArgsStringArrayCallback<unique_ptr<SendablePAHAsyncContext>>(
1330     napi_env env, napi_callback_info info,
1331     unique_ptr<SendablePAHAsyncContext> &context, vector<string> &array);
1332 
1333 template napi_status SendableMediaLibraryNapiUtils::GetParamCallback<unique_ptr<SendablePANAsyncContext>>(
1334     napi_env env, unique_ptr<SendablePANAsyncContext> &context);
1335 
1336 template napi_status SendableMediaLibraryNapiUtils::GetParamCallback<unique_ptr<SendablePAHAsyncContext>>(
1337     napi_env env, unique_ptr<SendablePAHAsyncContext> &context);
1338 
1339 template napi_status SendableMediaLibraryNapiUtils::GetParamCallback<unique_ptr<SendablePhotoAccessHelperInitContext>>(
1340     napi_env env, unique_ptr<SendablePhotoAccessHelperInitContext> &context);
1341 
1342 template napi_status SendableMediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<SendableFAAsyncContext>>(
1343     napi_env env, napi_callback_info info, unique_ptr<SendableFAAsyncContext> &context, string &param);
1344 
1345 template napi_status SendableMediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<SendablePANAsyncContext>>(
1346     napi_env env, napi_callback_info info,
1347     unique_ptr<SendablePANAsyncContext> &context, string &param);
1348 
1349 template napi_status SendableMediaLibraryNapiUtils::ParseArgsBoolCallBack<unique_ptr<SendableFAAsyncContext>>(
1350     napi_env env, napi_callback_info info, unique_ptr<SendableFAAsyncContext> &context, bool &param);
1351 
1352 template napi_status SendableMediaLibraryNapiUtils::AsyncContextSetObjectInfo<unique_ptr<SendablePAHAsyncContext>>(
1353     napi_env env, napi_callback_info info, unique_ptr<SendablePAHAsyncContext> &asyncContext,
1354     const size_t minArgs, const size_t maxArgs);
1355 
1356 template napi_status SendableMediaLibraryNapiUtils::AsyncContextSetObjectInfo<unique_ptr<SendableFAAsyncContext>>(
1357     napi_env env, napi_callback_info info, unique_ptr<SendableFAAsyncContext> &asyncContext,
1358     const size_t minArgs, const size_t maxArgs);
1359 
1360 template napi_status SendableMediaLibraryNapiUtils::AsyncContextSetObjectInfo<unique_ptr<SendablePANAsyncContext>>(
1361     napi_env env, napi_callback_info info, unique_ptr<SendablePANAsyncContext> &asyncContext,
1362     const size_t minArgs, const size_t maxArgs);
1363 
1364 template napi_value SendableMediaLibraryNapiUtils::NapiCreateAsyncWork<SendablePAHAsyncContext>(
1365     napi_env env, unique_ptr<SendablePAHAsyncContext> &asyncContext, const string &resourceName,
1366     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1367 
1368 template napi_value SendableMediaLibraryNapiUtils::NapiCreateAsyncWork<SendablePhotoAccessHelperInitContext>(
1369     napi_env env, unique_ptr<SendablePhotoAccessHelperInitContext> &asyncContext, const string &resourceName,
1370     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1371 
1372 template napi_value SendableMediaLibraryNapiUtils::NapiCreateAsyncWork<SendableFAAsyncContext>(napi_env env,
1373     unique_ptr<SendableFAAsyncContext> &asyncContext, const string &resourceName,
1374     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1375 
1376 template napi_value SendableMediaLibraryNapiUtils::NapiCreateAsyncWork<SendablePANAsyncContext>(
1377     napi_env env, unique_ptr<SendablePANAsyncContext> &asyncContext, const string &resourceName,
1378     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1379 
1380 template napi_status SendableMediaLibraryNapiUtils::ParseArgsNumberCallback<unique_ptr<SendableFAAsyncContext>>(
1381     napi_env env, napi_callback_info info, unique_ptr<SendableFAAsyncContext> &context, int32_t &value);
1382 
1383 template napi_status SendableMediaLibraryNapiUtils::ParseArgsOnlyCallBack<unique_ptr<SendableFAAsyncContext>>(
1384     napi_env env, napi_callback_info info, unique_ptr<SendableFAAsyncContext> &context);
1385 
1386 template napi_status SendableMediaLibraryNapiUtils::ParsePredicates<unique_ptr<SendablePAHAsyncContext>>(
1387     napi_env env, const napi_value arg, unique_ptr<SendablePAHAsyncContext> &context,
1388     const FetchOptionType &fetchOptType);
1389 
1390 } // namespace Media
1391 } // namespace OHOS
1392