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_utils.h"
35 #include "medialibrary_tracer.h"
36 #include "medialibrary_type_const.h"
37 #include "photo_album_napi.h"
38 #include "photo_map_column.h"
39 #include "smart_album_napi.h"
40 #include "tokenid_kit.h"
41 #include "userfile_client.h"
42 #include "vision_album_column.h"
43 #include "vision_column.h"
44 #include "vision_face_tag_column.h"
45 #include "vision_pose_column.h"
46 #include "vision_image_face_column.h"
47 #include "userfile_manager_types.h"
48
49 using namespace std;
50 using namespace OHOS::DataShare;
51
52 namespace OHOS {
53 namespace Media {
54 static const string EMPTY_STRING = "";
55 using json = nlohmann::json;
56 using SendablePAHAsyncContext = SendablePhotoAccessHelperAsyncContext;
57 using SendablePANAsyncContext = SendablePhotoAlbumNapiAsyncContext;
58 using SendableFAAsyncContext = SendableFileAssetAsyncContext;
59
GetUInt32(napi_env env,napi_value arg,uint32_t & value)60 napi_status SendableMediaLibraryNapiUtils::GetUInt32(napi_env env, napi_value arg, uint32_t &value)
61 {
62 napi_valuetype valueType = napi_undefined;
63 CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
64 CHECK_COND_RET(valueType == napi_number, napi_number_expected, "Type is not as expected number");
65 CHECK_STATUS_RET(napi_get_value_uint32(env, arg, &value), "Failed to get uint32 value");
66 return napi_ok;
67 }
68
GetInt32(napi_env env,napi_value arg,int32_t & value)69 napi_status SendableMediaLibraryNapiUtils::GetInt32(napi_env env, napi_value arg, int32_t &value)
70 {
71 napi_valuetype valueType = napi_undefined;
72 CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
73 CHECK_COND_RET(valueType == napi_number, napi_number_expected, "Type is not as expected number");
74 CHECK_STATUS_RET(napi_get_value_int32(env, arg, &value), "Failed to get int32 value");
75 return napi_ok;
76 }
77
GetParamBool(napi_env env,napi_value arg,bool & value)78 napi_status SendableMediaLibraryNapiUtils::GetParamBool(napi_env env, napi_value arg, bool &value)
79 {
80 napi_valuetype valueType = napi_undefined;
81 CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
82 CHECK_COND_RET(valueType == napi_boolean, napi_boolean_expected, "Type is not as expected boolean");
83 CHECK_STATUS_RET(napi_get_value_bool(env, arg, &value), "Failed to get param");
84 return napi_ok;
85 }
86
GetParamFunction(napi_env env,napi_value arg,napi_ref & callbackRef)87 napi_status SendableMediaLibraryNapiUtils::GetParamFunction(napi_env env, napi_value arg, napi_ref &callbackRef)
88 {
89 napi_valuetype valueType = napi_undefined;
90 CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
91 CHECK_COND_RET(valueType == napi_function, napi_function_expected, "Type is not as expected function");
92 CHECK_STATUS_RET(napi_create_reference(env, arg, NAPI_INIT_REF_COUNT, &callbackRef), "Failed to make callbackref");
93 return napi_ok;
94 }
95
GetParamStr(napi_env env,napi_value arg,const size_t size,string & result)96 static napi_status GetParamStr(napi_env env, napi_value arg, const size_t size, string &result)
97 {
98 size_t res = 0;
99 unique_ptr<char[]> buffer = make_unique<char[]>(size);
100 CHECK_COND_RET(buffer != nullptr, napi_invalid_arg, "Failed to alloc buffer for parameter");
101 napi_valuetype valueType = napi_undefined;
102 CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
103 CHECK_COND_RET(valueType == napi_string, napi_string_expected, "Type is not as expected string");
104 CHECK_STATUS_RET(napi_get_value_string_utf8(env, arg, buffer.get(), size, &res), "Failed to get string value");
105 result = string(buffer.get());
106 return napi_ok;
107 }
108
GetParamStringWithLength(napi_env env,napi_value arg,int32_t maxLen,string & result)109 napi_status SendableMediaLibraryNapiUtils::GetParamStringWithLength(napi_env env, napi_value arg, int32_t maxLen,
110 string &result)
111 {
112 CHECK_STATUS_RET(GetParamStr(env, arg, maxLen, result), "Failed to get string parameter");
113 return napi_ok;
114 }
115
GetParamStringPathMax(napi_env env,napi_value arg,string & result)116 napi_status SendableMediaLibraryNapiUtils::GetParamStringPathMax(napi_env env, napi_value arg, string &result)
117 {
118 CHECK_STATUS_RET(GetParamStr(env, arg, PATH_MAX, result), "Failed to get string parameter");
119 return napi_ok;
120 }
121
GetProperty(napi_env env,const napi_value arg,const string & propName,string & propValue)122 napi_status SendableMediaLibraryNapiUtils::GetProperty(napi_env env, const napi_value arg, const string &propName,
123 string &propValue)
124 {
125 bool present = false;
126 napi_value property = nullptr;
127 CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present),
128 "Failed to check property name");
129 if (present) {
130 CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property), "Failed to get property");
131 CHECK_STATUS_RET(GetParamStringPathMax(env, property, propValue), "Failed to get string buffer");
132 }
133 return napi_ok;
134 }
135
GetStringArray(napi_env env,napi_value arg,vector<string> & array)136 napi_status SendableMediaLibraryNapiUtils::GetStringArray(napi_env env, napi_value arg, vector<string> &array)
137 {
138 bool isArray = false;
139 uint32_t len = 0;
140 CHECK_STATUS_RET(napi_is_array(env, arg, &isArray), "Failed to check array type");
141 CHECK_COND_RET(isArray, napi_array_expected, "Expected array type");
142 CHECK_STATUS_RET(napi_get_array_length(env, arg, &len), "Failed to get array length");
143 for (uint32_t i = 0; i < len; i++) {
144 napi_value item = nullptr;
145 string val;
146 CHECK_STATUS_RET(napi_get_element(env, arg, i, &item), "Failed to get array item");
147 CHECK_STATUS_RET(GetParamStringPathMax(env, item, val), "Failed to get string buffer");
148 array.push_back(val);
149 }
150 return napi_ok;
151 }
152
GetArrayProperty(napi_env env,napi_value arg,const string & propName,vector<string> & array)153 napi_status SendableMediaLibraryNapiUtils::GetArrayProperty(napi_env env, napi_value arg, const string &propName,
154 vector<string> &array)
155 {
156 bool present = false;
157 CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present), "Failed to check property name");
158 if (present) {
159 napi_value property = nullptr;
160 CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property),
161 "Failed to get selectionArgs property");
162 GetStringArray(env, property, array);
163 }
164 return napi_ok;
165 }
166
HasCallback(napi_env env,const size_t argc,const napi_value argv[],bool & isCallback)167 napi_status SendableMediaLibraryNapiUtils::HasCallback(napi_env env, const size_t argc, const napi_value argv[],
168 bool &isCallback)
169 {
170 isCallback = false;
171 if (argc < ARGS_ONE) {
172 return napi_ok;
173 }
174 napi_valuetype valueType = napi_undefined;
175 CHECK_STATUS_RET(napi_typeof(env, argv[argc - 1], &valueType), "Failed to get type");
176 isCallback = (valueType == napi_function);
177 return napi_ok;
178 }
179
hasFetchOpt(napi_env env,const napi_value arg,bool & hasFetchOpt)180 napi_status SendableMediaLibraryNapiUtils::hasFetchOpt(napi_env env, const napi_value arg, bool &hasFetchOpt)
181 {
182 hasFetchOpt = false;
183 napi_valuetype valueType = napi_undefined;
184 CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type");
185 if (valueType != napi_object) {
186 hasFetchOpt = false;
187 return napi_ok;
188 }
189 CHECK_STATUS_RET(napi_has_named_property(env, arg, "selections", &hasFetchOpt),
190 "Failed to get property selections");
191 return napi_ok;
192 }
193
GetMediaTypeFromUri(const string & uri)194 MediaType SendableMediaLibraryNapiUtils::GetMediaTypeFromUri(const string &uri)
195 {
196 if (uri.find(MEDIALIBRARY_IMAGE_URI) != string::npos) {
197 return MediaType::MEDIA_TYPE_IMAGE;
198 } else if (uri.find(MEDIALIBRARY_VIDEO_URI) != string::npos) {
199 return MediaType::MEDIA_TYPE_VIDEO;
200 } else if (uri.find(MEDIALIBRARY_AUDIO_URI) != string::npos) {
201 return MediaType::MEDIA_TYPE_AUDIO;
202 } else if (uri.find(MEDIALIBRARY_FILE_URI) != string::npos) {
203 return MediaType::MEDIA_TYPE_FILE;
204 }
205 return MediaType::MEDIA_TYPE_ALL;
206 }
207
HandleSpecialDateTypePredicate(const OperationItem & item,vector<OperationItem> & operations,const FetchOptionType & fetchOptType)208 static bool HandleSpecialDateTypePredicate(const OperationItem &item,
209 vector<OperationItem> &operations, const FetchOptionType &fetchOptType)
210 {
211 constexpr int32_t FIELD_IDX = 0;
212 constexpr int32_t VALUE_IDX = 1;
213 vector<string>dateTypes = { MEDIA_DATA_DB_DATE_ADDED, MEDIA_DATA_DB_DATE_TRASHED, MEDIA_DATA_DB_DATE_MODIFIED,
214 MEDIA_DATA_DB_DATE_TAKEN };
215 string dateType = item.GetSingle(FIELD_IDX);
216 auto it = find(dateTypes.begin(), dateTypes.end(), dateType);
217 if (it != dateTypes.end() && item.operation != DataShare::ORDER_BY_ASC &&
218 item.operation != DataShare::ORDER_BY_DESC) {
219 dateType += "_s";
220 operations.push_back({ item.operation, { dateType, static_cast<double>(item.GetSingle(VALUE_IDX)) } });
221 return true;
222 }
223 if (DATE_TRANSITION_MAP.count(dateType) != 0) {
224 dateType = DATE_TRANSITION_MAP.at(dateType);
225 operations.push_back({ item.operation, { dateType, static_cast<double>(item.GetSingle(VALUE_IDX)) } });
226 return true;
227 }
228 return false;
229 }
230
231 template <class AsyncContext>
HandleSpecialPredicate(AsyncContext & context,shared_ptr<DataShareAbsPredicates> & predicate,const FetchOptionType & fetchOptType,vector<OperationItem> operations)232 bool SendableMediaLibraryNapiUtils::HandleSpecialPredicate(AsyncContext &context,
233 shared_ptr<DataShareAbsPredicates> &predicate, const FetchOptionType &fetchOptType,
234 vector<OperationItem> operations)
235 {
236 constexpr int32_t FIELD_IDX = 0;
237 constexpr int32_t VALUE_IDX = 1;
238 auto &items = predicate->GetOperationList();
239 for (auto &item : items) {
240 if (item.singleParams.empty()) {
241 operations.push_back(item);
242 continue;
243 }
244 if (HandleSpecialDateTypePredicate(item, operations, fetchOptType)) {
245 continue;
246 }
247 // change uri ->file id
248 // get networkid
249 // replace networkid with file id
250 if (static_cast<string>(item.GetSingle(FIELD_IDX)) == DEVICE_DB_NETWORK_ID) {
251 if (item.operation != DataShare::EQUAL_TO || static_cast<string>(item.GetSingle(VALUE_IDX)).empty()) {
252 NAPI_ERR_LOG("DEVICE_DB_NETWORK_ID predicates not support %{public}d", item.operation);
253 return false;
254 }
255 context->networkId = static_cast<string>(item.GetSingle(VALUE_IDX));
256 continue;
257 }
258 if (static_cast<string>(item.GetSingle(FIELD_IDX)) == MEDIA_DATA_DB_URI) {
259 if (item.operation != DataShare::EQUAL_TO) {
260 NAPI_ERR_LOG("MEDIA_DATA_DB_URI predicates not support %{public}d", item.operation);
261 return false;
262 }
263 string uri = static_cast<string>(item.GetSingle(VALUE_IDX));
264 MediaFileUri::RemoveAllFragment(uri);
265 MediaFileUri fileUri(uri);
266 context->uri = uri;
267 if ((fetchOptType != ALBUM_FETCH_OPT) && (!fileUri.IsApi10())) {
268 fileUri = MediaFileUri(MediaFileUtils::GetRealUriFromVirtualUri(uri));
269 }
270 context->networkId = fileUri.GetNetworkId();
271 string field = (fetchOptType == ALBUM_FETCH_OPT) ? PhotoAlbumColumns::ALBUM_ID : MEDIA_DATA_DB_ID;
272 operations.push_back({ item.operation, { field, fileUri.GetFileId() } });
273 continue;
274 }
275 if (static_cast<string>(item.GetSingle(FIELD_IDX)) == PENDING_STATUS) {
276 // do not query pending files below API11
277 continue;
278 }
279 if (LOCATION_PARAM_MAP.find(static_cast<string>(item.GetSingle(FIELD_IDX))) != LOCATION_PARAM_MAP.end()) {
280 continue;
281 }
282 operations.push_back(item);
283 }
284 context->predicates = DataSharePredicates(move(operations));
285 return true;
286 }
287
288 template <class AsyncContext>
GetLocationPredicate(AsyncContext & context,shared_ptr<DataShareAbsPredicates> & predicate)289 bool SendableMediaLibraryNapiUtils::GetLocationPredicate(AsyncContext &context,
290 shared_ptr<DataShareAbsPredicates> &predicate)
291 {
292 constexpr int32_t FIELD_IDX = 0;
293 constexpr int32_t VALUE_IDX = 1;
294 map<string, string> locationMap;
295 auto &items = predicate->GetOperationList();
296 for (auto &item : items) {
297 if (item.singleParams.empty()) {
298 continue;
299 }
300 if (LOCATION_PARAM_MAP.find(static_cast<string>(item.GetSingle(FIELD_IDX))) != LOCATION_PARAM_MAP.end()) {
301 if (item.operation != DataShare::EQUAL_TO) {
302 NAPI_ERR_LOG("location predicates not support %{public}d", item.operation);
303 return false;
304 }
305 string param = static_cast<string>(item.GetSingle(FIELD_IDX));
306 string value = static_cast<string>(item.GetSingle(VALUE_IDX));
307 locationMap.insert(make_pair(param, value));
308 if (param == DIAMETER) {
309 continue;
310 }
311 if (LOCATION_PARAM_MAP.at(param).second == DataShare::GREATER_THAN_OR_EQUAL_TO) {
312 context->predicates.GreaterThanOrEqualTo(LOCATION_PARAM_MAP.at(param).first, value);
313 continue;
314 }
315 if (LOCATION_PARAM_MAP.at(param).second == DataShare::LESS_THAN) {
316 context->predicates.LessThan(LOCATION_PARAM_MAP.at(param).first, value);
317 continue;
318 }
319 if (LOCATION_PARAM_MAP.at(param).second == DataShare::EQUAL_TO) {
320 context->predicates.EqualTo(LOCATION_PARAM_MAP.at(param).first, value);
321 continue;
322 }
323 }
324 }
325
326 if (locationMap.count(DIAMETER) == 1 && locationMap.count(START_LATITUDE) == 1
327 && locationMap.count(START_LONGITUDE) == 1) {
328 // 0.5:Used for rounding down
329 string latitudeIndex = "round((latitude - " + locationMap.at(START_LATITUDE) + ") / " +
330 locationMap.at(DIAMETER) + " - 0.5)";
331 string longitudeIndex = "round((longitude - " + locationMap.at(START_LONGITUDE) + ") / " +
332 locationMap.at(DIAMETER) + " - 0.5)";
333 string albumName = LATITUDE + "||'_'||" + LONGITUDE + "||'_'||" + latitudeIndex + "||'_'||" +
334 longitudeIndex + " AS " + ALBUM_NAME;
335 context->fetchColumn.push_back(albumName);
336 string locationGroup = latitudeIndex + "," + longitudeIndex;
337 context->predicates.GroupBy({ locationGroup });
338 }
339 return true;
340 }
341
342 template <class AsyncContext>
GetFetchOption(napi_env env,napi_value arg,const FetchOptionType & fetchOptType,AsyncContext & context,vector<OperationItem> operations)343 napi_status SendableMediaLibraryNapiUtils::GetFetchOption(napi_env env, napi_value arg,
344 const FetchOptionType &fetchOptType, AsyncContext &context, vector<OperationItem> operations)
345 {
346 // Parse the argument into fetchOption if any
347 CHECK_STATUS_RET(GetPredicate(env, arg, "predicates", context, fetchOptType, move(operations)),
348 "invalid predicate");
349 CHECK_STATUS_RET(GetArrayProperty(env, arg, "fetchColumns", context->fetchColumn),
350 "Failed to parse fetchColumn");
351 return napi_ok;
352 }
353
354 template <class AsyncContext>
GetAlbumFetchOption(napi_env env,napi_value arg,const FetchOptionType & fetchOptType,AsyncContext & context)355 napi_status SendableMediaLibraryNapiUtils::GetAlbumFetchOption(napi_env env, napi_value arg,
356 const FetchOptionType &fetchOptType, AsyncContext &context)
357 {
358 // Parse the argument into AlbumFetchOption if any
359 CHECK_STATUS_RET(GetPredicate(env, arg, "predicates", context, fetchOptType), "invalid predicate");
360 return napi_ok;
361 }
362
363 template <class AsyncContext>
GetPredicate(napi_env env,const napi_value arg,const string & propName,AsyncContext & context,const FetchOptionType & fetchOptType,vector<OperationItem> operations)364 napi_status SendableMediaLibraryNapiUtils::GetPredicate(napi_env env, const napi_value arg, const string &propName,
365 AsyncContext &context, const FetchOptionType &fetchOptType, vector<OperationItem> operations)
366 {
367 bool present = false;
368 napi_value property = nullptr;
369 CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present),
370 "Failed to check property name");
371 if (present) {
372 CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property), "Failed to get property");
373 JSProxy::JSProxy<DataShareAbsPredicates> *jsProxy = nullptr;
374 napi_unwrap(env, property, reinterpret_cast<void **>(&jsProxy));
375 if (jsProxy == nullptr) {
376 NAPI_ERR_LOG("jsProxy is invalid");
377 return napi_invalid_arg;
378 }
379 shared_ptr<DataShareAbsPredicates> predicate = jsProxy->GetInstance();
380 CHECK_COND_RET(HandleSpecialPredicate(context, predicate, fetchOptType, move(operations)) == TRUE,
381 napi_invalid_arg, "invalid predicate");
382 CHECK_COND_RET(GetLocationPredicate(context, predicate) == TRUE, napi_invalid_arg, "invalid predicate");
383 }
384 return napi_ok;
385 }
386
387 template <class AsyncContext>
ParseAssetFetchOptCallback(napi_env env,napi_callback_info info,AsyncContext & context)388 napi_status SendableMediaLibraryNapiUtils::ParseAssetFetchOptCallback(napi_env env, napi_callback_info info,
389 AsyncContext &context)
390 {
391 constexpr size_t minArgs = ARGS_ONE;
392 constexpr size_t maxArgs = ARGS_TWO;
393 CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
394 "Failed to get object info");
395 CHECK_STATUS_RET(GetFetchOption(env, context->argv[PARAM0], ASSET_FETCH_OPT, context),
396 "Failed to get fetch option");
397 return napi_ok;
398 }
399
400 template <class AsyncContext>
ParseAlbumFetchOptCallback(napi_env env,napi_callback_info info,AsyncContext & context)401 napi_status SendableMediaLibraryNapiUtils::ParseAlbumFetchOptCallback(napi_env env, napi_callback_info info,
402 AsyncContext &context)
403 {
404 constexpr size_t minArgs = ARGS_ONE;
405 constexpr size_t maxArgs = ARGS_TWO;
406 CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
407 "Failed to get object info");
408 // Parse the argument into fetchOption if any
409 CHECK_STATUS_RET(GetPredicate(env, context->argv[PARAM0], "predicates", context, ALBUM_FETCH_OPT),
410 "invalid predicate");
411 context->predicates.And()->NotEqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::HIDDEN));
412 return napi_ok;
413 }
414
415 template <class AsyncContext>
UpdateMediaTypeSelections(AsyncContext * context)416 void SendableMediaLibraryNapiUtils::UpdateMediaTypeSelections(AsyncContext *context)
417 {
418 constexpr int FIRST_MEDIA_TYPE = 0;
419 constexpr int SECOND_MEDIA_TYPE = 1;
420 if ((context->mediaTypes.size() != ARGS_ONE) && (context->mediaTypes.size() != ARGS_TWO)) {
421 return;
422 }
423 DataShare::DataSharePredicates &predicates = context->predicates;
424 predicates.BeginWrap();
425 predicates.EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, (int)context->mediaTypes[FIRST_MEDIA_TYPE]);
426 if (context->mediaTypes.size() == ARGS_TWO) {
427 predicates.Or()->EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, (int)context->mediaTypes[SECOND_MEDIA_TYPE]);
428 }
429 predicates.EndWrap();
430 }
431
432 template <class AsyncContext>
AsyncContextSetObjectInfo(napi_env env,napi_callback_info info,AsyncContext & asyncContext,const size_t minArgs,const size_t maxArgs)433 napi_status SendableMediaLibraryNapiUtils::AsyncContextSetObjectInfo(napi_env env, napi_callback_info info,
434 AsyncContext &asyncContext, const size_t minArgs, const size_t maxArgs)
435 {
436 napi_value thisVar = nullptr;
437 asyncContext->argc = maxArgs;
438 CHECK_STATUS_RET(napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), &thisVar,
439 nullptr), "Failed to get cb info");
440 CHECK_COND_RET(((asyncContext->argc >= minArgs) && (asyncContext->argc <= maxArgs)), napi_invalid_arg,
441 "Number of args is invalid");
442 if (minArgs > 0) {
443 CHECK_COND_RET(asyncContext->argv[ARGS_ZERO] != nullptr, napi_invalid_arg, "Argument list is empty");
444 }
445 CHECK_STATUS_RET(napi_unwrap_sendable(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo)),
446 "Failed to unwrap thisVar");
447 CHECK_COND_RET(asyncContext->objectInfo != nullptr, napi_invalid_arg, "Failed to get object info");
448 CHECK_STATUS_RET(GetParamCallback(env, asyncContext), "Failed to get callback param!");
449 return napi_ok;
450 }
451
452 template <class AsyncContext>
AsyncContextGetArgs(napi_env env,napi_callback_info info,AsyncContext & asyncContext,const size_t minArgs,const size_t maxArgs)453 napi_status SendableMediaLibraryNapiUtils::AsyncContextGetArgs(napi_env env, napi_callback_info info,
454 AsyncContext &asyncContext, const size_t minArgs, const size_t maxArgs)
455 {
456 asyncContext->argc = maxArgs;
457 CHECK_STATUS_RET(napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), nullptr,
458 nullptr), "Failed to get cb info");
459 CHECK_COND_RET(asyncContext->argc >= minArgs && asyncContext->argc <= maxArgs, napi_invalid_arg,
460 "Number of args is invalid");
461 if (minArgs > 0) {
462 CHECK_COND_RET(asyncContext->argv[ARGS_ZERO] != nullptr, napi_invalid_arg, "Argument list is empty");
463 }
464 CHECK_STATUS_RET(GetParamCallback(env, asyncContext), "Failed to get callback param");
465 return napi_ok;
466 }
467
468 template <class AsyncContext>
GetParamCallback(napi_env env,AsyncContext & context)469 napi_status SendableMediaLibraryNapiUtils::GetParamCallback(napi_env env, AsyncContext &context)
470 {
471 /* Parse the last argument into callbackref if any */
472 bool isCallback = false;
473 CHECK_STATUS_RET(HasCallback(env, context->argc, context->argv, isCallback), "Failed to check callback");
474 if (isCallback) {
475 CHECK_STATUS_RET(GetParamFunction(env, context->argv[context->argc - 1], context->callbackRef),
476 "Failed to get callback");
477 }
478 return napi_ok;
479 }
480
481 template <class AsyncContext>
ParseArgsBoolCallBack(napi_env env,napi_callback_info info,AsyncContext & context,bool & param)482 napi_status SendableMediaLibraryNapiUtils::ParseArgsBoolCallBack(napi_env env, napi_callback_info info,
483 AsyncContext &context,
484 bool ¶m)
485 {
486 constexpr size_t minArgs = ARGS_ONE;
487 constexpr size_t maxArgs = ARGS_TWO;
488 CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
489 "Failed to get object info");
490
491 /* Parse the first argument into param */
492 CHECK_STATUS_RET(GetParamBool(env, context->argv[ARGS_ZERO], param), "Failed to get parameter");
493 return napi_ok;
494 }
495
496 template <class AsyncContext>
ParseArgsStringCallback(napi_env env,napi_callback_info info,AsyncContext & context,string & param)497 napi_status SendableMediaLibraryNapiUtils::ParseArgsStringCallback(napi_env env, napi_callback_info info,
498 AsyncContext &context, string ¶m)
499 {
500 constexpr size_t minArgs = ARGS_ONE;
501 constexpr size_t maxArgs = ARGS_TWO;
502 CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
503 "Failed to get object info");
504
505 CHECK_STATUS_RET(GetParamStringPathMax(env, context->argv[ARGS_ZERO], param), "Failed to get string argument");
506 return napi_ok;
507 }
508
509 template <class AsyncContext>
ParseArgsStringArrayCallback(napi_env env,napi_callback_info info,AsyncContext & context,vector<string> & array)510 napi_status SendableMediaLibraryNapiUtils::ParseArgsStringArrayCallback(napi_env env, napi_callback_info info,
511 AsyncContext &context, vector<string> &array)
512 {
513 constexpr size_t minArgs = ARGS_ONE;
514 constexpr size_t maxArgs = ARGS_TWO;
515 CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
516 "Failed to get object info");
517
518 CHECK_STATUS_RET(GetStringArray(env, context->argv[ARGS_ZERO], array), "Failed to get string array");
519 CHECK_STATUS_RET(GetParamCallback(env, context), "Failed to get callback");
520 return napi_ok;
521 }
522
523 template <class AsyncContext>
ParseArgsNumberCallback(napi_env env,napi_callback_info info,AsyncContext & context,int32_t & value)524 napi_status SendableMediaLibraryNapiUtils::ParseArgsNumberCallback(napi_env env, napi_callback_info info,
525 AsyncContext &context, int32_t &value)
526 {
527 constexpr size_t minArgs = ARGS_ONE;
528 constexpr size_t maxArgs = ARGS_TWO;
529 CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
530 "Failed to get object info");
531
532 CHECK_STATUS_RET(GetInt32(env, context->argv[ARGS_ZERO], value), "Failed to get number argument");
533 return napi_ok;
534 }
535
536 template <class AsyncContext>
ParseArgsOnlyCallBack(napi_env env,napi_callback_info info,AsyncContext & context)537 napi_status SendableMediaLibraryNapiUtils::ParseArgsOnlyCallBack(napi_env env, napi_callback_info info,
538 AsyncContext &context)
539 {
540 constexpr size_t minArgs = ARGS_ZERO;
541 constexpr size_t maxArgs = ARGS_ONE;
542 CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs),
543 "Failed to get object info");
544 return napi_ok;
545 }
546
GetAssetType(MediaType type)547 AssetType SendableMediaLibraryNapiUtils::GetAssetType(MediaType type)
548 {
549 AssetType result;
550
551 switch (type) {
552 case MEDIA_TYPE_AUDIO:
553 result = ASSET_AUDIO;
554 break;
555 case MEDIA_TYPE_VIDEO:
556 result = ASSET_VIDEO;
557 break;
558 case MEDIA_TYPE_IMAGE:
559 result = ASSET_IMAGE;
560 break;
561 case MEDIA_TYPE_MEDIA:
562 result = ASSET_MEDIA;
563 break;
564 default:
565 result = ASSET_NONE;
566 break;
567 }
568
569 return result;
570 }
571
AppendFetchOptionSelection(string & selection,const string & newCondition)572 void SendableMediaLibraryNapiUtils::AppendFetchOptionSelection(string &selection, const string &newCondition)
573 {
574 if (!newCondition.empty()) {
575 if (!selection.empty()) {
576 selection = "(" + selection + ") AND " + newCondition;
577 } else {
578 selection = newCondition;
579 }
580 }
581 }
582
TransErrorCode(const string & Name,shared_ptr<DataShare::DataShareResultSet> resultSet)583 int SendableMediaLibraryNapiUtils::TransErrorCode(const string &Name,
584 shared_ptr<DataShare::DataShareResultSet> resultSet)
585 {
586 NAPI_ERR_LOG("interface: %{public}s, server return nullptr", Name.c_str());
587 // Query can't return errorcode, so assume nullptr as permission deny
588 if (resultSet == nullptr) {
589 return JS_ERR_PERMISSION_DENIED;
590 }
591 return ERR_DEFAULT;
592 }
593
TransErrorCode(const string & Name,int error)594 int SendableMediaLibraryNapiUtils::TransErrorCode(const string &Name, int error)
595 {
596 NAPI_ERR_LOG("interface: %{public}s, server errcode:%{public}d ", Name.c_str(), error);
597 // Transfer Server error to napi error code
598 if (error <= E_COMMON_START && error >= E_COMMON_END) {
599 error = JS_INNER_FAIL;
600 } else if (trans2JsError.count(error)) {
601 error = trans2JsError.at(error);
602 }
603 return error;
604 }
605
HandleError(napi_env env,int error,napi_value & errorObj,const string & Name)606 void SendableMediaLibraryNapiUtils::HandleError(napi_env env, int error, napi_value &errorObj, const string &Name)
607 {
608 if (error == ERR_DEFAULT) {
609 return;
610 }
611
612 string errMsg = "System inner fail";
613 int originalError = error;
614 if (jsErrMap.count(error) > 0) {
615 errMsg = jsErrMap.at(error);
616 } else {
617 error = JS_INNER_FAIL;
618 }
619 CreateNapiErrorObject(env, errorObj, error, errMsg);
620 errMsg = Name + " " + errMsg;
621 NAPI_ERR_LOG("Error: %{public}s, js errcode:%{public}d ", errMsg.c_str(), originalError);
622 }
623
CreateNapiErrorObject(napi_env env,napi_value & errorObj,const int32_t errCode,const string errMsg)624 void SendableMediaLibraryNapiUtils::CreateNapiErrorObject(napi_env env, napi_value &errorObj, const int32_t errCode,
625 const string errMsg)
626 {
627 napi_status statusError;
628 napi_value napiErrorCode = nullptr;
629 napi_value napiErrorMsg = nullptr;
630 statusError = napi_create_string_utf8(env, to_string(errCode).c_str(), NAPI_AUTO_LENGTH, &napiErrorCode);
631 if (statusError == napi_ok) {
632 statusError = napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &napiErrorMsg);
633 if (statusError == napi_ok) {
634 statusError = napi_create_error(env, napiErrorCode, napiErrorMsg, &errorObj);
635 if (statusError == napi_ok) {
636 NAPI_DEBUG_LOG("napi_create_error success");
637 }
638 }
639 }
640 }
641
InvokeJSAsyncMethod(napi_env env,napi_deferred deferred,napi_ref callbackRef,napi_async_work work,const SendableJSAsyncContextOutput & asyncContext)642 void SendableMediaLibraryNapiUtils::InvokeJSAsyncMethod(napi_env env, napi_deferred deferred, napi_ref callbackRef,
643 napi_async_work work, const SendableJSAsyncContextOutput &asyncContext)
644 {
645 MediaLibraryTracer tracer;
646 tracer.Start("InvokeJSAsyncMethod");
647
648 napi_value retVal;
649 napi_value callback = nullptr;
650
651 /* Deferred is used when JS Callback method expects a promise value */
652 if (deferred) {
653 if (asyncContext.status) {
654 napi_resolve_deferred(env, deferred, asyncContext.data);
655 } else {
656 napi_reject_deferred(env, deferred, asyncContext.error);
657 }
658 } else {
659 napi_value result[ARGS_TWO];
660 result[PARAM0] = asyncContext.error;
661 result[PARAM1] = asyncContext.data;
662 napi_get_reference_value(env, callbackRef, &callback);
663 napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
664 napi_delete_reference(env, callbackRef);
665 }
666 napi_delete_async_work(env, work);
667 }
668
669 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 *))670 napi_value SendableMediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr<AsyncContext> &asyncContext,
671 const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *))
672 {
673 napi_value result = nullptr;
674 napi_value resource = nullptr;
675 NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
676 NAPI_CREATE_RESOURCE_NAME(env, resource, resourceName.c_str(), asyncContext);
677
678 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, execute, complete,
679 static_cast<void *>(asyncContext.get()), &asyncContext->work));
680 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated));
681 asyncContext.release();
682
683 return result;
684 }
685
ToUTF8String(napi_env env,napi_value value)686 tuple<bool, unique_ptr<char[]>, size_t> SendableMediaLibraryNapiUtils::ToUTF8String(napi_env env, napi_value value)
687 {
688 size_t strLen = 0;
689 napi_status status = napi_get_value_string_utf8(env, value, nullptr, -1, &strLen);
690 if (status != napi_ok) {
691 NAPI_ERR_LOG("ToUTF8String get fail, %{public}d", status);
692 return { false, nullptr, 0 };
693 }
694
695 size_t bufLen = strLen + 1;
696 unique_ptr<char[]> str = make_unique<char[]>(bufLen);
697 if (str == nullptr) {
698 NAPI_ERR_LOG("ToUTF8String get memory fail");
699 return { false, nullptr, 0 };
700 }
701 status = napi_get_value_string_utf8(env, value, str.get(), bufLen, &strLen);
702 return make_tuple(status == napi_ok, move(str), strLen);
703 }
704
IsExistsByPropertyName(napi_env env,napi_value jsObject,const char * propertyName)705 bool SendableMediaLibraryNapiUtils::IsExistsByPropertyName(napi_env env, napi_value jsObject, const char *propertyName)
706 {
707 bool result = false;
708 if (napi_has_named_property(env, jsObject, propertyName, &result) == napi_ok) {
709 return result;
710 } else {
711 NAPI_ERR_LOG("IsExistsByPropertyName not exist %{public}s", propertyName);
712 return false;
713 }
714 }
715
GetPropertyValueByName(napi_env env,napi_value jsObject,const char * propertyName)716 napi_value SendableMediaLibraryNapiUtils::GetPropertyValueByName(napi_env env, napi_value jsObject,
717 const char *propertyName)
718 {
719 napi_value value = nullptr;
720 if (IsExistsByPropertyName(env, jsObject, propertyName) == false) {
721 NAPI_ERR_LOG("GetPropertyValueByName not exist %{public}s", propertyName);
722 return nullptr;
723 }
724 if (napi_get_named_property(env, jsObject, propertyName, &value) != napi_ok) {
725 NAPI_ERR_LOG("GetPropertyValueByName get fail %{public}s", propertyName);
726 return nullptr;
727 }
728 return value;
729 }
730
CheckJSArgsTypeAsFunc(napi_env env,napi_value arg)731 bool SendableMediaLibraryNapiUtils::CheckJSArgsTypeAsFunc(napi_env env, napi_value arg)
732 {
733 napi_valuetype valueType = napi_undefined;
734 napi_typeof(env, arg, &valueType);
735 return (valueType == napi_function);
736 }
737
IsArrayForNapiValue(napi_env env,napi_value param,uint32_t & arraySize)738 bool SendableMediaLibraryNapiUtils::IsArrayForNapiValue(napi_env env, napi_value param, uint32_t &arraySize)
739 {
740 bool isArray = false;
741 arraySize = 0;
742 if ((napi_is_array(env, param, &isArray) != napi_ok) || (isArray == false)) {
743 return false;
744 }
745 if (napi_get_array_length(env, param, &arraySize) != napi_ok) {
746 return false;
747 }
748 return true;
749 }
750
GetInt32Arg(napi_env env,napi_value arg,int32_t & value)751 napi_value SendableMediaLibraryNapiUtils::GetInt32Arg(napi_env env, napi_value arg, int32_t &value)
752 {
753 napi_valuetype valueType = napi_undefined;
754 CHECK_ARGS(env, napi_typeof(env, arg, &valueType), JS_INNER_FAIL);
755 if (valueType != napi_number) {
756 NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID);
757 return nullptr;
758 }
759 CHECK_ARGS(env, napi_get_value_int32(env, arg, &value), JS_INNER_FAIL);
760
761 napi_value result = nullptr;
762 CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
763 return result;
764 }
765
UriAppendKeyValue(string & uri,const string & key,const string & value)766 void SendableMediaLibraryNapiUtils::UriAppendKeyValue(string &uri, const string &key, const string &value)
767 {
768 string uriKey = key + '=';
769 if (uri.find(uriKey) != string::npos) {
770 return;
771 }
772
773 char queryMark = (uri.find('?') == string::npos) ? '?' : '&';
774 string append = queryMark + key + '=' + value;
775
776 size_t posJ = uri.find('#');
777 if (posJ == string::npos) {
778 uri += append;
779 } else {
780 uri.insert(posJ, append);
781 }
782 }
783
AddAssetColumns(napi_env env,vector<string> & fetchColumn,function<bool (const string & columnName)> isValidColumn,std::set<std::string> & validFetchColumns,const PhotoAlbumSubType subType)784 napi_value SendableMediaLibraryNapiUtils::AddAssetColumns(napi_env env, vector<string> &fetchColumn,
785 function<bool(const string &columnName)> isValidColumn, std::set<std::string>& validFetchColumns,
786 const PhotoAlbumSubType subType)
787 {
788 switch (subType) {
789 case PhotoAlbumSubType::FAVORITE:
790 validFetchColumns.insert(MediaColumn::MEDIA_IS_FAV);
791 break;
792 case PhotoAlbumSubType::VIDEO:
793 validFetchColumns.insert(MediaColumn::MEDIA_TYPE);
794 break;
795 case PhotoAlbumSubType::HIDDEN:
796 validFetchColumns.insert(MediaColumn::MEDIA_HIDDEN);
797 break;
798 case PhotoAlbumSubType::TRASH:
799 validFetchColumns.insert(MediaColumn::MEDIA_DATE_TRASHED);
800 break;
801 case PhotoAlbumSubType::SCREENSHOT:
802 case PhotoAlbumSubType::CAMERA:
803 validFetchColumns.insert(PhotoColumn::PHOTO_SUBTYPE);
804 break;
805 default:
806 break;
807 }
808 for (const auto &column : fetchColumn) {
809 if (column == PENDING_STATUS) {
810 validFetchColumns.insert(MediaColumn::MEDIA_TIME_PENDING);
811 } else if (isValidColumn(column)) {
812 validFetchColumns.insert(column);
813 } else if (column == MEDIA_DATA_DB_URI) {
814 continue;
815 } else if (DATE_TRANSITION_MAP.count(column) != 0) {
816 validFetchColumns.insert(DATE_TRANSITION_MAP.at(column));
817 } else {
818 NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID);
819 return nullptr;
820 }
821 }
822 fetchColumn.assign(validFetchColumns.begin(), validFetchColumns.end());
823
824 napi_value result = nullptr;
825 CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL);
826 return result;
827 }
828
AddDefaultAssetColumns(napi_env env,vector<string> & fetchColumn,function<bool (const string & columnName)> isValidColumn,NapiAssetType assetType,const PhotoAlbumSubType subType)829 napi_value SendableMediaLibraryNapiUtils::AddDefaultAssetColumns(napi_env env, vector<string> &fetchColumn,
830 function<bool(const string &columnName)> isValidColumn, NapiAssetType assetType,
831 const PhotoAlbumSubType subType)
832 {
833 auto validFetchColumns = MediaColumn::DEFAULT_FETCH_COLUMNS;
834 if (assetType == TYPE_PHOTO) {
835 validFetchColumns.insert(
836 PhotoColumn::DEFAULT_FETCH_COLUMNS.begin(), PhotoColumn::DEFAULT_FETCH_COLUMNS.end());
837 }
838 return AddAssetColumns(env, fetchColumn, isValidColumn, validFetchColumns, subType);
839 }
840
SetDefaultPredicatesCondition(DataSharePredicates & predicates,const int32_t dateTrashed,const bool isHidden,const int32_t timePending,const bool isTemp)841 inline void SetDefaultPredicatesCondition(DataSharePredicates &predicates, const int32_t dateTrashed,
842 const bool isHidden, const int32_t timePending, const bool isTemp)
843 {
844 predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, to_string(dateTrashed));
845 predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, to_string(isHidden));
846 predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, to_string(timePending));
847 predicates.EqualTo(PhotoColumn::PHOTO_IS_TEMP, to_string(isTemp));
848 predicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL,
849 to_string(static_cast<int32_t>(BurstCoverLevelType::COVER)));
850 }
851
GetUserAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates,const bool hiddenOnly)852 int32_t SendableMediaLibraryNapiUtils::GetUserAlbumPredicates(
853 const int32_t albumId, DataSharePredicates &predicates, const bool hiddenOnly)
854 {
855 predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(albumId));
856 SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false);
857 return E_SUCCESS;
858 }
859
GetPortraitAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates)860 int32_t SendableMediaLibraryNapiUtils::GetPortraitAlbumPredicates(const int32_t albumId,
861 DataSharePredicates &predicates)
862 {
863 string onClause = MediaColumn::MEDIA_ID + " = " + PhotoMap::ASSET_ID;
864 vector<string> clauses = { onClause };
865 predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On(clauses);
866 onClause = ALBUM_ID + " = " + PhotoMap::ALBUM_ID;
867 clauses = { onClause };
868 predicates.InnerJoin(ANALYSIS_ALBUM_TABLE)->On(clauses);
869 string tempTable = "(SELECT " + GROUP_TAG + " FROM " + ANALYSIS_ALBUM_TABLE + " WHERE " + ALBUM_ID + " = " +
870 to_string(albumId) + ") ag";
871 onClause = "ag." + GROUP_TAG + " = " + ANALYSIS_ALBUM_TABLE + "." + GROUP_TAG;
872 clauses = { onClause };
873 predicates.InnerJoin(tempTable)->On(clauses);
874 SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
875 predicates.Distinct();
876 return E_SUCCESS;
877 }
878
GetAnalysisAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates)879 int32_t SendableMediaLibraryNapiUtils::GetAnalysisAlbumPredicates(const int32_t albumId,
880 DataSharePredicates &predicates)
881 {
882 string onClause = MediaColumn::MEDIA_ID + " = " + PhotoMap::ASSET_ID;
883 predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On({ onClause });
884 predicates.EqualTo(PhotoMap::ALBUM_ID, to_string(albumId));
885 SetDefaultPredicatesCondition(predicates, 0, 0, 0, false);
886 return E_SUCCESS;
887 }
888
IsFeaturedSinglePortraitAlbum(std::string albumName,DataShare::DataSharePredicates & predicates)889 bool SendableMediaLibraryNapiUtils::IsFeaturedSinglePortraitAlbum(
890 std::string albumName, DataShare::DataSharePredicates &predicates)
891 {
892 bool isFeaturedSinglePortrait = false;
893 int portraitAlbumId = 0;
894 if (albumName.compare(to_string(portraitAlbumId)) != 0) {
895 return isFeaturedSinglePortrait;
896 }
897
898 DataSharePredicates featuredSinglePortraitPredicates;
899 std::vector<OperationItem> operationList = predicates.GetOperationList();
900 for (auto& operationItem : operationList) {
901 switch (operationItem.operation) {
902 case OHOS::DataShare::OperationType::LIKE : {
903 std::string field = std::get<string>(operationItem.singleParams[0]);
904 std::string value = std::get<string>(operationItem.singleParams[1]);
905 if (field.compare("FeaturedSinglePortrait") == 0 && value.compare("true") == 0) {
906 isFeaturedSinglePortrait = true;
907 } else {
908 featuredSinglePortraitPredicates.Like(field, value);
909 }
910 break;
911 }
912 case OHOS::DataShare::OperationType::ORDER_BY_DESC : {
913 featuredSinglePortraitPredicates.OrderByDesc(operationItem.GetSingle(0));
914 break;
915 }
916 case OHOS::DataShare::OperationType::LIMIT : {
917 featuredSinglePortraitPredicates.Limit(operationItem.GetSingle(0), operationItem.GetSingle(1));
918 break;
919 }
920 default: {
921 break;
922 }
923 }
924 }
925
926 if (isFeaturedSinglePortrait) {
927 predicates = featuredSinglePortraitPredicates;
928 }
929 return isFeaturedSinglePortrait;
930 }
931
GetFeaturedSinglePortraitAlbumPredicates(const int32_t albumId,DataSharePredicates & predicates)932 int32_t SendableMediaLibraryNapiUtils::GetFeaturedSinglePortraitAlbumPredicates(
933 const int32_t albumId, DataSharePredicates &predicates)
934 {
935 string onClause = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID + " = " +
936 ANALYSIS_PHOTO_MAP_TABLE + "." + PhotoMap::ASSET_ID;
937 predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On({ onClause });
938
939 constexpr int32_t minSize = 224;
940 string imgHeightColumn = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_HEIGHT;
941 string imgWidthColumn = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_WIDTH;
942 string imgFaceHeightColumn = VISION_IMAGE_FACE_TABLE + "." + SCALE_HEIGHT;
943 string imgFaceWidthColumn = VISION_IMAGE_FACE_TABLE + "." + SCALE_WIDTH;
944 string imgFaceHeightClause = "( " + imgFaceHeightColumn + " > " + to_string(minSize) +
945 " OR ( " + imgFaceHeightColumn + " <= 1.0 " + " AND " + imgFaceHeightColumn + " * " + imgHeightColumn +
946 " > " + to_string(minSize) + " ) )";
947 string imgFaceWidthClause = "( " + imgFaceWidthColumn + " > " + to_string(minSize) +
948 " OR ( " + imgFaceWidthColumn + " <= 1.0 " + " AND " + imgFaceWidthColumn + " * " + imgWidthColumn +
949 " > " + to_string(minSize) + " ) )";
950 string imgFaceOcclusionClause = "( " + VISION_IMAGE_FACE_TABLE + "." + FACE_OCCLUSION + " != 1 OR " +
951 VISION_IMAGE_FACE_TABLE + "." + FACE_OCCLUSION + " IS NULL )";
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 " + imgFaceOcclusionClause + " 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