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