• 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 "cloud_file_cache_ani.h"
17 
18 #include "ani_utils.h"
19 #include "dfs_error.h"
20 #include "error_handler.h"
21 #include "utils_log.h"
22 
23 namespace OHOS::FileManagement::CloudSync {
24 
25 using namespace arkts::ani_signature;
26 
CloudFileCacheUnwrap(ani_env * env,ani_object object)27 static CloudFileCacheCore *CloudFileCacheUnwrap(ani_env *env, ani_object object)
28 {
29     ani_long nativePtr;
30     auto ret = env->Object_GetFieldByName_Long(object, "nativePtr", &nativePtr);
31     if (ret != ANI_OK) {
32         LOGE("Unwrap cloudFileCacheCore err: %{public}d", static_cast<int32_t>(ret));
33         return nullptr;
34     }
35     std::uintptr_t ptrValue = static_cast<std::uintptr_t>(nativePtr);
36     CloudFileCacheCore *cloudFileCache = reinterpret_cast<CloudFileCacheCore *>(ptrValue);
37     return cloudFileCache;
38 }
39 
CloudFileCacheConstructor(ani_env * env,ani_object object)40 void CloudFileCacheAni::CloudFileCacheConstructor(ani_env *env, ani_object object)
41 {
42     ani_namespace ns {};
43     Namespace nsSign = Builder::BuildNamespace("@ohos.file.cloudSync.cloudSync");
44     ani_status ret = env->FindNamespace(nsSign.Descriptor().c_str(), &ns);
45     if (ret != ANI_OK) {
46         LOGE("find namespace failed. ret = %{public}d", static_cast<int32_t>(ret));
47         ErrorHandler::Throw(env, ENOMEM);
48         return;
49     }
50     Type clsName = Builder::BuildClass("CloudFileCache");
51     ani_class cls;
52     ret = env->Namespace_FindClass(ns, clsName.Descriptor().c_str(), &cls);
53     if (ret != ANI_OK) {
54         LOGE("find class failed. ret = %{public}d", static_cast<int32_t>(ret));
55         ErrorHandler::Throw(env, ENOMEM);
56         return;
57     }
58 
59     ani_method bindNativePtr;
60     std::string bindSign = Builder::BuildSignatureDescriptor({Builder::BuildLong()});
61     ret = env->Class_FindMethod(cls, "bindNativePtr", bindSign.c_str(), &bindNativePtr);
62     if (ret != ANI_OK) {
63         LOGE("find class ctor. ret = %{public}d", static_cast<int32_t>(ret));
64         ErrorHandler::Throw(env, ENOMEM);
65         return;
66     }
67 
68     FsResult<CloudFileCacheCore *> data = CloudFileCacheCore::Constructor();
69     if (!data.IsSuccess()) {
70         LOGE("cloudFileCache constructor failed.");
71         const auto &err = data.GetError();
72         ErrorHandler::Throw(env, err);
73         return;
74     }
75 
76     const CloudFileCacheCore *cloudFileCache = data.GetData().value();
77     ret = env->Object_CallMethod_Void(object, bindNativePtr, reinterpret_cast<ani_long>(cloudFileCache));
78     if (ret != ANI_OK) {
79         LOGE("bindNativePtr failed.");
80         delete cloudFileCache;
81         ErrorHandler::Throw(env, ENOMEM);
82     }
83 }
84 
CloudFileCacheOn(ani_env * env,ani_object object,ani_string evt,ani_object fun)85 void CloudFileCacheAni::CloudFileCacheOn(ani_env *env, ani_object object, ani_string evt, ani_object fun)
86 {
87     std::string event;
88     ani_status ret = ANIUtils::AniString2String(env, evt, event);
89     if (ret != ANI_OK) {
90         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
91         return;
92     }
93 
94     if (event == "multiProgress") {
95         event = MULTI_PROGRESS;
96     }
97     if (event != PROGRESS && event != MULTI_PROGRESS) {
98         LOGE("Invalid argument for event type.");
99         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
100         return;
101     }
102 
103     auto cloudFileCache = CloudFileCacheUnwrap(env, object);
104     if (cloudFileCache == nullptr) {
105         LOGE("Cannot wrap cloudFileCache.");
106         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
107         return;
108     }
109 
110     std::shared_ptr<CloudFileCacheCallbackImplAni> callbackImpl = cloudFileCache->GetCallbackImpl(event, true);
111     callbackImpl->InitVm(env);
112     auto status = callbackImpl->RegisterCallback(env, fun);
113     if (status != ANI_OK) {
114         LOGE("Failed to register callback, status: %{public}d.", status);
115         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
116         return;
117     }
118 }
119 
CloudFileCacheOff0(ani_env * env,ani_object object,ani_string evt,ani_object fun)120 void CloudFileCacheAni::CloudFileCacheOff0(ani_env *env, ani_object object, ani_string evt, ani_object fun)
121 {
122     std::string event;
123     ani_status ret = ANIUtils::AniString2String(env, evt, event);
124     if (ret != ANI_OK) {
125         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
126         return;
127     }
128 
129     if (event == "multiProgress") {
130         event = MULTI_PROGRESS;
131     }
132     if (event != PROGRESS && event != MULTI_PROGRESS) {
133         LOGE("Invalid argument for event type.");
134         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
135         return;
136     }
137 
138     auto cloudFileCache = CloudFileCacheUnwrap(env, object);
139     if (cloudFileCache == nullptr) {
140         LOGE("Cannot wrap cloudFileCache.");
141         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
142         return;
143     }
144 
145     std::shared_ptr<CloudFileCacheCallbackImplAni> callbackImpl = cloudFileCache->GetCallbackImpl(event, false);
146     if (callbackImpl == nullptr || callbackImpl->UnregisterCallback(env, fun) != ANI_OK) {
147         LOGE("Failed to unregister callback.");
148         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
149         return;
150     }
151 }
152 
CloudFileCacheOff1(ani_env * env,ani_object object,ani_string evt)153 void CloudFileCacheAni::CloudFileCacheOff1(ani_env *env, ani_object object, ani_string evt)
154 {
155     CloudFileCacheOff0(env, object, evt, nullptr);
156 }
157 
CloudFileCacheStart(ani_env * env,ani_object object,ani_string uri)158 void CloudFileCacheAni::CloudFileCacheStart(ani_env *env, ani_object object, ani_string uri)
159 {
160     std::string uriInput;
161     ani_status ret = ANIUtils::AniString2String(env, uri, uriInput);
162     if (ret != ANI_OK) {
163         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
164         return;
165     }
166 
167     auto cloudFileCache = CloudFileCacheUnwrap(env, object);
168     if (cloudFileCache == nullptr) {
169         LOGE("Cannot wrap cloudFileCache.");
170         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
171         return;
172     }
173     auto data = cloudFileCache->DoStart(uriInput);
174     if (!data.IsSuccess()) {
175         const auto &err = data.GetError();
176         LOGE("cloudFileCache do start failed, ret = %{public}d", err.GetErrNo());
177         ErrorHandler::Throw(env, err);
178     }
179 }
180 
CloudFileCacheStartBatch(ani_env * env,ani_object object,ani_array_ref uriList,ani_enum_item fileType)181 ani_double CloudFileCacheAni::CloudFileCacheStartBatch(ani_env *env,
182                                                        ani_object object,
183                                                        ani_array_ref uriList,
184                                                        ani_enum_item fileType)
185 {
186     ani_double errResult = 0;
187     auto [ret, urisInput] = ANIUtils::AniToStringArray(env, uriList);
188     if (!ret) {
189         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
190         return errResult;
191     }
192 
193     int32_t fieldKey = static_cast<int32_t>(FieldKey::FIELDKEY_CONTENT);
194     tie(ret, fieldKey) = ANIUtils::EnumToInt32(env, fileType);
195     if (!ret) {
196         LOGE("cloudFileCache get fileType failed");
197         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
198         return errResult;
199     }
200 
201     auto cloudFileCache = CloudFileCacheUnwrap(env, object);
202     if (cloudFileCache == nullptr) {
203         LOGE("Cannot wrap cloudFileCache.");
204         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
205         return errResult;
206     }
207     auto data = cloudFileCache->DoStart(urisInput, fieldKey);
208     if (!data.IsSuccess()) {
209         const auto &err = data.GetError();
210         LOGE("cloudFileCache do start failed, ret = %{public}d", err.GetErrNo());
211         ErrorHandler::Throw(env, err);
212         return errResult;
213     }
214 
215     return static_cast<ani_double>(data.GetData().value());
216 }
217 
CloudFileCacheStop(ani_env * env,ani_object object,ani_string uri,ani_boolean needClean)218 void CloudFileCacheAni::CloudFileCacheStop(ani_env *env, ani_object object, ani_string uri, ani_boolean needClean)
219 {
220     std::string uriInput;
221     ani_status ret = ANIUtils::AniString2String(env, uri, uriInput);
222     if (ret != ANI_OK) {
223         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
224         return;
225     }
226 
227     auto cloudFileCache = CloudFileCacheUnwrap(env, object);
228     if (cloudFileCache == nullptr) {
229         LOGE("Cannot wrap cloudFileCache.");
230         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
231         return;
232     }
233 
234     bool needCleanInput = needClean;
235 
236     auto data = cloudFileCache->DoStop(uriInput, needCleanInput);
237     if (!data.IsSuccess()) {
238         const auto &err = data.GetError();
239         LOGE("cloudFileCache do stop failed, ret = %{public}d", err.GetErrNo());
240         ErrorHandler::Throw(env, err);
241     }
242 }
243 
CloudFileCacheStopBatch(ani_env * env,ani_object object,ani_double taskId,ani_boolean needClean)244 void CloudFileCacheAni::CloudFileCacheStopBatch(ani_env *env,
245                                                 ani_object object,
246                                                 ani_double taskId,
247                                                 ani_boolean needClean)
248 {
249     auto cloudFileCache = CloudFileCacheUnwrap(env, object);
250     if (cloudFileCache == nullptr) {
251         LOGE("Cannot wrap cloudFileCache.");
252         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
253         return;
254     }
255 
256     bool needCleanInput = needClean;
257 
258     auto data = cloudFileCache->DoStop(static_cast<int64_t>(taskId), needCleanInput);
259     if (!data.IsSuccess()) {
260         const auto &err = data.GetError();
261         LOGE("cloudFileCache do stop failed, ret = %{public}d", err.GetErrNo());
262         ErrorHandler::Throw(env, err);
263     }
264 }
265 
CloudFileCacheCleanCache(ani_env * env,ani_object object,ani_string uri)266 void CloudFileCacheAni::CloudFileCacheCleanCache(ani_env *env, ani_object object, ani_string uri)
267 {
268     std::string uriInput;
269     ani_status ret = ANIUtils::AniString2String(env, uri, uriInput);
270     if (ret != ANI_OK) {
271         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
272         return;
273     }
274 
275     auto cloudFileCache = CloudFileCacheUnwrap(env, object);
276     if (cloudFileCache == nullptr) {
277         LOGE("Cannot wrap cloudFileCache.");
278         ErrorHandler::Throw(env, JsErrCode::E_IPCSS);
279         return;
280     }
281     auto data = cloudFileCache->CleanCache(uriInput);
282     if (!data.IsSuccess()) {
283         const auto &err = data.GetError();
284         LOGE("cloudFileCache do cleanCache failed, ret = %{public}d", err.GetErrNo());
285         ErrorHandler::Throw(env, err);
286     }
287 }
288 } // namespace OHOS::FileManagement::CloudSync