• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_ani.h"
17 #include "dfs_error.h"
18 #include "multi_download_progress_ani.h"
19 #include "utils_log.h"
20 
21 namespace OHOS::FileManagement::CloudSync {
22 constexpr int32_t ANI_SCOPE_SIZE = 16;
RemoveDownloadInfo(int64_t downloadId)23 void CloudDlCallbackMiddleAni::RemoveDownloadInfo(int64_t downloadId)
24 {
25     std::lock_guard<std::mutex> lock(downloadInfoMtx_);
26     downloadInfos_.erase(downloadId);
27 }
28 
GetDownloadInfo(const DownloadProgressObj & progress)29 std::shared_ptr<DlProgressAni> CloudDlCallbackMiddleAni::GetDownloadInfo(const DownloadProgressObj &progress)
30 {
31     std::shared_ptr<DlProgressAni> originProgress = nullptr;
32     {
33         std::lock_guard<std::mutex> lock(downloadInfoMtx_);
34         auto it = downloadInfos_.find(progress.downloadId);
35         if (it == downloadInfos_.end()) {
36             return nullptr;
37         }
38         originProgress = it->second;
39     }
40 
41     // Copy a new object to return the callback to avoid affecting the download progress.
42     std::shared_ptr<DlProgressAni> resProgress = originProgress->CreateNewObject();
43     originProgress->Update(progress);
44     resProgress->Update(progress);
45     return resProgress;
46 }
47 
GetDownloadIdsByUri(const std::string & uri)48 std::vector<int64_t> CloudDlCallbackMiddleAni::GetDownloadIdsByUri(const std::string &uri)
49 {
50     std::vector<int64_t> ids;
51     std::lock_guard<std::mutex> lock(downloadInfoMtx_);
52     for (const auto &[id, progress] : downloadInfos_) {
53         if (progress->GetUri() == uri) {
54             ids.push_back(id);
55         }
56     }
57     return ids;
58 }
59 
OnDownloadProcess(const DownloadProgressObj & progress)60 void CloudDlCallbackMiddleAni::OnDownloadProcess(const DownloadProgressObj &progress)
61 {
62     auto fileCacheInfo = GetDownloadInfo(progress);
63     if (fileCacheInfo == nullptr) {
64         LOGE("Failed to callback, no such taskId: %{public}lld", static_cast<long long>(progress.downloadId));
65         return;
66     }
67     std::shared_ptr<CloudDlCallbackMiddleAni> callbackImpl = shared_from_this();
68     auto task = [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         LOGI("CloudDlCallbackMiddleAni OnDownloadProcess for JS");
74         ani_env *tmpEnv = callbackImpl->GetEnv();
75         if (tmpEnv == nullptr) {
76             LOGE("Failed to get env from vm");
77             return;
78         }
79         ani_size nr_refs = ANI_SCOPE_SIZE;
80         ani_status ret = tmpEnv->CreateLocalScope(nr_refs);
81         if (ret != ANI_OK) {
82             LOGE("crete local scope failed. ret = %{public}d", ret);
83             return;
84         }
85         ani_object pg = fileCacheInfo->ConvertToObject(tmpEnv);
86         callbackImpl->OnJsCallback(tmpEnv, pg, 1);
87         ret = tmpEnv->DestroyLocalScope();
88         if (ret != ANI_OK) {
89             LOGE("failed to DestroyLocalScope. ret = %{public}d", ret);
90         }
91         if (fileCacheInfo->IsNeedClean()) {
92             callbackImpl->RemoveDownloadInfo(fileCacheInfo->GetTaskId());
93         }
94         callbackImpl->DetachEnv();
95     };
96     if (!ANIUtils::SendEventToMainThread(task)) {
97         LOGE("failed to send event");
98     }
99 }
100 } // namespace OHOS::FileManagement::CloudSync