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