• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #define LOG_TAG "CloudServiceProxy"
16 #include "cloud_service_proxy.h"
17 
18 #include "itypes_util.h"
19 #include "logger.h"
20 
21 namespace OHOS::CloudData {
22 using namespace OHOS::Rdb;
23 
24 #define IPC_SEND(code, reply, ...)                                              \
25     ({                                                                          \
26         int32_t __status = SUCCESS;                                             \
27         do {                                                                    \
28             MessageParcel request;                                              \
29             if (!request.WriteInterfaceToken(GetDescriptor())) {                \
30                 __status = IPC_PARCEL_ERROR;                                    \
31                 break;                                                          \
32             }                                                                   \
33             if (!ITypesUtil::Marshal(request, ##__VA_ARGS__)) {                 \
34                 __status = IPC_PARCEL_ERROR;                                    \
35                 break;                                                          \
36             }                                                                   \
37             MessageOption option;                                               \
38             auto result = remote_->SendRequest((code), request, reply, option); \
39             if (result != 0) {                                                  \
40                 __status = IPC_ERROR;                                           \
41                 break;                                                          \
42             }                                                                   \
43                                                                                 \
44             ITypesUtil::Unmarshal(reply, __status);                             \
45         } while (0);                                                            \
46         __status;                                                               \
47     })
48 
CloudServiceProxy(const sptr<IRemoteObject> & object)49 CloudServiceProxy::CloudServiceProxy(const sptr<IRemoteObject> &object)
50     : IRemoteProxy<ICloudService>(object)
51 {
52     remote_ = Remote();
53 }
54 
EnableCloud(const std::string & id,const std::map<std::string,int32_t> & switches)55 int32_t CloudServiceProxy::EnableCloud(const std::string &id, const std::map<std::string, int32_t> &switches)
56 {
57     MessageParcel reply;
58     int32_t status = IPC_SEND(TRANS_ENABLE_CLOUD, reply, id, switches);
59     if (status != SUCCESS) {
60         LOG_ERROR("Status:0x%{public}x id:%{public}.6s size:%{public}zu", status, id.c_str(), switches.size());
61     }
62     return static_cast<Status>(status);
63 }
64 
DisableCloud(const std::string & id)65 int32_t CloudServiceProxy::DisableCloud(const std::string &id)
66 {
67     MessageParcel reply;
68     int32_t status = IPC_SEND(TRANS_DISABLE_CLOUD, reply, id);
69     if (status != SUCCESS) {
70         LOG_ERROR("Status:0x%{public}x id:%{public}.6s", status, id.c_str());
71     }
72     return static_cast<Status>(status);
73 }
74 
ChangeAppSwitch(const std::string & id,const std::string & bundleName,int32_t appSwitch)75 int32_t CloudServiceProxy::ChangeAppSwitch(const std::string &id, const std::string &bundleName, int32_t appSwitch)
76 {
77     MessageParcel reply;
78     int32_t status = IPC_SEND(TRANS_CHANGE_APP_SWITCH, reply, id, bundleName, appSwitch);
79     if (status != SUCCESS) {
80         LOG_ERROR("Status:0x%{public}x id:%{public}.6s bundleName:%{public}s switch:%{public}d", status, id.c_str(),
81             bundleName.c_str(), appSwitch);
82     }
83     return static_cast<Status>(status);
84 }
85 
Clean(const std::string & id,const std::map<std::string,int32_t> & actions)86 int32_t CloudServiceProxy::Clean(const std::string &id, const std::map<std::string, int32_t> &actions)
87 {
88     MessageParcel reply;
89     int32_t status = IPC_SEND(TRANS_CLEAN, reply, id, actions);
90     if (status != SUCCESS) {
91         LOG_ERROR("Status:0x%{public}x id:%{public}.6s size:%{public}zu", status, id.c_str(), actions.size());
92     }
93     return static_cast<Status>(status);
94 }
95 
NotifyDataChange(const std::string & id,const std::string & bundleName)96 int32_t CloudServiceProxy::NotifyDataChange(const std::string &id, const std::string &bundleName)
97 {
98     MessageParcel reply;
99     int32_t status = IPC_SEND(TRANS_NOTIFY_DATA_CHANGE, reply, id, bundleName);
100     if (status != SUCCESS) {
101         LOG_ERROR("Status:0x%{public}x id:%{public}.6s bundleName:%{public}s", status, id.c_str(), bundleName.c_str());
102     }
103     return static_cast<Status>(status);
104 }
105 
SetGlobalCloudStrategy(Strategy strategy,const std::vector<CommonType::Value> & values)106 int32_t CloudServiceProxy::SetGlobalCloudStrategy(Strategy strategy, const std::vector<CommonType::Value> &values)
107 {
108     MessageParcel reply;
109     int32_t status = IPC_SEND(TRANS_SET_GLOBAL_CLOUD_STRATEGY, reply, strategy, values);
110     if (status != SUCCESS) {
111         LOG_ERROR("Status:0x%{public}x strategy:%{public}d values size:%{public}zu", status,
112             static_cast<uint32_t>(strategy), values.size());
113     }
114     return static_cast<Status>(status);
115 }
116 
AllocResourceAndShare(const std::string & storeId,const DistributedRdb::PredicatesMemo & predicates,const std::vector<std::string> & columns,const std::vector<Participant> & participants)117 std::pair<int32_t, std::vector<NativeRdb::ValuesBucket>> CloudServiceProxy::AllocResourceAndShare(
118     const std::string &storeId, const DistributedRdb::PredicatesMemo &predicates,
119     const std::vector<std::string> &columns, const std::vector<Participant> &participants)
120 {
121     MessageParcel reply;
122     int32_t status = IPC_SEND(TRANS_ALLOC_RESOURCE_AND_SHARE, reply, storeId, predicates, columns, participants);
123     if (status != SUCCESS) {
124         LOG_ERROR("Status:0x%{public}x storeName:%{public}.6s", status, storeId.c_str());
125     }
126     std::vector<NativeRdb::ValuesBucket> valueBuckets;
127     ITypesUtil::Unmarshal(reply, valueBuckets);
128     return { static_cast<Status>(status), valueBuckets };
129 }
130 
NotifyDataChange(const std::string & eventId,const std::string & extraData,int32_t userId)131 int32_t CloudServiceProxy::NotifyDataChange(const std::string &eventId, const std::string &extraData, int32_t userId)
132 {
133     MessageParcel reply;
134     int32_t status = IPC_SEND(TRANS_NOTIFY_DATA_CHANGE_EXT, reply, eventId, extraData, userId);
135     if (status != SUCCESS) {
136         LOG_ERROR("Status:0x%{public}x eventId:%{public}.6s extraData:%{public}.6s", status, eventId.c_str(),
137             extraData.c_str());
138     }
139     return static_cast<Status>(status);
140 }
141 
QueryStatistics(const std::string & id,const std::string & bundleName,const std::string & storeId)142 std::pair<int32_t, std::map<std::string, StatisticInfos>> CloudServiceProxy::QueryStatistics(
143     const std::string &id, const std::string &bundleName, const std::string &storeId)
144 {
145     MessageParcel reply;
146     int32_t status = IPC_SEND(TRANS_QUERY_STATISTICS, reply, id, bundleName, storeId);
147     if (status != SUCCESS) {
148         LOG_ERROR(
149             "Status:0x%{public}x bundleName:%{public}.6s storeId:%{public}.6s", status, id.c_str(), storeId.c_str());
150     }
151     std::map<std::string, StatisticInfos> infos;
152     ITypesUtil::Unmarshal(reply, infos);
153     return { status, infos };
154 }
155 
Share(const std::string & sharingRes,const Participants & participants,Results & results)156 int32_t CloudServiceProxy::Share(const std::string &sharingRes, const Participants &participants, Results &results)
157 {
158     MessageParcel reply;
159     int32_t status = IPC_SEND(TRANS_SHARE, reply, sharingRes, participants);
160     if (status != SUCCESS) {
161         LOG_ERROR("Status:0x%{public}x sharingRes:%{public}.6s participants:%{public}zu", status, sharingRes.c_str(),
162             participants.size());
163     }
164     ITypesUtil::Unmarshal(reply, results);
165     return static_cast<Status>(status);
166 }
167 
Unshare(const std::string & sharingRes,const Participants & participants,Results & results)168 int32_t CloudServiceProxy::Unshare(const std::string &sharingRes, const Participants &participants, Results &results)
169 {
170     MessageParcel reply;
171     int32_t status = IPC_SEND(TRANS_UNSHARE, reply, sharingRes, participants);
172     if (status != SUCCESS) {
173         LOG_ERROR("Status:0x%{public}x sharingRes:%{public}.6s participants:%{public}zu", status, sharingRes.c_str(),
174             participants.size());
175     }
176     ITypesUtil::Unmarshal(reply, results);
177     return static_cast<Status>(status);
178 }
179 
Exit(const std::string & sharingRes,std::pair<int32_t,std::string> & result)180 int32_t CloudServiceProxy::Exit(const std::string &sharingRes, std::pair<int32_t, std::string> &result)
181 {
182     MessageParcel reply;
183     int32_t status = IPC_SEND(TRANS_EXIT, reply, sharingRes);
184     if (status != SUCCESS) {
185         LOG_ERROR("Status:0x%{public}x sharingRes:%{public}.6s", status, sharingRes.c_str());
186     }
187     ITypesUtil::Unmarshal(reply, result);
188     return static_cast<Status>(status);
189 }
190 
ChangePrivilege(const std::string & sharingRes,const Participants & participants,Results & results)191 int32_t CloudServiceProxy::ChangePrivilege(
192     const std::string &sharingRes, const Participants &participants, Results &results)
193 {
194     MessageParcel reply;
195     int32_t status = IPC_SEND(TRANS_CHANGE_PRIVILEGE, reply, sharingRes, participants);
196     if (status != SUCCESS) {
197         LOG_ERROR("Status:0x%{public}x sharingRes:%{public}.6s participants:%{public}zu", status, sharingRes.c_str(),
198             participants.size());
199     }
200     ITypesUtil::Unmarshal(reply, results);
201     return static_cast<Status>(status);
202 }
203 
Query(const std::string & sharingRes,QueryResults & results)204 int32_t CloudServiceProxy::Query(const std::string &sharingRes, QueryResults &results)
205 {
206     MessageParcel reply;
207     int32_t status = IPC_SEND(TRANS_QUERY, reply, sharingRes);
208     if (status != SUCCESS) {
209         LOG_ERROR("Status:0x%{public}x sharingRes:%{public}.6s", status, sharingRes.c_str());
210     }
211     ITypesUtil::Unmarshal(reply, results);
212     return static_cast<Status>(status);
213 }
214 
QueryByInvitation(const std::string & invitation,QueryResults & results)215 int32_t CloudServiceProxy::QueryByInvitation(const std::string &invitation, QueryResults &results)
216 {
217     MessageParcel reply;
218     int32_t status = IPC_SEND(TRANS_QUERY_BY_INVITATION, reply, invitation);
219     if (status != SUCCESS) {
220         LOG_ERROR("Status:0x%{public}x invitation:%{public}.6s", status, invitation.c_str());
221     }
222     ITypesUtil::Unmarshal(reply, results);
223     return static_cast<Status>(status);
224 }
225 
ConfirmInvitation(const std::string & invitation,int32_t confirmation,std::tuple<int32_t,std::string,std::string> & result)226 int32_t CloudServiceProxy::ConfirmInvitation(
227     const std::string &invitation, int32_t confirmation, std::tuple<int32_t, std::string, std::string> &result)
228 {
229     MessageParcel reply;
230     int32_t status = IPC_SEND(TRANS_CONFIRM_INVITATION, reply, invitation, confirmation);
231     if (status != SUCCESS) {
232         LOG_ERROR("Status:0x%{public}x invitation:%{public}.6s", status, invitation.c_str());
233     }
234     ITypesUtil::Unmarshal(reply, result);
235     return static_cast<Status>(status);
236 }
237 
ChangeConfirmation(const std::string & sharingRes,int32_t confirmation,std::pair<int32_t,std::string> & result)238 int32_t CloudServiceProxy::ChangeConfirmation(
239     const std::string &sharingRes, int32_t confirmation, std::pair<int32_t, std::string> &result)
240 {
241     MessageParcel reply;
242     int32_t status = IPC_SEND(TRANS_CHANGE_CONFIRMATION, reply, sharingRes, confirmation);
243     if (status != SUCCESS) {
244         LOG_ERROR("Status:0x%{public}x sharingRes:%{public}.6s", status, sharingRes.c_str());
245     }
246     ITypesUtil::Unmarshal(reply, result);
247     return static_cast<Status>(status);
248 }
249 
SetCloudStrategy(Strategy strategy,const std::vector<CommonType::Value> & values)250 int32_t CloudServiceProxy::SetCloudStrategy(Strategy strategy, const std::vector<CommonType::Value> &values)
251 {
252     MessageParcel reply;
253     int32_t status = IPC_SEND(TRANS_SET_CLOUD_STRATEGY, reply, strategy, values);
254     if (status != SUCCESS) {
255         LOG_ERROR("Status:0x%{public}x strategy:%{public}d values size:%{public}zu", status,
256             static_cast<uint32_t>(strategy), values.size());
257     }
258     return static_cast<Status>(status);
259 }
260 
QueryLastSyncInfo(const std::string & id,const std::string & bundleName,const std::string & storeId)261 std::pair<int32_t, QueryLastResults> CloudServiceProxy::QueryLastSyncInfo(
262     const std::string &id, const std::string &bundleName, const std::string &storeId)
263 {
264     MessageParcel reply;
265     int32_t status = IPC_SEND(TRANS_QUERY_LAST_SYNC_INFO, reply, id, bundleName, storeId);
266     if (status != SUCCESS) {
267         LOG_ERROR("Status:0x%{public}x id:%{public}.6s bundleName:%{public}s storeId:%{public}.3s", status, id.c_str(),
268             bundleName.c_str(), storeId.c_str());
269     }
270     QueryLastResults results;
271     ITypesUtil::Unmarshal(reply, results);
272     return { status, results };
273 }
274 
DoAsync(const std::string & bundleName,const std::string & storeId,Option option)275 int32_t CloudServiceProxy::DoAsync(const std::string &bundleName, const std::string &storeId, Option option)
276 {
277     MessageParcel reply;
278     int32_t status = IPC_SEND(TRANS_CLOUD_SYNC, reply, bundleName, storeId, option);
279     if (status != SUCCESS) {
280         LOG_ERROR(
281             "Status:0x%{public}x bundleName:%{public}s storeId:%{public}.3s syncMode:%{public}d seqNum:%{public}u",
282             status, bundleName.c_str(), storeId.c_str(), option.syncMode, option.seqNum);
283     }
284     return status;
285 }
286 
InitNotifier(sptr<IRemoteObject> notifier)287 int32_t CloudServiceProxy::InitNotifier(sptr<IRemoteObject> notifier)
288 {
289     MessageParcel reply;
290     int32_t status = IPC_SEND(TRANS_INIT_NOTIFIER, reply, notifier);
291     if (status != SUCCESS) {
292         LOG_ERROR("Status:0x%{public}x", status);
293     }
294     return status;
295 }
296 
InitNotifier()297 int32_t CloudServiceProxy::InitNotifier()
298 {
299     notifier_ = new (std::nothrow) CloudNotifierStub([this](uint32_t seqNum, Details &&result) {
300         OnSyncComplete(seqNum, std::move(result));
301     });
302     if (notifier_ == nullptr) {
303         LOG_ERROR("create notifier failed");
304         return ERROR;
305     }
306     auto status = InitNotifier(notifier_->AsObject());
307     if (status != SUCCESS) {
308         notifier_ = nullptr;
309         LOG_ERROR("init notifier failed.");
310         return status;
311     }
312     return SUCCESS;
313 }
314 
OnSyncComplete(uint32_t seqNum,Details && result)315 void CloudServiceProxy::OnSyncComplete(uint32_t seqNum, Details &&result)
316 {
317     syncCallbacks_.ComputeIfPresent(seqNum, [&result](const auto &key, const AsyncDetail &callback) {
318         auto finished = result.empty() || (result.begin()->second.progress == SYNC_FINISH);
319         if (callback != nullptr) {
320             callback(std::move(result));
321         }
322         return !finished;
323     });
324 }
325 
CloudSync(const std::string & bundleName,const std::string & storeId,const Option & option,const AsyncDetail & async)326 int32_t CloudServiceProxy::CloudSync(const std::string &bundleName, const std::string &storeId,
327     const Option &option, const AsyncDetail &async)
328 {
329     LOG_INFO("cloud sync start, bundleName = %{public}s, seqNum = %{public}u", bundleName.c_str(), option.seqNum);
330     if (bundleName.empty() || storeId.empty() || option.syncMode  < DistributedRdb::TIME_FIRST ||
331         option.syncMode  > DistributedRdb::CLOUD_FIRST || async == nullptr) {
332         LOG_ERROR("invalid args, bundleName = %{public}s", bundleName.c_str());
333         return INVALID_ARGUMENT;
334     }
335     if (!syncCallbacks_.Insert(option.seqNum, async)) {
336         LOG_ERROR("register progress failed, bundleName = %{public}s", bundleName.c_str());
337         return ERROR;
338     }
339     auto status = DoAsync(bundleName, storeId, option);
340     if (status != SUCCESS) {
341         syncCallbacks_.Erase(option.seqNum);
342     }
343     return status;
344 }
345 } // namespace OHOS::CloudData
346