* Copyright (C) 2021-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 "FetchResultNapi"
#include "fetch_file_result_napi.h"
#include <set>
#include "album_napi.h"
#include "medialibrary_client_errno.h"
#include "medialibrary_tracer.h"
#include "smart_album_napi.h"
#include "media_file_utils.h"
#include "album_order_napi.h"
#include "photo_album_napi.h"
#include "media_log.h"
#include "user_define_ipc_client.h"
#include "compatible_info_vo.h"
#include "userfile_client.h"
#include "medialibrary_business_code.h"
#include "preferred_compatible_mode_check_utils.h"
using OHOS::HiviewDFX::HiLog;
using OHOS::HiviewDFX::HiLogLabel;
using namespace std;
namespace OHOS {
namespace Media {
thread_local napi_ref FetchFileResultNapi::sConstructor_ = nullptr;
thread_local napi_ref FetchFileResultNapi::userFileMgrConstructor_ = nullptr;
thread_local napi_ref FetchFileResultNapi::photoAccessHelperConstructor_ = nullptr;
const uint32_t MAX_SIZE = 500;
FetchFileResultNapi::FetchFileResultNapi()
: env_(nullptr) {}
FetchFileResultNapi::~FetchFileResultNapi()
{
propertyPtr = nullptr;
}
void FetchFileResultNapi::FetchFileResultNapiDestructor(napi_env env, void *nativeObject, void *finalize_hint)
{
FetchFileResultNapi *fetchFileResultObj = reinterpret_cast<FetchFileResultNapi*>(nativeObject);
if (fetchFileResultObj != nullptr) {
delete fetchFileResultObj;
fetchFileResultObj = nullptr;
}
}
napi_value FetchFileResultNapi::Init(napi_env env, napi_value exports)
{
napi_status status;
napi_value ctorObj;
int32_t refCount = 1;
napi_property_descriptor fetch_file_result_props[] = {
DECLARE_NAPI_FUNCTION("getCount", JSGetCount),
DECLARE_NAPI_FUNCTION("isAfterLast", JSIsAfterLast),
DECLARE_NAPI_FUNCTION("getFirstObject", JSGetFirstObject),
DECLARE_NAPI_FUNCTION("getNextObject", JSGetNextObject),
DECLARE_NAPI_FUNCTION("getLastObject", JSGetLastObject),
DECLARE_NAPI_FUNCTION("getPositionObject", JSGetPositionObject),
DECLARE_NAPI_FUNCTION("getAllObject", JSGetAllObject),
DECLARE_NAPI_FUNCTION("close", JSClose)
};
status = napi_define_class(env, FETCH_FILE_RESULT_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH,
FetchFileResultNapiConstructor, nullptr,
sizeof(fetch_file_result_props) / sizeof(fetch_file_result_props[PARAM0]),
fetch_file_result_props, &ctorObj);
if (status == napi_ok) {
status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
if (status == napi_ok) {
status = napi_set_named_property(env, exports, FETCH_FILE_RESULT_CLASS_NAME.c_str(), ctorObj);
if (status == napi_ok) {
return exports;
}
}
}
NAPI_DEBUG_LOG("Init success");
return nullptr;
}
void FetchFileResultNapi::GetFetchResult(unique_ptr<FetchFileResultNapi> &obj)
{
switch (sFetchResType_) {
case FetchResType::TYPE_FILE: {
auto fileResult = make_shared<FetchResult<FileAsset>>(move(sFetchFileResult_->GetDataShareResultSet()));
obj->propertyPtr->fetchFileResult_ = fileResult;
obj->propertyPtr->fetchFileResult_->SetInfo(sFetchFileResult_);
obj->propertyPtr->fetchFileResult_->SetUserId(sFetchFileResult_->GetUserId());
break;
}
case FetchResType::TYPE_ALBUM: {
auto albumResult = make_shared<FetchResult<AlbumAsset>>(move(sFetchAlbumResult_->GetDataShareResultSet()));
obj->propertyPtr->fetchAlbumResult_ = albumResult;
obj->propertyPtr->fetchAlbumResult_->SetInfo(sFetchAlbumResult_);
obj->propertyPtr->fetchAlbumResult_->SetUserId(sFetchAlbumResult_->GetUserId());
break;
}
case FetchResType::TYPE_PHOTOALBUM: {
auto photoAlbumResult =
make_shared<FetchResult<PhotoAlbum>>(move(sFetchPhotoAlbumResult_->GetDataShareResultSet()));
obj->propertyPtr->fetchPhotoAlbumResult_ = photoAlbumResult;
obj->propertyPtr->fetchPhotoAlbumResult_->SetInfo(sFetchPhotoAlbumResult_);
obj->propertyPtr->fetchPhotoAlbumResult_->SetUserId(sFetchPhotoAlbumResult_->GetUserId());
break;
}
case FetchResType::TYPE_SMARTALBUM: {
auto smartResult =
make_shared<FetchResult<SmartAlbumAsset>>(move(sFetchSmartAlbumResult_->GetDataShareResultSet()));
obj->propertyPtr->fetchSmartAlbumResult_ = smartResult;
obj->propertyPtr->fetchSmartAlbumResult_->SetInfo(sFetchSmartAlbumResult_);
break;
}
case FetchResType::TYPE_CUSTOMRECORD: {
auto cRecordResult = make_shared<FetchResult<PhotoAssetCustomRecord>>(
move(sFetchPhotoAssetCustomRecordResult_->GetDataShareResultSet()));
obj->propertyPtr->fetchCustomRecordResult_ = cRecordResult;
obj->propertyPtr->fetchCustomRecordResult_->SetInfo(sFetchPhotoAssetCustomRecordResult_);
break;
}
case FetchResType::TYPE_ALBUMORDER: {
auto albumOrderResult = make_shared<FetchResult<AlbumOrder>>(
move(sFetchAlbumOrderResult_->GetDataShareResultSet()));
obj->propertyPtr->fetchAlbumOrderResult_ = albumOrderResult;
obj->propertyPtr->fetchAlbumOrderResult_->SetInfo(sFetchAlbumOrderResult_);
break;
}
default:
NAPI_ERR_LOG("unsupported FetchResType");
break;
}
}
napi_value FetchFileResultNapi::FetchFileResultNapiConstructor(napi_env env, napi_callback_info info)
{
MediaLibraryTracer tracer;
tracer.Start("FetchFileResultNapiConstructor");
napi_status status;
napi_value result = nullptr;
napi_value thisVar = nullptr;
napi_get_undefined(env, &result);
GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
if (status != napi_ok || thisVar == nullptr) {
NAPI_ERR_LOG("Get Js obj failed, status: %{public}d, (thisVar == nullptr) = %{public}d",
status, (thisVar == nullptr));
return result;
}
unique_ptr<FetchFileResultNapi> obj = make_unique<FetchFileResultNapi>();
if (obj == nullptr) {
NAPI_ERR_LOG("Get FetchFileResultNapi failed");
return result;
}
obj->env_ = env;
obj->propertyPtr = make_shared<FetchResultProperty>();
GetFetchResult(obj);
obj->propertyPtr->fetchResType_ = sFetchResType_;
status = napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()),
FetchFileResultNapi::FetchFileResultNapiDestructor, nullptr, nullptr);
if (status == napi_ok) {
obj.release();
return thisVar;
} else {
NAPI_ERR_LOG("Failure wrapping js to native napi, status: %{public}d", status);
}
return result;
}
FetchResType FetchFileResultNapi::GetFetchResType()
{
return propertyPtr->fetchResType_;
}
void FetchFileResultNapi::SolveConstructorRef(unique_ptr<FetchResult<FileAsset>> &fileResult,
napi_ref &constructorRef)
{
switch(fileResult->GetResultNapiType()) {
case ResultNapiType::TYPE_USERFILE_MGR: {
constructorRef = userFileMgrConstructor_;
break;
}
case ResultNapiType::TYPE_PHOTOACCESS_HELPER: {
constructorRef = photoAccessHelperConstructor_;
break;
}
default:
constructorRef = sConstructor_;
break;
}
}
void FetchFileResultNapi::SolveConstructorRef(unique_ptr<FetchResult<AlbumAsset>> &fileResult,
napi_ref &constructorRef)
{
switch(fileResult->GetResultNapiType()) {
case ResultNapiType::TYPE_USERFILE_MGR: {
constructorRef = userFileMgrConstructor_;
break;
}
case ResultNapiType::TYPE_PHOTOACCESS_HELPER: {
constructorRef = photoAccessHelperConstructor_;
break;
}
default:
constructorRef = sConstructor_;
break;
}
}
void FetchFileResultNapi::SolveConstructorRef(unique_ptr<FetchResult<SmartAlbumAsset>> &fileResult,
napi_ref &constructorRef)
{
switch(fileResult->GetResultNapiType()) {
case ResultNapiType::TYPE_USERFILE_MGR: {
constructorRef = userFileMgrConstructor_;
break;
}
case ResultNapiType::TYPE_PHOTOACCESS_HELPER: {
constructorRef = photoAccessHelperConstructor_;
break;
}
default:
constructorRef = sConstructor_;
break;
}
}
void FetchFileResultNapi::SolveConstructorRef(unique_ptr<FetchResult<PhotoAlbum>> &fileResult,
napi_ref &constructorRef)
{
switch(fileResult->GetResultNapiType()) {
case ResultNapiType::TYPE_USERFILE_MGR: {
constructorRef = userFileMgrConstructor_;
break;
}
case ResultNapiType::TYPE_PHOTOACCESS_HELPER: {
constructorRef = photoAccessHelperConstructor_;
break;
}
default:
constructorRef = sConstructor_;
break;
}
}
void FetchFileResultNapi::SolveConstructorRef(unique_ptr<FetchResult<PhotoAssetCustomRecord>> &fileResult,
napi_ref &constructorRef)
{
CHECK_NULL_PTR_RETURN_VOID(fileResult, "fileResult is nullptr");
switch(fileResult->GetResultNapiType()) {
case ResultNapiType::TYPE_USERFILE_MGR: {
constructorRef = userFileMgrConstructor_;
break;
}
case ResultNapiType::TYPE_PHOTOACCESS_HELPER: {
constructorRef = photoAccessHelperConstructor_;
break;
}
default:
constructorRef = sConstructor_;
break;
}
}
void FetchFileResultNapi::SolveConstructorRef(unique_ptr<FetchResult<AlbumOrder>> &fileResult,
napi_ref &constructorRef)
{
CHECK_NULL_PTR_RETURN_VOID(fileResult, "fileResult is nullptr");
constructorRef = photoAccessHelperConstructor_;
}
napi_value FetchFileResultNapi::CreateFetchFileResult(napi_env env, unique_ptr<FetchResult<FileAsset>> fileResult)
{
MediaLibraryTracer tracer;
tracer.Start("CreateFetchFileResult");
napi_value constructor;
napi_ref constructorRef;
FetchFileResultNapi::SolveConstructorRef(fileResult, constructorRef);
NAPI_CALL(env, napi_get_reference_value(env, constructorRef, &constructor));
sFetchResType_ = fileResult->GetFetchResType();
sFetchFileResult_ = move(fileResult);
napi_value result = nullptr;
NAPI_CALL(env, napi_new_instance(env, constructor, 0, nullptr, &result));
sFetchFileResult_ = nullptr;
return result;
}
napi_value FetchFileResultNapi::CreateFetchFileResult(napi_env env, unique_ptr<FetchResult<AlbumAsset>> fileResult)
{
MediaLibraryTracer tracer;
tracer.Start("CreateFetchFileResult");
napi_value constructor;
napi_ref constructorRef;
FetchFileResultNapi::SolveConstructorRef(fileResult, constructorRef);
NAPI_CALL(env, napi_get_reference_value(env, constructorRef, &constructor));
sFetchResType_ = fileResult->GetFetchResType();
sFetchAlbumResult_ = move(fileResult);
napi_value result = nullptr;
NAPI_CALL(env, napi_new_instance(env, constructor, 0, nullptr, &result));
sFetchAlbumResult_ = nullptr;
return result;
}
napi_value FetchFileResultNapi::CreateFetchFileResult(napi_env env, unique_ptr<FetchResult<PhotoAlbum>> fileResult)
{
MediaLibraryTracer tracer;
tracer.Start("CreateFetchFileResult");
napi_value constructor;
napi_ref constructorRef;
FetchFileResultNapi::SolveConstructorRef(fileResult, constructorRef);
NAPI_CALL(env, napi_get_reference_value(env, constructorRef, &constructor));
sFetchResType_ = fileResult->GetFetchResType();
sFetchPhotoAlbumResult_ = move(fileResult);
napi_value result = nullptr;
NAPI_CALL(env, napi_new_instance(env, constructor, 0, nullptr, &result));
sFetchPhotoAlbumResult_ = nullptr;
return result;
}
napi_value FetchFileResultNapi::CreateFetchFileResult(napi_env env, unique_ptr<FetchResult<SmartAlbumAsset>> fileResult)
{
MediaLibraryTracer tracer;
tracer.Start("CreateFetchFileResult");
napi_value constructor;
napi_ref constructorRef;
FetchFileResultNapi::SolveConstructorRef(fileResult, constructorRef);
NAPI_CALL(env, napi_get_reference_value(env, constructorRef, &constructor));
sFetchResType_ = fileResult->GetFetchResType();
sFetchSmartAlbumResult_ = move(fileResult);
napi_value result = nullptr;
NAPI_CALL(env, napi_new_instance(env, constructor, 0, nullptr, &result));
sFetchSmartAlbumResult_ = nullptr;
return result;
}
napi_value FetchFileResultNapi::CreateFetchFileResult(napi_env env,
unique_ptr<FetchResult<PhotoAssetCustomRecord>> fileResult)
{
MediaLibraryTracer tracer;
tracer.Start("CreateFetchFileResult");
napi_value constructor;
napi_ref constructorRef;
FetchFileResultNapi::SolveConstructorRef(fileResult, constructorRef);
NAPI_CALL(env, napi_get_reference_value(env, constructorRef, &constructor));
sFetchResType_ = fileResult->GetFetchResType();
sFetchPhotoAssetCustomRecordResult_ = move(fileResult);
napi_value result = nullptr;
NAPI_CALL(env, napi_new_instance(env, constructor, 0, nullptr, &result));
sFetchPhotoAssetCustomRecordResult_ = nullptr;
return result;
}
napi_value FetchFileResultNapi::CreateFetchFileResult(napi_env env,
unique_ptr<FetchResult<AlbumOrder>> fileResult)
{
MediaLibraryTracer tracer;
tracer.Start("CreateFetchFileResult");
napi_value constructor;
napi_ref constructorRef;
FetchFileResultNapi::SolveConstructorRef(fileResult, constructorRef);
NAPI_CALL(env, napi_get_reference_value(env, constructorRef, &constructor));
sFetchResType_ = fileResult->GetFetchResType();
sFetchAlbumOrderResult_ = move(fileResult);
napi_value result = nullptr;
NAPI_CALL(env, napi_new_instance(env, constructor, 0, nullptr, &result));
sFetchAlbumOrderResult_ = nullptr;
return result;
}
std::shared_ptr<FetchResult<FileAsset>> FetchFileResultNapi::GetFetchFileResult() const
{
return propertyPtr->fetchFileResult_;
}
napi_value FetchFileResultNapi::UserFileMgrInit(napi_env env, napi_value exports)
{
NapiClassInfo info = {
.name = UFM_FETCH_FILE_RESULT_CLASS_NAME,
.ref = &userFileMgrConstructor_,
.constructor = FetchFileResultNapiConstructor,
.props = {
DECLARE_NAPI_FUNCTION("getCount", JSGetCount),
DECLARE_NAPI_FUNCTION("isAfterLast", JSIsAfterLast),
DECLARE_NAPI_FUNCTION("getFirstObject", JSGetFirstObject),
DECLARE_NAPI_FUNCTION("getNextObject", JSGetNextObject),
DECLARE_NAPI_FUNCTION("getLastObject", JSGetLastObject),
DECLARE_NAPI_FUNCTION("getPositionObject", JSGetPositionObject),
DECLARE_NAPI_FUNCTION("getAllObject", JSGetAllObject),
DECLARE_NAPI_FUNCTION("close", JSClose)
}
};
MediaLibraryNapiUtils::NapiDefineClass(env, exports, info);
return exports;
}
napi_value FetchFileResultNapi::PhotoAccessHelperInit(napi_env env, napi_value exports)
{
NapiClassInfo info = {
.name = PAH_FETCH_FILE_RESULT_CLASS_NAME,
.ref = &photoAccessHelperConstructor_,
.constructor = FetchFileResultNapiConstructor,
.props = {
DECLARE_NAPI_FUNCTION("getCount", JSGetCount),
DECLARE_NAPI_FUNCTION("isAfterLast", JSIsAfterLast),
DECLARE_NAPI_FUNCTION("getFirstObject", JSGetFirstObject),
DECLARE_NAPI_FUNCTION("getNextObject", JSGetNextObject),
DECLARE_NAPI_FUNCTION("getLastObject", JSGetLastObject),
DECLARE_NAPI_FUNCTION("getObjectByPosition", JSGetPositionObject),
DECLARE_NAPI_FUNCTION("getAllObjects", JSGetAllObject),
DECLARE_NAPI_FUNCTION("getRangeObjects", JSGetRangeObjects),
DECLARE_NAPI_FUNCTION("contains", JSContains),
DECLARE_NAPI_FUNCTION("getObjectsByIndexSet", JSGetObjectsByIndexSet),
DECLARE_NAPI_FUNCTION("getIndex", JSGetIndex),
DECLARE_NAPI_FUNCTION("close", JSClose)
}
};
MediaLibraryNapiUtils::NapiDefineClass(env, exports, info);
return exports;
}
static bool CheckIfFFRNapiNotEmpty(FetchFileResultNapi* obj)
{
if (obj == nullptr) {
NAPI_INFO_LOG("FetchFileResultNapi is nullptr");
return false;
}
if (obj->CheckIfPropertyPtrNull()) {
NAPI_INFO_LOG("PropertyPtr in FetchFileResultNapi is nullptr");
return false;
}
return true;
}
void GetCountFromObject(FetchFileResultNapi* obj, int32_t &count)
{
switch (obj->GetFetchResType()) {
case FetchResType::TYPE_FILE:
CHECK_NULL_PTR_RETURN_VOID(obj, "obj is nullptr");
CHECK_NULL_PTR_RETURN_VOID(obj->GetFetchFileResultObject(),
"GetFetchFileResultObject is nullptr");
count = obj->GetFetchFileResultObject()->GetCount();
break;
case FetchResType::TYPE_ALBUM:
CHECK_NULL_PTR_RETURN_VOID(obj, "obj is nullptr");
CHECK_NULL_PTR_RETURN_VOID(obj->GetFetchAlbumResultObject(),
"GetFetchAlbumResultObject is nullptr");
count = obj->GetFetchAlbumResultObject()->GetCount();
break;
case FetchResType::TYPE_PHOTOALBUM:
CHECK_NULL_PTR_RETURN_VOID(obj, "obj is nullptr");
CHECK_NULL_PTR_RETURN_VOID(obj->GetFetchPhotoAlbumResultObject(),
"GetFetchPhotoAlbumResultObject is nullptr");
count = obj->GetFetchPhotoAlbumResultObject()->GetCount();
break;
case FetchResType::TYPE_SMARTALBUM:
CHECK_NULL_PTR_RETURN_VOID(obj, "obj is nullptr");
CHECK_NULL_PTR_RETURN_VOID(obj->GetFetchSmartAlbumResultObject(),
"GetFetchSmartAlbumResultObject is nullptr");
count = obj->GetFetchSmartAlbumResultObject()->GetCount();
break;
case FetchResType::TYPE_CUSTOMRECORD:
CHECK_NULL_PTR_RETURN_VOID(obj, "obj is nullptr");
CHECK_NULL_PTR_RETURN_VOID(obj->GetFetchCustomRecordResultObject(),
"GetFetchCustomRecordResultObject is nullptr");
count = obj->GetFetchCustomRecordResultObject()->GetCount();
break;
case FetchResType::TYPE_ALBUMORDER:
CHECK_NULL_PTR_RETURN_VOID(obj, "obj is nullptr");
CHECK_NULL_PTR_RETURN_VOID(obj->GetFetchAlbumOrderResultObject(),
"GetFetchAlbumOrderResultObject is nullptr");
count = obj->GetFetchAlbumOrderResultObject()->GetCount();
break;
default:
NAPI_ERR_LOG("unsupported FetchResType");
break;
}
}
static void SetTranscodeInfo(FetchFileResultAsyncContext* context)
{
if (context->objectPtr->fetchResType_ == FetchResType::TYPE_FILE &&
(context->objectPtr->fetchFileResult_->supportedHeif == -1 ||
context->objectPtr->fetchFileResult_->supportedHighResolution == -1)) {
GetTranscodeCheckInfoReqBody reqBody;
GetTranscodeCheckInfoRespBody respBody;
reqBody.bundleName = UserFileClient::GetBundleName();
int32_t ret = IPC::UserDefineIPCClient().Call(
static_cast<uint32_t>(MediaLibraryBusinessCode::GET_TRANSCODE_CHECK_INFO), reqBody, respBody);
if (ret != 0) {
NAPI_ERR_LOG("UserDefineIPCClient().Call failed, ret: %{public}d", ret);
return;
}
if (respBody.preferredCompatibleMode == static_cast<int32_t>(PreferredCompatibleMode::CURRENT)) {
context->objectPtr->fetchFileResult_->supportedHeif = 1;
context->objectPtr->fetchFileResult_->supportedHighResolution = 1;
return;
}
if (respBody.preferredCompatibleMode == static_cast<int32_t>(PreferredCompatibleMode::COMPATIBLE)) {
context->objectPtr->fetchFileResult_->supportedHeif = 0;
context->objectPtr->fetchFileResult_->supportedHighResolution = 0;
return;
}
auto types = respBody.supportedMimeTypes;
context->objectPtr->fetchFileResult_->supportedHeif =
(std::find(types.begin(), types.end(), "image/heic") != types.end() ||
std::find(types.begin(), types.end(), "image/heif") != types.end());
context->objectPtr->fetchFileResult_->supportedHighResolution = respBody.supportedHighResolution;
}
}
napi_value FetchFileResultNapi::JSGetCount(napi_env env, napi_callback_info info)
{
napi_status status;
napi_value jsResult = nullptr;
FetchFileResultNapi* obj = nullptr;
int32_t count = 0;
napi_value thisVar = nullptr;
MediaLibraryTracer tracer;
tracer.Start("JSGetCount");
napi_get_undefined(env, &jsResult);
GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
if (status != napi_ok || thisVar == nullptr) {
NAPI_ERR_LOG("JSGetCount Invalid arguments!, status: %{public}d", status);
NAPI_ASSERT(env, false, "JSGetCount thisVar == nullptr");
}
status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
if ((status == napi_ok) && CheckIfFFRNapiNotEmpty(obj)) {
GetCountFromObject(obj, count);
if (count < 0) {
NapiError::ThrowError(env, JS_INNER_FAIL, "Failed to get count");
return nullptr;
}
napi_create_int32(env, count, &jsResult);
} else {
NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID, "Failed to get native obj");
return nullptr;
}
return jsResult;
}
napi_value FetchFileResultNapi::JSIsAfterLast(napi_env env, napi_callback_info info)
{
napi_status status;
napi_value jsResult = nullptr;
FetchFileResultNapi* obj = nullptr;
bool isAfterLast = false;
napi_value thisVar = nullptr;
MediaLibraryTracer tracer;
tracer.Start("JSIsAfterLast");
napi_get_undefined(env, &jsResult);
GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
if (status != napi_ok || thisVar == nullptr) {
NAPI_ERR_LOG("JSIsAfterLast Invalid arguments!, status: %{public}d", status);
NAPI_ASSERT(env, false, "JSIsAfterLast thisVar == nullptr");
}
status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
if ((status == napi_ok) && CheckIfFFRNapiNotEmpty(obj)) {
switch (obj->GetFetchResType()) {
case FetchResType::TYPE_FILE:
isAfterLast = obj->GetFetchFileResultObject()->IsAtLastRow();
break;
case FetchResType::TYPE_ALBUM:
isAfterLast = obj->GetFetchAlbumResultObject()->IsAtLastRow();
break;
case FetchResType::TYPE_PHOTOALBUM:
isAfterLast = obj->GetFetchPhotoAlbumResultObject()->IsAtLastRow();
break;
case FetchResType::TYPE_SMARTALBUM:
isAfterLast = obj->GetFetchSmartAlbumResultObject()->IsAtLastRow();
break;
case FetchResType::TYPE_CUSTOMRECORD:
isAfterLast = obj->GetFetchCustomRecordResultObject()->IsAtLastRow();
break;
case FetchResType::TYPE_ALBUMORDER:
isAfterLast = obj->GetFetchAlbumOrderResultObject()->IsAtLastRow();
break;
default:
NAPI_ERR_LOG("unsupported FetchResType");
break;
}
napi_get_boolean(env, isAfterLast, &jsResult);
} else {
NAPI_ERR_LOG("JSIsAfterLast obj == nullptr, status: %{public}d", status);
NAPI_ASSERT(env, false, "JSIsAfterLast obj == nullptr");
}
return jsResult;
}
static void GetNapiResFromAsset(napi_env env, FetchFileResultAsyncContext *context,
unique_ptr<JSAsyncContextOutput> &jsContext)
{
napi_value jsAsset;
CHECK_NULL_PTR_RETURN_VOID(context, "GetNapiResFromAsset async context is nullptr");
switch (context->objectPtr->fetchResType_) {
NAPI_INFO_LOG("GetNapiResFromAsset fetchResType: %{public}d",
static_cast<int32_t>(context->objectPtr->fetchResType_));
case FetchResType::TYPE_FILE:
if (context->fileAsset != nullptr && context->objectPtr->fetchFileResult_ != nullptr) {
context->fileAsset->SetUserId(context->objectPtr->fetchFileResult_->GetUserId());
}
jsAsset = FileAssetNapi::CreateFileAsset(env, context->fileAsset);
break;
case FetchResType::TYPE_ALBUM:
jsAsset = AlbumNapi::CreateAlbumNapi(env, context->albumAsset);
break;
case FetchResType::TYPE_PHOTOALBUM:
if (context->photoAlbum != nullptr && context->objectPtr->fetchPhotoAlbumResult_ != nullptr) {
context->photoAlbum->SetUserId(context->objectPtr->fetchPhotoAlbumResult_->GetUserId());
}
jsAsset = PhotoAlbumNapi::CreatePhotoAlbumNapi(env, context->photoAlbum);
break;
case FetchResType::TYPE_SMARTALBUM:
jsAsset = SmartAlbumNapi::CreateSmartAlbumNapi(env, context->smartAlbumAsset);
break;
case FetchResType::TYPE_CUSTOMRECORD:
jsAsset = PhotoAssetCustomRecordNapi::CreateCustomRecordNapi(env, context->customRecordAsset);
break;
case FetchResType::TYPE_ALBUMORDER:
jsAsset = AlbumOrderNapi::CreateAlbumOrderNapi(env, context->albumOrder);
break;
default:
NAPI_ERR_LOG("unsupported FetchResType");
break;
}
if (jsAsset == nullptr) {
NAPI_ERR_LOG("Failed to get file asset napi object");
napi_get_undefined(env, &jsContext->data);
MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, JS_INNER_FAIL,
"System inner fail");
} else {
jsContext->data = jsAsset;
napi_get_undefined(env, &jsContext->error);
jsContext->status = true;
}
}
static void GetPositionObjectCompleteCallback(napi_env env, napi_status status, FetchFileResultAsyncContext* context)
{
MediaLibraryTracer tracer;
tracer.Start("GetPositionObjectCompleteCallback");
CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
unique_ptr<JSAsyncContextOutput> jsContext = make_unique<JSAsyncContextOutput>();
jsContext->status = false;
GetNapiResFromAsset(env, context, jsContext);
if (context->work != nullptr) {
MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
context->work, *jsContext);
}
delete context;
}
napi_value FetchFileResultNapi::JSGetFirstObject(napi_env env, napi_callback_info info)
{
napi_status status;
napi_value result = nullptr;
const int32_t refCount = 1;
napi_value resource = nullptr;
size_t argc = ARGS_ONE;
napi_value argv[ARGS_ONE] = {0};
napi_value thisVar = nullptr;
MediaLibraryTracer tracer;
tracer.Start("JSGetFirstObject");
GET_JS_ARGS(env, info, argc, argv, thisVar);
NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameter");
napi_get_undefined(env, &result);
unique_ptr<FetchFileResultAsyncContext> asyncContext = make_unique<FetchFileResultAsyncContext>();
status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
if (status == napi_ok && CheckIfFFRNapiNotEmpty(asyncContext->objectInfo)) {
if (argc == ARGS_ONE) {
GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef);
}
NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
NAPI_CREATE_RESOURCE_NAME(env, resource, "JSGetFirstObject", asyncContext);
asyncContext->objectPtr = asyncContext->objectInfo->propertyPtr;
CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "propertyPtr is nullptr");
status = napi_create_async_work(
env, nullptr, resource, [](napi_env env, void *data) {
auto context = static_cast<FetchFileResultAsyncContext*>(data);
SetTranscodeInfo(context);
context->GetFirstAsset();
},
reinterpret_cast<napi_async_complete_callback>(GetPositionObjectCompleteCallback),
static_cast<void *>(asyncContext.get()), &asyncContext->work);
if (status != napi_ok) {
napi_get_undefined(env, &result);
} else {
napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
asyncContext.release();
}
} else {
NAPI_ERR_LOG("JSGetFirstObject obj == nullptr, status: %{public}d", status);
NAPI_ASSERT(env, false, "JSGetFirstObject obj == nullptr");
}
return result;
}
napi_value FetchFileResultNapi::JSGetNextObject(napi_env env, napi_callback_info info)
{
napi_status status;
napi_value result = nullptr;
const int32_t refCount = 1;
napi_value resource = nullptr;
size_t argc = ARGS_ONE;
napi_value argv[ARGS_ONE] = {0};
napi_value thisVar = nullptr;
MediaLibraryTracer tracer;
tracer.Start("JSGetNextObject");
GET_JS_ARGS(env, info, argc, argv, thisVar);
NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameter");
napi_get_undefined(env, &result);
unique_ptr<FetchFileResultAsyncContext> asyncContext = make_unique<FetchFileResultAsyncContext>();
status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
if (status == napi_ok && CheckIfFFRNapiNotEmpty(asyncContext->objectInfo)) {
if (argc == ARGS_ONE) {
GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef);
}
NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
NAPI_CREATE_RESOURCE_NAME(env, resource, "JSGetNextObject", asyncContext);
asyncContext->objectPtr = asyncContext->objectInfo->propertyPtr;
CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "propertyPtr is nullptr");
status = napi_create_async_work(
env, nullptr, resource, [](napi_env env, void *data) {
auto context = static_cast<FetchFileResultAsyncContext*>(data);
SetTranscodeInfo(context);
context->GetNextObject();
},
reinterpret_cast<napi_async_complete_callback>(GetPositionObjectCompleteCallback),
static_cast<void *>(asyncContext.get()), &asyncContext->work);
if (status != napi_ok) {
napi_get_undefined(env, &result);
asyncContext.release();
} else {
napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
asyncContext.release();
}
} else {
asyncContext.release();
NAPI_ERR_LOG("JSGetNextObject obj == nullptr, status: %{public}d", status);
NAPI_ASSERT(env, false, "JSGetNextObject obj == nullptr");
}
return result;
}
napi_value FetchFileResultNapi::JSGetLastObject(napi_env env, napi_callback_info info)
{
napi_status status;
napi_value result = nullptr;
const int32_t refCount = 1;
napi_value resource = nullptr;
size_t argc = ARGS_ONE;
napi_value argv[ARGS_ONE] = {0};
napi_value thisVar = nullptr;
MediaLibraryTracer tracer;
tracer.Start("JSGetLastObject");
GET_JS_ARGS(env, info, argc, argv, thisVar);
NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameter");
napi_get_undefined(env, &result);
unique_ptr<FetchFileResultAsyncContext> asyncContext = make_unique<FetchFileResultAsyncContext>();
status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
if (status == napi_ok && CheckIfFFRNapiNotEmpty(asyncContext->objectInfo)) {
if (argc == ARGS_ONE) {
GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef);
}
NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
NAPI_CREATE_RESOURCE_NAME(env, resource, "JSGetLastObject", asyncContext);
asyncContext->objectPtr = asyncContext->objectInfo->propertyPtr;
CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "propertyPtr is nullptr");
status = napi_create_async_work(
env, nullptr, resource, [](napi_env env, void *data) {
auto context = static_cast<FetchFileResultAsyncContext*>(data);
SetTranscodeInfo(context);
context->GetLastObject();
},
reinterpret_cast<napi_async_complete_callback>(GetPositionObjectCompleteCallback),
static_cast<void *>(asyncContext.get()), &asyncContext->work);
if (status != napi_ok) {
napi_get_undefined(env, &result);
} else {
napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
asyncContext.release();
}
} else {
NAPI_ERR_LOG("JSGetLastObject obj == nullptr, status: %{public}d", status);
NAPI_ASSERT(env, false, "JSGetLastObject obj == nullptr");
}
return result;
}
napi_value FetchFileResultNapi::JSGetPositionObject(napi_env env, napi_callback_info info)
{
napi_status status;
napi_value result = nullptr;
const int32_t refCount = 1;
napi_valuetype type = napi_undefined;
napi_value resource = nullptr;
size_t argc = ARGS_TWO;
napi_value argv[ARGS_TWO] = {0};
napi_value thisVar = nullptr;
MediaLibraryTracer tracer;
tracer.Start("JSGetPositionObject");
GET_JS_ARGS(env, info, argc, argv, thisVar);
NAPI_ASSERT(env, (argc == ARGS_ONE || argc == ARGS_TWO), "requires 2 parameter maximum");
napi_get_undefined(env, &result);
unique_ptr<FetchFileResultAsyncContext> asyncContext = make_unique<FetchFileResultAsyncContext>();
status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
if (status == napi_ok && CheckIfFFRNapiNotEmpty(asyncContext->objectInfo)) {
napi_typeof(env, argv[PARAM0], &type);
if (type == napi_number) {
napi_get_value_int32(env, argv[PARAM0], &(asyncContext->position));
} else {
NAPI_ERR_LOG("Argument mismatch, type: %{public}d", type);
return result;
}
if (argc == ARGS_TWO) {
GET_JS_ASYNC_CB_REF(env, argv[PARAM1], refCount, asyncContext->callbackRef);
}
NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
NAPI_CREATE_RESOURCE_NAME(env, resource, "JSGetPositionObject", asyncContext);
asyncContext->objectPtr = asyncContext->objectInfo->propertyPtr;
CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "propertyPtr is nullptr");
status = napi_create_async_work(
env, nullptr, resource, [](napi_env env, void *data) {
auto context = static_cast<FetchFileResultAsyncContext*>(data);
SetTranscodeInfo(context);
context->GetObjectAtPosition();
},
reinterpret_cast<napi_async_complete_callback>(GetPositionObjectCompleteCallback),
static_cast<void *>(asyncContext.get()), &asyncContext->work);
if (status != napi_ok) {
napi_get_undefined(env, &result);
} else {
napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
asyncContext.release();
}
} else {
NAPI_ASSERT(env, false, "JSGetPositionObject obj == nullptr");
}
return result;
}
static napi_value GetAsset(napi_env env, vector<std::unique_ptr<FileAsset>> &array, int index)
{
return FileAssetNapi::CreateFileAsset(env, array[index]);
}
static napi_value GetAsset(napi_env env, vector<std::unique_ptr<AlbumAsset>> &array, int index)
{
return AlbumNapi::CreateAlbumNapi(env, array[index]);
}
static napi_value GetAsset(napi_env env, vector<std::unique_ptr<PhotoAlbum>> &array, int index)
{
return PhotoAlbumNapi::CreatePhotoAlbumNapi(env, array[index]);
}
static napi_value GetAsset(napi_env env, vector<std::unique_ptr<SmartAlbumAsset>> &array, int index)
{
return SmartAlbumNapi::CreateSmartAlbumNapi(env, array[index]);
}
static napi_value GetAsset(napi_env env, vector<std::unique_ptr<AlbumOrder>> &array, int index)
{
return AlbumOrderNapi::CreateAlbumOrderNapi(env, array[index]);
}
static napi_value GetAsset(napi_env env, vector<std::unique_ptr<PhotoAssetCustomRecord>> &array, int index)
{
return PhotoAssetCustomRecordNapi::CreateCustomRecordNapi(env, array[index]);
}
template<class T>
static void GetAssetFromArray(napi_env env, FetchFileResultAsyncContext* context, T& array,
unique_ptr<JSAsyncContextOutput> &jsContext)
{
napi_value jsFileArray = nullptr;
napi_create_array_with_length(env, array.size(), &jsFileArray);
napi_value jsFileAsset = nullptr;
size_t i = 0;
for (i = 0; i < array.size(); i++) {
jsFileAsset = GetAsset(env, array, i);
if ((jsFileAsset == nullptr) || (napi_set_element(env, jsFileArray, i, jsFileAsset) != napi_ok)) {
NAPI_ERR_LOG("Failed to get file asset napi object");
napi_get_undefined(env, &jsContext->data);
MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_MEM_ALLOCATION,
"Failed to create js object");
break;
}
}
if (i == array.size()) {
jsContext->data = jsFileArray;
napi_get_undefined(env, &jsContext->error);
jsContext->status = true;
}
}
static void GetAllObjectCompleteCallback(napi_env env, napi_status status, FetchFileResultAsyncContext* context)
{
MediaLibraryTracer tracer;
tracer.Start("GetAllObjectCompleteCallback");
CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
unique_ptr<JSAsyncContextOutput> jsContext = make_unique<JSAsyncContextOutput>();
jsContext->status = false;
CHECK_NULL_PTR_RETURN_VOID(context->objectPtr, "Async objectPtr is null");
switch (context->objectPtr->fetchResType_) {
case FetchResType::TYPE_FILE:
GetAssetFromArray(env, context, context->fileAssetArray, jsContext);
break;
case FetchResType::TYPE_ALBUM:
GetAssetFromArray(env, context, context->fileAlbumArray, jsContext);
break;
case FetchResType::TYPE_PHOTOALBUM:
GetAssetFromArray(env, context, context->filePhotoAlbumArray, jsContext);
break;
case FetchResType::TYPE_SMARTALBUM:
GetAssetFromArray(env, context, context->fileSmartAlbumArray, jsContext);
break;
case FetchResType::TYPE_ALBUMORDER:
GetAssetFromArray(env, context, context->fileAlbumOrderArray, jsContext);
break;
case FetchResType::TYPE_CUSTOMRECORD:
GetAssetFromArray(env, context, context->customRecordArray, jsContext);
break;
default:
NAPI_ERR_LOG("unsupported FetchResType");
napi_get_undefined(env, &jsContext->data);
MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_INVALID_OUTPUT,
"Failed to obtain fileAsset array from DB");
}
if (context->work != nullptr) {
int64_t start = MediaFileUtils::UTCTimeMilliSeconds();
MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
context->work, *jsContext);
int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
int64_t normalTime = 500;
if ((long)(end - start) >= normalTime) {
NAPI_INFO_LOG("InvokeJSAsync dir cost: %{public}ld", (long)(end - start));
}
}
delete context;
}
std::shared_ptr<FetchResult<FileAsset>> FetchFileResultNapi::GetFetchFileResultObject()
{
return propertyPtr->fetchFileResult_;
}
std::shared_ptr<FetchResult<AlbumAsset>> FetchFileResultNapi::GetFetchAlbumResultObject()
{
return propertyPtr->fetchAlbumResult_;
}
std::shared_ptr<FetchResult<PhotoAlbum>> FetchFileResultNapi::GetFetchPhotoAlbumResultObject()
{
return propertyPtr->fetchPhotoAlbumResult_;
}
std::shared_ptr<FetchResult<SmartAlbumAsset>> FetchFileResultNapi::GetFetchSmartAlbumResultObject()
{
return propertyPtr->fetchSmartAlbumResult_;
}
std::shared_ptr<FetchResult<PhotoAssetCustomRecord>> FetchFileResultNapi::GetFetchCustomRecordResultObject()
{
if (propertyPtr == nullptr) {
return nullptr;
}
return propertyPtr->fetchCustomRecordResult_;
}
std::shared_ptr<FetchResult<AlbumOrder>> FetchFileResultNapi::GetFetchAlbumOrderResultObject()
{
CHECK_NULLPTR_RET(propertyPtr);
return propertyPtr->fetchAlbumOrderResult_;
}
void GetAllObjectFromFetchResult(const FetchFileResultAsyncContext &asyncContext)
{
MediaLibraryTracer tracer;
tracer.Start("GetAllObjectFromFetchResult");
FetchFileResultAsyncContext *context = const_cast<FetchFileResultAsyncContext *>(&asyncContext);
context->GetAllObjectFromFetchResult();
}
napi_value FetchFileResultNapi::JSGetAllObject(napi_env env, napi_callback_info info)
{
napi_status status;
napi_value result = nullptr;
const int32_t refCount = 1;
napi_value resource = nullptr;
size_t argc = ARGS_ONE;
napi_value argv[ARGS_ONE] = {0};
napi_value thisVar = nullptr;
MediaLibraryTracer tracer;
tracer.Start("JSGetAllObject");
GET_JS_ARGS(env, info, argc, argv, thisVar);
NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameter maximum");
napi_get_undefined(env, &result);
unique_ptr<FetchFileResultAsyncContext> asyncContext = make_unique<FetchFileResultAsyncContext>();
status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
if (status == napi_ok && CheckIfFFRNapiNotEmpty(asyncContext->objectInfo)) {
if (argc == ARGS_ONE) {
GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef);
}
NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
NAPI_CREATE_RESOURCE_NAME(env, resource, "JSGetAllObject", asyncContext);
asyncContext->objectPtr = asyncContext->objectInfo->propertyPtr;
CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "propertyPtr is nullptr");
status = napi_create_async_work(
env, nullptr, resource, [](napi_env env, void *data) {
auto context = static_cast<FetchFileResultAsyncContext*>(data);
SetTranscodeInfo(context);
GetAllObjectFromFetchResult(*context);
},
reinterpret_cast<napi_async_complete_callback>(GetAllObjectCompleteCallback),
static_cast<void *>(asyncContext.get()), &asyncContext->work);
if (status != napi_ok) {
napi_get_undefined(env, &result);
} else {
napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
asyncContext.release();
}
} else {
NAPI_ERR_LOG("JSGetAllObject obj == nullptr, status: %{public}d", status);
NAPI_ASSERT(env, false, "JSGetAllObject obj == nullptr");
}
return result;
}
napi_value FetchFileResultNapi::ProcessValidContext(
napi_env env, unique_ptr<FetchFileResultAsyncContext> &asyncContext, napi_value argv[], napi_value &result)
{
napi_valuetype type = napi_undefined;
napi_typeof(env, argv[PARAM0], &type);
if (type == napi_number) {
napi_get_value_int32(env, argv[PARAM0], &(asyncContext->offset));
} else {
NAPI_ERR_LOG("Invalid offset type: %{public}d", type);
NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID, "Invalid offset type");
return nullptr;
}
napi_typeof(env, argv[PARAM1], &type);
if (type == napi_number) {
napi_get_value_int32(env, argv[PARAM1], &(asyncContext->length));
} else {
NAPI_ERR_LOG("Invalid length type: %{public}d", type);
NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID, "Invalid length type");
return nullptr;
}
int32_t total_count = 0;
GetCountFromObject(asyncContext->objectInfo, total_count);
if (asyncContext->offset < 0 || asyncContext->length <= 0 ||
(asyncContext->offset + asyncContext->length) > total_count) {
NapiError::ThrowError(env, JS_E_PARAM_INVALID, "Index exceeds range of objects");
return nullptr;
}
NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
napi_value resource = nullptr;
NAPI_CREATE_RESOURCE_NAME(env, resource, "JSGetRangeObjects", asyncContext);
asyncContext->objectPtr = asyncContext->objectInfo->propertyPtr;
return resource;
}
napi_value FetchFileResultNapi::JSGetRangeObjects(napi_env env, napi_callback_info info)
{
napi_status status;
napi_value result = nullptr;
const int32_t refCount = 1;
size_t argc = ARGS_THREE;
napi_value argv[ARGS_THREE] = {0};
napi_value thisVar = nullptr;
MediaLibraryTracer tracer;
tracer.Start("JSGetRangeObjects");
GET_JS_ARGS(env, info, argc, argv, thisVar);
NAPI_ASSERT(env, argc <= ARGS_THREE, "requires 3 parameter maximum");
napi_get_undefined(env, &result);
unique_ptr<FetchFileResultAsyncContext> asyncContext = make_unique<FetchFileResultAsyncContext>();
status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
if (status == napi_ok && CheckIfFFRNapiNotEmpty(asyncContext->objectInfo)) {
if (argc == ARGS_THREE) {
GET_JS_ASYNC_CB_REF(env, argv[PARAM2], refCount, asyncContext->callbackRef);
}
napi_value resource = ProcessValidContext(env, asyncContext, argv, result);
CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "propertyPtr is nullptr");
napi_status status = napi_create_async_work(
env, nullptr, resource, [](napi_env env, void *data) {
auto context = static_cast<FetchFileResultAsyncContext *>(data);
SetTranscodeInfo(context);
context->GetObjectsInRange();
},
reinterpret_cast<napi_async_complete_callback>(GetAllObjectCompleteCallback),
static_cast<void *>(asyncContext.get()),
&asyncContext->work);
if (status != napi_ok) {
napi_get_undefined(env, &result);
} else {
napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
asyncContext.release();
}
} else {
NAPI_ERR_LOG("JSGetRangeObjects obj == nullptr, status: %{public}d", status);
NAPI_ASSERT(env, false, "JSGetRangeObjects obj == nullptr");
}
return result;
}
static void GetContainsCompleteCallback(napi_env env, napi_status status, FetchFileResultAsyncContext* context)
{
MediaLibraryTracer tracer;
tracer.Start("GetContainsCompleteCallback");
CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
unique_ptr<JSAsyncContextOutput> jsContext = make_unique<JSAsyncContextOutput>();
jsContext->status = false;
CHECK_ARGS_RET_VOID_WITH_MEG(env, napi_get_undefined(env, &jsContext->data), JS_E_INNER_FAIL,
"Failed to initialize data field");
CHECK_ARGS_RET_VOID_WITH_MEG(env, napi_get_undefined(env, &jsContext->error), JS_E_INNER_FAIL,
"Failed to initialize error field");
if (context->error == ERR_DEFAULT) {
CHECK_ARGS_RET_VOID_WITH_MEG(env,
napi_get_boolean(env, context->fetchResultIndexId != -1, &jsContext->data), JS_E_INNER_FAIL,
"Failed to create boolean value");
jsContext->status = true;
} else {
context->HandleError(env, jsContext->error);
}
if (context->work != nullptr) {
MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
context->work, *jsContext);
}
delete context;
}
static void GetIndexCompleteCallback(napi_env env, napi_status status, FetchFileResultAsyncContext* context)
{
MediaLibraryTracer tracer;
tracer.Start("GetIndexCompleteCallback");
CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
unique_ptr<JSAsyncContextOutput> jsContext = make_unique<JSAsyncContextOutput>();
jsContext->status = false;
CHECK_ARGS_RET_VOID_WITH_MEG(env, napi_get_undefined(env, &jsContext->data), JS_E_INNER_FAIL,
"Failed to initialize data field");
CHECK_ARGS_RET_VOID_WITH_MEG(env, napi_get_undefined(env, &jsContext->error), JS_E_INNER_FAIL,
"Failed to initialize error field");
if (context->error == ERR_DEFAULT) {
CHECK_ARGS_RET_VOID_WITH_MEG(env,
napi_create_int32(env, context->fetchResultIndexId, &jsContext->data), JS_E_INNER_FAIL,
"Failed to get int32 value");
jsContext->status = true;
} else {
context->HandleError(env, jsContext->error);
}
if (context->work != nullptr) {
MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
context->work, *jsContext);
}
delete context;
}
static napi_status CheckArgValuePre(napi_env env, void* data, const napi_value arg)
{
auto* context = static_cast<FetchFileResultAsyncContext*>(data);
if (context == nullptr) {
NAPI_ERR_LOG("context is nullptr.");
return napi_invalid_arg;
}
if (context->objectInfo == nullptr) {
NAPI_ERR_LOG("context->objectInfo is nullptr.");
return napi_invalid_arg;
}
switch (context->objectInfo->GetFetchResType()) {
case FetchResType::TYPE_FILE:
CHECK_STATUS_RET(napi_unwrap(env, arg, reinterpret_cast<void**>(&context->fileAssetParameter)),
"Failed to unwrap arg.");
CHECK_COND_RET(context->fileAssetParameter != nullptr, napi_invalid_arg,
"Failed to get FileAssetNapi object");
context->indexObjectId = context->fileAssetParameter->GetFileId();
break;
case FetchResType::TYPE_ALBUM:
CHECK_STATUS_RET(napi_unwrap(env, arg, reinterpret_cast<void**>(&context->albumAssetParameter)),
"Failed to unwrap arg.");
CHECK_COND_RET(context->albumAssetParameter != nullptr, napi_invalid_arg,
"Failed to get AlbumAssetNapi object");
context->indexObjectId = context->albumAssetParameter->GetAlbumId();
break;
case FetchResType::TYPE_PHOTOALBUM:
CHECK_STATUS_RET(napi_unwrap(env, arg, reinterpret_cast<void**>(&context->photoAlbumParameter)),
"Failed to unwrap arg.");
CHECK_COND_RET(context->photoAlbumParameter != nullptr, napi_invalid_arg,
"Failed to get PhotoAlbumNapi object");
context->indexObjectId = context->photoAlbumParameter->GetAlbumId();
context->albumType = static_cast<int32_t>(context->photoAlbumParameter->GetPhotoAlbumType());
context->albumSubType = static_cast<int32_t>(context->photoAlbumParameter->GetPhotoAlbumSubType());
break;
default:
NAPI_INFO_LOG("need more check.");
return napi_invalid_arg;
}
return napi_ok;
}
static napi_status CheckArgValue(napi_env env, void* data, const napi_value arg)
{
if (CheckArgValuePre(env, data, arg) == napi_ok) {
return napi_ok;
}
auto* context = static_cast<FetchFileResultAsyncContext*>(data);
if (context == nullptr) {
NAPI_ERR_LOG("context is nullptr.");
return napi_invalid_arg;
}
if (context->objectInfo == nullptr) {
NAPI_ERR_LOG("context->objectInfo is nullptr.");
return napi_invalid_arg;
}
switch (context->objectInfo->GetFetchResType()) {
case FetchResType::TYPE_SMARTALBUM:
CHECK_STATUS_RET(napi_unwrap(env, arg, reinterpret_cast<void**>(&context->smartAlbumAssetParameter)),
"Failed to unwrap arg.");
CHECK_COND_RET(context->smartAlbumAssetParameter != nullptr, napi_invalid_arg,
"Failed to get SmartAlbumNapi object");
context->indexObjectId = context->smartAlbumAssetParameter->GetSmartAlbumId();
break;
case FetchResType::TYPE_CUSTOMRECORD:
CHECK_STATUS_RET(napi_unwrap(env, arg, reinterpret_cast<void**>(&context->customRecordAssetParameter)),
"Failed to unwrap arg.");
CHECK_COND_RET(context->customRecordAssetParameter != nullptr, napi_invalid_arg,
"Failed to get CustomRecordNapi object");
context->indexObjectId = context->customRecordAssetParameter->GetFileId();
break;
case FetchResType::TYPE_ALBUMORDER:
CHECK_STATUS_RET(napi_unwrap(env, arg, reinterpret_cast<void**>(&context->albumOrderParameter)),
"Failed to unwrap arg.");
CHECK_COND_RET(context->albumOrderParameter != nullptr, napi_invalid_arg,
"Failed to get AlbumOrderNapi object");
context->indexObjectId = context->albumOrderParameter->GetAlbumId();
break;
default:
NAPI_ERR_LOG("unsupported FetchResType");
return napi_invalid_arg;
}
return napi_ok;
}
static napi_status ProcessIndexSet(napi_env env, void* data, const napi_value arg)
{
auto* context = static_cast<FetchFileResultAsyncContext*>(data);
if (context == nullptr) {
NAPI_ERR_LOG("context is nullptr.");
return napi_invalid_arg;
}
if (context->objectInfo == nullptr) {
NAPI_ERR_LOG("context->objectInfo is nullptr.");
return napi_invalid_arg;
}
napi_valuetype valueType;
napi_typeof(env, arg, &valueType);
if (valueType == napi_undefined || valueType == napi_null) {
NAPI_ERR_LOG("JSGetObjectsByIndexSet indexSet is null or undefined");
NapiError::ThrowError(env, JS_E_PARAM_INVALID, "indexSet is null or undefined");
return napi_invalid_arg;
}
napi_status status = MediaLibraryNapiUtils::GetInt32Array(env, arg, context->indexSet);
if (status != napi_ok) {
NapiError::ThrowError(env, JS_E_PARAM_INVALID, "indexSet is not int.");
return napi_invalid_arg;
}
if (context->indexSet.empty()) {
NAPI_ERR_LOG("JSGetObjectsByIndexSet indexSet is empty!");
NapiError::ThrowError(env, JS_E_PARAM_INVALID, "indexSet is empty");
return napi_invalid_arg;
}
if (context->indexSet.size() > MAX_SIZE) {
NAPI_ERR_LOG("JSGetObjectsByIndexSet indexSet.size exceeds MAX_SIZE");
NapiError::ThrowError(env, JS_E_PARAM_INVALID, "indexSet.size exceeds MAX_SIZE");
return napi_invalid_arg;
}
std::set<int32_t> tempIndexSet(context->indexSet.begin(), context->indexSet.end());
int32_t minIndex = *tempIndexSet.begin();
int32_t maxIndex = *tempIndexSet.rbegin();
int32_t total_count = 0;
GetCountFromObject(context->objectInfo, total_count);
if (minIndex < 0 || maxIndex >= total_count) {
NapiError::ThrowError(env, JS_E_PARAM_INVALID, "Index exceeds range of objects");
return napi_invalid_arg;
}
return napi_ok;
}
napi_value FetchFileResultNapi::JSContains(napi_env env, napi_callback_info info)
{
napi_status status;
napi_value result = nullptr;
size_t argc = ARGS_ONE;
napi_value argv[ARGS_ONE] = { 0 };
napi_value thisVar = nullptr;
napi_valuetype valueType;
MediaLibraryTracer tracer;
tracer.Start("JSContains");
CHECK_ARGS_WITH_MSG(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr), JS_E_INNER_FAIL,
"Failed to get callback info");
NAPI_ASSERT(env, argc == ARGS_ONE, "Number of args is invalid");
CHECK_ARGS_WITH_MSG(env, napi_typeof(env, argv[PARAM0], &valueType), JS_E_INNER_FAIL,
"Failed to get argument type");
NAPI_ASSERT(env, valueType == napi_object || valueType == napi_undefined || valueType == napi_null,
"Invalid argument type");
napi_get_undefined(env, &result);
unique_ptr<FetchFileResultAsyncContext> asyncContext = make_unique<FetchFileResultAsyncContext>();
status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
if (status == napi_ok && CheckIfFFRNapiNotEmpty(asyncContext->objectInfo)) {
if (valueType == napi_object) {
status = CheckArgValue(env, asyncContext.get(), argv[PARAM0]);
NAPI_ASSERT(env, status == napi_ok, "CheckArgValue failed");
}
NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
napi_value resource = nullptr;
NAPI_CREATE_RESOURCE_NAME(env, resource, "JSContains", asyncContext);
asyncContext->objectPtr = asyncContext->objectInfo->propertyPtr;
CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "propertyPtr is nullptr");
status = napi_create_async_work(
env, nullptr, resource, [](napi_env env, void *data) {
auto context = static_cast<FetchFileResultAsyncContext*>(data);
SetTranscodeInfo(context);
context->fetchResultIndexId = context->GetObjectIndexById();
},
reinterpret_cast<napi_async_complete_callback>(GetContainsCompleteCallback),
static_cast<void *>(asyncContext.get()), &asyncContext->work);
if (status != napi_ok) {
napi_get_undefined(env, &result);
} else {
napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
asyncContext.release();
}
} else {
NAPI_ERR_LOG("JSContains obj == nullptr, status: %{public}d", status);
NAPI_ASSERT(env, false, "JSContains obj == nullptr");
}
return result;
}
napi_value FetchFileResultNapi::JSGetObjectsByIndexSet(napi_env env, napi_callback_info info)
{
napi_status status;
napi_value result = nullptr;
size_t argc = ARGS_ONE;
napi_value argv[ARGS_ONE] = { 0 };
napi_value thisVar = nullptr;
MediaLibraryTracer tracer;
tracer.Start("JSGetObjectsByIndexSet");
CHECK_ARGS_WITH_MSG(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr), JS_E_INNER_FAIL,
"Failed to get callback info");
NAPI_ASSERT(env, argc == ARGS_ONE, "Number of args is invalid");
bool isArray = false;
CHECK_ARGS_WITH_MSG(env, napi_is_array(env, argv[PARAM0], &isArray), JS_E_PARAM_INVALID,
"Failed to check argv[0] is array");
napi_get_undefined(env, &result);
unique_ptr<FetchFileResultAsyncContext> asyncContext = make_unique<FetchFileResultAsyncContext>();
status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
if (status == napi_ok && CheckIfFFRNapiNotEmpty(asyncContext->objectInfo)) {
status = ProcessIndexSet(env, asyncContext.get(), argv[PARAM0]);
NAPI_ASSERT(env, status == napi_ok, "ProcessIndexSet failed");
NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
napi_value resource = nullptr;
NAPI_CREATE_RESOURCE_NAME(env, resource, "JSGetObjectsByIndexSet", asyncContext);
asyncContext->objectPtr = asyncContext->objectInfo->propertyPtr;
CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "propertyPtr is nullptr");
status = napi_create_async_work(
env, nullptr, resource, [](napi_env env, void *data) {
auto context = static_cast<FetchFileResultAsyncContext *>(data);
SetTranscodeInfo(context);
context->GetObjectsByIndexSet();
},
reinterpret_cast<napi_async_complete_callback>(GetAllObjectCompleteCallback),
static_cast<void *>(asyncContext.get()),
&asyncContext->work);
if (status != napi_ok) {
napi_get_undefined(env, &result);
} else {
napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
asyncContext.release();
}
} else {
NAPI_ERR_LOG("JSGetObjectsByIndexSet obj == nullptr, status: %{public}d", status);
NAPI_ASSERT(env, false, "JSGetObjectsByIndexSet obj == nullptr");
}
return result;
}
napi_value FetchFileResultNapi::JSGetIndex(napi_env env, napi_callback_info info)
{
napi_status status;
napi_value result = nullptr;
size_t argc = ARGS_ONE;
napi_value argv[ARGS_ONE] = { 0 };
napi_value thisVar = nullptr;
napi_valuetype valueType;
MediaLibraryTracer tracer;
tracer.Start("JSGetIndex");
CHECK_ARGS_WITH_MSG(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr), JS_E_INNER_FAIL,
"Failed to get callback info");
NAPI_ASSERT(env, argc == ARGS_ONE, "Number of args is invalid");
CHECK_ARGS_WITH_MSG(env, napi_typeof(env, argv[PARAM0], &valueType), JS_E_INNER_FAIL,
"Failed to check argument type");
NAPI_ASSERT(env, valueType == napi_object || valueType == napi_undefined || valueType == napi_null,
"Invalid argument type");
napi_get_undefined(env, &result);
unique_ptr<FetchFileResultAsyncContext> asyncContext = make_unique<FetchFileResultAsyncContext>();
status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
if (status == napi_ok && CheckIfFFRNapiNotEmpty(asyncContext->objectInfo)) {
if (valueType == napi_object) {
status = CheckArgValue(env, asyncContext.get(), argv[PARAM0]);
NAPI_ASSERT(env, status == napi_ok, "CheckArgValue failed");
}
NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
napi_value resource = nullptr;
NAPI_CREATE_RESOURCE_NAME(env, resource, "JSGetIndex", asyncContext);
asyncContext->objectPtr = asyncContext->objectInfo->propertyPtr;
CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "propertyPtr is nullptr");
status = napi_create_async_work(
env, nullptr, resource, [](napi_env env, void *data) {
auto context = static_cast<FetchFileResultAsyncContext*>(data);
context->fetchResultIndexId = context->GetObjectIndexById();
},
reinterpret_cast<napi_async_complete_callback>(GetIndexCompleteCallback),
static_cast<void *>(asyncContext.get()), &asyncContext->work);
if (status != napi_ok) {
napi_get_undefined(env, &result);
} else {
napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
asyncContext.release();
}
} else {
NAPI_ERR_LOG("JSGetIndex obj == nullptr, status: %{public}d", status);
NAPI_ASSERT(env, false, "JSGetIndex obj == nullptr");
}
return result;
}
napi_value FetchFileResultNapi::JSClose(napi_env env, napi_callback_info info)
{
napi_status status;
napi_value jsResult = nullptr;
FetchFileResultNapi* obj = nullptr;
napi_value thisVar = nullptr;
MediaLibraryTracer tracer;
tracer.Start("JSClose");
napi_get_undefined(env, &jsResult);
GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
if (status != napi_ok || thisVar == nullptr) {
NAPI_ERR_LOG("Invalid arguments!, status: %{public}d", status);
return jsResult;
}
status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
if ((status == napi_ok) && (obj != nullptr)) {
obj->propertyPtr = nullptr;
}
status = napi_remove_wrap(env, thisVar, reinterpret_cast<void **>(&obj));
if ((status == napi_ok) && (obj != nullptr)) {
napi_create_int32(env, E_SUCCESS, &jsResult);
} else {
NAPI_DEBUG_LOG("JSClose obj == nullptr");
}
NAPI_DEBUG_LOG("JSClose OUT!");
return jsResult;
}
void FetchFileResultAsyncContext::GetFirstAsset()
{
switch (objectPtr->fetchResType_) {
case FetchResType::TYPE_FILE: {
fileAsset = objectPtr->fetchFileResult_->GetFirstObject();
break;
}
case FetchResType::TYPE_ALBUM: {
albumAsset = objectPtr->fetchAlbumResult_->GetFirstObject();
break;
}
case FetchResType::TYPE_PHOTOALBUM: {
photoAlbum = objectPtr->fetchPhotoAlbumResult_->GetFirstObject();
break;
}
case FetchResType::TYPE_SMARTALBUM: {
smartAlbumAsset = objectPtr->fetchSmartAlbumResult_->GetFirstObject();
break;
}
case FetchResType::TYPE_CUSTOMRECORD: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr, "objectPtr is nullptr");
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchCustomRecordResult_, "fetchCustomRecordResult_ is nullptr");
customRecordAsset = objectPtr->fetchCustomRecordResult_->GetFirstObject();
break;
}
case FetchResType::TYPE_ALBUMORDER: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr, "objectPtr is nullptr");
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchAlbumOrderResult_, "fetchAlbumOrderResult_ is nullptr");
albumOrder = objectPtr->fetchAlbumOrderResult_->GetFirstObject();
break;
}
default:
NAPI_ERR_LOG("unsupported FetchResType");
break;
}
}
void FetchFileResultAsyncContext::GetObjectAtPosition()
{
switch (objectPtr->fetchResType_) {
case FetchResType::TYPE_FILE: {
fileAsset = objectPtr->fetchFileResult_->GetObjectAtPosition(position);
break;
}
case FetchResType::TYPE_ALBUM: {
albumAsset = objectPtr->fetchAlbumResult_->GetObjectAtPosition(position);
break;
}
case FetchResType::TYPE_PHOTOALBUM: {
photoAlbum = objectPtr->fetchPhotoAlbumResult_->GetObjectAtPosition(position);
break;
}
case FetchResType::TYPE_SMARTALBUM: {
smartAlbumAsset = objectPtr->fetchSmartAlbumResult_->GetObjectAtPosition(position);
break;
}
case FetchResType::TYPE_CUSTOMRECORD: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr, "objectPtr is nullptr");
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchCustomRecordResult_, "fetchCustomRecordResult_ is nullptr");
customRecordAsset = objectPtr->fetchCustomRecordResult_->GetObjectAtPosition(position);
break;
}
case FetchResType::TYPE_ALBUMORDER: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr, "objectPtr is nullptr");
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchAlbumOrderResult_, "fetchAlbumOrderResult_ is nullptr");
albumOrder = objectPtr->fetchAlbumOrderResult_->GetObjectAtPosition(position);
break;
}
default:
NAPI_ERR_LOG("unsupported FetchResType");
break;
}
}
void FetchFileResultAsyncContext::GetLastObject()
{
switch (objectPtr->fetchResType_) {
case FetchResType::TYPE_FILE: {
fileAsset = objectPtr->fetchFileResult_->GetLastObject();
break;
}
case FetchResType::TYPE_ALBUM: {
albumAsset = objectPtr->fetchAlbumResult_->GetLastObject();
break;
}
case FetchResType::TYPE_PHOTOALBUM: {
photoAlbum = objectPtr->fetchPhotoAlbumResult_->GetLastObject();
break;
}
case FetchResType::TYPE_SMARTALBUM: {
smartAlbumAsset = objectPtr->fetchSmartAlbumResult_->GetLastObject();
break;
}
case FetchResType::TYPE_CUSTOMRECORD: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr, "objectPtr is nullptr");
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchCustomRecordResult_, "fetchCustomRecordResult_ is nullptr");
customRecordAsset = objectPtr->fetchCustomRecordResult_->GetLastObject();
break;
}
case FetchResType::TYPE_ALBUMORDER: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr, "objectPtr is nullptr");
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchAlbumOrderResult_, "fetchAlbumOrderResult_ is nullptr");
albumOrder = objectPtr->fetchAlbumOrderResult_->GetLastObject();
break;
}
default:
NAPI_ERR_LOG("unsupported FetchResType");
break;
}
}
void FetchFileResultAsyncContext::GetNextObject()
{
switch (objectPtr->fetchResType_) {
case FetchResType::TYPE_FILE: {
fileAsset = objectPtr->fetchFileResult_->GetNextObject();
break;
}
case FetchResType::TYPE_ALBUM: {
albumAsset = objectPtr->fetchAlbumResult_->GetNextObject();
break;
}
case FetchResType::TYPE_PHOTOALBUM: {
photoAlbum = objectPtr->fetchPhotoAlbumResult_->GetNextObject();
break;
}
case FetchResType::TYPE_SMARTALBUM: {
smartAlbumAsset = objectPtr->fetchSmartAlbumResult_->GetNextObject();
break;
}
case FetchResType::TYPE_CUSTOMRECORD: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr, "objectPtr is nullptr");
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchCustomRecordResult_, "fetchCustomRecordResult_ is nullptr");
customRecordAsset = objectPtr->fetchCustomRecordResult_->GetNextObject();
break;
}
case FetchResType::TYPE_ALBUMORDER: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr, "objectPtr is nullptr");
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchAlbumOrderResult_, "fetchAlbumOrderResult_ is nullptr");
albumOrder = objectPtr->fetchAlbumOrderResult_->GetNextObject();
break;
}
default:
NAPI_ERR_LOG("unsupported FetchResType");
break;
}
}
void FetchFileResultAsyncContext::GetAllObjectFromFetchResult()
{
switch (objectPtr->fetchResType_) {
case FetchResType::TYPE_FILE: {
auto fetchResult = objectPtr->fetchFileResult_;
auto file = fetchResult->GetFirstObject();
while (file != nullptr) {
file->SetUserId(fetchResult->GetUserId());
fileAssetArray.push_back(move(file));
file = fetchResult->GetNextObject();
}
break;
}
case FetchResType::TYPE_ALBUM: {
auto fetchResult = objectPtr->fetchAlbumResult_;
auto album = fetchResult->GetFirstObject();
while (album != nullptr) {
fileAlbumArray.push_back(move(album));
album = fetchResult->GetNextObject();
}
break;
}
case FetchResType::TYPE_PHOTOALBUM: {
auto fetchResult = objectPtr->fetchPhotoAlbumResult_;
auto photoAlbum = fetchResult->GetFirstObject();
while (photoAlbum != nullptr) {
photoAlbum->SetUserId(fetchResult->GetUserId());
filePhotoAlbumArray.push_back(move(photoAlbum));
photoAlbum = fetchResult->GetNextObject();
}
break;
}
case FetchResType::TYPE_SMARTALBUM: {
auto fetchResult = objectPtr->fetchSmartAlbumResult_;
auto smartAlbum = fetchResult->GetFirstObject();
while (smartAlbum != nullptr) {
fileSmartAlbumArray.push_back(move(smartAlbum));
smartAlbum = fetchResult->GetNextObject();
}
break;
}
case FetchResType::TYPE_CUSTOMRECORD: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr, "objectPtr is nullptr");
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchCustomRecordResult_, "fetchCustomRecordResult_ is nullptr");
auto fetchResult = objectPtr->fetchCustomRecordResult_;
auto customRecord = fetchResult->GetFirstObject();
while (customRecord != nullptr) {
customRecordArray.push_back(move(customRecord));
customRecord = fetchResult->GetNextObject();
}
break;
}
case FetchResType::TYPE_ALBUMORDER: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr, "objectPtr is nullptr");
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchAlbumOrderResult_, "fetchAlbumOrderResult_ is nullptr");
auto fetchResult = objectPtr->fetchAlbumOrderResult_;
auto albumOrder = fetchResult->GetFirstObject();
while (albumOrder != nullptr) {
fileAlbumOrderArray.push_back(move(albumOrder));
albumOrder = fetchResult->GetNextObject();
}
break;
}
default:
NAPI_ERR_LOG("unsupported FetchResType");
break;
}
}
void FetchFileResultAsyncContext::GetPhotosInRange()
{
switch (objectPtr->fetchResType_) {
case FetchResType::TYPE_ALBUM: {
auto fetchResult = objectPtr->fetchAlbumResult_;
auto album = fetchResult->GetObjectAtPosition(offset);
while (album != nullptr && (length--) > 0) {
fileAlbumArray.push_back(move(album));
album = fetchResult->GetNextObject();
}
break;
}
case FetchResType::TYPE_PHOTOALBUM: {
auto fetchResult = objectPtr->fetchPhotoAlbumResult_;
auto photoAlbum = fetchResult->GetObjectAtPosition(offset);
while (photoAlbum != nullptr && (length--) > 0) {
photoAlbum->SetUserId(fetchResult->GetUserId());
filePhotoAlbumArray.push_back(move(photoAlbum));
photoAlbum = fetchResult->GetNextObject();
}
break;
}
case FetchResType::TYPE_SMARTALBUM: {
auto fetchResult = objectPtr->fetchSmartAlbumResult_;
auto smartAlbum = fetchResult->GetObjectAtPosition(offset);
while (smartAlbum != nullptr && (length--) > 0) {
fileSmartAlbumArray.push_back(move(smartAlbum));
smartAlbum = fetchResult->GetNextObject();
}
break;
}
default:
break;
}
}
void FetchFileResultAsyncContext::GetObjectsInRange()
{
FetchFileResultAsyncContext::GetPhotosInRange();
switch (objectPtr->fetchResType_) {
case FetchResType::TYPE_FILE: {
auto fetchResult = objectPtr->fetchFileResult_;
auto file = fetchResult->GetObjectAtPosition(offset);
while (file != nullptr && (length--) > 0) {
file->SetUserId(fetchResult->GetUserId());
fileAssetArray.push_back(move(file));
file = fetchResult->GetNextObject();
}
break;
}
case FetchResType::TYPE_CUSTOMRECORD: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr, "objectPtr is nullptr");
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchCustomRecordResult_, "fetchCustomRecordResult_ is nullptr");
auto fetchResult = objectPtr->fetchCustomRecordResult_;
auto customRecord = fetchResult->GetObjectAtPosition(offset);
while (customRecord != nullptr && (length--) > 0) {
customRecordArray.push_back(move(customRecord));
customRecord = fetchResult->GetNextObject();
}
break;
}
case FetchResType::TYPE_ALBUMORDER: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr, "objectPtr is nullptr");
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchAlbumOrderResult_, "fetchAlbumOrderResult_ is nullptr");
auto fetchResult = objectPtr->fetchAlbumOrderResult_;
auto albumOrder = fetchResult->GetObjectAtPosition(offset);
while (albumOrder != nullptr && (length--) > 0) {
fileAlbumOrderArray.push_back(move(albumOrder));
albumOrder = fetchResult->GetNextObject();
}
break;
}
default:
NAPI_ERR_LOG("unsupported FetchResType");
break;
}
}
void FetchFileResultAsyncContext::GetPhotosInIndexSet()
{
CHECK_NULL_PTR_RETURN_VOID(objectPtr, "objectPtr is nullptr");
if (indexSet.empty()) {
return;
}
switch (objectPtr->fetchResType_) {
case FetchResType::TYPE_ALBUM: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchAlbumResult_, "fetchAlbumResult_ is nullptr");
auto fetchResult = objectPtr->fetchAlbumResult_;
for (size_t i = 0; i < indexSet.size(); i++) {
auto album = fetchResult->GetObjectAtPosition(indexSet[i]);
CHECK_AND_CONTINUE(album != nullptr);
fileAlbumArray.push_back(move(album));
}
break;
}
case FetchResType::TYPE_PHOTOALBUM: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchPhotoAlbumResult_, "fetchPhotoAlbumResult_ is nullptr");
auto fetchResult = objectPtr->fetchPhotoAlbumResult_;
for (size_t i = 0; i < indexSet.size(); i++) {
auto photoAlbum = fetchResult->GetObjectAtPosition(indexSet[i]);
CHECK_AND_CONTINUE(photoAlbum != nullptr);
photoAlbum->SetUserId(fetchResult->GetUserId());
filePhotoAlbumArray.push_back(move(photoAlbum));
}
break;
}
case FetchResType::TYPE_SMARTALBUM: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchSmartAlbumResult_, "fetchSmartAlbumResult_ is nullptr");
auto fetchResult = objectPtr->fetchSmartAlbumResult_;
for (size_t i = 0; i < indexSet.size(); i++) {
auto smartAlbum = fetchResult->GetObjectAtPosition(indexSet[i]);
CHECK_AND_CONTINUE(smartAlbum != nullptr);
fileSmartAlbumArray.push_back(move(smartAlbum));
}
break;
}
default:
NAPI_INFO_LOG("need more check.");
break;
}
}
void FetchFileResultAsyncContext::GetObjectsByIndexSet()
{
CHECK_NULL_PTR_RETURN_VOID(objectPtr, "objectPtr is nullptr");
if (indexSet.empty()) {
return;
}
FetchFileResultAsyncContext::GetPhotosInIndexSet();
switch (objectPtr->fetchResType_) {
case FetchResType::TYPE_FILE: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchFileResult_, "fetchFileResult_ is nullptr");
auto fetchResult = objectPtr->fetchFileResult_;
for (size_t i = 0; i < indexSet.size(); i++) {
auto file = fetchResult->GetObjectAtPosition(indexSet[i]);
CHECK_AND_CONTINUE(file != nullptr);
file->SetUserId(fetchResult->GetUserId());
fileAssetArray.push_back(move(file));
}
break;
}
case FetchResType::TYPE_CUSTOMRECORD: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchCustomRecordResult_, "fetchCustomRecordResult_ is nullptr");
auto fetchResult = objectPtr->fetchCustomRecordResult_;
for (size_t i = 0; i < indexSet.size(); i++) {
auto customRecord = fetchResult->GetObjectAtPosition(indexSet[i]);
CHECK_AND_CONTINUE(customRecord != nullptr);
customRecordArray.push_back(move(customRecord));
}
break;
}
case FetchResType::TYPE_ALBUMORDER: {
CHECK_NULL_PTR_RETURN_VOID(objectPtr->fetchAlbumOrderResult_, "fetchAlbumOrderResult_ is nullptr");
auto fetchResult = objectPtr->fetchAlbumOrderResult_;
for (size_t i = 0; i < indexSet.size(); i++) {
auto albumOrder = fetchResult->GetObjectAtPosition(indexSet[i]);
CHECK_AND_CONTINUE(albumOrder != nullptr);
fileAlbumOrderArray.push_back(move(albumOrder));
}
break;
}
default:
NAPI_ERR_LOG("unsupported FetchResType");
break;
}
}
int32_t FetchFileResultAsyncContext::GetObjectIndexById()
{
int32_t index = -1;
CHECK_COND_RET(objectPtr != nullptr, index, "objectPtr is nullptr");
switch (objectPtr->fetchResType_) {
case FetchResType::TYPE_FILE: {
CHECK_COND_RET(objectPtr->fetchFileResult_, index, "fetchFileResult_ is nullptr");
index = objectPtr->fetchFileResult_->GetObjectIndexById(indexObjectId);
break;
}
case FetchResType::TYPE_ALBUM: {
CHECK_COND_RET(objectPtr->fetchAlbumResult_, index, "fetchAlbumResult_ is nullptr");
index = objectPtr->fetchAlbumResult_->GetObjectIndexById(indexObjectId);
break;
}
case FetchResType::TYPE_PHOTOALBUM: {
CHECK_COND_RET(objectPtr->fetchPhotoAlbumResult_, index, "fetchPhotoAlbumResult_ is nullptr");
index = objectPtr->fetchPhotoAlbumResult_->GetAlbumIndex(indexObjectId, albumType, albumSubType);
break;
}
case FetchResType::TYPE_SMARTALBUM: {
CHECK_COND_RET(objectPtr->fetchSmartAlbumResult_, index, "fetchSmartAlbumResult_ is nullptr");
index = objectPtr->fetchSmartAlbumResult_->GetObjectIndexById(indexObjectId);
break;
}
case FetchResType::TYPE_CUSTOMRECORD: {
CHECK_COND_RET(objectPtr->fetchCustomRecordResult_, index, "fetchCustomRecordResult_ is nullptr");
index = objectPtr->fetchCustomRecordResult_->GetObjectIndexById(indexObjectId);
break;
}
case FetchResType::TYPE_ALBUMORDER: {
CHECK_COND_RET(objectPtr->fetchAlbumOrderResult_, index, "fetchAlbumOrderResult_ is nullptr");
index = objectPtr->fetchAlbumOrderResult_->GetObjectIndexById(indexObjectId);
break;
}
default:
NAPI_ERR_LOG("unsupported FetchResType");
break;
}
return index;
}
bool FetchFileResultNapi::CheckIfPropertyPtrNull()
{
return propertyPtr == nullptr;
}
}
}