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 "itypes_util.h"
19 #include "kvstore_observer_client.h"
20 #include "kvstore_service_death_notifier.h"
21 #include "log_print.h"
22 #include "security_manager.h"
23 #include "single_store_impl.h"
24 #include "store_factory.h"
25 #include "store_util.h"
26 namespace OHOS::DistributedKv {
27 #define IPC_SEND(code, reply, ...) \
28 ({ \
29 int32_t __status = SUCCESS; \
30 do { \
31 MessageParcel request; \
32 if (!request.WriteInterfaceToken(GetDescriptor())) { \
33 __status = IPC_PARCEL_ERROR; \
34 break; \
35 } \
36 if (!ITypesUtil::Marshal(request, ##__VA_ARGS__)) { \
37 __status = IPC_PARCEL_ERROR; \
38 break; \
39 } \
40 MessageOption option; \
41 auto result = remote_->SendRequest((code), request, reply, option); \
42 if (result != 0) { \
43 __status = IPC_ERROR; \
44 break; \
45 } \
46 \
47 ITypesUtil::Unmarshal(reply, __status); \
48 } while (0); \
49 __status; \
50 })
51
52 std::mutex KVDBServiceClient::mutex_;
53 std::shared_ptr<KVDBServiceClient> KVDBServiceClient::instance_;
54 std::atomic_bool KVDBServiceClient::isWatched_(false);
55
GetInstance()56 std::shared_ptr<KVDBServiceClient> KVDBServiceClient::GetInstance()
57 {
58 if (!isWatched_.exchange(true)) {
59 KvStoreServiceDeathNotifier::AddServiceDeathWatcher(std::make_shared<ServiceDeath>());
60 }
61
62 std::lock_guard<decltype(mutex_)> lockGuard(mutex_);
63 if (instance_ != nullptr) {
64 return instance_;
65 }
66
67 sptr<IKvStoreDataService> ability = KvStoreServiceDeathNotifier::GetDistributedKvDataService();
68 if (ability == nullptr) {
69 return nullptr;
70 }
71
72 sptr<IRemoteObject> service = ability->GetFeatureInterface("kv_store");
73 if (service == nullptr) {
74 return nullptr;
75 }
76
77 sptr<KVDBServiceClient> client = iface_cast<KVDBServiceClient>(service);
78 if (client == nullptr) {
79 client = new (std::nothrow) KVDBServiceClient(service);
80 }
81 if (client == nullptr) {
82 return nullptr;
83 }
84
85 instance_.reset(client.GetRefPtr(), [client](auto *) mutable { client = nullptr; });
86 return instance_;
87 }
88
OnRemoteDied()89 void KVDBServiceClient::ServiceDeath::OnRemoteDied()
90 {
91 std::lock_guard<decltype(mutex_)> lockGuard(mutex_);
92 instance_ = nullptr;
93 }
94
KVDBServiceClient(const sptr<IRemoteObject> & handle)95 KVDBServiceClient::KVDBServiceClient(const sptr<IRemoteObject> &handle) : IRemoteProxy(handle)
96 {
97 remote_ = Remote();
98 }
99
GetStoreIds(const AppId & appId,std::vector<StoreId> & storeIds)100 Status KVDBServiceClient::GetStoreIds(const AppId &appId, std::vector<StoreId> &storeIds)
101 {
102 MessageParcel reply;
103 int32_t status = IPC_SEND(TRANS_GET_STORE_IDS, reply, appId, StoreId(), storeIds);
104 if (status != SUCCESS) {
105 ZLOGE("status:0x%{public}x, appId:%{public}s", status, appId.appId.c_str());
106 }
107 ITypesUtil::Unmarshal(reply, storeIds);
108 return static_cast<Status>(status);
109 }
110
BeforeCreate(const AppId & appId,const StoreId & storeId,const Options & options)111 Status KVDBServiceClient::BeforeCreate(const AppId &appId, const StoreId &storeId, const Options &options)
112 {
113 MessageParcel reply;
114 int32_t status = IPC_SEND(TRANS_BEFORE_CREATE, reply, appId, storeId, options);
115 if (status != SUCCESS) {
116 ZLOGE("status:0x%{public}x appId:%{public}s, storeId:%{public}s", status, appId.appId.c_str(),
117 storeId.storeId.c_str());
118 }
119 return static_cast<Status>(status);
120 }
121
AfterCreate(const AppId & appId,const StoreId & storeId,const Options & options,const std::vector<uint8_t> & password)122 Status KVDBServiceClient::AfterCreate(
123 const AppId &appId, const StoreId &storeId, const Options &options, const std::vector<uint8_t> &password)
124 {
125 MessageParcel reply;
126 int32_t status = IPC_SEND(TRANS_AFTER_CREATE, reply, appId, storeId, options, password);
127 if (status != SUCCESS) {
128 ZLOGE("status:0x%{public}x appId:%{public}s, storeId:%{public}s, encrypt:%{public}d", status,
129 appId.appId.c_str(), storeId.storeId.c_str(), options.encrypt);
130 }
131 return static_cast<Status>(status);
132 }
133
Delete(const AppId & appId,const StoreId & storeId)134 Status KVDBServiceClient::Delete(const AppId &appId, const StoreId &storeId)
135 {
136 MessageParcel reply;
137 int32_t status = IPC_SEND(TRANS_DELETE, reply, appId, storeId);
138 if (status != SUCCESS) {
139 ZLOGE("status:0x%{public}x appId:%{public}s, storeId:%{public}s", status, appId.appId.c_str(),
140 storeId.storeId.c_str());
141 }
142 return static_cast<Status>(status);
143 }
144
Sync(const AppId & appId,const StoreId & storeId,const SyncInfo & syncInfo)145 Status KVDBServiceClient::Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo)
146 {
147 MessageParcel reply;
148 int32_t status = IPC_SEND(TRANS_SYNC, reply, appId, storeId, syncInfo.seqId, syncInfo.mode, syncInfo.devices,
149 syncInfo.delay, syncInfo.query);
150 if (status != SUCCESS) {
151 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s, sequenceId:%{public}" PRIu64, status,
152 appId.appId.c_str(), storeId.storeId.c_str(), syncInfo.seqId);
153 }
154 return static_cast<Status>(status);
155 }
156
RegisterSyncCallback(const AppId & appId,sptr<IKvStoreSyncCallback> callback)157 Status KVDBServiceClient::RegisterSyncCallback(const AppId &appId, sptr<IKvStoreSyncCallback> callback)
158 {
159 MessageParcel reply;
160 int32_t status = IPC_SEND(TRANS_REGISTER_CALLBACK, reply, appId, StoreId(), callback->AsObject().GetRefPtr());
161 if (status != SUCCESS) {
162 ZLOGE("status:0x%{public}x, appId:%{public}s, callback:0x%{public}x", status, appId.appId.c_str(),
163 StoreUtil::Anonymous(callback.GetRefPtr()));
164 }
165 return static_cast<Status>(status);
166 }
167
UnregisterSyncCallback(const AppId & appId)168 Status KVDBServiceClient::UnregisterSyncCallback(const AppId &appId)
169 {
170 MessageParcel reply;
171 int32_t status = IPC_SEND(TRANS_UNREGISTER_CALLBACK, reply, appId, StoreId());
172 if (status != SUCCESS) {
173 ZLOGE("status:0x%{public}x, appId:%{public}s", status, appId.appId.c_str());
174 }
175 return static_cast<Status>(status);
176 }
177
SetSyncParam(const AppId & appId,const StoreId & storeId,const KvSyncParam & syncParam)178 Status KVDBServiceClient::SetSyncParam(const AppId &appId, const StoreId &storeId, const KvSyncParam &syncParam)
179 {
180 MessageParcel reply;
181 int32_t status = IPC_SEND(TRANS_SET_SYNC_PARAM, reply, appId, storeId, syncParam.allowedDelayMs);
182 if (status != SUCCESS) {
183 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s", status, appId.appId.c_str(),
184 storeId.storeId.c_str());
185 }
186 return static_cast<Status>(status);
187 }
188
GetSyncParam(const AppId & appId,const StoreId & storeId,KvSyncParam & syncParam)189 Status KVDBServiceClient::GetSyncParam(const AppId &appId, const StoreId &storeId, KvSyncParam &syncParam)
190 {
191 MessageParcel reply;
192 int32_t status = IPC_SEND(TRANS_GET_SYNC_PARAM, reply, appId, storeId);
193 if (status != SUCCESS) {
194 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s", status, appId.appId.c_str(),
195 storeId.storeId.c_str());
196 return SUCCESS;
197 }
198 ITypesUtil::Unmarshal(reply, syncParam.allowedDelayMs);
199 return static_cast<Status>(status);
200 }
201
EnableCapability(const AppId & appId,const StoreId & storeId)202 Status KVDBServiceClient::EnableCapability(const AppId &appId, const StoreId &storeId)
203 {
204 MessageParcel reply;
205 int32_t status = IPC_SEND(TRANS_ENABLE_CAP, reply, appId, storeId);
206 if (status != SUCCESS) {
207 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s", status, appId.appId.c_str(),
208 storeId.storeId.c_str());
209 }
210 return static_cast<Status>(status);
211 }
212
DisableCapability(const AppId & appId,const StoreId & storeId)213 Status KVDBServiceClient::DisableCapability(const AppId &appId, const StoreId &storeId)
214 {
215 MessageParcel reply;
216 int32_t status = IPC_SEND(TRANS_DISABLE_CAP, reply, appId, storeId);
217 if (status != SUCCESS) {
218 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s", status, appId.appId.c_str(),
219 storeId.storeId.c_str());
220 }
221 return static_cast<Status>(status);
222 }
223
SetCapability(const AppId & appId,const StoreId & storeId,const std::vector<std::string> & local,const std::vector<std::string> & remote)224 Status KVDBServiceClient::SetCapability(const AppId &appId, const StoreId &storeId,
225 const std::vector<std::string> &local, const std::vector<std::string> &remote)
226 {
227 MessageParcel reply;
228 int32_t status = IPC_SEND(TRANS_SET_CAP, reply, appId, storeId, local, remote);
229 if (status != SUCCESS) {
230 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s", status, appId.appId.c_str(),
231 storeId.storeId.c_str());
232 }
233 return static_cast<Status>(status);
234 }
235
AddSubscribeInfo(const AppId & appId,const StoreId & storeId,const SyncInfo & syncInfo)236 Status KVDBServiceClient::AddSubscribeInfo(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo)
237 {
238 MessageParcel reply;
239 int32_t status = IPC_SEND(TRANS_ADD_SUB, reply, appId, storeId, syncInfo.seqId, syncInfo.devices, syncInfo.query);
240 if (status != SUCCESS) {
241 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s, query:%{public}s", status,
242 appId.appId.c_str(), storeId.storeId.c_str(), StoreUtil::Anonymous(syncInfo.query).c_str());
243 }
244 return static_cast<Status>(status);
245 }
246
RmvSubscribeInfo(const AppId & appId,const StoreId & storeId,const SyncInfo & syncInfo)247 Status KVDBServiceClient::RmvSubscribeInfo(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo)
248 {
249 MessageParcel reply;
250 int32_t status = IPC_SEND(TRANS_RMV_SUB, reply, appId, storeId, syncInfo.seqId, syncInfo.devices, syncInfo.query);
251 if (status != SUCCESS) {
252 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s, query:%{public}s", status,
253 appId.appId.c_str(), storeId.storeId.c_str(), StoreUtil::Anonymous(syncInfo.query).c_str());
254 }
255 return static_cast<Status>(status);
256 }
257
Subscribe(const AppId & appId,const StoreId & storeId,sptr<IKvStoreObserver> observer)258 Status KVDBServiceClient::Subscribe(const AppId &appId, const StoreId &storeId, sptr<IKvStoreObserver> observer)
259 {
260 MessageParcel reply;
261 int32_t status = IPC_SEND(TRANS_SUB, reply, appId, storeId, observer->AsObject());
262 if (status != SUCCESS) {
263 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s, observer:0x%{public}x", status,
264 appId.appId.c_str(), storeId.storeId.c_str(), StoreUtil::Anonymous(observer.GetRefPtr()));
265 }
266 return static_cast<Status>(status);
267 }
268
Unsubscribe(const AppId & appId,const StoreId & storeId,sptr<IKvStoreObserver> observer)269 Status KVDBServiceClient::Unsubscribe(const AppId &appId, const StoreId &storeId, sptr<IKvStoreObserver> observer)
270 {
271 MessageParcel reply;
272 int32_t status = IPC_SEND(TRANS_UNSUB, reply, appId, storeId, observer->AsObject().GetRefPtr());
273 if (status != SUCCESS) {
274 ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s, observer:0x%{public}x", status,
275 appId.appId.c_str(), storeId.storeId.c_str(), StoreUtil::Anonymous(observer.GetRefPtr()));
276 }
277 return static_cast<Status>(status);
278 }
279
GetBackupPassword(const AppId & appId,const StoreId & storeId,std::vector<uint8_t> & password)280 Status KVDBServiceClient::GetBackupPassword(
281 const AppId &appId, const StoreId &storeId, std::vector<uint8_t> &password)
282 {
283 MessageParcel reply;
284 int32_t status = IPC_SEND(TRANS_GET_PASSWORD, reply, appId, storeId);
285 if (status != SUCCESS) {
286 ZLOGE("status:0x%{public}x appId:%{public}s, storeId:%{public}s", status,
287 appId.appId.c_str(), storeId.storeId.c_str());
288 }
289 ITypesUtil::Unmarshal(reply, password);
290 return static_cast<Status>(status);
291 }
292
GetLocalDevice()293 KVDBService::DevBrief KVDBServiceClient::GetLocalDevice()
294 {
295 DevBrief brief;
296 MessageParcel reply;
297 int32_t status = IPC_SEND(TRANS_GET_LOCAL_DEVICE, reply);
298 if (status != SUCCESS) {
299 ZLOGE("status:0x%{public}x", status);
300 }
301 ITypesUtil::Unmarshal(reply, brief);
302 return brief;
303 }
304
GetRemoteDevices()305 std::vector<KVDBService::DevBrief> KVDBServiceClient::GetRemoteDevices()
306 {
307 std::vector<DevBrief> briefs;
308 MessageParcel reply;
309 int32_t status = IPC_SEND(TRANS_GET_REMOTE_DEVICES, reply);
310 if (status != SUCCESS) {
311 ZLOGE("status:0x%{public}x", status);
312 }
313 ITypesUtil::Unmarshal(reply, briefs);
314 return briefs;
315 }
316
GetSyncAgent(const AppId & appId)317 sptr<KvStoreSyncCallbackClient> KVDBServiceClient::GetSyncAgent(const AppId &appId)
318 {
319 std::lock_guard<decltype(agentMtx_)> lockGuard(agentMtx_);
320 if (syncAgent_ != nullptr) {
321 return syncAgent_;
322 }
323
324 sptr<KvStoreSyncCallbackClient> syncAgent = new (std::nothrow) KvStoreSyncCallbackClient();
325 auto status = RegisterSyncCallback(appId, syncAgent);
326 if (status == SUCCESS) {
327 syncAgent_ = std::move(syncAgent);
328 }
329 return syncAgent_;
330 }
331 } // namespace OHOS::DistributedKv