176fd607bSopenharmony_ci/*
276fd607bSopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd.
376fd607bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
476fd607bSopenharmony_ci * you may not use this file except in compliance with the License.
576fd607bSopenharmony_ci * You may obtain a copy of the License at
676fd607bSopenharmony_ci *
776fd607bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
876fd607bSopenharmony_ci *
976fd607bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1076fd607bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1176fd607bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1276fd607bSopenharmony_ci * See the License for the specific language governing permissions and
1376fd607bSopenharmony_ci * limitations under the License.
1476fd607bSopenharmony_ci */
1576fd607bSopenharmony_ci
1676fd607bSopenharmony_ci#include "thumbnail_manager.h"
1776fd607bSopenharmony_ci
1876fd607bSopenharmony_ci#include <memory>
1976fd607bSopenharmony_ci#include <mutex>
2076fd607bSopenharmony_ci#include <sys/mman.h>
2176fd607bSopenharmony_ci#include <sys/stat.h>
2276fd607bSopenharmony_ci#include <uuid/uuid.h>
2376fd607bSopenharmony_ci
2476fd607bSopenharmony_ci#include "ashmem.h"
2576fd607bSopenharmony_ci#include "image_source.h"
2676fd607bSopenharmony_ci#include "image_type.h"
2776fd607bSopenharmony_ci#include "js_native_api.h"
2876fd607bSopenharmony_ci#include "media_file_uri.h"
2976fd607bSopenharmony_ci#include "medialibrary_errno.h"
3076fd607bSopenharmony_ci#include "medialibrary_napi_log.h"
3176fd607bSopenharmony_ci#include "medialibrary_napi_utils.h"
3276fd607bSopenharmony_ci#include "medialibrary_tracer.h"
3376fd607bSopenharmony_ci#include "pixel_map.h"
3476fd607bSopenharmony_ci#include "pixel_map_napi.h"
3576fd607bSopenharmony_ci#include "post_proc.h"
3676fd607bSopenharmony_ci#include "securec.h"
3776fd607bSopenharmony_ci#include "string_ex.h"
3876fd607bSopenharmony_ci#include "thumbnail_const.h"
3976fd607bSopenharmony_ci#include "unique_fd.h"
4076fd607bSopenharmony_ci#include "userfile_manager_types.h"
4176fd607bSopenharmony_ci#include "uv.h"
4276fd607bSopenharmony_ci#include "userfile_client.h"
4376fd607bSopenharmony_ci
4476fd607bSopenharmony_ci#ifdef IMAGE_PURGEABLE_PIXELMAP
4576fd607bSopenharmony_ci#include "purgeable_pixelmap_builder.h"
4676fd607bSopenharmony_ci#endif
4776fd607bSopenharmony_ci
4876fd607bSopenharmony_ciusing namespace std;
4976fd607bSopenharmony_ciconst int UUID_STR_LENGTH = 37;
5076fd607bSopenharmony_ci
5176fd607bSopenharmony_cinamespace OHOS {
5276fd607bSopenharmony_cinamespace Media {
5376fd607bSopenharmony_cishared_ptr<ThumbnailManager> ThumbnailManager::instance_ = nullptr;
5476fd607bSopenharmony_cimutex ThumbnailManager::mutex_;
5576fd607bSopenharmony_cibool ThumbnailManager::init_ = false;
5676fd607bSopenharmony_cistatic constexpr int32_t DEFAULT_FD = -1;
5776fd607bSopenharmony_ci
5876fd607bSopenharmony_ciThumbnailRequest::ThumbnailRequest(const RequestPhotoParams &params, napi_env env,
5976fd607bSopenharmony_ci    napi_ref callback) : callback_(env, callback), requestPhotoType(params.type), uri_(params.uri),
6076fd607bSopenharmony_ci    path_(params.path), requestSize_(params.size)
6176fd607bSopenharmony_ci{
6276fd607bSopenharmony_ci}
6376fd607bSopenharmony_ci
6476fd607bSopenharmony_ciThumbnailRequest::~ThumbnailRequest()
6576fd607bSopenharmony_ci{
6676fd607bSopenharmony_ci}
6776fd607bSopenharmony_ci
6876fd607bSopenharmony_civoid ThumbnailRequest::ReleaseCallbackRef()
6976fd607bSopenharmony_ci{
7076fd607bSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
7176fd607bSopenharmony_ci    if (callback_.callBackRef_) {
7276fd607bSopenharmony_ci        napi_delete_reference(callback_.env_, callback_.callBackRef_);
7376fd607bSopenharmony_ci        callback_.callBackRef_ = nullptr;
7476fd607bSopenharmony_ci    }
7576fd607bSopenharmony_ci}
7676fd607bSopenharmony_ci
7776fd607bSopenharmony_cibool ThumbnailRequest::UpdateStatus(ThumbnailStatus status)
7876fd607bSopenharmony_ci{
7976fd607bSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
8076fd607bSopenharmony_ci    if (status <= status_) {
8176fd607bSopenharmony_ci        return false;
8276fd607bSopenharmony_ci    }
8376fd607bSopenharmony_ci    status_ = status;
8476fd607bSopenharmony_ci    return true;
8576fd607bSopenharmony_ci}
8676fd607bSopenharmony_ci
8776fd607bSopenharmony_ciThumbnailStatus ThumbnailRequest::GetStatus()
8876fd607bSopenharmony_ci{
8976fd607bSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
9076fd607bSopenharmony_ci    return status_;
9176fd607bSopenharmony_ci}
9276fd607bSopenharmony_ci
9376fd607bSopenharmony_cibool ThumbnailRequest::NeedContinue()
9476fd607bSopenharmony_ci{
9576fd607bSopenharmony_ci    return GetStatus() < ThumbnailStatus::THUMB_REMOVE;
9676fd607bSopenharmony_ci}
9776fd607bSopenharmony_ci
9876fd607bSopenharmony_cistatic bool IsPhotoSizeThumb(const Size &size)
9976fd607bSopenharmony_ci{
10076fd607bSopenharmony_ci    return ((size.width >= DEFAULT_THUMB_SIZE || size.height >= DEFAULT_THUMB_SIZE) ||
10176fd607bSopenharmony_ci        (size.width == DEFAULT_MTH_SIZE || size.height == DEFAULT_MTH_SIZE));
10276fd607bSopenharmony_ci}
10376fd607bSopenharmony_ci
10476fd607bSopenharmony_cistatic bool NeedFastThumb(const Size &size, RequestPhotoType type)
10576fd607bSopenharmony_ci{
10676fd607bSopenharmony_ci    return IsPhotoSizeThumb(size) && (type != RequestPhotoType::REQUEST_QUALITY_THUMBNAIL);
10776fd607bSopenharmony_ci}
10876fd607bSopenharmony_ci
10976fd607bSopenharmony_cistatic bool NeedQualityThumb(const Size &size, RequestPhotoType type)
11076fd607bSopenharmony_ci{
11176fd607bSopenharmony_ci    return IsPhotoSizeThumb(size) && (type != RequestPhotoType::REQUEST_FAST_THUMBNAIL);
11276fd607bSopenharmony_ci}
11376fd607bSopenharmony_ci
11476fd607bSopenharmony_ciMMapFdPtr::MMapFdPtr(int32_t fd, bool isNeedRelease)
11576fd607bSopenharmony_ci{
11676fd607bSopenharmony_ci    if (fd < 0) {
11776fd607bSopenharmony_ci        NAPI_ERR_LOG("Fd is invalid: %{public}d", fd);
11876fd607bSopenharmony_ci        return;
11976fd607bSopenharmony_ci    }
12076fd607bSopenharmony_ci
12176fd607bSopenharmony_ci    struct stat st;
12276fd607bSopenharmony_ci    if (fstat(fd, &st) == -1) {
12376fd607bSopenharmony_ci        NAPI_ERR_LOG("fstat error, errno:%{public}d", errno);
12476fd607bSopenharmony_ci        return;
12576fd607bSopenharmony_ci    }
12676fd607bSopenharmony_ci    size_ = st.st_size;
12776fd607bSopenharmony_ci
12876fd607bSopenharmony_ci    // mmap ptr from fd
12976fd607bSopenharmony_ci    fdPtr_ = mmap(nullptr, size_, PROT_READ, MAP_SHARED, fd, 0);
13076fd607bSopenharmony_ci    if (fdPtr_ == MAP_FAILED || fdPtr_ == nullptr) {
13176fd607bSopenharmony_ci        NAPI_ERR_LOG("mmap uniqueFd failed, errno = %{public}d", errno);
13276fd607bSopenharmony_ci        return;
13376fd607bSopenharmony_ci    }
13476fd607bSopenharmony_ci
13576fd607bSopenharmony_ci    isValid_ = true;
13676fd607bSopenharmony_ci    isNeedRelease_ = isNeedRelease;
13776fd607bSopenharmony_ci}
13876fd607bSopenharmony_ci
13976fd607bSopenharmony_ciMMapFdPtr::~MMapFdPtr()
14076fd607bSopenharmony_ci{
14176fd607bSopenharmony_ci    // munmap ptr from fd
14276fd607bSopenharmony_ci    if (isNeedRelease_) {
14376fd607bSopenharmony_ci        munmap(fdPtr_, size_);
14476fd607bSopenharmony_ci    }
14576fd607bSopenharmony_ci}
14676fd607bSopenharmony_ci
14776fd607bSopenharmony_civoid* MMapFdPtr::GetFdPtr()
14876fd607bSopenharmony_ci{
14976fd607bSopenharmony_ci    return fdPtr_;
15076fd607bSopenharmony_ci}
15176fd607bSopenharmony_ci
15276fd607bSopenharmony_cioff_t MMapFdPtr::GetFdSize()
15376fd607bSopenharmony_ci{
15476fd607bSopenharmony_ci    return size_;
15576fd607bSopenharmony_ci}
15676fd607bSopenharmony_ci
15776fd607bSopenharmony_cibool MMapFdPtr::IsValid()
15876fd607bSopenharmony_ci{
15976fd607bSopenharmony_ci    return isValid_;
16076fd607bSopenharmony_ci}
16176fd607bSopenharmony_ci
16276fd607bSopenharmony_cistatic string GenerateRequestId()
16376fd607bSopenharmony_ci{
16476fd607bSopenharmony_ci    uuid_t uuid;
16576fd607bSopenharmony_ci    uuid_generate(uuid);
16676fd607bSopenharmony_ci    char str[UUID_STR_LENGTH] = {};
16776fd607bSopenharmony_ci    uuid_unparse(uuid, str);
16876fd607bSopenharmony_ci    return str;
16976fd607bSopenharmony_ci}
17076fd607bSopenharmony_ci
17176fd607bSopenharmony_cishared_ptr<ThumbnailManager> ThumbnailManager::GetInstance()
17276fd607bSopenharmony_ci{
17376fd607bSopenharmony_ci    if (instance_ == nullptr) {
17476fd607bSopenharmony_ci        lock_guard<mutex> lock(mutex_);
17576fd607bSopenharmony_ci        if (instance_ == nullptr) {
17676fd607bSopenharmony_ci            instance_ = shared_ptr<ThumbnailManager>(new ThumbnailManager());
17776fd607bSopenharmony_ci        }
17876fd607bSopenharmony_ci    }
17976fd607bSopenharmony_ci
18076fd607bSopenharmony_ci    return instance_;
18176fd607bSopenharmony_ci}
18276fd607bSopenharmony_ci
18376fd607bSopenharmony_civoid ThumbnailManager::Init()
18476fd607bSopenharmony_ci{
18576fd607bSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
18676fd607bSopenharmony_ci    if (init_) {
18776fd607bSopenharmony_ci        return;
18876fd607bSopenharmony_ci    }
18976fd607bSopenharmony_ci    init_ = true;
19076fd607bSopenharmony_ci    isThreadRunning_ = true;
19176fd607bSopenharmony_ci    for (auto i = 0; i < THREAD_NUM; i++) {
19276fd607bSopenharmony_ci        threads_.emplace_back(
19376fd607bSopenharmony_ci            std::thread([this, num = i]() { this->ImageWorker(num); })
19476fd607bSopenharmony_ci        );
19576fd607bSopenharmony_ci        threads_[i].detach();
19676fd607bSopenharmony_ci    }
19776fd607bSopenharmony_ci    return;
19876fd607bSopenharmony_ci}
19976fd607bSopenharmony_ci
20076fd607bSopenharmony_cistring ThumbnailManager::AddPhotoRequest(const RequestPhotoParams &params, napi_env env, napi_ref callback)
20176fd607bSopenharmony_ci{
20276fd607bSopenharmony_ci    shared_ptr<ThumbnailRequest> request = make_shared<ThumbnailRequest>(params, env, callback);
20376fd607bSopenharmony_ci    string requestId = GenerateRequestId();
20476fd607bSopenharmony_ci    request->SetUUID(requestId);
20576fd607bSopenharmony_ci    if (!thumbRequest_.Insert(requestId, request)) {
20676fd607bSopenharmony_ci        return "";
20776fd607bSopenharmony_ci    }
20876fd607bSopenharmony_ci    // judge from request option
20976fd607bSopenharmony_ci    if (NeedFastThumb(params.size, params.type)) {
21076fd607bSopenharmony_ci        AddFastPhotoRequest(request);
21176fd607bSopenharmony_ci    } else {
21276fd607bSopenharmony_ci        AddQualityPhotoRequest(request);
21376fd607bSopenharmony_ci    }
21476fd607bSopenharmony_ci    return requestId;
21576fd607bSopenharmony_ci}
21676fd607bSopenharmony_ci
21776fd607bSopenharmony_civoid ThumbnailManager::RemovePhotoRequest(const string &requestId)
21876fd607bSopenharmony_ci{
21976fd607bSopenharmony_ci    RequestSharedPtr ptr;
22076fd607bSopenharmony_ci    if (thumbRequest_.Find(requestId, ptr)) {
22176fd607bSopenharmony_ci        if (ptr == nullptr) {
22276fd607bSopenharmony_ci            return;
22376fd607bSopenharmony_ci        }
22476fd607bSopenharmony_ci        // do not need delete from queue, just update remove status.
22576fd607bSopenharmony_ci        ptr->UpdateStatus(ThumbnailStatus::THUMB_REMOVE);
22676fd607bSopenharmony_ci        ptr->ReleaseCallbackRef();
22776fd607bSopenharmony_ci    }
22876fd607bSopenharmony_ci    thumbRequest_.Erase(requestId);
22976fd607bSopenharmony_ci}
23076fd607bSopenharmony_ci
23176fd607bSopenharmony_ciThumbnailManager::~ThumbnailManager()
23276fd607bSopenharmony_ci{
23376fd607bSopenharmony_ci    isThreadRunning_ = false;
23476fd607bSopenharmony_ci    queueCv_.notify_all();
23576fd607bSopenharmony_ci    for (auto &thread : threads_) {
23676fd607bSopenharmony_ci        if (thread.joinable()) {
23776fd607bSopenharmony_ci            thread.join();
23876fd607bSopenharmony_ci        }
23976fd607bSopenharmony_ci    }
24076fd607bSopenharmony_ci}
24176fd607bSopenharmony_ci
24276fd607bSopenharmony_civoid SetThreadName(const string &threadName, int num)
24376fd607bSopenharmony_ci{
24476fd607bSopenharmony_ci    string name = threadName;
24576fd607bSopenharmony_ci    name.append(to_string(num));
24676fd607bSopenharmony_ci    pthread_setname_np(pthread_self(), name.c_str());
24776fd607bSopenharmony_ci}
24876fd607bSopenharmony_ci
24976fd607bSopenharmony_civoid ThumbnailManager::AddFastPhotoRequest(const RequestSharedPtr &request)
25076fd607bSopenharmony_ci{
25176fd607bSopenharmony_ci    request->UpdateStatus(ThumbnailStatus::THUMB_FAST);
25276fd607bSopenharmony_ci    fastQueue_.Push(request);
25376fd607bSopenharmony_ci    queueCv_.notify_one();
25476fd607bSopenharmony_ci}
25576fd607bSopenharmony_ci
25676fd607bSopenharmony_civoid ThumbnailManager::AddQualityPhotoRequest(const RequestSharedPtr &request)
25776fd607bSopenharmony_ci{
25876fd607bSopenharmony_ci    request->UpdateStatus(ThumbnailStatus::THUMB_QUALITY);
25976fd607bSopenharmony_ci    qualityQueue_.Push(request);
26076fd607bSopenharmony_ci    queueCv_.notify_one();
26176fd607bSopenharmony_ci}
26276fd607bSopenharmony_ci
26376fd607bSopenharmony_cistatic bool GetFastThumbNewSize(const Size &size, Size &newSize)
26476fd607bSopenharmony_ci{
26576fd607bSopenharmony_ci    // if thumbnail size is YEAR SIZE, do not need to request fast thumb
26676fd607bSopenharmony_ci    // if thumbnail size is MTH SIZE, return YEAR SIZE
26776fd607bSopenharmony_ci    // if thumbnail size is THUMB SIZE, return MTH SIZE
26876fd607bSopenharmony_ci    // else return THUMB SIZE
26976fd607bSopenharmony_ci    if (size.width == DEFAULT_YEAR_SIZE && size.height == DEFAULT_YEAR_SIZE) {
27076fd607bSopenharmony_ci        newSize.height = DEFAULT_YEAR_SIZE;
27176fd607bSopenharmony_ci        newSize.width = DEFAULT_YEAR_SIZE;
27276fd607bSopenharmony_ci        return false;
27376fd607bSopenharmony_ci    } else if (size.width == DEFAULT_MTH_SIZE && size.height == DEFAULT_MTH_SIZE) {
27476fd607bSopenharmony_ci        newSize.height = DEFAULT_YEAR_SIZE;
27576fd607bSopenharmony_ci        newSize.width = DEFAULT_YEAR_SIZE;
27676fd607bSopenharmony_ci        return true;
27776fd607bSopenharmony_ci    } else if (size.width <= DEFAULT_THUMB_SIZE && size.height <= DEFAULT_THUMB_SIZE) {
27876fd607bSopenharmony_ci        newSize.height = DEFAULT_MTH_SIZE;
27976fd607bSopenharmony_ci        newSize.width = DEFAULT_MTH_SIZE;
28076fd607bSopenharmony_ci        return true;
28176fd607bSopenharmony_ci    } else {
28276fd607bSopenharmony_ci        newSize.height = DEFAULT_THUMB_SIZE;
28376fd607bSopenharmony_ci        newSize.width = DEFAULT_THUMB_SIZE;
28476fd607bSopenharmony_ci        return true;
28576fd607bSopenharmony_ci    }
28676fd607bSopenharmony_ci}
28776fd607bSopenharmony_ci
28876fd607bSopenharmony_cistatic int OpenThumbnail(const string &path, ThumbnailType type)
28976fd607bSopenharmony_ci{
29076fd607bSopenharmony_ci    if (!path.empty()) {
29176fd607bSopenharmony_ci        string sandboxPath = GetSandboxPath(path, type);
29276fd607bSopenharmony_ci        int fd = -1;
29376fd607bSopenharmony_ci        if (!sandboxPath.empty()) {
29476fd607bSopenharmony_ci            fd = open(sandboxPath.c_str(), O_RDONLY);
29576fd607bSopenharmony_ci        }
29676fd607bSopenharmony_ci        if (fd > 0) {
29776fd607bSopenharmony_ci            return fd;
29876fd607bSopenharmony_ci        }
29976fd607bSopenharmony_ci    }
30076fd607bSopenharmony_ci    return E_ERR;
30176fd607bSopenharmony_ci}
30276fd607bSopenharmony_ci
30376fd607bSopenharmony_cistatic int OpenKeyFrameThumbnail(const string &path, const int32_t &beginStamp, const int32_t &type)
30476fd607bSopenharmony_ci{
30576fd607bSopenharmony_ci    if (!path.empty()) {
30676fd607bSopenharmony_ci        string sandboxPath = GetKeyFrameSandboxPath(path, beginStamp, type);
30776fd607bSopenharmony_ci        int fd = -1;
30876fd607bSopenharmony_ci        if (!sandboxPath.empty()) {
30976fd607bSopenharmony_ci            fd = open(sandboxPath.c_str(), O_RDONLY);
31076fd607bSopenharmony_ci        }
31176fd607bSopenharmony_ci        if (fd > 0) {
31276fd607bSopenharmony_ci            return fd;
31376fd607bSopenharmony_ci        }
31476fd607bSopenharmony_ci        NAPI_ERR_LOG("OpenKeyFrameThumbnail failed, fd: %{public}d", fd);
31576fd607bSopenharmony_ci    }
31676fd607bSopenharmony_ci    return E_ERR;
31776fd607bSopenharmony_ci}
31876fd607bSopenharmony_ci
31976fd607bSopenharmony_cistatic bool IfSizeEqualsRatio(const Size &imageSize, const Size &targetSize)
32076fd607bSopenharmony_ci{
32176fd607bSopenharmony_ci    if (imageSize.height <= 0 || targetSize.height <= 0) {
32276fd607bSopenharmony_ci        return false;
32376fd607bSopenharmony_ci    }
32476fd607bSopenharmony_ci
32576fd607bSopenharmony_ci    float imageSizeScale = static_cast<float>(imageSize.width) / static_cast<float>(imageSize.height);
32676fd607bSopenharmony_ci    float targetSizeScale = static_cast<float>(targetSize.width) / static_cast<float>(targetSize.height);
32776fd607bSopenharmony_ci    if (imageSizeScale - targetSizeScale > FLOAT_EPSILON || targetSizeScale - imageSizeScale > FLOAT_EPSILON) {
32876fd607bSopenharmony_ci        return false;
32976fd607bSopenharmony_ci    } else {
33076fd607bSopenharmony_ci        return true;
33176fd607bSopenharmony_ci    }
33276fd607bSopenharmony_ci}
33376fd607bSopenharmony_ci
33476fd607bSopenharmony_cistatic PixelMapPtr CreateThumbnailByAshmem(UniqueFd &uniqueFd, const Size &size)
33576fd607bSopenharmony_ci{
33676fd607bSopenharmony_ci    MediaLibraryTracer tracer;
33776fd607bSopenharmony_ci    tracer.Start("CreateThumbnailByAshmem");
33876fd607bSopenharmony_ci
33976fd607bSopenharmony_ci    Media::InitializationOptions option = {
34076fd607bSopenharmony_ci        .size = size,
34176fd607bSopenharmony_ci    };
34276fd607bSopenharmony_ci    PixelMapPtr pixel = Media::PixelMap::Create(option);
34376fd607bSopenharmony_ci    if (pixel == nullptr) {
34476fd607bSopenharmony_ci        NAPI_ERR_LOG("Can not create pixel");
34576fd607bSopenharmony_ci        return nullptr;
34676fd607bSopenharmony_ci    }
34776fd607bSopenharmony_ci
34876fd607bSopenharmony_ci    UniqueFd dupFd = UniqueFd(dup(uniqueFd.Get()));
34976fd607bSopenharmony_ci    MMapFdPtr mmapFd(dupFd.Get(), false);
35076fd607bSopenharmony_ci    if (!mmapFd.IsValid()) {
35176fd607bSopenharmony_ci        NAPI_ERR_LOG("Can not mmap by fd");
35276fd607bSopenharmony_ci        return nullptr;
35376fd607bSopenharmony_ci    }
35476fd607bSopenharmony_ci    auto memSize = static_cast<int32_t>(mmapFd.GetFdSize());
35576fd607bSopenharmony_ci
35676fd607bSopenharmony_ci    void* fdPtr = new int32_t();
35776fd607bSopenharmony_ci    *static_cast<int32_t*>(fdPtr) = dupFd.Release();
35876fd607bSopenharmony_ci    pixel->SetPixelsAddr(mmapFd.GetFdPtr(), fdPtr, memSize, Media::AllocatorType::SHARE_MEM_ALLOC, nullptr);
35976fd607bSopenharmony_ci    return pixel;
36076fd607bSopenharmony_ci}
36176fd607bSopenharmony_ci
36276fd607bSopenharmony_cistatic PixelMapPtr DecodeThumbnail(const UniqueFd &uniqueFd, const Size &size)
36376fd607bSopenharmony_ci{
36476fd607bSopenharmony_ci    MediaLibraryTracer tracer;
36576fd607bSopenharmony_ci    tracer.Start("ImageSource::CreateImageSource");
36676fd607bSopenharmony_ci    SourceOptions opts;
36776fd607bSopenharmony_ci    uint32_t err = 0;
36876fd607bSopenharmony_ci    unique_ptr<ImageSource> imageSource = ImageSource::CreateImageSource(uniqueFd.Get(), opts, err);
36976fd607bSopenharmony_ci    if (imageSource == nullptr) {
37076fd607bSopenharmony_ci        NAPI_ERR_LOG("CreateImageSource err %{public}d", err);
37176fd607bSopenharmony_ci        return nullptr;
37276fd607bSopenharmony_ci    }
37376fd607bSopenharmony_ci
37476fd607bSopenharmony_ci    ImageInfo imageInfo;
37576fd607bSopenharmony_ci    err = imageSource->GetImageInfo(0, imageInfo);
37676fd607bSopenharmony_ci    if (err != E_OK) {
37776fd607bSopenharmony_ci        NAPI_ERR_LOG("GetImageInfo err %{public}d", err);
37876fd607bSopenharmony_ci        return nullptr;
37976fd607bSopenharmony_ci    }
38076fd607bSopenharmony_ci
38176fd607bSopenharmony_ci    bool isEqualsRatio = IfSizeEqualsRatio(imageInfo.size, size);
38276fd607bSopenharmony_ci    DecodeOptions decodeOpts;
38376fd607bSopenharmony_ci    decodeOpts.desiredSize = isEqualsRatio ? size : imageInfo.size;
38476fd607bSopenharmony_ci    unique_ptr<PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, err);
38576fd607bSopenharmony_ci    if (pixelMap == nullptr) {
38676fd607bSopenharmony_ci        NAPI_ERR_LOG("CreatePixelMap err %{public}d", err);
38776fd607bSopenharmony_ci        return nullptr;
38876fd607bSopenharmony_ci    }
38976fd607bSopenharmony_ci
39076fd607bSopenharmony_ci    PostProc postProc;
39176fd607bSopenharmony_ci    if (size.width != DEFAULT_ORIGINAL && !isEqualsRatio && !postProc.CenterScale(size, *pixelMap)) {
39276fd607bSopenharmony_ci        NAPI_ERR_LOG("CenterScale failed, size: %{public}d * %{public}d, imageInfo size: %{public}d * %{public}d",
39376fd607bSopenharmony_ci            size.width, size.height, imageInfo.size.width, imageInfo.size.height);
39476fd607bSopenharmony_ci        return nullptr;
39576fd607bSopenharmony_ci    }
39676fd607bSopenharmony_ci
39776fd607bSopenharmony_ci    // Make the ashmem of pixelmap to be purgeable after the operation on ashmem.
39876fd607bSopenharmony_ci    // And then make the pixelmap subject to PurgeableManager's control.
39976fd607bSopenharmony_ci#ifdef IMAGE_PURGEABLE_PIXELMAP
40076fd607bSopenharmony_ci    PurgeableBuilder::MakePixelMapToBePurgeable(pixelMap, imageSource, decodeOpts, size);
40176fd607bSopenharmony_ci#endif
40276fd607bSopenharmony_ci    return pixelMap;
40376fd607bSopenharmony_ci}
40476fd607bSopenharmony_ci
40576fd607bSopenharmony_cistatic int32_t GetPixelMapFromServer(const string &uriStr, const Size &size, const string &path)
40676fd607bSopenharmony_ci{
40776fd607bSopenharmony_ci    string openUriStr = uriStr + "?" + MEDIA_OPERN_KEYWORD + "=" + MEDIA_DATA_DB_THUMBNAIL + "&" +
40876fd607bSopenharmony_ci        MEDIA_DATA_DB_WIDTH + "=" + to_string(size.width) + "&" + MEDIA_DATA_DB_HEIGHT + "=" +
40976fd607bSopenharmony_ci        to_string(size.height);
41076fd607bSopenharmony_ci    if (IsAsciiString(path)) {
41176fd607bSopenharmony_ci        openUriStr += "&" + THUMBNAIL_PATH + "=" + path;
41276fd607bSopenharmony_ci    }
41376fd607bSopenharmony_ci    Uri openUri(openUriStr);
41476fd607bSopenharmony_ci    return UserFileClient::OpenFile(openUri, "R");
41576fd607bSopenharmony_ci}
41676fd607bSopenharmony_ci
41776fd607bSopenharmony_cistatic int32_t GetKeyFramePixelMapFromServer(const string &uriStr, const string &path,
41876fd607bSopenharmony_ci    const int32_t &beginStamp, const int32_t &type)
41976fd607bSopenharmony_ci{
42076fd607bSopenharmony_ci    string openUriStr = uriStr + "?" + MEDIA_OPERN_KEYWORD + "=" + MEDIA_DATA_DB_KEY_FRAME + "&" +
42176fd607bSopenharmony_ci        MEDIA_DATA_DB_BEGIN_STAMP + "=" + to_string(beginStamp) + "&" + MEDIA_DATA_DB_TYPE + "=" + to_string(type);
42276fd607bSopenharmony_ci    if (IsAsciiString(path)) {
42376fd607bSopenharmony_ci        openUriStr += "&" + THUMBNAIL_PATH + "=" + path;
42476fd607bSopenharmony_ci    }
42576fd607bSopenharmony_ci    Uri openUri(openUriStr);
42676fd607bSopenharmony_ci    return UserFileClient::OpenFile(openUri, "R");
42776fd607bSopenharmony_ci}
42876fd607bSopenharmony_ci
42976fd607bSopenharmony_ciunique_ptr<PixelMap> ThumbnailManager::QueryThumbnail(const string &uriStr, const Size &size, const string &path)
43076fd607bSopenharmony_ci{
43176fd607bSopenharmony_ci    MediaLibraryTracer tracer;
43276fd607bSopenharmony_ci    tracer.Start("QueryThumbnail uri:" + uriStr);
43376fd607bSopenharmony_ci    tracer.Start("DataShare::OpenFile");
43476fd607bSopenharmony_ci    ThumbnailType thumbType = GetThumbType(size.width, size.height);
43576fd607bSopenharmony_ci    if (MediaFileUri::GetMediaTypeFromUri(uriStr) == MediaType::MEDIA_TYPE_AUDIO &&
43676fd607bSopenharmony_ci        (thumbType == ThumbnailType::MTH || thumbType == ThumbnailType::YEAR)) {
43776fd607bSopenharmony_ci        thumbType = ThumbnailType::THUMB;
43876fd607bSopenharmony_ci    }
43976fd607bSopenharmony_ci    UniqueFd uniqueFd(OpenThumbnail(path, thumbType));
44076fd607bSopenharmony_ci    if (uniqueFd.Get() == E_ERR) {
44176fd607bSopenharmony_ci        uniqueFd = UniqueFd(GetPixelMapFromServer(uriStr, size, path));
44276fd607bSopenharmony_ci        if (uniqueFd.Get() < 0) {
44376fd607bSopenharmony_ci            NAPI_ERR_LOG("queryThumb is null, errCode is %{public}d", uniqueFd.Get());
44476fd607bSopenharmony_ci            return nullptr;
44576fd607bSopenharmony_ci        }
44676fd607bSopenharmony_ci        return DecodeThumbnail(uniqueFd, size);
44776fd607bSopenharmony_ci    }
44876fd607bSopenharmony_ci    tracer.Finish();
44976fd607bSopenharmony_ci    if (thumbType == ThumbnailType::MTH || thumbType == ThumbnailType::YEAR) {
45076fd607bSopenharmony_ci        return CreateThumbnailByAshmem(uniqueFd, size);
45176fd607bSopenharmony_ci    } else {
45276fd607bSopenharmony_ci        return DecodeThumbnail(uniqueFd, size);
45376fd607bSopenharmony_ci    }
45476fd607bSopenharmony_ci}
45576fd607bSopenharmony_ci
45676fd607bSopenharmony_ciunique_ptr<PixelMap> ThumbnailManager::QueryKeyFrameThumbnail(const string &uriStr, const int &beginStamp,
45776fd607bSopenharmony_ci    const int &type, const string &path)
45876fd607bSopenharmony_ci{
45976fd607bSopenharmony_ci    MediaLibraryTracer tracer;
46076fd607bSopenharmony_ci    tracer.Start("QueryKeyFrameThumbnail uri:" + uriStr);
46176fd607bSopenharmony_ci
46276fd607bSopenharmony_ci    UniqueFd uniqueFd(OpenKeyFrameThumbnail(path, beginStamp, type));
46376fd607bSopenharmony_ci    Size size;
46476fd607bSopenharmony_ci    size.width = DEFAULT_THUMB_SIZE;
46576fd607bSopenharmony_ci    size.height = DEFAULT_THUMB_SIZE;
46676fd607bSopenharmony_ci    if (uniqueFd.Get() == E_ERR) {
46776fd607bSopenharmony_ci        uniqueFd = UniqueFd(GetKeyFramePixelMapFromServer(uriStr, path, beginStamp, type));
46876fd607bSopenharmony_ci        if (uniqueFd.Get() < 0) {
46976fd607bSopenharmony_ci            NAPI_ERR_LOG("queryKeyFrameThumb is null, errCode is %{public}d", uniqueFd.Get());
47076fd607bSopenharmony_ci            return nullptr;
47176fd607bSopenharmony_ci        }
47276fd607bSopenharmony_ci    }
47376fd607bSopenharmony_ci    tracer.Finish();
47476fd607bSopenharmony_ci    return DecodeThumbnail(uniqueFd, size);
47576fd607bSopenharmony_ci}
47676fd607bSopenharmony_ci
47776fd607bSopenharmony_civoid ThumbnailManager::DeleteRequestIdFromMap(const string &requestId)
47876fd607bSopenharmony_ci{
47976fd607bSopenharmony_ci    thumbRequest_.Erase(requestId);
48076fd607bSopenharmony_ci}
48176fd607bSopenharmony_ci
48276fd607bSopenharmony_cibool ThumbnailManager::RequestFastImage(const RequestSharedPtr &request)
48376fd607bSopenharmony_ci{
48476fd607bSopenharmony_ci    MediaLibraryTracer tracer;
48576fd607bSopenharmony_ci    tracer.Start("ThumbnailManager::RequestFastImage");
48676fd607bSopenharmony_ci    request->SetFd(DEFAULT_FD);
48776fd607bSopenharmony_ci    Size fastSize;
48876fd607bSopenharmony_ci    if (!GetFastThumbNewSize(request->GetRequestSize(), fastSize)) {
48976fd607bSopenharmony_ci        return false;
49076fd607bSopenharmony_ci    }
49176fd607bSopenharmony_ci    UniqueFd uniqueFd(OpenThumbnail(request->GetPath(), GetThumbType(fastSize.width, fastSize.height)));
49276fd607bSopenharmony_ci    if (uniqueFd.Get() < 0) {
49376fd607bSopenharmony_ci        // Can not get fast image in sandbox
49476fd607bSopenharmony_ci        int32_t outFd = GetPixelMapFromServer(request->GetUri(), request->GetRequestSize(), request->GetPath());
49576fd607bSopenharmony_ci        if (outFd <= 0) {
49676fd607bSopenharmony_ci            NAPI_ERR_LOG("Can not get thumbnail from server, uri=%{private}s", request->GetUri().c_str());
49776fd607bSopenharmony_ci            request->error = E_FAIL;
49876fd607bSopenharmony_ci            return false;
49976fd607bSopenharmony_ci        }
50076fd607bSopenharmony_ci        request->SetFd(outFd);
50176fd607bSopenharmony_ci    }
50276fd607bSopenharmony_ci
50376fd607bSopenharmony_ci    ThumbnailType thumbType = GetThumbType(fastSize.width, fastSize.height);
50476fd607bSopenharmony_ci    PixelMapPtr pixelMap = nullptr;
50576fd607bSopenharmony_ci    if (request->GetFd().Get() == DEFAULT_FD &&
50676fd607bSopenharmony_ci        (thumbType == ThumbnailType::MTH || thumbType == ThumbnailType::YEAR)) {
50776fd607bSopenharmony_ci        pixelMap = CreateThumbnailByAshmem(uniqueFd, fastSize);
50876fd607bSopenharmony_ci    } else {
50976fd607bSopenharmony_ci        pixelMap = DecodeThumbnail(request->GetFd(), fastSize);
51076fd607bSopenharmony_ci    }
51176fd607bSopenharmony_ci    if (pixelMap == nullptr) {
51276fd607bSopenharmony_ci        request->error = E_FAIL;
51376fd607bSopenharmony_ci        return false;
51476fd607bSopenharmony_ci    }
51576fd607bSopenharmony_ci    request->SetFastPixelMap(move(pixelMap));
51676fd607bSopenharmony_ci    return true;
51776fd607bSopenharmony_ci}
51876fd607bSopenharmony_ci
51976fd607bSopenharmony_civoid ThumbnailManager::DealWithFastRequest(const RequestSharedPtr &request)
52076fd607bSopenharmony_ci{
52176fd607bSopenharmony_ci    MediaLibraryTracer tracer;
52276fd607bSopenharmony_ci    tracer.Start("ThumbnailManager::DealWithFastRequest");
52376fd607bSopenharmony_ci
52476fd607bSopenharmony_ci    if (request == nullptr) {
52576fd607bSopenharmony_ci        return;
52676fd607bSopenharmony_ci    }
52776fd607bSopenharmony_ci
52876fd607bSopenharmony_ci    if (!RequestFastImage(request) && request->error != E_FAIL) {
52976fd607bSopenharmony_ci        // when local pixelmap not exit, must add QualityThread
53076fd607bSopenharmony_ci        AddQualityPhotoRequest(request);
53176fd607bSopenharmony_ci        return;
53276fd607bSopenharmony_ci    }
53376fd607bSopenharmony_ci
53476fd607bSopenharmony_ci    // callback
53576fd607bSopenharmony_ci    NotifyImage(request);
53676fd607bSopenharmony_ci}
53776fd607bSopenharmony_ci
53876fd607bSopenharmony_civoid ThumbnailManager::DealWithQualityRequest(const RequestSharedPtr &request)
53976fd607bSopenharmony_ci{
54076fd607bSopenharmony_ci    MediaLibraryTracer tracer;
54176fd607bSopenharmony_ci    tracer.Start("ThumbnailManager::DealWithQualityRequest");
54276fd607bSopenharmony_ci
54376fd607bSopenharmony_ci    unique_ptr<PixelMap> pixelMapPtr = nullptr;
54476fd607bSopenharmony_ci    if (request->GetFd().Get() > 0) {
54576fd607bSopenharmony_ci        pixelMapPtr = DecodeThumbnail(request->GetFd(), request->GetRequestSize());
54676fd607bSopenharmony_ci    } else {
54776fd607bSopenharmony_ci        pixelMapPtr = QueryThumbnail(request->GetUri(), request->GetRequestSize(), request->GetPath());
54876fd607bSopenharmony_ci    }
54976fd607bSopenharmony_ci
55076fd607bSopenharmony_ci    if (pixelMapPtr == nullptr) {
55176fd607bSopenharmony_ci        NAPI_ERR_LOG("Can not get pixelMap");
55276fd607bSopenharmony_ci        request->error = E_FAIL;
55376fd607bSopenharmony_ci    }
55476fd607bSopenharmony_ci    request->SetPixelMap(move(pixelMapPtr));
55576fd607bSopenharmony_ci
55676fd607bSopenharmony_ci    // callback
55776fd607bSopenharmony_ci    NotifyImage(request);
55876fd607bSopenharmony_ci}
55976fd607bSopenharmony_ci
56076fd607bSopenharmony_civoid ThumbnailManager::ImageWorker(int num)
56176fd607bSopenharmony_ci{
56276fd607bSopenharmony_ci    SetThreadName("ImageWorker", num);
56376fd607bSopenharmony_ci    while (true) {
56476fd607bSopenharmony_ci        if (!isThreadRunning_) {
56576fd607bSopenharmony_ci            return;
56676fd607bSopenharmony_ci        }
56776fd607bSopenharmony_ci        if (!fastQueue_.Empty()) {
56876fd607bSopenharmony_ci            RequestSharedPtr request;
56976fd607bSopenharmony_ci            if (fastQueue_.Pop(request) && request->NeedContinue()) {
57076fd607bSopenharmony_ci                DealWithFastRequest(request);
57176fd607bSopenharmony_ci            }
57276fd607bSopenharmony_ci        } else if (!qualityQueue_.Empty()) {
57376fd607bSopenharmony_ci            RequestSharedPtr request;
57476fd607bSopenharmony_ci            if (qualityQueue_.Pop(request) && request->NeedContinue()) {
57576fd607bSopenharmony_ci                DealWithQualityRequest(request);
57676fd607bSopenharmony_ci            }
57776fd607bSopenharmony_ci        } else {
57876fd607bSopenharmony_ci            std::unique_lock<std::mutex> lock(queueLock_);
57976fd607bSopenharmony_ci            queueCv_.wait(lock, [this]() {
58076fd607bSopenharmony_ci                return !isThreadRunning_ || !(qualityQueue_.Empty() && fastQueue_.Empty());
58176fd607bSopenharmony_ci            });
58276fd607bSopenharmony_ci        }
58376fd607bSopenharmony_ci    }
58476fd607bSopenharmony_ci}
58576fd607bSopenharmony_ci
58676fd607bSopenharmony_cistatic void HandlePixelCallback(const RequestSharedPtr &request)
58776fd607bSopenharmony_ci{
58876fd607bSopenharmony_ci    napi_env env = request->callback_.env_;
58976fd607bSopenharmony_ci    napi_value jsCallback = nullptr;
59076fd607bSopenharmony_ci    napi_status status = napi_get_reference_value(env, request->callback_.callBackRef_, &jsCallback);
59176fd607bSopenharmony_ci    if (status != napi_ok) {
59276fd607bSopenharmony_ci        NAPI_ERR_LOG("Create reference fail, status: %{public}d", status);
59376fd607bSopenharmony_ci        return;
59476fd607bSopenharmony_ci    }
59576fd607bSopenharmony_ci
59676fd607bSopenharmony_ci    napi_value retVal = nullptr;
59776fd607bSopenharmony_ci    napi_value result[ARGS_TWO];
59876fd607bSopenharmony_ci    if (request->GetStatus() == ThumbnailStatus::THUMB_REMOVE) {
59976fd607bSopenharmony_ci        return;
60076fd607bSopenharmony_ci    }
60176fd607bSopenharmony_ci
60276fd607bSopenharmony_ci    if (request->error == E_FAIL) {
60376fd607bSopenharmony_ci        int32_t errorNum = MediaLibraryNapiUtils::TransErrorCode("requestPhoto", request->error);
60476fd607bSopenharmony_ci        MediaLibraryNapiUtils::CreateNapiErrorObject(env, result[PARAM0], errorNum,
60576fd607bSopenharmony_ci            "Failed to request Photo");
60676fd607bSopenharmony_ci    } else {
60776fd607bSopenharmony_ci        result[PARAM0] = nullptr;
60876fd607bSopenharmony_ci    }
60976fd607bSopenharmony_ci    if (request->GetStatus() == ThumbnailStatus::THUMB_FAST) {
61076fd607bSopenharmony_ci        result[PARAM1] = Media::PixelMapNapi::CreatePixelMap(env,
61176fd607bSopenharmony_ci            shared_ptr<PixelMap>(request->GetFastPixelMap()));
61276fd607bSopenharmony_ci    } else {
61376fd607bSopenharmony_ci        result[PARAM1] = Media::PixelMapNapi::CreatePixelMap(env,
61476fd607bSopenharmony_ci            shared_ptr<PixelMap>(request->GetPixelMap()));
61576fd607bSopenharmony_ci    }
61676fd607bSopenharmony_ci
61776fd607bSopenharmony_ci    status = napi_call_function(env, nullptr, jsCallback, ARGS_TWO, result, &retVal);
61876fd607bSopenharmony_ci    if (status != napi_ok) {
61976fd607bSopenharmony_ci        NAPI_ERR_LOG("CallJs napi_call_function fail, status: %{public}d", status);
62076fd607bSopenharmony_ci        return;
62176fd607bSopenharmony_ci    }
62276fd607bSopenharmony_ci}
62376fd607bSopenharmony_ci
62476fd607bSopenharmony_cistatic void UvJsExecute(uv_work_t *work)
62576fd607bSopenharmony_ci{
62676fd607bSopenharmony_ci    // js thread
62776fd607bSopenharmony_ci    if (work == nullptr) {
62876fd607bSopenharmony_ci        return;
62976fd607bSopenharmony_ci    }
63076fd607bSopenharmony_ci
63176fd607bSopenharmony_ci    ThumnailUv *uvMsg = reinterpret_cast<ThumnailUv *>(work->data);
63276fd607bSopenharmony_ci    if (uvMsg == nullptr) {
63376fd607bSopenharmony_ci        delete work;
63476fd607bSopenharmony_ci        return;
63576fd607bSopenharmony_ci    }
63676fd607bSopenharmony_ci    if (uvMsg->request_ == nullptr) {
63776fd607bSopenharmony_ci        delete uvMsg;
63876fd607bSopenharmony_ci        delete work;
63976fd607bSopenharmony_ci        return;
64076fd607bSopenharmony_ci    }
64176fd607bSopenharmony_ci    do {
64276fd607bSopenharmony_ci        napi_env env = uvMsg->request_->callback_.env_;
64376fd607bSopenharmony_ci        if (!uvMsg->request_->NeedContinue()) {
64476fd607bSopenharmony_ci            break;
64576fd607bSopenharmony_ci        }
64676fd607bSopenharmony_ci        NapiScopeHandler scopeHandler(env);
64776fd607bSopenharmony_ci        if (!scopeHandler.IsValid()) {
64876fd607bSopenharmony_ci            break;
64976fd607bSopenharmony_ci        }
65076fd607bSopenharmony_ci        HandlePixelCallback(uvMsg->request_);
65176fd607bSopenharmony_ci    } while (0);
65276fd607bSopenharmony_ci    if (uvMsg->manager_ == nullptr) {
65376fd607bSopenharmony_ci        delete uvMsg;
65476fd607bSopenharmony_ci        delete work;
65576fd607bSopenharmony_ci        return;
65676fd607bSopenharmony_ci    }
65776fd607bSopenharmony_ci    if (uvMsg->request_->GetStatus() == ThumbnailStatus::THUMB_FAST &&
65876fd607bSopenharmony_ci        NeedQualityThumb(uvMsg->request_->GetRequestSize(), uvMsg->request_->requestPhotoType)) {
65976fd607bSopenharmony_ci        uvMsg->manager_->AddQualityPhotoRequest(uvMsg->request_);
66076fd607bSopenharmony_ci    } else {
66176fd607bSopenharmony_ci        uvMsg->manager_->DeleteRequestIdFromMap(uvMsg->request_->GetUUID());
66276fd607bSopenharmony_ci        uvMsg->request_->ReleaseCallbackRef();
66376fd607bSopenharmony_ci    }
66476fd607bSopenharmony_ci
66576fd607bSopenharmony_ci    delete uvMsg;
66676fd607bSopenharmony_ci    delete work;
66776fd607bSopenharmony_ci}
66876fd607bSopenharmony_ci
66976fd607bSopenharmony_civoid ThumbnailManager::NotifyImage(const RequestSharedPtr &request)
67076fd607bSopenharmony_ci{
67176fd607bSopenharmony_ci    MediaLibraryTracer tracer;
67276fd607bSopenharmony_ci    tracer.Start("ThumbnailManager::NotifyImage");
67376fd607bSopenharmony_ci
67476fd607bSopenharmony_ci    if (!request->NeedContinue()) {
67576fd607bSopenharmony_ci        DeleteRequestIdFromMap(request->GetUUID());
67676fd607bSopenharmony_ci        return;
67776fd607bSopenharmony_ci    }
67876fd607bSopenharmony_ci
67976fd607bSopenharmony_ci    uv_loop_s *loop = nullptr;
68076fd607bSopenharmony_ci    napi_get_uv_event_loop(request->callback_.env_, &loop);
68176fd607bSopenharmony_ci    if (loop == nullptr) {
68276fd607bSopenharmony_ci        DeleteRequestIdFromMap(request->GetUUID());
68376fd607bSopenharmony_ci        return;
68476fd607bSopenharmony_ci    }
68576fd607bSopenharmony_ci
68676fd607bSopenharmony_ci    uv_work_t *work = new (nothrow) uv_work_t;
68776fd607bSopenharmony_ci    if (work == nullptr) {
68876fd607bSopenharmony_ci        DeleteRequestIdFromMap(request->GetUUID());
68976fd607bSopenharmony_ci        return;
69076fd607bSopenharmony_ci    }
69176fd607bSopenharmony_ci
69276fd607bSopenharmony_ci    ThumnailUv *msg = new (nothrow) ThumnailUv(request, this);
69376fd607bSopenharmony_ci    if (msg == nullptr) {
69476fd607bSopenharmony_ci        delete work;
69576fd607bSopenharmony_ci        DeleteRequestIdFromMap(request->GetUUID());
69676fd607bSopenharmony_ci        return;
69776fd607bSopenharmony_ci    }
69876fd607bSopenharmony_ci
69976fd607bSopenharmony_ci    work->data = reinterpret_cast<void *>(msg);
70076fd607bSopenharmony_ci    int ret = uv_queue_work(loop, work, [](uv_work_t *w) {}, [](uv_work_t *w, int s) {
70176fd607bSopenharmony_ci        UvJsExecute(w);
70276fd607bSopenharmony_ci    });
70376fd607bSopenharmony_ci    if (ret != 0) {
70476fd607bSopenharmony_ci        NAPI_ERR_LOG("Failed to execute libuv work queue, ret: %{public}d", ret);
70576fd607bSopenharmony_ci        delete msg;
70676fd607bSopenharmony_ci        delete work;
70776fd607bSopenharmony_ci        return;
70876fd607bSopenharmony_ci    }
70976fd607bSopenharmony_ci    return;
71076fd607bSopenharmony_ci}
71176fd607bSopenharmony_ci}
71276fd607bSopenharmony_ci}
713