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