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 "DataManager"
16
17 #include "data_manager.h"
18
19 #include "checker_manager.h"
20 #include "dfx_types.h"
21 #include "file.h"
22 #include "lifecycle/lifecycle_manager.h"
23 #include "log_print.h"
24 #include "preprocess_utils.h"
25 #include "uri_permission_manager.h"
26 #include "uri.h"
27
28 namespace OHOS {
29 namespace UDMF {
30 const std::string MSDP_PROCESS_NAME = "msdp_sa";
31 const std::string DATA_PREFIX = "udmf://";
DataManager()32 DataManager::DataManager()
33 {
34 authorizationMap_[UD_INTENTION_MAP.at(UD_INTENTION_DRAG)] = MSDP_PROCESS_NAME;
35 CheckerManager::GetInstance().LoadCheckers();
36 }
37
~DataManager()38 DataManager::~DataManager()
39 {
40 }
41
GetInstance()42 DataManager &DataManager::GetInstance()
43 {
44 static DataManager instance;
45 return instance;
46 }
47
SaveData(CustomOption & option,UnifiedData & unifiedData,std::string & key)48 int32_t DataManager::SaveData(CustomOption &option, UnifiedData &unifiedData, std::string &key)
49 {
50 if (unifiedData.IsEmpty()) {
51 ZLOGE("Invalid parameters, have no record");
52 return E_INVALID_PARAMETERS;
53 }
54
55 if (!UnifiedDataUtils::IsValidIntention(option.intention)) {
56 ZLOGE("Invalid parameters intention: %{public}d.", option.intention);
57 return E_INVALID_PARAMETERS;
58 }
59
60 // imput runtime info before put it into store and save one privilege
61 if (PreProcessUtils::RuntimeDataImputation(unifiedData, option) != E_OK) {
62 ZLOGE("Imputation failed");
63 return E_UNKNOWN;
64 }
65
66 std::string intention = unifiedData.GetRuntime()->key.intention;
67 if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
68 int32_t ret = PreProcessUtils::SetRemoteUri(option.tokenId, unifiedData);
69 if (ret != E_OK) {
70 ZLOGE("SetRemoteUri failed, ret: %{public}d.", ret);
71 return ret;
72 }
73 }
74
75 for (const auto &record : unifiedData.GetRecords()) {
76 record->SetUid(PreProcessUtils::IdGenerator());
77 }
78
79 auto store = storeCache_.GetStore(intention);
80 if (store == nullptr) {
81 ZLOGE("Get store failed, intention: %{public}s.", intention.c_str());
82 return E_DB_ERROR;
83 }
84
85 if (!UnifiedDataUtils::IsPersist(intention) && store->Clear() != E_OK) {
86 ZLOGE("Clear store failed, intention: %{public}s.", intention.c_str());
87 return E_DB_ERROR;
88 }
89
90 if (store->Put(unifiedData) != E_OK) {
91 ZLOGE("Put unified data failed, intention: %{public}s.", intention.c_str());
92 return E_DB_ERROR;
93 }
94 key = unifiedData.GetRuntime()->key.GetUnifiedKey();
95 ZLOGD("Put unified data successful, key: %{public}s.", key.c_str());
96 return E_OK;
97 }
98
RetrieveData(const QueryOption & query,UnifiedData & unifiedData)99 int32_t DataManager::RetrieveData(const QueryOption &query, UnifiedData &unifiedData)
100 {
101 UnifiedKey key(query.key);
102 if (!key.IsValid()) {
103 ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
104 return E_INVALID_PARAMETERS;
105 }
106 auto store = storeCache_.GetStore(key.intention);
107 if (store == nullptr) {
108 ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
109 return E_DB_ERROR;
110 }
111 int32_t res = store->Get(query.key, unifiedData);
112 if (res != E_OK) {
113 ZLOGE("Get data from store failed, res: %{public}d, key: %{public}s.", res, query.key.c_str());
114 return res;
115 }
116
117 std::shared_ptr<Runtime> runtime = unifiedData.GetRuntime();
118 if (static_cast<uint32_t>(unifiedData.GetRecords().size()) != runtime->recordTotalNum) {
119 ZLOGE("Get data from DB is incomplete, key: %{public}s, expected recordsNum is %{public}u, not %{public}zu.",
120 query.key.c_str(), runtime->recordTotalNum, unifiedData.GetRecords().size());
121 return E_NOT_FOUND;
122 }
123
124 CheckerManager::CheckInfo info;
125 info.tokenId = query.tokenId;
126 if (!CheckerManager::GetInstance().IsValid(runtime->privileges, info) && !CheckPermissionInCache(query)) {
127 return E_NO_PERMISSION;
128 }
129
130 if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
131 int32_t ret = ProcessingUri(query, unifiedData);
132 if (ret != E_OK) {
133 ZLOGE("DragUriProcessing failed. ret=%{public}d", ret);
134 return E_NO_PERMISSION;
135 }
136 }
137
138 if (LifeCycleManager::GetInstance().DeleteOnGet(key) != E_OK) {
139 ZLOGE("Remove data failed, intention: %{public}s.", key.intention.c_str());
140 return E_DB_ERROR;
141 }
142 privilegeCache_.erase(query.key);
143
144 PreProcessUtils::SetRemoteData(unifiedData);
145 return E_OK;
146 }
147
CheckPermissionInCache(const QueryOption & query)148 bool DataManager::CheckPermissionInCache(const QueryOption &query)
149 {
150 auto iter = privilegeCache_.find(query.key);
151 if (iter != privilegeCache_.end() && iter->second.tokenId == query.tokenId) {
152 return true;
153 }
154 return false;
155 }
156
ProcessingUri(const QueryOption & query,UnifiedData & unifiedData)157 int32_t DataManager::ProcessingUri(const QueryOption &query, UnifiedData &unifiedData)
158 {
159 std::string localDeviceId = PreProcessUtils::GetLocalDeviceId();
160 auto records = unifiedData.GetRecords();
161 if (localDeviceId != unifiedData.GetRuntime()->deviceId) {
162 for (auto record : records) {
163 if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) {
164 auto file = static_cast<File *>(record.get());
165 std::string remoteUri = file->GetRemoteUri();
166 if (remoteUri.empty()) {
167 ZLOGW("Get remoteUri is empyt, key=%{public}s.", query.key.c_str());
168 continue;
169 }
170 file->SetUri(remoteUri); // cross dev, need dis path.
171 }
172 }
173 }
174
175 std::string bundleName;
176 if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) {
177 ZLOGE("GetHapBundleNameByToken fail, key=%{public}s.", query.key.c_str());
178 return E_ERROR;
179 }
180 for (auto record : records) {
181 if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) {
182 auto file = static_cast<File *>(record.get());
183 if (file->GetUri().empty()) {
184 ZLOGW("Get uri is empty, key=%{public}s.", query.key.c_str());
185 continue;
186 }
187 Uri uri(file->GetUri());
188 if (uri.GetAuthority().empty()) {
189 ZLOGW("Get authority is empty, key=%{public}s.", query.key.c_str());
190 continue;
191 }
192 if (UriPermissionManager::GetInstance().GrantUriPermission(file->GetUri(), bundleName) != E_OK) {
193 ZLOGE("GrantUriPermission fail, uriAuthority=%{public}s, bundleName=%{public}s, key=%{public}s.",
194 uri.GetAuthority().c_str(), bundleName.c_str(), query.key.c_str());
195 return E_NO_PERMISSION;
196 }
197 }
198 }
199 return E_OK;
200 }
201
RetrieveBatchData(const QueryOption & query,std::vector<UnifiedData> & unifiedDataSet)202 int32_t DataManager::RetrieveBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
203 {
204 std::vector<UnifiedData> dataSet;
205 std::shared_ptr<Store> store;
206 auto status = QueryDataCommon(query, dataSet, store);
207 if (status != E_OK) {
208 ZLOGE("QueryDataCommon failed.");
209 return status;
210 }
211 if (dataSet.empty()) {
212 ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention);
213 return E_OK;
214 }
215 for (auto &data : dataSet) {
216 PreProcessUtils::SetRemoteData(data);
217 unifiedDataSet.push_back(data);
218 }
219 return E_OK;
220 }
221
UpdateData(const QueryOption & query,UnifiedData & unifiedData)222 int32_t DataManager::UpdateData(const QueryOption &query, UnifiedData &unifiedData)
223 {
224 UnifiedKey key(query.key);
225 if (!key.IsValid()) {
226 ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
227 return E_INVALID_PARAMETERS;
228 }
229 if (unifiedData.IsEmpty()) {
230 ZLOGE("Invalid parameters, unified data has no record.");
231 return E_INVALID_PARAMETERS;
232 }
233 auto store = storeCache_.GetStore(key.intention);
234 if (store == nullptr) {
235 ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
236 return E_DB_ERROR;
237 }
238
239 UnifiedData data;
240 int32_t res = store->Get(query.key, data);
241 if (res != E_OK) {
242 ZLOGE("Get data from store failed, intention: %{public}s.", key.intention.c_str());
243 return res;
244 }
245 if (data.IsEmpty()) {
246 ZLOGE("Invalid parameter, unified data has no record; intention: %{public}s.", key.intention.c_str());
247 return E_INVALID_PARAMETERS;
248 }
249 std::shared_ptr<Runtime> runtime = data.GetRuntime();
250 runtime->lastModifiedTime = PreProcessUtils::GetTimeStamp();
251 unifiedData.SetRuntime(*runtime);
252 for (auto &record : unifiedData.GetRecords()) {
253 record->SetUid(PreProcessUtils::IdGenerator());
254 }
255 if (store->Update(unifiedData) != E_OK) {
256 ZLOGE("Update unified data failed, intention: %{public}s.", key.intention.c_str());
257 return E_DB_ERROR;
258 }
259 return E_OK;
260 }
DeleteData(const QueryOption & query,std::vector<UnifiedData> & unifiedDataSet)261 int32_t DataManager::DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
262 {
263 std::vector<UnifiedData> dataSet;
264 std::shared_ptr<Store> store;
265 auto status = QueryDataCommon(query, dataSet, store);
266 if (status != E_OK) {
267 ZLOGE("QueryDataCommon failed.");
268 return status;
269 }
270 if (dataSet.empty()) {
271 ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention);
272 return E_OK;
273 }
274 std::shared_ptr<Runtime> runtime;
275 std::vector<std::string> deleteKeys;
276 for (const auto &data : dataSet) {
277 runtime = data.GetRuntime();
278 unifiedDataSet.push_back(data);
279 deleteKeys.push_back(runtime->key.key);
280 }
281 if (store->DeleteBatch(deleteKeys) != E_OK) {
282 ZLOGE("Remove data failed.");
283 return E_DB_ERROR;
284 }
285 return E_OK;
286 }
287
GetSummary(const QueryOption & query,Summary & summary)288 int32_t DataManager::GetSummary(const QueryOption &query, Summary &summary)
289 {
290 UnifiedKey key(query.key);
291 if (!key.IsValid()) {
292 ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
293 return E_INVALID_PARAMETERS;
294 }
295
296 auto store = storeCache_.GetStore(key.intention);
297 if (store == nullptr) {
298 ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
299 return E_DB_ERROR;
300 }
301
302 if (store->GetSummary(query.key, summary) != E_OK) {
303 ZLOGE("Store get summary failed, intention: %{public}s.", key.intention.c_str());
304 return E_DB_ERROR;
305 }
306 return E_OK;
307 }
308
AddPrivilege(const QueryOption & query,const Privilege & privilege)309 int32_t DataManager::AddPrivilege(const QueryOption &query, const Privilege &privilege)
310 {
311 UnifiedKey key(query.key);
312 if (!key.IsValid()) {
313 ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
314 return E_INVALID_PARAMETERS;
315 }
316
317 std::string processName;
318 if (!PreProcessUtils::GetNativeProcessNameByToken(query.tokenId, processName)) {
319 return E_UNKNOWN;
320 }
321
322 if (processName != authorizationMap_[key.intention]) {
323 ZLOGE("Process: %{public}s have no permission", processName.c_str());
324 return E_NO_PERMISSION;
325 }
326
327 auto store = storeCache_.GetStore(key.intention);
328 if (store == nullptr) {
329 ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
330 return E_DB_ERROR;
331 }
332
333 UnifiedData data;
334 int32_t res = store->Get(query.key, data);
335 if (res == E_NOT_FOUND) {
336 privilegeCache_[query.key] = privilege;
337 ZLOGW("Add privilege in cache, key: %{public}s.", query.key.c_str());
338 return E_OK;
339 }
340 if (res != E_OK) {
341 ZLOGE("Get data from store failed, res:%{public}d,intention: %{public}s.", res, key.intention.c_str());
342 return res;
343 }
344 data.GetRuntime()->privileges.emplace_back(privilege);
345 if (store->Update(data) != E_OK) {
346 ZLOGE("Update unified data failed, intention: %{public}s.", key.intention.c_str());
347 return E_DB_ERROR;
348 }
349 return E_OK;
350 }
351
Sync(const QueryOption & query,const std::vector<std::string> & devices)352 int32_t DataManager::Sync(const QueryOption &query, const std::vector<std::string> &devices)
353 {
354 UnifiedKey key(query.key);
355 if (!key.IsValid()) {
356 ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
357 return E_INVALID_PARAMETERS;
358 }
359
360 auto store = storeCache_.GetStore(key.intention);
361 if (store == nullptr) {
362 ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
363 return E_DB_ERROR;
364 }
365
366 if (store->Sync(devices) != E_OK) {
367 ZLOGE("Store sync failed, intention: %{public}s.", key.intention.c_str());
368 return E_DB_ERROR;
369 }
370 return E_OK;
371 }
372
QueryDataCommon(const QueryOption & query,std::vector<UnifiedData> & dataSet,std::shared_ptr<Store> & store)373 int32_t DataManager::QueryDataCommon(
374 const QueryOption &query, std::vector<UnifiedData> &dataSet, std::shared_ptr<Store> &store)
375 {
376 auto find = UD_INTENTION_MAP.find(query.intention);
377 std::string intention = find == UD_INTENTION_MAP.end() ? intention : find->second;
378 if (!UnifiedDataUtils::IsValidOptions(query.key, intention)) {
379 ZLOGE("Unified key: %{public}s and intention: %{public}s is invalid.", query.key.c_str(), intention.c_str());
380 return E_INVALID_PARAMETERS;
381 }
382 std::string dataPrefix = DATA_PREFIX + intention;
383 UnifiedKey key(query.key);
384 key.IsValid();
385 if (intention.empty()) {
386 dataPrefix = key.key;
387 intention = key.intention;
388 }
389 ZLOGD("dataPrefix = %{public}s, intention: %{public}s.", dataPrefix.c_str(), intention.c_str());
390 store = storeCache_.GetStore(intention);
391 if (store == nullptr) {
392 ZLOGE("Get store failed, intention: %{public}s.", intention.c_str());
393 return E_DB_ERROR;
394 }
395 if (store->GetBatchData(dataPrefix, dataSet) != E_OK) {
396 ZLOGE("Get dataSet failed, dataPrefix: %{public}s.", dataPrefix.c_str());
397 return E_DB_ERROR;
398 }
399 return E_OK;
400 }
401 } // namespace UDMF
402 } // namespace OHOS