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