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