/* * Copyright (C) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define MLOG_TAG "MediaLibraryNapiUtils" #include "medialibrary_napi_utils.h" #include #include "basic/result_set.h" #include "datashare_predicates.h" #include "location_column.h" #include "ipc_skeleton.h" #include "js_proxy.h" #include "cloud_enhancement_napi.h" #include "cloud_media_asset_manager_napi.h" #include "highlight_album_napi.h" #include "media_asset_change_request_napi.h" #include "media_assets_change_request_napi.h" #include "media_album_change_request_napi.h" #include "media_asset_manager_napi.h" #include "media_device_column.h" #include "media_file_uri.h" #include "media_file_utils.h" #include "media_library_napi.h" #include "medialibrary_client_errno.h" #include "medialibrary_db_const.h" #include "medialibrary_errno.h" #include "medialibrary_tracer.h" #include "medialibrary_type_const.h" #include "moving_photo_napi.h" #include "photo_album_napi.h" #include "photo_map_column.h" #include "smart_album_napi.h" #include "tokenid_kit.h" #include "userfile_client.h" #include "vision_album_column.h" #include "vision_column.h" #include "vision_face_tag_column.h" #include "vision_pose_column.h" #include "vision_image_face_column.h" using namespace std; using namespace OHOS::DataShare; namespace OHOS { namespace Media { static const string EMPTY_STRING = ""; using json = nlohmann::json; napi_value MediaLibraryNapiUtils::NapiDefineClass(napi_env env, napi_value exports, const NapiClassInfo &info) { napi_value ctorObj; NAPI_CALL(env, napi_define_class(env, info.name.c_str(), NAPI_AUTO_LENGTH, info.constructor, nullptr, info.props.size(), info.props.data(), &ctorObj)); NAPI_CALL(env, napi_create_reference(env, ctorObj, NAPI_INIT_REF_COUNT, info.ref)); NAPI_CALL(env, napi_set_named_property(env, exports, info.name.c_str(), ctorObj)); return exports; } napi_value MediaLibraryNapiUtils::NapiAddStaticProps(napi_env env, napi_value exports, const vector &staticProps) { NAPI_CALL(env, napi_define_properties(env, exports, staticProps.size(), staticProps.data())); return exports; } napi_status MediaLibraryNapiUtils::GetUInt32(napi_env env, napi_value arg, uint32_t &value) { napi_valuetype valueType = napi_undefined; CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type"); CHECK_COND_RET(valueType == napi_number, napi_number_expected, "Type is not as expected number"); CHECK_STATUS_RET(napi_get_value_uint32(env, arg, &value), "Failed to get uint32 value"); return napi_ok; } napi_status MediaLibraryNapiUtils::GetInt32(napi_env env, napi_value arg, int32_t &value) { napi_valuetype valueType = napi_undefined; CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type"); CHECK_COND_RET(valueType == napi_number, napi_number_expected, "Type is not as expected number"); CHECK_STATUS_RET(napi_get_value_int32(env, arg, &value), "Failed to get int32 value"); return napi_ok; } napi_status MediaLibraryNapiUtils::GetDouble(napi_env env, napi_value arg, double &value) { napi_valuetype valueType = napi_undefined; CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type"); CHECK_COND_RET(valueType == napi_number, napi_number_expected, "Type is not as expected number"); CHECK_STATUS_RET(napi_get_value_double(env, arg, &value), "Failed to get double value"); return napi_ok; } napi_status MediaLibraryNapiUtils::GetParamBool(napi_env env, napi_value arg, bool &value) { napi_valuetype valueType = napi_undefined; CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type"); CHECK_COND_RET(valueType == napi_boolean, napi_boolean_expected, "Type is not as expected boolean"); CHECK_STATUS_RET(napi_get_value_bool(env, arg, &value), "Failed to get param"); return napi_ok; } napi_status MediaLibraryNapiUtils::GetUInt32Array(napi_env env, napi_value arg, vector &result) { uint32_t arraySize = 0; CHECK_COND_RET(IsArrayForNapiValue(env, arg, arraySize), napi_array_expected, "Failed to check array type"); for (uint32_t i = 0; i < arraySize; i++) { napi_value val = nullptr; CHECK_STATUS_RET(napi_get_element(env, arg, i, &val), "Failed to get element"); uint32_t value = 0; CHECK_STATUS_RET(GetUInt32(env, val, value), "Failed to get element value"); result.push_back(value); } return napi_ok; } napi_status MediaLibraryNapiUtils::GetParamFunction(napi_env env, napi_value arg, napi_ref &callbackRef) { napi_valuetype valueType = napi_undefined; CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type"); CHECK_COND_RET(valueType == napi_function, napi_function_expected, "Type is not as expected function"); CHECK_STATUS_RET(napi_create_reference(env, arg, NAPI_INIT_REF_COUNT, &callbackRef), "Failed to make callbackref"); return napi_ok; } static napi_status GetParamStr(napi_env env, napi_value arg, const size_t size, string &result) { size_t res = 0; unique_ptr buffer = make_unique(size); CHECK_COND_RET(buffer != nullptr, napi_invalid_arg, "Failed to alloc buffer for parameter"); napi_valuetype valueType = napi_undefined; CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type"); CHECK_COND_RET(valueType == napi_string, napi_string_expected, "Type is not as expected string"); CHECK_STATUS_RET(napi_get_value_string_utf8(env, arg, buffer.get(), size, &res), "Failed to get string value"); result = string(buffer.get()); return napi_ok; } napi_status MediaLibraryNapiUtils::GetParamStringWithLength(napi_env env, napi_value arg, int32_t maxLen, string &result) { CHECK_STATUS_RET(GetParamStr(env, arg, maxLen, result), "Failed to get string parameter"); return napi_ok; } napi_status MediaLibraryNapiUtils::GetParamStringPathMax(napi_env env, napi_value arg, string &result) { CHECK_STATUS_RET(GetParamStr(env, arg, PATH_MAX, result), "Failed to get string parameter"); return napi_ok; } napi_status MediaLibraryNapiUtils::GetProperty(napi_env env, const napi_value arg, const string &propName, string &propValue) { bool present = false; napi_value property = nullptr; CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present), "Failed to check property name"); if (present) { CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property), "Failed to get property"); CHECK_STATUS_RET(GetParamStringPathMax(env, property, propValue), "Failed to get string buffer"); } return napi_ok; } napi_status MediaLibraryNapiUtils::GetStringArray(napi_env env, napi_value arg, vector &array) { bool isArray = false; uint32_t len = 0; CHECK_STATUS_RET(napi_is_array(env, arg, &isArray), "Failed to check array type"); CHECK_COND_RET(isArray, napi_array_expected, "Expected array type"); CHECK_STATUS_RET(napi_get_array_length(env, arg, &len), "Failed to get array length"); for (uint32_t i = 0; i < len; i++) { napi_value item = nullptr; string val; CHECK_STATUS_RET(napi_get_element(env, arg, i, &item), "Failed to get array item"); CHECK_STATUS_RET(GetParamStringPathMax(env, item, val), "Failed to get string buffer"); array.push_back(val); } return napi_ok; } napi_status MediaLibraryNapiUtils::GetArrayProperty(napi_env env, napi_value arg, const string &propName, vector &array) { bool present = false; CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present), "Failed to check property name"); if (present) { napi_value property = nullptr; CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property), "Failed to get selectionArgs property"); GetStringArray(env, property, array); } return napi_ok; } napi_status MediaLibraryNapiUtils::HasCallback(napi_env env, const size_t argc, const napi_value argv[], bool &isCallback) { isCallback = false; if (argc < ARGS_ONE) { return napi_ok; } napi_valuetype valueType = napi_undefined; CHECK_STATUS_RET(napi_typeof(env, argv[argc - 1], &valueType), "Failed to get type"); isCallback = (valueType == napi_function); return napi_ok; } napi_status MediaLibraryNapiUtils::hasFetchOpt(napi_env env, const napi_value arg, bool &hasFetchOpt) { hasFetchOpt = false; napi_valuetype valueType = napi_undefined; CHECK_STATUS_RET(napi_typeof(env, arg, &valueType), "Failed to get type"); if (valueType != napi_object) { hasFetchOpt = false; return napi_ok; } CHECK_STATUS_RET(napi_has_named_property(env, arg, "selections", &hasFetchOpt), "Failed to get property selections"); return napi_ok; } void MediaLibraryNapiUtils::UriAddTableName(string &uri, const string tableName) { if (!tableName.empty()) { uri += "/" + tableName; } } string MediaLibraryNapiUtils::GetFileIdFromUri(const string &uri) { string id = "-1"; string temp = uri; MediaFileUri::RemoveAllFragment(temp); size_t pos = temp.rfind('/'); if (pos != string::npos) { id = temp.substr(pos + 1); } return id; } int32_t MediaLibraryNapiUtils::GetFileIdFromPhotoUri(const string &uri) { const static int ERROR = -1; if (PhotoColumn::PHOTO_URI_PREFIX.size() >= uri.size()) { NAPI_ERR_LOG("photo uri is too short"); return ERROR; } if (uri.substr(0, PhotoColumn::PHOTO_URI_PREFIX.size()) != PhotoColumn::PHOTO_URI_PREFIX) { NAPI_ERR_LOG("only photo uri is valid"); return ERROR; } std::string tmp = uri.substr(PhotoColumn::PHOTO_URI_PREFIX.size()); std::string fileIdStr = tmp.substr(0, tmp.find_first_of('/')); if (fileIdStr.empty()) { NAPI_ERR_LOG("intercepted fileId is empty"); return ERROR; } if (std::all_of(fileIdStr.begin(), fileIdStr.end(), ::isdigit)) { return std::stoi(fileIdStr); } NAPI_ERR_LOG("asset fileId is invalid"); return ERROR; } MediaType MediaLibraryNapiUtils::GetMediaTypeFromUri(const string &uri) { if (uri.find(MEDIALIBRARY_IMAGE_URI) != string::npos) { return MediaType::MEDIA_TYPE_IMAGE; } else if (uri.find(MEDIALIBRARY_VIDEO_URI) != string::npos) { return MediaType::MEDIA_TYPE_VIDEO; } else if (uri.find(MEDIALIBRARY_AUDIO_URI) != string::npos) { return MediaType::MEDIA_TYPE_AUDIO; } else if (uri.find(MEDIALIBRARY_FILE_URI) != string::npos) { return MediaType::MEDIA_TYPE_FILE; } return MediaType::MEDIA_TYPE_ALL; } static bool HandleSpecialDateTypePredicate(const OperationItem &item, vector &operations, const FetchOptionType &fetchOptType) { constexpr int32_t FIELD_IDX = 0; constexpr int32_t VALUE_IDX = 1; vectordateTypes = { MEDIA_DATA_DB_DATE_ADDED, MEDIA_DATA_DB_DATE_TRASHED, MEDIA_DATA_DB_DATE_MODIFIED, MEDIA_DATA_DB_DATE_TAKEN }; string dateType = item.GetSingle(FIELD_IDX); auto it = find(dateTypes.begin(), dateTypes.end(), dateType); if (it != dateTypes.end() && item.operation != DataShare::ORDER_BY_ASC && item.operation != DataShare::ORDER_BY_DESC) { dateType += "_s"; operations.push_back({ item.operation, { dateType, static_cast(item.GetSingle(VALUE_IDX)) } }); return true; } if (DATE_TRANSITION_MAP.count(dateType) != 0) { dateType = DATE_TRANSITION_MAP.at(dateType); operations.push_back({ item.operation, { dateType, static_cast(item.GetSingle(VALUE_IDX)) } }); return true; } return false; } template bool MediaLibraryNapiUtils::HandleSpecialPredicate(AsyncContext &context, shared_ptr &predicate, const FetchOptionType &fetchOptType) { constexpr int32_t FIELD_IDX = 0; constexpr int32_t VALUE_IDX = 1; vector operations; auto &items = predicate->GetOperationList(); for (auto &item : items) { if (item.singleParams.empty()) { operations.push_back(item); continue; } if (HandleSpecialDateTypePredicate(item, operations, fetchOptType)) { continue; } // change uri ->file id // get networkid // replace networkid with file id if (static_cast(item.GetSingle(FIELD_IDX)) == DEVICE_DB_NETWORK_ID) { if (item.operation != DataShare::EQUAL_TO || static_cast(item.GetSingle(VALUE_IDX)).empty()) { NAPI_ERR_LOG("DEVICE_DB_NETWORK_ID predicates not support %{public}d", item.operation); return false; } context->networkId = static_cast(item.GetSingle(VALUE_IDX)); continue; } if (static_cast(item.GetSingle(FIELD_IDX)) == MEDIA_DATA_DB_URI) { if (item.operation != DataShare::EQUAL_TO) { NAPI_ERR_LOG("MEDIA_DATA_DB_URI predicates not support %{public}d", item.operation); return false; } string uri = static_cast(item.GetSingle(VALUE_IDX)); MediaFileUri::RemoveAllFragment(uri); MediaFileUri fileUri(uri); context->uri = uri; if ((fetchOptType != ALBUM_FETCH_OPT) && (!fileUri.IsApi10())) { fileUri = MediaFileUri(MediaFileUtils::GetRealUriFromVirtualUri(uri)); } context->networkId = fileUri.GetNetworkId(); string field = (fetchOptType == ALBUM_FETCH_OPT) ? PhotoAlbumColumns::ALBUM_ID : MEDIA_DATA_DB_ID; operations.push_back({ item.operation, { field, fileUri.GetFileId() } }); continue; } if (static_cast(item.GetSingle(FIELD_IDX)) == PENDING_STATUS) { // do not query pending files below API11 continue; } if (LOCATION_PARAM_MAP.find(static_cast(item.GetSingle(FIELD_IDX))) != LOCATION_PARAM_MAP.end()) { continue; } operations.push_back(item); } context->predicates = DataSharePredicates(move(operations)); return true; } template bool MediaLibraryNapiUtils::GetLocationPredicate(AsyncContext &context, shared_ptr &predicate) { constexpr int32_t FIELD_IDX = 0; constexpr int32_t VALUE_IDX = 1; map locationMap; auto &items = predicate->GetOperationList(); for (auto &item : items) { if (item.singleParams.empty()) { continue; } if (LOCATION_PARAM_MAP.find(static_cast(item.GetSingle(FIELD_IDX))) != LOCATION_PARAM_MAP.end()) { if (item.operation != DataShare::EQUAL_TO) { NAPI_ERR_LOG("location predicates not support %{public}d", item.operation); return false; } string param = static_cast(item.GetSingle(FIELD_IDX)); string value = static_cast(item.GetSingle(VALUE_IDX)); locationMap.insert(make_pair(param, value)); if (param == DIAMETER) { continue; } if (LOCATION_PARAM_MAP.at(param).second == DataShare::GREATER_THAN_OR_EQUAL_TO) { context->predicates.GreaterThanOrEqualTo(LOCATION_PARAM_MAP.at(param).first, value); continue; } if (LOCATION_PARAM_MAP.at(param).second == DataShare::LESS_THAN) { context->predicates.LessThan(LOCATION_PARAM_MAP.at(param).first, value); continue; } if (LOCATION_PARAM_MAP.at(param).second == DataShare::EQUAL_TO) { context->predicates.EqualTo(LOCATION_PARAM_MAP.at(param).first, value); continue; } } } if (locationMap.count(DIAMETER) == 1 && locationMap.count(START_LATITUDE) == 1 && locationMap.count(START_LONGITUDE) == 1) { // 0.5:Used for rounding down string latitudeIndex = "round((latitude - " + locationMap.at(START_LATITUDE) + ") / " + locationMap.at(DIAMETER) + " - 0.5)"; string longitudeIndex = "round((longitude - " + locationMap.at(START_LONGITUDE) + ") / " + locationMap.at(DIAMETER) + " - 0.5)"; string albumName = LATITUDE + "||'_'||" + LONGITUDE + "||'_'||" + latitudeIndex + "||'_'||" + longitudeIndex + " AS " + ALBUM_NAME; context->fetchColumn.push_back(albumName); string locationGroup = latitudeIndex + "," + longitudeIndex; context->predicates.GroupBy({ locationGroup }); } return true; } template napi_status MediaLibraryNapiUtils::GetFetchOption(napi_env env, napi_value arg, const FetchOptionType &fetchOptType, AsyncContext &context) { // Parse the argument into fetchOption if any CHECK_STATUS_RET(GetPredicate(env, arg, "predicates", context, fetchOptType), "invalid predicate"); CHECK_STATUS_RET(GetArrayProperty(env, arg, "fetchColumns", context->fetchColumn), "Failed to parse fetchColumn"); return napi_ok; } template napi_status MediaLibraryNapiUtils::GetAlbumFetchOption(napi_env env, napi_value arg, const FetchOptionType &fetchOptType, AsyncContext &context) { // Parse the argument into AlbumFetchOption if any CHECK_STATUS_RET(GetPredicate(env, arg, "predicates", context, fetchOptType), "invalid predicate"); return napi_ok; } template napi_status MediaLibraryNapiUtils::GetPredicate(napi_env env, const napi_value arg, const string &propName, AsyncContext &context, const FetchOptionType &fetchOptType) { bool present = false; napi_value property = nullptr; CHECK_STATUS_RET(napi_has_named_property(env, arg, propName.c_str(), &present), "Failed to check property name"); if (present) { CHECK_STATUS_RET(napi_get_named_property(env, arg, propName.c_str(), &property), "Failed to get property"); JSProxy::JSProxy *jsProxy = nullptr; napi_unwrap(env, property, reinterpret_cast(&jsProxy)); if (jsProxy == nullptr) { NAPI_ERR_LOG("jsProxy is invalid"); return napi_invalid_arg; } shared_ptr predicate = jsProxy->GetInstance(); CHECK_COND_RET(HandleSpecialPredicate(context, predicate, fetchOptType) == TRUE, napi_invalid_arg, "invalid predicate"); CHECK_COND_RET(GetLocationPredicate(context, predicate) == TRUE, napi_invalid_arg, "invalid predicate"); } return napi_ok; } template napi_status MediaLibraryNapiUtils::ParseAssetFetchOptCallback(napi_env env, napi_callback_info info, AsyncContext &context) { constexpr size_t minArgs = ARGS_ONE; constexpr size_t maxArgs = ARGS_TWO; CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs), "Failed to get object info"); CHECK_STATUS_RET(GetFetchOption(env, context->argv[PARAM0], ASSET_FETCH_OPT, context), "Failed to get fetch option"); return napi_ok; } template napi_status MediaLibraryNapiUtils::ParseAlbumFetchOptCallback(napi_env env, napi_callback_info info, AsyncContext &context) { constexpr size_t minArgs = ARGS_ONE; constexpr size_t maxArgs = ARGS_TWO; CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs), "Failed to get object info"); // Parse the argument into fetchOption if any CHECK_STATUS_RET(GetPredicate(env, context->argv[PARAM0], "predicates", context, ALBUM_FETCH_OPT), "invalid predicate"); context->predicates.And()->NotEqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::HIDDEN)); return napi_ok; } template void MediaLibraryNapiUtils::UpdateMediaTypeSelections(AsyncContext *context) { constexpr int FIRST_MEDIA_TYPE = 0; constexpr int SECOND_MEDIA_TYPE = 1; if ((context->mediaTypes.size() != ARGS_ONE) && (context->mediaTypes.size() != ARGS_TWO)) { return; } DataShare::DataSharePredicates &predicates = context->predicates; predicates.BeginWrap(); predicates.EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, (int)context->mediaTypes[FIRST_MEDIA_TYPE]); if (context->mediaTypes.size() == ARGS_TWO) { predicates.Or()->EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, (int)context->mediaTypes[SECOND_MEDIA_TYPE]); } predicates.EndWrap(); } template napi_status MediaLibraryNapiUtils::AsyncContextSetObjectInfo(napi_env env, napi_callback_info info, AsyncContext &asyncContext, const size_t minArgs, const size_t maxArgs) { napi_value thisVar = nullptr; asyncContext->argc = maxArgs; CHECK_STATUS_RET(napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), &thisVar, nullptr), "Failed to get cb info"); CHECK_COND_RET(((asyncContext->argc >= minArgs) && (asyncContext->argc <= maxArgs)), napi_invalid_arg, "Number of args is invalid"); if (minArgs > 0) { CHECK_COND_RET(asyncContext->argv[ARGS_ZERO] != nullptr, napi_invalid_arg, "Argument list is empty"); } CHECK_STATUS_RET(napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)), "Failed to unwrap thisVar"); CHECK_COND_RET(asyncContext->objectInfo != nullptr, napi_invalid_arg, "Failed to get object info"); CHECK_STATUS_RET(GetParamCallback(env, asyncContext), "Failed to get callback param!"); return napi_ok; } template napi_status MediaLibraryNapiUtils::AsyncContextGetArgs(napi_env env, napi_callback_info info, AsyncContext &asyncContext, const size_t minArgs, const size_t maxArgs) { asyncContext->argc = maxArgs; CHECK_STATUS_RET(napi_get_cb_info(env, info, &asyncContext->argc, &(asyncContext->argv[ARGS_ZERO]), nullptr, nullptr), "Failed to get cb info"); CHECK_COND_RET(asyncContext->argc >= minArgs && asyncContext->argc <= maxArgs, napi_invalid_arg, "Number of args is invalid"); if (minArgs > 0) { CHECK_COND_RET(asyncContext->argv[ARGS_ZERO] != nullptr, napi_invalid_arg, "Argument list is empty"); } CHECK_STATUS_RET(GetParamCallback(env, asyncContext), "Failed to get callback param"); return napi_ok; } template napi_status MediaLibraryNapiUtils::GetParamCallback(napi_env env, AsyncContext &context) { /* Parse the last argument into callbackref if any */ bool isCallback = false; CHECK_STATUS_RET(HasCallback(env, context->argc, context->argv, isCallback), "Failed to check callback"); if (isCallback) { CHECK_STATUS_RET(GetParamFunction(env, context->argv[context->argc - 1], context->callbackRef), "Failed to get callback"); } return napi_ok; } template napi_status MediaLibraryNapiUtils::ParseArgsBoolCallBack(napi_env env, napi_callback_info info, AsyncContext &context, bool ¶m) { constexpr size_t minArgs = ARGS_ONE; constexpr size_t maxArgs = ARGS_TWO; CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs), "Failed to get object info"); /* Parse the first argument into param */ CHECK_STATUS_RET(GetParamBool(env, context->argv[ARGS_ZERO], param), "Failed to get parameter"); return napi_ok; } template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback(napi_env env, napi_callback_info info, AsyncContext &context, string ¶m) { constexpr size_t minArgs = ARGS_ONE; constexpr size_t maxArgs = ARGS_TWO; CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs), "Failed to get object info"); CHECK_STATUS_RET(GetParamStringPathMax(env, context->argv[ARGS_ZERO], param), "Failed to get string argument"); return napi_ok; } template napi_status MediaLibraryNapiUtils::ParseArgsStringArrayCallback(napi_env env, napi_callback_info info, AsyncContext &context, vector &array) { constexpr size_t minArgs = ARGS_ONE; constexpr size_t maxArgs = ARGS_TWO; CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs), "Failed to get object info"); CHECK_STATUS_RET(GetStringArray(env, context->argv[ARGS_ZERO], array), "Failed to get string array"); CHECK_STATUS_RET(GetParamCallback(env, context), "Failed to get callback"); return napi_ok; } template napi_status MediaLibraryNapiUtils::ParseArgsNumberCallback(napi_env env, napi_callback_info info, AsyncContext &context, int32_t &value) { constexpr size_t minArgs = ARGS_ONE; constexpr size_t maxArgs = ARGS_TWO; CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs), "Failed to get object info"); CHECK_STATUS_RET(GetInt32(env, context->argv[ARGS_ZERO], value), "Failed to get number argument"); return napi_ok; } template napi_status MediaLibraryNapiUtils::ParseArgsOnlyCallBack(napi_env env, napi_callback_info info, AsyncContext &context) { constexpr size_t minArgs = ARGS_ZERO; constexpr size_t maxArgs = ARGS_ONE; CHECK_STATUS_RET(AsyncContextSetObjectInfo(env, info, context, minArgs, maxArgs), "Failed to get object info"); return napi_ok; } AssetType MediaLibraryNapiUtils::GetAssetType(MediaType type) { AssetType result; switch (type) { case MEDIA_TYPE_AUDIO: result = ASSET_AUDIO; break; case MEDIA_TYPE_VIDEO: result = ASSET_VIDEO; break; case MEDIA_TYPE_IMAGE: result = ASSET_IMAGE; break; case MEDIA_TYPE_MEDIA: result = ASSET_MEDIA; break; default: result = ASSET_NONE; break; } return result; } void MediaLibraryNapiUtils::AppendFetchOptionSelection(string &selection, const string &newCondition) { if (!newCondition.empty()) { if (!selection.empty()) { selection = "(" + selection + ") AND " + newCondition; } else { selection = newCondition; } } } int MediaLibraryNapiUtils::TransErrorCode(const string &Name, shared_ptr resultSet) { NAPI_ERR_LOG("interface: %{public}s, server return nullptr", Name.c_str()); // Query can't return errorcode, so assume nullptr as permission deny if (resultSet == nullptr) { return JS_ERR_PERMISSION_DENIED; } return ERR_DEFAULT; } int MediaLibraryNapiUtils::TransErrorCode(const string &Name, int error) { NAPI_ERR_LOG("interface: %{public}s, server errcode:%{public}d ", Name.c_str(), error); // Transfer Server error to napi error code if (error <= E_COMMON_START && error >= E_COMMON_END) { error = JS_INNER_FAIL; } else if (trans2JsError.count(error)) { error = trans2JsError.at(error); } return error; } void MediaLibraryNapiUtils::HandleError(napi_env env, int error, napi_value &errorObj, const string &Name) { if (error == ERR_DEFAULT) { return; } string errMsg = "System inner fail"; int originalError = error; if (jsErrMap.count(error) > 0) { errMsg = jsErrMap.at(error); } else { error = JS_INNER_FAIL; } CreateNapiErrorObject(env, errorObj, error, errMsg); errMsg = Name + " " + errMsg; NAPI_ERR_LOG("Error: %{public}s, js errcode:%{public}d ", errMsg.c_str(), originalError); } void MediaLibraryNapiUtils::CreateNapiErrorObject(napi_env env, napi_value &errorObj, const int32_t errCode, const string errMsg) { napi_status statusError; napi_value napiErrorCode = nullptr; napi_value napiErrorMsg = nullptr; statusError = napi_create_string_utf8(env, to_string(errCode).c_str(), NAPI_AUTO_LENGTH, &napiErrorCode); if (statusError == napi_ok) { statusError = napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &napiErrorMsg); if (statusError == napi_ok) { statusError = napi_create_error(env, napiErrorCode, napiErrorMsg, &errorObj); if (statusError == napi_ok) { NAPI_DEBUG_LOG("napi_create_error success"); } } } } void MediaLibraryNapiUtils::InvokeJSAsyncMethod(napi_env env, napi_deferred deferred, napi_ref callbackRef, napi_async_work work, const JSAsyncContextOutput &asyncContext) { MediaLibraryTracer tracer; tracer.Start("InvokeJSAsyncMethod"); napi_value retVal; napi_value callback = nullptr; /* Deferred is used when JS Callback method expects a promise value */ if (deferred) { if (asyncContext.status) { napi_resolve_deferred(env, deferred, asyncContext.data); } else { napi_reject_deferred(env, deferred, asyncContext.error); } } else { napi_value result[ARGS_TWO]; result[PARAM0] = asyncContext.error; result[PARAM1] = asyncContext.data; napi_get_reference_value(env, callbackRef, &callback); napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal); napi_delete_reference(env, callbackRef); } napi_delete_async_work(env, work); } template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr &asyncContext, const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)) { napi_value result = nullptr; napi_value resource = nullptr; NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); NAPI_CREATE_RESOURCE_NAME(env, resource, resourceName.c_str(), asyncContext); NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, execute, complete, static_cast(asyncContext.get()), &asyncContext->work)); NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated)); asyncContext.release(); return result; } tuple, size_t> MediaLibraryNapiUtils::ToUTF8String(napi_env env, napi_value value) { size_t strLen = 0; napi_status status = napi_get_value_string_utf8(env, value, nullptr, -1, &strLen); if (status != napi_ok) { NAPI_ERR_LOG("ToUTF8String get fail, %{public}d", status); return { false, nullptr, 0 }; } size_t bufLen = strLen + 1; unique_ptr str = make_unique(bufLen); if (str == nullptr) { NAPI_ERR_LOG("ToUTF8String get memory fail"); return { false, nullptr, 0 }; } status = napi_get_value_string_utf8(env, value, str.get(), bufLen, &strLen); return make_tuple(status == napi_ok, move(str), strLen); } bool MediaLibraryNapiUtils::IsExistsByPropertyName(napi_env env, napi_value jsObject, const char *propertyName) { bool result = false; if (napi_has_named_property(env, jsObject, propertyName, &result) == napi_ok) { return result; } else { NAPI_ERR_LOG("IsExistsByPropertyName not exist %{public}s", propertyName); return false; } } napi_value MediaLibraryNapiUtils::GetPropertyValueByName(napi_env env, napi_value jsObject, const char *propertyName) { napi_value value = nullptr; if (IsExistsByPropertyName(env, jsObject, propertyName) == false) { NAPI_ERR_LOG("GetPropertyValueByName not exist %{public}s", propertyName); return nullptr; } if (napi_get_named_property(env, jsObject, propertyName, &value) != napi_ok) { NAPI_ERR_LOG("GetPropertyValueByName get fail %{public}s", propertyName); return nullptr; } return value; } bool MediaLibraryNapiUtils::CheckJSArgsTypeAsFunc(napi_env env, napi_value arg) { napi_valuetype valueType = napi_undefined; napi_typeof(env, arg, &valueType); return (valueType == napi_function); } bool MediaLibraryNapiUtils::IsArrayForNapiValue(napi_env env, napi_value param, uint32_t &arraySize) { bool isArray = false; arraySize = 0; if ((napi_is_array(env, param, &isArray) != napi_ok) || (isArray == false)) { return false; } if (napi_get_array_length(env, param, &arraySize) != napi_ok) { return false; } return true; } napi_value MediaLibraryNapiUtils::GetInt32Arg(napi_env env, napi_value arg, int32_t &value) { napi_valuetype valueType = napi_undefined; CHECK_ARGS(env, napi_typeof(env, arg, &valueType), JS_INNER_FAIL); if (valueType != napi_number) { NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID); return nullptr; } CHECK_ARGS(env, napi_get_value_int32(env, arg, &value), JS_INNER_FAIL); napi_value result = nullptr; CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL); return result; } void MediaLibraryNapiUtils::UriAppendKeyValue(string &uri, const string &key, const string &value) { string uriKey = key + '='; if (uri.find(uriKey) != string::npos) { return; } char queryMark = (uri.find('?') == string::npos) ? '?' : '&'; string append = queryMark + key + '=' + value; size_t posJ = uri.find('#'); if (posJ == string::npos) { uri += append; } else { uri.insert(posJ, append); } } napi_value MediaLibraryNapiUtils::AddDefaultAssetColumns(napi_env env, vector &fetchColumn, function isValidColumn, NapiAssetType assetType, const PhotoAlbumSubType subType) { auto validFetchColumns = MediaColumn::DEFAULT_FETCH_COLUMNS; if (assetType == TYPE_PHOTO) { validFetchColumns.insert( PhotoColumn::DEFAULT_FETCH_COLUMNS.begin(), PhotoColumn::DEFAULT_FETCH_COLUMNS.end()); } switch (subType) { case PhotoAlbumSubType::FAVORITE: validFetchColumns.insert(MediaColumn::MEDIA_IS_FAV); break; case PhotoAlbumSubType::VIDEO: validFetchColumns.insert(MediaColumn::MEDIA_TYPE); break; case PhotoAlbumSubType::HIDDEN: validFetchColumns.insert(MediaColumn::MEDIA_HIDDEN); break; case PhotoAlbumSubType::TRASH: validFetchColumns.insert(MediaColumn::MEDIA_DATE_TRASHED); break; case PhotoAlbumSubType::SCREENSHOT: case PhotoAlbumSubType::CAMERA: validFetchColumns.insert(PhotoColumn::PHOTO_SUBTYPE); break; default: break; } for (const auto &column : fetchColumn) { if (column == PENDING_STATUS) { validFetchColumns.insert(MediaColumn::MEDIA_TIME_PENDING); } else if (isValidColumn(column)) { validFetchColumns.insert(column); } else if (column == MEDIA_DATA_DB_URI) { continue; } else if (DATE_TRANSITION_MAP.count(column) != 0) { validFetchColumns.insert(DATE_TRANSITION_MAP.at(column)); } else { NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID); return nullptr; } } fetchColumn.assign(validFetchColumns.begin(), validFetchColumns.end()); napi_value result = nullptr; CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL); return result; } inline void SetDefaultPredicatesCondition(DataSharePredicates &predicates, const int32_t dateTrashed, const bool isHidden, const int32_t timePending, const bool isTemp) { predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, to_string(dateTrashed)); predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, to_string(isHidden)); predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, to_string(timePending)); predicates.EqualTo(PhotoColumn::PHOTO_IS_TEMP, to_string(isTemp)); predicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL, to_string(static_cast(BurstCoverLevelType::COVER))); } int32_t MediaLibraryNapiUtils::GetUserAlbumPredicates( const int32_t albumId, DataSharePredicates &predicates, const bool hiddenOnly) { predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(albumId)); SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false); return E_SUCCESS; } int32_t MediaLibraryNapiUtils::GetPortraitAlbumPredicates(const int32_t albumId, DataSharePredicates &predicates) { string onClause = MediaColumn::MEDIA_ID + " = " + PhotoMap::ASSET_ID; vector clauses = { onClause }; predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On(clauses); onClause = ALBUM_ID + " = " + PhotoMap::ALBUM_ID; clauses = { onClause }; predicates.InnerJoin(ANALYSIS_ALBUM_TABLE)->On(clauses); string tempTable = "(SELECT " + GROUP_TAG + " FROM " + ANALYSIS_ALBUM_TABLE + " WHERE " + ALBUM_ID + " = " + to_string(albumId) + ") ag"; onClause = "ag." + GROUP_TAG + " = " + ANALYSIS_ALBUM_TABLE + "." + GROUP_TAG; clauses = { onClause }; predicates.InnerJoin(tempTable)->On(clauses); SetDefaultPredicatesCondition(predicates, 0, 0, 0, false); predicates.Distinct(); return E_SUCCESS; } int32_t MediaLibraryNapiUtils::GetAnalysisAlbumPredicates(const int32_t albumId, DataSharePredicates &predicates) { string onClause = MediaColumn::MEDIA_ID + " = " + PhotoMap::ASSET_ID; predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On({ onClause }); predicates.EqualTo(PhotoMap::ALBUM_ID, to_string(albumId)); SetDefaultPredicatesCondition(predicates, 0, 0, 0, false); return E_SUCCESS; } bool MediaLibraryNapiUtils::IsFeaturedSinglePortraitAlbum( std::string albumName, DataShare::DataSharePredicates &predicates) { bool isFeaturedSinglePortrait = false; int portraitAlbumId = 0; if (albumName.compare(to_string(portraitAlbumId)) != 0) { return isFeaturedSinglePortrait; } DataSharePredicates featuredSinglePortraitPredicates; std::vector operationList = predicates.GetOperationList(); for (auto& operationItem : operationList) { switch (operationItem.operation) { case OHOS::DataShare::OperationType::LIKE : { std::string field = std::get(operationItem.singleParams[0]); std::string value = std::get(operationItem.singleParams[1]); if (field.compare("FeaturedSinglePortrait") == 0 && value.compare("true") == 0) { isFeaturedSinglePortrait = true; } else { featuredSinglePortraitPredicates.Like(field, value); } break; } case OHOS::DataShare::OperationType::ORDER_BY_DESC : { featuredSinglePortraitPredicates.OrderByDesc(operationItem.GetSingle(0)); break; } case OHOS::DataShare::OperationType::LIMIT : { featuredSinglePortraitPredicates.Limit(operationItem.GetSingle(0), operationItem.GetSingle(1)); break; } default: { break; } } } if (isFeaturedSinglePortrait) { predicates = featuredSinglePortraitPredicates; } return isFeaturedSinglePortrait; } int32_t MediaLibraryNapiUtils::GetFeaturedSinglePortraitAlbumPredicates( const int32_t albumId, DataSharePredicates &predicates) { string onClause = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID + " = " + ANALYSIS_PHOTO_MAP_TABLE + "." + PhotoMap::ASSET_ID; predicates.InnerJoin(ANALYSIS_PHOTO_MAP_TABLE)->On({ onClause }); constexpr int32_t minSize = 224; string imgHeightColumn = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_HEIGHT; string imgWidthColumn = PhotoColumn::PHOTOS_TABLE + "." + PhotoColumn::PHOTO_WIDTH; string imgFaceHeightColumn = VISION_IMAGE_FACE_TABLE + "." + SCALE_HEIGHT; string imgFaceWidthColumn = VISION_IMAGE_FACE_TABLE + "." + SCALE_WIDTH; string imgFaceHeightClause = "( " + imgFaceHeightColumn + " > " + to_string(minSize) + " OR ( " + imgFaceHeightColumn + " <= 1.0 " + " AND " + imgFaceHeightColumn + " * " + imgHeightColumn + " > " + to_string(minSize) + " ) )"; string imgFaceWidthClause = "( " + imgFaceWidthColumn + " > " + to_string(minSize) + " OR ( " + imgFaceWidthColumn + " <= 1.0 " + " AND " + imgFaceWidthColumn + " * " + imgWidthColumn + " > " + to_string(minSize) + " ) )"; string imgFaceOcclusionClause = "( " + VISION_IMAGE_FACE_TABLE + "." + FACE_OCCLUSION + " != 1 OR " + VISION_IMAGE_FACE_TABLE + "." + FACE_OCCLUSION + " IS NULL )"; string portraitRotationLimit = "BETWEEN -30 AND 30"; onClause = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID + " = " + VISION_IMAGE_FACE_TABLE + "." + MediaColumn::MEDIA_ID + " AND " + VISION_IMAGE_FACE_TABLE + "." + TOTAL_FACES + " = 1 AND " + imgFaceHeightClause + " AND " + imgFaceWidthClause + " AND " + imgFaceOcclusionClause + " AND " + VISION_IMAGE_FACE_TABLE + "." + PITCH + " " + portraitRotationLimit + " AND " + VISION_IMAGE_FACE_TABLE + "." + YAW + " " + portraitRotationLimit + " AND " + VISION_IMAGE_FACE_TABLE + "." + ROLL + " " + portraitRotationLimit; predicates.InnerJoin(VISION_IMAGE_FACE_TABLE)->On({ onClause }); string portraitType = "IN ( 1, 2 )"; onClause = PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID + " = " + VISION_POSE_TABLE + "." + MediaColumn::MEDIA_ID + " AND " + VISION_POSE_TABLE + "." + POSE_TYPE + " " + portraitType; predicates.InnerJoin(VISION_POSE_TABLE)->On({ onClause }); predicates.EqualTo(PhotoMap::ALBUM_ID, to_string(albumId)); SetDefaultPredicatesCondition(predicates, 0, 0, 0, false); return E_SUCCESS; } int32_t MediaLibraryNapiUtils::GetAllLocationPredicates(DataSharePredicates &predicates) { SetDefaultPredicatesCondition(predicates, 0, 0, 0, false); predicates.And()->NotEqualTo(PhotoColumn::PHOTO_LATITUDE, to_string(0)); predicates.And()->NotEqualTo(PhotoColumn::PHOTO_LONGITUDE, to_string(0)); return E_SUCCESS; } static int32_t GetFavoritePredicates(DataSharePredicates &predicates, const bool hiddenOnly) { predicates.BeginWrap(); constexpr int32_t IS_FAVORITE = 1; predicates.EqualTo(MediaColumn::MEDIA_IS_FAV, to_string(IS_FAVORITE)); SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false); predicates.EndWrap(); return E_SUCCESS; } static int32_t GetVideoPredicates(DataSharePredicates &predicates, const bool hiddenOnly) { predicates.BeginWrap(); predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_VIDEO)); SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false); predicates.EndWrap(); return E_SUCCESS; } static int32_t GetHiddenPredicates(DataSharePredicates &predicates) { predicates.BeginWrap(); SetDefaultPredicatesCondition(predicates, 0, 1, 0, false); predicates.EndWrap(); return E_SUCCESS; } static int32_t GetTrashPredicates(DataSharePredicates &predicates) { predicates.BeginWrap(); predicates.GreaterThan(MediaColumn::MEDIA_DATE_TRASHED, to_string(0)); predicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL, to_string(static_cast(BurstCoverLevelType::COVER))); predicates.EndWrap(); return E_SUCCESS; } static int32_t GetScreenshotPredicates(DataSharePredicates &predicates, const bool hiddenOnly) { predicates.BeginWrap(); predicates.EqualTo(PhotoColumn::PHOTO_SUBTYPE, to_string(static_cast(PhotoSubType::SCREENSHOT))); SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false); predicates.EndWrap(); return E_SUCCESS; } static int32_t GetCameraPredicates(DataSharePredicates &predicates, const bool hiddenOnly) { predicates.BeginWrap(); predicates.EqualTo(PhotoColumn::PHOTO_SUBTYPE, to_string(static_cast(PhotoSubType::CAMERA))); SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false); predicates.EndWrap(); return E_SUCCESS; } static int32_t GetAllImagesPredicates(DataSharePredicates &predicates, const bool hiddenOnly) { predicates.BeginWrap(); predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_IMAGE)); SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false); predicates.EndWrap(); return E_SUCCESS; } static int32_t GetCloudEnhancementPredicates(DataSharePredicates &predicates, const bool hiddenOnly) { predicates.BeginWrap(); predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_IMAGE)); predicates.EqualTo(PhotoColumn::PHOTO_STRONG_ASSOCIATION, to_string(static_cast(StrongAssociationType::CLOUD_ENHANCEMENT))); SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false); predicates.EndWrap(); return E_SUCCESS; } int32_t MediaLibraryNapiUtils::GetSourceAlbumPredicates(const int32_t albumId, DataSharePredicates &predicates, const bool hiddenOnly) { predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(albumId)); predicates.EqualTo(PhotoColumn::PHOTO_SYNC_STATUS, to_string(static_cast(SyncStatusType::TYPE_VISIBLE))); SetDefaultPredicatesCondition(predicates, 0, hiddenOnly, 0, false); return E_SUCCESS; } int32_t MediaLibraryNapiUtils::GetSystemAlbumPredicates(const PhotoAlbumSubType subType, DataSharePredicates &predicates, const bool hiddenOnly) { switch (subType) { case PhotoAlbumSubType::FAVORITE: { return GetFavoritePredicates(predicates, hiddenOnly); } case PhotoAlbumSubType::VIDEO: { return GetVideoPredicates(predicates, hiddenOnly); } case PhotoAlbumSubType::HIDDEN: { return GetHiddenPredicates(predicates); } case PhotoAlbumSubType::TRASH: { return GetTrashPredicates(predicates); } case PhotoAlbumSubType::SCREENSHOT: { return GetScreenshotPredicates(predicates, hiddenOnly); } case PhotoAlbumSubType::CAMERA: { return GetCameraPredicates(predicates, hiddenOnly); } case PhotoAlbumSubType::IMAGE: { return GetAllImagesPredicates(predicates, hiddenOnly); } case PhotoAlbumSubType::CLOUD_ENHANCEMENT: { return GetCloudEnhancementPredicates(predicates, hiddenOnly); } default: { NAPI_ERR_LOG("Unsupported photo album subtype: %{public}d", subType); return E_INVALID_ARGUMENTS; } } } string MediaLibraryNapiUtils::ParseResultSet2JsonStr(shared_ptr resultSet, const std::vector &columns) { json jsonArray = json::array(); if (resultSet == nullptr) { return jsonArray.dump(); } while (resultSet->GoToNextRow() == NativeRdb::E_OK) { json jsonObject; for (uint32_t i = 0; i < columns.size(); i++) { string columnName = columns[i]; jsonObject[columnName] = GetStringValueByColumn(resultSet, columnName); } jsonArray.push_back(jsonObject); } return jsonArray.dump(); } string MediaLibraryNapiUtils::ParseAnalysisFace2JsonStr(shared_ptr resultSet, const vector &columns) { json jsonArray = json::array(); if (resultSet == nullptr) { return jsonArray.dump(); } Uri uri(PAH_QUERY_ANA_PHOTO_ALBUM); DataShare::DataSharePredicates predicates; predicates.EqualTo(ALBUM_SUBTYPE, to_string(PhotoAlbumSubType::PORTRAIT))->And()->IsNotNull(TAG_ID); vector albumColumns = { ALBUM_ID, TAG_ID }; int errCode = 0; shared_ptr albumSet = UserFileClient::Query(uri, predicates, albumColumns, errCode); unordered_map tagIdToAlbumIdMap; if (albumSet != nullptr) { while (albumSet->GoToNextRow() == NativeRdb::E_OK) { tagIdToAlbumIdMap[GetStringValueByColumn(albumSet, TAG_ID)] = GetStringValueByColumn(albumSet, ALBUM_ID); } } while (resultSet->GoToNextRow() == NativeRdb::E_OK) { json jsonObject; for (uint32_t i = 0; i < columns.size(); i++) { string columnName = columns[i]; string columnValue = GetStringValueByColumn(resultSet, columnName); jsonObject[columnName] = columnValue; if (columnName == TAG_ID) { jsonObject[ALBUM_URI] = PhotoAlbumColumns::ANALYSIS_ALBUM_URI_PREFIX + tagIdToAlbumIdMap[columnValue]; } } jsonArray.push_back(jsonObject); } return jsonArray.dump(); } string MediaLibraryNapiUtils::GetStringValueByColumn(shared_ptr resultSet, const std::string columnName) { int index; DataShare::DataType dataType; if (resultSet->GetColumnIndex(columnName, index) || resultSet->GetDataType(index, dataType)) { return EMPTY_STRING; } switch (dataType) { case DataShare::DataType::TYPE_INTEGER: { int64_t intValue = -1; if (resultSet->GetLong(index, intValue) == NativeRdb::E_OK) { return to_string(intValue); } break; } case DataShare::DataType::TYPE_FLOAT: { double douValue = 0.0; if (resultSet->GetDouble(index, douValue) == NativeRdb::E_OK) { return to_string(douValue); } break; } case DataShare::DataType::TYPE_STRING: { std::string strValue; if (resultSet->GetString(index, strValue) == NativeRdb::E_OK) { return strValue; } break; } case DataShare::DataType::TYPE_BLOB: { std::vector blobValue; if (resultSet->GetBlob(index, blobValue) == NativeRdb::E_OK) { std::string tempValue(blobValue.begin(), blobValue.end()); return tempValue; } break; } default: { break; } } return EMPTY_STRING; } string MediaLibraryNapiUtils::TransferUri(const string &oldUri) { MediaFileUri fileUri(oldUri); if (fileUri.IsApi10()) { return oldUri; } string fileId = fileUri.GetFileId(); if (fileId.empty()) { return oldUri; } vector columns = { PhotoColumn::MEDIA_FILE_PATH, PhotoColumn::MEDIA_NAME }; string queryUri = MEDIALIBRARY_DATA_URI; DataShare::DataSharePredicates predicates; predicates.EqualTo(PhotoColumn::MEDIA_ID, fileId); Uri uri(queryUri); int errCode = 0; shared_ptr resultSet = UserFileClient::Query(uri, predicates, columns, errCode); if (resultSet->GoToFirstRow() != NativeRdb::E_OK) { NAPI_ERR_LOG("Fail to query file asset!"); return oldUri; } string extrUri = MediaFileUtils::GetExtraUri(GetStringValueByColumn(resultSet, PhotoColumn::MEDIA_NAME), GetStringValueByColumn(resultSet, PhotoColumn::MEDIA_FILE_PATH), false); return MediaFileUri (fileUri.GetMediaTypeFromUri(oldUri), fileId, "", MEDIA_API_VERSION_V10, extrUri).ToString(); } string MediaLibraryNapiUtils::GetStringFetchProperty(napi_env env, napi_value arg, bool &err, bool &present, const string &propertyName) { size_t res = 0; char buffer[PATH_MAX] = {0}; napi_value property = nullptr; napi_has_named_property(env, arg, propertyName.c_str(), &present); if (present) { if ((napi_get_named_property(env, arg, propertyName.c_str(), &property) != napi_ok) || (napi_get_value_string_utf8(env, property, buffer, PATH_MAX, &res) != napi_ok)) { NAPI_ERR_LOG("Could not get the string argument!"); err = true; return ""; } else { string str(buffer); present = false; return str; } } return ""; } napi_value MediaLibraryNapiUtils::CreateValueByIndex(napi_env env, int32_t index, string name, shared_ptr &resultSet, const shared_ptr &asset) { int status; int integerVal = 0; string stringVal = ""; int64_t longVal = 0; double doubleVal = 0.0; napi_value value = nullptr; auto dataType = MediaLibraryNapiUtils::GetTypeMap().at(name); switch (dataType.first) { case TYPE_STRING: status = resultSet->GetString(index, stringVal); napi_create_string_utf8(env, stringVal.c_str(), NAPI_AUTO_LENGTH, &value); asset->GetMemberMap().emplace(name, stringVal); break; case TYPE_INT32: status = resultSet->GetInt(index, integerVal); napi_create_int32(env, integerVal, &value); asset->GetMemberMap().emplace(name, integerVal); break; case TYPE_INT64: status = resultSet->GetLong(index, longVal); napi_create_int64(env, longVal, &value); asset->GetMemberMap().emplace(name, longVal); break; case TYPE_DOUBLE: status = resultSet->GetDouble(index, doubleVal); napi_create_double(env, doubleVal, &value); asset->GetMemberMap().emplace(name, doubleVal); break; default: NAPI_ERR_LOG("not match dataType %{public}d", dataType.first); break; } return value; } void MediaLibraryNapiUtils::handleTimeInfo(napi_env env, const std::string& name, napi_value result, int32_t index, const std::shared_ptr& resultSet) { if (TIME_COLUMN.count(name) == 0) { return; } int64_t longVal = 0; int status; napi_value value = nullptr; status = resultSet->GetLong(index, longVal); int64_t modifieldValue = longVal / 1000; napi_create_int64(env, modifieldValue, &value); auto dataType = MediaLibraryNapiUtils::GetTimeTypeMap().at(name); napi_set_named_property(env, result, dataType.second.c_str(), value); } static void handleThumbnailReady(napi_env env, const std::string& name, napi_value result, int32_t index, const std::shared_ptr& resultSet) { if (name != "thumbnail_ready") { return; } int64_t longVal = 0; int status; napi_value value = nullptr; status = resultSet->GetLong(index, longVal); bool resultVal = longVal > 0; napi_create_int32(env, resultVal, &value); napi_set_named_property(env, result, "thumbnailReady", value); } napi_value MediaLibraryNapiUtils::GetNextRowObject(napi_env env, shared_ptr &resultSet, bool isShared) { if (resultSet == nullptr) { NAPI_ERR_LOG("GetNextRowObject fail, result is nullptr"); return nullptr; } vector columnNames; resultSet->GetAllColumnNames(columnNames); napi_value result = nullptr; napi_create_object(env, &result); napi_value value = nullptr; int32_t index = -1; auto fileAsset = make_shared(); for (const auto &name : columnNames) { index++; // Check if the column name exists in the type map if (MediaLibraryNapiUtils::GetTypeMap().count(name) == 0) { continue; } value = MediaLibraryNapiUtils::CreateValueByIndex(env, index, name, resultSet, fileAsset); auto dataType = MediaLibraryNapiUtils::GetTypeMap().at(name); std::string tmpName = isShared ? dataType.second : name; napi_set_named_property(env, result, tmpName.c_str(), value); if (!isShared) { continue; } handleTimeInfo(env, name, result, index, resultSet); handleThumbnailReady(env, name, result, index, resultSet); } string extrUri = MediaFileUtils::GetExtraUri(fileAsset->GetDisplayName(), fileAsset->GetPath(), false); MediaFileUri fileUri(fileAsset->GetMediaType(), to_string(fileAsset->GetId()), "", MEDIA_API_VERSION_V10, extrUri); fileAsset->SetUri(move(fileUri.ToString())); napi_create_string_utf8(env, fileAsset->GetUri().c_str(), NAPI_AUTO_LENGTH, &value); napi_set_named_property(env, result, MEDIA_DATA_DB_URI.c_str(), value); return result; } void MediaLibraryNapiUtils::HandleCoverSharedPhotoAsset(napi_env env, int32_t index, napi_value result, const string& name, const shared_ptr& resultSet) { if (name != "cover_uri") { return; } int status; string coverUri = ""; status = resultSet->GetString(index, coverUri); if (status != NativeRdb::E_OK || coverUri.empty()) { return; } vector albumIds; albumIds.push_back(GetFileIdFromUriString(coverUri)); napi_value coverValue = GetSharedPhotoAssets(env, albumIds, true); napi_set_named_property(env, result, "coverSharedPhotoAsset", coverValue); } napi_value MediaLibraryNapiUtils::GetNextRowAlbumObject(napi_env env, shared_ptr &resultSet) { if (resultSet == nullptr) { NAPI_ERR_LOG("GetNextRowObject fail, result is nullptr"); return nullptr; } vector columnNames; resultSet->GetAllColumnNames(columnNames); napi_value result = nullptr; napi_create_object(env, &result); napi_value value = nullptr; int32_t index = -1; auto fileAsset = make_shared(); for (const auto &name : columnNames) { index++; // Check if the column name exists in the type map if (MediaLibraryNapiUtils::GetTypeMap().count(name) == 0) { continue; } value = MediaLibraryNapiUtils::CreateValueByIndex(env, index, name, resultSet, fileAsset); auto dataType = MediaLibraryNapiUtils::GetTypeMap().at(name); napi_set_named_property(env, result, dataType.second.c_str(), value); HandleCoverSharedPhotoAsset(env, index, result, name, resultSet); } return result; } string MediaLibraryNapiUtils::GetFileIdFromUriString(const string& uri) { auto startIndex = uri.find(PhotoColumn::PHOTO_URI_PREFIX); if (startIndex == std::string::npos) { return ""; } auto endIndex = uri.find("/", startIndex + PhotoColumn::PHOTO_URI_PREFIX.length()); if (endIndex == std::string::npos) { return uri.substr(startIndex + PhotoColumn::PHOTO_URI_PREFIX.length()); } return uri.substr(startIndex + PhotoColumn::PHOTO_URI_PREFIX.length(), endIndex - startIndex - PhotoColumn::PHOTO_URI_PREFIX.length()); } string MediaLibraryNapiUtils::GetAlbumIdFromUriString(const string& uri) { string albumId = ""; auto startIndex = uri.find(PhotoAlbumColumns::ALBUM_URI_PREFIX); if (startIndex != std::string::npos) { albumId = uri.substr(startIndex + PhotoAlbumColumns::ALBUM_URI_PREFIX.length()); } return albumId; } napi_value MediaLibraryNapiUtils::GetSharedPhotoAssets(const napi_env& env, vector& fileIds, bool isSingleResult) { string queryUri = PAH_QUERY_PHOTO; MediaLibraryNapiUtils::UriAppendKeyValue(queryUri, API_VERSION, to_string(MEDIA_API_VERSION_V10)); Uri photoUri(queryUri); DataShare::DataSharePredicates predicates; predicates.In(MediaColumn::MEDIA_ID, fileIds); std::vector columns = PHOTO_COLUMN; std::shared_ptr result = UserFileClient::QueryRdb(photoUri, predicates, columns); napi_value value = nullptr; napi_status status = napi_create_array_with_length(env, fileIds.size(), &value); if (status != napi_ok) { NAPI_ERR_LOG("Create array error!"); return value; } if (result == nullptr) { return value; } if (isSingleResult) { napi_value assetValue = nullptr; if (result->GoToNextRow() == NativeRdb::E_OK) { assetValue = MediaLibraryNapiUtils::GetNextRowObject(env, result, true); } result->Close(); return assetValue; } else { int elementIndex = 0; while (result->GoToNextRow() == NativeRdb::E_OK) { napi_value assetValue = MediaLibraryNapiUtils::GetNextRowObject(env, result, true); if (assetValue == nullptr) { return nullptr; } status = napi_set_element(env, value, elementIndex++, assetValue); if (status != napi_ok) { NAPI_ERR_LOG("Set photo asset value failed"); return nullptr; } } result->Close(); } return value; } napi_value MediaLibraryNapiUtils::GetSharedAlbumAssets(const napi_env& env, vector& albumIds) { string queryUri = PAH_QUERY_PHOTO_ALBUM; Uri albumUri(queryUri); DataShare::DataSharePredicates predicates; predicates.In(PhotoAlbumColumns::ALBUM_ID, albumIds); std::vector columns = ALBUM_COLUMN; std::shared_ptr result = UserFileClient::QueryRdb(albumUri, predicates, columns); napi_value value = nullptr; napi_status status = napi_create_array_with_length(env, albumIds.size(), &value); if (status != napi_ok) { NAPI_ERR_LOG("Create array error!"); return value; } if (result == nullptr) { return value; } int err = result->GoToFirstRow(); if (err != napi_ok) { NAPI_ERR_LOG("Failed GoToFirstRow %{public}d", err); return value; } int elementIndex = 0; do { napi_value assetValue = MediaLibraryNapiUtils::GetNextRowAlbumObject(env, result); if (assetValue == nullptr) { return nullptr; } status = napi_set_element(env, value, elementIndex++, assetValue); if (status != napi_ok) { NAPI_ERR_LOG("Set albumn asset Value failed"); return nullptr; } } while (result->GoToNextRow() == E_OK); result->Close(); return value; } bool MediaLibraryNapiUtils::IsSystemApp() { static bool isSys = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetSelfTokenID()); return isSys; } NapiScopeHandler::NapiScopeHandler(napi_env env): env_(env) { napi_status status = napi_open_handle_scope(env_, &scope_); if (status != napi_ok) { NAPI_ERR_LOG("Open Handler scope failed, status %{public}d", status); isValid_ = false; } else { isValid_ = true; } } NapiScopeHandler::~NapiScopeHandler() { if (isValid_) { napi_status status = napi_close_handle_scope(env_, scope_); if (status != napi_ok) { NAPI_ERR_LOG("Close Handler scope failed, status %{public}d", status); } } } bool NapiScopeHandler::IsValid() { return isValid_; } napi_value MediaLibraryNapiUtils::GetNapiValueArray(napi_env env, napi_value arg, vector &values) { bool isArray = false; CHECK_ARGS(env, napi_is_array(env, arg, &isArray), OHOS_INVALID_PARAM_CODE); if (!isArray) { NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, "Failed to check array type"); return nullptr; } uint32_t len = 0; CHECK_ARGS(env, napi_get_array_length(env, arg, &len), JS_INNER_FAIL); if (len == 0) { napi_value result = nullptr; CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL); return result; } for (uint32_t i = 0; i < len; i++) { napi_value value = nullptr; CHECK_ARGS(env, napi_get_element(env, arg, i, &value), JS_INNER_FAIL); if (value == nullptr) { NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, "Failed to get element"); return nullptr; } values.push_back(value); } napi_value result = nullptr; CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_INNER_FAIL); return result; } napi_value MediaLibraryNapiUtils::GetStringArray(napi_env env, vector &napiValues, vector &values) { napi_valuetype valueType = napi_undefined; unique_ptr buffer = make_unique(PATH_MAX); for (const auto &napiValue : napiValues) { CHECK_ARGS(env, napi_typeof(env, napiValue, &valueType), JS_ERR_PARAMETER_INVALID); CHECK_COND(env, valueType == napi_string, JS_ERR_PARAMETER_INVALID); size_t res = 0; CHECK_ARGS( env, napi_get_value_string_utf8(env, napiValue, buffer.get(), PATH_MAX, &res), JS_ERR_PARAMETER_INVALID); values.emplace_back(buffer.get()); } napi_value ret = nullptr; CHECK_ARGS(env, napi_get_boolean(env, true, &ret), JS_INNER_FAIL); return ret; } std::string GetUriFromAsset(const FileAssetNapi *obj) { string displayName = obj->GetFileDisplayName(); string filePath = obj->GetFilePath(); return MediaFileUtils::GetUriByExtrConditions(PhotoColumn::PHOTO_URI_PREFIX, to_string(obj->GetFileId()), MediaFileUtils::GetExtraUri(displayName, filePath)); } napi_value MediaLibraryNapiUtils::GetUriArrayFromAssets( napi_env env, vector &napiValues, vector &values) { FileAssetNapi *obj = nullptr; for (const auto &napiValue : napiValues) { CHECK_ARGS(env, napi_unwrap(env, napiValue, reinterpret_cast(&obj)), JS_INNER_FAIL); if (obj == nullptr) { NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID, "Failed to get asset napi object"); return nullptr; } if ((obj->GetMediaType() != MEDIA_TYPE_IMAGE && obj->GetMediaType() != MEDIA_TYPE_VIDEO)) { NAPI_INFO_LOG("Skip invalid asset, mediaType: %{public}d", obj->GetMediaType()); continue; } values.push_back(GetUriFromAsset(obj)); } napi_value ret = nullptr; CHECK_ARGS(env, napi_get_boolean(env, true, &ret), JS_INNER_FAIL); return ret; } void MediaLibraryNapiUtils::FixSpecialDateType(string &selections) { vector dateTypes = { MEDIA_DATA_DB_DATE_ADDED, MEDIA_DATA_DB_DATE_TRASHED, MEDIA_DATA_DB_DATE_MODIFIED, MEDIA_DATA_DB_DATE_TAKEN }; for (string dateType : dateTypes) { string date2Second = dateType + "_s"; auto pos = selections.find(dateType); while (pos != string::npos) { selections.replace(pos, dateType.length(), date2Second); pos = selections.find(dateType, pos + date2Second.length()); } } } template napi_status MediaLibraryNapiUtils::ParsePredicates(napi_env env, const napi_value arg, AsyncContext &context, const FetchOptionType &fetchOptType) { JSProxy::JSProxy *jsProxy = nullptr; napi_unwrap(env, arg, reinterpret_cast(&jsProxy)); if (jsProxy == nullptr) { NAPI_ERR_LOG("jsProxy is invalid"); return napi_invalid_arg; } shared_ptr predicate = jsProxy->GetInstance(); CHECK_COND_RET(HandleSpecialPredicate(context, predicate, fetchOptType) == TRUE, napi_invalid_arg, "invalid predicate"); CHECK_COND_RET(GetLocationPredicate(context, predicate) == TRUE, napi_invalid_arg, "invalid predicate"); return napi_ok; } template bool MediaLibraryNapiUtils::HandleSpecialPredicate>( unique_ptr &context, shared_ptr &predicate, const FetchOptionType &fetchOptType); template bool MediaLibraryNapiUtils::HandleSpecialPredicate>( unique_ptr &context, shared_ptr &predicate, const FetchOptionType &fetchOptType); template bool MediaLibraryNapiUtils::HandleSpecialPredicate>( unique_ptr &context, shared_ptr &predicate, const FetchOptionType &fetchOptType); template bool MediaLibraryNapiUtils::GetLocationPredicate>( unique_ptr &context, shared_ptr &predicate); template bool MediaLibraryNapiUtils::GetLocationPredicate>( unique_ptr &context, shared_ptr &predicate); template bool MediaLibraryNapiUtils::GetLocationPredicate>( unique_ptr &context, shared_ptr &predicate); template napi_status MediaLibraryNapiUtils::GetFetchOption>(napi_env env, napi_value arg, const FetchOptionType &fetchOptType, unique_ptr &context); template napi_status MediaLibraryNapiUtils::GetFetchOption>(napi_env env, napi_value arg, const FetchOptionType &fetchOptType, unique_ptr &context); template napi_status MediaLibraryNapiUtils::GetAlbumFetchOption>(napi_env env, napi_value arg, const FetchOptionType &fetchOptType, unique_ptr &context); template napi_status MediaLibraryNapiUtils::GetAlbumFetchOption>(napi_env env, napi_value arg, const FetchOptionType &fetchOptType, unique_ptr &context); template napi_status MediaLibraryNapiUtils::GetPredicate>(napi_env env, const napi_value arg, const string &propName, unique_ptr &context, const FetchOptionType &fetchOptType); template napi_status MediaLibraryNapiUtils::GetPredicate>(napi_env env, const napi_value arg, const string &propName, unique_ptr &context, const FetchOptionType &fetchOptType); template napi_status MediaLibraryNapiUtils::GetPredicate>(napi_env env, const napi_value arg, const string &propName, unique_ptr &context, const FetchOptionType &fetchOptType); template napi_status MediaLibraryNapiUtils::ParseAssetFetchOptCallback>( napi_env env, napi_callback_info info, unique_ptr &context); template napi_status MediaLibraryNapiUtils::ParseAssetFetchOptCallback>( napi_env env, napi_callback_info info, unique_ptr &context); template napi_status MediaLibraryNapiUtils::ParseAssetFetchOptCallback>( napi_env env, napi_callback_info info, unique_ptr &context); template napi_status MediaLibraryNapiUtils::ParseAlbumFetchOptCallback>( napi_env env, napi_callback_info info, unique_ptr &context); template void MediaLibraryNapiUtils::UpdateMediaTypeSelections( SmartAlbumNapiAsyncContext *context); template void MediaLibraryNapiUtils::UpdateMediaTypeSelections( AlbumNapiAsyncContext *context); template void MediaLibraryNapiUtils::UpdateMediaTypeSelections( MediaLibraryAsyncContext *context); template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback>( napi_env env, napi_callback_info info, unique_ptr &context, string ¶m); template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback>( napi_env env, napi_callback_info info, unique_ptr &context, string ¶m); template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback>( napi_env env, napi_callback_info info, unique_ptr &context, string ¶m); template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback>( napi_env env, napi_callback_info info, unique_ptr &context, string ¶m); template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback>( napi_env env, napi_callback_info info, unique_ptr &context, string ¶m); template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback>( napi_env env, napi_callback_info info, unique_ptr &context, string ¶m); template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback>( napi_env env, napi_callback_info info, unique_ptr &context, string ¶m); template napi_status MediaLibraryNapiUtils::ParseArgsStringCallback>( napi_env env, napi_callback_info info, unique_ptr &context, string ¶m); template napi_status MediaLibraryNapiUtils::ParseArgsStringArrayCallback>( napi_env env, napi_callback_info info, unique_ptr &context, vector &array); template napi_status MediaLibraryNapiUtils::GetParamCallback>(napi_env env, unique_ptr &context); template napi_status MediaLibraryNapiUtils::GetParamCallback>(napi_env env, unique_ptr &context); template napi_status MediaLibraryNapiUtils::GetParamCallback>(napi_env env, unique_ptr &context); template napi_status MediaLibraryNapiUtils::ParseArgsBoolCallBack>(napi_env env, napi_callback_info info, unique_ptr &context, bool ¶m); template napi_status MediaLibraryNapiUtils::ParseArgsBoolCallBack>(napi_env env, napi_callback_info info, unique_ptr &context, bool ¶m); template napi_status MediaLibraryNapiUtils::ParseArgsBoolCallBack>( napi_env env, napi_callback_info info, unique_ptr &context, bool ¶m); template napi_status MediaLibraryNapiUtils::ParseArgsBoolCallBack>( napi_env env, napi_callback_info info, unique_ptr &context, bool ¶m); template napi_status MediaLibraryNapiUtils::AsyncContextSetObjectInfo>( napi_env env, napi_callback_info info, unique_ptr &asyncContext, const size_t minArgs, const size_t maxArgs); template napi_status MediaLibraryNapiUtils::AsyncContextSetObjectInfo>( napi_env env, napi_callback_info info, unique_ptr &asyncContext, const size_t minArgs, const size_t maxArgs); template napi_status MediaLibraryNapiUtils::AsyncContextGetArgs>( napi_env env, napi_callback_info info, unique_ptr& asyncContext, const size_t minArgs, const size_t maxArgs); template napi_status MediaLibraryNapiUtils::AsyncContextGetArgs>( napi_env env, napi_callback_info info, unique_ptr& asyncContext, const size_t minArgs, const size_t maxArgs); template napi_status MediaLibraryNapiUtils::AsyncContextGetArgs>( napi_env env, napi_callback_info info, unique_ptr& asyncContext, const size_t minArgs, const size_t maxArgs); template napi_status MediaLibraryNapiUtils::AsyncContextGetArgs>( napi_env env, napi_callback_info info, unique_ptr& asyncContext, const size_t minArgs, const size_t maxArgs); template napi_status MediaLibraryNapiUtils::AsyncContextGetArgs>( napi_env env, napi_callback_info info, unique_ptr& asyncContext, const size_t minArgs, const size_t maxArgs); template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr &asyncContext, const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)); template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr &asyncContext, const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)); template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr &asyncContext, const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)); template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr &asyncContext, const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)); template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr &asyncContext, const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)); template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr &asyncContext, const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)); template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr &asyncContext, const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)); template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr &asyncContext, const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)); template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr &asyncContext, const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)); template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr &asyncContext, const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)); template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr &asyncContext, const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)); template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr &asyncContext, const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)); template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr &asyncContext, const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)); template napi_value MediaLibraryNapiUtils::NapiCreateAsyncWork(napi_env env, unique_ptr &asyncContext, const string &resourceName, void (*execute)(napi_env, void *), void (*complete)(napi_env, napi_status, void *)); template napi_status MediaLibraryNapiUtils::ParseArgsNumberCallback>(napi_env env, napi_callback_info info, unique_ptr &context, int32_t &value); template napi_status MediaLibraryNapiUtils::ParseArgsNumberCallback>(napi_env env, napi_callback_info info, unique_ptr &context, int32_t &value); template napi_status MediaLibraryNapiUtils::ParseArgsNumberCallback>( napi_env env, napi_callback_info info, unique_ptr &context, int32_t &value); template napi_status MediaLibraryNapiUtils::ParseArgsNumberCallback>( napi_env env, napi_callback_info info, unique_ptr &context, int32_t &value); template napi_status MediaLibraryNapiUtils::ParseArgsNumberCallback>( napi_env env, napi_callback_info info, unique_ptr &context, int32_t &value); template napi_status MediaLibraryNapiUtils::ParseArgsOnlyCallBack>(napi_env env, napi_callback_info info, unique_ptr &context); template napi_status MediaLibraryNapiUtils::ParseArgsOnlyCallBack>(napi_env env, napi_callback_info info, unique_ptr &context); template napi_status MediaLibraryNapiUtils::ParseArgsOnlyCallBack>(napi_env env, napi_callback_info info, unique_ptr &context); template napi_status MediaLibraryNapiUtils::ParsePredicates>(napi_env env, const napi_value arg, unique_ptr &context, const FetchOptionType &fetchOptType); } // namespace Media } // namespace OHOS