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