1 /*
2 * Copyright (c) 2024 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 "RdbSchemaConfig"
16
17 #include "rdb_schema_config.h"
18 #include <fstream>
19 #include <sstream>
20 #include "if_system_ability_manager.h"
21 #include "iservice_registry.h"
22 #include "system_ability_definition.h"
23 #include "metadata/meta_data_manager.h"
24 #include "iremote_broker.h"
25 #include "iremote_object.h"
26 #include "refbase.h"
27 #include "resource_manager.h"
28 #include "log_print.h"
29
30 namespace OHOS::DistributedRdb {
31 using namespace OHOS::Global::Resource;
32 using namespace OHOS::DistributedData;
33 using Serializable = DistributedData::Serializable;
34 constexpr const char *SCHEMA_PATH = "arkdata/schema/sync_schema.json";
35
GetDistributedSchema(const StoreMetaData & meta,Database & database)36 bool RdbSchemaConfig::GetDistributedSchema(const StoreMetaData &meta, Database &database)
37 {
38 OHOS::AppExecFwk::BundleInfo bundleInfo;
39 if (!InitBundleInfo(meta.bundleName, std::atoi(meta.user.c_str()), bundleInfo)) {
40 return false;
41 }
42 std::string storeName = meta.storeId;
43 auto ret = GetSchemaFromHap(bundleInfo, meta.storeId, database);
44 if (ret) {
45 database.user = meta.user;
46 database.deviceId = meta.deviceId;
47 return true;
48 }
49 return false;
50 }
51
InitBundleInfo(const std::string & bundleName,int32_t userId,OHOS::AppExecFwk::BundleInfo & bundleInfo)52 bool RdbSchemaConfig::InitBundleInfo(
53 const std::string &bundleName, int32_t userId, OHOS::AppExecFwk::BundleInfo &bundleInfo)
54 {
55 OHOS::sptr<OHOS::ISystemAbilityManager> systemAbilityManager =
56 OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
57 if (systemAbilityManager == nullptr) {
58 ZLOGE("Fail to get ststem ability mgr, bundleName: %{public}s.", bundleName.c_str());
59 return false;
60 }
61
62 OHOS::sptr<OHOS::IRemoteObject> remoteObject =
63 systemAbilityManager->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
64 if (remoteObject == nullptr) {
65 ZLOGE("Fail to get bundle manager proxy, bundleName: %{public}s.", bundleName.c_str());
66 return false;
67 }
68
69 auto bundleMgrProxy = iface_cast<OHOS::AppExecFwk::BundleMgrProxy>(remoteObject);
70 if (bundleMgrProxy == nullptr) {
71 ZLOGE("Fail to cast proxy, bundleName: %{public}s.", bundleName.c_str());
72 return false;
73 }
74 bool ret = bundleMgrProxy->GetBundleInfo(
75 bundleName, OHOS::AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId);
76 if (!ret || bundleInfo.moduleDirs.size() == 0) {
77 ZLOGE("Get bundle info failed, bundleName: %{public}s.", bundleName.c_str());
78 return false;
79 }
80 return true;
81 }
82
GetSchemaFromHap(const OHOS::AppExecFwk::BundleInfo & bundleInfo,const std::string & storeName,Database & database)83 bool RdbSchemaConfig::GetSchemaFromHap(
84 const OHOS::AppExecFwk::BundleInfo &bundleInfo, const std::string &storeName, Database &database)
85 {
86 for (auto &hapInfo : bundleInfo.hapModuleInfos) {
87 std::shared_ptr<ResourceManager> resMgr(CreateResourceManager());
88 if (resMgr == nullptr) {
89 ZLOGE("Create resourceManager failed");
90 return {};
91 }
92 resMgr->AddResource(hapInfo.hapPath.c_str());
93 size_t length = 0;
94 std::unique_ptr<uint8_t[]> fileContent;
95 int err = resMgr->GetRawFileFromHap(SCHEMA_PATH, length, fileContent);
96 if (err != 0) {
97 continue;
98 }
99 std::string jsonData(fileContent.get(), fileContent.get() + length);
100 DbSchema databases;
101 databases.Unmarshall(jsonData);
102 for (auto &schema : databases.databases) {
103 if (schema.name == storeName) {
104 database = schema;
105 return true;
106 }
107 }
108 }
109 return false;
110 }
111 } // namespace OHOS::DistributedRdb