• 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 "MediaLibraryNapiUtils"
16 
17 #include "medialibrary_napi_utils.h"
18 
19 #include "datashare_predicates_proxy.h"
20 #include "ipc_skeleton.h"
21 #include "media_file_uri.h"
22 #include "media_file_utils.h"
23 #include "media_library_napi.h"
24 #include "medialibrary_client_errno.h"
25 #include "medialibrary_data_manager_utils.h"
26 #include "medialibrary_errno.h"
27 #include "medialibrary_tracer.h"
28 #include "photo_album_napi.h"
29 #include "photo_map_column.h"
30 #include "smart_album_napi.h"
31 #include "tokenid_kit.h"
32 
33 using namespace std;
34 using namespace OHOS::DataShare;
35 
36 namespace OHOS {
37 namespace Media {
NapiDefineClass(napi_env env,napi_value exports,const NapiClassInfo & info)38 napi_value MediaLibraryNapiUtils::NapiDefineClass(napi_env env, napi_value exports, const NapiClassInfo &info)
39 {
40     napi_value ctorObj;
41     NAPI_CALL(env, napi_define_class(env, info.name.c_str(), NAPI_AUTO_LENGTH, info.constructor, nullptr,
42         info.props.size(), info.props.data(), &ctorObj));
43     NAPI_CALL(env, napi_create_reference(env, ctorObj, NAPI_INIT_REF_COUNT, info.ref));
44     NAPI_CALL(env, napi_set_named_property(env, exports, info.name.c_str(), ctorObj));
45     return exports;
46 }
47 
NapiAddStaticProps(napi_env env,napi_value exports,const vector<napi_property_descriptor> & staticProps)48 napi_value MediaLibraryNapiUtils::NapiAddStaticProps(napi_env env, napi_value exports,
49     const vector<napi_property_descriptor> &staticProps)
50 {
51     NAPI_CALL(env, napi_define_properties(env, exports, staticProps.size(), staticProps.data()));
52     return exports;
53 }
54 
GetUInt32(napi_env env,napi_value arg,uint32_t & value)55 napi_status MediaLibraryNapiUtils::GetUInt32(napi_env env, napi_value arg, uint32_t &value)
56 {
57     napi_valuetype valueType = napi_undefined;
58     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
59     CHECK_COND_RET(valueType == napi_number, napi_number_expected, "Type is not as expected number");
60     CHECK_STATUS_RET(napi_get_value_uint32(env, arg, &value), "Failed to get uint32 value");
61     return napi_ok;
62 }
63 
GetInt32(napi_env env,napi_value arg,int32_t & value)64 napi_status MediaLibraryNapiUtils::GetInt32(napi_env env, napi_value arg, int32_t &value)
65 {
66     napi_valuetype valueType = napi_undefined;
67     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
68     CHECK_COND_RET(valueType == napi_number, napi_number_expected, "Type is not as expected number");
69     CHECK_STATUS_RET(napi_get_value_int32(env, arg, &value), "Failed to get int32 value");
70     return napi_ok;
71 }
72 
GetParamBool(napi_env env,napi_value arg,bool & value)73 napi_status MediaLibraryNapiUtils::GetParamBool(napi_env env, napi_value arg, bool &value)
74 {
75     napi_valuetype valueType = napi_undefined;
76     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
77     CHECK_COND_RET(valueType == napi_boolean, napi_boolean_expected, "Type is not as expected boolean");
78     CHECK_STATUS_RET(napi_get_value_bool(env, arg, &value), "Failed to get param");
79     return napi_ok;
80 }
81 
GetUInt32Array(napi_env env,napi_value arg,vector<uint32_t> & result)82 napi_status MediaLibraryNapiUtils::GetUInt32Array(napi_env env, napi_value arg, vector<uint32_t> &result)
83 {
84     uint32_t arraySize = 0;
85     CHECK_COND_RET(IsArrayForNapiValue(env, arg, arraySize), napi_array_expected, "Failed to check array type");
86     for (uint32_t i = 0; i < arraySize; i++) {
87         napi_value val = nullptr;
88         CHECK_STATUS_RET(napi_get_element(env, arg, i, &val), "Failed to get element");
89         uint32_t value = 0;
90         CHECK_STATUS_RET(GetUInt32(env, val, value), "Failed to get element value");
91         result.push_back(value);
92     }
93     return napi_ok;
94 }
95 
GetParamFunction(napi_env env,napi_value arg,napi_ref & callbackRef)96 napi_status MediaLibraryNapiUtils::GetParamFunction(napi_env env, napi_value arg, napi_ref &callbackRef)
97 {
98     napi_valuetype valueType = napi_undefined;
99     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
100     CHECK_COND_RET(valueType == napi_function, napi_function_expected, "Type is not as expected function");
101     CHECK_STATUS_RET(napi_create_reference(env, arg, NAPI_INIT_REF_COUNT, &callbackRef), "Failed to make callbackref");
102     return napi_ok;
103 }
104 
GetParamStr(napi_env env,napi_value arg,const size_t size,string & result)105 static napi_status GetParamStr(napi_env env, napi_value arg, const size_t size, string &result)
106 {
107     size_t res = 0;
108     unique_ptr<char[]> buffer = make_unique<char[]>(size);
109     CHECK_COND_RET(buffer != nullptr, napi_invalid_arg, "Failed to alloc buffer for parameter");
110     napi_valuetype valueType = napi_undefined;
111     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
112     CHECK_COND_RET(valueType == napi_string, napi_string_expected, "Type is not as expected string");
113     CHECK_STATUS_RET(napi_get_value_string_utf8(env, arg, buffer.get(), size, &res), "Failed to get string value");
114     result = string(buffer.get());
115     return napi_ok;
116 }
117 
GetParamString(napi_env env,napi_value arg,string & result)118 napi_status MediaLibraryNapiUtils::GetParamString(napi_env env, napi_value arg, string &result)
119 {
120     CHECK_STATUS_RET(GetParamStr(env, arg, ARG_BUF_SIZE, result), "Failed to get string parameter");
121     return napi_ok;
122 }
123 
GetParamStringPathMax(napi_env env,napi_value arg,string & result)124 napi_status MediaLibraryNapiUtils::GetParamStringPathMax(napi_env env, napi_value arg, string &result)
125 {
126     CHECK_STATUS_RET(GetParamStr(env, arg, PATH_MAX, result), "Failed to get string parameter");
127     return napi_ok;
128 }
129 
GetProperty(napi_env env,const napi_value arg,const string & propName,string & propValue)130 napi_status MediaLibraryNapiUtils::GetProperty(napi_env env, const napi_value arg, const string &propName,
131     string &propValue)
132 {
133     bool present = false;
134     napi_value property = nullptr;
135     CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present),
136         "Failed to check property name");
137     if (present) {
138         CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property), "Failed to get property");
139         CHECK_STATUS_RET(GetParamStringPathMax(env, property, propValue), "Failed to get string buffer");
140     }
141     return napi_ok;
142 }
143 
GetStringArray(napi_env env,napi_value arg,vector<string> & array)144 napi_status MediaLibraryNapiUtils::GetStringArray(napi_env env, napi_value arg, vector<string> &array)
145 {
146     bool isArray = false;
147     uint32_t len = 0;
148     CHECK_STATUS_RET(napi_is_array(env, arg, &isArray), "Failed to check array type");
149     CHECK_COND_RET(isArray, napi_array_expected, "Expected array type");
150     CHECK_STATUS_RET(napi_get_array_length(env, arg, &len), "Failed to get array length");
151     for (uint32_t i = 0; i < len; i++) {
152         napi_value item = nullptr;
153         string val;
154         CHECK_STATUS_RET(napi_get_element(env, arg, i, &item), "Failed to get array item");
155         CHECK_STATUS_RET(GetParamStringPathMax(env, item, val), "Failed to get string buffer");
156         array.push_back(val);
157     }
158     return napi_ok;
159 }
160 
GetArrayProperty(napi_env env,napi_value arg,const string & propName,vector<string> & array)161 napi_status MediaLibraryNapiUtils::GetArrayProperty(napi_env env, napi_value arg, const string &propName,
162     vector<string> &array)
163 {
164     bool present = false;
165     CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present), "Failed to check property name");
166     if (present) {
167         napi_value property = nullptr;
168         CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property),
169             "Failed to get selectionArgs property");
170         GetStringArray(env, property, array);
171     }
172     return napi_ok;
173 }
174 
HasCallback(napi_env env,const size_t argc,const napi_value argv[],bool & isCallback)175 napi_status MediaLibraryNapiUtils::HasCallback(napi_env env, const size_t argc, const napi_value argv[],
176     bool &isCallback)
177 {
178     isCallback = false;
179     if (argc < ARGS_ONE) {
180         return napi_ok;
181     }
182     napi_valuetype valueType = napi_undefined;
183     CHECK_STATUS_RET(napi_typeof(env, argv[argc - 1], &valueType), "Failed to get type");
184     isCallback = (valueType == napi_function);
185     return napi_ok;
186 }
187 
hasFetchOpt(napi_env env,const napi_value arg,bool & hasFetchOpt)188 napi_status MediaLibraryNapiUtils::hasFetchOpt(napi_env env, const napi_value arg, bool &hasFetchOpt)
189 {
190     hasFetchOpt = false;
191     napi_valuetype valueType = napi_undefined;
192     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
193     if (valueType != napi_object) {
194         hasFetchOpt = false;
195         return napi_ok;
196     }
197     CHECK_STATUS_RET(napi_has_named_property(env, arg, "selections", &hasFetchOpt),
198         "Failed to get property selections");
199     return napi_ok;
200 }
201 
UriAddTableName(string & uri,const string tableName)202 void MediaLibraryNapiUtils::UriAddTableName(string &uri, const string tableName)
203 {
204     if (!tableName.empty()) {
205         uri += "/" + tableName;
206     }
207 }
208 
GetFileIdFromUri(const string & uri)209 string MediaLibraryNapiUtils::GetFileIdFromUri(const string &uri)
210 {
211     string id = "-1";
212 
213     string temp = uri;
214     MediaFileUri::RemoveAllFragment(temp);
215     size_t pos = temp.rfind('/');
216     if (pos != string::npos) {
217         id = temp.substr(pos + 1);
218     }
219 
220     return id;
221 }
222 
GetMediaTypeFromUri(const string & uri)223 MediaType MediaLibraryNapiUtils::GetMediaTypeFromUri(const string &uri)
224 {
225     if (uri.find(MEDIALIBRARY_IMAGE_URI) != string::npos) {
226         return MediaType::MEDIA_TYPE_IMAGE;
227     } else if (uri.find(MEDIALIBRARY_VIDEO_URI) != string::npos) {
228         return MediaType::MEDIA_TYPE_VIDEO;
229     } else if (uri.find(MEDIALIBRARY_AUDIO_URI) != string::npos) {
230         return MediaType::MEDIA_TYPE_AUDIO;
231     } else if (uri.find(MEDIALIBRARY_FILE_URI) != string::npos) {
232         return MediaType::MEDIA_TYPE_FILE;
233     }
234     return MediaType::MEDIA_TYPE_ALL;
235 }
236 
237 template <class AsyncContext>
HandleSpecialPredicate(AsyncContext & context,shared_ptr<DataShareAbsPredicates> & predicate,const FetchOptionType & fetchOptType)238 bool MediaLibraryNapiUtils::HandleSpecialPredicate(AsyncContext &context,
239     shared_ptr<DataShareAbsPredicates> &predicate, const FetchOptionType &fetchOptType)
240 {
241     constexpr int32_t FIELD_IDX = 0;
242     constexpr int32_t VALUE_IDX = 1;
243     vector<OperationItem> operations;
244     auto &items = predicate->GetOperationList();
245     for (auto &item : items) {
246         if (item.singleParams.empty()) {
247             operations.push_back(item);
248             continue;
249         }
250         // change uri ->file id
251         // get networkid
252         // replace networkid with file id
253         if (static_cast<string>(item.GetSingle(FIELD_IDX)) == DEVICE_DB_NETWORK_ID) {
254             if (item.operation != DataShare::EQUAL_TO || static_cast<string>(item.GetSingle(VALUE_IDX)).empty()) {
255                 NAPI_ERR_LOG("DEVICE_DB_NETWORK_ID predicates not support %{public}d", item.operation);
256                 return false;
257             }
258             context->networkId = static_cast<string>(item.GetSingle(VALUE_IDX));
259             continue;
260         }
261         if (static_cast<string>(item.GetSingle(FIELD_IDX)) == MEDIA_DATA_DB_URI) {
262             if (item.operation != DataShare::EQUAL_TO) {
263                 NAPI_ERR_LOG("MEDIA_DATA_DB_URI predicates not support %{public}d", item.operation);
264                 return false;
265             }
266             string uri = static_cast<string>(item.GetSingle(VALUE_IDX));
267             MediaFileUri::RemoveAllFragment(uri);
268             MediaFileUri fileUri(uri);
269 #ifdef MEDIALIBRARY_COMPATIBILITY
270             if ((fetchOptType != ALBUM_FETCH_OPT) && (!fileUri.IsApi10())) {
271                 fileUri = MediaFileUri(MediaFileUtils::GetRealUriFromVirtualUri(uri));
272             }
273 #endif
274             context->networkId = fileUri.GetNetworkId();
275             string field = (fetchOptType == ALBUM_FETCH_OPT) ? PhotoAlbumColumns::ALBUM_ID : MEDIA_DATA_DB_ID;
276             operations.push_back({ item.operation, { field, fileUri.GetFileId() } });
277             continue;
278         }
279         operations.push_back(item);
280     }
281     context->predicates = DataSharePredicates(move(operations));
282     return true;
283 }
284 
285 template <class AsyncContext>
GetFetchOption(napi_env env,napi_value arg,const FetchOptionType & fetchOptType,AsyncContext & context)286 napi_status MediaLibraryNapiUtils::GetFetchOption(napi_env env, napi_value arg, const FetchOptionType &fetchOptType,
287     AsyncContext &context)
288 {
289     // Parse the argument into fetchOption if any
290     CHECK_STATUS_RET(GetPredicate(env, arg, "predicates", context, fetchOptType), "invalid predicate");
291     CHECK_STATUS_RET(GetArrayProperty(env, arg, "fetchColumns", context->fetchColumn),
292         "Failed to parse fetchColumn");
293     return napi_ok;
294 }
295 
296 template <class AsyncContext>
GetAlbumFetchOption(napi_env env,napi_value arg,const FetchOptionType & fetchOptType,AsyncContext & context)297 napi_status MediaLibraryNapiUtils::GetAlbumFetchOption(napi_env env, napi_value arg,
298     const FetchOptionType &fetchOptType, AsyncContext &context)
299 {
300     // Parse the argument into AlbumFetchOption if any
301     CHECK_STATUS_RET(GetPredicate(env, arg, "predicates", context, fetchOptType), "invalid predicate");
302     return napi_ok;
303 }
304 
305 template <class AsyncContext>
GetPredicate(napi_env env,const napi_value arg,const string & propName,AsyncContext & context,const FetchOptionType & fetchOptType)306 napi_status MediaLibraryNapiUtils::GetPredicate(napi_env env, const napi_value arg, const string &propName,
307     AsyncContext &context, const FetchOptionType &fetchOptType)
308 {
309     bool present = false;
310     napi_value property = nullptr;
311     CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present),
312         "Failed to check property name");
313     if (present) {
314         CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property), "Failed to get property");
315         shared_ptr<DataShareAbsPredicates> predicate = DataSharePredicatesProxy::GetNativePredicates(env, property);
316         CHECK_COND_RET(HandleSpecialPredicate(context, predicate, fetchOptType) == TRUE, napi_invalid_arg,
317             "invalid predicate");
318     }
319     return napi_ok;
320 }
321 
322 template <class AsyncContext>
ParseAssetFetchOptCallback(napi_env env,napi_callback_info info,AsyncContext & context)323 napi_status MediaLibraryNapiUtils::ParseAssetFetchOptCallback(napi_env env, napi_callback_info info,
324     AsyncContext &context)
325 {
326     constexpr size_t minArgs = ARGS_ONE;
327     constexpr size_t maxArgs = ARGS_TWO;
328     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
329         "Failed to get object info");
330     CHECK_STATUS_RET(GetFetchOption(env, context->argv[PARAM0], ASSET_FETCH_OPT, context),
331         "Failed to get fetch option");
332     return napi_ok;
333 }
334 
335 template <class AsyncContext>
ParseAlbumFetchOptCallback(napi_env env,napi_callback_info info,AsyncContext & context)336 napi_status MediaLibraryNapiUtils::ParseAlbumFetchOptCallback(napi_env env, napi_callback_info info,
337     AsyncContext &context)
338 {
339     constexpr size_t minArgs = ARGS_ONE;
340     constexpr size_t maxArgs = ARGS_TWO;
341     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
342         "Failed to get object info");
343     // Parse the argument into fetchOption if any
344     CHECK_STATUS_RET(GetPredicate(env, context->argv[PARAM0], "predicates", context, ALBUM_FETCH_OPT),
345         "invalid predicate");
346     return napi_ok;
347 }
348 
349 template <class AsyncContext>
UpdateMediaTypeSelections(AsyncContext * context)350 void MediaLibraryNapiUtils::UpdateMediaTypeSelections(AsyncContext *context)
351 {
352     constexpr int FIRST_MEDIA_TYPE = 0;
353     constexpr int SECOND_MEDIA_TYPE = 1;
354     if ((context->mediaTypes.size() != ARGS_ONE) && (context->mediaTypes.size() != ARGS_TWO)) {
355         return;
356     }
357     DataShare::DataSharePredicates &predicates = context->predicates;
358     predicates.BeginWrap();
359     predicates.EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, (int)context->mediaTypes[FIRST_MEDIA_TYPE]);
360     if (context->mediaTypes.size() == ARGS_TWO) {
361         predicates.Or()->EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, (int)context->mediaTypes[SECOND_MEDIA_TYPE]);
362     }
363     predicates.EndWrap();
364 }
365 
366 template <class AsyncContext>
AsyncContextSetObjectInfo(napi_env env,napi_callback_info info,AsyncContext & asyncContext,const size_t minArgs,const size_t maxArgs)367 napi_status MediaLibraryNapiUtils::AsyncContextSetObjectInfo(napi_env env, napi_callback_info info,
368     AsyncContext &asyncContext, const size_t minArgs, const size_t maxArgs)
369 {
370     napi_value thisVar = nullptr;
371     asyncContext->argc = maxArgs;
372     CHECK_STATUS_RET(napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), &thisVar,
373         nullptr), "Failed to get cb info");
374     CHECK_COND_RET(((asyncContext->argc >= minArgs) && (asyncContext->argc <= maxArgs)), napi_invalid_arg,
375         "Number of args is invalid");
376     if (minArgs > 0) {
377         CHECK_COND_RET(asyncContext->argv[ARGS_ZERO] != nullptr, napi_invalid_arg, "Argument list is empty");
378     }
379     CHECK_STATUS_RET(napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo)),
380         "Failed to unwrap thisVar");
381     CHECK_COND_RET(asyncContext->objectInfo != nullptr, napi_invalid_arg, "Failed to get object info");
382     CHECK_STATUS_RET(GetParamCallback(env, asyncContext), "Failed to get callback param!");
383     return napi_ok;
384 }
385 
386 template <class AsyncContext>
GetParamCallback(napi_env env,AsyncContext & context)387 napi_status MediaLibraryNapiUtils::GetParamCallback(napi_env env, AsyncContext &context)
388 {
389     /* Parse the last argument into callbackref if any */
390     bool isCallback = false;
391     CHECK_STATUS_RET(HasCallback(env, context->argc, context->argv, isCallback), "Failed to check callback");
392     if (isCallback) {
393         CHECK_STATUS_RET(GetParamFunction(env, context->argv[context->argc - 1], context->callbackRef),
394             "Failed to get callback");
395     }
396     return napi_ok;
397 }
398 
399 template <class AsyncContext>
ParseArgsBoolCallBack(napi_env env,napi_callback_info info,AsyncContext & context,bool & param)400 napi_status MediaLibraryNapiUtils::ParseArgsBoolCallBack(napi_env env, napi_callback_info info, AsyncContext &context,
401     bool &param)
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 
408     /* Parse the first argument into param */
409     CHECK_STATUS_RET(GetParamBool(env, context->argv[ARGS_ZERO], param), "Failed to get parameter");
410     return napi_ok;
411 }
412 
413 template <class AsyncContext>
ParseArgsStringCallback(napi_env env,napi_callback_info info,AsyncContext & context,string & param)414 napi_status MediaLibraryNapiUtils::ParseArgsStringCallback(napi_env env, napi_callback_info info, AsyncContext &context,
415     string &param)
416 {
417     constexpr size_t minArgs = ARGS_ONE;
418     constexpr size_t maxArgs = ARGS_TWO;
419     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
420         "Failed to get object info");
421 
422     CHECK_STATUS_RET(GetParamStringPathMax(env, context->argv[ARGS_ZERO], param), "Failed to get string argument");
423     return napi_ok;
424 }
425 
426 template <class AsyncContext>
ParseArgsStringArrayCallback(napi_env env,napi_callback_info info,AsyncContext & context,vector<string> & array)427 napi_status MediaLibraryNapiUtils::ParseArgsStringArrayCallback(napi_env env, napi_callback_info info,
428     AsyncContext &context, vector<string> &array)
429 {
430     constexpr size_t minArgs = ARGS_ONE;
431     constexpr size_t maxArgs = ARGS_TWO;
432     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
433         "Failed to get object info");
434 
435     CHECK_STATUS_RET(GetStringArray(env, context->argv[ARGS_ZERO], array), "Failed to get string array");
436     CHECK_STATUS_RET(GetParamCallback(env, context), "Failed to get callback");
437     return napi_ok;
438 }
439 
440 template <class AsyncContext>
ParseArgsNumberCallback(napi_env env,napi_callback_info info,AsyncContext & context,int32_t & value)441 napi_status MediaLibraryNapiUtils::ParseArgsNumberCallback(napi_env env, napi_callback_info info, AsyncContext &context,
442     int32_t &value)
443 {
444     constexpr size_t minArgs = ARGS_ONE;
445     constexpr size_t maxArgs = ARGS_TWO;
446     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
447         "Failed to get object info");
448 
449     CHECK_STATUS_RET(GetInt32(env, context->argv[ARGS_ZERO], value), "Failed to get number argument");
450     return napi_ok;
451 }
452 
453 template <class AsyncContext>
ParseArgsOnlyCallBack(napi_env env,napi_callback_info info,AsyncContext & context)454 napi_status MediaLibraryNapiUtils::ParseArgsOnlyCallBack(napi_env env, napi_callback_info info, AsyncContext &context)
455 {
456     constexpr size_t minArgs = ARGS_ZERO;
457     constexpr size_t maxArgs = ARGS_ONE;
458     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
459         "Failed to get object info");
460     return napi_ok;
461 }
462 
GetAssetType(MediaType type)463 AssetType MediaLibraryNapiUtils::GetAssetType(MediaType type)
464 {
465     AssetType result;
466 
467     switch (type) {
468         case MEDIA_TYPE_AUDIO:
469             result = ASSET_AUDIO;
470             break;
471         case MEDIA_TYPE_VIDEO:
472             result = ASSET_VIDEO;
473             break;
474         case MEDIA_TYPE_IMAGE:
475             result = ASSET_IMAGE;
476             break;
477         case MEDIA_TYPE_MEDIA:
478             result = ASSET_MEDIA;
479             break;
480         default:
481             result = ASSET_NONE;
482             break;
483     }
484 
485     return result;
486 }
487 
AppendFetchOptionSelection(string & selection,const string & newCondition)488 void MediaLibraryNapiUtils::AppendFetchOptionSelection(string &selection, const string &newCondition)
489 {
490     if (!newCondition.empty()) {
491         if (!selection.empty()) {
492             selection = "(" + selection + ") AND " + newCondition;
493         } else {
494             selection = newCondition;
495         }
496     }
497 }
498 
TransErrorCode(const string & Name,shared_ptr<DataShare::DataShareResultSet> resultSet)499 int MediaLibraryNapiUtils::TransErrorCode(const string &Name, shared_ptr<DataShare::DataShareResultSet> resultSet)
500 {
501     NAPI_ERR_LOG("interface: %{public}s, server return nullptr", Name.c_str());
502     // Query can't return errorcode, so assume nullptr as permission deny
503     if (resultSet == nullptr) {
504         return JS_ERR_PERMISSION_DENIED;
505     }
506     return ERR_DEFAULT;
507 }
508 
TransErrorCode(const string & Name,int error)509 int MediaLibraryNapiUtils::TransErrorCode(const string &Name, int error)
510 {
511     NAPI_ERR_LOG("interface: %{public}s, server errcode:%{public}d ", Name.c_str(), error);
512     // Transfer Server error to napi error code
513     if (error <= E_COMMON_START && error >= E_COMMON_END) {
514         error = JS_INNER_FAIL;
515     } else if (trans2JsError.count(error)) {
516         error = trans2JsError.at(error);
517     }
518     return error;
519 }
520 
HandleError(napi_env env,int error,napi_value & errorObj,const string & Name)521 void MediaLibraryNapiUtils::HandleError(napi_env env, int error, napi_value &errorObj, const string &Name)
522 {
523     if (error == ERR_DEFAULT) {
524         return;
525     }
526 
527     string errMsg = "operation fail";
528     if (jsErrMap.count(error) > 0) {
529         errMsg = jsErrMap.at(error);
530     }
531     CreateNapiErrorObject(env, errorObj, error, errMsg);
532     errMsg = Name + " " + errMsg;
533     NAPI_ERR_LOG("Error: %{public}s, js errcode:%{public}d ", errMsg.c_str(), error);
534 }
535 
CreateNapiErrorObject(napi_env env,napi_value & errorObj,const int32_t errCode,const string errMsg)536 void MediaLibraryNapiUtils::CreateNapiErrorObject(napi_env env, napi_value &errorObj, const int32_t errCode,
537     const string errMsg)
538 {
539     napi_status statusError;
540     napi_value napiErrorCode = nullptr;
541     napi_value napiErrorMsg = nullptr;
542     statusError = napi_create_string_utf8(env, to_string(errCode).c_str(), NAPI_AUTO_LENGTH, &napiErrorCode);
543     if (statusError == napi_ok) {
544         statusError = napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &napiErrorMsg);
545         if (statusError == napi_ok) {
546             statusError = napi_create_error(env, napiErrorCode, napiErrorMsg, &errorObj);
547             if (statusError == napi_ok) {
548                 NAPI_DEBUG_LOG("napi_create_error success");
549             }
550         }
551     }
552 }
553 
InvokeJSAsyncMethod(napi_env env,napi_deferred deferred,napi_ref callbackRef,napi_async_work work,const JSAsyncContextOutput & asyncContext)554 void MediaLibraryNapiUtils::InvokeJSAsyncMethod(napi_env env, napi_deferred deferred, napi_ref callbackRef,
555     napi_async_work work, const JSAsyncContextOutput &asyncContext)
556 {
557     MediaLibraryTracer tracer;
558     tracer.Start("InvokeJSAsyncMethod");
559 
560     napi_value retVal;
561     napi_value callback = nullptr;
562 
563     /* Deferred is used when JS Callback method expects a promise value */
564     if (deferred) {
565         if (asyncContext.status) {
566             napi_resolve_deferred(env, deferred, asyncContext.data);
567         } else {
568             napi_reject_deferred(env, deferred, asyncContext.error);
569         }
570     } else {
571         napi_value result[ARGS_TWO];
572         result[PARAM0] = asyncContext.error;
573         result[PARAM1] = asyncContext.data;
574         napi_get_reference_value(env, callbackRef, &callback);
575         napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
576         napi_delete_reference(env, callbackRef);
577     }
578     napi_delete_async_work(env, work);
579 }
580 
581 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 *))582 napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr<AsyncContext> &asyncContext,
583     const string &resourceName,  void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *))
584 {
585     napi_value result = nullptr;
586     napi_value resource = nullptr;
587     NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
588     NAPI_CREATE_RESOURCE_NAME(env, resource, resourceName.c_str(), asyncContext);
589 
590     NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, execute, complete,
591         static_cast<void *>(asyncContext.get()), &asyncContext->work));
592     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
593     asyncContext.release();
594 
595     return result;
596 }
597 
ToUTF8String(napi_env env,napi_value value)598 tuple<bool, unique_ptr<char[]>, size_t> MediaLibraryNapiUtils::ToUTF8String(napi_env env, napi_value value)
599 {
600     size_t strLen = 0;
601     napi_status status = napi_get_value_string_utf8(env, value, nullptr, -1, &strLen);
602     if (status != napi_ok) {
603         NAPI_ERR_LOG("ToUTF8String get fail, %{public}d", status);
604         return { false, nullptr, 0 };
605     }
606 
607     size_t bufLen = strLen + 1;
608     unique_ptr<char[]> str = make_unique<char[]>(bufLen);
609     if (str == nullptr) {
610         NAPI_ERR_LOG("ToUTF8String get memory fail");
611         return { false, nullptr, 0 };
612     }
613     status = napi_get_value_string_utf8(env, value, str.get(), bufLen, &strLen);
614     return make_tuple(status == napi_ok, move(str), strLen);
615 }
616 
IsExistsByPropertyName(napi_env env,napi_value jsObject,const char * propertyName)617 bool MediaLibraryNapiUtils::IsExistsByPropertyName(napi_env env, napi_value jsObject, const char *propertyName)
618 {
619     bool result = false;
620     if (napi_has_named_property(env, jsObject, propertyName, &result) == napi_ok) {
621         return result;
622     } else {
623         NAPI_ERR_LOG("IsExistsByPropertyName not exist %{public}s", propertyName);
624         return false;
625     }
626 }
627 
GetPropertyValueByName(napi_env env,napi_value jsObject,const char * propertyName)628 napi_value MediaLibraryNapiUtils::GetPropertyValueByName(napi_env env, napi_value jsObject, const char *propertyName)
629 {
630     napi_value value = nullptr;
631     if (IsExistsByPropertyName(env, jsObject, propertyName) == false) {
632         NAPI_ERR_LOG("GetPropertyValueByName not exist %{public}s", propertyName);
633         return nullptr;
634     }
635     if (napi_get_named_property(env, jsObject, propertyName, &value) != napi_ok) {
636         NAPI_ERR_LOG("GetPropertyValueByName get fail %{public}s", propertyName);
637         return nullptr;
638     }
639     return value;
640 }
641 
CheckJSArgsTypeAsFunc(napi_env env,napi_value arg)642 bool MediaLibraryNapiUtils::CheckJSArgsTypeAsFunc(napi_env env, napi_value arg)
643 {
644     napi_valuetype valueType = napi_undefined;
645     napi_typeof(env, arg, &valueType);
646     return (valueType == napi_function);
647 }
648 
IsArrayForNapiValue(napi_env env,napi_value param,uint32_t & arraySize)649 bool MediaLibraryNapiUtils::IsArrayForNapiValue(napi_env env, napi_value param, uint32_t &arraySize)
650 {
651     bool isArray = false;
652     arraySize = 0;
653     if ((napi_is_array(env, param, &isArray) != napi_ok) || (isArray == false)) {
654         return false;
655     }
656     if (napi_get_array_length(env, param, &arraySize) != napi_ok) {
657         return false;
658     }
659     return true;
660 }
661 
GetInt32Arg(napi_env env,napi_value arg,int32_t & value)662 napi_value MediaLibraryNapiUtils::GetInt32Arg(napi_env env, napi_value arg, int32_t &value)
663 {
664     napi_valuetype valueType = napi_undefined;
665     CHECK_ARGS(env, napi_typeof(env, arg, &valueType), JS_INNER_FAIL);
666     if (valueType != napi_number) {
667         NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID);
668         return nullptr;
669     }
670     CHECK_ARGS(env, napi_get_value_int32(env, arg, &value), JS_INNER_FAIL);
671 
672     napi_value result = nullptr;
673     CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
674     return result;
675 }
676 
UriAppendKeyValue(string & uri,const string & key,const string & value)677 void MediaLibraryNapiUtils::UriAppendKeyValue(string &uri, const string &key, const string &value)
678 {
679     string uriKey = key + '=';
680     if (uri.find(uriKey) != string::npos) {
681         return;
682     }
683 
684     char queryMark = (uri.find('?') == string::npos) ? '?' : '&';
685     string append = queryMark + key + '=' + value;
686 
687     size_t posJ = uri.find('#');
688     if (posJ == string::npos) {
689         uri += append;
690     } else {
691         uri.insert(posJ, append);
692     }
693 }
694 
AddDefaultAssetColumns(napi_env env,vector<string> & fetchColumn,function<bool (const string & columnName)> isValidColumn,const PhotoAlbumSubType subType)695 napi_value MediaLibraryNapiUtils::AddDefaultAssetColumns(napi_env env, vector<string> &fetchColumn,
696     function<bool(const string &columnName)> isValidColumn, const PhotoAlbumSubType subType)
697 {
698     auto validFetchColumns = MediaColumn::DEFAULT_FETCH_COLUMNS;
699     switch (subType) {
700         case PhotoAlbumSubType::FAVORITE:
701             validFetchColumns.insert(MediaColumn::MEDIA_IS_FAV);
702             break;
703         case PhotoAlbumSubType::VIDEO:
704             validFetchColumns.insert(MediaColumn::MEDIA_TYPE);
705             break;
706         case PhotoAlbumSubType::HIDDEN:
707             validFetchColumns.insert(MediaColumn::MEDIA_HIDDEN);
708             break;
709         case PhotoAlbumSubType::TRASH:
710             validFetchColumns.insert(MediaColumn::MEDIA_DATE_TRASHED);
711             break;
712         case PhotoAlbumSubType::SCREENSHOT:
713         case PhotoAlbumSubType::CAMERA:
714             validFetchColumns.insert(PhotoColumn::PHOTO_SUBTYPE);
715             break;
716         default:
717             break;
718     }
719     for (const auto &column : fetchColumn) {
720         if (isValidColumn(column)) {
721             validFetchColumns.insert(column);
722         } else if (column == MEDIA_DATA_DB_URI) {
723             continue;
724         } else {
725             NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID);
726             return nullptr;
727         }
728     }
729     fetchColumn.assign(validFetchColumns.begin(), validFetchColumns.end());
730 
731     napi_value result = nullptr;
732     CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
733     return result;
734 }
735 
GetUserAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates)736 int32_t MediaLibraryNapiUtils::GetUserAlbumPredicates(const int32_t albumId, DataSharePredicates &predicates)
737 {
738     string onClause = MediaColumn::MEDIA_ID + " = " + PhotoMap::ASSET_ID;
739     predicates.InnerJoin(PhotoMap::TABLE)->On({ onClause });
740     predicates.EqualTo(PhotoMap::ALBUM_ID, to_string(albumId));
741     predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, to_string(0));
742     predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, to_string(0));
743     predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, to_string(0));
744     return E_SUCCESS;
745 }
746 
GetFavoritePredicates(DataSharePredicates & predicates)747 static int32_t GetFavoritePredicates(DataSharePredicates &predicates)
748 {
749     predicates.BeginWrap();
750     constexpr int32_t IS_FAVORITE = 1;
751     predicates.EqualTo(MediaColumn::MEDIA_IS_FAV, to_string(IS_FAVORITE));
752     predicates.And()->EqualTo(MediaColumn::MEDIA_DATE_TRASHED, to_string(0));
753     predicates.And()->EqualTo(MediaColumn::MEDIA_HIDDEN, to_string(0));
754     predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, to_string(0));
755     predicates.EndWrap();
756     return E_SUCCESS;
757 }
758 
GetVideoPredicates(DataSharePredicates & predicates)759 static int32_t GetVideoPredicates(DataSharePredicates &predicates)
760 {
761     predicates.BeginWrap();
762     predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_VIDEO));
763     predicates.And()->EqualTo(MediaColumn::MEDIA_DATE_TRASHED, to_string(0));
764     predicates.And()->EqualTo(MediaColumn::MEDIA_HIDDEN, to_string(0));
765     predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, to_string(0));
766     predicates.EndWrap();
767     return E_SUCCESS;
768 }
769 
GetHiddenPredicates(DataSharePredicates & predicates)770 static int32_t GetHiddenPredicates(DataSharePredicates &predicates)
771 {
772     predicates.BeginWrap();
773     constexpr int32_t IS_HIDDEN = 1;
774     predicates.And()->EqualTo(MediaColumn::MEDIA_DATE_TRASHED, to_string(0));
775     predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, to_string(IS_HIDDEN));
776     predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, to_string(0));
777     predicates.EndWrap();
778     return E_SUCCESS;
779 }
780 
GetTrashPredicates(DataSharePredicates & predicates)781 static int32_t GetTrashPredicates(DataSharePredicates &predicates)
782 {
783     predicates.BeginWrap();
784     predicates.GreaterThan(MediaColumn::MEDIA_DATE_TRASHED, to_string(0));
785     predicates.EndWrap();
786     return E_SUCCESS;
787 }
788 
GetScreenshotPredicates(DataSharePredicates & predicates)789 static int32_t GetScreenshotPredicates(DataSharePredicates &predicates)
790 {
791     predicates.BeginWrap();
792     predicates.EqualTo(PhotoColumn::PHOTO_SUBTYPE, to_string(static_cast<int32_t>(PhotoSubType::SCREENSHOT)));
793     predicates.And()->EqualTo(MediaColumn::MEDIA_DATE_TRASHED, to_string(0));
794     predicates.And()->EqualTo(MediaColumn::MEDIA_HIDDEN, to_string(0));
795     predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, to_string(0));
796     predicates.EndWrap();
797     return E_SUCCESS;
798 }
799 
GetCameraPredicates(DataSharePredicates & predicates)800 static int32_t GetCameraPredicates(DataSharePredicates &predicates)
801 {
802     predicates.BeginWrap();
803     predicates.EqualTo(PhotoColumn::PHOTO_SUBTYPE, to_string(static_cast<int32_t>(PhotoSubType::CAMERA)));
804     predicates.And()->EqualTo(MediaColumn::MEDIA_DATE_TRASHED, to_string(0));
805     predicates.And()->EqualTo(MediaColumn::MEDIA_HIDDEN, to_string(0));
806     predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, to_string(0));
807     predicates.EndWrap();
808     return E_SUCCESS;
809 }
810 
GetAllImagesPredicates(DataSharePredicates & predicates)811 static int32_t GetAllImagesPredicates(DataSharePredicates &predicates)
812 {
813     predicates.BeginWrap();
814     predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_IMAGE));
815     predicates.And()->EqualTo(MediaColumn::MEDIA_DATE_TRASHED, to_string(0));
816     predicates.And()->EqualTo(MediaColumn::MEDIA_HIDDEN, to_string(0));
817     predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, to_string(0));
818     predicates.EndWrap();
819     return E_SUCCESS;
820 }
821 
GetSystemAlbumPredicates(const PhotoAlbumSubType subType,DataSharePredicates & predicates)822 int32_t MediaLibraryNapiUtils::GetSystemAlbumPredicates(const PhotoAlbumSubType subType,
823     DataSharePredicates &predicates)
824 {
825     switch (subType) {
826         case PhotoAlbumSubType::FAVORITE: {
827             return GetFavoritePredicates(predicates);
828         }
829         case PhotoAlbumSubType::VIDEO: {
830             return GetVideoPredicates(predicates);
831         }
832         case PhotoAlbumSubType::HIDDEN: {
833             return GetHiddenPredicates(predicates);
834         }
835         case PhotoAlbumSubType::TRASH: {
836             return GetTrashPredicates(predicates);
837         }
838         case PhotoAlbumSubType::SCREENSHOT: {
839             return GetScreenshotPredicates(predicates);
840         }
841         case PhotoAlbumSubType::CAMERA: {
842             return GetCameraPredicates(predicates);
843         }
844         case PhotoAlbumSubType::IMAGES: {
845             return GetAllImagesPredicates(predicates);
846         }
847         default: {
848             NAPI_ERR_LOG("Unsupported photo album subtype: %{public}d", subType);
849             return E_INVALID_ARGUMENTS;
850         }
851     }
852 }
853 
IsSystemApp()854 bool MediaLibraryNapiUtils::IsSystemApp()
855 {
856     static bool isSys = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetSelfTokenID());
857     return isSys;
858 }
859 
860 template bool MediaLibraryNapiUtils::HandleSpecialPredicate<unique_ptr<MediaLibraryAsyncContext>>(
861     unique_ptr<MediaLibraryAsyncContext> &context, shared_ptr<DataShareAbsPredicates> &predicate,
862     const FetchOptionType &fetchOptType);
863 
864 template bool MediaLibraryNapiUtils::HandleSpecialPredicate<unique_ptr<AlbumNapiAsyncContext>>(
865     unique_ptr<AlbumNapiAsyncContext> &context, shared_ptr<DataShareAbsPredicates> &predicate,
866     const FetchOptionType &fetchOptType);
867 
868 template bool MediaLibraryNapiUtils::HandleSpecialPredicate<unique_ptr<SmartAlbumNapiAsyncContext>>(
869     unique_ptr<SmartAlbumNapiAsyncContext> &context, shared_ptr<DataShareAbsPredicates> &predicate,
870     const FetchOptionType &fetchOptType);
871 
872 template napi_status MediaLibraryNapiUtils::GetFetchOption<unique_ptr<MediaLibraryAsyncContext>>(napi_env env,
873     napi_value arg, const FetchOptionType &fetchOptType, unique_ptr<MediaLibraryAsyncContext> &context);
874 
875 template napi_status MediaLibraryNapiUtils::GetFetchOption<unique_ptr<PhotoAlbumNapiAsyncContext>>(napi_env env,
876     napi_value arg, const FetchOptionType &fetchOptType, unique_ptr<PhotoAlbumNapiAsyncContext> &context);
877 
878 template napi_status MediaLibraryNapiUtils::GetAlbumFetchOption<unique_ptr<MediaLibraryAsyncContext>>(napi_env env,
879     napi_value arg, const FetchOptionType &fetchOptType, unique_ptr<MediaLibraryAsyncContext> &context);
880 
881 template napi_status MediaLibraryNapiUtils::GetAlbumFetchOption<unique_ptr<PhotoAlbumNapiAsyncContext>>(napi_env env,
882     napi_value arg, const FetchOptionType &fetchOptType, unique_ptr<PhotoAlbumNapiAsyncContext> &context);
883 
884 template napi_status MediaLibraryNapiUtils::GetPredicate<unique_ptr<MediaLibraryAsyncContext>>(napi_env env,
885     const napi_value arg, const string &propName, unique_ptr<MediaLibraryAsyncContext> &context,
886     const FetchOptionType &fetchOptType);
887 
888 template napi_status MediaLibraryNapiUtils::GetPredicate<unique_ptr<AlbumNapiAsyncContext>>(napi_env env,
889     const napi_value arg, const string &propName, unique_ptr<AlbumNapiAsyncContext> &context,
890     const FetchOptionType &fetchOptType);
891 
892 template napi_status MediaLibraryNapiUtils::GetPredicate<unique_ptr<SmartAlbumNapiAsyncContext>>(napi_env env,
893     const napi_value arg, const string &propName, unique_ptr<SmartAlbumNapiAsyncContext> &context,
894     const FetchOptionType &fetchOptType);
895 
896 template napi_status MediaLibraryNapiUtils::ParseAssetFetchOptCallback<unique_ptr<MediaLibraryAsyncContext>>(
897     napi_env env, napi_callback_info info, unique_ptr<MediaLibraryAsyncContext> &context);
898 
899 template napi_status MediaLibraryNapiUtils::ParseAssetFetchOptCallback<unique_ptr<AlbumNapiAsyncContext>>(
900     napi_env env, napi_callback_info info, unique_ptr<AlbumNapiAsyncContext> &context);
901 
902 template napi_status MediaLibraryNapiUtils::ParseAssetFetchOptCallback<unique_ptr<SmartAlbumNapiAsyncContext>>(
903     napi_env env, napi_callback_info info, unique_ptr<SmartAlbumNapiAsyncContext> &context);
904 
905 template napi_status MediaLibraryNapiUtils::ParseAlbumFetchOptCallback<unique_ptr<MediaLibraryAsyncContext>>(
906     napi_env env, napi_callback_info info, unique_ptr<MediaLibraryAsyncContext> &context);
907 
908 template void MediaLibraryNapiUtils::UpdateMediaTypeSelections<SmartAlbumNapiAsyncContext>(
909     SmartAlbumNapiAsyncContext *context);
910 
911 template void MediaLibraryNapiUtils::UpdateMediaTypeSelections<AlbumNapiAsyncContext>(
912     AlbumNapiAsyncContext *context);
913 
914 template void MediaLibraryNapiUtils::UpdateMediaTypeSelections<MediaLibraryAsyncContext>(
915     MediaLibraryAsyncContext *context);
916 
917 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<FileAssetAsyncContext>>(
918     napi_env env, napi_callback_info info, unique_ptr<FileAssetAsyncContext> &context, string &param);
919 
920 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<MediaLibraryAsyncContext>>(
921     napi_env env, napi_callback_info info, unique_ptr<MediaLibraryAsyncContext> &context, string &param);
922 
923 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<SmartAlbumNapiAsyncContext>>(
924     napi_env env, napi_callback_info info, unique_ptr<SmartAlbumNapiAsyncContext> &context, string &param);
925 
926 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<PhotoAlbumNapiAsyncContext>>(
927     napi_env env, napi_callback_info info, unique_ptr<PhotoAlbumNapiAsyncContext> &context, string &param);
928 
929 template napi_status MediaLibraryNapiUtils::ParseArgsStringArrayCallback<unique_ptr<MediaLibraryAsyncContext>>(
930     napi_env env, napi_callback_info info, unique_ptr<MediaLibraryAsyncContext> &context, vector<string> &array);
931 
932 template napi_status MediaLibraryNapiUtils::GetParamCallback<unique_ptr<PhotoAlbumNapiAsyncContext>>(napi_env env,
933     unique_ptr<PhotoAlbumNapiAsyncContext> &context);
934 
935 template napi_status MediaLibraryNapiUtils::GetParamCallback<unique_ptr<SmartAlbumNapiAsyncContext>>(napi_env env,
936     unique_ptr<SmartAlbumNapiAsyncContext> &context);
937 
938 template napi_status MediaLibraryNapiUtils::GetParamCallback<unique_ptr<MediaLibraryInitContext>>(napi_env env,
939     unique_ptr<MediaLibraryInitContext> &context);
940 
941 template napi_status MediaLibraryNapiUtils::ParseArgsBoolCallBack<unique_ptr<MediaLibraryAsyncContext>>(napi_env env,
942     napi_callback_info info, unique_ptr<MediaLibraryAsyncContext> &context, bool &param);
943 
944 template napi_status MediaLibraryNapiUtils::ParseArgsBoolCallBack<unique_ptr<FileAssetAsyncContext>>(napi_env env,
945     napi_callback_info info, unique_ptr<FileAssetAsyncContext> &context, bool &param);
946 
947 template napi_status MediaLibraryNapiUtils::AsyncContextSetObjectInfo<unique_ptr<PhotoAlbumNapiAsyncContext>>(
948     napi_env env, napi_callback_info info, unique_ptr<PhotoAlbumNapiAsyncContext> &asyncContext, const size_t minArgs,
949     const size_t maxArgs);
950 
951 template napi_status MediaLibraryNapiUtils::AsyncContextSetObjectInfo<unique_ptr<SmartAlbumNapiAsyncContext>>(
952     napi_env env, napi_callback_info info, unique_ptr<SmartAlbumNapiAsyncContext> &asyncContext, const size_t minArgs,
953     const size_t maxArgs);
954 
955 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<MediaLibraryAsyncContext>(napi_env env,
956     unique_ptr<MediaLibraryAsyncContext> &asyncContext, const string &resourceName,
957     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
958 
959 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<FileAssetAsyncContext>(napi_env env,
960     unique_ptr<FileAssetAsyncContext> &asyncContext, const string &resourceName,
961     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
962 
963 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<AlbumNapiAsyncContext>(napi_env env,
964     unique_ptr<AlbumNapiAsyncContext> &asyncContext, const string &resourceName,
965     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
966 
967 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<PhotoAlbumNapiAsyncContext>(napi_env env,
968     unique_ptr<PhotoAlbumNapiAsyncContext> &asyncContext, const string &resourceName,
969     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
970 
971 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<SmartAlbumNapiAsyncContext>(napi_env env,
972     unique_ptr<SmartAlbumNapiAsyncContext> &asyncContext, const string &resourceName,
973     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
974 
975 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<MediaLibraryInitContext>(napi_env env,
976     unique_ptr<MediaLibraryInitContext> &asyncContext, const string &resourceName,
977     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
978 
979 template napi_status MediaLibraryNapiUtils::ParseArgsNumberCallback<unique_ptr<MediaLibraryAsyncContext>>(napi_env env,
980     napi_callback_info info, unique_ptr<MediaLibraryAsyncContext> &context, int32_t &value);
981 
982 template napi_status MediaLibraryNapiUtils::ParseArgsNumberCallback<unique_ptr<FileAssetAsyncContext>>(napi_env env,
983     napi_callback_info info, unique_ptr<FileAssetAsyncContext> &context, int32_t &value);
984 
985 template napi_status MediaLibraryNapiUtils::ParseArgsOnlyCallBack<unique_ptr<MediaLibraryAsyncContext>>(napi_env env,
986     napi_callback_info info, unique_ptr<MediaLibraryAsyncContext> &context);
987 
988 template napi_status MediaLibraryNapiUtils::ParseArgsOnlyCallBack<unique_ptr<FileAssetAsyncContext>>(napi_env env,
989     napi_callback_info info, unique_ptr<FileAssetAsyncContext> &context);
990 
991 template napi_status MediaLibraryNapiUtils::ParseArgsOnlyCallBack<unique_ptr<AlbumNapiAsyncContext>>(napi_env env,
992     napi_callback_info info, unique_ptr<AlbumNapiAsyncContext> &context);
993 } // namespace Media
994 } // namespace OHOS
995