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