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 #define LOG_TAG "KVDBServiceClient"
16 #include "kvdb_service_client.h"
17 #include <cinttypes>
18 #include "distributeddata_kvdb_ipc_interface_code.h"
19 #include "itypes_util.h"
20 #include "kvstore_observer_client.h"
21 #include "kvstore_service_death_notifier.h"
22 #include "log_print.h"
23 #include "security_manager.h"
24 #include "single_store_impl.h"
25 #include "store_factory.h"
26 #include "store_util.h"
27 namespace OHOS::DistributedKv {
28 #define IPC_SEND(code, reply, ...) \
29 ({ \
30 int32_t __status = SUCCESS; \
31 do { \
32 MessageParcel request; \
33 if (!request.WriteInterfaceToken(GetDescriptor())) { \
34 __status = IPC_PARCEL_ERROR; \
35 break; \
36 } \
37 if (!ITypesUtil::Marshal(request, ##__VA_ARGS__)) { \
38 __status = IPC_PARCEL_ERROR; \
39 break; \
40 } \
41 MessageOption option; \
42 auto result = remote_->SendRequest((code), request, reply, option); \
43 if (result != 0) { \
44 __status = IPC_ERROR; \
45 break; \
46 } \
47 \
48 ITypesUtil::Unmarshal(reply, __status); \
49 } while (0); \
50 __status; \
51 })
52
53 std::mutex KVDBServiceClient::mutex_;
54 std::shared_ptr<KVDBServiceClient> KVDBServiceClient::instance_;
55 std::atomic_bool KVDBServiceClient::isWatched_(false);
56
GetInstance()57 std::shared_ptr<KVDBServiceClient> KVDBServiceClient::GetInstance()
58 {
59 if (!isWatched_.exchange(true)) {
60 KvStoreServiceDeathNotifier::AddServiceDeathWatcher(std::make_shared<ServiceDeath>());
61 }
62
63 std::lock_guard<decltype(mutex_)> lockGuard(mutex_);
64 if (instance_ != nullptr) {
65 return instance_;
66 }
67
68 sptr<IKvStoreDataService> ability = KvStoreServiceDeathNotifier::GetDistributedKvDataService();
69 if (ability == nullptr) {
70 return nullptr;
71 }
72
73 sptr<IRemoteObject> service = ability->GetFeatureInterface("kv_store");
74 if (service == nullptr) {
75 return nullptr;
76 }
77
78 sptr<KVDBServiceClient> client = nullptr;
79 if (service->IsProxyObject()) {
80 client = iface_cast<KVDBServiceClient>(service);
81 }
82
83 if (client == nullptr) {
84 client = new (std::nothrow) KVDBServiceClient(service);
85 }
86
87 if (client == nullptr) {
88 return nullptr;
89 }
90
91 instance_.reset(client.GetRefPtr(), [client](auto *) mutable { client = nullptr; });
92 return instance_;
93 }
94
OnRemoteDied()95 void KVDBServiceClient::ServiceDeath::OnRemoteDied()
96 {
97 std::lock_guard<decltype(mutex_)> lockGuard(mutex_);
98 instance_ = nullptr;
99 }
100
KVDBServiceClient(const sptr<IRemoteObject> & handle)101 KVDBServiceClient::KVDBServiceClient(const sptr<IRemoteObject> &handle) : IRemoteProxy(handle)
102 {
103 remote_ = Remote();
104 }
105
GetStoreIds(const AppId & appId,int32_t subUser,std::vector<StoreId> & storeIds)106 Status KVDBServiceClient::GetStoreIds(const AppId &appId, int32_t subUser, std::vector<StoreId> &storeIds)
107 {
108 MessageParcel reply;
109 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_GET_STORE_IDS),
110 reply, appId, StoreId(), subUser);
111 if (status != SUCCESS) {
112 ZLOGE("status:0x%{public}x, appId:%{public}s", status, appId.appId.c_str());
113 }
114 ITypesUtil::Unmarshal(reply, storeIds);
115 return static_cast<Status>(status);
116 }
117
BeforeCreate(const AppId & appId,const StoreId & storeId,const Options & options)118 Status KVDBServiceClient::BeforeCreate(const AppId &appId, const StoreId &storeId, const Options &options)
119 {
120 MessageParcel reply;
121 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_BEFORE_CREATE),
122 reply, appId, storeId, options);
123 if (status != SUCCESS) {
124 ZLOGE("status:0x%{public}x appId:%{public}s, storeId:%{public}s", status, appId.appId.c_str(),
125 StoreUtil::Anonymous(storeId.storeId).c_str());
126 }
127 return static_cast<Status>(status);
128 }
129
AfterCreate(const AppId & appId,const StoreId & storeId,const Options & options,const std::vector<uint8_t> & password)130 Status KVDBServiceClient::AfterCreate(
131 const AppId &appId, const StoreId &storeId, const Options &options, const std::vector<uint8_t> &password)
132 {
133 MessageParcel reply;
134 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_AFTER_CREATE),
135 reply, appId, storeId, options, password);
136 if (status != SUCCESS) {
137 ZLOGE("status:0x%{public}x appId:%{public}s, storeId:%{public}s, encrypt:%{public}d", status,
138 appId.appId.c_str(), StoreUtil::Anonymous(storeId.storeId).c_str(), options.encrypt);
139 }
140 return static_cast<Status>(status);
141 }
142
Delete(const AppId & appId,const StoreId & storeId,int32_t subUser)143 Status KVDBServiceClient::Delete(const AppId &appId, const StoreId &storeId, int32_t subUser)
144 {
145 MessageParcel reply;
146 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_DELETE),
147 reply, appId, storeId, subUser);
148 if (status != SUCCESS) {
149 ZLOGE("status:0x%{public}x appId:%{public}s, storeId:%{public}s", status, appId.appId.c_str(),
150 StoreUtil::Anonymous(storeId.storeId).c_str());
151 }
152 return static_cast<Status>(status);
153 }
154
Close(const AppId & appId,const StoreId & storeId,int32_t subUser)155 Status KVDBServiceClient::Close(const AppId &appId, const StoreId &storeId, int32_t subUser)
156 {
157 MessageParcel reply;
158 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_CLOSE),
159 reply, appId, storeId, subUser);
160 if (status != SUCCESS) {
161 ZLOGE("status:0x%{public}x appId:%{public}s, storeId:%{public}s", status, appId.appId.c_str(),
162 StoreUtil::Anonymous(storeId.storeId).c_str());
163 }
164 return static_cast<Status>(status);
165 }
166
Sync(const AppId & appId,const StoreId & storeId,int32_t subUser,SyncInfo & syncInfo)167 Status KVDBServiceClient::Sync(const AppId &appId, const StoreId &storeId, int32_t subUser, SyncInfo &syncInfo)
168 {
169 MessageParcel reply;
170 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_SYNC), reply, appId, storeId,
171 syncInfo.seqId, syncInfo.mode, syncInfo.devices, syncInfo.delay, syncInfo.query, subUser);
172 if (status != SUCCESS) {
173 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s, sequenceId:%{public}" PRIu64, status,
174 appId.appId.c_str(), StoreUtil::Anonymous(storeId.storeId).c_str(), syncInfo.seqId);
175 }
176 return static_cast<Status>(status);
177 }
178
CloudSync(const AppId & appId,const StoreId & storeId,const SyncInfo & syncInfo)179 Status KVDBServiceClient::CloudSync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo)
180 {
181 MessageParcel reply;
182 int32_t status = IPC_SEND(
183 static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_CLOUD_SYNC), reply, appId, storeId, syncInfo.seqId);
184 if (status != SUCCESS) {
185 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s" PRIu64, status, appId.appId.c_str(),
186 StoreUtil::Anonymous(storeId.storeId).c_str());
187 }
188 return static_cast<Status>(status);
189 }
190
NotifyDataChange(const AppId & appId,const StoreId & storeId,uint64_t delay)191 Status KVDBServiceClient::NotifyDataChange(const AppId &appId, const StoreId &storeId, uint64_t delay)
192 {
193 MessageParcel reply;
194 int32_t status = IPC_SEND(
195 static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_NOTIFY_DATA_CHANGE), reply, appId, storeId, delay);
196 if (status != SUCCESS) {
197 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s",
198 status, appId.appId.c_str(), StoreUtil::Anonymous(storeId.storeId).c_str());
199 }
200 return static_cast<Status>(status);
201 }
202
RegServiceNotifier(const AppId & appId,sptr<IKVDBNotifier> notifier)203 Status KVDBServiceClient::RegServiceNotifier(const AppId &appId, sptr<IKVDBNotifier> notifier)
204 {
205 MessageParcel reply;
206 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_REGISTER_NOTIFIER), reply,
207 appId, StoreId(), notifier->AsObject().GetRefPtr());
208 if (status != SUCCESS) {
209 ZLOGE("status:0x%{public}x, appId:%{public}s, notifier:0x%{public}x", status, appId.appId.c_str(),
210 StoreUtil::Anonymous(notifier.GetRefPtr()));
211 }
212 return static_cast<Status>(status);
213 }
214
UnregServiceNotifier(const AppId & appId)215 Status KVDBServiceClient::UnregServiceNotifier(const AppId &appId)
216 {
217 MessageParcel reply;
218 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_UNREGISTER_NOTIFIER),
219 reply, appId, StoreId());
220 if (status != SUCCESS) {
221 ZLOGE("status:0x%{public}x, appId:%{public}s", status, appId.appId.c_str());
222 }
223 return static_cast<Status>(status);
224 }
225
SetSyncParam(const AppId & appId,const StoreId & storeId,int32_t subUser,const KvSyncParam & syncParam)226 Status KVDBServiceClient::SetSyncParam(const AppId &appId, const StoreId &storeId, int32_t subUser,
227 const KvSyncParam &syncParam)
228 {
229 MessageParcel reply;
230 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_SET_SYNC_PARAM), reply,
231 appId, storeId, syncParam.allowedDelayMs, subUser);
232 if (status != SUCCESS) {
233 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s", status, appId.appId.c_str(),
234 StoreUtil::Anonymous(storeId.storeId).c_str());
235 }
236 return static_cast<Status>(status);
237 }
238
GetSyncParam(const AppId & appId,const StoreId & storeId,int32_t subUser,KvSyncParam & syncParam)239 Status KVDBServiceClient::GetSyncParam(const AppId &appId, const StoreId &storeId, int32_t subUser,
240 KvSyncParam &syncParam)
241 {
242 MessageParcel reply;
243 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_GET_SYNC_PARAM),
244 reply, appId, storeId, subUser);
245 if (status != SUCCESS) {
246 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s", status, appId.appId.c_str(),
247 StoreUtil::Anonymous(storeId.storeId).c_str());
248 return SUCCESS;
249 }
250 ITypesUtil::Unmarshal(reply, syncParam.allowedDelayMs);
251 return static_cast<Status>(status);
252 }
253
EnableCapability(const AppId & appId,const StoreId & storeId,int32_t subUser)254 Status KVDBServiceClient::EnableCapability(const AppId &appId, const StoreId &storeId, int32_t subUser)
255 {
256 MessageParcel reply;
257 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_ENABLE_CAP),
258 reply, appId, storeId, subUser);
259 if (status != SUCCESS) {
260 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s", status, appId.appId.c_str(),
261 StoreUtil::Anonymous(storeId.storeId).c_str());
262 }
263 return static_cast<Status>(status);
264 }
265
DisableCapability(const AppId & appId,const StoreId & storeId,int32_t subUser)266 Status KVDBServiceClient::DisableCapability(const AppId &appId, const StoreId &storeId, int32_t subUser)
267 {
268 MessageParcel reply;
269 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_DISABLE_CAP),
270 reply, appId, storeId, subUser);
271 if (status != SUCCESS) {
272 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s", status, appId.appId.c_str(),
273 StoreUtil::Anonymous(storeId.storeId).c_str());
274 }
275 return static_cast<Status>(status);
276 }
277
SetCapability(const AppId & appId,const StoreId & storeId,int32_t subUser,const std::vector<std::string> & local,const std::vector<std::string> & remote)278 Status KVDBServiceClient::SetCapability(const AppId &appId, const StoreId &storeId, int32_t subUser,
279 const std::vector<std::string> &local, const std::vector<std::string> &remote)
280 {
281 MessageParcel reply;
282 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_SET_CAP),
283 reply, appId, storeId, local, remote, subUser);
284 if (status != SUCCESS) {
285 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s", status, appId.appId.c_str(),
286 StoreUtil::Anonymous(storeId.storeId).c_str());
287 }
288 return static_cast<Status>(status);
289 }
290
AddSubscribeInfo(const AppId & appId,const StoreId & storeId,int32_t subUser,const SyncInfo & syncInfo)291 Status KVDBServiceClient::AddSubscribeInfo(const AppId &appId, const StoreId &storeId, int32_t subUser,
292 const SyncInfo &syncInfo)
293 {
294 MessageParcel reply;
295 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_ADD_SUB),
296 reply, appId, storeId, syncInfo.seqId, syncInfo.devices, syncInfo.query, subUser);
297 if (status != SUCCESS) {
298 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s, query:%{public}s", status,
299 appId.appId.c_str(), StoreUtil::Anonymous(storeId.storeId).c_str(),
300 StoreUtil::Anonymous(syncInfo.query).c_str());
301 }
302 return static_cast<Status>(status);
303 }
304
RmvSubscribeInfo(const AppId & appId,const StoreId & storeId,int32_t subUser,const SyncInfo & syncInfo)305 Status KVDBServiceClient::RmvSubscribeInfo(const AppId &appId, const StoreId &storeId, int32_t subUser,
306 const SyncInfo &syncInfo)
307 {
308 MessageParcel reply;
309 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_RMV_SUB),
310 reply, appId, storeId, syncInfo.seqId, syncInfo.devices, syncInfo.query, subUser);
311 if (status != SUCCESS) {
312 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s, query:%{public}s", status,
313 appId.appId.c_str(), StoreUtil::Anonymous(storeId.storeId).c_str(),
314 StoreUtil::Anonymous(syncInfo.query).c_str());
315 }
316 return static_cast<Status>(status);
317 }
318
Subscribe(const AppId & appId,const StoreId & storeId,int32_t subUser,sptr<IKvStoreObserver> observer)319 Status KVDBServiceClient::Subscribe(const AppId &appId, const StoreId &storeId, int32_t subUser,
320 sptr<IKvStoreObserver> observer)
321 {
322 MessageParcel reply;
323 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_SUB),
324 reply, appId, storeId, observer->AsObject(), subUser);
325 if (status != SUCCESS) {
326 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s, observer:0x%{public}x", status,
327 appId.appId.c_str(), StoreUtil::Anonymous(storeId.storeId).c_str(),
328 StoreUtil::Anonymous(observer.GetRefPtr()));
329 }
330 return static_cast<Status>(status);
331 }
332
Unsubscribe(const AppId & appId,const StoreId & storeId,int32_t subUser,sptr<IKvStoreObserver> observer)333 Status KVDBServiceClient::Unsubscribe(const AppId &appId, const StoreId &storeId, int32_t subUser,
334 sptr<IKvStoreObserver> observer)
335 {
336 MessageParcel reply;
337 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_UNSUB),
338 reply, appId, storeId, observer->AsObject().GetRefPtr(), subUser);
339 if (status != SUCCESS) {
340 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s, observer:0x%{public}x", status,
341 appId.appId.c_str(), StoreUtil::Anonymous(storeId.storeId).c_str(),
342 StoreUtil::Anonymous(observer.GetRefPtr()));
343 }
344 return static_cast<Status>(status);
345 }
346
GetBackupPassword(const AppId & appId,const StoreId & storeId,int32_t subUser,std::vector<std::vector<uint8_t>> & passwords,int32_t passwordType)347 Status KVDBServiceClient::GetBackupPassword(const AppId &appId, const StoreId &storeId, int32_t subUser,
348 std::vector<std::vector<uint8_t>> &passwords, int32_t passwordType)
349 {
350 MessageParcel reply;
351 int32_t status = IPC_SEND(static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_GET_PASSWORD),
352 reply, appId, storeId, passwordType, subUser);
353 if (status != SUCCESS) {
354 ZLOGE("status:0x%{public}x appId:%{public}s, storeId:%{public}s", status,
355 appId.appId.c_str(), StoreUtil::Anonymous(storeId.storeId).c_str());
356 }
357 ITypesUtil::Unmarshal(reply, passwords);
358 return static_cast<Status>(status);
359 }
360
GetServiceAgent(const AppId & appId)361 sptr<KVDBNotifierClient> KVDBServiceClient::GetServiceAgent(const AppId &appId)
362 {
363 std::lock_guard<decltype(agentMtx_)> lockGuard(agentMtx_);
364 if (serviceAgent_ != nullptr) {
365 return serviceAgent_;
366 }
367
368 sptr<KVDBNotifierClient> serviceAgent = new (std::nothrow) KVDBNotifierClient();
369 if (serviceAgent == nullptr) {
370 ZLOGE("New KVDBNotifierClient failed, appId:%{public}s", appId.appId.c_str());
371 return nullptr;
372 }
373 auto status = RegServiceNotifier(appId, serviceAgent);
374 if (status == SUCCESS) {
375 serviceAgent_ = std::move(serviceAgent);
376 }
377 return serviceAgent_;
378 }
379
PutSwitch(const AppId & appId,const SwitchData & data)380 Status KVDBServiceClient::PutSwitch(const AppId &appId, const SwitchData &data)
381 {
382 MessageParcel reply;
383 int32_t status = IPC_SEND(
384 static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_PUT_SWITCH), reply, appId, StoreId(), data);
385 if (status != SUCCESS) {
386 ZLOGE("status:0x%{public}x, appId:%{public}s", status, appId.appId.c_str());
387 }
388 return static_cast<Status>(status);
389 }
390
GetSwitch(const AppId & appId,const std::string & networkId,SwitchData & data)391 Status KVDBServiceClient::GetSwitch(const AppId &appId, const std::string &networkId, SwitchData &data)
392 {
393 MessageParcel reply;
394 int32_t status = IPC_SEND(
395 static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_GET_SWITCH), reply, appId, StoreId(), networkId);
396 if (status != SUCCESS) {
397 ZLOGE("status:0x%{public}x, appId:%{public}s, networkId:%{public}s",
398 status, appId.appId.c_str(), StoreUtil::Anonymous(networkId).c_str());
399 }
400 ITypesUtil::Unmarshal(reply, data);
401 return static_cast<Status>(status);
402 }
403
SubscribeSwitchData(const AppId & appId)404 Status KVDBServiceClient::SubscribeSwitchData(const AppId &appId)
405 {
406 MessageParcel reply;
407 int32_t status = IPC_SEND(
408 static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_SUBSCRIBE_SWITCH_DATA), reply, appId, StoreId());
409 if (status != SUCCESS) {
410 ZLOGE("status:0x%{public}x, appId:%{public}s", status, appId.appId.c_str());
411 }
412 return static_cast<Status>(status);
413 }
414
UnsubscribeSwitchData(const AppId & appId)415 Status KVDBServiceClient::UnsubscribeSwitchData(const AppId &appId)
416 {
417 MessageParcel reply;
418 int32_t status = IPC_SEND(
419 static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_UNSUBSCRIBE_SWITCH_DATA), reply, appId, StoreId());
420 if (status != SUCCESS) {
421 ZLOGE("status:0x%{public}x, appId:%{public}s", status, appId.appId.c_str());
422 }
423 return static_cast<Status>(status);
424 }
425
SetConfig(const AppId & appId,const StoreId & storeId,const StoreConfig & storeConfig)426 Status KVDBServiceClient::SetConfig(const AppId &appId, const StoreId &storeId, const StoreConfig &storeConfig)
427 {
428 MessageParcel reply;
429 int32_t status = IPC_SEND(
430 static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_SET_CONFIG), reply, appId, storeId, storeConfig);
431 if (status != SUCCESS) {
432 ZLOGE("status:0x%{public}x appId:%{public}s, storeId:%{public}s", status,
433 appId.appId.c_str(), StoreUtil::Anonymous(storeId.storeId).c_str());
434 }
435 return static_cast<Status>(status);
436 }
437
RemoveDeviceData(const AppId & appId,const StoreId & storeId,int32_t subUser,const std::string & device)438 Status KVDBServiceClient::RemoveDeviceData(const AppId &appId, const StoreId &storeId, int32_t subUser,
439 const std::string &device)
440 {
441 MessageParcel reply;
442 int32_t status = IPC_SEND(
443 static_cast<uint32_t>(KVDBServiceInterfaceCode::TRANS_REMOVE_DEVICE_DATA), reply, appId, storeId, device,
444 subUser);
445 if (status != SUCCESS) {
446 ZLOGE("status:0x%{public}x appId:%{public}s, storeId:%{public}s", status,
447 appId.appId.c_str(), StoreUtil::Anonymous(storeId.storeId).c_str());
448 }
449 return static_cast<Status>(status);
450 }
451 } // namespace OHOS::DistributedKv