• 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 <cctype>
20 #include "basic/result_set.h"
21 #include "datashare_predicates.h"
22 #include "location_column.h"
23 #include "ipc_skeleton.h"
24 #include "js_proxy.h"
25 #include "cloud_enhancement_napi.h"
26 #include "highlight_album_napi.h"
27 #include "media_asset_change_request_napi.h"
28 #include "media_assets_change_request_napi.h"
29 #include "media_album_change_request_napi.h"
30 #include "media_asset_manager_napi.h"
31 #include "media_device_column.h"
32 #include "media_file_uri.h"
33 #include "media_file_utils.h"
34 #include "media_library_napi.h"
35 #include "medialibrary_client_errno.h"
36 #include "medialibrary_db_const.h"
37 #include "medialibrary_errno.h"
38 #include "medialibrary_tracer.h"
39 #include "medialibrary_type_const.h"
40 #include "moving_photo_napi.h"
41 #include "photo_album_napi.h"
42 #include "photo_map_column.h"
43 #include "smart_album_napi.h"
44 #include "tokenid_kit.h"
45 #include "userfile_client.h"
46 #include "vision_album_column.h"
47 #include "vision_column.h"
48 #include "vision_face_tag_column.h"
49 #include "vision_pose_column.h"
50 #include "vision_image_face_column.h"
51 
52 using namespace std;
53 using namespace OHOS::DataShare;
54 
55 namespace OHOS {
56 namespace Media {
57 static const string EMPTY_STRING = "";
58 using json = nlohmann::json;
NapiDefineClass(napi_env env,napi_value exports,const NapiClassInfo & info)59 napi_value MediaLibraryNapiUtils::NapiDefineClass(napi_env env, napi_value exports, const NapiClassInfo &info)
60 {
61     napi_value ctorObj;
62     NAPI_CALL(env, napi_define_class(env, info.name.c_str(), NAPI_AUTO_LENGTH, info.constructor, nullptr,
63         info.props.size(), info.props.data(), &ctorObj));
64     NAPI_CALL(env, napi_create_reference(env, ctorObj, NAPI_INIT_REF_COUNT, info.ref));
65     NAPI_CALL(env, napi_set_named_property(env, exports, info.name.c_str(), ctorObj));
66     return exports;
67 }
68 
NapiAddStaticProps(napi_env env,napi_value exports,const vector<napi_property_descriptor> & staticProps)69 napi_value MediaLibraryNapiUtils::NapiAddStaticProps(napi_env env, napi_value exports,
70     const vector<napi_property_descriptor> &staticProps)
71 {
72     NAPI_CALL(env, napi_define_properties(env, exports, staticProps.size(), staticProps.data()));
73     return exports;
74 }
75 
GetUInt32(napi_env env,napi_value arg,uint32_t & value)76 napi_status MediaLibraryNapiUtils::GetUInt32(napi_env env, napi_value arg, uint32_t &value)
77 {
78     napi_valuetype valueType = napi_undefined;
79     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
80     CHECK_COND_RET(valueType == napi_number, napi_number_expected, "Type is not as expected number");
81     CHECK_STATUS_RET(napi_get_value_uint32(env, arg, &value), "Failed to get uint32 value");
82     return napi_ok;
83 }
84 
GetInt32(napi_env env,napi_value arg,int32_t & value)85 napi_status MediaLibraryNapiUtils::GetInt32(napi_env env, napi_value arg, int32_t &value)
86 {
87     napi_valuetype valueType = napi_undefined;
88     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
89     CHECK_COND_RET(valueType == napi_number, napi_number_expected, "Type is not as expected number");
90     CHECK_STATUS_RET(napi_get_value_int32(env, arg, &value), "Failed to get int32 value");
91     return napi_ok;
92 }
93 
GetDouble(napi_env env,napi_value arg,double & value)94 napi_status MediaLibraryNapiUtils::GetDouble(napi_env env, napi_value arg, double &value)
95 {
96     napi_valuetype valueType = napi_undefined;
97     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
98     CHECK_COND_RET(valueType == napi_number, napi_number_expected, "Type is not as expected number");
99     CHECK_STATUS_RET(napi_get_value_double(env, arg, &value), "Failed to get double value");
100     return napi_ok;
101 }
102 
GetParamBool(napi_env env,napi_value arg,bool & value)103 napi_status MediaLibraryNapiUtils::GetParamBool(napi_env env, napi_value arg, bool &value)
104 {
105     napi_valuetype valueType = napi_undefined;
106     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
107     CHECK_COND_RET(valueType == napi_boolean, napi_boolean_expected, "Type is not as expected boolean");
108     CHECK_STATUS_RET(napi_get_value_bool(env, arg, &value), "Failed to get param");
109     return napi_ok;
110 }
111 
GetUInt32Array(napi_env env,napi_value arg,vector<uint32_t> & result)112 napi_status MediaLibraryNapiUtils::GetUInt32Array(napi_env env, napi_value arg, vector<uint32_t> &result)
113 {
114     uint32_t arraySize = 0;
115     CHECK_COND_RET(IsArrayForNapiValue(env, arg, arraySize), napi_array_expected, "Failed to check array type");
116     for (uint32_t i = 0; i < arraySize; i++) {
117         napi_value val = nullptr;
118         CHECK_STATUS_RET(napi_get_element(env, arg, i, &val), "Failed to get element");
119         uint32_t value = 0;
120         CHECK_STATUS_RET(GetUInt32(env, val, value), "Failed to get element value");
121         result.push_back(value);
122     }
123     return napi_ok;
124 }
125 
GetParamFunction(napi_env env,napi_value arg,napi_ref & callbackRef)126 napi_status MediaLibraryNapiUtils::GetParamFunction(napi_env env, napi_value arg, napi_ref &callbackRef)
127 {
128     napi_valuetype valueType = napi_undefined;
129     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
130     CHECK_COND_RET(valueType == napi_function, napi_function_expected, "Type is not as expected function");
131     CHECK_STATUS_RET(napi_create_reference(env, arg, NAPI_INIT_REF_COUNT, &callbackRef), "Failed to make callbackref");
132     return napi_ok;
133 }
134 
GetParamStr(napi_env env,napi_value arg,const size_t size,string & result)135 static napi_status GetParamStr(napi_env env, napi_value arg, const size_t size, string &result)
136 {
137     size_t res = 0;
138     unique_ptr<char[]> buffer = make_unique<char[]>(size);
139     CHECK_COND_RET(buffer != nullptr, napi_invalid_arg, "Failed to alloc buffer for parameter");
140     napi_valuetype valueType = napi_undefined;
141     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
142     CHECK_COND_RET(valueType == napi_string, napi_string_expected, "Type is not as expected string");
143     CHECK_STATUS_RET(napi_get_value_string_utf8(env, arg, buffer.get(), size, &res), "Failed to get string value");
144     result = string(buffer.get());
145     return napi_ok;
146 }
147 
GetParamStringWithLength(napi_env env,napi_value arg,int32_t maxLen,string & result)148 napi_status MediaLibraryNapiUtils::GetParamStringWithLength(napi_env env, napi_value arg, int32_t maxLen,
149     string &result)
150 {
151     CHECK_STATUS_RET(GetParamStr(env, arg, maxLen, result), "Failed to get string parameter");
152     return napi_ok;
153 }
154 
GetParamStringPathMax(napi_env env,napi_value arg,string & result)155 napi_status MediaLibraryNapiUtils::GetParamStringPathMax(napi_env env, napi_value arg, string &result)
156 {
157     CHECK_STATUS_RET(GetParamStr(env, arg, PATH_MAX, result), "Failed to get string parameter");
158     return napi_ok;
159 }
160 
GetProperty(napi_env env,const napi_value arg,const string & propName,string & propValue)161 napi_status MediaLibraryNapiUtils::GetProperty(napi_env env, const napi_value arg, const string &propName,
162     string &propValue)
163 {
164     bool present = false;
165     napi_value property = nullptr;
166     CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present),
167         "Failed to check property name");
168     if (present) {
169         CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property), "Failed to get property");
170         CHECK_STATUS_RET(GetParamStringPathMax(env, property, propValue), "Failed to get string buffer");
171     }
172     return napi_ok;
173 }
174 
GetStringArray(napi_env env,napi_value arg,vector<string> & array)175 napi_status MediaLibraryNapiUtils::GetStringArray(napi_env env, napi_value arg, vector<string> &array)
176 {
177     bool isArray = false;
178     uint32_t len = 0;
179     CHECK_STATUS_RET(napi_is_array(env, arg, &isArray), "Failed to check array type");
180     CHECK_COND_RET(isArray, napi_array_expected, "Expected array type");
181     CHECK_STATUS_RET(napi_get_array_length(env, arg, &len), "Failed to get array length");
182     for (uint32_t i = 0; i < len; i++) {
183         napi_value item = nullptr;
184         string val;
185         CHECK_STATUS_RET(napi_get_element(env, arg, i, &item), "Failed to get array item");
186         CHECK_STATUS_RET(GetParamStringPathMax(env, item, val), "Failed to get string buffer");
187         array.push_back(val);
188     }
189     return napi_ok;
190 }
191 
GetArrayProperty(napi_env env,napi_value arg,const string & propName,vector<string> & array)192 napi_status MediaLibraryNapiUtils::GetArrayProperty(napi_env env, napi_value arg, const string &propName,
193     vector<string> &array)
194 {
195     bool present = false;
196     CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present), "Failed to check property name");
197     if (present) {
198         napi_value property = nullptr;
199         CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property),
200             "Failed to get selectionArgs property");
201         GetStringArray(env, property, array);
202     }
203     return napi_ok;
204 }
205 
HasCallback(napi_env env,const size_t argc,const napi_value argv[],bool & isCallback)206 napi_status MediaLibraryNapiUtils::HasCallback(napi_env env, const size_t argc, const napi_value argv[],
207     bool &isCallback)
208 {
209     isCallback = false;
210     if (argc < ARGS_ONE) {
211         return napi_ok;
212     }
213     napi_valuetype valueType = napi_undefined;
214     CHECK_STATUS_RET(napi_typeof(env, argv[argc - 1], &valueType), "Failed to get type");
215     isCallback = (valueType == napi_function);
216     return napi_ok;
217 }
218 
hasFetchOpt(napi_env env,const napi_value arg,bool & hasFetchOpt)219 napi_status MediaLibraryNapiUtils::hasFetchOpt(napi_env env, const napi_value arg, bool &hasFetchOpt)
220 {
221     hasFetchOpt = false;
222     napi_valuetype valueType = napi_undefined;
223     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
224     if (valueType != napi_object) {
225         hasFetchOpt = false;
226         return napi_ok;
227     }
228     CHECK_STATUS_RET(napi_has_named_property(env, arg, "selections", &hasFetchOpt),
229         "Failed to get property selections");
230     return napi_ok;
231 }
232 
UriAddTableName(string & uri,const string tableName)233 void MediaLibraryNapiUtils::UriAddTableName(string &uri, const string tableName)
234 {
235     if (!tableName.empty()) {
236         uri += "/" + tableName;
237     }
238 }
239 
GetFileIdFromUri(const string & uri)240 string MediaLibraryNapiUtils::GetFileIdFromUri(const string &uri)
241 {
242     string id = "-1";
243 
244     string temp = uri;
245     MediaFileUri::RemoveAllFragment(temp);
246     size_t pos = temp.rfind('/');
247     if (pos != string::npos) {
248         id = temp.substr(pos + 1);
249     }
250 
251     return id;
252 }
253 
GetFileIdFromPhotoUri(const string & uri)254 int32_t MediaLibraryNapiUtils::GetFileIdFromPhotoUri(const string &uri)
255 {
256     const static int ERROR = -1;
257     if (PhotoColumn::PHOTO_URI_PREFIX.size() >= uri.size()) {
258         NAPI_ERR_LOG("photo uri is too short");
259         return ERROR;
260     }
261     if (uri.substr(0, PhotoColumn::PHOTO_URI_PREFIX.size()) !=
262         PhotoColumn::PHOTO_URI_PREFIX) {
263         NAPI_ERR_LOG("only photo uri is valid");
264         return ERROR;
265     }
266     std::string tmp = uri.substr(PhotoColumn::PHOTO_URI_PREFIX.size());
267 
268     std::string fileIdStr = tmp.substr(0, tmp.find_first_of('/'));
269     if (fileIdStr.empty()) {
270         NAPI_ERR_LOG("intercepted fileId is empty");
271         return ERROR;
272     }
273     if (std::all_of(fileIdStr.begin(), fileIdStr.end(), ::isdigit)) {
274         return std::stoi(fileIdStr);
275     }
276     NAPI_ERR_LOG("asset fileId is invalid");
277     return ERROR;
278 }
279 
GetMediaTypeFromUri(const string & uri)280 MediaType MediaLibraryNapiUtils::GetMediaTypeFromUri(const string &uri)
281 {
282     if (uri.find(MEDIALIBRARY_IMAGE_URI) != string::npos) {
283         return MediaType::MEDIA_TYPE_IMAGE;
284     } else if (uri.find(MEDIALIBRARY_VIDEO_URI) != string::npos) {
285         return MediaType::MEDIA_TYPE_VIDEO;
286     } else if (uri.find(MEDIALIBRARY_AUDIO_URI) != string::npos) {
287         return MediaType::MEDIA_TYPE_AUDIO;
288     } else if (uri.find(MEDIALIBRARY_FILE_URI) != string::npos) {
289         return MediaType::MEDIA_TYPE_FILE;
290     }
291     return MediaType::MEDIA_TYPE_ALL;
292 }
293 
HandleSpecialDateTypePredicate(const OperationItem & item,vector<OperationItem> & operations,const FetchOptionType & fetchOptType)294 static bool HandleSpecialDateTypePredicate(const OperationItem &item,
295     vector<OperationItem> &operations, const FetchOptionType &fetchOptType)
296 {
297     constexpr int32_t FIELD_IDX = 0;
298     constexpr int32_t VALUE_IDX = 1;
299     vector<string>dateTypes = { MEDIA_DATA_DB_DATE_ADDED, MEDIA_DATA_DB_DATE_TRASHED, MEDIA_DATA_DB_DATE_MODIFIED,
300         MEDIA_DATA_DB_DATE_TAKEN };
301     string dateType = item.GetSingle(FIELD_IDX);
302     auto it = find(dateTypes.begin(), dateTypes.end(), dateType);
303     if (it != dateTypes.end() && item.operation != DataShare::ORDER_BY_ASC &&
304         item.operation != DataShare::ORDER_BY_DESC) {
305         dateType += "_s";
306         operations.push_back({ item.operation, { dateType, static_cast<double>(item.GetSingle(VALUE_IDX)) } });
307         return true;
308     }
309     if (DATE_TRANSITION_MAP.count(dateType) != 0) {
310         dateType = DATE_TRANSITION_MAP.at(dateType);
311         operations.push_back({ item.operation, { dateType, static_cast<double>(item.GetSingle(VALUE_IDX)) } });
312         return true;
313     }
314     return false;
315 }
316 
317 template <class AsyncContext>
HandleSpecialPredicate(AsyncContext & context,shared_ptr<DataShareAbsPredicates> & predicate,const FetchOptionType & fetchOptType)318 bool MediaLibraryNapiUtils::HandleSpecialPredicate(AsyncContext &context,
319     shared_ptr<DataShareAbsPredicates> &predicate, const FetchOptionType &fetchOptType)
320 {
321     constexpr int32_t FIELD_IDX = 0;
322     constexpr int32_t VALUE_IDX = 1;
323     vector<OperationItem> operations;
324     auto &items = predicate->GetOperationList();
325     for (auto &item : items) {
326         if (item.singleParams.empty()) {
327             operations.push_back(item);
328             continue;
329         }
330         if (HandleSpecialDateTypePredicate(item, operations, fetchOptType)) {
331             continue;
332         }
333         // change uri ->file id
334         // get networkid
335         // replace networkid with file id
336         if (static_cast<string>(item.GetSingle(FIELD_IDX)) == DEVICE_DB_NETWORK_ID) {
337             if (item.operation != DataShare::EQUAL_TO || static_cast<string>(item.GetSingle(VALUE_IDX)).empty()) {
338                 NAPI_ERR_LOG("DEVICE_DB_NETWORK_ID predicates not support %{public}d", item.operation);
339                 return false;
340             }
341             context->networkId = static_cast<string>(item.GetSingle(VALUE_IDX));
342             continue;
343         }
344         if (static_cast<string>(item.GetSingle(FIELD_IDX)) == MEDIA_DATA_DB_URI) {
345             if (item.operation != DataShare::EQUAL_TO) {
346                 NAPI_ERR_LOG("MEDIA_DATA_DB_URI predicates not support %{public}d", item.operation);
347                 return false;
348             }
349             string uri = static_cast<string>(item.GetSingle(VALUE_IDX));
350             MediaFileUri::RemoveAllFragment(uri);
351             MediaFileUri fileUri(uri);
352             context->uri = uri;
353             if ((fetchOptType != ALBUM_FETCH_OPT) && (!fileUri.IsApi10())) {
354                 fileUri = MediaFileUri(MediaFileUtils::GetRealUriFromVirtualUri(uri));
355             }
356             context->networkId = fileUri.GetNetworkId();
357             string field = (fetchOptType == ALBUM_FETCH_OPT) ? PhotoAlbumColumns::ALBUM_ID : MEDIA_DATA_DB_ID;
358             operations.push_back({ item.operation, { field, fileUri.GetFileId() } });
359             continue;
360         }
361         if (static_cast<string>(item.GetSingle(FIELD_IDX)) == PENDING_STATUS) {
362             // do not query pending files below API11
363             continue;
364         }
365         if (LOCATION_PARAM_MAP.find(static_cast<string>(item.GetSingle(FIELD_IDX))) != LOCATION_PARAM_MAP.end()) {
366             continue;
367         }
368         operations.push_back(item);
369     }
370     context->predicates = DataSharePredicates(move(operations));
371     return true;
372 }
373 
374 template <class AsyncContext>
GetLocationPredicate(AsyncContext & context,shared_ptr<DataShareAbsPredicates> & predicate)375 bool MediaLibraryNapiUtils::GetLocationPredicate(AsyncContext &context,
376     shared_ptr<DataShareAbsPredicates> &predicate)
377 {
378     constexpr int32_t FIELD_IDX = 0;
379     constexpr int32_t VALUE_IDX = 1;
380     map<string, string> locationMap;
381     auto &items = predicate->GetOperationList();
382     for (auto &item : items) {
383         if (item.singleParams.empty()) {
384             continue;
385         }
386         if (LOCATION_PARAM_MAP.find(static_cast<string>(item.GetSingle(FIELD_IDX))) != LOCATION_PARAM_MAP.end()) {
387             if (item.operation != DataShare::EQUAL_TO) {
388                 NAPI_ERR_LOG("location predicates not support %{public}d", item.operation);
389                 return false;
390             }
391             string param = static_cast<string>(item.GetSingle(FIELD_IDX));
392             string value = static_cast<string>(item.GetSingle(VALUE_IDX));
393             locationMap.insert(make_pair(param, value));
394             if (param == DIAMETER) {
395                 continue;
396             }
397             if (LOCATION_PARAM_MAP.at(param).second == DataShare::GREATER_THAN_OR_EQUAL_TO) {
398                 context->predicates.GreaterThanOrEqualTo(LOCATION_PARAM_MAP.at(param).first, value);
399                 continue;
400             }
401             if (LOCATION_PARAM_MAP.at(param).second == DataShare::LESS_THAN) {
402                 context->predicates.LessThan(LOCATION_PARAM_MAP.at(param).first, value);
403                 continue;
404             }
405             if (LOCATION_PARAM_MAP.at(param).second == DataShare::EQUAL_TO) {
406                 context->predicates.EqualTo(LOCATION_PARAM_MAP.at(param).first, value);
407                 continue;
408             }
409         }
410     }
411 
412     if (locationMap.count(DIAMETER) == 1 && locationMap.count(START_LATITUDE) == 1
413         && locationMap.count(START_LONGITUDE) == 1) {
414         // 0.5:Used for rounding down
415         string latitudeIndex = "round((latitude - " + locationMap.at(START_LATITUDE) + ") / " +
416             locationMap.at(DIAMETER) + " - 0.5)";
417         string longitudeIndex = "round((longitude - " + locationMap.at(START_LONGITUDE) + ") / " +
418             locationMap.at(DIAMETER) + " - 0.5)";
419         string albumName = LATITUDE + "||'_'||" + LONGITUDE + "||'_'||" + latitudeIndex + "||'_'||" +
420             longitudeIndex + " AS " + ALBUM_NAME;
421         context->fetchColumn.push_back(albumName);
422         string locationGroup = latitudeIndex + "," + longitudeIndex;
423         context->predicates.GroupBy({ locationGroup });
424     }
425     return true;
426 }
427 
428 template <class AsyncContext>
GetFetchOption(napi_env env,napi_value arg,const FetchOptionType & fetchOptType,AsyncContext & context)429 napi_status MediaLibraryNapiUtils::GetFetchOption(napi_env env, napi_value arg, const FetchOptionType &fetchOptType,
430     AsyncContext &context)
431 {
432     // Parse the argument into fetchOption if any
433     CHECK_STATUS_RET(GetPredicate(env, arg, "predicates", context, fetchOptType), "invalid predicate");
434     CHECK_STATUS_RET(GetArrayProperty(env, arg, "fetchColumns", context->fetchColumn),
435         "Failed to parse fetchColumn");
436     return napi_ok;
437 }
438 
439 template <class AsyncContext>
GetAlbumFetchOption(napi_env env,napi_value arg,const FetchOptionType & fetchOptType,AsyncContext & context)440 napi_status MediaLibraryNapiUtils::GetAlbumFetchOption(napi_env env, napi_value arg,
441     const FetchOptionType &fetchOptType, AsyncContext &context)
442 {
443     // Parse the argument into AlbumFetchOption if any
444     CHECK_STATUS_RET(GetPredicate(env, arg, "predicates", context, fetchOptType), "invalid predicate");
445     return napi_ok;
446 }
447 
448 template <class AsyncContext>
GetPredicate(napi_env env,const napi_value arg,const string & propName,AsyncContext & context,const FetchOptionType & fetchOptType)449 napi_status MediaLibraryNapiUtils::GetPredicate(napi_env env, const napi_value arg, const string &propName,
450     AsyncContext &context, const FetchOptionType &fetchOptType)
451 {
452     bool present = false;
453     napi_value property = nullptr;
454     CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present),
455         "Failed to check property name");
456     if (present) {
457         CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property), "Failed to get property");
458         JSProxy::JSProxy<DataShareAbsPredicates> *jsProxy = nullptr;
459         napi_unwrap(env, property, reinterpret_cast<void **>(&jsProxy));
460         if (jsProxy == nullptr) {
461             NAPI_ERR_LOG("jsProxy is invalid");
462             return napi_invalid_arg;
463         }
464         shared_ptr<DataShareAbsPredicates> predicate = jsProxy->GetInstance();
465         CHECK_COND_RET(HandleSpecialPredicate(context, predicate, fetchOptType) == TRUE, napi_invalid_arg,
466             "invalid predicate");
467         CHECK_COND_RET(GetLocationPredicate(context, predicate) == TRUE, napi_invalid_arg, "invalid predicate");
468     }
469     return napi_ok;
470 }
471 
472 template <class AsyncContext>
ParseAssetFetchOptCallback(napi_env env,napi_callback_info info,AsyncContext & context)473 napi_status MediaLibraryNapiUtils::ParseAssetFetchOptCallback(napi_env env, napi_callback_info info,
474     AsyncContext &context)
475 {
476     constexpr size_t minArgs = ARGS_ONE;
477     constexpr size_t maxArgs = ARGS_TWO;
478     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
479         "Failed to get object info");
480     CHECK_STATUS_RET(GetFetchOption(env, context->argv[PARAM0], ASSET_FETCH_OPT, context),
481         "Failed to get fetch option");
482     return napi_ok;
483 }
484 
485 template <class AsyncContext>
ParseAlbumFetchOptCallback(napi_env env,napi_callback_info info,AsyncContext & context)486 napi_status MediaLibraryNapiUtils::ParseAlbumFetchOptCallback(napi_env env, napi_callback_info info,
487     AsyncContext &context)
488 {
489     constexpr size_t minArgs = ARGS_ONE;
490     constexpr size_t maxArgs = ARGS_TWO;
491     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
492         "Failed to get object info");
493     // Parse the argument into fetchOption if any
494     CHECK_STATUS_RET(GetPredicate(env, context->argv[PARAM0], "predicates", context, ALBUM_FETCH_OPT),
495         "invalid predicate");
496     context->predicates.And()->NotEqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::HIDDEN));
497     return napi_ok;
498 }
499 
500 template <class AsyncContext>
UpdateMediaTypeSelections(AsyncContext * context)501 void MediaLibraryNapiUtils::UpdateMediaTypeSelections(AsyncContext *context)
502 {
503     constexpr int FIRST_MEDIA_TYPE = 0;
504     constexpr int SECOND_MEDIA_TYPE = 1;
505     if ((context->mediaTypes.size() != ARGS_ONE) && (context->mediaTypes.size() != ARGS_TWO)) {
506         return;
507     }
508     DataShare::DataSharePredicates &predicates = context->predicates;
509     predicates.BeginWrap();
510     predicates.EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, (int)context->mediaTypes[FIRST_MEDIA_TYPE]);
511     if (context->mediaTypes.size() == ARGS_TWO) {
512         predicates.Or()->EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, (int)context->mediaTypes[SECOND_MEDIA_TYPE]);
513     }
514     predicates.EndWrap();
515 }
516 
517 template <class AsyncContext>
AsyncContextSetObjectInfo(napi_env env,napi_callback_info info,AsyncContext & asyncContext,const size_t minArgs,const size_t maxArgs)518 napi_status MediaLibraryNapiUtils::AsyncContextSetObjectInfo(napi_env env, napi_callback_info info,
519     AsyncContext &asyncContext, const size_t minArgs, const size_t maxArgs)
520 {
521     napi_value thisVar = nullptr;
522     asyncContext->argc = maxArgs;
523     CHECK_STATUS_RET(napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), &thisVar,
524         nullptr), "Failed to get cb info");
525     CHECK_COND_RET(((asyncContext->argc >= minArgs) && (asyncContext->argc <= maxArgs)), napi_invalid_arg,
526         "Number of args is invalid");
527     if (minArgs > 0) {
528         CHECK_COND_RET(asyncContext->argv[ARGS_ZERO] != nullptr, napi_invalid_arg, "Argument list is empty");
529     }
530     CHECK_STATUS_RET(napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo)),
531         "Failed to unwrap thisVar");
532     CHECK_COND_RET(asyncContext->objectInfo != nullptr, napi_invalid_arg, "Failed to get object info");
533     CHECK_STATUS_RET(GetParamCallback(env, asyncContext), "Failed to get callback param!");
534     return napi_ok;
535 }
536 
537 template <class AsyncContext>
AsyncContextGetArgs(napi_env env,napi_callback_info info,AsyncContext & asyncContext,const size_t minArgs,const size_t maxArgs)538 napi_status MediaLibraryNapiUtils::AsyncContextGetArgs(napi_env env, napi_callback_info info,
539     AsyncContext &asyncContext, const size_t minArgs, const size_t maxArgs)
540 {
541     asyncContext->argc = maxArgs;
542     CHECK_STATUS_RET(napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), nullptr,
543         nullptr), "Failed to get cb info");
544     CHECK_COND_RET(asyncContext->argc >= minArgs && asyncContext->argc <= maxArgs, napi_invalid_arg,
545         "Number of args is invalid");
546     if (minArgs > 0) {
547         CHECK_COND_RET(asyncContext->argv[ARGS_ZERO] != nullptr, napi_invalid_arg, "Argument list is empty");
548     }
549     CHECK_STATUS_RET(GetParamCallback(env, asyncContext), "Failed to get callback param");
550     return napi_ok;
551 }
552 
553 template <class AsyncContext>
GetParamCallback(napi_env env,AsyncContext & context)554 napi_status MediaLibraryNapiUtils::GetParamCallback(napi_env env, AsyncContext &context)
555 {
556     /* Parse the last argument into callbackref if any */
557     bool isCallback = false;
558     CHECK_STATUS_RET(HasCallback(env, context->argc, context->argv, isCallback), "Failed to check callback");
559     if (isCallback) {
560         CHECK_STATUS_RET(GetParamFunction(env, context->argv[context->argc - 1], context->callbackRef),
561             "Failed to get callback");
562     }
563     return napi_ok;
564 }
565 
566 template <class AsyncContext>
ParseArgsBoolCallBack(napi_env env,napi_callback_info info,AsyncContext & context,bool & param)567 napi_status MediaLibraryNapiUtils::ParseArgsBoolCallBack(napi_env env, napi_callback_info info, AsyncContext &context,
568     bool &param)
569 {
570     constexpr size_t minArgs = ARGS_ONE;
571     constexpr size_t maxArgs = ARGS_TWO;
572     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
573         "Failed to get object info");
574 
575     /* Parse the first argument into param */
576     CHECK_STATUS_RET(GetParamBool(env, context->argv[ARGS_ZERO], param), "Failed to get parameter");
577     return napi_ok;
578 }
579 
580 template <class AsyncContext>
ParseArgsStringCallback(napi_env env,napi_callback_info info,AsyncContext & context,string & param)581 napi_status MediaLibraryNapiUtils::ParseArgsStringCallback(napi_env env, napi_callback_info info, AsyncContext &context,
582     string &param)
583 {
584     constexpr size_t minArgs = ARGS_ONE;
585     constexpr size_t maxArgs = ARGS_TWO;
586     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
587         "Failed to get object info");
588 
589     CHECK_STATUS_RET(GetParamStringPathMax(env, context->argv[ARGS_ZERO], param), "Failed to get string argument");
590     return napi_ok;
591 }
592 
593 template <class AsyncContext>
ParseArgsStringArrayCallback(napi_env env,napi_callback_info info,AsyncContext & context,vector<string> & array)594 napi_status MediaLibraryNapiUtils::ParseArgsStringArrayCallback(napi_env env, napi_callback_info info,
595     AsyncContext &context, vector<string> &array)
596 {
597     constexpr size_t minArgs = ARGS_ONE;
598     constexpr size_t maxArgs = ARGS_TWO;
599     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
600         "Failed to get object info");
601 
602     CHECK_STATUS_RET(GetStringArray(env, context->argv[ARGS_ZERO], array), "Failed to get string array");
603     CHECK_STATUS_RET(GetParamCallback(env, context), "Failed to get callback");
604     return napi_ok;
605 }
606 
607 template <class AsyncContext>
ParseArgsNumberCallback(napi_env env,napi_callback_info info,AsyncContext & context,int32_t & value)608 napi_status MediaLibraryNapiUtils::ParseArgsNumberCallback(napi_env env, napi_callback_info info, AsyncContext &context,
609     int32_t &value)
610 {
611     constexpr size_t minArgs = ARGS_ONE;
612     constexpr size_t maxArgs = ARGS_TWO;
613     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
614         "Failed to get object info");
615 
616     CHECK_STATUS_RET(GetInt32(env, context->argv[ARGS_ZERO], value), "Failed to get number argument");
617     return napi_ok;
618 }
619 
620 template <class AsyncContext>
ParseArgsOnlyCallBack(napi_env env,napi_callback_info info,AsyncContext & context)621 napi_status MediaLibraryNapiUtils::ParseArgsOnlyCallBack(napi_env env, napi_callback_info info, AsyncContext &context)
622 {
623     constexpr size_t minArgs = ARGS_ZERO;
624     constexpr size_t maxArgs = ARGS_ONE;
625     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
626         "Failed to get object info");
627     return napi_ok;
628 }
629 
GetAssetType(MediaType type)630 AssetType MediaLibraryNapiUtils::GetAssetType(MediaType type)
631 {
632     AssetType result;
633 
634     switch (type) {
635         case MEDIA_TYPE_AUDIO:
636             result = ASSET_AUDIO;
637             break;
638         case MEDIA_TYPE_VIDEO:
639             result = ASSET_VIDEO;
640             break;
641         case MEDIA_TYPE_IMAGE:
642             result = ASSET_IMAGE;
643             break;
644         case MEDIA_TYPE_MEDIA:
645             result = ASSET_MEDIA;
646             break;
647         default:
648             result = ASSET_NONE;
649             break;
650     }
651 
652     return result;
653 }
654 
AppendFetchOptionSelection(string & selection,const string & newCondition)655 void MediaLibraryNapiUtils::AppendFetchOptionSelection(string &selection, const string &newCondition)
656 {
657     if (!newCondition.empty()) {
658         if (!selection.empty()) {
659             selection = "(" + selection + ") AND " + newCondition;
660         } else {
661             selection = newCondition;
662         }
663     }
664 }
665 
TransErrorCode(const string & Name,shared_ptr<DataShare::DataShareResultSet> resultSet)666 int MediaLibraryNapiUtils::TransErrorCode(const string &Name, shared_ptr<DataShare::DataShareResultSet> resultSet)
667 {
668     NAPI_ERR_LOG("interface: %{public}s, server return nullptr", Name.c_str());
669     // Query can't return errorcode, so assume nullptr as permission deny
670     if (resultSet == nullptr) {
671         return JS_ERR_PERMISSION_DENIED;
672     }
673     return ERR_DEFAULT;
674 }
675 
TransErrorCode(const string & Name,int error)676 int MediaLibraryNapiUtils::TransErrorCode(const string &Name, int error)
677 {
678     NAPI_ERR_LOG("interface: %{public}s, server errcode:%{public}d ", Name.c_str(), error);
679     // Transfer Server error to napi error code
680     if (error <= E_COMMON_START && error >= E_COMMON_END) {
681         error = JS_INNER_FAIL;
682     } else if (trans2JsError.count(error)) {
683         error = trans2JsError.at(error);
684     }
685     return error;
686 }
687 
HandleError(napi_env env,int error,napi_value & errorObj,const string & Name)688 void MediaLibraryNapiUtils::HandleError(napi_env env, int error, napi_value &errorObj, const string &Name)
689 {
690     if (error == ERR_DEFAULT) {
691         return;
692     }
693 
694     string errMsg = "System inner fail";
695     int originalError = error;
696     if (jsErrMap.count(error) > 0) {
697         errMsg = jsErrMap.at(error);
698     } else {
699         error = JS_INNER_FAIL;
700     }
701     CreateNapiErrorObject(env, errorObj, error, errMsg);
702     errMsg = Name + " " + errMsg;
703     NAPI_ERR_LOG("Error: %{public}s, js errcode:%{public}d ", errMsg.c_str(), originalError);
704 }
705 
CreateNapiErrorObject(napi_env env,napi_value & errorObj,const int32_t errCode,const string errMsg)706 void MediaLibraryNapiUtils::CreateNapiErrorObject(napi_env env, napi_value &errorObj, const int32_t errCode,
707     const string errMsg)
708 {
709     napi_status statusError;
710     napi_value napiErrorCode = nullptr;
711     napi_value napiErrorMsg = nullptr;
712     statusError = napi_create_string_utf8(env, to_string(errCode).c_str(), NAPI_AUTO_LENGTH, &napiErrorCode);
713     if (statusError == napi_ok) {
714         statusError = napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &napiErrorMsg);
715         if (statusError == napi_ok) {
716             statusError = napi_create_error(env, napiErrorCode, napiErrorMsg, &errorObj);
717             if (statusError == napi_ok) {
718                 NAPI_DEBUG_LOG("napi_create_error success");
719             }
720         }
721     }
722 }
723 
InvokeJSAsyncMethod(napi_env env,napi_deferred deferred,napi_ref callbackRef,napi_async_work work,const JSAsyncContextOutput & asyncContext)724 void MediaLibraryNapiUtils::InvokeJSAsyncMethod(napi_env env, napi_deferred deferred, napi_ref callbackRef,
725     napi_async_work work, const JSAsyncContextOutput &asyncContext)
726 {
727     MediaLibraryTracer tracer;
728     tracer.Start("InvokeJSAsyncMethod");
729 
730     napi_value retVal;
731     napi_value callback = nullptr;
732 
733     /* Deferred is used when JS Callback method expects a promise value */
734     if (deferred) {
735         if (asyncContext.status) {
736             napi_resolve_deferred(env, deferred, asyncContext.data);
737         } else {
738             napi_reject_deferred(env, deferred, asyncContext.error);
739         }
740     } else {
741         napi_value result[ARGS_TWO];
742         result[PARAM0] = asyncContext.error;
743         result[PARAM1] = asyncContext.data;
744         napi_get_reference_value(env, callbackRef, &callback);
745         napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
746         napi_delete_reference(env, callbackRef);
747     }
748     napi_delete_async_work(env, work);
749 }
750 
751 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 *))752 napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr<AsyncContext> &asyncContext,
753     const string &resourceName,  void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *))
754 {
755     napi_value result = nullptr;
756     napi_value resource = nullptr;
757     NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
758     NAPI_CREATE_RESOURCE_NAME(env, resource, resourceName.c_str(), asyncContext);
759 
760     NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, execute, complete,
761         static_cast<void *>(asyncContext.get()), &asyncContext->work));
762     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
763     asyncContext.release();
764 
765     return result;
766 }
767 
ToUTF8String(napi_env env,napi_value value)768 tuple<bool, unique_ptr<char[]>, size_t> MediaLibraryNapiUtils::ToUTF8String(napi_env env, napi_value value)
769 {
770     size_t strLen = 0;
771     napi_status status = napi_get_value_string_utf8(env, value, nullptr, -1, &strLen);
772     if (status != napi_ok) {
773         NAPI_ERR_LOG("ToUTF8String get fail, %{public}d", status);
774         return { false, nullptr, 0 };
775     }
776 
777     size_t bufLen = strLen + 1;
778     unique_ptr<char[]> str = make_unique<char[]>(bufLen);
779     if (str == nullptr) {
780         NAPI_ERR_LOG("ToUTF8String get memory fail");
781         return { false, nullptr, 0 };
782     }
783     status = napi_get_value_string_utf8(env, value, str.get(), bufLen, &strLen);
784     return make_tuple(status == napi_ok, move(str), strLen);
785 }
786 
IsExistsByPropertyName(napi_env env,napi_value jsObject,const char * propertyName)787 bool MediaLibraryNapiUtils::IsExistsByPropertyName(napi_env env, napi_value jsObject, const char *propertyName)
788 {
789     bool result = false;
790     if (napi_has_named_property(env, jsObject, propertyName, &result) == napi_ok) {
791         return result;
792     } else {
793         NAPI_ERR_LOG("IsExistsByPropertyName not exist %{public}s", propertyName);
794         return false;
795     }
796 }
797 
GetPropertyValueByName(napi_env env,napi_value jsObject,const char * propertyName)798 napi_value MediaLibraryNapiUtils::GetPropertyValueByName(napi_env env, napi_value jsObject, const char *propertyName)
799 {
800     napi_value value = nullptr;
801     if (IsExistsByPropertyName(env, jsObject, propertyName) == false) {
802         NAPI_ERR_LOG("GetPropertyValueByName not exist %{public}s", propertyName);
803         return nullptr;
804     }
805     if (napi_get_named_property(env, jsObject, propertyName, &value) != napi_ok) {
806         NAPI_ERR_LOG("GetPropertyValueByName get fail %{public}s", propertyName);
807         return nullptr;
808     }
809     return value;
810 }
811 
CheckJSArgsTypeAsFunc(napi_env env,napi_value arg)812 bool MediaLibraryNapiUtils::CheckJSArgsTypeAsFunc(napi_env env, napi_value arg)
813 {
814     napi_valuetype valueType = napi_undefined;
815     napi_typeof(env, arg, &valueType);
816     return (valueType == napi_function);
817 }
818 
IsArrayForNapiValue(napi_env env,napi_value param,uint32_t & arraySize)819 bool MediaLibraryNapiUtils::IsArrayForNapiValue(napi_env env, napi_value param, uint32_t &arraySize)
820 {
821     bool isArray = false;
822     arraySize = 0;
823     if ((napi_is_array(env, param, &isArray) != napi_ok) || (isArray == false)) {
824         return false;
825     }
826     if (napi_get_array_length(env, param, &arraySize) != napi_ok) {
827         return false;
828     }
829     return true;
830 }
831 
GetInt32Arg(napi_env env,napi_value arg,int32_t & value)832 napi_value MediaLibraryNapiUtils::GetInt32Arg(napi_env env, napi_value arg, int32_t &value)
833 {
834     napi_valuetype valueType = napi_undefined;
835     CHECK_ARGS(env, napi_typeof(env, arg, &valueType), JS_INNER_FAIL);
836     if (valueType != napi_number) {
837         NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID);
838         return nullptr;
839     }
840     CHECK_ARGS(env, napi_get_value_int32(env, arg, &value), JS_INNER_FAIL);
841 
842     napi_value result = nullptr;
843     CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
844     return result;
845 }
846 
UriAppendKeyValue(string & uri,const string & key,const string & value)847 void MediaLibraryNapiUtils::UriAppendKeyValue(string &uri, const string &key, const string &value)
848 {
849     string uriKey = key + '=';
850     if (uri.find(uriKey) != string::npos) {
851         return;
852     }
853 
854     char queryMark = (uri.find('?') == string::npos) ? '?' : '&';
855     string append = queryMark + key + '=' + value;
856 
857     size_t posJ = uri.find('#');
858     if (posJ == string::npos) {
859         uri += append;
860     } else {
861         uri.insert(posJ, append);
862     }
863 }
864 
AddDefaultAssetColumns(napi_env env,vector<string> & fetchColumn,function<bool (const string & columnName)> isValidColumn,NapiAssetType assetType,const PhotoAlbumSubType subType)865 napi_value MediaLibraryNapiUtils::AddDefaultAssetColumns(napi_env env, vector<string> &fetchColumn,
866     function<bool(const string &columnName)> isValidColumn, NapiAssetType assetType,
867     const PhotoAlbumSubType subType)
868 {
869     auto validFetchColumns = MediaColumn::DEFAULT_FETCH_COLUMNS;
870     if (assetType == TYPE_PHOTO) {
871         validFetchColumns.insert(
872             PhotoColumn::DEFAULT_FETCH_COLUMNS.begin(), PhotoColumn::DEFAULT_FETCH_COLUMNS.end());
873     }
874     switch (subType) {
875         case PhotoAlbumSubType::FAVORITE:
876             validFetchColumns.insert(MediaColumn::MEDIA_IS_FAV);
877             break;
878         case PhotoAlbumSubType::VIDEO:
879             validFetchColumns.insert(MediaColumn::MEDIA_TYPE);
880             break;
881         case PhotoAlbumSubType::HIDDEN:
882             validFetchColumns.insert(MediaColumn::MEDIA_HIDDEN);
883             break;
884         case PhotoAlbumSubType::TRASH:
885             validFetchColumns.insert(MediaColumn::MEDIA_DATE_TRASHED);
886             break;
887         case PhotoAlbumSubType::SCREENSHOT:
888         case PhotoAlbumSubType::CAMERA:
889             validFetchColumns.insert(PhotoColumn::PHOTO_SUBTYPE);
890             break;
891         default:
892             break;
893     }
894     for (const auto &column : fetchColumn) {
895         if (column == PENDING_STATUS) {
896             validFetchColumns.insert(MediaColumn::MEDIA_TIME_PENDING);
897         } else if (isValidColumn(column)) {
898             validFetchColumns.insert(column);
899         } else if (column == MEDIA_DATA_DB_URI) {
900             continue;
901         } else if (DATE_TRANSITION_MAP.count(column) != 0) {
902             validFetchColumns.insert(DATE_TRANSITION_MAP.at(column));
903         } else {
904             NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID);
905             return nullptr;
906         }
907     }
908     fetchColumn.assign(validFetchColumns.begin(), validFetchColumns.end());
909 
910     napi_value result = nullptr;
911     CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
912     return result;
913 }
914 
SetDefaultPredicatesCondition(DataSharePredicates & predicates,const int32_t dateTrashed,const bool isHidden,const int32_t timePending,const bool isTemp)915 inline void SetDefaultPredicatesCondition(DataSharePredicates &predicates, const int32_t dateTrashed,
916     const bool isHidden, const int32_t timePending, const bool isTemp)
917 {
918     predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, to_string(dateTrashed));
919     predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, to_string(isHidden));
920     predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, to_string(timePending));
921     predicates.EqualTo(PhotoColumn::PHOTO_IS_TEMP, to_string(isTemp));
922     predicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL,
923         to_string(static_cast<int32_t>(BurstCoverLevelType::COVER)));
924 }
925 
GetUserAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates,const bool hiddenOnly)926 int32_t MediaLibraryNapiUtils::GetUserAlbumPredicates(
927     const int32_t albumId, DataSharePredicates &predicates, const bool hiddenOnly)
928 {
929     predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(albumId));
930     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
931     return E_SUCCESS;
932 }
933 
GetPortraitAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates)934 int32_t MediaLibraryNapiUtils::GetPortraitAlbumPredicates(const int32_t albumId, DataSharePredicates &predicates)
935 {
936     string onClause = MediaColumn::MEDIA_ID + " = " + PhotoMap::ASSET_ID;
937     vector<string> clauses = { onClause };
938     predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On(clauses);
939     onClause = ALBUM_ID + " = " + PhotoMap::ALBUM_ID;
940     clauses = { onClause };
941     predicates.InnerJoin(ANALYSIS_ALBUM_TABLE)->On(clauses);
942     string tempTable = "(SELECT " + GROUP_TAG + " FROM " + ANALYSIS_ALBUM_TABLE + " WHERE " + ALBUM_ID + " = " +
943         to_string(albumId) + ") ag";
944     onClause = "ag." + GROUP_TAG + " = " + ANALYSIS_ALBUM_TABLE + "." + GROUP_TAG;
945     clauses = { onClause };
946     predicates.InnerJoin(tempTable)->On(clauses);
947     SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
948     predicates.Distinct();
949     return E_SUCCESS;
950 }
951 
GetAnalysisAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates)952 int32_t MediaLibraryNapiUtils::GetAnalysisAlbumPredicates(const int32_t albumId, DataSharePredicates &predicates)
953 {
954     string onClause = MediaColumn::MEDIA_ID + " = " + PhotoMap::ASSET_ID;
955     predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On({ onClause });
956     predicates.EqualTo(PhotoMap::ALBUM_ID, to_string(albumId));
957     SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
958     return E_SUCCESS;
959 }
960 
IsFeaturedSinglePortraitAlbum(std::string albumName,DataShare::DataSharePredicates & predicates)961 bool MediaLibraryNapiUtils::IsFeaturedSinglePortraitAlbum(
962     std::string albumName, DataShare::DataSharePredicates &predicates)
963 {
964     bool isFeaturedSinglePortrait = false;
965     int portraitAlbumId = 0;
966     if (albumName.compare(to_string(portraitAlbumId)) != 0) {
967         return isFeaturedSinglePortrait;
968     }
969 
970     DataSharePredicates featuredSinglePortraitPredicates;
971     std::vector<OperationItem> operationList = predicates.GetOperationList();
972     for (auto& operationItem : operationList) {
973         switch (operationItem.operation) {
974             case OHOS::DataShare::OperationType::LIKE : {
975                 std::string field = std::get<string>(operationItem.singleParams[0]);
976                 std::string value = std::get<string>(operationItem.singleParams[1]);
977                 if (field.compare("FeaturedSinglePortrait") == 0 && value.compare("true") == 0) {
978                     isFeaturedSinglePortrait = true;
979                 } else {
980                     featuredSinglePortraitPredicates.Like(field, value);
981                 }
982                 break;
983             }
984             case OHOS::DataShare::OperationType::ORDER_BY_DESC : {
985                 featuredSinglePortraitPredicates.OrderByDesc(operationItem.GetSingle(0));
986                 break;
987             }
988             case OHOS::DataShare::OperationType::LIMIT : {
989                 featuredSinglePortraitPredicates.Limit(operationItem.GetSingle(0), operationItem.GetSingle(1));
990                 break;
991             }
992             default: {
993                 break;
994             }
995         }
996     }
997 
998     if (isFeaturedSinglePortrait) {
999         predicates = featuredSinglePortraitPredicates;
1000     }
1001     return isFeaturedSinglePortrait;
1002 }
1003 
GetFeaturedSinglePortraitAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates)1004 int32_t MediaLibraryNapiUtils::GetFeaturedSinglePortraitAlbumPredicates(
1005     const int32_t albumId, DataSharePredicates &predicates)
1006 {
1007     string onClause = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID + " = " +
1008         ANALYSIS_PHOTO_MAP_TABLE + "." + PhotoMap::ASSET_ID;
1009     predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On({ onClause });
1010 
1011     constexpr int32_t minSize = 224;
1012     string imgHeightColumn = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_HEIGHT;
1013     string imgWidthColumn = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_WIDTH;
1014     string imgFaceHeightColumn = VISION_IMAGE_FACE_TABLE + "." + SCALE_HEIGHT;
1015     string imgFaceWidthColumn = VISION_IMAGE_FACE_TABLE + "." + SCALE_WIDTH;
1016     string imgFaceHeightClause = "( " + imgFaceHeightColumn + " > " + to_string(minSize) +
1017         " OR ( " + imgFaceHeightColumn + " <= 1.0 " + " AND " + imgFaceHeightColumn + " * " + imgHeightColumn +
1018         " > " + to_string(minSize) + " ) )";
1019     string imgFaceWidthClause = "( " + imgFaceWidthColumn + " > " + to_string(minSize) +
1020         " OR ( " + imgFaceWidthColumn + " <= 1.0 " + " AND " + imgFaceWidthColumn + " * " + imgWidthColumn +
1021         " > " + to_string(minSize) + " ) )";
1022     string imgFaceOcclusionClause = "( " + VISION_IMAGE_FACE_TABLE + "." + FACE_OCCLUSION + " != 1 OR " +
1023         VISION_IMAGE_FACE_TABLE + "." + FACE_OCCLUSION + " IS NULL )";
1024     string portraitRotationLimit = "BETWEEN -30 AND 30";
1025     onClause = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID + " = " + VISION_IMAGE_FACE_TABLE + "." +
1026         MediaColumn::MEDIA_ID + " AND " + VISION_IMAGE_FACE_TABLE + "." + TOTAL_FACES + " = 1 AND " +
1027         imgFaceHeightClause + " AND " + imgFaceWidthClause + " AND " + imgFaceOcclusionClause + " AND " +
1028         VISION_IMAGE_FACE_TABLE + "." + PITCH + " " + portraitRotationLimit + " AND " +
1029         VISION_IMAGE_FACE_TABLE + "." + YAW + " " + portraitRotationLimit + " AND " +
1030         VISION_IMAGE_FACE_TABLE + "." + ROLL + " " + portraitRotationLimit;
1031     predicates.InnerJoin(VISION_IMAGE_FACE_TABLE)->On({ onClause });
1032 
1033     string portraitType = "IN ( 1, 2 )";
1034     onClause = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID + " = " + VISION_POSE_TABLE + "." +
1035         MediaColumn::MEDIA_ID + " AND " + VISION_POSE_TABLE + "." + POSE_TYPE + " " + portraitType;
1036     predicates.InnerJoin(VISION_POSE_TABLE)->On({ onClause });
1037 
1038     predicates.EqualTo(PhotoMap::ALBUM_ID, to_string(albumId));
1039     SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
1040     return E_SUCCESS;
1041 }
1042 
GetAllLocationPredicates(DataSharePredicates & predicates)1043 int32_t MediaLibraryNapiUtils::GetAllLocationPredicates(DataSharePredicates &predicates)
1044 {
1045     SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
1046     predicates.And()->NotEqualTo(PhotoColumn::PHOTO_LATITUDE, to_string(0));
1047     predicates.And()->NotEqualTo(PhotoColumn::PHOTO_LONGITUDE, to_string(0));
1048     return E_SUCCESS;
1049 }
1050 
GetFavoritePredicates(DataSharePredicates & predicates,const bool hiddenOnly)1051 static int32_t GetFavoritePredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1052 {
1053     predicates.BeginWrap();
1054     constexpr int32_t IS_FAVORITE = 1;
1055     predicates.EqualTo(MediaColumn::MEDIA_IS_FAV, to_string(IS_FAVORITE));
1056     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1057     predicates.EndWrap();
1058     return E_SUCCESS;
1059 }
1060 
GetVideoPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1061 static int32_t GetVideoPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1062 {
1063     predicates.BeginWrap();
1064     predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_VIDEO));
1065     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1066     predicates.EndWrap();
1067     return E_SUCCESS;
1068 }
1069 
GetHiddenPredicates(DataSharePredicates & predicates)1070 static int32_t GetHiddenPredicates(DataSharePredicates &predicates)
1071 {
1072     predicates.BeginWrap();
1073     SetDefaultPredicatesCondition(predicates, 0, 1, 0, false);
1074     predicates.EndWrap();
1075     return E_SUCCESS;
1076 }
1077 
GetTrashPredicates(DataSharePredicates & predicates)1078 static int32_t GetTrashPredicates(DataSharePredicates &predicates)
1079 {
1080     predicates.BeginWrap();
1081     predicates.GreaterThan(MediaColumn::MEDIA_DATE_TRASHED, to_string(0));
1082     predicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL,
1083         to_string(static_cast<int32_t>(BurstCoverLevelType::COVER)));
1084     predicates.EndWrap();
1085     return E_SUCCESS;
1086 }
1087 
GetScreenshotPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1088 static int32_t GetScreenshotPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1089 {
1090     predicates.BeginWrap();
1091     predicates.EqualTo(PhotoColumn::PHOTO_SUBTYPE, to_string(static_cast<int32_t>(PhotoSubType::SCREENSHOT)));
1092     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1093     predicates.EndWrap();
1094     return E_SUCCESS;
1095 }
1096 
GetCameraPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1097 static int32_t GetCameraPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1098 {
1099     predicates.BeginWrap();
1100     predicates.EqualTo(PhotoColumn::PHOTO_SUBTYPE, to_string(static_cast<int32_t>(PhotoSubType::CAMERA)));
1101     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1102     predicates.EndWrap();
1103     return E_SUCCESS;
1104 }
1105 
GetAllImagesPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1106 static int32_t GetAllImagesPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1107 {
1108     predicates.BeginWrap();
1109     predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_IMAGE));
1110     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1111     predicates.EndWrap();
1112     return E_SUCCESS;
1113 }
1114 
GetCloudEnhancementPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1115 static int32_t GetCloudEnhancementPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1116 {
1117     predicates.BeginWrap();
1118     predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_IMAGE));
1119     predicates.EqualTo(PhotoColumn::PHOTO_STRONG_ASSOCIATION,
1120         to_string(static_cast<int32_t>(StrongAssociationType::CLOUD_ENHANCEMENT)));
1121     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1122     predicates.EndWrap();
1123     return E_SUCCESS;
1124 }
1125 
GetSourceAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates,const bool hiddenOnly)1126 int32_t MediaLibraryNapiUtils::GetSourceAlbumPredicates(const int32_t albumId, DataSharePredicates &predicates,
1127     const bool hiddenOnly)
1128 {
1129     predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(albumId));
1130     predicates.EqualTo(PhotoColumn::PHOTO_SYNC_STATUS, to_string(static_cast<int32_t>(SyncStatusType::TYPE_VISIBLE)));
1131     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1132     return E_SUCCESS;
1133 }
1134 
GetSystemAlbumPredicates(const PhotoAlbumSubType subType,DataSharePredicates & predicates,const bool hiddenOnly)1135 int32_t MediaLibraryNapiUtils::GetSystemAlbumPredicates(const PhotoAlbumSubType subType,
1136     DataSharePredicates &predicates, const bool hiddenOnly)
1137 {
1138     switch (subType) {
1139         case PhotoAlbumSubType::FAVORITE: {
1140             return GetFavoritePredicates(predicates, hiddenOnly);
1141         }
1142         case PhotoAlbumSubType::VIDEO: {
1143             return GetVideoPredicates(predicates, hiddenOnly);
1144         }
1145         case PhotoAlbumSubType::HIDDEN: {
1146             return GetHiddenPredicates(predicates);
1147         }
1148         case PhotoAlbumSubType::TRASH: {
1149             return GetTrashPredicates(predicates);
1150         }
1151         case PhotoAlbumSubType::SCREENSHOT: {
1152             return GetScreenshotPredicates(predicates, hiddenOnly);
1153         }
1154         case PhotoAlbumSubType::CAMERA: {
1155             return GetCameraPredicates(predicates, hiddenOnly);
1156         }
1157         case PhotoAlbumSubType::IMAGE: {
1158             return GetAllImagesPredicates(predicates, hiddenOnly);
1159         }
1160         case PhotoAlbumSubType::CLOUD_ENHANCEMENT: {
1161             return GetCloudEnhancementPredicates(predicates, hiddenOnly);
1162         }
1163         default: {
1164             NAPI_ERR_LOG("Unsupported photo album subtype: %{public}d", subType);
1165             return E_INVALID_ARGUMENTS;
1166         }
1167     }
1168 }
1169 
ParseResultSet2JsonStr(shared_ptr<DataShare::DataShareResultSet> resultSet,const std::vector<std::string> & columns)1170 string MediaLibraryNapiUtils::ParseResultSet2JsonStr(shared_ptr<DataShare::DataShareResultSet> resultSet,
1171     const std::vector<std::string> &columns)
1172 {
1173     json jsonArray = json::array();
1174     if (resultSet == nullptr) {
1175         return jsonArray.dump();
1176     }
1177     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
1178         json jsonObject;
1179         for (uint32_t i = 0; i < columns.size(); i++) {
1180             string columnName = columns[i];
1181             jsonObject[columnName] = GetStringValueByColumn(resultSet, columnName);
1182         }
1183         jsonArray.push_back(jsonObject);
1184     }
1185     return jsonArray.dump();
1186 }
1187 
ParseAnalysisFace2JsonStr(shared_ptr<DataShare::DataShareResultSet> resultSet,const vector<string> & columns)1188 string MediaLibraryNapiUtils::ParseAnalysisFace2JsonStr(shared_ptr<DataShare::DataShareResultSet> resultSet,
1189     const vector<string> &columns)
1190 {
1191     json jsonArray = json::array();
1192     if (resultSet == nullptr) {
1193         return jsonArray.dump();
1194     }
1195 
1196     Uri uri(PAH_QUERY_ANA_PHOTO_ALBUM);
1197     DataShare::DataSharePredicates predicates;
1198     predicates.EqualTo(ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::PORTRAIT))->And()->IsNotNull(TAG_ID);
1199     vector<string> albumColumns = { ALBUM_ID, TAG_ID };
1200     int errCode = 0;
1201     shared_ptr<DataShare::DataShareResultSet> albumSet = UserFileClient::Query(uri, predicates, albumColumns, errCode);
1202 
1203     unordered_map<string, string> tagIdToAlbumIdMap;
1204     if (albumSet != nullptr) {
1205         while (albumSet->GoToNextRow() == NativeRdb::E_OK) {
1206             tagIdToAlbumIdMap[GetStringValueByColumn(albumSet, TAG_ID)] = GetStringValueByColumn(albumSet, ALBUM_ID);
1207         }
1208     }
1209 
1210     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
1211         json jsonObject;
1212         for (uint32_t i = 0; i < columns.size(); i++) {
1213             string columnName = columns[i];
1214             string columnValue = GetStringValueByColumn(resultSet, columnName);
1215             jsonObject[columnName] = columnValue;
1216             if (columnName == TAG_ID) {
1217                 jsonObject[ALBUM_URI] = PhotoAlbumColumns::ANALYSIS_ALBUM_URI_PREFIX + tagIdToAlbumIdMap[columnValue];
1218             }
1219         }
1220         jsonArray.push_back(jsonObject);
1221     }
1222 
1223     return jsonArray.dump();
1224 }
1225 
GetStringValueByColumn(shared_ptr<DataShare::DataShareResultSet> resultSet,const std::string columnName)1226 string MediaLibraryNapiUtils::GetStringValueByColumn(shared_ptr<DataShare::DataShareResultSet> resultSet,
1227     const std::string columnName)
1228 {
1229     int index;
1230     DataShare::DataType dataType;
1231     if (resultSet->GetColumnIndex(columnName, index) || resultSet->GetDataType(index, dataType)) {
1232         return EMPTY_STRING;
1233     }
1234     switch (dataType) {
1235         case DataShare::DataType::TYPE_INTEGER: {
1236             int64_t intValue = -1;
1237             if (resultSet->GetLong(index, intValue) == NativeRdb::E_OK) {
1238                 return to_string(intValue);
1239             }
1240             break;
1241         }
1242         case DataShare::DataType::TYPE_FLOAT: {
1243             double douValue = 0.0;
1244             if (resultSet->GetDouble(index, douValue) == NativeRdb::E_OK) {
1245                 return to_string(douValue);
1246             }
1247             break;
1248         }
1249         case DataShare::DataType::TYPE_STRING: {
1250             std::string strValue;
1251             if (resultSet->GetString(index, strValue) == NativeRdb::E_OK) {
1252                 return strValue;
1253             }
1254             break;
1255         }
1256         case DataShare::DataType::TYPE_BLOB: {
1257             std::vector<uint8_t> blobValue;
1258             if (resultSet->GetBlob(index, blobValue) == NativeRdb::E_OK) {
1259                 std::string tempValue(blobValue.begin(), blobValue.end());
1260                 return tempValue;
1261             }
1262             break;
1263         }
1264         default: {
1265             break;
1266         }
1267     }
1268     return EMPTY_STRING;
1269 }
1270 
TransferUri(const string & oldUri)1271 string MediaLibraryNapiUtils::TransferUri(const string &oldUri)
1272 {
1273     MediaFileUri fileUri(oldUri);
1274     if (fileUri.IsApi10()) {
1275         return oldUri;
1276     }
1277     string fileId = fileUri.GetFileId();
1278     if (fileId.empty()) {
1279         return oldUri;
1280     }
1281     vector<string> columns = {
1282         PhotoColumn::MEDIA_FILE_PATH,
1283         PhotoColumn::MEDIA_NAME
1284     };
1285     string queryUri = MEDIALIBRARY_DATA_URI;
1286     DataShare::DataSharePredicates predicates;
1287     predicates.EqualTo(PhotoColumn::MEDIA_ID, fileId);
1288     Uri uri(queryUri);
1289     int errCode = 0;
1290     shared_ptr<DataShare::DataShareResultSet> resultSet = UserFileClient::Query(uri,
1291         predicates, columns, errCode);
1292     if (resultSet->GoToFirstRow() != NativeRdb::E_OK) {
1293         NAPI_ERR_LOG("Fail to query file asset!");
1294         return oldUri;
1295     }
1296     string extrUri = MediaFileUtils::GetExtraUri(GetStringValueByColumn(resultSet, PhotoColumn::MEDIA_NAME),
1297         GetStringValueByColumn(resultSet, PhotoColumn::MEDIA_FILE_PATH), false);
1298     return MediaFileUri (fileUri.GetMediaTypeFromUri(oldUri), fileId, "",
1299         MEDIA_API_VERSION_V10, extrUri).ToString();
1300 }
1301 
GetStringFetchProperty(napi_env env,napi_value arg,bool & err,bool & present,const string & propertyName)1302 string MediaLibraryNapiUtils::GetStringFetchProperty(napi_env env, napi_value arg, bool &err, bool &present,
1303     const string &propertyName)
1304 {
1305     size_t res = 0;
1306     char buffer[PATH_MAX] = {0};
1307     napi_value property = nullptr;
1308     napi_has_named_property(env, arg, propertyName.c_str(), &present);
1309     if (present) {
1310         if ((napi_get_named_property(env, arg, propertyName.c_str(), &property) != napi_ok) ||
1311             (napi_get_value_string_utf8(env, property, buffer, PATH_MAX, &res) != napi_ok)) {
1312             NAPI_ERR_LOG("Could not get the string argument!");
1313             err = true;
1314             return "";
1315         } else {
1316             string str(buffer);
1317             present = false;
1318             return str;
1319         }
1320     }
1321     return "";
1322 }
1323 
CreateValueByIndex(napi_env env,int32_t index,string name,shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet,const shared_ptr<FileAsset> & asset)1324 napi_value MediaLibraryNapiUtils::CreateValueByIndex(napi_env env, int32_t index, string name,
1325     shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet, const shared_ptr<FileAsset> &asset)
1326 {
1327     int status;
1328     int integerVal = 0;
1329     string stringVal = "";
1330     int64_t longVal = 0;
1331     double doubleVal = 0.0;
1332     napi_value value = nullptr;
1333     auto dataType = MediaLibraryNapiUtils::GetTypeMap().at(name);
1334     switch (dataType.first) {
1335         case TYPE_STRING:
1336             status = resultSet->GetString(index, stringVal);
1337             napi_create_string_utf8(env, stringVal.c_str(), NAPI_AUTO_LENGTH, &value);
1338             asset->GetMemberMap().emplace(name, stringVal);
1339             break;
1340         case TYPE_INT32:
1341             status = resultSet->GetInt(index, integerVal);
1342             napi_create_int32(env, integerVal, &value);
1343             asset->GetMemberMap().emplace(name, integerVal);
1344             break;
1345         case TYPE_INT64:
1346             status = resultSet->GetLong(index, longVal);
1347             napi_create_int64(env, longVal, &value);
1348             asset->GetMemberMap().emplace(name, longVal);
1349             break;
1350         case TYPE_DOUBLE:
1351             status = resultSet->GetDouble(index, doubleVal);
1352             napi_create_double(env, doubleVal, &value);
1353             asset->GetMemberMap().emplace(name, doubleVal);
1354             break;
1355         default:
1356             NAPI_ERR_LOG("not match dataType %{public}d", dataType.first);
1357             break;
1358     }
1359 
1360     return value;
1361 }
1362 
handleTimeInfo(napi_env env,const std::string & name,napi_value result,int32_t index,const std::shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet)1363 void MediaLibraryNapiUtils::handleTimeInfo(napi_env env, const std::string& name, napi_value result, int32_t index,
1364     const std::shared_ptr<NativeRdb::AbsSharedResultSet>& resultSet)
1365 {
1366     if (TIME_COLUMN.count(name) == 0) {
1367         return;
1368     }
1369     int64_t longVal = 0;
1370     int status;
1371     napi_value value = nullptr;
1372     status = resultSet->GetLong(index, longVal);
1373     int64_t modifieldValue = longVal / 1000;
1374     napi_create_int64(env, modifieldValue, &value);
1375     auto dataType = MediaLibraryNapiUtils::GetTimeTypeMap().at(name);
1376     napi_set_named_property(env, result, dataType.second.c_str(), value);
1377 }
1378 
handleThumbnailReady(napi_env env,const std::string & name,napi_value result,int32_t index,const std::shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet)1379 static void handleThumbnailReady(napi_env env, const std::string& name, napi_value result, int32_t index,
1380     const std::shared_ptr<NativeRdb::AbsSharedResultSet>& resultSet)
1381 {
1382     if (name != "thumbnail_ready") {
1383         return;
1384     }
1385     int64_t longVal = 0;
1386     int status;
1387     napi_value value = nullptr;
1388     status = resultSet->GetLong(index, longVal);
1389     bool resultVal = longVal > 0;
1390     napi_create_int32(env, resultVal, &value);
1391     napi_set_named_property(env, result, "thumbnailReady", value);
1392 }
1393 
GetNextRowObject(napi_env env,shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet,bool isShared)1394 napi_value MediaLibraryNapiUtils::GetNextRowObject(napi_env env, shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet,
1395     bool isShared)
1396 {
1397     if (resultSet == nullptr) {
1398         NAPI_ERR_LOG("GetNextRowObject fail, result is nullptr");
1399         return nullptr;
1400     }
1401     vector<string> columnNames;
1402     resultSet->GetAllColumnNames(columnNames);
1403 
1404     napi_value result = nullptr;
1405     napi_create_object(env, &result);
1406 
1407     napi_value value = nullptr;
1408     int32_t index = -1;
1409     auto fileAsset = make_shared<FileAsset>();
1410     for (const auto &name : columnNames) {
1411         index++;
1412 
1413         // Check if the column name exists in the type map
1414         if (MediaLibraryNapiUtils::GetTypeMap().count(name) == 0) {
1415             continue;
1416         }
1417         value = MediaLibraryNapiUtils::CreateValueByIndex(env, index, name, resultSet, fileAsset);
1418         auto dataType = MediaLibraryNapiUtils::GetTypeMap().at(name);
1419         std::string tmpName = isShared ? dataType.second : name;
1420         napi_set_named_property(env, result, tmpName.c_str(), value);
1421         if (!isShared) {
1422             continue;
1423         }
1424         handleTimeInfo(env, name, result, index, resultSet);
1425         handleThumbnailReady(env, name, result, index, resultSet);
1426     }
1427     string extrUri = MediaFileUtils::GetExtraUri(fileAsset->GetDisplayName(), fileAsset->GetPath(), false);
1428     MediaFileUri fileUri(fileAsset->GetMediaType(), to_string(fileAsset->GetId()), "", MEDIA_API_VERSION_V10, extrUri);
1429     fileAsset->SetUri(move(fileUri.ToString()));
1430     napi_create_string_utf8(env, fileAsset->GetUri().c_str(), NAPI_AUTO_LENGTH, &value);
1431     napi_set_named_property(env, result, MEDIA_DATA_DB_URI.c_str(), value);
1432     return result;
1433 }
1434 
GetNextRowAlbumObject(napi_env env,shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet)1435 napi_value MediaLibraryNapiUtils::GetNextRowAlbumObject(napi_env env,
1436     shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet)
1437 {
1438     if (resultSet == nullptr) {
1439         NAPI_ERR_LOG("GetNextRowObject fail, result is nullptr");
1440         return nullptr;
1441     }
1442     vector<string> columnNames;
1443     resultSet->GetAllColumnNames(columnNames);
1444 
1445     napi_value result = nullptr;
1446     napi_create_object(env, &result);
1447 
1448     napi_value value = nullptr;
1449     int32_t index = -1;
1450     auto fileAsset = make_shared<FileAsset>();
1451     for (const auto &name : columnNames) {
1452         index++;
1453 
1454         // Check if the column name exists in the type map
1455         if (MediaLibraryNapiUtils::GetTypeMap().count(name) == 0) {
1456             continue;
1457         }
1458         value = MediaLibraryNapiUtils::CreateValueByIndex(env, index, name, resultSet, fileAsset);
1459         auto dataType = MediaLibraryNapiUtils::GetTypeMap().at(name);
1460         napi_set_named_property(env, result, dataType.second.c_str(), value);
1461     }
1462     return result;
1463 }
1464 
IsSystemApp()1465 bool MediaLibraryNapiUtils::IsSystemApp()
1466 {
1467     static bool isSys = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetSelfTokenID());
1468     return isSys;
1469 }
1470 
NapiScopeHandler(napi_env env)1471 NapiScopeHandler::NapiScopeHandler(napi_env env): env_(env)
1472 {
1473     napi_status status = napi_open_handle_scope(env_, &scope_);
1474     if (status != napi_ok) {
1475         NAPI_ERR_LOG("Open Handler scope failed, status %{public}d", status);
1476         isValid_ = false;
1477     } else {
1478         isValid_ = true;
1479     }
1480 }
1481 
~NapiScopeHandler()1482 NapiScopeHandler::~NapiScopeHandler()
1483 {
1484     if (isValid_) {
1485         napi_status status = napi_close_handle_scope(env_, scope_);
1486         if (status != napi_ok) {
1487             NAPI_ERR_LOG("Close Handler scope failed, status %{public}d", status);
1488         }
1489     }
1490 }
1491 
IsValid()1492 bool NapiScopeHandler::IsValid()
1493 {
1494     return isValid_;
1495 }
1496 
GetNapiValueArray(napi_env env,napi_value arg,vector<napi_value> & values)1497 napi_value MediaLibraryNapiUtils::GetNapiValueArray(napi_env env, napi_value arg, vector<napi_value> &values)
1498 {
1499     bool isArray = false;
1500     CHECK_ARGS(env, napi_is_array(env, arg, &isArray), OHOS_INVALID_PARAM_CODE);
1501     if (!isArray) {
1502         NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, "Failed to check array type");
1503         return nullptr;
1504     }
1505 
1506     uint32_t len = 0;
1507     CHECK_ARGS(env, napi_get_array_length(env, arg, &len), JS_INNER_FAIL);
1508     if (len == 0) {
1509         napi_value result = nullptr;
1510         CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
1511         return result;
1512     }
1513 
1514     for (uint32_t i = 0; i < len; i++) {
1515         napi_value value = nullptr;
1516         CHECK_ARGS(env, napi_get_element(env, arg, i, &value), JS_INNER_FAIL);
1517         if (value == nullptr) {
1518             NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, "Failed to get element");
1519             return nullptr;
1520         }
1521         values.push_back(value);
1522     }
1523 
1524     napi_value result = nullptr;
1525     CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
1526     return result;
1527 }
1528 
GetStringArray(napi_env env,vector<napi_value> & napiValues,vector<string> & values)1529 napi_value MediaLibraryNapiUtils::GetStringArray(napi_env env, vector<napi_value> &napiValues, vector<string> &values)
1530 {
1531     napi_valuetype valueType = napi_undefined;
1532     unique_ptr<char[]> buffer = make_unique<char[]>(PATH_MAX);
1533     for (const auto &napiValue : napiValues) {
1534         CHECK_ARGS(env, napi_typeof(env, napiValue, &valueType), JS_ERR_PARAMETER_INVALID);
1535         CHECK_COND(env, valueType == napi_string, JS_ERR_PARAMETER_INVALID);
1536 
1537         size_t res = 0;
1538         CHECK_ARGS(
1539             env, napi_get_value_string_utf8(env, napiValue, buffer.get(), PATH_MAX, &res), JS_ERR_PARAMETER_INVALID);
1540         values.emplace_back(buffer.get());
1541     }
1542     napi_value ret = nullptr;
1543     CHECK_ARGS(env, napi_get_boolean(env, true, &ret), JS_INNER_FAIL);
1544     return ret;
1545 }
1546 
GetUriFromAsset(const FileAssetNapi * obj)1547 std::string GetUriFromAsset(const FileAssetNapi *obj)
1548 {
1549     string displayName = obj->GetFileDisplayName();
1550     string filePath = obj->GetFilePath();
1551     return MediaFileUtils::GetUriByExtrConditions(PhotoColumn::PHOTO_URI_PREFIX, to_string(obj->GetFileId()),
1552         MediaFileUtils::GetExtraUri(displayName, filePath));
1553 }
1554 
GetUriArrayFromAssets(napi_env env,vector<napi_value> & napiValues,vector<string> & values)1555 napi_value MediaLibraryNapiUtils::GetUriArrayFromAssets(
1556     napi_env env, vector<napi_value> &napiValues, vector<string> &values)
1557 {
1558     FileAssetNapi *obj = nullptr;
1559     for (const auto &napiValue : napiValues) {
1560         CHECK_ARGS(env, napi_unwrap(env, napiValue, reinterpret_cast<void **>(&obj)), JS_INNER_FAIL);
1561         if (obj == nullptr) {
1562             NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID, "Failed to get asset napi object");
1563             return nullptr;
1564         }
1565         if ((obj->GetMediaType() != MEDIA_TYPE_IMAGE && obj->GetMediaType() != MEDIA_TYPE_VIDEO)) {
1566             NAPI_INFO_LOG("Skip invalid asset, mediaType: %{public}d", obj->GetMediaType());
1567             continue;
1568         }
1569         values.push_back(GetUriFromAsset(obj));
1570     }
1571     napi_value ret = nullptr;
1572     CHECK_ARGS(env, napi_get_boolean(env, true, &ret), JS_INNER_FAIL);
1573     return ret;
1574 }
1575 
FixSpecialDateType(string & selections)1576 void MediaLibraryNapiUtils::FixSpecialDateType(string &selections)
1577 {
1578     vector<string> dateTypes = { MEDIA_DATA_DB_DATE_ADDED, MEDIA_DATA_DB_DATE_TRASHED, MEDIA_DATA_DB_DATE_MODIFIED,
1579         MEDIA_DATA_DB_DATE_TAKEN };
1580     for (string dateType : dateTypes) {
1581         string date2Second = dateType + "_s";
1582         auto pos = selections.find(dateType);
1583         while (pos != string::npos) {
1584             selections.replace(pos, dateType.length(), date2Second);
1585             pos = selections.find(dateType, pos + date2Second.length());
1586         }
1587     }
1588 }
1589 
1590 template <class AsyncContext>
ParsePredicates(napi_env env,const napi_value arg,AsyncContext & context,const FetchOptionType & fetchOptType)1591 napi_status MediaLibraryNapiUtils::ParsePredicates(napi_env env, const napi_value arg,
1592     AsyncContext &context, const FetchOptionType &fetchOptType)
1593 {
1594     JSProxy::JSProxy<DataShareAbsPredicates> *jsProxy = nullptr;
1595     napi_unwrap(env, arg, reinterpret_cast<void **>(&jsProxy));
1596     if (jsProxy == nullptr) {
1597         NAPI_ERR_LOG("jsProxy is invalid");
1598         return napi_invalid_arg;
1599     }
1600     shared_ptr<DataShareAbsPredicates> predicate = jsProxy->GetInstance();
1601     CHECK_COND_RET(HandleSpecialPredicate(context, predicate, fetchOptType) == TRUE,
1602         napi_invalid_arg, "invalid predicate");
1603     CHECK_COND_RET(GetLocationPredicate(context, predicate) == TRUE, napi_invalid_arg, "invalid predicate");
1604     return napi_ok;
1605 }
1606 
1607 template bool MediaLibraryNapiUtils::HandleSpecialPredicate<unique_ptr<MediaLibraryAsyncContext>>(
1608     unique_ptr<MediaLibraryAsyncContext> &context, shared_ptr<DataShareAbsPredicates> &predicate,
1609     const FetchOptionType &fetchOptType);
1610 
1611 template bool MediaLibraryNapiUtils::HandleSpecialPredicate<unique_ptr<AlbumNapiAsyncContext>>(
1612     unique_ptr<AlbumNapiAsyncContext> &context, shared_ptr<DataShareAbsPredicates> &predicate,
1613     const FetchOptionType &fetchOptType);
1614 
1615 template bool MediaLibraryNapiUtils::HandleSpecialPredicate<unique_ptr<SmartAlbumNapiAsyncContext>>(
1616     unique_ptr<SmartAlbumNapiAsyncContext> &context, shared_ptr<DataShareAbsPredicates> &predicate,
1617     const FetchOptionType &fetchOptType);
1618 
1619 template bool MediaLibraryNapiUtils::GetLocationPredicate<unique_ptr<MediaLibraryAsyncContext>>(
1620     unique_ptr<MediaLibraryAsyncContext> &context, shared_ptr<DataShareAbsPredicates> &predicate);
1621 
1622 template bool MediaLibraryNapiUtils::GetLocationPredicate<unique_ptr<AlbumNapiAsyncContext>>(
1623     unique_ptr<AlbumNapiAsyncContext> &context, shared_ptr<DataShareAbsPredicates> &predicate);
1624 
1625 template bool MediaLibraryNapiUtils::GetLocationPredicate<unique_ptr<SmartAlbumNapiAsyncContext>>(
1626     unique_ptr<SmartAlbumNapiAsyncContext> &context, shared_ptr<DataShareAbsPredicates> &predicate);
1627 
1628 template napi_status MediaLibraryNapiUtils::GetFetchOption<unique_ptr<MediaLibraryAsyncContext>>(napi_env env,
1629     napi_value arg, const FetchOptionType &fetchOptType, unique_ptr<MediaLibraryAsyncContext> &context);
1630 
1631 template napi_status MediaLibraryNapiUtils::GetFetchOption<unique_ptr<PhotoAlbumNapiAsyncContext>>(napi_env env,
1632     napi_value arg, const FetchOptionType &fetchOptType, unique_ptr<PhotoAlbumNapiAsyncContext> &context);
1633 
1634 template napi_status MediaLibraryNapiUtils::GetAlbumFetchOption<unique_ptr<MediaLibraryAsyncContext>>(napi_env env,
1635     napi_value arg, const FetchOptionType &fetchOptType, unique_ptr<MediaLibraryAsyncContext> &context);
1636 
1637 template napi_status MediaLibraryNapiUtils::GetAlbumFetchOption<unique_ptr<PhotoAlbumNapiAsyncContext>>(napi_env env,
1638     napi_value arg, const FetchOptionType &fetchOptType, unique_ptr<PhotoAlbumNapiAsyncContext> &context);
1639 
1640 template napi_status MediaLibraryNapiUtils::GetPredicate<unique_ptr<MediaLibraryAsyncContext>>(napi_env env,
1641     const napi_value arg, const string &propName, unique_ptr<MediaLibraryAsyncContext> &context,
1642     const FetchOptionType &fetchOptType);
1643 
1644 template napi_status MediaLibraryNapiUtils::GetPredicate<unique_ptr<AlbumNapiAsyncContext>>(napi_env env,
1645     const napi_value arg, const string &propName, unique_ptr<AlbumNapiAsyncContext> &context,
1646     const FetchOptionType &fetchOptType);
1647 
1648 template napi_status MediaLibraryNapiUtils::GetPredicate<unique_ptr<SmartAlbumNapiAsyncContext>>(napi_env env,
1649     const napi_value arg, const string &propName, unique_ptr<SmartAlbumNapiAsyncContext> &context,
1650     const FetchOptionType &fetchOptType);
1651 
1652 template napi_status MediaLibraryNapiUtils::ParseAssetFetchOptCallback<unique_ptr<MediaLibraryAsyncContext>>(
1653     napi_env env, napi_callback_info info, unique_ptr<MediaLibraryAsyncContext> &context);
1654 
1655 template napi_status MediaLibraryNapiUtils::ParseAssetFetchOptCallback<unique_ptr<AlbumNapiAsyncContext>>(
1656     napi_env env, napi_callback_info info, unique_ptr<AlbumNapiAsyncContext> &context);
1657 
1658 template napi_status MediaLibraryNapiUtils::ParseAssetFetchOptCallback<unique_ptr<SmartAlbumNapiAsyncContext>>(
1659     napi_env env, napi_callback_info info, unique_ptr<SmartAlbumNapiAsyncContext> &context);
1660 
1661 template napi_status MediaLibraryNapiUtils::ParseAlbumFetchOptCallback<unique_ptr<MediaLibraryAsyncContext>>(
1662     napi_env env, napi_callback_info info, unique_ptr<MediaLibraryAsyncContext> &context);
1663 
1664 template void MediaLibraryNapiUtils::UpdateMediaTypeSelections<SmartAlbumNapiAsyncContext>(
1665     SmartAlbumNapiAsyncContext *context);
1666 
1667 template void MediaLibraryNapiUtils::UpdateMediaTypeSelections<AlbumNapiAsyncContext>(
1668     AlbumNapiAsyncContext *context);
1669 
1670 template void MediaLibraryNapiUtils::UpdateMediaTypeSelections<MediaLibraryAsyncContext>(
1671     MediaLibraryAsyncContext *context);
1672 
1673 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<FileAssetAsyncContext>>(
1674     napi_env env, napi_callback_info info, unique_ptr<FileAssetAsyncContext> &context, string &param);
1675 
1676 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<MediaLibraryAsyncContext>>(
1677     napi_env env, napi_callback_info info, unique_ptr<MediaLibraryAsyncContext> &context, string &param);
1678 
1679 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<SmartAlbumNapiAsyncContext>>(
1680     napi_env env, napi_callback_info info, unique_ptr<SmartAlbumNapiAsyncContext> &context, string &param);
1681 
1682 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<PhotoAlbumNapiAsyncContext>>(
1683     napi_env env, napi_callback_info info, unique_ptr<PhotoAlbumNapiAsyncContext> &context, string &param);
1684 
1685 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<MediaAssetChangeRequestAsyncContext>>(
1686     napi_env env, napi_callback_info info, unique_ptr<MediaAssetChangeRequestAsyncContext> &context, string &param);
1687 
1688 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<MediaAssetsChangeRequestAsyncContext>>(
1689     napi_env env, napi_callback_info info, unique_ptr<MediaAssetsChangeRequestAsyncContext> &context, string &param);
1690 
1691 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<MediaAlbumChangeRequestAsyncContext>>(
1692     napi_env env, napi_callback_info info, unique_ptr<MediaAlbumChangeRequestAsyncContext> &context, string &param);
1693 
1694 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<HighlightAlbumNapiAsyncContext>>(
1695     napi_env env, napi_callback_info info, unique_ptr<HighlightAlbumNapiAsyncContext> &context, string &param);
1696 
1697 template napi_status MediaLibraryNapiUtils::ParseArgsStringArrayCallback<unique_ptr<MediaLibraryAsyncContext>>(
1698     napi_env env, napi_callback_info info, unique_ptr<MediaLibraryAsyncContext> &context, vector<string> &array);
1699 
1700 template napi_status MediaLibraryNapiUtils::GetParamCallback<unique_ptr<PhotoAlbumNapiAsyncContext>>(napi_env env,
1701     unique_ptr<PhotoAlbumNapiAsyncContext> &context);
1702 
1703 template napi_status MediaLibraryNapiUtils::GetParamCallback<unique_ptr<SmartAlbumNapiAsyncContext>>(napi_env env,
1704     unique_ptr<SmartAlbumNapiAsyncContext> &context);
1705 
1706 template napi_status MediaLibraryNapiUtils::GetParamCallback<unique_ptr<MediaLibraryInitContext>>(napi_env env,
1707     unique_ptr<MediaLibraryInitContext> &context);
1708 
1709 template napi_status MediaLibraryNapiUtils::ParseArgsBoolCallBack<unique_ptr<MediaLibraryAsyncContext>>(napi_env env,
1710     napi_callback_info info, unique_ptr<MediaLibraryAsyncContext> &context, bool &param);
1711 
1712 template napi_status MediaLibraryNapiUtils::ParseArgsBoolCallBack<unique_ptr<FileAssetAsyncContext>>(napi_env env,
1713     napi_callback_info info, unique_ptr<FileAssetAsyncContext> &context, bool &param);
1714 
1715 template napi_status MediaLibraryNapiUtils::ParseArgsBoolCallBack<unique_ptr<MediaAssetChangeRequestAsyncContext>>(
1716     napi_env env, napi_callback_info info, unique_ptr<MediaAssetChangeRequestAsyncContext> &context, bool &param);
1717 
1718 template napi_status MediaLibraryNapiUtils::ParseArgsBoolCallBack<unique_ptr<MediaAssetsChangeRequestAsyncContext>>(
1719     napi_env env, napi_callback_info info, unique_ptr<MediaAssetsChangeRequestAsyncContext> &context, bool &param);
1720 
1721 template napi_status MediaLibraryNapiUtils::AsyncContextSetObjectInfo<unique_ptr<PhotoAlbumNapiAsyncContext>>(
1722     napi_env env, napi_callback_info info, unique_ptr<PhotoAlbumNapiAsyncContext> &asyncContext, const size_t minArgs,
1723     const size_t maxArgs);
1724 
1725 template napi_status MediaLibraryNapiUtils::AsyncContextSetObjectInfo<unique_ptr<SmartAlbumNapiAsyncContext>>(
1726     napi_env env, napi_callback_info info, unique_ptr<SmartAlbumNapiAsyncContext> &asyncContext, const size_t minArgs,
1727     const size_t maxArgs);
1728 
1729 template napi_status MediaLibraryNapiUtils::AsyncContextGetArgs<unique_ptr<MediaAssetChangeRequestAsyncContext>>(
1730     napi_env env, napi_callback_info info, unique_ptr<MediaAssetChangeRequestAsyncContext>& asyncContext,
1731     const size_t minArgs, const size_t maxArgs);
1732 
1733 template napi_status MediaLibraryNapiUtils::AsyncContextGetArgs<unique_ptr<MediaAssetsChangeRequestAsyncContext>>(
1734     napi_env env, napi_callback_info info, unique_ptr<MediaAssetsChangeRequestAsyncContext>& asyncContext,
1735     const size_t minArgs, const size_t maxArgs);
1736 
1737 template napi_status MediaLibraryNapiUtils::AsyncContextGetArgs<unique_ptr<MediaAlbumChangeRequestAsyncContext>>(
1738     napi_env env, napi_callback_info info, unique_ptr<MediaAlbumChangeRequestAsyncContext>& asyncContext,
1739     const size_t minArgs, const size_t maxArgs);
1740 
1741 template napi_status MediaLibraryNapiUtils::AsyncContextGetArgs<unique_ptr<CloudEnhancementAsyncContext>>(
1742     napi_env env, napi_callback_info info, unique_ptr<CloudEnhancementAsyncContext>& asyncContext,
1743     const size_t minArgs, const size_t maxArgs);
1744 
1745 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<MediaLibraryAsyncContext>(napi_env env,
1746     unique_ptr<MediaLibraryAsyncContext> &asyncContext, const string &resourceName,
1747     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1748 
1749 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<FileAssetAsyncContext>(napi_env env,
1750     unique_ptr<FileAssetAsyncContext> &asyncContext, const string &resourceName,
1751     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1752 
1753 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<AlbumNapiAsyncContext>(napi_env env,
1754     unique_ptr<AlbumNapiAsyncContext> &asyncContext, const string &resourceName,
1755     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1756 
1757 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<PhotoAlbumNapiAsyncContext>(napi_env env,
1758     unique_ptr<PhotoAlbumNapiAsyncContext> &asyncContext, const string &resourceName,
1759     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1760 
1761 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<SmartAlbumNapiAsyncContext>(napi_env env,
1762     unique_ptr<SmartAlbumNapiAsyncContext> &asyncContext, const string &resourceName,
1763     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1764 
1765 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<MediaLibraryInitContext>(napi_env env,
1766     unique_ptr<MediaLibraryInitContext> &asyncContext, const string &resourceName,
1767     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1768 
1769 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<MediaAssetChangeRequestAsyncContext>(napi_env env,
1770     unique_ptr<MediaAssetChangeRequestAsyncContext> &asyncContext, const string &resourceName,
1771     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1772 
1773 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<MediaAssetsChangeRequestAsyncContext>(napi_env env,
1774     unique_ptr<MediaAssetsChangeRequestAsyncContext> &asyncContext, const string &resourceName,
1775     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1776 
1777 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<MediaAlbumChangeRequestAsyncContext>(napi_env env,
1778     unique_ptr<MediaAlbumChangeRequestAsyncContext> &asyncContext, const string &resourceName,
1779     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1780 
1781 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<HighlightAlbumNapiAsyncContext>(napi_env env,
1782     unique_ptr<HighlightAlbumNapiAsyncContext> &asyncContext, const string &resourceName,
1783     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1784 
1785 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<MovingPhotoAsyncContext>(napi_env env,
1786     unique_ptr<MovingPhotoAsyncContext> &asyncContext, const string &resourceName,
1787     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1788 
1789 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<MediaAssetManagerAsyncContext>(napi_env env,
1790     unique_ptr<MediaAssetManagerAsyncContext> &asyncContext, const string &resourceName,
1791     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1792 
1793 template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork<CloudEnhancementAsyncContext>(napi_env env,
1794     unique_ptr<CloudEnhancementAsyncContext> &asyncContext, const string &resourceName,
1795     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1796 
1797 template napi_status MediaLibraryNapiUtils::ParseArgsNumberCallback<unique_ptr<MediaLibraryAsyncContext>>(napi_env env,
1798     napi_callback_info info, unique_ptr<MediaLibraryAsyncContext> &context, int32_t &value);
1799 
1800 template napi_status MediaLibraryNapiUtils::ParseArgsNumberCallback<unique_ptr<FileAssetAsyncContext>>(napi_env env,
1801     napi_callback_info info, unique_ptr<FileAssetAsyncContext> &context, int32_t &value);
1802 
1803 template napi_status MediaLibraryNapiUtils::ParseArgsNumberCallback<unique_ptr<MediaAssetChangeRequestAsyncContext>>(
1804     napi_env env, napi_callback_info info, unique_ptr<MediaAssetChangeRequestAsyncContext> &context, int32_t &value);
1805 
1806 template napi_status MediaLibraryNapiUtils::ParseArgsNumberCallback<unique_ptr<MediaAlbumChangeRequestAsyncContext>>(
1807     napi_env env, napi_callback_info info, unique_ptr<MediaAlbumChangeRequestAsyncContext> &context, int32_t &value);
1808 
1809 template napi_status MediaLibraryNapiUtils::ParseArgsNumberCallback<unique_ptr<HighlightAlbumNapiAsyncContext>>(
1810     napi_env env, napi_callback_info info, unique_ptr<HighlightAlbumNapiAsyncContext> &context, int32_t &value);
1811 
1812 template napi_status MediaLibraryNapiUtils::ParseArgsOnlyCallBack<unique_ptr<MediaLibraryAsyncContext>>(napi_env env,
1813     napi_callback_info info, unique_ptr<MediaLibraryAsyncContext> &context);
1814 
1815 template napi_status MediaLibraryNapiUtils::ParseArgsOnlyCallBack<unique_ptr<FileAssetAsyncContext>>(napi_env env,
1816     napi_callback_info info, unique_ptr<FileAssetAsyncContext> &context);
1817 
1818 template napi_status MediaLibraryNapiUtils::ParseArgsOnlyCallBack<unique_ptr<AlbumNapiAsyncContext>>(napi_env env,
1819     napi_callback_info info, unique_ptr<AlbumNapiAsyncContext> &context);
1820 
1821 template napi_status MediaLibraryNapiUtils::ParsePredicates<unique_ptr<MediaLibraryAsyncContext>>(napi_env env,
1822     const napi_value arg, unique_ptr<MediaLibraryAsyncContext> &context, const FetchOptionType &fetchOptType);
1823 } // namespace Media
1824 } // namespace OHOS
1825