1 /*
2 * Copyright (c) 2022 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_download_callback_client.h"
17 #include "cloud_sync_manager_impl.h"
18 #include "cloud_sync_callback_client.h"
19 #include "cloud_sync_service_proxy.h"
20 #include "dfs_error.h"
21 #include "system_ability_definition.h"
22 #include "iservice_registry.h"
23 #include "utils_log.h"
24
25 namespace OHOS::FileManagement::CloudSync {
26 using namespace std;
27 constexpr int32_t MIN_USER_ID = 100;
28 constexpr int32_t MAX_FILE_CACHE_NUM = 400;
GetInstance()29 CloudSyncManagerImpl &CloudSyncManagerImpl::GetInstance()
30 {
31 static CloudSyncManagerImpl instance;
32 return instance;
33 }
34
RegisterCallback(const std::shared_ptr<CloudSyncCallback> callback,const std::string & bundleName)35 int32_t CloudSyncManagerImpl::RegisterCallback(const std::shared_ptr<CloudSyncCallback> callback,
36 const std::string &bundleName)
37 {
38 if (!callback) {
39 LOGE("callback is null");
40 return E_INVAL_ARG;
41 }
42 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
43 if (!CloudSyncServiceProxy) {
44 LOGE("proxy is null");
45 return E_SA_LOAD_FAILED;
46 }
47 auto ret = CloudSyncServiceProxy->RegisterCallbackInner(sptr(new (std::nothrow) CloudSyncCallbackClient(callback)),
48 bundleName);
49 {
50 unique_lock<mutex> lock(callbackMutex_);
51 callback_ = callback;
52 }
53 SubscribeListener(bundleName);
54 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
55 LOGI("RegisterCallback ret %{public}d", ret);
56 return ret;
57 }
58
UnRegisterCallback(const std::string & bundleName)59 int32_t CloudSyncManagerImpl::UnRegisterCallback(const std::string &bundleName)
60 {
61 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
62 if (!CloudSyncServiceProxy) {
63 LOGE("proxy is null");
64 return E_SA_LOAD_FAILED;
65 }
66
67 auto ret = CloudSyncServiceProxy->UnRegisterCallbackInner(bundleName);
68 if (!ret) {
69 {
70 unique_lock<mutex> lock(callbackMutex_);
71 callback_ = nullptr;
72 }
73 SubscribeListener();
74 }
75 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
76 LOGI("UnRegisterCallback ret %{public}d", ret);
77 return ret;
78 }
79
StartSync(const std::string & bundleName)80 int32_t CloudSyncManagerImpl::StartSync(const std::string &bundleName)
81 {
82 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
83 if (!CloudSyncServiceProxy) {
84 LOGE("proxy is null");
85 return E_SA_LOAD_FAILED;
86 }
87 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
88 return CloudSyncServiceProxy->StartSyncInner(true, bundleName);
89 }
90
GetSyncTime(int64_t & syncTime,const std::string & bundleName)91 int32_t CloudSyncManagerImpl::GetSyncTime(int64_t &syncTime, const std::string &bundleName)
92 {
93 LOGI("GetSyncTime Start");
94 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
95 if (!CloudSyncServiceProxy) {
96 LOGE("proxy is null");
97 return E_SA_LOAD_FAILED;
98 }
99 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
100 return CloudSyncServiceProxy->GetSyncTimeInner(syncTime, bundleName);
101 }
102
StartSync(bool forceFlag,const std::shared_ptr<CloudSyncCallback> callback)103 int32_t CloudSyncManagerImpl::StartSync(bool forceFlag, const std::shared_ptr<CloudSyncCallback> callback)
104 {
105 if (!callback) {
106 LOGE("callback is null");
107 return E_INVAL_ARG;
108 }
109 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
110 if (!CloudSyncServiceProxy) {
111 LOGE("proxy is null");
112 return E_SA_LOAD_FAILED;
113 }
114
115 if (!isFirstCall_.test()) {
116 LOGI("Register callback");
117 auto ret =
118 CloudSyncServiceProxy->RegisterCallbackInner(sptr(new (std::nothrow) CloudSyncCallbackClient(callback)));
119 if (ret) {
120 LOGE("Register callback failed");
121 isFirstCall_.clear();
122 return ret;
123 }
124 callback_ = callback;
125 SubscribeListener();
126 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
127 }
128
129 return CloudSyncServiceProxy->StartSyncInner(forceFlag);
130 }
131
TriggerSync(const std::string & bundleName,const int32_t & userId)132 int32_t CloudSyncManagerImpl::TriggerSync(const std::string &bundleName, const int32_t &userId)
133 {
134 if (bundleName.empty() || userId < MIN_USER_ID) {
135 LOGE("Trigger Sync parameter is invalid");
136 return E_INVAL_ARG;
137 }
138 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
139 if (!CloudSyncServiceProxy) {
140 LOGE("proxy is null");
141 return E_SA_LOAD_FAILED;
142 }
143 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
144 return CloudSyncServiceProxy->TriggerSyncInner(bundleName, userId);
145 }
146
StopSync(const std::string & bundleName,bool forceFlag)147 int32_t CloudSyncManagerImpl::StopSync(const std::string &bundleName, bool forceFlag)
148 {
149 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
150 if (!CloudSyncServiceProxy) {
151 LOGE("proxy is null");
152 return E_SA_LOAD_FAILED;
153 }
154 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
155 return CloudSyncServiceProxy->StopSyncInner(bundleName, forceFlag);
156 }
157
ResetCursor(const std::string & bundleName)158 int32_t CloudSyncManagerImpl::ResetCursor(const std::string &bundleName)
159 {
160 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
161 if (!CloudSyncServiceProxy) {
162 LOGE("proxy is null");
163 return E_SA_LOAD_FAILED;
164 }
165 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
166 return CloudSyncServiceProxy->ResetCursor(bundleName);
167 }
168
ChangeAppSwitch(const std::string & accoutId,const std::string & bundleName,bool status)169 int32_t CloudSyncManagerImpl::ChangeAppSwitch(const std::string &accoutId, const std::string &bundleName, bool status)
170 {
171 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
172 if (!CloudSyncServiceProxy) {
173 LOGE("proxy is null");
174 return E_SA_LOAD_FAILED;
175 }
176
177 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
178
179 int32_t ret = CloudSyncServiceProxy->ChangeAppSwitch(accoutId, bundleName, status);
180 LOGI("ChangeAppSwitch ret %{public}d", ret);
181 return ret;
182 }
183
NotifyDataChange(const std::string & accoutId,const std::string & bundleName)184 int32_t CloudSyncManagerImpl::NotifyDataChange(const std::string &accoutId, const std::string &bundleName)
185 {
186 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
187 if (!CloudSyncServiceProxy) {
188 LOGE("proxy is null");
189 return E_SA_LOAD_FAILED;
190 }
191
192 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
193
194 int32_t ret = CloudSyncServiceProxy->NotifyDataChange(accoutId, bundleName);
195 LOGI("NotifyDataChange ret %{public}d", ret);
196 return ret;
197 }
198
NotifyEventChange(int32_t userId,const std::string & eventId,const std::string & extraData)199 int32_t CloudSyncManagerImpl::NotifyEventChange(
200 int32_t userId, const std::string &eventId, const std::string &extraData)
201 {
202 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
203 if (!CloudSyncServiceProxy) {
204 LOGE("proxy is null");
205 return E_SA_LOAD_FAILED;
206 }
207
208 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
209
210 int32_t ret = CloudSyncServiceProxy->NotifyEventChange(userId, eventId, extraData);
211 LOGI("NotifyDataChange ret %{public}d", ret);
212 return ret;
213 }
214
StartDownloadFile(const std::string & uri)215 int32_t CloudSyncManagerImpl::StartDownloadFile(const std::string &uri)
216 {
217 LOGI("StartDownloadFile start");
218 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
219 if (!CloudSyncServiceProxy) {
220 LOGE("proxy is null");
221 return E_SA_LOAD_FAILED;
222 }
223 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
224 int32_t ret = CloudSyncServiceProxy->StartDownloadFile(uri);
225 LOGI("StartDownloadFile ret %{public}d", ret);
226 return ret;
227 }
228
StartFileCache(const std::string & uri)229 int32_t CloudSyncManagerImpl::StartFileCache(const std::string &uri)
230 {
231 LOGI("StartFileCache start");
232 int64_t downloadId = 0;
233 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
234 if (!CloudSyncServiceProxy) {
235 LOGE("proxy is null");
236 return E_SA_LOAD_FAILED;
237 }
238 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
239 std::vector<std::string> uriVec;
240 uriVec.push_back(uri);
241 int32_t ret = CloudSyncServiceProxy->StartFileCache(uriVec, downloadId);
242 LOGI("StartFileCache ret %{public}d", ret);
243 return ret;
244 }
245
StartFileCache(const std::vector<std::string> & uriVec,int64_t & downloadId)246 int32_t CloudSyncManagerImpl::StartFileCache(const std::vector<std::string> &uriVec, int64_t &downloadId)
247 {
248 LOGI("StartFileCache batch start, uriVec size: %{public}zu", uriVec.size());
249 if (uriVec.empty()) {
250 LOGE("StartFileCache, uri list is empty");
251 return E_INVAL_ARG;
252 }
253 if (uriVec.size() > MAX_FILE_CACHE_NUM) {
254 LOGE("StartFileCache, the size of uri list exceeded the maximum limit, size: %{public}zu", uriVec.size());
255 return E_EXCEED_MAX_SIZE;
256 }
257 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
258 if (!CloudSyncServiceProxy) {
259 LOGE("proxy is null");
260 return E_SA_LOAD_FAILED;
261 }
262 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
263 int32_t ret = CloudSyncServiceProxy->StartFileCache(uriVec, downloadId);
264 LOGI("StartFileCache batch ret %{public}d", ret);
265 return ret;
266 }
267
StopDownloadFile(const std::string & uri,bool needClean)268 int32_t CloudSyncManagerImpl::StopDownloadFile(const std::string &uri, bool needClean)
269 {
270 LOGI("StopDownloadFile start");
271 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
272 if (!CloudSyncServiceProxy) {
273 LOGE("proxy is null");
274 return E_SA_LOAD_FAILED;
275 }
276 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
277 int32_t ret = CloudSyncServiceProxy->StopDownloadFile(uri, needClean);
278 LOGI("StopDownloadFile ret %{public}d", ret);
279 return ret;
280 }
281
StopFileCache(const int64_t & downloadId,bool needClean)282 int32_t CloudSyncManagerImpl::StopFileCache(const int64_t &downloadId, bool needClean)
283 {
284 LOGI("StopFileCache start");
285 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
286 if (!CloudSyncServiceProxy) {
287 LOGE("proxy is null");
288 return E_SA_LOAD_FAILED;
289 }
290 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
291 int32_t ret = CloudSyncServiceProxy->StopFileCache(downloadId, needClean);
292 LOGI("StopFileCache ret %{public}d", ret);
293 return ret;
294 }
295
RegisterDownloadFileCallback(const std::shared_ptr<CloudDownloadCallback> downloadCallback)296 int32_t CloudSyncManagerImpl::RegisterDownloadFileCallback(
297 const std::shared_ptr<CloudDownloadCallback> downloadCallback)
298 {
299 LOGI("RegisterDownloadFileCallback start");
300 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
301 if (!CloudSyncServiceProxy) {
302 LOGE("proxy is null");
303 return E_SA_LOAD_FAILED;
304 }
305 {
306 unique_lock<mutex> lock(downloadMutex_);
307 auto dlCallback = sptr(new (std::nothrow) CloudDownloadCallbackClient(downloadCallback));
308 if (dlCallback == nullptr ||
309 CloudSyncServiceProxy->RegisterDownloadFileCallback(dlCallback) != E_OK) {
310 LOGE("register download callback failed");
311 } else {
312 downloadCallback_ = downloadCallback;
313 }
314 }
315 SubscribeListener();
316 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
317 return E_OK;
318 }
319
UnregisterDownloadFileCallback()320 int32_t CloudSyncManagerImpl::UnregisterDownloadFileCallback()
321 {
322 LOGI("UnregisterDownloadFileCallback start");
323 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
324 if (!CloudSyncServiceProxy) {
325 LOGE("proxy is null");
326 return E_SA_LOAD_FAILED;
327 }
328 int32_t ret = E_OK;
329 {
330 unique_lock<mutex> lock(downloadMutex_);
331 ret = CloudSyncServiceProxy->UnregisterDownloadFileCallback();
332 LOGI("UnregisterDownloadFileCallback ret %{public}d", ret);
333 if (ret == E_OK) {
334 downloadCallback_ = nullptr;
335 }
336 }
337 SubscribeListener();
338 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
339 return ret;
340 }
SetDeathRecipient(const sptr<IRemoteObject> & remoteObject)341 void CloudSyncManagerImpl::SetDeathRecipient(const sptr<IRemoteObject> &remoteObject)
342 {
343 if (!isFirstCall_.test_and_set()) {
344 auto deathCallback = [this](const wptr<IRemoteObject> &obj) {
345 LOGE("service died.");
346 CloudSyncServiceProxy::InvaildInstance();
347 if (callback_) {
348 callback_->OnSyncStateChanged(CloudSyncState::COMPLETED, ErrorType::NO_ERROR);
349 }
350 isFirstCall_.clear();
351 };
352 deathRecipient_ = sptr(new SvcDeathRecipient(deathCallback));
353 if (!remoteObject->AddDeathRecipient(deathRecipient_)) {
354 LOGE("add death recipient failed");
355 isFirstCall_.clear();
356 }
357 }
358 }
359
EnableCloud(const std::string & accoutId,const SwitchDataObj & switchData)360 int32_t CloudSyncManagerImpl::EnableCloud(const std::string &accoutId,
361 const SwitchDataObj &switchData)
362 {
363 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
364 if (!CloudSyncServiceProxy) {
365 LOGE("proxy is null");
366 return E_SA_LOAD_FAILED;
367 }
368
369 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
370
371 return CloudSyncServiceProxy->EnableCloud(accoutId, switchData);
372 }
373
DisableCloud(const std::string & accoutId)374 int32_t CloudSyncManagerImpl::DisableCloud(const std::string &accoutId)
375 {
376 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
377 if (!CloudSyncServiceProxy) {
378 LOGE("proxy is null");
379 return E_SA_LOAD_FAILED;
380 }
381
382 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
383 return CloudSyncServiceProxy->DisableCloud(accoutId);
384 }
385
Clean(const std::string & accountId,const CleanOptions & cleanOptions)386 int32_t CloudSyncManagerImpl::Clean(const std::string &accountId, const CleanOptions &cleanOptions)
387 {
388 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
389 if (!CloudSyncServiceProxy) {
390 LOGE("proxy is null");
391 return E_SA_LOAD_FAILED;
392 }
393
394 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
395
396 return CloudSyncServiceProxy->Clean(accountId, cleanOptions);
397 }
398
CleanCache(const std::string & uri)399 int32_t CloudSyncManagerImpl::CleanCache(const std::string &uri)
400 {
401 LOGI("CleanCache Start");
402 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
403 if (!CloudSyncServiceProxy) {
404 LOGE("proxy is null");
405 return E_SA_LOAD_FAILED;
406 }
407 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
408 return CloudSyncServiceProxy->CleanCacheInner(uri);
409 }
410
SubscribeListener(std::string bundleName)411 void CloudSyncManagerImpl::SubscribeListener(std::string bundleName)
412 {
413 unique_lock<mutex> lock(subscribeMutex_);
414 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
415 if (samgr == nullptr) {
416 LOGE("Samgr is nullptr");
417 return;
418 }
419 if (listener_ != nullptr) {
420 auto ret = samgr->UnSubscribeSystemAbility(FILEMANAGEMENT_CLOUD_SYNC_SERVICE_SA_ID, listener_);
421 LOGI("unsubscribed to systemAbility ret %{public}d", ret);
422 }
423 if (callback_ != nullptr || downloadCallback_ != nullptr) {
424 listener_ = new SystemAbilityStatusChange(bundleName);
425 auto ret = samgr->SubscribeSystemAbility(FILEMANAGEMENT_CLOUD_SYNC_SERVICE_SA_ID, listener_);
426 LOGI("subscribed to systemAbility ret %{public}d", ret);
427 } else {
428 listener_ = nullptr;
429 }
430 }
431
ResetProxyCallback(uint32_t retryCount,const string & bundleName)432 bool CloudSyncManagerImpl::ResetProxyCallback(uint32_t retryCount, const string &bundleName)
433 {
434 auto cloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
435 if (cloudSyncServiceProxy == nullptr) {
436 LOGE("proxy is null");
437 return false;
438 }
439 bool hasCallback = false;
440 {
441 unique_lock<mutex> downloadLock(downloadMutex_);
442 if (downloadCallback_ != nullptr) {
443 auto dlCallback = sptr(new (std::nothrow) CloudDownloadCallbackClient(downloadCallback_));
444 if (dlCallback == nullptr ||
445 cloudSyncServiceProxy->RegisterDownloadFileCallback(dlCallback) != E_OK) {
446 LOGW("register download callback failed, try time is %{public}d", retryCount);
447 } else {
448 hasCallback = true;
449 }
450 }
451 }
452 if (callback_ != nullptr) {
453 auto callback = sptr(new (std::nothrow) CloudSyncCallbackClient(callback_));
454 if (callback == nullptr ||
455 cloudSyncServiceProxy->RegisterCallbackInner(callback, bundleName) != E_OK) {
456 LOGW("register callback failed, try time is %{public}d", retryCount);
457 } else {
458 hasCallback = true;
459 }
460 }
461 if (hasCallback) {
462 CloudSyncManagerImpl::GetInstance().SetDeathRecipient(cloudSyncServiceProxy->AsObject());
463 }
464 return true;
465 }
466
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)467 void CloudSyncManagerImpl::SystemAbilityStatusChange::OnAddSystemAbility(int32_t systemAbilityId,
468 const std::string &deviceId)
469 {
470 const uint32_t RETRY_TIMES = 3;
471 const uint32_t SLEEP_TIME = 20 * 1000;
472 uint32_t retryCount = 0;
473 LOGI("saId %{public}d loaded", systemAbilityId);
474 do {
475 usleep(SLEEP_TIME);
476 if (!CloudSyncManagerImpl::GetInstance().ResetProxyCallback(retryCount, bundleName_)) {
477 continue;
478 }
479 return;
480 } while (++retryCount < RETRY_TIMES);
481 LOGE("register callback failed, try too many times");
482 }
483
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)484 void CloudSyncManagerImpl::SystemAbilityStatusChange::OnRemoveSystemAbility(int32_t systemAbilityId,
485 const std::string &deviceId)
486 {
487 return;
488 }
489 } // namespace OHOS::FileManagement::CloudSync
490