• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #define MLOG_TAG "SendableMediaLibraryNapiUtils"
16 
17 #include "sendable_medialibrary_napi_utils.h"
18 
19 #include "basic/result_set.h"
20 #include "datashare_predicates.h"
21 #include "location_column.h"
22 #include "ipc_skeleton.h"
23 #include "js_proxy.h"
24 #include "sendable_photo_album_napi.h"
25 #include "sendable_fetch_file_result_napi.h"
26 #include "sendable_photo_access_helper_napi.h"
27 #include "media_device_column.h"
28 #include "media_file_uri.h"
29 #include "media_file_utils.h"
30 #include "media_library_napi.h"
31 #include "medialibrary_client_errno.h"
32 #include "medialibrary_db_const.h"
33 #include "medialibrary_errno.h"
34 #include "medialibrary_napi_enum_comm.h"
35 #include "medialibrary_napi_utils.h"
36 #include "medialibrary_tracer.h"
37 #include "medialibrary_type_const.h"
38 #include "photo_album_napi.h"
39 #include "photo_map_column.h"
40 #include "smart_album_napi.h"
41 #include "tokenid_kit.h"
42 #include "userfile_client.h"
43 #include "vision_album_column.h"
44 #include "vision_column.h"
45 #include "vision_face_tag_column.h"
46 #include "vision_pose_column.h"
47 #include "vision_image_face_column.h"
48 #include "userfilemgr_uri.h"
49 #include "data_secondary_directory_uri.h"
50 
51 using namespace std;
52 using namespace OHOS::DataShare;
53 
54 namespace OHOS {
55 namespace Media {
56 static const string EMPTY_STRING = "";
57 using json = nlohmann::json;
58 using SendablePAHAsyncContext = SendablePhotoAccessHelperAsyncContext;
59 using SendablePANAsyncContext = SendablePhotoAlbumNapiAsyncContext;
60 using SendableFAAsyncContext = SendableFileAssetAsyncContext;
61 
GetUInt32(napi_env env,napi_value arg,uint32_t & value)62 napi_status SendableMediaLibraryNapiUtils::GetUInt32(napi_env env, napi_value arg, uint32_t &value)
63 {
64     napi_valuetype valueType = napi_undefined;
65     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
66     CHECK_COND_RET(valueType == napi_number, napi_number_expected, "Type is not as expected number");
67     CHECK_STATUS_RET(napi_get_value_uint32(env, arg, &value), "Failed to get uint32 value");
68     return napi_ok;
69 }
70 
GetInt32(napi_env env,napi_value arg,int32_t & value)71 napi_status SendableMediaLibraryNapiUtils::GetInt32(napi_env env, napi_value arg, int32_t &value)
72 {
73     napi_valuetype valueType = napi_undefined;
74     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
75     CHECK_COND_RET(valueType == napi_number, napi_number_expected, "Type is not as expected number");
76     CHECK_STATUS_RET(napi_get_value_int32(env, arg, &value), "Failed to get int32 value");
77     return napi_ok;
78 }
79 
GetParamBool(napi_env env,napi_value arg,bool & value)80 napi_status SendableMediaLibraryNapiUtils::GetParamBool(napi_env env, napi_value arg, bool &value)
81 {
82     napi_valuetype valueType = napi_undefined;
83     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
84     CHECK_COND_RET(valueType == napi_boolean, napi_boolean_expected, "Type is not as expected boolean");
85     CHECK_STATUS_RET(napi_get_value_bool(env, arg, &value), "Failed to get param");
86     return napi_ok;
87 }
88 
GetParamFunction(napi_env env,napi_value arg,napi_ref & callbackRef)89 napi_status SendableMediaLibraryNapiUtils::GetParamFunction(napi_env env, napi_value arg, napi_ref &callbackRef)
90 {
91     napi_valuetype valueType = napi_undefined;
92     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
93     CHECK_COND_RET(valueType == napi_function, napi_function_expected, "Type is not as expected function");
94     CHECK_STATUS_RET(napi_create_reference(env, arg, NAPI_INIT_REF_COUNT, &callbackRef), "Failed to make callbackref");
95     return napi_ok;
96 }
97 
GetParamStr(napi_env env,napi_value arg,const size_t size,string & result)98 static napi_status GetParamStr(napi_env env, napi_value arg, const size_t size, string &result)
99 {
100     size_t res = 0;
101     unique_ptr<char[]> buffer = make_unique<char[]>(size);
102     CHECK_COND_RET(buffer != nullptr, napi_invalid_arg, "Failed to alloc buffer for parameter");
103     napi_valuetype valueType = napi_undefined;
104     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
105     CHECK_COND_RET(valueType == napi_string, napi_string_expected, "Type is not as expected string");
106     CHECK_STATUS_RET(napi_get_value_string_utf8(env, arg, buffer.get(), size, &res), "Failed to get string value");
107     result = string(buffer.get());
108     return napi_ok;
109 }
110 
GetParamStringWithLength(napi_env env,napi_value arg,int32_t maxLen,string & result)111 napi_status SendableMediaLibraryNapiUtils::GetParamStringWithLength(napi_env env, napi_value arg, int32_t maxLen,
112     string &result)
113 {
114     CHECK_STATUS_RET(GetParamStr(env, arg, maxLen, result), "Failed to get string parameter");
115     return napi_ok;
116 }
117 
GetParamStringPathMax(napi_env env,napi_value arg,string & result)118 napi_status SendableMediaLibraryNapiUtils::GetParamStringPathMax(napi_env env, napi_value arg, string &result)
119 {
120     CHECK_STATUS_RET(GetParamStr(env, arg, PATH_MAX, result), "Failed to get string parameter");
121     return napi_ok;
122 }
123 
GetProperty(napi_env env,const napi_value arg,const string & propName,string & propValue)124 napi_status SendableMediaLibraryNapiUtils::GetProperty(napi_env env, const napi_value arg, const string &propName,
125     string &propValue)
126 {
127     bool present = false;
128     napi_value property = nullptr;
129     CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present),
130         "Failed to check property name");
131     if (present) {
132         CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property), "Failed to get property");
133         CHECK_STATUS_RET(GetParamStringPathMax(env, property, propValue), "Failed to get string buffer");
134     }
135     return napi_ok;
136 }
137 
GetStringArray(napi_env env,napi_value arg,vector<string> & array)138 napi_status SendableMediaLibraryNapiUtils::GetStringArray(napi_env env, napi_value arg, vector<string> &array)
139 {
140     bool isArray = false;
141     uint32_t len = 0;
142     CHECK_STATUS_RET(napi_is_array(env, arg, &isArray), "Failed to check array type");
143     CHECK_COND_RET(isArray, napi_array_expected, "Expected array type");
144     CHECK_STATUS_RET(napi_get_array_length(env, arg, &len), "Failed to get array length");
145     for (uint32_t i = 0; i < len; i++) {
146         napi_value item = nullptr;
147         string val;
148         CHECK_STATUS_RET(napi_get_element(env, arg, i, &item), "Failed to get array item");
149         CHECK_STATUS_RET(GetParamStringPathMax(env, item, val), "Failed to get string buffer");
150         array.push_back(val);
151     }
152     return napi_ok;
153 }
154 
GetArrayProperty(napi_env env,napi_value arg,const string & propName,vector<string> & array)155 napi_status SendableMediaLibraryNapiUtils::GetArrayProperty(napi_env env, napi_value arg, const string &propName,
156     vector<string> &array)
157 {
158     bool present = false;
159     CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present), "Failed to check property name");
160     if (present) {
161         napi_value property = nullptr;
162         CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property),
163             "Failed to get selectionArgs property");
164         GetStringArray(env, property, array);
165     }
166     return napi_ok;
167 }
168 
HasCallback(napi_env env,const size_t argc,const napi_value argv[],bool & isCallback)169 napi_status SendableMediaLibraryNapiUtils::HasCallback(napi_env env, const size_t argc, const napi_value argv[],
170     bool &isCallback)
171 {
172     isCallback = false;
173     if (argc < ARGS_ONE) {
174         return napi_ok;
175     }
176     napi_valuetype valueType = napi_undefined;
177     CHECK_STATUS_RET(napi_typeof(env, argv[argc - 1], &valueType), "Failed to get type");
178     isCallback = (valueType == napi_function);
179     return napi_ok;
180 }
181 
hasFetchOpt(napi_env env,const napi_value arg,bool & hasFetchOpt)182 napi_status SendableMediaLibraryNapiUtils::hasFetchOpt(napi_env env, const napi_value arg, bool &hasFetchOpt)
183 {
184     hasFetchOpt = false;
185     napi_valuetype valueType = napi_undefined;
186     CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
187     if (valueType != napi_object) {
188         hasFetchOpt = false;
189         return napi_ok;
190     }
191     CHECK_STATUS_RET(napi_has_named_property(env, arg, "selections", &hasFetchOpt),
192         "Failed to get property selections");
193     return napi_ok;
194 }
195 
GetMediaTypeFromUri(const string & uri)196 MediaType SendableMediaLibraryNapiUtils::GetMediaTypeFromUri(const string &uri)
197 {
198     if (uri.find(MEDIALIBRARY_IMAGE_URI) != string::npos) {
199         return MediaType::MEDIA_TYPE_IMAGE;
200     } else if (uri.find(MEDIALIBRARY_VIDEO_URI) != string::npos) {
201         return MediaType::MEDIA_TYPE_VIDEO;
202     } else if (uri.find(MEDIALIBRARY_AUDIO_URI) != string::npos) {
203         return MediaType::MEDIA_TYPE_AUDIO;
204     } else if (uri.find(MEDIALIBRARY_FILE_URI) != string::npos) {
205         return MediaType::MEDIA_TYPE_FILE;
206     }
207     return MediaType::MEDIA_TYPE_ALL;
208 }
209 
HandleSpecialDateTypePredicate(const OperationItem & item,vector<OperationItem> & operations,const FetchOptionType & fetchOptType)210 static bool HandleSpecialDateTypePredicate(const OperationItem &item,
211     vector<OperationItem> &operations, const FetchOptionType &fetchOptType)
212 {
213     constexpr int32_t FIELD_IDX = 0;
214     constexpr int32_t VALUE_IDX = 1;
215     vector<string>dateTypes = { MEDIA_DATA_DB_DATE_ADDED, MEDIA_DATA_DB_DATE_TRASHED, MEDIA_DATA_DB_DATE_MODIFIED,
216         MEDIA_DATA_DB_DATE_TAKEN };
217     string dateType = item.GetSingle(FIELD_IDX);
218     auto it = find(dateTypes.begin(), dateTypes.end(), dateType);
219     if (it != dateTypes.end() && item.operation != DataShare::ORDER_BY_ASC &&
220         item.operation != DataShare::ORDER_BY_DESC) {
221         dateType += "_s";
222         operations.push_back({ item.operation, { dateType, static_cast<double>(item.GetSingle(VALUE_IDX)) } });
223         return true;
224     }
225     if (DATE_TRANSITION_MAP.count(dateType) != 0) {
226         dateType = DATE_TRANSITION_MAP.at(dateType);
227         operations.push_back({ item.operation, { dateType, static_cast<double>(item.GetSingle(VALUE_IDX)) } });
228         return true;
229     }
230     return false;
231 }
232 
233 template <class AsyncContext>
HandleSpecialPredicate(AsyncContext & context,shared_ptr<DataShareAbsPredicates> & predicate,const FetchOptionType & fetchOptType,vector<OperationItem> operations)234 bool SendableMediaLibraryNapiUtils::HandleSpecialPredicate(AsyncContext &context,
235     shared_ptr<DataShareAbsPredicates> &predicate, const FetchOptionType &fetchOptType,
236     vector<OperationItem> operations)
237 {
238     constexpr int32_t FIELD_IDX = 0;
239     constexpr int32_t VALUE_IDX = 1;
240     auto &items = predicate->GetOperationList();
241     for (auto &item : items) {
242         if (item.singleParams.empty()) {
243             operations.push_back(item);
244             continue;
245         }
246         if (HandleSpecialDateTypePredicate(item, operations, fetchOptType)) {
247             continue;
248         }
249         // change uri ->file id
250         // get networkid
251         // replace networkid with file id
252         if (static_cast<string>(item.GetSingle(FIELD_IDX)) == DEVICE_DB_NETWORK_ID) {
253             if (item.operation != DataShare::EQUAL_TO || static_cast<string>(item.GetSingle(VALUE_IDX)).empty()) {
254                 NAPI_ERR_LOG("DEVICE_DB_NETWORK_ID predicates not support %{public}d", item.operation);
255                 return false;
256             }
257             context->networkId = static_cast<string>(item.GetSingle(VALUE_IDX));
258             continue;
259         }
260         if (static_cast<string>(item.GetSingle(FIELD_IDX)) == MEDIA_DATA_DB_URI) {
261             if (item.operation != DataShare::EQUAL_TO) {
262                 NAPI_ERR_LOG("MEDIA_DATA_DB_URI predicates not support %{public}d", item.operation);
263                 return false;
264             }
265             string uri = static_cast<string>(item.GetSingle(VALUE_IDX));
266             MediaFileUri::RemoveAllFragment(uri);
267             MediaFileUri fileUri(uri);
268             context->uri = uri;
269             if ((fetchOptType != ALBUM_FETCH_OPT) && (!fileUri.IsApi10())) {
270                 fileUri = MediaFileUri(MediaFileUtils::GetRealUriFromVirtualUri(uri));
271             }
272             context->networkId = fileUri.GetNetworkId();
273             string field = (fetchOptType == ALBUM_FETCH_OPT) ? PhotoAlbumColumns::ALBUM_ID : MEDIA_DATA_DB_ID;
274             operations.push_back({ item.operation, { field, fileUri.GetFileId() } });
275             continue;
276         }
277         if (static_cast<string>(item.GetSingle(FIELD_IDX)) == PENDING_STATUS) {
278             // do not query pending files below API11
279             continue;
280         }
281         if (LOCATION_PARAM_MAP.find(static_cast<string>(item.GetSingle(FIELD_IDX))) != LOCATION_PARAM_MAP.end()) {
282             continue;
283         }
284         operations.push_back(item);
285     }
286     context->predicates = DataSharePredicates(move(operations));
287     return true;
288 }
289 
290 template <class AsyncContext>
GetLocationPredicate(AsyncContext & context,shared_ptr<DataShareAbsPredicates> & predicate)291 bool SendableMediaLibraryNapiUtils::GetLocationPredicate(AsyncContext &context,
292     shared_ptr<DataShareAbsPredicates> &predicate)
293 {
294     constexpr int32_t FIELD_IDX = 0;
295     constexpr int32_t VALUE_IDX = 1;
296     map<string, string> locationMap;
297     auto &items = predicate->GetOperationList();
298     for (auto &item : items) {
299         if (item.singleParams.empty()) {
300             continue;
301         }
302         if (LOCATION_PARAM_MAP.find(static_cast<string>(item.GetSingle(FIELD_IDX))) != LOCATION_PARAM_MAP.end()) {
303             if (item.operation != DataShare::EQUAL_TO) {
304                 NAPI_ERR_LOG("location predicates not support %{public}d", item.operation);
305                 return false;
306             }
307             string param = static_cast<string>(item.GetSingle(FIELD_IDX));
308             string value = static_cast<string>(item.GetSingle(VALUE_IDX));
309             locationMap.insert(make_pair(param, value));
310             if (param == DIAMETER) {
311                 continue;
312             }
313             if (LOCATION_PARAM_MAP.at(param).second == DataShare::GREATER_THAN_OR_EQUAL_TO) {
314                 context->predicates.GreaterThanOrEqualTo(LOCATION_PARAM_MAP.at(param).first, value);
315                 continue;
316             }
317             if (LOCATION_PARAM_MAP.at(param).second == DataShare::LESS_THAN) {
318                 context->predicates.LessThan(LOCATION_PARAM_MAP.at(param).first, value);
319                 continue;
320             }
321             if (LOCATION_PARAM_MAP.at(param).second == DataShare::EQUAL_TO) {
322                 context->predicates.EqualTo(LOCATION_PARAM_MAP.at(param).first, value);
323                 continue;
324             }
325         }
326     }
327 
328     if (locationMap.count(DIAMETER) == 1 && locationMap.count(START_LATITUDE) == 1
329         && locationMap.count(START_LONGITUDE) == 1) {
330         // 0.5:Used for rounding down
331         string latitudeIndex = "round((latitude - " + locationMap.at(START_LATITUDE) + ") / " +
332             locationMap.at(DIAMETER) + " - 0.5)";
333         string longitudeIndex = "round((longitude - " + locationMap.at(START_LONGITUDE) + ") / " +
334             locationMap.at(DIAMETER) + " - 0.5)";
335         string albumName = LATITUDE + "||'_'||" + LONGITUDE + "||'_'||" + latitudeIndex + "||'_'||" +
336             longitudeIndex + " AS " + ALBUM_NAME;
337         context->fetchColumn.push_back(albumName);
338         string locationGroup = latitudeIndex + "," + longitudeIndex;
339         context->predicates.GroupBy({ locationGroup });
340     }
341     return true;
342 }
343 
344 template <class AsyncContext>
GetFetchOption(napi_env env,napi_value arg,const FetchOptionType & fetchOptType,AsyncContext & context,vector<OperationItem> operations)345 napi_status SendableMediaLibraryNapiUtils::GetFetchOption(napi_env env, napi_value arg,
346     const FetchOptionType &fetchOptType, AsyncContext &context, vector<OperationItem> operations)
347 {
348     // Parse the argument into fetchOption if any
349     CHECK_STATUS_RET(GetPredicate(env, arg, "predicates", context, fetchOptType, move(operations)),
350         "invalid predicate");
351     CHECK_STATUS_RET(GetArrayProperty(env, arg, "fetchColumns", context->fetchColumn),
352         "Failed to parse fetchColumn");
353     return napi_ok;
354 }
355 
356 template <class AsyncContext>
GetAlbumFetchOption(napi_env env,napi_value arg,const FetchOptionType & fetchOptType,AsyncContext & context)357 napi_status SendableMediaLibraryNapiUtils::GetAlbumFetchOption(napi_env env, napi_value arg,
358     const FetchOptionType &fetchOptType, AsyncContext &context)
359 {
360     // Parse the argument into AlbumFetchOption if any
361     CHECK_STATUS_RET(GetPredicate(env, arg, "predicates", context, fetchOptType), "invalid predicate");
362     return napi_ok;
363 }
364 
365 template <class AsyncContext>
GetPredicate(napi_env env,const napi_value arg,const string & propName,AsyncContext & context,const FetchOptionType & fetchOptType,vector<OperationItem> operations)366 napi_status SendableMediaLibraryNapiUtils::GetPredicate(napi_env env, const napi_value arg, const string &propName,
367     AsyncContext &context, const FetchOptionType &fetchOptType, vector<OperationItem> operations)
368 {
369     bool present = false;
370     napi_value property = nullptr;
371     CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present),
372         "Failed to check property name");
373     if (present) {
374         CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property), "Failed to get property");
375         JSProxy::JSProxy<DataShareAbsPredicates> *jsProxy = nullptr;
376         napi_unwrap(env, property, reinterpret_cast<void **>(&jsProxy));
377         if (jsProxy == nullptr) {
378             NAPI_ERR_LOG("jsProxy is invalid");
379             return napi_invalid_arg;
380         }
381         shared_ptr<DataShareAbsPredicates> predicate = jsProxy->GetInstance();
382         CHECK_COND_RET(HandleSpecialPredicate(context, predicate, fetchOptType, move(operations)) == TRUE,
383             napi_invalid_arg, "invalid predicate");
384         CHECK_COND_RET(GetLocationPredicate(context, predicate) == TRUE, napi_invalid_arg, "invalid predicate");
385     }
386     return napi_ok;
387 }
388 
389 template <class AsyncContext>
ParseAssetFetchOptCallback(napi_env env,napi_callback_info info,AsyncContext & context)390 napi_status SendableMediaLibraryNapiUtils::ParseAssetFetchOptCallback(napi_env env, napi_callback_info info,
391     AsyncContext &context)
392 {
393     constexpr size_t minArgs = ARGS_ONE;
394     constexpr size_t maxArgs = ARGS_TWO;
395     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
396         "Failed to get object info");
397     CHECK_STATUS_RET(GetFetchOption(env, context->argv[PARAM0], ASSET_FETCH_OPT, context),
398         "Failed to get fetch option");
399     return napi_ok;
400 }
401 
402 template <class AsyncContext>
ParseAlbumFetchOptCallback(napi_env env,napi_callback_info info,AsyncContext & context)403 napi_status SendableMediaLibraryNapiUtils::ParseAlbumFetchOptCallback(napi_env env, napi_callback_info info,
404     AsyncContext &context)
405 {
406     constexpr size_t minArgs = ARGS_ONE;
407     constexpr size_t maxArgs = ARGS_TWO;
408     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
409         "Failed to get object info");
410     // Parse the argument into fetchOption if any
411     CHECK_STATUS_RET(GetPredicate(env, context->argv[PARAM0], "predicates", context, ALBUM_FETCH_OPT),
412         "invalid predicate");
413     context->predicates.And()->NotEqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::HIDDEN));
414     return napi_ok;
415 }
416 
417 template <class AsyncContext>
UpdateMediaTypeSelections(AsyncContext * context)418 void SendableMediaLibraryNapiUtils::UpdateMediaTypeSelections(AsyncContext *context)
419 {
420     constexpr int FIRST_MEDIA_TYPE = 0;
421     constexpr int SECOND_MEDIA_TYPE = 1;
422     if ((context->mediaTypes.size() != ARGS_ONE) && (context->mediaTypes.size() != ARGS_TWO)) {
423         return;
424     }
425     DataShare::DataSharePredicates &predicates = context->predicates;
426     predicates.BeginWrap();
427     predicates.EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, (int)context->mediaTypes[FIRST_MEDIA_TYPE]);
428     if (context->mediaTypes.size() == ARGS_TWO) {
429         predicates.Or()->EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, (int)context->mediaTypes[SECOND_MEDIA_TYPE]);
430     }
431     predicates.EndWrap();
432 }
433 
434 template <class AsyncContext>
AsyncContextSetObjectInfo(napi_env env,napi_callback_info info,AsyncContext & asyncContext,const size_t minArgs,const size_t maxArgs)435 napi_status SendableMediaLibraryNapiUtils::AsyncContextSetObjectInfo(napi_env env, napi_callback_info info,
436     AsyncContext &asyncContext, const size_t minArgs, const size_t maxArgs)
437 {
438     napi_value thisVar = nullptr;
439     asyncContext->argc = maxArgs;
440     CHECK_STATUS_RET(napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), &thisVar,
441         nullptr), "Failed to get cb info");
442     CHECK_COND_RET(((asyncContext->argc >= minArgs) && (asyncContext->argc <= maxArgs)), napi_invalid_arg,
443         "Number of args is invalid");
444     if (minArgs > 0) {
445         CHECK_COND_RET(asyncContext->argv[ARGS_ZERO] != nullptr, napi_invalid_arg, "Argument list is empty");
446     }
447     CHECK_STATUS_RET(napi_unwrap_sendable(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo)),
448         "Failed to unwrap thisVar");
449     CHECK_COND_RET(asyncContext->objectInfo != nullptr, napi_invalid_arg, "Failed to get object info");
450     CHECK_STATUS_RET(GetParamCallback(env, asyncContext), "Failed to get callback param!");
451     return napi_ok;
452 }
453 
454 template <class AsyncContext>
AsyncContextGetArgs(napi_env env,napi_callback_info info,AsyncContext & asyncContext,const size_t minArgs,const size_t maxArgs)455 napi_status SendableMediaLibraryNapiUtils::AsyncContextGetArgs(napi_env env, napi_callback_info info,
456     AsyncContext &asyncContext, const size_t minArgs, const size_t maxArgs)
457 {
458     asyncContext->argc = maxArgs;
459     CHECK_STATUS_RET(napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), nullptr,
460         nullptr), "Failed to get cb info");
461     CHECK_COND_RET(asyncContext->argc >= minArgs && asyncContext->argc <= maxArgs, napi_invalid_arg,
462         "Number of args is invalid");
463     if (minArgs > 0) {
464         CHECK_COND_RET(asyncContext->argv[ARGS_ZERO] != nullptr, napi_invalid_arg, "Argument list is empty");
465     }
466     CHECK_STATUS_RET(GetParamCallback(env, asyncContext), "Failed to get callback param");
467     return napi_ok;
468 }
469 
470 template <class AsyncContext>
GetParamCallback(napi_env env,AsyncContext & context)471 napi_status SendableMediaLibraryNapiUtils::GetParamCallback(napi_env env, AsyncContext &context)
472 {
473     /* Parse the last argument into callbackref if any */
474     bool isCallback = false;
475     CHECK_STATUS_RET(HasCallback(env, context->argc, context->argv, isCallback), "Failed to check callback");
476     if (isCallback) {
477         CHECK_STATUS_RET(GetParamFunction(env, context->argv[context->argc - 1], context->callbackRef),
478             "Failed to get callback");
479     }
480     return napi_ok;
481 }
482 
483 template <class AsyncContext>
ParseArgsBoolCallBack(napi_env env,napi_callback_info info,AsyncContext & context,bool & param)484 napi_status SendableMediaLibraryNapiUtils::ParseArgsBoolCallBack(napi_env env, napi_callback_info info,
485     AsyncContext &context,
486     bool &param)
487 {
488     constexpr size_t minArgs = ARGS_ONE;
489     constexpr size_t maxArgs = ARGS_TWO;
490     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
491         "Failed to get object info");
492 
493     /* Parse the first argument into param */
494     CHECK_STATUS_RET(GetParamBool(env, context->argv[ARGS_ZERO], param), "Failed to get parameter");
495     return napi_ok;
496 }
497 
498 template <class AsyncContext>
ParseArgsStringCallback(napi_env env,napi_callback_info info,AsyncContext & context,string & param)499 napi_status SendableMediaLibraryNapiUtils::ParseArgsStringCallback(napi_env env, napi_callback_info info,
500     AsyncContext &context, string &param)
501 {
502     constexpr size_t minArgs = ARGS_ONE;
503     constexpr size_t maxArgs = ARGS_TWO;
504     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
505         "Failed to get object info");
506 
507     CHECK_STATUS_RET(GetParamStringPathMax(env, context->argv[ARGS_ZERO], param), "Failed to get string argument");
508     return napi_ok;
509 }
510 
511 template <class AsyncContext>
ParseArgsStringArrayCallback(napi_env env,napi_callback_info info,AsyncContext & context,vector<string> & array)512 napi_status SendableMediaLibraryNapiUtils::ParseArgsStringArrayCallback(napi_env env, napi_callback_info info,
513     AsyncContext &context, vector<string> &array)
514 {
515     constexpr size_t minArgs = ARGS_ONE;
516     constexpr size_t maxArgs = ARGS_TWO;
517     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
518         "Failed to get object info");
519 
520     CHECK_STATUS_RET(GetStringArray(env, context->argv[ARGS_ZERO], array), "Failed to get string array");
521     CHECK_STATUS_RET(GetParamCallback(env, context), "Failed to get callback");
522     return napi_ok;
523 }
524 
525 template <class AsyncContext>
ParseArgsNumberCallback(napi_env env,napi_callback_info info,AsyncContext & context,int32_t & value)526 napi_status SendableMediaLibraryNapiUtils::ParseArgsNumberCallback(napi_env env, napi_callback_info info,
527     AsyncContext &context, int32_t &value)
528 {
529     constexpr size_t minArgs = ARGS_ONE;
530     constexpr size_t maxArgs = ARGS_TWO;
531     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
532         "Failed to get object info");
533 
534     CHECK_STATUS_RET(GetInt32(env, context->argv[ARGS_ZERO], value), "Failed to get number argument");
535     return napi_ok;
536 }
537 
538 template <class AsyncContext>
ParseArgsOnlyCallBack(napi_env env,napi_callback_info info,AsyncContext & context)539 napi_status SendableMediaLibraryNapiUtils::ParseArgsOnlyCallBack(napi_env env, napi_callback_info info,
540     AsyncContext &context)
541 {
542     constexpr size_t minArgs = ARGS_ZERO;
543     constexpr size_t maxArgs = ARGS_ONE;
544     CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
545         "Failed to get object info");
546     return napi_ok;
547 }
548 
GetAssetType(MediaType type)549 AssetType SendableMediaLibraryNapiUtils::GetAssetType(MediaType type)
550 {
551     AssetType result;
552 
553     switch (type) {
554         case MEDIA_TYPE_AUDIO:
555             result = ASSET_AUDIO;
556             break;
557         case MEDIA_TYPE_VIDEO:
558             result = ASSET_VIDEO;
559             break;
560         case MEDIA_TYPE_IMAGE:
561             result = ASSET_IMAGE;
562             break;
563         case MEDIA_TYPE_MEDIA:
564             result = ASSET_MEDIA;
565             break;
566         default:
567             result = ASSET_NONE;
568             break;
569     }
570 
571     return result;
572 }
573 
AppendFetchOptionSelection(string & selection,const string & newCondition)574 void SendableMediaLibraryNapiUtils::AppendFetchOptionSelection(string &selection, const string &newCondition)
575 {
576     if (!newCondition.empty()) {
577         if (!selection.empty()) {
578             selection = "(" + selection + ") AND " + newCondition;
579         } else {
580             selection = newCondition;
581         }
582     }
583 }
584 
TransErrorCode(const string & Name,shared_ptr<DataShare::DataShareResultSet> resultSet)585 int SendableMediaLibraryNapiUtils::TransErrorCode(const string &Name,
586     shared_ptr<DataShare::DataShareResultSet> resultSet)
587 {
588     NAPI_ERR_LOG("interface: %{public}s, server return nullptr", Name.c_str());
589     // Query can't return errorcode, so assume nullptr as permission deny
590     if (resultSet == nullptr) {
591         return JS_ERR_PERMISSION_DENIED;
592     }
593     return ERR_DEFAULT;
594 }
595 
TransErrorCode(const string & Name,int error)596 int SendableMediaLibraryNapiUtils::TransErrorCode(const string &Name, int error)
597 {
598     NAPI_ERR_LOG("interface: %{public}s, server errcode:%{public}d ", Name.c_str(), error);
599     // Transfer Server error to napi error code
600     if (error <= E_COMMON_START && error >= E_COMMON_END) {
601         error = (error == -E_CHECK_SYSTEMAPP_FAIL) ? E_CHECK_SYSTEMAPP_FAIL : JS_INNER_FAIL;
602     } else if (trans2JsError.count(error)) {
603         error = trans2JsError.at(error);
604     }
605     return error;
606 }
607 
HandleError(napi_env env,int error,napi_value & errorObj,const string & Name)608 void SendableMediaLibraryNapiUtils::HandleError(napi_env env, int error, napi_value &errorObj, const string &Name)
609 {
610     if (error == ERR_DEFAULT) {
611         return;
612     }
613 
614     string errMsg = "System inner fail";
615     int originalError = error;
616     if (jsErrMap.count(error) > 0) {
617         errMsg = jsErrMap.at(error);
618     } else {
619         error = JS_INNER_FAIL;
620     }
621     CreateNapiErrorObject(env, errorObj, error, errMsg);
622     errMsg = Name + " " + errMsg;
623     NAPI_ERR_LOG("Error: %{public}s, js errcode:%{public}d ", errMsg.c_str(), originalError);
624 }
625 
CreateNapiErrorObject(napi_env env,napi_value & errorObj,const int32_t errCode,const string errMsg)626 void SendableMediaLibraryNapiUtils::CreateNapiErrorObject(napi_env env, napi_value &errorObj, const int32_t errCode,
627     const string errMsg)
628 {
629     napi_status statusError;
630     napi_value napiErrorCode = nullptr;
631     napi_value napiErrorMsg = nullptr;
632     statusError = napi_create_string_utf8(env, to_string(errCode).c_str(), NAPI_AUTO_LENGTH, &napiErrorCode);
633     if (statusError == napi_ok) {
634         statusError = napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &napiErrorMsg);
635         if (statusError == napi_ok) {
636             statusError = napi_create_error(env, napiErrorCode, napiErrorMsg, &errorObj);
637             if (statusError == napi_ok) {
638                 NAPI_DEBUG_LOG("napi_create_error success");
639             }
640         }
641     }
642 }
643 
InvokeJSAsyncMethodWithoutWork(napi_env env,napi_deferred deferred,napi_ref callbackRef,const SendableJSAsyncContextOutput & asyncContext)644 void SendableMediaLibraryNapiUtils::InvokeJSAsyncMethodWithoutWork(napi_env env, napi_deferred deferred,
645     napi_ref callbackRef, const SendableJSAsyncContextOutput &asyncContext)
646 {
647     MediaLibraryTracer tracer;
648     tracer.Start("InvokeJSAsyncMethod");
649 
650     napi_value retVal;
651     napi_value callback = nullptr;
652 
653     /* Deferred is used when JS Callback method expects a promise value */
654     if (deferred) {
655         if (asyncContext.status) {
656             napi_resolve_deferred(env, deferred, asyncContext.data);
657         } else {
658             napi_reject_deferred(env, deferred, asyncContext.error);
659         }
660     } else {
661         napi_value result[ARGS_TWO];
662         result[PARAM0] = asyncContext.error;
663         result[PARAM1] = asyncContext.data;
664         napi_get_reference_value(env, callbackRef, &callback);
665         napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
666         napi_delete_reference(env, callbackRef);
667         callbackRef = nullptr;
668     }
669 }
670 
InvokeJSAsyncMethod(napi_env env,napi_deferred deferred,napi_ref callbackRef,napi_async_work work,const SendableJSAsyncContextOutput & asyncContext)671 void SendableMediaLibraryNapiUtils::InvokeJSAsyncMethod(napi_env env, napi_deferred deferred, napi_ref callbackRef,
672     napi_async_work work, const SendableJSAsyncContextOutput &asyncContext)
673 {
674     MediaLibraryTracer tracer;
675     tracer.Start("InvokeJSAsyncMethod");
676 
677     napi_value retVal;
678     napi_value callback = nullptr;
679 
680     /* Deferred is used when JS Callback method expects a promise value */
681     if (deferred) {
682         if (asyncContext.status) {
683             napi_resolve_deferred(env, deferred, asyncContext.data);
684         } else {
685             napi_reject_deferred(env, deferred, asyncContext.error);
686         }
687     } else {
688         napi_value result[ARGS_TWO];
689         result[PARAM0] = asyncContext.error;
690         result[PARAM1] = asyncContext.data;
691         napi_get_reference_value(env, callbackRef, &callback);
692         napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
693         napi_delete_reference(env, callbackRef);
694         callbackRef = nullptr;
695     }
696     napi_delete_async_work(env, work);
697 }
698 
699 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 *))700 napi_value SendableMediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr<AsyncContext> &asyncContext,
701     const string &resourceName,  void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *))
702 {
703     napi_value result = nullptr;
704     napi_value resource = nullptr;
705     NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
706     NAPI_CREATE_RESOURCE_NAME(env, resource, resourceName.c_str(), asyncContext);
707 
708     NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, execute, complete,
709         static_cast<void *>(asyncContext.get()), &asyncContext->work));
710     NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated));
711     asyncContext.release();
712 
713     return result;
714 }
715 
ToUTF8String(napi_env env,napi_value value)716 tuple<bool, unique_ptr<char[]>, size_t> SendableMediaLibraryNapiUtils::ToUTF8String(napi_env env, napi_value value)
717 {
718     size_t strLen = 0;
719     napi_status status = napi_get_value_string_utf8(env, value, nullptr, -1, &strLen);
720     if (status != napi_ok) {
721         NAPI_ERR_LOG("ToUTF8String get fail, %{public}d", status);
722         return { false, nullptr, 0 };
723     }
724 
725     size_t bufLen = strLen + 1;
726     unique_ptr<char[]> str = make_unique<char[]>(bufLen);
727     if (str == nullptr) {
728         NAPI_ERR_LOG("ToUTF8String get memory fail");
729         return { false, nullptr, 0 };
730     }
731     status = napi_get_value_string_utf8(env, value, str.get(), bufLen, &strLen);
732     return make_tuple(status == napi_ok, move(str), strLen);
733 }
734 
IsExistsByPropertyName(napi_env env,napi_value jsObject,const char * propertyName)735 bool SendableMediaLibraryNapiUtils::IsExistsByPropertyName(napi_env env, napi_value jsObject, const char *propertyName)
736 {
737     bool result = false;
738     if (napi_has_named_property(env, jsObject, propertyName, &result) == napi_ok) {
739         return result;
740     } else {
741         NAPI_ERR_LOG("IsExistsByPropertyName not exist %{public}s", propertyName);
742         return false;
743     }
744 }
745 
GetPropertyValueByName(napi_env env,napi_value jsObject,const char * propertyName)746 napi_value SendableMediaLibraryNapiUtils::GetPropertyValueByName(napi_env env, napi_value jsObject,
747     const char *propertyName)
748 {
749     napi_value value = nullptr;
750     if (IsExistsByPropertyName(env, jsObject, propertyName) == false) {
751         NAPI_ERR_LOG("GetPropertyValueByName not exist %{public}s", propertyName);
752         return nullptr;
753     }
754     if (napi_get_named_property(env, jsObject, propertyName, &value) != napi_ok) {
755         NAPI_ERR_LOG("GetPropertyValueByName get fail %{public}s", propertyName);
756         return nullptr;
757     }
758     return value;
759 }
760 
CheckJSArgsTypeAsFunc(napi_env env,napi_value arg)761 bool SendableMediaLibraryNapiUtils::CheckJSArgsTypeAsFunc(napi_env env, napi_value arg)
762 {
763     napi_valuetype valueType = napi_undefined;
764     napi_typeof(env, arg, &valueType);
765     return (valueType == napi_function);
766 }
767 
IsArrayForNapiValue(napi_env env,napi_value param,uint32_t & arraySize)768 bool SendableMediaLibraryNapiUtils::IsArrayForNapiValue(napi_env env, napi_value param, uint32_t &arraySize)
769 {
770     bool isArray = false;
771     arraySize = 0;
772     if ((napi_is_array(env, param, &isArray) != napi_ok) || (isArray == false)) {
773         return false;
774     }
775     if (napi_get_array_length(env, param, &arraySize) != napi_ok) {
776         return false;
777     }
778     return true;
779 }
780 
GetInt32Arg(napi_env env,napi_value arg,int32_t & value)781 napi_value SendableMediaLibraryNapiUtils::GetInt32Arg(napi_env env, napi_value arg, int32_t &value)
782 {
783     napi_valuetype valueType = napi_undefined;
784     CHECK_ARGS(env, napi_typeof(env, arg, &valueType), JS_INNER_FAIL);
785     if (valueType != napi_number) {
786         NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID);
787         return nullptr;
788     }
789     CHECK_ARGS(env, napi_get_value_int32(env, arg, &value), JS_INNER_FAIL);
790 
791     napi_value result = nullptr;
792     CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
793     return result;
794 }
795 
UriAppendKeyValue(string & uri,const string & key,const string & value)796 void SendableMediaLibraryNapiUtils::UriAppendKeyValue(string &uri, const string &key, const string &value)
797 {
798     string uriKey = key + '=';
799     if (uri.find(uriKey) != string::npos) {
800         return;
801     }
802 
803     char queryMark = (uri.find('?') == string::npos) ? '?' : '&';
804     string append = queryMark + key + '=' + value;
805 
806     size_t posJ = uri.find('#');
807     if (posJ == string::npos) {
808         uri += append;
809     } else {
810         uri.insert(posJ, append);
811     }
812 }
813 
AddAssetColumns(napi_env env,vector<string> & fetchColumn,function<bool (const string & columnName)> isValidColumn,std::set<std::string> & validFetchColumns,const PhotoAlbumSubType subType)814 napi_value SendableMediaLibraryNapiUtils::AddAssetColumns(napi_env env, vector<string> &fetchColumn,
815     function<bool(const string &columnName)> isValidColumn, std::set<std::string>& validFetchColumns,
816     const PhotoAlbumSubType subType)
817 {
818     switch (subType) {
819         case PhotoAlbumSubType::FAVORITE:
820             validFetchColumns.insert(MediaColumn::MEDIA_IS_FAV);
821             break;
822         case PhotoAlbumSubType::VIDEO:
823             validFetchColumns.insert(MediaColumn::MEDIA_TYPE);
824             break;
825         case PhotoAlbumSubType::HIDDEN:
826             validFetchColumns.insert(MediaColumn::MEDIA_HIDDEN);
827             break;
828         case PhotoAlbumSubType::TRASH:
829             validFetchColumns.insert(MediaColumn::MEDIA_DATE_TRASHED);
830             break;
831         case PhotoAlbumSubType::SCREENSHOT:
832         case PhotoAlbumSubType::CAMERA:
833             validFetchColumns.insert(PhotoColumn::PHOTO_SUBTYPE);
834             break;
835         default:
836             break;
837     }
838     for (const auto &column : fetchColumn) {
839         if (column == PENDING_STATUS) {
840             validFetchColumns.insert(MediaColumn::MEDIA_TIME_PENDING);
841         } else if (isValidColumn(column) || (column == MEDIA_SUM_SIZE && IsSystemApp())) {
842             validFetchColumns.insert(column);
843         } else if (column == MEDIA_DATA_DB_URI) {
844             continue;
845         } else if (DATE_TRANSITION_MAP.count(column) != 0) {
846             validFetchColumns.insert(DATE_TRANSITION_MAP.at(column));
847         } else {
848             NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID);
849             return nullptr;
850         }
851     }
852     fetchColumn.assign(validFetchColumns.begin(), validFetchColumns.end());
853 
854     napi_value result = nullptr;
855     CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
856     return result;
857 }
858 
AddDefaultAssetColumns(napi_env env,vector<string> & fetchColumn,function<bool (const string & columnName)> isValidColumn,NapiAssetType assetType,const PhotoAlbumSubType subType)859 napi_value SendableMediaLibraryNapiUtils::AddDefaultAssetColumns(napi_env env, vector<string> &fetchColumn,
860     function<bool(const string &columnName)> isValidColumn, NapiAssetType assetType,
861     const PhotoAlbumSubType subType)
862 {
863     auto validFetchColumns = MediaColumn::DEFAULT_FETCH_COLUMNS;
864     if (assetType == TYPE_PHOTO) {
865         validFetchColumns.insert(
866             PhotoColumn::DEFAULT_FETCH_COLUMNS.begin(), PhotoColumn::DEFAULT_FETCH_COLUMNS.end());
867     }
868     return AddAssetColumns(env, fetchColumn, isValidColumn, validFetchColumns, subType);
869 }
870 
SetDefaultPredicatesCondition(DataSharePredicates & predicates,const int32_t dateTrashed,const bool isHidden,const int32_t timePending,const bool isTemp)871 inline void SetDefaultPredicatesCondition(DataSharePredicates &predicates, const int32_t dateTrashed,
872     const bool isHidden, const int32_t timePending, const bool isTemp)
873 {
874     predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, to_string(dateTrashed));
875     predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, to_string(isHidden));
876     predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, to_string(timePending));
877     predicates.EqualTo(PhotoColumn::PHOTO_IS_TEMP, to_string(isTemp));
878     predicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL,
879         to_string(static_cast<int32_t>(BurstCoverLevelType::COVER)));
880 }
881 
GetUserAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates,const bool hiddenOnly)882 int32_t SendableMediaLibraryNapiUtils::GetUserAlbumPredicates(
883     const int32_t albumId, DataSharePredicates &predicates, const bool hiddenOnly)
884 {
885     predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(albumId));
886     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
887     return E_SUCCESS;
888 }
889 
GetPortraitAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates)890 int32_t SendableMediaLibraryNapiUtils::GetPortraitAlbumPredicates(const int32_t albumId,
891     DataSharePredicates &predicates)
892 {
893     string onClause = MediaColumn::MEDIA_ID + " = " + PhotoMap::ASSET_ID;
894     vector<string> clauses = { onClause };
895     predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On(clauses);
896     onClause = ALBUM_ID + " = " + PhotoMap::ALBUM_ID;
897     clauses = { onClause };
898     predicates.InnerJoin(ANALYSIS_ALBUM_TABLE)->On(clauses);
899     string tempTable = "(SELECT " + GROUP_TAG + " FROM " + ANALYSIS_ALBUM_TABLE + " WHERE " + ALBUM_ID + " = " +
900         to_string(albumId) + ") ag";
901     onClause = "ag." + GROUP_TAG + " = " + ANALYSIS_ALBUM_TABLE + "." + GROUP_TAG;
902     clauses = { onClause };
903     predicates.InnerJoin(tempTable)->On(clauses);
904     SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
905     predicates.Distinct();
906     return E_SUCCESS;
907 }
908 
GetAnalysisPhotoMapPredicates(const int32_t albumId,DataSharePredicates & predicates)909 int32_t SendableMediaLibraryNapiUtils::GetAnalysisPhotoMapPredicates(const int32_t albumId,
910     DataSharePredicates &predicates)
911 {
912     string onClause = MediaColumn::MEDIA_ID + " = " + PhotoMap::ASSET_ID;
913     predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On({ onClause });
914     predicates.EqualTo(PhotoMap::ALBUM_ID, to_string(albumId));
915     SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
916     return E_SUCCESS;
917 }
918 
IsFeaturedSinglePortraitAlbum(std::string albumName,DataShare::DataSharePredicates & predicates)919 bool SendableMediaLibraryNapiUtils::IsFeaturedSinglePortraitAlbum(
920     std::string albumName, DataShare::DataSharePredicates &predicates)
921 {
922     bool isFeaturedSinglePortrait = false;
923     int portraitAlbumId = 0;
924     if (albumName.compare(to_string(portraitAlbumId)) != 0) {
925         return isFeaturedSinglePortrait;
926     }
927 
928     DataSharePredicates featuredSinglePortraitPredicates;
929     std::vector<OperationItem> operationList = predicates.GetOperationList();
930     for (auto& operationItem : operationList) {
931         switch (operationItem.operation) {
932             case OHOS::DataShare::OperationType::LIKE : {
933                 std::string field = std::get<string>(operationItem.singleParams[0]);
934                 std::string value = std::get<string>(operationItem.singleParams[1]);
935                 if (field.compare("FeaturedSinglePortrait") == 0 && value.compare("true") == 0) {
936                     isFeaturedSinglePortrait = true;
937                 } else {
938                     featuredSinglePortraitPredicates.Like(field, value);
939                 }
940                 break;
941             }
942             case OHOS::DataShare::OperationType::ORDER_BY_DESC : {
943                 featuredSinglePortraitPredicates.OrderByDesc(operationItem.GetSingle(0));
944                 break;
945             }
946             case OHOS::DataShare::OperationType::LIMIT : {
947                 featuredSinglePortraitPredicates.Limit(operationItem.GetSingle(0), operationItem.GetSingle(1));
948                 break;
949             }
950             default: {
951                 break;
952             }
953         }
954     }
955 
956     if (isFeaturedSinglePortrait) {
957         predicates = featuredSinglePortraitPredicates;
958     }
959     return isFeaturedSinglePortrait;
960 }
961 
GetFeaturedSinglePortraitAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates)962 int32_t SendableMediaLibraryNapiUtils::GetFeaturedSinglePortraitAlbumPredicates(
963     const int32_t albumId, DataSharePredicates &predicates)
964 {
965     string onClause = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID + " = " +
966         ANALYSIS_PHOTO_MAP_TABLE + "." + PhotoMap::ASSET_ID;
967     predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On({ onClause });
968 
969     constexpr int32_t minSize = 224;
970     string imgHeightColumn = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_HEIGHT;
971     string imgWidthColumn = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_WIDTH;
972     string imgFaceHeightColumn = VISION_IMAGE_FACE_TABLE + "." + SCALE_HEIGHT;
973     string imgFaceWidthColumn = VISION_IMAGE_FACE_TABLE + "." + SCALE_WIDTH;
974     string imgFaceHeightClause = "( " + imgFaceHeightColumn + " > " + to_string(minSize) +
975         " OR ( " + imgFaceHeightColumn + " <= 1.0 " + " AND " + imgFaceHeightColumn + " * " + imgHeightColumn +
976         " > " + to_string(minSize) + " ) )";
977     string imgFaceWidthClause = "( " + imgFaceWidthColumn + " > " + to_string(minSize) +
978         " OR ( " + imgFaceWidthColumn + " <= 1.0 " + " AND " + imgFaceWidthColumn + " * " + imgWidthColumn +
979         " > " + to_string(minSize) + " ) )";
980     string portraitRotationLimit = "BETWEEN -30 AND 30";
981     onClause = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID + " = " + VISION_IMAGE_FACE_TABLE + "." +
982         MediaColumn::MEDIA_ID + " AND " + VISION_IMAGE_FACE_TABLE + "." + TOTAL_FACES + " = 1 AND " +
983         imgFaceHeightClause + " AND " + imgFaceWidthClause + " AND " +
984         VISION_IMAGE_FACE_TABLE + "." + PITCH + " " + portraitRotationLimit + " AND " +
985         VISION_IMAGE_FACE_TABLE + "." + YAW + " " + portraitRotationLimit + " AND " +
986         VISION_IMAGE_FACE_TABLE + "." + ROLL + " " + portraitRotationLimit;
987     predicates.InnerJoin(VISION_IMAGE_FACE_TABLE)->On({ onClause });
988 
989     string portraitType = "IN ( 1, 2 )";
990     onClause = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID + " = " + VISION_POSE_TABLE + "." +
991         MediaColumn::MEDIA_ID + " AND " + VISION_POSE_TABLE + "." + POSE_TYPE + " " + portraitType;
992     predicates.InnerJoin(VISION_POSE_TABLE)->On({ onClause });
993 
994     predicates.EqualTo(PhotoMap::ALBUM_ID, to_string(albumId));
995     SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
996     return E_SUCCESS;
997 }
998 
GetAllLocationPredicates(DataSharePredicates & predicates)999 int32_t SendableMediaLibraryNapiUtils::GetAllLocationPredicates(DataSharePredicates &predicates)
1000 {
1001     SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
1002     predicates.And()->NotEqualTo(PhotoColumn::PHOTO_LATITUDE, to_string(0));
1003     predicates.And()->NotEqualTo(PhotoColumn::PHOTO_LONGITUDE, to_string(0));
1004     return E_SUCCESS;
1005 }
1006 
GetFavoritePredicates(DataSharePredicates & predicates,const bool hiddenOnly)1007 static int32_t GetFavoritePredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1008 {
1009     predicates.BeginWrap();
1010     constexpr int32_t IS_FAVORITE = 1;
1011     predicates.EqualTo(MediaColumn::MEDIA_IS_FAV, to_string(IS_FAVORITE));
1012     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1013     predicates.EndWrap();
1014     return E_SUCCESS;
1015 }
1016 
GetVideoPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1017 static int32_t GetVideoPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1018 {
1019     predicates.BeginWrap();
1020     predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_VIDEO));
1021     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1022     predicates.EndWrap();
1023     return E_SUCCESS;
1024 }
1025 
GetHiddenPredicates(DataSharePredicates & predicates)1026 static int32_t GetHiddenPredicates(DataSharePredicates &predicates)
1027 {
1028     predicates.BeginWrap();
1029     SetDefaultPredicatesCondition(predicates, 0, 1, 0, false);
1030     predicates.EndWrap();
1031     return E_SUCCESS;
1032 }
1033 
GetTrashPredicates(DataSharePredicates & predicates)1034 static int32_t GetTrashPredicates(DataSharePredicates &predicates)
1035 {
1036     predicates.BeginWrap();
1037     predicates.GreaterThan(MediaColumn::MEDIA_DATE_TRASHED, to_string(0));
1038     predicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL,
1039         to_string(static_cast<int32_t>(BurstCoverLevelType::COVER)));
1040     predicates.EndWrap();
1041     return E_SUCCESS;
1042 }
1043 
GetScreenshotPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1044 static int32_t GetScreenshotPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1045 {
1046     predicates.BeginWrap();
1047     predicates.EqualTo(PhotoColumn::PHOTO_SUBTYPE, to_string(static_cast<int32_t>(PhotoSubType::SCREENSHOT)));
1048     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1049     predicates.EndWrap();
1050     return E_SUCCESS;
1051 }
1052 
GetCameraPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1053 static int32_t GetCameraPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1054 {
1055     predicates.BeginWrap();
1056     predicates.EqualTo(PhotoColumn::PHOTO_SUBTYPE, to_string(static_cast<int32_t>(PhotoSubType::CAMERA)));
1057     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1058     predicates.EndWrap();
1059     return E_SUCCESS;
1060 }
1061 
GetAllImagesPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1062 static int32_t GetAllImagesPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1063 {
1064     predicates.BeginWrap();
1065     predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_IMAGE));
1066     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1067     predicates.EndWrap();
1068     return E_SUCCESS;
1069 }
1070 
GetCloudEnhancementPredicates(DataSharePredicates & predicates,const bool hiddenOnly)1071 static int32_t GetCloudEnhancementPredicates(DataSharePredicates &predicates, const bool hiddenOnly)
1072 {
1073     predicates.BeginWrap();
1074     predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_IMAGE));
1075     predicates.EqualTo(PhotoColumn::PHOTO_STRONG_ASSOCIATION,
1076         to_string(static_cast<int32_t>(StrongAssociationType::CLOUD_ENHANCEMENT)));
1077     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1078     predicates.EndWrap();
1079     return E_SUCCESS;
1080 }
1081 
GetSourceAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates,const bool hiddenOnly)1082 int32_t SendableMediaLibraryNapiUtils::GetSourceAlbumPredicates(const int32_t albumId, DataSharePredicates &predicates,
1083     const bool hiddenOnly)
1084 {
1085     predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(albumId));
1086     predicates.EqualTo(PhotoColumn::PHOTO_SYNC_STATUS, to_string(static_cast<int32_t>(SyncStatusType::TYPE_VISIBLE)));
1087     SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
1088     return E_SUCCESS;
1089 }
1090 
GetSystemAlbumPredicates(const PhotoAlbumSubType subType,DataSharePredicates & predicates,const bool hiddenOnly)1091 int32_t SendableMediaLibraryNapiUtils::GetSystemAlbumPredicates(const PhotoAlbumSubType subType,
1092     DataSharePredicates &predicates, const bool hiddenOnly)
1093 {
1094     switch (subType) {
1095         case PhotoAlbumSubType::FAVORITE: {
1096             return GetFavoritePredicates(predicates, hiddenOnly);
1097         }
1098         case PhotoAlbumSubType::VIDEO: {
1099             return GetVideoPredicates(predicates, hiddenOnly);
1100         }
1101         case PhotoAlbumSubType::HIDDEN: {
1102             return GetHiddenPredicates(predicates);
1103         }
1104         case PhotoAlbumSubType::TRASH: {
1105             return GetTrashPredicates(predicates);
1106         }
1107         case PhotoAlbumSubType::SCREENSHOT: {
1108             return GetScreenshotPredicates(predicates, hiddenOnly);
1109         }
1110         case PhotoAlbumSubType::CAMERA: {
1111             return GetCameraPredicates(predicates, hiddenOnly);
1112         }
1113         case PhotoAlbumSubType::IMAGE: {
1114             return GetAllImagesPredicates(predicates, hiddenOnly);
1115         }
1116         case PhotoAlbumSubType::CLOUD_ENHANCEMENT: {
1117             return GetCloudEnhancementPredicates(predicates, hiddenOnly);
1118         }
1119         default: {
1120             NAPI_ERR_LOG("Unsupported photo album subtype: %{public}d", subType);
1121             return E_INVALID_ARGUMENTS;
1122         }
1123     }
1124 }
1125 
CreateValueByIndex(napi_env env,int32_t index,string name,shared_ptr<NativeRdb::ResultSet> & resultSet,const shared_ptr<FileAsset> & asset)1126 napi_value SendableMediaLibraryNapiUtils::CreateValueByIndex(napi_env env, int32_t index, string name,
1127     shared_ptr<NativeRdb::ResultSet> &resultSet, const shared_ptr<FileAsset> &asset)
1128 {
1129     int status;
1130     int integerVal = 0;
1131     string stringVal = "";
1132     int64_t longVal = 0;
1133     double doubleVal = 0.0;
1134     napi_value value = nullptr;
1135     auto dataType = SendableMediaLibraryNapiUtils::GetTypeMap().at(name);
1136     switch (dataType.first) {
1137         case TYPE_STRING:
1138             status = resultSet->GetString(index, stringVal);
1139             napi_create_string_utf8(env, stringVal.c_str(), NAPI_AUTO_LENGTH, &value);
1140             asset->GetMemberMap().emplace(name, stringVal);
1141             break;
1142         case TYPE_INT32:
1143             status = resultSet->GetInt(index, integerVal);
1144             napi_create_int32(env, integerVal, &value);
1145             asset->GetMemberMap().emplace(name, integerVal);
1146             break;
1147         case TYPE_INT64:
1148             status = resultSet->GetLong(index, longVal);
1149             napi_create_int64(env, longVal, &value);
1150             asset->GetMemberMap().emplace(name, longVal);
1151             break;
1152         case TYPE_DOUBLE:
1153             status = resultSet->GetDouble(index, doubleVal);
1154             napi_create_double(env, doubleVal, &value);
1155             asset->GetMemberMap().emplace(name, doubleVal);
1156             break;
1157         default:
1158             NAPI_ERR_LOG("not match dataType %{public}d", dataType.first);
1159             break;
1160     }
1161 
1162     return value;
1163 }
1164 
handleTimeInfo(napi_env env,const std::string & name,napi_value result,int32_t index,const std::shared_ptr<NativeRdb::ResultSet> & resultSet)1165 void SendableMediaLibraryNapiUtils::handleTimeInfo(napi_env env, const std::string& name, napi_value result,
1166     int32_t index, const std::shared_ptr<NativeRdb::ResultSet>& resultSet)
1167 {
1168     if (TIME_COLUMN.count(name) == 0) {
1169         return;
1170     }
1171     int64_t longVal = 0;
1172     int status;
1173     napi_value value = nullptr;
1174     status = resultSet->GetLong(index, longVal);
1175     int64_t modifieldValue = longVal / 1000;
1176     napi_create_int64(env, modifieldValue, &value);
1177     auto dataType = SendableMediaLibraryNapiUtils::GetTimeTypeMap().at(name);
1178     napi_set_named_property(env, result, dataType.second.c_str(), value);
1179 }
1180 
handleThumbnailReady(napi_env env,const std::string & name,napi_value result,int32_t index,const std::shared_ptr<NativeRdb::ResultSet> & resultSet)1181 static void handleThumbnailReady(napi_env env, const std::string& name, napi_value result, int32_t index,
1182     const std::shared_ptr<NativeRdb::ResultSet>& resultSet)
1183 {
1184     if (name != "thumbnail_ready") {
1185         return;
1186     }
1187     int64_t longVal = 0;
1188     int status;
1189     napi_value value = nullptr;
1190     status = resultSet->GetLong(index, longVal);
1191     bool resultVal = longVal > 0;
1192     napi_create_int32(env, resultVal, &value);
1193     napi_set_named_property(env, result, "thumbnailReady", value);
1194 }
1195 
GetNextRowObject(napi_env env,shared_ptr<NativeRdb::ResultSet> & resultSet)1196 napi_value SendableMediaLibraryNapiUtils::GetNextRowObject(napi_env env,
1197     shared_ptr<NativeRdb::ResultSet> &resultSet)
1198 {
1199     if (resultSet == nullptr) {
1200         NAPI_ERR_LOG("GetNextRowObject fail, result is nullptr");
1201         return nullptr;
1202     }
1203     vector<string> columnNames;
1204     resultSet->GetAllColumnNames(columnNames);
1205 
1206     napi_value result = nullptr;
1207     napi_create_object(env, &result);
1208 
1209     napi_value value = nullptr;
1210     int32_t index = -1;
1211     auto fileAsset = make_shared<FileAsset>();
1212     for (const auto &name : columnNames) {
1213         index++;
1214 
1215         // Check if the column name exists in the type map
1216         if (SendableMediaLibraryNapiUtils::GetTypeMap().count(name) == 0) {
1217             continue;
1218         }
1219         value = SendableMediaLibraryNapiUtils::CreateValueByIndex(env, index, name, resultSet, fileAsset);
1220         auto dataType = SendableMediaLibraryNapiUtils::GetTypeMap().at(name);
1221         napi_set_named_property(env, result, dataType.second.c_str(), value);
1222         handleTimeInfo(env, name, result, index, resultSet);
1223         handleThumbnailReady(env, name, result, index, resultSet);
1224     }
1225 
1226     if (fileAsset->GetDisplayName().empty() && fileAsset->GetPath().empty()) {
1227         return result;
1228     }
1229     string extrUri = MediaFileUtils::GetExtraUri(fileAsset->GetDisplayName(), fileAsset->GetPath(), false);
1230     MediaFileUri fileUri(fileAsset->GetMediaType(), to_string(fileAsset->GetId()), "", MEDIA_API_VERSION_V10, extrUri);
1231     fileAsset->SetUri(move(fileUri.ToString()));
1232     napi_create_string_utf8(env, fileAsset->GetUri().c_str(), NAPI_AUTO_LENGTH, &value);
1233     napi_set_named_property(env, result, MEDIA_DATA_DB_URI.c_str(), value);
1234     return result;
1235 }
1236 
IsSystemApp()1237 bool SendableMediaLibraryNapiUtils::IsSystemApp()
1238 {
1239     static bool isSys = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetSelfTokenID());
1240     return isSys;
1241 }
1242 
SendableNapiScopeHandler(napi_env env)1243 SendableNapiScopeHandler::SendableNapiScopeHandler(napi_env env): env_(env)
1244 {
1245     napi_status status = napi_open_handle_scope(env_, &scope_);
1246     if (status != napi_ok) {
1247         NAPI_ERR_LOG("Open Handler scope failed, status %{public}d", status);
1248         isValid_ = false;
1249     } else {
1250         isValid_ = true;
1251     }
1252 }
1253 
~SendableNapiScopeHandler()1254 SendableNapiScopeHandler::~SendableNapiScopeHandler()
1255 {
1256     if (isValid_) {
1257         napi_status status = napi_close_handle_scope(env_, scope_);
1258         if (status != napi_ok) {
1259             NAPI_ERR_LOG("Close Handler scope failed, status %{public}d", status);
1260         }
1261     }
1262 }
1263 
IsValid()1264 bool SendableNapiScopeHandler::IsValid()
1265 {
1266     return isValid_;
1267 }
1268 
GetNapiValueArray(napi_env env,napi_value arg,vector<napi_value> & values)1269 napi_value SendableMediaLibraryNapiUtils::GetNapiValueArray(napi_env env, napi_value arg, vector<napi_value> &values)
1270 {
1271     bool isArray = false;
1272     CHECK_ARGS(env, napi_is_array(env, arg, &isArray), OHOS_INVALID_PARAM_CODE);
1273     if (!isArray) {
1274         NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, "Failed to check array type");
1275         return nullptr;
1276     }
1277 
1278     uint32_t len = 0;
1279     CHECK_ARGS(env, napi_get_array_length(env, arg, &len), JS_INNER_FAIL);
1280     if (len == 0) {
1281         napi_value result = nullptr;
1282         CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
1283         return result;
1284     }
1285 
1286     for (uint32_t i = 0; i < len; i++) {
1287         napi_value value = nullptr;
1288         CHECK_ARGS(env, napi_get_element(env, arg, i, &value), JS_INNER_FAIL);
1289         if (value == nullptr) {
1290             NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, "Failed to get element");
1291             return nullptr;
1292         }
1293         values.push_back(value);
1294     }
1295 
1296     napi_value result = nullptr;
1297     CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
1298     return result;
1299 }
1300 
GetStringArray(napi_env env,vector<napi_value> & napiValues,vector<string> & values)1301 napi_value SendableMediaLibraryNapiUtils::GetStringArray(napi_env env, vector<napi_value> &napiValues,
1302     vector<string> &values)
1303 {
1304     napi_valuetype valueType = napi_undefined;
1305     unique_ptr<char[]> buffer = make_unique<char[]>(PATH_MAX);
1306     for (const auto &napiValue : napiValues) {
1307         CHECK_ARGS(env, napi_typeof(env, napiValue, &valueType), JS_ERR_PARAMETER_INVALID);
1308         CHECK_COND(env, valueType == napi_string, JS_ERR_PARAMETER_INVALID);
1309 
1310         size_t res = 0;
1311         CHECK_ARGS(
1312             env, napi_get_value_string_utf8(env, napiValue, buffer.get(), PATH_MAX, &res), JS_ERR_PARAMETER_INVALID);
1313         values.emplace_back(buffer.get());
1314     }
1315     napi_value ret = nullptr;
1316     CHECK_ARGS(env, napi_get_boolean(env, true, &ret), JS_INNER_FAIL);
1317     return ret;
1318 }
1319 
1320 template <class AsyncContext>
ParsePredicates(napi_env env,const napi_value arg,AsyncContext & context,const FetchOptionType & fetchOptType)1321 napi_status SendableMediaLibraryNapiUtils::ParsePredicates(napi_env env, const napi_value arg,
1322     AsyncContext &context, const FetchOptionType &fetchOptType)
1323 {
1324     JSProxy::JSProxy<DataShareAbsPredicates> *jsProxy = nullptr;
1325     napi_unwrap(env, arg, reinterpret_cast<void **>(&jsProxy));
1326     if (jsProxy == nullptr) {
1327         NAPI_ERR_LOG("jsProxy is invalid");
1328         return napi_invalid_arg;
1329     }
1330     shared_ptr<DataShareAbsPredicates> predicate = jsProxy->GetInstance();
1331     CHECK_COND_RET(HandleSpecialPredicate(context, predicate, fetchOptType) == TRUE,
1332         napi_invalid_arg, "invalid predicate");
1333     CHECK_COND_RET(GetLocationPredicate(context, predicate) == TRUE, napi_invalid_arg, "invalid predicate");
1334     return napi_ok;
1335 }
1336 
1337 template bool SendableMediaLibraryNapiUtils::HandleSpecialPredicate<unique_ptr<SendablePAHAsyncContext>>(
1338     unique_ptr<SendablePAHAsyncContext> &context, shared_ptr<DataShareAbsPredicates> &predicate,
1339     const FetchOptionType &fetchOptType, vector<OperationItem> operations);
1340 
1341 template napi_status SendableMediaLibraryNapiUtils::GetFetchOption<unique_ptr<SendablePAHAsyncContext>>(napi_env env,
1342     napi_value arg, const FetchOptionType &fetchOptType, unique_ptr<SendablePAHAsyncContext> &context,
1343     vector<OperationItem> operations);
1344 
1345 template napi_status SendableMediaLibraryNapiUtils::GetFetchOption<unique_ptr<SendablePANAsyncContext>>(napi_env env,
1346     napi_value arg, const FetchOptionType &fetchOptType, unique_ptr<SendablePANAsyncContext> &context,
1347     vector<OperationItem> operations);
1348 
1349 template napi_status SendableMediaLibraryNapiUtils::GetAlbumFetchOption<unique_ptr<SendablePANAsyncContext>>(
1350     napi_env env, napi_value arg, const FetchOptionType &fetchOptType,
1351     unique_ptr<SendablePANAsyncContext> &context);
1352 
1353 template napi_status SendableMediaLibraryNapiUtils::GetPredicate<unique_ptr<SendablePAHAsyncContext>>(napi_env env,
1354     const napi_value arg, const string &propName, unique_ptr<SendablePAHAsyncContext> &context,
1355     const FetchOptionType &fetchOptType, vector<OperationItem> operations);
1356 
1357 template napi_status SendableMediaLibraryNapiUtils::ParseArgsStringArrayCallback<unique_ptr<SendablePAHAsyncContext>>(
1358     napi_env env, napi_callback_info info,
1359     unique_ptr<SendablePAHAsyncContext> &context, vector<string> &array);
1360 
1361 template napi_status SendableMediaLibraryNapiUtils::GetParamCallback<unique_ptr<SendablePANAsyncContext>>(
1362     napi_env env, unique_ptr<SendablePANAsyncContext> &context);
1363 
1364 template napi_status SendableMediaLibraryNapiUtils::GetParamCallback<unique_ptr<SendablePAHAsyncContext>>(
1365     napi_env env, unique_ptr<SendablePAHAsyncContext> &context);
1366 
1367 template napi_status SendableMediaLibraryNapiUtils::GetParamCallback<unique_ptr<SendablePhotoAccessHelperInitContext>>(
1368     napi_env env, unique_ptr<SendablePhotoAccessHelperInitContext> &context);
1369 
1370 template napi_status SendableMediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<SendableFAAsyncContext>>(
1371     napi_env env, napi_callback_info info, unique_ptr<SendableFAAsyncContext> &context, string &param);
1372 
1373 template napi_status SendableMediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<SendablePANAsyncContext>>(
1374     napi_env env, napi_callback_info info,
1375     unique_ptr<SendablePANAsyncContext> &context, string &param);
1376 
1377 template napi_status SendableMediaLibraryNapiUtils::ParseArgsBoolCallBack<unique_ptr<SendableFAAsyncContext>>(
1378     napi_env env, napi_callback_info info, unique_ptr<SendableFAAsyncContext> &context, bool &param);
1379 
1380 template napi_status SendableMediaLibraryNapiUtils::AsyncContextSetObjectInfo<unique_ptr<SendablePAHAsyncContext>>(
1381     napi_env env, napi_callback_info info, unique_ptr<SendablePAHAsyncContext> &asyncContext,
1382     const size_t minArgs, const size_t maxArgs);
1383 
1384 template napi_status SendableMediaLibraryNapiUtils::AsyncContextSetObjectInfo<unique_ptr<SendableFAAsyncContext>>(
1385     napi_env env, napi_callback_info info, unique_ptr<SendableFAAsyncContext> &asyncContext,
1386     const size_t minArgs, const size_t maxArgs);
1387 
1388 template napi_status SendableMediaLibraryNapiUtils::AsyncContextSetObjectInfo<unique_ptr<SendablePANAsyncContext>>(
1389     napi_env env, napi_callback_info info, unique_ptr<SendablePANAsyncContext> &asyncContext,
1390     const size_t minArgs, const size_t maxArgs);
1391 
1392 template napi_value SendableMediaLibraryNapiUtils::NapiCreateAsyncWork<SendablePAHAsyncContext>(
1393     napi_env env, unique_ptr<SendablePAHAsyncContext> &asyncContext, const string &resourceName,
1394     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1395 
1396 template napi_value SendableMediaLibraryNapiUtils::NapiCreateAsyncWork<SendablePhotoAccessHelperInitContext>(
1397     napi_env env, unique_ptr<SendablePhotoAccessHelperInitContext> &asyncContext, const string &resourceName,
1398     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1399 
1400 template napi_value SendableMediaLibraryNapiUtils::NapiCreateAsyncWork<SendableFAAsyncContext>(napi_env env,
1401     unique_ptr<SendableFAAsyncContext> &asyncContext, const string &resourceName,
1402     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1403 
1404 template napi_value SendableMediaLibraryNapiUtils::NapiCreateAsyncWork<SendablePANAsyncContext>(
1405     napi_env env, unique_ptr<SendablePANAsyncContext> &asyncContext, const string &resourceName,
1406     void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *));
1407 
1408 template napi_status SendableMediaLibraryNapiUtils::ParseArgsNumberCallback<unique_ptr<SendableFAAsyncContext>>(
1409     napi_env env, napi_callback_info info, unique_ptr<SendableFAAsyncContext> &context, int32_t &value);
1410 
1411 template napi_status SendableMediaLibraryNapiUtils::ParseArgsOnlyCallBack<unique_ptr<SendableFAAsyncContext>>(
1412     napi_env env, napi_callback_info info, unique_ptr<SendableFAAsyncContext> &context);
1413 
1414 template napi_status SendableMediaLibraryNapiUtils::ParsePredicates<unique_ptr<SendablePAHAsyncContext>>(
1415     napi_env env, const napi_value arg, unique_ptr<SendablePAHAsyncContext> &context,
1416     const FetchOptionType &fetchOptType);
1417 
1418 } // namespace Media
1419 } // namespace OHOS
1420