1 /*
2  * Copyright (c) 2021 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 "DistributedKvDataManager"
16 #include "distributed_kv_data_manager.h"
17 
18 #include "dds_trace.h"
19 #include "dev_manager.h"
20 #include "ikvstore_data_service.h"
21 #include "kvstore_service_death_notifier.h"
22 #include "log_print.h"
23 #include "refbase.h"
24 #include "store_manager.h"
25 #include "task_executor.h"
26 #include "store_util.h"
27 #include "runtime_config.h"
28 #include "kv_store_delegate_manager.h"
29 #include "process_communication_impl.h"
30 #include "process_system_api_adapter_impl.h"
31 #include "store_factory.h"
32 
33 namespace OHOS {
34 namespace DistributedKv {
35 using namespace OHOS::DistributedDataDfx;
36 bool DistributedKvDataManager::isAlreadySet_ = false;
DistributedKvDataManager()37 DistributedKvDataManager::DistributedKvDataManager()
38 {}
39 
~DistributedKvDataManager()40 DistributedKvDataManager::~DistributedKvDataManager()
41 {}
42 
GetSingleKvStore(const Options & options,const AppId & appId,const StoreId & storeId,std::shared_ptr<SingleKvStore> & singleKvStore)43 Status DistributedKvDataManager::GetSingleKvStore(const Options &options, const AppId &appId, const StoreId &storeId,
44                                                   std::shared_ptr<SingleKvStore> &singleKvStore)
45 {
46     DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__),
47         TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
48 
49     singleKvStore = nullptr;
50     if (options.securityLevel == INVALID_LABEL) {
51         ZLOGE("invalid security level, appId = %{private}s, storeId = %{private}s, kvStoreType = %{private}d",
52             appId.appId.c_str(), storeId.storeId.c_str(), options.kvStoreType);
53         return Status::INVALID_ARGUMENT;
54     }
55     if (options.dataType == DataType::TYPE_STATICS && options.autoSync) {
56         ZLOGE("STATICS data do not support auto sync, type:%{public}d", options.dataType);
57         return Status::INVALID_ARGUMENT;
58     }
59     if (!storeId.IsValid()) {
60         ZLOGE("invalid storeId.");
61         return Status::INVALID_ARGUMENT;
62     }
63     if (!options.IsPathValid()) {
64         ZLOGE("invalid path.");
65         return Status::INVALID_ARGUMENT;
66     }
67     KvStoreServiceDeathNotifier::SetAppId(appId);
68 
69     Status status = Status::INVALID_ARGUMENT;
70     singleKvStore = StoreManager::GetInstance().GetKVStore(appId, storeId, options, status);
71     return status;
72 }
73 
GetAllKvStoreId(const AppId & appId,std::vector<StoreId> & storeIds)74 Status DistributedKvDataManager::GetAllKvStoreId(const AppId &appId, std::vector<StoreId> &storeIds)
75 {
76     DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__));
77 
78     KvStoreServiceDeathNotifier::SetAppId(appId);
79     return StoreManager::GetInstance().GetStoreIds(appId, storeIds);
80 }
81 
CloseKvStore(const AppId & appId,const StoreId & storeId)82 Status DistributedKvDataManager::CloseKvStore(const AppId &appId, const StoreId &storeId)
83 {
84     DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__),
85         TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
86 
87     KvStoreServiceDeathNotifier::SetAppId(appId);
88     if (!storeId.IsValid()) {
89         ZLOGE("invalid storeId.");
90         return Status::INVALID_ARGUMENT;
91     }
92 
93     return StoreManager::GetInstance().CloseKVStore(appId, storeId);
94 }
95 
CloseKvStore(const AppId & appId,std::shared_ptr<SingleKvStore> & kvStorePtr)96 Status DistributedKvDataManager::CloseKvStore(const AppId &appId, std::shared_ptr<SingleKvStore> &kvStorePtr)
97 {
98     DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__),
99         TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
100 
101     if (kvStorePtr == nullptr) {
102         ZLOGE("kvStorePtr is nullptr.");
103         return Status::INVALID_ARGUMENT;
104     }
105     KvStoreServiceDeathNotifier::SetAppId(appId);
106     StoreId storeId = kvStorePtr->GetStoreId();
107     kvStorePtr = nullptr;
108 
109     return StoreManager::GetInstance().CloseKVStore(appId, storeId);
110 }
111 
CloseAllKvStore(const AppId & appId)112 Status DistributedKvDataManager::CloseAllKvStore(const AppId &appId)
113 {
114     DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__),
115         TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
116 
117     KvStoreServiceDeathNotifier::SetAppId(appId);
118     return StoreManager::GetInstance().CloseAllKVStore(appId);
119 }
120 
DeleteKvStore(const AppId & appId,const StoreId & storeId,const std::string & path)121 Status DistributedKvDataManager::DeleteKvStore(const AppId &appId, const StoreId &storeId, const std::string &path)
122 {
123     DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__),
124         TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
125     if (!storeId.IsValid()) {
126         ZLOGE("invalid storeId.");
127         return Status::INVALID_ARGUMENT;
128     }
129     if (path.empty()) {
130         ZLOGE("path empty");
131         return Status::INVALID_ARGUMENT;
132     }
133     KvStoreServiceDeathNotifier::SetAppId(appId);
134 
135     return StoreManager::GetInstance().Delete(appId, storeId, path);
136 }
137 
DeleteAllKvStore(const AppId & appId,const std::string & path)138 Status DistributedKvDataManager::DeleteAllKvStore(const AppId &appId, const std::string &path)
139 {
140     DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__),
141         TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
142     if (path.empty()) {
143         ZLOGE("path empty");
144         return Status::INVALID_ARGUMENT;
145     }
146     KvStoreServiceDeathNotifier::SetAppId(appId);
147 
148     std::vector<StoreId> storeIds;
149     Status status = GetAllKvStoreId(appId, storeIds);
150     if (status != SUCCESS) {
151         return status;
152     }
153     for (auto &storeId : storeIds) {
154         status = StoreManager::GetInstance().Delete(appId, storeId, path);
155         if (status != SUCCESS) {
156             return status;
157         }
158     }
159     return SUCCESS;
160 }
161 
RegisterKvStoreServiceDeathRecipient(std::shared_ptr<KvStoreDeathRecipient> kvStoreDeathRecipient)162 void DistributedKvDataManager::RegisterKvStoreServiceDeathRecipient(
163     std::shared_ptr<KvStoreDeathRecipient> kvStoreDeathRecipient)
164 {
165     ZLOGD("begin");
166     if (kvStoreDeathRecipient == nullptr) {
167         ZLOGW("Register KvStoreService Death Recipient input is null.");
168         return;
169     }
170     KvStoreServiceDeathNotifier::AddServiceDeathWatcher(kvStoreDeathRecipient);
171 }
172 
UnRegisterKvStoreServiceDeathRecipient(std::shared_ptr<KvStoreDeathRecipient> kvStoreDeathRecipient)173 void DistributedKvDataManager::UnRegisterKvStoreServiceDeathRecipient(
174     std::shared_ptr<KvStoreDeathRecipient> kvStoreDeathRecipient)
175 {
176     ZLOGD("begin");
177     if (kvStoreDeathRecipient == nullptr) {
178         ZLOGW("UnRegister KvStoreService Death Recipient input is null.");
179         return;
180     }
181     KvStoreServiceDeathNotifier::RemoveServiceDeathWatcher(kvStoreDeathRecipient);
182 }
183 
SetExecutors(std::shared_ptr<ExecutorPool> executors)184 void DistributedKvDataManager::SetExecutors(std::shared_ptr<ExecutorPool> executors)
185 {
186     TaskExecutor::GetInstance().SetExecutors(std::move(executors));
187 }
188 
SetEndpoint(std::shared_ptr<Endpoint> endpoint)189 Status DistributedKvDataManager::SetEndpoint(std::shared_ptr<Endpoint> endpoint)
190 {
191     std::lock_guard<std::mutex> lock(mutex_);
192     if (endpoint == nullptr) {
193         ZLOGE("Endpoint is nullptr.");
194         return INVALID_ARGUMENT;
195     }
196 
197     if (isAlreadySet_) {
198         ZLOGW("Endpoint already set");
199         return SUCCESS;
200     }
201 
202     auto dbStatus = DistributedDB::KvStoreDelegateManager::SetProcessLabel("default", "default");
203     auto status = StoreUtil::ConvertStatus(dbStatus);
204     if (status != SUCCESS) {
205         ZLOGE("SetProcessLabel failed: %d", status);
206         return status;
207     }
208 
209     auto communicator = std::make_shared<ProcessCommunicationImpl>(endpoint);
210     dbStatus = DistributedDB::KvStoreDelegateManager::SetProcessCommunicator(communicator);
211     status = StoreUtil::ConvertStatus(dbStatus);
212     if (status != SUCCESS) {
213         ZLOGE("SetProcessCommunicator failed: %d", status);
214         return status;
215     }
216 
217     auto systemApi = std::make_shared<ProcessSystemApiAdapterImpl>(endpoint);
218     dbStatus = DistributedDB::KvStoreDelegateManager::SetProcessSystemAPIAdapter(systemApi);
219     status = StoreUtil::ConvertStatus(dbStatus);
220     if (status != SUCCESS) {
221         ZLOGE("SetProcessSystemAPIAdapter failed: %d", status);
222         return status;
223     }
224 
225     auto permissionCallback = [endpoint](const DistributedDB::PermissionCheckParam &param, uint8_t flag) -> bool {
226         StoreBriefInfo params = {
227             std::move(param.userId), std::move(param.appId), std::move(param.storeId), std::move(param.deviceId),
228             std::move(param.instanceId), std::move(param.extraConditions)
229         };
230         return endpoint->HasDataSyncPermission(params, flag);
231     };
232 
233     dbStatus = DistributedDB::RuntimeConfig::SetPermissionCheckCallback(permissionCallback);
234     status = StoreUtil::ConvertStatus(dbStatus);
235     if (status != SUCCESS) {
236         ZLOGE("SetPermissionCheckCallback failed: %d", status);
237         return status;
238     }
239     isAlreadySet_ = true;
240     return status;
241 }
242 
PutSwitch(const AppId & appId,const SwitchData & data)243 Status DistributedKvDataManager::PutSwitch(const AppId &appId, const SwitchData &data)
244 {
245     return StoreManager::GetInstance().PutSwitch(appId, data);
246 }
247 
GetSwitch(const AppId & appId,const std::string & networkId)248 std::pair<Status, SwitchData> DistributedKvDataManager::GetSwitch(const AppId &appId, const std::string &networkId)
249 {
250     return StoreManager::GetInstance().GetSwitch(appId, networkId);
251 }
252 
SubscribeSwitchData(const AppId & appId,std::shared_ptr<KvStoreObserver> observer)253 Status DistributedKvDataManager::SubscribeSwitchData(const AppId &appId, std::shared_ptr<KvStoreObserver> observer)
254 {
255     return StoreManager::GetInstance().SubscribeSwitchData(appId, observer);
256 }
257 
UnsubscribeSwitchData(const AppId & appId,std::shared_ptr<KvStoreObserver> observer)258 Status DistributedKvDataManager::UnsubscribeSwitchData(const AppId &appId, std::shared_ptr<KvStoreObserver> observer)
259 {
260     return StoreManager::GetInstance().UnsubscribeSwitchData(appId, observer);
261 }
262 }  // namespace DistributedKv
263 }  // namespace OHOS
264