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 ¶m)
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 ¶m)
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 ¶m);
2418
2419 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<MediaLibraryAsyncContext>>(
2420 napi_env env, napi_callback_info info, unique_ptr<MediaLibraryAsyncContext> &context, string ¶m);
2421
2422 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<SmartAlbumNapiAsyncContext>>(
2423 napi_env env, napi_callback_info info, unique_ptr<SmartAlbumNapiAsyncContext> &context, string ¶m);
2424
2425 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<PhotoAlbumNapiAsyncContext>>(
2426 napi_env env, napi_callback_info info, unique_ptr<PhotoAlbumNapiAsyncContext> &context, string ¶m);
2427
2428 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<MediaAssetChangeRequestAsyncContext>>(
2429 napi_env env, napi_callback_info info, unique_ptr<MediaAssetChangeRequestAsyncContext> &context, string ¶m);
2430
2431 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<MediaAssetsChangeRequestAsyncContext>>(
2432 napi_env env, napi_callback_info info, unique_ptr<MediaAssetsChangeRequestAsyncContext> &context, string ¶m);
2433
2434 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<MediaAlbumChangeRequestAsyncContext>>(
2435 napi_env env, napi_callback_info info, unique_ptr<MediaAlbumChangeRequestAsyncContext> &context, string ¶m);
2436
2437 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<HighlightAlbumNapiAsyncContext>>(
2438 napi_env env, napi_callback_info info, unique_ptr<HighlightAlbumNapiAsyncContext> &context, string ¶m);
2439
2440 template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<ResultSetAsyncContext>>(
2441 napi_env env, napi_callback_info info, unique_ptr<ResultSetAsyncContext> &context, string ¶m);
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 ¶m);
2457
2458 template napi_status MediaLibraryNapiUtils::ParseArgsBoolCallBack<unique_ptr<FileAssetAsyncContext>>(napi_env env,
2459 napi_callback_info info, unique_ptr<FileAssetAsyncContext> &context, bool ¶m);
2460
2461 template napi_status MediaLibraryNapiUtils::ParseArgsBoolCallBack<unique_ptr<MediaAssetChangeRequestAsyncContext>>(
2462 napi_env env, napi_callback_info info, unique_ptr<MediaAssetChangeRequestAsyncContext> &context, bool ¶m);
2463
2464 template napi_status MediaLibraryNapiUtils::ParseArgsBoolCallBack<unique_ptr<MediaAssetsChangeRequestAsyncContext>>(
2465 napi_env env, napi_callback_info info, unique_ptr<MediaAssetsChangeRequestAsyncContext> &context, bool ¶m);
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