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,std::bitset<FIELD_KEY_MAX_SIZE> fieldkey,const std::shared_ptr<CloudDownloadCallback> downloadCallback)246 int32_t CloudSyncManagerImpl::StartFileCache(const std::vector<std::string> &uriVec,
247 int64_t &downloadId, std::bitset<FIELD_KEY_MAX_SIZE> fieldkey,
248 const std::shared_ptr<CloudDownloadCallback> downloadCallback)
249 {
250 LOGI("StartFileCache batch start, uriVec size: %{public}zu, fieldKey: %{public}llu, Callback is null: %{public}d",
251 uriVec.size(), static_cast<unsigned long long>(fieldkey.to_ulong()), (downloadCallback == nullptr));
252 if (uriVec.empty()) {
253 LOGE("StartFileCache, uri list is empty");
254 return E_INVAL_ARG;
255 }
256 if (uriVec.size() > MAX_FILE_CACHE_NUM) {
257 LOGE("StartFileCache, the size of uri list exceeded the maximum limit, size: %{public}zu", uriVec.size());
258 return E_EXCEED_MAX_SIZE;
259 }
260 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
261 if (!CloudSyncServiceProxy) {
262 LOGE("proxy is null");
263 return E_SA_LOAD_FAILED;
264 }
265 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
266
267 bool isCallbackValid = false;
268 sptr<CloudDownloadCallbackClient> dlCallback = nullptr;
269 if (downloadCallback != nullptr) {
270 dlCallback = sptr(new (std::nothrow) CloudDownloadCallbackClient(downloadCallback));
271 isCallbackValid = true;
272 if (dlCallback == nullptr) {
273 LOGE("register download callback failed");
274 isCallbackValid = false;
275 }
276 }
277
278 int32_t ret = CloudSyncServiceProxy->StartFileCache(uriVec, downloadId, fieldkey, isCallbackValid, dlCallback);
279 LOGI("StartFileCache batch ret %{public}d", ret);
280 return ret;
281 }
282
StopDownloadFile(const std::string & uri,bool needClean)283 int32_t CloudSyncManagerImpl::StopDownloadFile(const std::string &uri, bool needClean)
284 {
285 LOGI("StopDownloadFile start");
286 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
287 if (!CloudSyncServiceProxy) {
288 LOGE("proxy is null");
289 return E_SA_LOAD_FAILED;
290 }
291 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
292 int32_t ret = CloudSyncServiceProxy->StopDownloadFile(uri, needClean);
293 LOGI("StopDownloadFile ret %{public}d", ret);
294 return ret;
295 }
296
StopFileCache(const int64_t & downloadId,bool needClean)297 int32_t CloudSyncManagerImpl::StopFileCache(const int64_t &downloadId, bool needClean)
298 {
299 LOGI("StopFileCache start");
300 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
301 if (!CloudSyncServiceProxy) {
302 LOGE("proxy is null");
303 return E_SA_LOAD_FAILED;
304 }
305 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
306 int32_t ret = CloudSyncServiceProxy->StopFileCache(downloadId, needClean);
307 LOGI("StopFileCache ret %{public}d", ret);
308 return ret;
309 }
310
RegisterDownloadFileCallback(const std::shared_ptr<CloudDownloadCallback> downloadCallback)311 int32_t CloudSyncManagerImpl::RegisterDownloadFileCallback(
312 const std::shared_ptr<CloudDownloadCallback> downloadCallback)
313 {
314 LOGI("RegisterDownloadFileCallback start");
315 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
316 if (!CloudSyncServiceProxy) {
317 LOGE("proxy is null");
318 return E_SA_LOAD_FAILED;
319 }
320 {
321 unique_lock<mutex> lock(downloadMutex_);
322 auto dlCallback = sptr(new (std::nothrow) CloudDownloadCallbackClient(downloadCallback));
323 if (dlCallback == nullptr ||
324 CloudSyncServiceProxy->RegisterDownloadFileCallback(dlCallback) != E_OK) {
325 LOGE("register download callback failed");
326 } else {
327 downloadCallback_ = downloadCallback;
328 }
329 }
330 SubscribeListener();
331 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
332 return E_OK;
333 }
334
UnregisterDownloadFileCallback()335 int32_t CloudSyncManagerImpl::UnregisterDownloadFileCallback()
336 {
337 LOGI("UnregisterDownloadFileCallback start");
338 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
339 if (!CloudSyncServiceProxy) {
340 LOGE("proxy is null");
341 return E_SA_LOAD_FAILED;
342 }
343 int32_t ret = E_OK;
344 {
345 unique_lock<mutex> lock(downloadMutex_);
346 ret = CloudSyncServiceProxy->UnregisterDownloadFileCallback();
347 LOGI("UnregisterDownloadFileCallback ret %{public}d", ret);
348 if (ret == E_OK) {
349 downloadCallback_ = nullptr;
350 }
351 }
352 SubscribeListener();
353 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
354 return ret;
355 }
SetDeathRecipient(const sptr<IRemoteObject> & remoteObject)356 void CloudSyncManagerImpl::SetDeathRecipient(const sptr<IRemoteObject> &remoteObject)
357 {
358 if (!isFirstCall_.test_and_set()) {
359 auto deathCallback = [this](const wptr<IRemoteObject> &obj) {
360 LOGE("service died.");
361 CloudSyncServiceProxy::InvaildInstance();
362 if (callback_) {
363 callback_->OnSyncStateChanged(CloudSyncState::COMPLETED, ErrorType::NO_ERROR);
364 }
365 isFirstCall_.clear();
366 };
367 deathRecipient_ = sptr(new SvcDeathRecipient(deathCallback));
368 if (!remoteObject->AddDeathRecipient(deathRecipient_)) {
369 LOGE("add death recipient failed");
370 isFirstCall_.clear();
371 }
372 }
373 }
374
EnableCloud(const std::string & accoutId,const SwitchDataObj & switchData)375 int32_t CloudSyncManagerImpl::EnableCloud(const std::string &accoutId,
376 const SwitchDataObj &switchData)
377 {
378 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
379 if (!CloudSyncServiceProxy) {
380 LOGE("proxy is null");
381 return E_SA_LOAD_FAILED;
382 }
383
384 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
385
386 return CloudSyncServiceProxy->EnableCloud(accoutId, switchData);
387 }
388
DisableCloud(const std::string & accoutId)389 int32_t CloudSyncManagerImpl::DisableCloud(const std::string &accoutId)
390 {
391 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
392 if (!CloudSyncServiceProxy) {
393 LOGE("proxy is null");
394 return E_SA_LOAD_FAILED;
395 }
396
397 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
398 return CloudSyncServiceProxy->DisableCloud(accoutId);
399 }
400
Clean(const std::string & accountId,const CleanOptions & cleanOptions)401 int32_t CloudSyncManagerImpl::Clean(const std::string &accountId, const CleanOptions &cleanOptions)
402 {
403 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
404 if (!CloudSyncServiceProxy) {
405 LOGE("proxy is null");
406 return E_SA_LOAD_FAILED;
407 }
408
409 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
410
411 return CloudSyncServiceProxy->Clean(accountId, cleanOptions);
412 }
413
CleanCache(const std::string & uri)414 int32_t CloudSyncManagerImpl::CleanCache(const std::string &uri)
415 {
416 LOGI("CleanCache Start");
417 auto CloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
418 if (!CloudSyncServiceProxy) {
419 LOGE("proxy is null");
420 return E_SA_LOAD_FAILED;
421 }
422 SetDeathRecipient(CloudSyncServiceProxy->AsObject());
423 return CloudSyncServiceProxy->CleanCacheInner(uri);
424 }
425
SubscribeListener(std::string bundleName)426 void CloudSyncManagerImpl::SubscribeListener(std::string bundleName)
427 {
428 unique_lock<mutex> lock(subscribeMutex_);
429 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
430 if (samgr == nullptr) {
431 LOGE("Samgr is nullptr");
432 return;
433 }
434 if (listener_ != nullptr) {
435 auto ret = samgr->UnSubscribeSystemAbility(FILEMANAGEMENT_CLOUD_SYNC_SERVICE_SA_ID, listener_);
436 LOGI("unsubscribed to systemAbility ret %{public}d", ret);
437 }
438 if (callback_ != nullptr || downloadCallback_ != nullptr) {
439 listener_ = new SystemAbilityStatusChange(bundleName);
440 auto ret = samgr->SubscribeSystemAbility(FILEMANAGEMENT_CLOUD_SYNC_SERVICE_SA_ID, listener_);
441 LOGI("subscribed to systemAbility ret %{public}d", ret);
442 } else {
443 listener_ = nullptr;
444 }
445 }
446
ResetProxyCallback(uint32_t retryCount,const string & bundleName)447 bool CloudSyncManagerImpl::ResetProxyCallback(uint32_t retryCount, const string &bundleName)
448 {
449 auto cloudSyncServiceProxy = CloudSyncServiceProxy::GetInstance();
450 if (cloudSyncServiceProxy == nullptr) {
451 LOGE("proxy is null");
452 return false;
453 }
454 bool hasCallback = false;
455 {
456 unique_lock<mutex> downloadLock(downloadMutex_);
457 if (downloadCallback_ != nullptr) {
458 auto dlCallback = sptr(new (std::nothrow) CloudDownloadCallbackClient(downloadCallback_));
459 if (dlCallback == nullptr ||
460 cloudSyncServiceProxy->RegisterDownloadFileCallback(dlCallback) != E_OK) {
461 LOGW("register download callback failed, try time is %{public}d", retryCount);
462 } else {
463 hasCallback = true;
464 }
465 }
466 }
467 if (callback_ != nullptr) {
468 auto callback = sptr(new (std::nothrow) CloudSyncCallbackClient(callback_));
469 if (callback == nullptr ||
470 cloudSyncServiceProxy->RegisterCallbackInner(callback, bundleName) != E_OK) {
471 LOGW("register callback failed, try time is %{public}d", retryCount);
472 } else {
473 hasCallback = true;
474 }
475 }
476 if (hasCallback) {
477 CloudSyncManagerImpl::GetInstance().SetDeathRecipient(cloudSyncServiceProxy->AsObject());
478 }
479 return true;
480 }
481
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)482 void CloudSyncManagerImpl::SystemAbilityStatusChange::OnAddSystemAbility(int32_t systemAbilityId,
483 const std::string &deviceId)
484 {
485 const uint32_t RETRY_TIMES = 3;
486 const uint32_t SLEEP_TIME = 20 * 1000;
487 uint32_t retryCount = 0;
488 LOGI("saId %{public}d loaded", systemAbilityId);
489 do {
490 usleep(SLEEP_TIME);
491 if (!CloudSyncManagerImpl::GetInstance().ResetProxyCallback(retryCount, bundleName_)) {
492 continue;
493 }
494 return;
495 } while (++retryCount < RETRY_TIMES);
496 LOGE("register callback failed, try too many times");
497 }
498
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)499 void CloudSyncManagerImpl::SystemAbilityStatusChange::OnRemoveSystemAbility(int32_t systemAbilityId,
500 const std::string &deviceId)
501 {
502 return;
503 }
504 } // namespace OHOS::FileManagement::CloudSync
505