• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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