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 "LoadConfigFromDataShareBundleInfoStrategy"
16
17 #include "load_config_from_data_share_bundle_info_strategy.h"
18
19 #include "bundle_mgr_proxy.h"
20 #include "log_print.h"
21 #include "uri_utils.h"
22
23 namespace OHOS::DataShare {
24 struct ConfigData {
25 constexpr static int8_t TABLE_MATCH_PRIORITY = 3;
26 constexpr static int8_t STORE_MATCH_PRIORITY = 2;
27 constexpr static int8_t COMMON_MATCH_PRIORITY = 1;
28 constexpr static int8_t UNDEFINED_PRIORITY = -1;
ConfigDataOHOS::DataShare::ConfigData29 ConfigData() : crossMode_(AccessSystemMode::UNDEFINED, UNDEFINED_PRIORITY) {}
SetCrossUserModeOHOS::DataShare::ConfigData30 void SetCrossUserMode(uint8_t priority, uint8_t crossMode)
31 {
32 if (crossMode_.second < priority && crossMode > AccessSystemMode::UNDEFINED &&
33 crossMode < AccessSystemMode::MAX) {
34 crossMode_.first = static_cast<AccessSystemMode>(crossMode);
35 crossMode_.second = priority;
36 }
37 }
FillIntoContextOHOS::DataShare::ConfigData38 void FillIntoContext(std::shared_ptr<Context> context)
39 {
40 if (crossMode_.second != ConfigData::UNDEFINED_PRIORITY) {
41 context->accessSystemMode = crossMode_.first;
42 }
43 }
44
45 private:
46 std::pair<AccessSystemMode, int8_t> crossMode_;
47 };
48
LoadConfigFromProfile(const ProfileInfo & profileInfo,std::shared_ptr<Context> context)49 bool LoadConfigFromDataShareBundleInfoStrategy::LoadConfigFromProfile(
50 const ProfileInfo &profileInfo, std::shared_ptr<Context> context)
51 {
52 std::string storeUri = URIUtils::DATA_SHARE_SCHEMA + context->calledBundleName + "/" + context->calledModuleName +
53 "/" + context->calledStoreName;
54 std::string tableUri = storeUri + "/" + context->calledTableName;
55 ConfigData result;
56 for (auto const &item : profileInfo.tableConfig) {
57 if (item.uri == tableUri) {
58 result.SetCrossUserMode(ConfigData::TABLE_MATCH_PRIORITY, item.crossUserMode);
59 continue;
60 }
61 if (item.uri == storeUri) {
62 result.SetCrossUserMode(ConfigData::STORE_MATCH_PRIORITY, item.crossUserMode);
63 continue;
64 }
65 if (item.uri == "*") {
66 result.SetCrossUserMode(ConfigData::COMMON_MATCH_PRIORITY, item.crossUserMode);
67 continue;
68 }
69 }
70 result.FillIntoContext(context);
71 return true;
72 }
73
operator ()(std::shared_ptr<Context> context)74 bool LoadConfigFromDataShareBundleInfoStrategy::operator()(std::shared_ptr<Context> context)
75 {
76 if (!LoadConfigFromUri(context)) {
77 ZLOGE("LoadConfigFromUri failed! bundleName: %{public}s", context->calledBundleName.c_str());
78 return false;
79 }
80 if (!BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS(
81 context->calledBundleName, context->currentUserId, context->bundleInfo)) {
82 ZLOGE("GetBundleInfoFromBMS failed! bundleName: %{public}s", context->calledBundleName.c_str());
83 return false;
84 }
85 for (auto &item : context->bundleInfo.extensionInfos) {
86 if (item.type == AppExecFwk::ExtensionAbilityType::DATASHARE) {
87 context->permission = context->isRead ? item.readPermission : item.writePermission;
88
89 std::vector<std::string> infos;
90 auto ret = DataShareProfileInfo::GetResConfigFile(item, infos);
91 if (!ret) {
92 return true; // optional meta data config
93 }
94 ProfileInfo profileInfo;
95 if (!profileInfo.Unmarshall(infos[0])) {
96 ZLOGE("parse failed! %{public}s", infos[0].c_str());
97 return false;
98 }
99 LoadConfigFromProfile(profileInfo, context);
100 return true;
101 }
102 }
103 return false;
104 }
LoadConfigFromUri(std::shared_ptr<Context> context)105 bool LoadConfigFromDataShareBundleInfoStrategy::LoadConfigFromUri(std::shared_ptr<Context> context)
106 {
107 UriInfo uriInfo;
108 if (!URIUtils::GetInfoFromURI(context->uri, uriInfo)) {
109 return false;
110 }
111 context->calledBundleName = std::move(uriInfo.bundleName);
112 context->calledModuleName = std::move(uriInfo.moduleName);
113 context->calledStoreName = std::move(uriInfo.storeName);
114 context->calledTableName = std::move(uriInfo.tableName);
115 return true;
116 }
117 } // namespace OHOS::DataShare