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 ¶m)
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 ¶m)
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 ¶m);
1344
1345 template napi_status SendableMediaLibraryNapiUtils::ParseArgsStringCallback<unique_ptr<SendablePANAsyncContext>>(
1346 napi_env env, napi_callback_info info,
1347 unique_ptr<SendablePANAsyncContext> &context, string ¶m);
1348
1349 template napi_status SendableMediaLibraryNapiUtils::ParseArgsBoolCallBack<unique_ptr<SendableFAAsyncContext>>(
1350 napi_env env, napi_callback_info info, unique_ptr<SendableFAAsyncContext> &context, bool ¶m);
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