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_progress_ani.h"
17
18 #include <memory>
19
20 #include "error_handler.h"
21 #include "multi_download_progress_ani.h"
22
23 namespace OHOS::FileManagement::CloudSync {
24 using namespace arkts::ani_signature;
Update(const DownloadProgressObj & progress)25 void SingleProgressAni::Update(const DownloadProgressObj &progress)
26 {
27 if (taskId_ != progress.downloadId) {
28 return;
29 }
30 std::lock_guard<std::mutex> lock(mtx_);
31 uri_ = progress.path;
32 totalSize_ = progress.totalSize;
33 downloadedSize_ = progress.downloadedSize;
34 state_ = progress.state;
35 errorType_ = progress.downloadErrorType;
36 needClean_ = (progress.state != DownloadProgressObj::RUNNING);
37 }
38
ConvertToObject(ani_env * env)39 ani_object SingleProgressAni::ConvertToObject(ani_env *env)
40 {
41 ani_class cls;
42 ani_status ret;
43 std::string classDesc = Builder::BuildClass("@ohos.file.cloudSync.cloudSync.DownloadProgressInner").Descriptor();
44 if ((ret = env->FindClass(classDesc.c_str(), &cls)) != ANI_OK) {
45 LOGE("Cannot find class %{private}s, err: %{public}d", classDesc.c_str(), ret);
46 return nullptr;
47 }
48
49 ani_method ctor;
50 std::string ct = Builder::BuildConstructorName();
51 std::string argSign = Builder::BuildSignatureDescriptor(
52 {Builder::BuildDouble(), Builder::BuildEnum("@ohos.file.cloudSync.cloudSync.State"), Builder::BuildDouble(),
53 Builder::BuildDouble(), Builder::BuildClass("std.core.String"),
54 Builder::BuildEnum("@ohos.file.cloudSync.cloudSync.DownloadErrorType")});
55 ret = env->Class_FindMethod(cls, ct.c_str(), argSign.c_str(), &ctor);
56 if (ret != ANI_OK) {
57 LOGE("find ctor method failed. ret = %{public}d", ret);
58 return nullptr;
59 }
60 ani_string uri = nullptr;
61 ret = env->String_NewUTF8(uri_.c_str(), uri_.size(), &uri);
62 if (ret != ANI_OK) {
63 LOGE("get uri failed. ret = %{public}d", ret);
64 return nullptr;
65 }
66
67 ani_enum stateEnum;
68 Type stateSign = Builder::BuildEnum("@ohos.file.cloudSync.cloudSync.State");
69 env->FindEnum(stateSign.Descriptor().c_str(), &stateEnum);
70 ani_enum downloadErrorEnum;
71 Type errorSign = Builder::BuildEnum("@ohos.file.cloudSync.cloudSync.DownloadErrorType");
72 env->FindEnum(errorSign.Descriptor().c_str(), &downloadErrorEnum);
73
74 ani_enum_item stateEnumItem;
75 ani_enum_item downloadErrorEnumItem;
76 env->Enum_GetEnumItemByIndex(downloadErrorEnum, errorType_, &downloadErrorEnumItem);
77 env->Enum_GetEnumItemByIndex(stateEnum, state_, &stateEnumItem);
78 ani_object pg;
79 ret = env->Object_New(cls, ctor, &pg, static_cast<double>(taskId_), stateEnumItem,
80 static_cast<double>(downloadedSize_), static_cast<double>(totalSize_), uri,
81 downloadErrorEnumItem);
82 if (ret != ANI_OK) {
83 LOGE("create new object failed. ret = %{public}d", ret);
84 }
85 return pg;
86 }
87
CreateNewObject()88 std::shared_ptr<DlProgressAni> SingleProgressAni::CreateNewObject()
89 {
90 return std::make_shared<SingleProgressAni>(taskId_);
91 }
92
Update(const DownloadProgressObj & progress)93 void BatchProgressAni::Update(const DownloadProgressObj &progress)
94 {
95 if (taskId_ != progress.downloadId) {
96 return;
97 }
98 std::lock_guard<std::mutex> lock(mtx_);
99 state_ = static_cast<int32_t>(progress.batchState);
100 downloadedSize_ = progress.batchDownloadSize;
101 totalSize_ = progress.batchTotalSize;
102 totalNum_ = progress.batchTotalNum;
103 errorType_ = static_cast<int32_t>(progress.downloadErrorType);
104 if (progress.state == DownloadProgressObj::COMPLETED) {
105 downloadedFiles_.insert(progress.path);
106 } else if (progress.state != DownloadProgressObj::RUNNING) {
107 failedFiles_.insert(std::make_pair(progress.path, static_cast<int32_t>(progress.downloadErrorType)));
108 }
109 needClean_ = ((progress.batchTotalNum == progress.batchFailNum + progress.batchSuccNum) &&
110 progress.batchState != DownloadProgressObj::RUNNING);
111 }
112
113 // no need to lock here, because it is called only once when a new object is copied out.
SetDownloadedFiles(const std::unordered_set<std::string> & fileList)114 void BatchProgressAni::SetDownloadedFiles(const std::unordered_set<std::string> &fileList)
115 {
116 downloadedFiles_ = fileList;
117 }
118
SetFailedFiles(const std::unordered_map<std::string,int32_t> & fileList)119 void BatchProgressAni::SetFailedFiles(const std::unordered_map<std::string, int32_t> &fileList)
120 {
121 failedFiles_ = fileList;
122 }
123
CreateNewObject()124 std::shared_ptr<DlProgressAni> BatchProgressAni::CreateNewObject()
125 {
126 auto resProgress = std::make_shared<BatchProgressAni>(taskId_);
127 std::lock_guard<std::mutex> lock(mtx_);
128 resProgress->SetDownloadedFiles(downloadedFiles_);
129 resProgress->SetFailedFiles(failedFiles_);
130 return resProgress;
131 }
132
ConvertToObject(ani_env * env)133 ani_object BatchProgressAni::ConvertToObject(ani_env *env)
134 {
135 ModuleFileIO::FsResult<MultiDlProgressCore *> data = MultiDlProgressCore::Constructor();
136 if (!data.IsSuccess()) {
137 return nullptr;
138 }
139 MultiDlProgressCore *multiProgress = data.GetData().value();
140 multiProgress->downloadProgress_ = shared_from_this();
141
142 ani_object pg = MultiDlProgressWrapper::Wrap(env, multiProgress);
143 if (pg == nullptr) {
144 multiProgress->downloadProgress_.reset();
145 delete multiProgress;
146 }
147 return pg;
148 }
149 } // namespace OHOS::FileManagement::CloudSync
150