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 "CloudServiceStub"
16  #include "cloud_service_stub.h"
17  
18  #include "cloud/cloud_config_manager.h"
19  #include "cloud_types_util.h"
20  #include "ipc_skeleton.h"
21  #include "log_print.h"
22  #include "permission/permission_validator.h"
23  #include "rdb_types.h"
24  #include "tokenid_kit.h"
25  #include "utils/anonymous.h"
26  namespace OHOS::CloudData {
27  using namespace DistributedData;
28  using namespace OHOS::Security::AccessToken;
29  const CloudServiceStub::Handler CloudServiceStub::HANDLERS[TRANS_BUTT] = {
30      &CloudServiceStub::OnEnableCloud,
31      &CloudServiceStub::OnDisableCloud,
32      &CloudServiceStub::OnChangeAppSwitch,
33      &CloudServiceStub::OnClean,
34      &CloudServiceStub::OnNotifyDataChange,
35      &CloudServiceStub::OnNotifyChange,
36      &CloudServiceStub::OnQueryStatistics,
37      &CloudServiceStub::OnQueryLastSyncInfo,
38      &CloudServiceStub::OnSetGlobalCloudStrategy,
39      &CloudServiceStub::OnAllocResourceAndShare,
40      &CloudServiceStub::OnShare,
41      &CloudServiceStub::OnUnshare,
42      &CloudServiceStub::OnExit,
43      &CloudServiceStub::OnChangePrivilege,
44      &CloudServiceStub::OnQuery,
45      &CloudServiceStub::OnQueryByInvitation,
46      &CloudServiceStub::OnConfirmInvitation,
47      &CloudServiceStub::OnChangeConfirmation,
48      &CloudServiceStub::OnSetCloudStrategy,
49  };
50  
OnRemoteRequest(uint32_t code,OHOS::MessageParcel & data,OHOS::MessageParcel & reply)51  int CloudServiceStub::OnRemoteRequest(uint32_t code, OHOS::MessageParcel &data, OHOS::MessageParcel &reply)
52  {
53      ZLOGI("code:%{public}u callingPid:%{public}u", code, IPCSkeleton::GetCallingPid());
54      std::u16string local = CloudServiceStub::GetDescriptor();
55      std::u16string remote = data.ReadInterfaceToken();
56      if (local != remote) {
57          ZLOGE("local is not equal to remote");
58          return -1;
59      }
60  
61      if (TRANS_HEAD > code || code >= TRANS_BUTT || HANDLERS[code] == nullptr) {
62          ZLOGE("not support code:%{public}u, BUTT:%{public}d", code, TRANS_BUTT);
63          return -1;
64      }
65  
66      if (((code >= TRANS_CONFIG_HEAD && code < TRANS_CONFIG_BUTT) ||
67          (code >= TRANS_SHARE_HEAD && code < TRANS_SHARE_BUTT)) &&
68          !TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetCallingFullTokenID())) {
69          ZLOGE("permission denied! code:%{public}u", code);
70          auto result = static_cast<int32_t>(PERMISSION_DENIED);
71          return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
72      }
73  
74      if (code >= TRANS_CONFIG_HEAD && code < TRANS_CONFIG_BUTT &&
75          !DistributedKv::PermissionValidator::GetInstance().IsCloudConfigPermit(IPCSkeleton::GetCallingTokenID())) {
76          ZLOGE("cloud config permission denied! code:%{public}u, BUTT:%{public}d", code, TRANS_BUTT);
77          auto result = static_cast<int32_t>(CLOUD_CONFIG_PERMISSION_DENIED);
78          return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
79      }
80      return (this->*HANDLERS[code])(data, reply);
81  }
82  
OnEnableCloud(MessageParcel & data,MessageParcel & reply)83  int32_t CloudServiceStub::OnEnableCloud(MessageParcel &data, MessageParcel &reply)
84  {
85      std::string id;
86      std::map<std::string, int32_t> switches;
87      if (!ITypesUtil::Unmarshal(data, id, switches)) {
88          ZLOGE("Unmarshal id:%{public}s", Anonymous::Change(id).c_str());
89          return IPC_STUB_INVALID_DATA_ERR;
90      }
91      std::map<std::string, int32_t> localSwitches;
92      for (const auto &[bundle, status] : switches) {
93          localSwitches.insert_or_assign(CloudConfigManager::GetInstance().ToLocal(bundle), status);
94      }
95      auto result = EnableCloud(id, localSwitches);
96      return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
97  }
98  
OnDisableCloud(MessageParcel & data,MessageParcel & reply)99  int32_t CloudServiceStub::OnDisableCloud(MessageParcel &data, MessageParcel &reply)
100  {
101      std::string id;
102      if (!ITypesUtil::Unmarshal(data, id)) {
103          ZLOGE("Unmarshal id:%{public}s", Anonymous::Change(id).c_str());
104          return IPC_STUB_INVALID_DATA_ERR;
105      }
106      auto result = DisableCloud(id);
107      return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
108  }
109  
OnChangeAppSwitch(MessageParcel & data,MessageParcel & reply)110  int32_t CloudServiceStub::OnChangeAppSwitch(MessageParcel &data, MessageParcel &reply)
111  {
112      std::string id;
113      std::string bundleName;
114      int32_t appSwitch = SWITCH_OFF;
115      if (!ITypesUtil::Unmarshal(data, id, bundleName, appSwitch)) {
116          ZLOGE("Unmarshal id:%{public}s", Anonymous::Change(id).c_str());
117          return IPC_STUB_INVALID_DATA_ERR;
118      }
119      auto result = ChangeAppSwitch(id, CloudConfigManager::GetInstance().ToLocal(bundleName), appSwitch);
120      return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
121  }
122  
OnClean(MessageParcel & data,MessageParcel & reply)123  int32_t CloudServiceStub::OnClean(MessageParcel &data, MessageParcel &reply)
124  {
125      std::string id;
126      std::map<std::string, int32_t> actions;
127      if (!ITypesUtil::Unmarshal(data, id, actions)) {
128          ZLOGE("Unmarshal id:%{public}s", Anonymous::Change(id).c_str());
129          return IPC_STUB_INVALID_DATA_ERR;
130      }
131      std::map<std::string, int32_t> localActions;
132      for (const auto &[bundle, action] : actions) {
133          localActions.insert_or_assign(CloudConfigManager::GetInstance().ToLocal(bundle), action);
134      }
135      auto result = Clean(id, localActions);
136      return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
137  }
138  
OnNotifyDataChange(MessageParcel & data,MessageParcel & reply)139  int32_t CloudServiceStub::OnNotifyDataChange(MessageParcel &data, MessageParcel &reply)
140  {
141      std::string id;
142      std::string bundleName;
143      if (!ITypesUtil::Unmarshal(data, id, bundleName)) {
144          ZLOGE("Unmarshal id:%{public}s", Anonymous::Change(id).c_str());
145          return IPC_STUB_INVALID_DATA_ERR;
146      }
147      auto result = NotifyDataChange(id, CloudConfigManager::GetInstance().ToLocal(bundleName));
148      return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
149  }
150  
OnQueryLastSyncInfo(MessageParcel & data,MessageParcel & reply)151  int32_t CloudServiceStub::OnQueryLastSyncInfo(MessageParcel &data, MessageParcel &reply)
152  {
153      std::string id;
154      std::string bundleName;
155      std::string storeId;
156      if (!ITypesUtil::Unmarshal(data, id, bundleName, storeId)) {
157          ZLOGE("Unmarshal id:%{public}s, bundleName:%{public}s, storeId:%{public}s", Anonymous::Change(id).c_str(),
158              bundleName.c_str(), Anonymous::Change(storeId).c_str());
159          return IPC_STUB_INVALID_DATA_ERR;
160      }
161      auto [status, results] = QueryLastSyncInfo(id, bundleName, storeId);
162      return ITypesUtil::Marshal(reply, status, results) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
163  }
164  
OnSetGlobalCloudStrategy(MessageParcel & data,MessageParcel & reply)165  int32_t CloudServiceStub::OnSetGlobalCloudStrategy(MessageParcel &data, MessageParcel &reply)
166  {
167      Strategy strategy;
168      std::vector<CommonType::Value> values;
169      if (!ITypesUtil::Unmarshal(data, strategy, values)) {
170          ZLOGE("Unmarshal strategy:%{public}d, values size:%{public}zu", strategy, values.size());
171          return IPC_STUB_INVALID_DATA_ERR;
172      }
173      auto status = SetGlobalCloudStrategy(strategy, values);
174      return ITypesUtil::Marshal(reply, status) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
175  }
176  
OnAllocResourceAndShare(MessageParcel & data,MessageParcel & reply)177  int32_t CloudServiceStub::OnAllocResourceAndShare(MessageParcel &data, MessageParcel &reply)
178  {
179      std::string storeId;
180      DistributedRdb::PredicatesMemo predicatesMemo;
181      std::vector<std::string> columns;
182      std::vector<Participant> participants;
183      if (!ITypesUtil::Unmarshal(data, storeId, predicatesMemo, columns, participants)) {
184          ZLOGE("Unmarshal storeId:%{public}s", Anonymous::Change(storeId).c_str());
185          return IPC_STUB_INVALID_DATA_ERR;
186      }
187      auto [status, resultSet] = AllocResourceAndShare(storeId, predicatesMemo, columns, participants);
188      return ITypesUtil::Marshal(reply, status, resultSet) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
189  }
190  
OnNotifyChange(MessageParcel & data,MessageParcel & reply)191  int32_t CloudServiceStub::OnNotifyChange(MessageParcel &data, MessageParcel &reply)
192  {
193      std::string eventId;
194      std::string extraData;
195      int32_t userId;
196      if (!ITypesUtil::Unmarshal(data, eventId, extraData, userId)) {
197          ZLOGE("Unmarshal eventId:%{public}s", Anonymous::Change(eventId).c_str());
198          return IPC_STUB_INVALID_DATA_ERR;
199      }
200      auto result = NotifyDataChange(eventId, extraData, userId);
201      return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
202  }
203  
OnQueryStatistics(MessageParcel & data,MessageParcel & reply)204  int32_t CloudServiceStub::OnQueryStatistics(MessageParcel &data, MessageParcel &reply)
205  {
206      std::string id;
207      std::string bundleName;
208      std::string storeId;
209      if (!ITypesUtil::Unmarshal(data, id, bundleName, storeId)) {
210          ZLOGE("Unmarshal id:%{public}s", Anonymous::Change(id).c_str());
211          return IPC_STUB_INVALID_DATA_ERR;
212      }
213      auto result = QueryStatistics(id, bundleName, storeId);
214      return ITypesUtil::Marshal(reply, result.first, result.second) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
215  }
216  
OnShare(MessageParcel & data,MessageParcel & reply)217  int32_t CloudServiceStub::OnShare(MessageParcel &data, MessageParcel &reply)
218  {
219      std::string sharingRes;
220      Participants participants;
221      if (!ITypesUtil::Unmarshal(data, sharingRes, participants)) {
222          ZLOGE("Unmarshal sharingRes:%{public}s", Anonymous::Change(sharingRes).c_str());
223          return IPC_STUB_INVALID_DATA_ERR;
224      }
225      Results results;
226      auto status = Share(sharingRes, participants, results);
227      return ITypesUtil::Marshal(reply, status, results) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
228  }
229  
OnUnshare(MessageParcel & data,MessageParcel & reply)230  int32_t CloudServiceStub::OnUnshare(MessageParcel &data, MessageParcel &reply)
231  {
232      std::string sharingRes;
233      Participants participants;
234      if (!ITypesUtil::Unmarshal(data, sharingRes, participants)) {
235          ZLOGE("Unmarshal sharingRes:%{public}s", Anonymous::Change(sharingRes).c_str());
236          return IPC_STUB_INVALID_DATA_ERR;
237      }
238      Results results;
239      auto status = Unshare(sharingRes, participants, results);
240      return ITypesUtil::Marshal(reply, status, results) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
241  }
242  
OnExit(MessageParcel & data,MessageParcel & reply)243  int32_t CloudServiceStub::OnExit(MessageParcel &data, MessageParcel &reply)
244  {
245      std::string sharingRes;
246      if (!ITypesUtil::Unmarshal(data, sharingRes)) {
247          ZLOGE("Unmarshal sharingRes:%{public}s", Anonymous::Change(sharingRes).c_str());
248          return IPC_STUB_INVALID_DATA_ERR;
249      }
250      std::pair<int32_t, std::string> result;
251      auto status = Exit(sharingRes, result);
252      return ITypesUtil::Marshal(reply, status, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
253  }
254  
OnChangePrivilege(MessageParcel & data,MessageParcel & reply)255  int32_t CloudServiceStub::OnChangePrivilege(MessageParcel &data, MessageParcel &reply)
256  {
257      std::string sharingRes;
258      Participants participants;
259      if (!ITypesUtil::Unmarshal(data, sharingRes, participants)) {
260          ZLOGE("Unmarshal sharingRes:%{public}s", Anonymous::Change(sharingRes).c_str());
261          return IPC_STUB_INVALID_DATA_ERR;
262      }
263      Results results;
264      auto status = ChangePrivilege(sharingRes, participants, results);
265      return ITypesUtil::Marshal(reply, status, results) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
266  }
267  
OnQuery(MessageParcel & data,MessageParcel & reply)268  int32_t CloudServiceStub::OnQuery(MessageParcel &data, MessageParcel &reply)
269  {
270      std::string sharingRes;
271      if (!ITypesUtil::Unmarshal(data, sharingRes)) {
272          ZLOGE("Unmarshal sharingRes:%{public}s", Anonymous::Change(sharingRes).c_str());
273          return IPC_STUB_INVALID_DATA_ERR;
274      }
275      QueryResults results;
276      auto status = Query(sharingRes, results);
277      return ITypesUtil::Marshal(reply, status, results) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
278  }
279  
OnQueryByInvitation(MessageParcel & data,MessageParcel & reply)280  int32_t CloudServiceStub::OnQueryByInvitation(MessageParcel &data, MessageParcel &reply)
281  {
282      std::string invitation;
283      if (!ITypesUtil::Unmarshal(data, invitation)) {
284          ZLOGE("Unmarshal invitation:%{public}s", Anonymous::Change(invitation).c_str());
285          return IPC_STUB_INVALID_DATA_ERR;
286      }
287      QueryResults results;
288      auto status = QueryByInvitation(invitation, results);
289      return ITypesUtil::Marshal(reply, status, results) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
290  }
291  
OnConfirmInvitation(MessageParcel & data,MessageParcel & reply)292  int32_t CloudServiceStub::OnConfirmInvitation(MessageParcel &data, MessageParcel &reply)
293  {
294      std::string invitation;
295      int32_t confirmation;
296      if (!ITypesUtil::Unmarshal(data, invitation, confirmation)) {
297          ZLOGE("Unmarshal invitation:%{public}s", Anonymous::Change(invitation).c_str());
298          return IPC_STUB_INVALID_DATA_ERR;
299      }
300      std::tuple<int32_t, std::string, std::string> result;
301      auto status = ConfirmInvitation(invitation, confirmation, result);
302      return ITypesUtil::Marshal(reply, status, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
303  }
304  
OnChangeConfirmation(MessageParcel & data,MessageParcel & reply)305  int32_t CloudServiceStub::OnChangeConfirmation(MessageParcel &data, MessageParcel &reply)
306  {
307      std::string sharingRes;
308      int32_t confirmation;
309      if (!ITypesUtil::Unmarshal(data, sharingRes, confirmation)) {
310          ZLOGE("Unmarshal sharingRes:%{public}s", Anonymous::Change(sharingRes).c_str());
311          return IPC_STUB_INVALID_DATA_ERR;
312      }
313      std::pair<int32_t, std::string> result;
314      auto status = ChangeConfirmation(sharingRes, confirmation, result);
315      return ITypesUtil::Marshal(reply, status, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
316  }
317  
OnSetCloudStrategy(MessageParcel & data,MessageParcel & reply)318  int32_t CloudServiceStub::OnSetCloudStrategy(MessageParcel &data, MessageParcel &reply)
319  {
320      Strategy strategy;
321      std::vector<CommonType::Value> values;
322      if (!ITypesUtil::Unmarshal(data, strategy, values)) {
323          ZLOGE("Unmarshal strategy:%{public}d, values size:%{public}zu", strategy, values.size());
324          return IPC_STUB_INVALID_DATA_ERR;
325      }
326      auto status = SetCloudStrategy(strategy, values);
327      return ITypesUtil::Marshal(reply, status) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
328  }
329  } // namespace OHOS::CloudData