1 /*
2 * Copyright (c) 2025-2025 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
16 #include "installed_bundle_info_list_query.h"
17
18 #include <system_ability_definition.h>
19
20 #include <vector>
21
22 #include "bundle_info.h"
23 #include "bundle_mgr_proxy.h"
24 #include "edm_errors.h"
25 #include "edm_log.h"
26 #include "edm_sys_manager.h"
27 #include "ipc_skeleton.h"
28
29 namespace OHOS {
30 namespace EDM {
31 const std::string BUNDLE_MANAGER_ASHMEM_NAME = "EdmBundleQueryAshemeName";
32
GetPolicyName()33 std::string InstalledBundleInfoListQuery::GetPolicyName()
34 {
35 return PolicyName::POLICY_INSTALLED_BUNDLE_INFO_LIST;
36 }
37
GetPermission(IPlugin::PermissionType,const std::string & permissionTag)38 std::string InstalledBundleInfoListQuery::GetPermission(IPlugin::PermissionType, const std::string &permissionTag)
39 {
40 return EdmPermission::PERMISSION_ENTERPRISE_GET_ALL_BUNDLE_INFO;
41 }
42
QueryPolicy(std::string & policyData,MessageParcel & data,MessageParcel & reply,int32_t userId)43 ErrCode InstalledBundleInfoListQuery::QueryPolicy(std::string &policyData, MessageParcel &data, MessageParcel &reply,
44 int32_t userId)
45 {
46 EDMLOGI("InstalledBundleInfoListQuery QueryPolicy");
47 auto remoteObject = EdmSysManager::GetRemoteObjectOfSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
48 sptr<AppExecFwk::IBundleMgr> proxy = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
49 if (!proxy) {
50 EDMLOGE("InstalledBundleInfoListQuery QueryPolicy GetAppControlProxy failed.");
51 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
52 }
53
54 const int32_t bundleFlags =
55 static_cast<int32_t>(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
56 static_cast<int32_t>(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO);
57 std::vector<OHOS::AppExecFwk::BundleInfo> bundleInfos;
58 ErrCode getResult = proxy->GetBundleInfosV9(bundleFlags, bundleInfos, userId);
59 if (FAILED(getResult)) {
60 EDMLOGE("InstalledBundleInfoListQuery QueryPolicy getResult failed.");
61 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
62 }
63 if (bundleInfos.empty()) {
64 EDMLOGI("InstalledBundleInfoListQuery QueryPolicy getResult empty.");
65 return ERR_OK;
66 }
67 std::vector<EdmBundleInfo> edmBundleInfos;
68 for (auto &data : bundleInfos) {
69 EdmBundleInfo edmBundleInfo;
70 bool convertRet = ConvertBundleInfoList(data, edmBundleInfo);
71 if (!convertRet) {
72 EDMLOGE("InstalledBundleInfoListQuery QueryPolicy ConvertBundleInfoList failed");
73 continue;
74 }
75 edmBundleInfos.emplace_back(edmBundleInfo);
76 }
77 bool writeRet = WriteVectorToParcelIntelligent(edmBundleInfos, reply);
78 if (!writeRet) {
79 EDMLOGE("InstalledBundleInfoListQuery QueryPolicy WriteVectorToParcelIntelligent failed");
80 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
81 }
82 return ERR_OK;
83 }
84
ConvertBundleInfoList(OHOS::AppExecFwk::BundleInfo & bundleInfo,EdmBundleInfo & edmBundleInfo)85 bool InstalledBundleInfoListQuery::ConvertBundleInfoList(OHOS::AppExecFwk::BundleInfo &bundleInfo,
86 EdmBundleInfo &edmBundleInfo)
87 {
88 edmBundleInfo.versionCode = bundleInfo.versionCode;
89 edmBundleInfo.minCompatibleVersionCode = bundleInfo.minCompatibleVersionCode;
90 edmBundleInfo.targetVersion = bundleInfo.targetVersion;
91 edmBundleInfo.appIndex = bundleInfo.appIndex;
92 edmBundleInfo.installTime = bundleInfo.installTime;
93 edmBundleInfo.updateTime = bundleInfo.updateTime;
94 edmBundleInfo.firstInstallTime = bundleInfo.firstInstallTime;
95 edmBundleInfo.name = bundleInfo.name;
96 edmBundleInfo.vendor = bundleInfo.vendor;
97 edmBundleInfo.versionName = bundleInfo.versionName;
98
99 EdmSignatureInfo edmSignatureInfo;
100 bool signatureRet = ConvertSignatureInfo(bundleInfo.signatureInfo, edmSignatureInfo);
101 if (!signatureRet) {
102 EDMLOGE("InstalledBundleInfoListQuery ConvertSignatureInfo failed");
103 return false;
104 }
105 edmBundleInfo.signatureInfo = edmSignatureInfo;
106
107 EdmApplicationInfo edmApplicationInfo;
108 bool applicationRet = ConvertApplicationInfo(bundleInfo.applicationInfo, edmApplicationInfo);
109 if (!applicationRet) {
110 EDMLOGE("InstalledBundleInfoListQuery ConvertApplicationInfo failed");
111 return false;
112 }
113 edmBundleInfo.applicationInfo = edmApplicationInfo;
114 return true;
115 }
116
ConvertApplicationInfo(OHOS::AppExecFwk::ApplicationInfo & applicationInfo,EdmApplicationInfo & edmApplicationInfo)117 bool InstalledBundleInfoListQuery::ConvertApplicationInfo(OHOS::AppExecFwk::ApplicationInfo &applicationInfo,
118 EdmApplicationInfo &edmApplicationInfo)
119 {
120 edmApplicationInfo.removable = applicationInfo.removable;
121 edmApplicationInfo.isSystemApp = applicationInfo.isSystemApp;
122 edmApplicationInfo.debug = applicationInfo.debug;
123 edmApplicationInfo.userDataClearable = applicationInfo.userDataClearable;
124 edmApplicationInfo.enabled = applicationInfo.enabled;
125 edmApplicationInfo.accessTokenId = applicationInfo.accessTokenId;
126 edmApplicationInfo.iconId = applicationInfo.iconId;
127 edmApplicationInfo.labelId = applicationInfo.labelId;
128 edmApplicationInfo.descriptionId = applicationInfo.descriptionId;
129 edmApplicationInfo.uid = applicationInfo.uid;
130 edmApplicationInfo.appIndex = applicationInfo.appIndex;
131 edmApplicationInfo.name = applicationInfo.name;
132 edmApplicationInfo.description = applicationInfo.description;
133 edmApplicationInfo.label = applicationInfo.label;
134 edmApplicationInfo.icon = applicationInfo.iconPath;
135 edmApplicationInfo.process = applicationInfo.process;
136 edmApplicationInfo.codePath = applicationInfo.codePath;
137 edmApplicationInfo.appDistributionType = applicationInfo.appDistributionType;
138 edmApplicationInfo.appProvisionType = applicationInfo.appProvisionType;
139 edmApplicationInfo.nativeLibraryPath = applicationInfo.nativeLibraryPath;
140 edmApplicationInfo.installSource = applicationInfo.installSource;
141 edmApplicationInfo.apiReleaseType = applicationInfo.apiReleaseType;
142
143 EdmResource iconResource;
144 ConvertResourceInfo(applicationInfo.iconResource, iconResource);
145 edmApplicationInfo.iconResource = iconResource;
146
147 EdmResource labelResource;
148 ConvertResourceInfo(applicationInfo.labelResource, labelResource);
149 edmApplicationInfo.labelResource = labelResource;
150
151 EdmResource descriptionResource;
152 ConvertResourceInfo(applicationInfo.descriptionResource, descriptionResource);
153 edmApplicationInfo.descriptionResource = descriptionResource;
154 return true;
155 }
156
ConvertResourceInfo(OHOS::AppExecFwk::Resource & resource,EdmResource & edmResource)157 bool InstalledBundleInfoListQuery::ConvertResourceInfo(OHOS::AppExecFwk::Resource &resource, EdmResource &edmResource)
158 {
159 edmResource.id = resource.id;
160 edmResource.bundleName = resource.bundleName;
161 edmResource.moduleName = resource.moduleName;
162 return true;
163 }
164
ConvertSignatureInfo(OHOS::AppExecFwk::SignatureInfo & signatureInfo,EdmSignatureInfo & edmSignatureInfo)165 bool InstalledBundleInfoListQuery::ConvertSignatureInfo(OHOS::AppExecFwk::SignatureInfo &signatureInfo,
166 EdmSignatureInfo &edmSignatureInfo)
167 {
168 edmSignatureInfo.appId = signatureInfo.appId;
169 edmSignatureInfo.fingerprint = signatureInfo.fingerprint;
170 edmSignatureInfo.appIdentifier = signatureInfo.appIdentifier;
171 edmSignatureInfo.certificate = signatureInfo.certificate;
172 return true;
173 }
174
WriteVectorToParcelIntelligent(std::vector<EdmBundleInfo> & parcelableVector,MessageParcel & reply)175 bool InstalledBundleInfoListQuery::WriteVectorToParcelIntelligent(std::vector<EdmBundleInfo> &parcelableVector,
176 MessageParcel &reply)
177 {
178 MessageParcel tempParcel;
179 (void)tempParcel.SetMaxCapacity(EdmConstants::MAX_PARCEL_CAPACITY);
180 if (!tempParcel.WriteInt32(parcelableVector.size())) {
181 EDMLOGE("write ParcelableVector failed");
182 return false;
183 }
184
185 for (auto &parcelable : parcelableVector) {
186 if (!tempParcel.WriteParcelable(&parcelable)) {
187 EDMLOGE("write ParcelableVector failed");
188 return false;
189 }
190 }
191 reply.WriteInt32(ERR_OK);
192 size_t dataSize = tempParcel.GetDataSize();
193 if (!reply.WriteInt32(static_cast<int32_t>(dataSize))) {
194 EDMLOGE("write WriteInt32 failed");
195 return false;
196 }
197
198 if (dataSize > EdmConstants::MAX_IPC_RAWDATA_SIZE) {
199 (void)tempParcel.SetMaxCapacity(EdmConstants::MAX_PARCEL_CAPACITY_OF_ASHMEM);
200 int32_t callingUid = IPCSkeleton::GetCallingUid();
201 EDMLOGI("datasize is too large, use ashmem %{public}d", callingUid);
202 return WriteParcelableIntoAshmem(tempParcel, reply);
203 }
204 EDMLOGI("write to raw data");
205 if (!reply.WriteRawData(reinterpret_cast<uint8_t *>(tempParcel.GetData()), dataSize)) {
206 EDMLOGE("Failed to write data");
207 return false;
208 }
209 return true;
210 }
211
WriteParcelableIntoAshmem(MessageParcel & tempParcel,MessageParcel & reply)212 bool InstalledBundleInfoListQuery::WriteParcelableIntoAshmem(MessageParcel &tempParcel, MessageParcel &reply)
213 {
214 size_t dataSize = tempParcel.GetDataSize();
215 // The ashmem name must be unique.
216 sptr<Ashmem> ashmem = Ashmem::CreateAshmem(
217 (BUNDLE_MANAGER_ASHMEM_NAME + std::to_string(AllocatAshmemNum())).c_str(), dataSize);
218 if (ashmem == nullptr) {
219 EDMLOGE("Create shared memory failed");
220 return false;
221 }
222
223 // Set the read/write mode of the ashme.
224 if (!ashmem->MapReadAndWriteAshmem()) {
225 EDMLOGE("Map shared memory fail");
226 return false;
227 }
228
229 // Write the size and content of each item to the ashmem.
230 int32_t offset = 0;
231 if (!ashmem->WriteToAshmem(reinterpret_cast<uint8_t *>(tempParcel.GetData()), dataSize, offset)) {
232 EDMLOGE("Write info to shared memory fail");
233 return false;
234 }
235
236 if (!reply.WriteAshmem(ashmem)) {
237 EDMLOGE("Write ashmem to tempParcel fail");
238 return false;
239 }
240 return true;
241 }
242
AllocatAshmemNum()243 int32_t InstalledBundleInfoListQuery::AllocatAshmemNum()
244 {
245 std::lock_guard<std::mutex> lock(bundleAshmemMutex_);
246 return ashmemNum_++;
247 }
248
249 } // namespace EDM
250 } // namespace OHOS