1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "download_callback_middle_napi.h"
17 #include "dfs_error.h"
18 #include "utils_log.h"
19
20 namespace OHOS::FileManagement::CloudSync {
RemoveDownloadInfo(int64_t downloadId)21 void CloudDlCallbackMiddleNapi::RemoveDownloadInfo(int64_t downloadId)
22 {
23 std::lock_guard<std::mutex> lock(downloadInfoMtx_);
24 downloadInfos_.erase(downloadId);
25 }
26
GetDownloadInfo(const DownloadProgressObj & progress)27 std::shared_ptr<DlProgressNapi> CloudDlCallbackMiddleNapi::GetDownloadInfo(const DownloadProgressObj &progress)
28 {
29 std::shared_ptr<DlProgressNapi> originProgress = nullptr;
30 {
31 std::lock_guard<std::mutex> lock(downloadInfoMtx_);
32 auto it = downloadInfos_.find(progress.downloadId);
33 if (it == downloadInfos_.end()) {
34 return nullptr;
35 }
36 originProgress = it->second;
37 }
38
39 // Copy a new object to return the callback to avoid affecting the download progress.
40 std::shared_ptr<DlProgressNapi> resProgress = originProgress->CreateNewObject();
41 originProgress->Update(progress);
42 resProgress->Update(progress);
43 return resProgress;
44 }
45
GetDownloadIdsByUri(const std::string & uri)46 std::vector<int64_t> CloudDlCallbackMiddleNapi::GetDownloadIdsByUri(const std::string &uri)
47 {
48 std::vector<int64_t> ids;
49 std::lock_guard<std::mutex> lock(downloadInfoMtx_);
50 for (const auto &[id, progress] : downloadInfos_) {
51 if (progress->GetUri() == uri) {
52 ids.push_back(id);
53 }
54 }
55 return ids;
56 }
57
OnDownloadProcess(const DownloadProgressObj & progress)58 void CloudDlCallbackMiddleNapi::OnDownloadProcess(const DownloadProgressObj &progress)
59 {
60 auto fileCacheInfo = GetDownloadInfo(progress);
61 if (fileCacheInfo == nullptr) {
62 LOGE("Failed to callback, no such taskId: %{public}lld", static_cast<long long>(progress.downloadId));
63 return;
64 }
65 std::shared_ptr<CloudDlCallbackMiddleNapi> callbackImpl = shared_from_this();
66 napi_status status = napi_send_event(
67 callbackImpl->env_,
68 [fileCacheInfo, callbackImpl]() mutable {
69 if (fileCacheInfo == nullptr || callbackImpl == nullptr) {
70 LOGE("Failed to callback, is callbackImpl null: %{public}d", (callbackImpl == nullptr));
71 return;
72 }
73 napi_env tmpEnv = callbackImpl->env_;
74 napi_handle_scope scope = nullptr;
75 napi_status status = napi_open_handle_scope(tmpEnv, &scope);
76 if (status != napi_ok) {
77 LOGE("Failed to open handle scope, status: %{public}d", status);
78 return;
79 }
80 napi_value jsProgress = fileCacheInfo->ConvertToValue(tmpEnv);
81 if (jsProgress == nullptr) {
82 LOGE("Failed to convert progress to nvalue");
83 napi_close_handle_scope(tmpEnv, scope);
84 return;
85 }
86 callbackImpl->OnJsCallback(&jsProgress, 1);
87 napi_close_handle_scope(tmpEnv, scope);
88 if (fileCacheInfo->IsNeedClean()) {
89 callbackImpl->RemoveDownloadInfo(fileCacheInfo->GetTaskId());
90 }
91 },
92 napi_eprio_immediate);
93 if (status != napi_ok) {
94 LOGE("Failed to execute libuv work queue, status: %{public}d", status);
95 }
96 }
97 } // namespace OHOS::FileManagement::CloudSync