1 /*
2 * Copyright (c) 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 "plugin_installer.h"
17
18 #include <fcntl.h>
19 #include <iostream>
20 #include <sstream>
21
22 #include "app_log_tag_wrapper.h"
23 #include "app_provision_info_manager.h"
24 #include "bundle_mgr_service.h"
25 #include "bundle_permission_mgr.h"
26 #include "bundle_util.h"
27 #include "hitrace_meter.h"
28 #include "installd_client.h"
29 #include "ipc_skeleton.h"
30 #include "json_util.h"
31 #include "scope_guard.h"
32
33 namespace OHOS {
34 namespace AppExecFwk {
35 using namespace OHOS::Security;
36 namespace {
37 constexpr const char* COMPILE_SDK_TYPE_OPEN_HARMONY = "OpenHarmony";
38 constexpr const char* DEBUG_APP_IDENTIFIER = "DEBUG_LIB_ID";
39 constexpr const char* PLUGINS = "+plugins";
40 constexpr const char* LIBS_TMP = "libs_tmp";
41 constexpr const char* PERMISSION_KEY = "ohos.permission.kernel.SUPPORT_PLUGIN";
42 constexpr const char* PLUGIN_ID = "pluginDistributionIDs";
43 constexpr const char* PLUGIN_ID_SEPARATOR = ",";
44 constexpr const char* PLUGIN_ID_SEPARATOR_OTHER = "|";
45 constexpr const char* REMOVE_TMP_SUFFIX = "_removed";
46 constexpr const char* APP_INSTALL_SANDBOX_PATH = "/data/bms_app_install/";
47 constexpr const char* APP_INSTALL_PATH = "/data/app/el1/bundle";
48 }
49
PluginInstaller()50 PluginInstaller::PluginInstaller()
51 : bundleInstallChecker_(std::make_unique<BundleInstallChecker>())
52 {
53 APP_LOGD("create PluginInstaller instance");
54 }
55
~PluginInstaller()56 PluginInstaller::~PluginInstaller()
57 {
58 APP_LOGD("destroy PluginInstaller instance");
59 BundleUtil::DeleteTempDirs(toDeleteTempHspPath_);
60 toDeleteTempHspPath_.clear();
61 }
62
InstallPlugin(const std::string & hostBundleName,const std::vector<std::string> & pluginFilePaths,const InstallPluginParam & installPluginParam)63 ErrCode PluginInstaller::InstallPlugin(const std::string &hostBundleName,
64 const std::vector<std::string> &pluginFilePaths, const InstallPluginParam &installPluginParam)
65 {
66 HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr);
67 LOG_NOFUNC_I(BMS_TAG_INSTALLER, "begin to install plugin for %{public}s", hostBundleName.c_str());
68
69 if (!InitDataMgr()) {
70 return ERR_APPEXECFWK_NULL_PTR;
71 }
72 // check userId
73 if (installPluginParam.userId < Constants::DEFAULT_USERID) {
74 APP_LOGE("userId(%{public}d) invalid", installPluginParam.userId);
75 return ERR_APPEXECFWK_USER_NOT_EXIST;
76 }
77 if (!dataMgr_->HasUserId(installPluginParam.userId)) {
78 APP_LOGE("user %{public}d not exist", installPluginParam.userId);
79 return ERR_APPEXECFWK_USER_NOT_EXIST;
80 }
81 auto &mtx = dataMgr_->GetBundleMutex(hostBundleName);
82 std::lock_guard lock {mtx};
83 // check host application exist in userId
84 InnerBundleInfo hostBundleInfo;
85 if (!dataMgr_->FetchInnerBundleInfo(hostBundleName, hostBundleInfo)) {
86 APP_LOGE("hostBundleName:%{public}s get bundle info failed", hostBundleName.c_str());
87 return ERR_APPEXECFWK_HOST_APPLICATION_NOT_FOUND;
88 }
89 if (!hostBundleInfo.HasInnerBundleUserInfo(installPluginParam.userId)) {
90 APP_LOGE("HostBundleName: %{public}s not installed in user %{public}d",
91 hostBundleName.c_str(), installPluginParam.userId);
92 return ERR_APPEXECFWK_HOST_APPLICATION_NOT_FOUND;
93 }
94 userId_ = installPluginParam.userId;
95 // check host application permission
96 ErrCode result = ERR_OK;
97 result = CheckSupportPluginPermission(hostBundleInfo.GetBundleName());
98 CHECK_RESULT(result, "check host application permission failed %{public}d");
99 // parse hsp file
100 result = ParseFiles(pluginFilePaths, installPluginParam);
101 CHECK_RESULT(result, "parse file failed %{public}d");
102 if (bundleName_ == hostBundleName) {
103 APP_LOGE("plugin name:%{public}s same as host bundle name", bundleName_.c_str());
104 return ERR_APPEXECFWK_PLUGIN_INSTALL_SAME_BUNDLE_NAME;
105 }
106 bundleNameWithTime_ = bundleName_ + "." + std::to_string(BundleUtil::GetCurrentTimeNs());
107 // check host application and plugin
108 result = CheckPluginId(hostBundleName);
109 CHECK_RESULT(result, "check pluginId failed %{public}d");
110
111 result = ProcessPluginInstall(hostBundleInfo);
112 CHECK_RESULT(result, "process plugin install failed %{public}d");
113
114 int32_t uid = hostBundleInfo.GetUid(userId_);
115 NotifyPluginEvents(isPluginExist_ ? NotifyType::UPDATE : NotifyType::INSTALL, uid);
116 LOG_NOFUNC_I(BMS_TAG_INSTALLER, "install plugin finished");
117 return ERR_OK;
118 }
119
UninstallPlugin(const std::string & hostBundleName,const std::string & pluginBundleName,const InstallPluginParam & installPluginParam)120 ErrCode PluginInstaller::UninstallPlugin(const std::string &hostBundleName, const std::string &pluginBundleName,
121 const InstallPluginParam &installPluginParam)
122 {
123 HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr);
124 LOG_NOFUNC_I(BMS_TAG_INSTALLER, "begin to uninstall plugin %{public}s for %{public}s",
125 pluginBundleName.c_str(), hostBundleName.c_str());
126
127 ErrCode result = ERR_OK;
128 if (!InitDataMgr()) {
129 return ERR_APPEXECFWK_NULL_PTR;
130 }
131 // check userId
132 if (installPluginParam.userId < Constants::DEFAULT_USERID) {
133 APP_LOGE("userId(%{public}d) invalid", installPluginParam.userId);
134 return ERR_APPEXECFWK_USER_NOT_EXIST;
135 }
136 if (!dataMgr_->HasUserId(installPluginParam.userId)) {
137 APP_LOGE("user %{public}d not exist", installPluginParam.userId);
138 return ERR_APPEXECFWK_USER_NOT_EXIST;
139 }
140 auto &mtx = dataMgr_->GetBundleMutex(hostBundleName);
141 std::lock_guard lock {mtx};
142 // check host application exist in userId
143 InnerBundleInfo hostBundleInfo;
144 if (!dataMgr_->FetchInnerBundleInfo(hostBundleName, hostBundleInfo)) {
145 APP_LOGE("hostBundleName:%{public}s get bundle info failed", hostBundleName.c_str());
146 return ERR_APPEXECFWK_HOST_APPLICATION_NOT_FOUND;
147 }
148 if (!hostBundleInfo.HasInnerBundleUserInfo(installPluginParam.userId)) {
149 APP_LOGE("HostBundleName: %{public}s not installed in user %{public}d",
150 hostBundleName.c_str(), installPluginParam.userId);
151 return ERR_APPEXECFWK_HOST_APPLICATION_NOT_FOUND;
152 }
153 // check plugin exist in host application
154 isPluginExist_ = dataMgr_->GetPluginBundleInfo(hostBundleName, pluginBundleName,
155 installPluginParam.userId, oldPluginInfo_);
156 if (!isPluginExist_) {
157 APP_LOGE("plugin: %{public}s not installed in host application:%{public}s user %{public}d",
158 pluginBundleName.c_str(), hostBundleName.c_str(), installPluginParam.userId);
159 return ERR_APPEXECFWK_PLUGIN_NOT_FOUND;
160 }
161 userId_ = installPluginParam.userId;
162 bundleName_ = pluginBundleName;
163 result = ProcessPluginUninstall(hostBundleInfo);
164 CHECK_RESULT(result, "process plugin install failed %{public}d");
165
166 int32_t uid = hostBundleInfo.GetUid(userId_);
167 NotifyPluginEvents(NotifyType::UNINSTALL_BUNDLE, uid);
168 LOG_NOFUNC_I(BMS_TAG_INSTALLER, "uninstall plugin finish");
169 return ERR_OK;
170 }
171
ParseFiles(const std::vector<std::string> & pluginFilePaths,const InstallPluginParam & installPluginParam)172 ErrCode PluginInstaller::ParseFiles(const std::vector<std::string> &pluginFilePaths,
173 const InstallPluginParam &installPluginParam)
174 {
175 APP_LOGD("parsing plugin bundle files, path : %{private}s",
176 GetJsonStrFromInfo(pluginFilePaths).c_str());
177 ErrCode result = ERR_OK;
178
179 std::vector<std::string> parsedPaths;
180 result = ParseHapPaths(installPluginParam, pluginFilePaths, parsedPaths);
181 CHECK_RESULT(result, "hsp file parse failed %{public}d");
182 // check file paths
183 std::vector<std::string> inBundlePaths;
184 result = BundleUtil::CheckFilePath(parsedPaths, inBundlePaths);
185 CHECK_RESULT(result, "hsp files check failed %{public}d");
186
187 // copy the haps to the dir which cannot be accessed from caller
188 result = CopyHspToSecurityDir(inBundlePaths, installPluginParam);
189 CHECK_RESULT(result, "copy file failed %{public}d");
190
191 // check number and type of the hsp and sig files
192 std::vector<std::string> bundlePaths;
193 result = ObtainHspFileAndSignatureFilePath(inBundlePaths, bundlePaths, signatureFileDir_);
194 CHECK_RESULT(result, "obtain hsp file path or signature file path failed due to %{public}d");
195
196 // check syscap
197 result = bundleInstallChecker_->CheckSysCap(bundlePaths);
198 bool isSysCapValid = (result == ERR_OK);
199 if (!isSysCapValid) {
200 APP_LOGI("hap syscap check failed %{public}d", result);
201 }
202 // verify signature info for all haps
203 std::vector<Security::Verify::HapVerifyResult> hapVerifyResults;
204 result = bundleInstallChecker_->CheckMultipleHapsSignInfo(bundlePaths, hapVerifyResults);
205 if (result != ERR_OK) {
206 APP_LOGE("check multi hap signature info failed %{public}d", result);
207 return ERR_APPEXECFWK_INSTALL_FAILED_BUNDLE_SIGNATURE_VERIFICATION_FAILURE;
208 }
209
210 // parse bundle infos
211 InstallCheckParam checkParam;
212 checkParam.needSendEvent = false;
213 result = bundleInstallChecker_->ParseHapFiles(bundlePaths, checkParam, hapVerifyResults, parsedBundles_);
214 if (result != ERR_OK) {
215 APP_LOGE("parse haps file failed %{public}d", result);
216 return ERR_APPEXECFWK_PLUGIN_PARSER_ERROR;
217 }
218 if (!parsedBundles_.empty() &&
219 parsedBundles_.begin()->second.GetApplicationBundleType() != BundleType::APP_PLUGIN) {
220 result = ERR_APPEXECFWK_PLUGIN_INSTALL_NOT_ALLOW;
221 CHECK_RESULT(result, "plugin bundle type %{public}d");
222 }
223
224 // check hsp install condition
225 result = bundleInstallChecker_->CheckHspInstallCondition(hapVerifyResults);
226 CHECK_RESULT(result, "check hsp install condition failed %{public}d");
227
228 // check device type
229 if (!isSysCapValid) {
230 result = bundleInstallChecker_->CheckDeviceType(parsedBundles_);
231 if (result != ERR_OK) {
232 APP_LOGE("check device type failed %{public}d", result);
233 return ERR_APPEXECFWK_INSTALL_SYSCAP_FAILED_AND_DEVICE_TYPE_ERROR;
234 }
235 }
236
237 // check label info
238 result = CheckPluginAppLabelInfo();
239 CHECK_RESULT(result, "check plugin label info failed %{public}d");
240
241 // delivery sign profile to code signature
242 result = DeliveryProfileToCodeSign(hapVerifyResults);
243 CHECK_RESULT(result, "delivery sign profile failed %{public}d");
244
245 // check native file
246 result = bundleInstallChecker_->CheckMultiNativeFile(parsedBundles_);
247 CHECK_RESULT(result, "native so is incompatible in all haps %{public}d");
248
249 // check enterprise bundle
250 /* At this place, hapVerifyResults cannot be empty and unnecessary to check it */
251 isEnterpriseBundle_ = bundleInstallChecker_->CheckEnterpriseBundle(hapVerifyResults[0]);
252 appIdentifier_ = (hapVerifyResults[0].GetProvisionInfo().type == Security::Verify::ProvisionType::DEBUG) ?
253 DEBUG_APP_IDENTIFIER : hapVerifyResults[0].GetProvisionInfo().bundleInfo.appIdentifier;
254 compileSdkType_ = parsedBundles_.empty() ? COMPILE_SDK_TYPE_OPEN_HARMONY :
255 (parsedBundles_.begin()->second).GetBaseApplicationInfo().compileSdkType;
256 if (!ParsePluginId(hapVerifyResults[0].GetProvisionInfo().appServiceCapabilities, pluginIds_)) {
257 APP_LOGE("parse plugin id failed");
258 return ERR_APPEXECFWK_PLUGIN_INSTALL_PARSE_PLUGINID_ERROR;
259 }
260 isDebug_ = (hapVerifyResults[0].GetProvisionInfo().type == Security::Verify::ProvisionType::DEBUG) ?
261 true : false;
262 return result;
263 }
264
MkdirIfNotExist(const std::string & dir)265 ErrCode PluginInstaller::MkdirIfNotExist(const std::string &dir)
266 {
267 bool isDirExist = false;
268 ErrCode result = InstalldClient::GetInstance()->IsExistDir(dir, isDirExist);
269 CHECK_RESULT(result, "check if dir exist failed %{public}d");
270 if (!isDirExist) {
271 result = InstalldClient::GetInstance()->CreateBundleDir(dir);
272 CHECK_RESULT(result, "create dir failed %{public}d");
273 }
274 return result;
275 }
276
ParseHapPaths(const InstallPluginParam & installPluginParam,const std::vector<std::string> & inBundlePaths,std::vector<std::string> & parsedPaths)277 ErrCode PluginInstaller::ParseHapPaths(const InstallPluginParam &installPluginParam,
278 const std::vector<std::string> &inBundlePaths, std::vector<std::string> &parsedPaths)
279 {
280 parsedPaths.reserve(inBundlePaths.size());
281 if (!inBundlePaths.empty() && inBundlePaths.front().find(APP_INSTALL_SANDBOX_PATH) != 0) {
282 for (auto &bundlePath : inBundlePaths) {
283 if (bundlePath.find("..") != std::string::npos) {
284 APP_LOGE("path invalid: %{public}s", bundlePath.c_str());
285 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
286 }
287 parsedPaths.emplace_back(bundlePath);
288 }
289 return ERR_OK;
290 }
291 APP_LOGI("rename install");
292 const std::string newPrefix = std::string(ServiceConstants::BUNDLE_MANAGER_SERVICE_PATH) +
293 ServiceConstants::GALLERY_DOWNLOAD_PATH + std::to_string(userId_) + ServiceConstants::PATH_SEPARATOR;
294
295 for (const auto &bundlePath : inBundlePaths) {
296 if (bundlePath.find("..") != std::string::npos) {
297 APP_LOGE("path invalid: %{public}s", bundlePath.c_str());
298 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
299 }
300 if (bundlePath.find(APP_INSTALL_SANDBOX_PATH) == 0) {
301 std::string newPath = newPrefix + bundlePath.substr(std::strlen(APP_INSTALL_SANDBOX_PATH));
302 parsedPaths.push_back(newPath);
303 APP_LOGD("parsed path: %{public}s", newPath.c_str());
304 } else {
305 APP_LOGE("path invalid: %{public}s", bundlePath.c_str());
306 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
307 }
308 }
309 return ERR_OK;
310 }
311
CopyHspToSecurityDir(std::vector<std::string> & bundlePaths,const InstallPluginParam & installPluginParam)312 ErrCode PluginInstaller::CopyHspToSecurityDir(std::vector<std::string> &bundlePaths,
313 const InstallPluginParam &installPluginParam)
314 {
315 for (size_t index = 0; index < bundlePaths.size(); ++index) {
316 if (!BundleUtil::CheckSystemSize(bundlePaths[index], APP_INSTALL_PATH)) {
317 APP_LOGE("install %{public}s failed insufficient disk memory", bundlePaths[index].c_str());
318 return ERR_APPEXECFWK_INSTALL_DISK_MEM_INSUFFICIENT;
319 }
320 auto destination = BundleUtil::CopyFileToSecurityDir(bundlePaths[index], DirType::STREAM_INSTALL_DIR,
321 toDeleteTempHspPath_, installPluginParam.IsRenameInstall());
322 if (destination.empty()) {
323 APP_LOGE("copy file %{public}s to security dir failed", bundlePaths[index].c_str());
324 return ERR_APPEXECFWK_INSTALL_COPY_HAP_FAILED;
325 }
326 bundlePaths[index] = destination;
327 }
328 return ERR_OK;
329 }
330
ObtainHspFileAndSignatureFilePath(const std::vector<std::string> & inBundlePaths,std::vector<std::string> & bundlePaths,std::string & signatureFilePath)331 ErrCode PluginInstaller::ObtainHspFileAndSignatureFilePath(const std::vector<std::string> &inBundlePaths,
332 std::vector<std::string> &bundlePaths, std::string &signatureFilePath)
333 {
334 if (inBundlePaths.empty()) {
335 APP_LOGE("number of files in single shared lib path is illegal");
336 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
337 }
338 if (inBundlePaths.size() == 1) {
339 if (!BundleUtil::EndWith(inBundlePaths[0], ServiceConstants::HSP_FILE_SUFFIX)) {
340 APP_LOGE("invalid file in plugin bundle dir");
341 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
342 }
343 bundlePaths.emplace_back(inBundlePaths[0]);
344 return ERR_OK;
345 }
346 int32_t numberOfHsp = 0;
347 int32_t numberOfSignatureFile = 0;
348 for (const auto &path : inBundlePaths) {
349 if ((path.find(ServiceConstants::HSP_FILE_SUFFIX) == std::string::npos) &&
350 (path.find(ServiceConstants::CODE_SIGNATURE_FILE_SUFFIX) == std::string::npos)) {
351 APP_LOGE("only hsp or sig file can be contained in shared bundle dir");
352 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
353 }
354 if (BundleUtil::EndWith(path, ServiceConstants::HSP_FILE_SUFFIX)) {
355 numberOfHsp++;
356 bundlePaths.emplace_back(path);
357 }
358 if (BundleUtil::EndWith(path, ServiceConstants::CODE_SIGNATURE_FILE_SUFFIX)) {
359 numberOfSignatureFile++;
360 signatureFilePath = path;
361 }
362 }
363 APP_LOGD("signatureFilePath is %{public}s", signatureFilePath.c_str());
364 return ERR_OK;
365 }
366
ProcessNativeLibrary(const std::string & bundlePath,const std::string & moduleDir,const std::string & moduleName,const std::string & pluginBundleDir,InnerBundleInfo & newInfo)367 ErrCode PluginInstaller::ProcessNativeLibrary(
368 const std::string &bundlePath,
369 const std::string &moduleDir,
370 const std::string &moduleName,
371 const std::string &pluginBundleDir,
372 InnerBundleInfo &newInfo)
373 {
374 std::string cpuAbi;
375 if (!newInfo.FetchNativeSoAttrs(moduleName, cpuAbi, nativeLibraryPath_)) {
376 return ERR_OK;
377 }
378 isCompressNativeLibs_ = newInfo.IsCompressNativeLibs(moduleName);
379 if (isCompressNativeLibs_) {
380 if (nativeLibraryPath_.empty()) {
381 APP_LOGW("nativeLibraryPath is empty");
382 return ERR_OK;
383 }
384 std::string soPath = pluginBundleDir + ServiceConstants::PATH_SEPARATOR + nativeLibraryPath_;
385 APP_LOGD("tempSoPath=%{public}s,cpuAbi=%{public}s, bundlePath=%{public}s",
386 soPath.c_str(), cpuAbi.c_str(), bundlePath.c_str());
387
388 auto result = InstalldClient::GetInstance()->ExtractModuleFiles(bundlePath, moduleDir, soPath, cpuAbi);
389 CHECK_RESULT(result, "extract module files failed %{public}d");
390 // verify hap or hsp code signature for compressed so files
391 result = VerifyCodeSignatureForNativeFiles(
392 bundlePath, cpuAbi, soPath, signatureFileDir_, newInfo.IsPreInstallApp());
393 CHECK_RESULT(result, "fail to VerifyCodeSignature, error is %{public}d");
394 cpuAbi_ = cpuAbi;
395 soPath_ = soPath;
396 } else {
397 std::vector<std::string> fileNames;
398 auto result = InstalldClient::GetInstance()->GetNativeLibraryFileNames(bundlePath, cpuAbi, fileNames);
399 CHECK_RESULT(result, "fail to GetNativeLibraryFileNames, error is %{public}d");
400 newInfo.SetNativeLibraryFileNames(moduleName, fileNames);
401 }
402 return ERR_OK;
403 }
404
VerifyCodeSignatureForNativeFiles(const std::string & bundlePath,const std::string & cpuAbi,const std::string & targetSoPath,const std::string & signatureFileDir,bool isPreInstalledBundle) const405 ErrCode PluginInstaller::VerifyCodeSignatureForNativeFiles(const std::string &bundlePath,
406 const std::string &cpuAbi, const std::string &targetSoPath, const std::string &signatureFileDir,
407 bool isPreInstalledBundle) const
408 {
409 if (!isPreInstalledBundle) {
410 APP_LOGD("not pre-install app, skip verify code signature for native files");
411 return ERR_OK;
412 }
413 APP_LOGD("begin to verify code signature for hsp native files");
414 bool isCompileSdkOpenHarmony = (compileSdkType_ == COMPILE_SDK_TYPE_OPEN_HARMONY);
415 CodeSignatureParam codeSignatureParam;
416 codeSignatureParam.modulePath = bundlePath;
417 codeSignatureParam.cpuAbi = cpuAbi;
418 codeSignatureParam.targetSoPath = targetSoPath;
419 codeSignatureParam.signatureFileDir = signatureFileDir;
420 codeSignatureParam.isEnterpriseBundle = isEnterpriseBundle_;
421 codeSignatureParam.appIdentifier = appIdentifier_;
422 codeSignatureParam.isCompileSdkOpenHarmony = isCompileSdkOpenHarmony;
423 codeSignatureParam.isPreInstalledBundle = isPreInstalledBundle;
424 codeSignatureParam.isCompressNativeLibrary = isCompressNativeLibs_;
425 if (InstalldClient::GetInstance()->VerifyCodeSignature(codeSignatureParam) != ERR_OK) {
426 return ERR_BUNDLEMANAGER_INSTALL_CODE_SIGNATURE_FAILED;
427 }
428 return ERR_OK;
429 }
430
VerifyCodeSignatureForHsp(const std::string & hspPath,const std::string & appIdentifier,bool isEnterpriseBundle,bool isCompileSdkOpenHarmony) const431 ErrCode PluginInstaller::VerifyCodeSignatureForHsp(const std::string &hspPath,
432 const std::string &appIdentifier, bool isEnterpriseBundle, bool isCompileSdkOpenHarmony) const
433 {
434 APP_LOGI("begin to verify code signature for hsp, isDebug: %{public}d", isDebug_);
435 CodeSignatureParam codeSignatureParam;
436 codeSignatureParam.modulePath = hspPath;
437 codeSignatureParam.cpuAbi = cpuAbi_;
438 codeSignatureParam.targetSoPath = soPath_;
439 codeSignatureParam.appIdentifier = appIdentifier;
440 codeSignatureParam.signatureFileDir = signatureFileDir_;
441 codeSignatureParam.isEnterpriseBundle = isEnterpriseBundle;
442 codeSignatureParam.isCompileSdkOpenHarmony = isCompileSdkOpenHarmony;
443 codeSignatureParam.isPreInstalledBundle = false;
444 codeSignatureParam.isPlugin = true;
445 codeSignatureParam.pluginId = isDebug_ ? JoinPluginId() : Constants::EMPTY_STRING;
446 if (InstalldClient::GetInstance()->VerifyCodeSignatureForHap(codeSignatureParam) != ERR_OK) {
447 return ERR_BUNDLEMANAGER_INSTALL_CODE_SIGNATURE_FAILED;
448 }
449 return ERR_OK;
450 }
451
JoinPluginId() const452 std::string PluginInstaller::JoinPluginId() const
453 {
454 if (pluginIds_.empty()) {
455 return Constants::EMPTY_STRING;
456 }
457 std::ostringstream oss;
458 for (size_t i = 0; i < pluginIds_.size(); ++i) {
459 if (i != 0) {
460 oss << std::string(PLUGIN_ID_SEPARATOR);
461 }
462 oss << pluginIds_[i];
463 }
464 return oss.str();
465 }
466
DeliveryProfileToCodeSign(std::vector<Security::Verify::HapVerifyResult> & hapVerifyResults) const467 ErrCode PluginInstaller::DeliveryProfileToCodeSign(
468 std::vector<Security::Verify::HapVerifyResult> &hapVerifyResults) const
469 {
470 if (hapVerifyResults.empty()) {
471 APP_LOGE("no sign info in the all haps");
472 return ERR_APPEXECFWK_INSTALL_FAILED_INCOMPATIBLE_SIGNATURE;
473 }
474
475 Security::Verify::ProvisionInfo provisionInfo = hapVerifyResults[0].GetProvisionInfo();
476 if (provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE ||
477 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_NORMAL ||
478 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_MDM ||
479 provisionInfo.type == Security::Verify::ProvisionType::DEBUG) {
480 if (provisionInfo.profileBlockLength == 0 || provisionInfo.profileBlock == nullptr) {
481 APP_LOGE("invalid sign profile");
482 return ERR_APPEXECFWK_INSTALL_FAILED_INCOMPATIBLE_SIGNATURE;
483 }
484 return InstalldClient::GetInstance()->DeliverySignProfile(provisionInfo.bundleInfo.bundleName,
485 provisionInfo.profileBlockLength, provisionInfo.profileBlock.get());
486 }
487 return ERR_OK;
488 }
489
CheckPluginId(const std::string & hostBundleName)490 ErrCode PluginInstaller::CheckPluginId(const std::string &hostBundleName)
491 {
492 if (pluginIds_.empty()) {
493 APP_LOGE("plugin id is empty");
494 return ERR_APPEXECFWK_PLUGIN_INSTALL_CHECK_PLUGINID_ERROR;
495 }
496 auto appProvisionInfoMgr = DelayedSingleton<AppProvisionInfoManager>::GetInstance();
497 if (!appProvisionInfoMgr) {
498 APP_LOGE("appProvisionInfoMgr is nullptr");
499 return ERR_APPEXECFWK_NULL_PTR;
500 }
501 AppProvisionInfo hostAppProvisionInfo;
502 if (!appProvisionInfoMgr->GetAppProvisionInfo(hostBundleName, hostAppProvisionInfo)) {
503 APP_LOGW("bundleName:%{public}s GetAppProvisionInfo failed", hostBundleName.c_str());
504 return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
505 }
506 std::vector<std::string> hostPluginIds;
507 if (!ParsePluginId(hostAppProvisionInfo.appServiceCapabilities, hostPluginIds)) {
508 APP_LOGE("parse host application plugin id failed");
509 return ERR_APPEXECFWK_PLUGIN_INSTALL_PARSE_PLUGINID_ERROR;
510 }
511 if (hostPluginIds.empty()) {
512 APP_LOGE("host application plugin id is empty");
513 return ERR_APPEXECFWK_PLUGIN_INSTALL_CHECK_PLUGINID_ERROR;
514 }
515 std::unordered_set<std::string> pluginIdSet(hostPluginIds.begin(), hostPluginIds.end());
516 for (const auto &item : pluginIds_) {
517 if (pluginIdSet.find(item) != pluginIdSet.end()) {
518 return ERR_OK;
519 }
520 }
521 APP_LOGD("check plugin id success");
522 return ERR_APPEXECFWK_PLUGIN_INSTALL_CHECK_PLUGINID_ERROR;
523 }
524
ParsePluginId(const std::string & appServiceCapabilities,std::vector<std::string> & pluginIds)525 bool PluginInstaller::ParsePluginId(const std::string &appServiceCapabilities,
526 std::vector<std::string> &pluginIds)
527 {
528 if (appServiceCapabilities.empty()) {
529 APP_LOGE("appServiceCapabilities is empty");
530 return false;
531 }
532 auto appServiceCapabilityMap = BundleUtil::ParseMapFromJson(appServiceCapabilities);
533 for (auto &item : appServiceCapabilityMap) {
534 if (item.first == PERMISSION_KEY) {
535 std::unordered_map<std::string, std::string> pluginIdMap = BundleUtil::ParseMapFromJson(item.second);
536 auto it = pluginIdMap.find(PLUGIN_ID);
537 if (it == pluginIdMap.end()) {
538 APP_LOGE("pluginDistributionIDs not found in appServiceCapability");
539 return false;
540 }
541 if (it->second.find(PLUGIN_ID_SEPARATOR_OTHER) != std::string::npos) {
542 OHOS::SplitStr(it->second, PLUGIN_ID_SEPARATOR_OTHER, pluginIds);
543 } else {
544 OHOS::SplitStr(it->second, PLUGIN_ID_SEPARATOR, pluginIds);
545 }
546 return true;
547 }
548 }
549 APP_LOGE("support plugin permission not found in appServiceCapability");
550 return false;
551 }
552
CheckSupportPluginPermission(const std::string & hostBundleName)553 ErrCode PluginInstaller::CheckSupportPluginPermission(const std::string &hostBundleName)
554 {
555 if (BundlePermissionMgr::VerifyPermission(hostBundleName, ServiceConstants::PERMISSION_SUPPORT_PLUGIN,
556 userId_) == AccessToken::PermissionState::PERMISSION_GRANTED) {
557 APP_LOGD("verify support plugin permission success");
558 return ERR_OK;
559 }
560 return ERR_APPEXECFWK_SUPPORT_PLUGIN_PERMISSION_ERROR;
561 }
562
CheckPluginAppLabelInfo()563 ErrCode PluginInstaller::CheckPluginAppLabelInfo()
564 {
565 if (parsedBundles_.empty()) {
566 APP_LOGE("parsedBundles is empty");
567 return ERR_OK;
568 }
569 bundleName_ = parsedBundles_.begin()->second.GetBundleName();
570
571 ErrCode ret = bundleInstallChecker_->CheckAppLabelInfo(parsedBundles_);
572 if (ret != ERR_OK) {
573 APP_LOGE("check plugin app label info failed");
574 return ERR_APPEXECFWK_PLUGIN_CHECK_APP_LABEL_ERROR;
575 }
576 return ERR_OK;
577 }
578
ProcessPluginInstall(const InnerBundleInfo & hostBundleInfo)579 ErrCode PluginInstaller::ProcessPluginInstall(const InnerBundleInfo &hostBundleInfo)
580 {
581 if (parsedBundles_.empty()) {
582 APP_LOGD("no bundle to install");
583 return ERR_OK;
584 }
585 if (!InitDataMgr()) {
586 return ERR_APPEXECFWK_NULL_PTR;
587 }
588 ErrCode result = ERR_OK;
589 std::string pluginDir;
590 result = CreatePluginDir(hostBundleInfo.GetBundleName(), pluginDir);
591 CHECK_RESULT(result, "plugin dir check failed %{public}d");
592 isPluginExist_ = dataMgr_->FetchPluginBundleInfo(hostBundleInfo.GetBundleName(), bundleName_, oldPluginInfo_);
593 if (isPluginExist_) {
594 if (!CheckAppIdentifier()) {
595 return ERR_APPEXECFWK_INSTALL_FAILED_INCONSISTENT_SIGNATURE;
596 }
597 if (!CheckVersionCodeForUpdate()) {
598 return ERR_APPEXECFWK_INSTALL_VERSION_DOWNGRADE;
599 }
600 }
601 ScopeGuard deleteDirGuard([&] { RemovePluginDir(hostBundleInfo);});
602 for (auto &item : parsedBundles_) {
603 result = ExtractPluginBundles(item.first, item.second, pluginDir);
604 CHECK_RESULT(result, "extract plugin bundles failed %{public}d");
605 }
606
607 ScopeGuard dataRollBackGuard([&] { PluginRollBack(hostBundleInfo.GetBundleName());});
608 InnerBundleInfo pluginInfo;
609 MergePluginBundleInfo(pluginInfo);
610 result = SavePluginInfoToStorage(pluginInfo, hostBundleInfo);
611 CHECK_RESULT(result, "save plugin info to storage failed %{public}d");
612
613 RemoveEmptyDirs(pluginDir);
614 RemoveOldInstallDir();
615 deleteDirGuard.Dismiss();
616 dataRollBackGuard.Dismiss();
617 APP_LOGD("install plugin bundle successfully: %{public}s", bundleName_.c_str());
618 return result;
619 }
620
CreatePluginDir(const std::string & hostBundleName,std::string & pluginDir)621 ErrCode PluginInstaller::CreatePluginDir(const std::string &hostBundleName, std::string &pluginDir)
622 {
623 ErrCode result = ERR_OK;
624 std::string bundleDir = std::string(Constants::BUNDLE_CODE_DIR) + ServiceConstants::PATH_SEPARATOR + hostBundleName;
625 result = MkdirIfNotExist(bundleDir);
626 CHECK_RESULT(result, "check bundle dir failed %{public}d");
627
628 pluginDir = bundleDir + ServiceConstants::PATH_SEPARATOR + PLUGINS;
629 result = MkdirIfNotExist(pluginDir);
630 CHECK_RESULT(result, "check plugin dir failed %{public}d");
631
632 return result;
633 }
634
CheckAppIdentifier() const635 bool PluginInstaller::CheckAppIdentifier() const
636 {
637 auto &newInfo = parsedBundles_.begin()->second;
638 if (!newInfo.GetAppIdentifier().empty() &&
639 !oldPluginInfo_.appIdentifier.empty() &&
640 newInfo.GetAppIdentifier() == oldPluginInfo_.appIdentifier) {
641 return true;
642 }
643 if (oldPluginInfo_.appId == newInfo.GetAppId()) {
644 return true;
645 }
646 APP_LOGE("the appIdentifier or appId of the new bundle is not the same as old one");
647 return false;
648 }
649
CheckVersionCodeForUpdate() const650 bool PluginInstaller::CheckVersionCodeForUpdate() const
651 {
652 auto &newInfo = parsedBundles_.begin()->second;
653 if (newInfo.GetVersionCode() < oldPluginInfo_.versionCode) {
654 APP_LOGE("fail to update lower version plugin");
655 return false;
656 }
657 return true;
658 }
659
ExtractPluginBundles(const std::string & bundlePath,InnerBundleInfo & newInfo,const std::string & pluginDir)660 ErrCode PluginInstaller::ExtractPluginBundles(const std::string &bundlePath, InnerBundleInfo &newInfo,
661 const std::string &pluginDir)
662 {
663 ErrCode result = ERR_OK;
664 std::string pluginBundleDir = pluginDir + ServiceConstants::PATH_SEPARATOR + bundleNameWithTime_; // pass pluginDir
665 result = MkdirIfNotExist(pluginBundleDir);
666 CHECK_RESULT(result, "check plugin bundle dir failed %{public}d");
667 newInfo.SetAppCodePath(pluginBundleDir);
668
669 auto &moduleName = newInfo.GetInnerModuleInfos().begin()->second.moduleName;
670 std::string moduleDir = pluginBundleDir + ServiceConstants::PATH_SEPARATOR + moduleName;
671 result = MkdirIfNotExist(moduleDir);
672 CHECK_RESULT(result, "check module dir failed %{public}d");
673
674 result = ProcessNativeLibrary(bundlePath, moduleDir, moduleName, pluginBundleDir, newInfo);
675 CHECK_RESULT(result, "ProcessNativeLibrary failed %{public}d");
676
677 // save hsp and so files to installation dir
678 result = SaveHspToInstallDir(bundlePath, pluginBundleDir, moduleName, newInfo);
679 CHECK_RESULT(result, "save hsp file failed %{public}d");
680
681 newInfo.AddModuleSrcDir(moduleDir);
682 newInfo.AddModuleResPath(moduleDir);
683 return ERR_OK;
684 }
685
MergePluginBundleInfo(InnerBundleInfo & pluginBundleInfo)686 void PluginInstaller::MergePluginBundleInfo(InnerBundleInfo &pluginBundleInfo)
687 {
688 auto iter = parsedBundles_.begin();
689 pluginBundleInfo = iter->second;
690 InnerBundleUserInfo newInnerBundleUserInfo;
691 newInnerBundleUserInfo.bundleName = bundleName_;
692 newInnerBundleUserInfo.bundleUserInfo.userId = userId_;
693 pluginBundleInfo.AddInnerBundleUserInfo(newInnerBundleUserInfo);
694 iter++;
695
696 if (!InitDataMgr()) {
697 return;
698 }
699 for (; iter != parsedBundles_.end(); ++iter) {
700 InnerBundleInfo ¤tInfo = iter->second;
701 dataMgr_->AddNewModuleInfo(currentInfo, pluginBundleInfo);
702 }
703 }
704
SavePluginInfoToStorage(const InnerBundleInfo & pluginInfo,const InnerBundleInfo & hostBundleInfo)705 ErrCode PluginInstaller::SavePluginInfoToStorage(const InnerBundleInfo &pluginInfo,
706 const InnerBundleInfo &hostBundleInfo)
707 {
708 ErrCode result = ERR_OK;
709 PluginBundleInfo pluginBundleInfo;
710 pluginInfo.ConvertPluginBundleInfo(bundleNameWithTime_, pluginBundleInfo);
711
712 if (!InitDataMgr()) {
713 return ERR_APPEXECFWK_NULL_PTR;
714 }
715 result = dataMgr_->AddPluginInfo(hostBundleInfo.GetBundleName(), pluginBundleInfo, userId_);
716 if (result != ERR_OK) {
717 APP_LOGE("save pluginInfo to storage failed %{public}d, userId:%{public}d",
718 result, userId_);
719 return result;
720 }
721 APP_LOGI("save pluginInfo:%{public}s success", bundleName_.c_str());
722 return ERR_OK;
723 }
724
PluginRollBack(const std::string & hostBundleName)725 void PluginInstaller::PluginRollBack(const std::string &hostBundleName)
726 {
727 if (!InitDataMgr()) {
728 return;
729 }
730 ErrCode result = ERR_OK;
731 if (!isPluginExist_) {
732 //rollback database
733 result = dataMgr_->RemovePluginInfo(hostBundleName, bundleName_, userId_);
734 if (result != ERR_OK) {
735 APP_LOGW("plugin:%{public}s clean PluginInfo failed", bundleName_.c_str());
736 }
737 return;
738 }
739 // for update
740 result = dataMgr_->UpdatePluginBundleInfo(hostBundleName, oldPluginInfo_);
741 if (result != ERR_OK) {
742 APP_LOGW("save old pluginInfo failed %{public}d when rollback", result);
743 }
744 result = dataMgr_->RemovePluginFromUserInfo(hostBundleName, bundleName_, userId_);
745 if (result != ERR_OK) {
746 APP_LOGW("plugin:%{public}s clean Plugin from userInfo failed", bundleName_.c_str());
747 }
748 }
749
RemovePluginDir(const InnerBundleInfo & hostBundleInfo)750 ErrCode PluginInstaller::RemovePluginDir(const InnerBundleInfo &hostBundleInfo)
751 {
752 std::string pluginDir = hostBundleInfo.GetAppCodePath() + ServiceConstants::PATH_SEPARATOR + PLUGINS;
753 std::string pluginBundleDir = pluginDir + ServiceConstants::PATH_SEPARATOR + bundleNameWithTime_;
754 ErrCode err = InstalldClient::GetInstance()->RemoveDir(pluginBundleDir);
755 if (err != ERR_OK) {
756 APP_LOGW("remove dir of %{public}s failed: %{public}s", bundleName_.c_str(), pluginBundleDir.c_str());
757 return err;
758 }
759 return ERR_OK;
760 }
761
SaveHspToInstallDir(const std::string & bundlePath,const std::string & pluginBundleDir,const std::string & moduleName,InnerBundleInfo & newInfo)762 ErrCode PluginInstaller::SaveHspToInstallDir(const std::string &bundlePath,
763 const std::string &pluginBundleDir,
764 const std::string &moduleName,
765 InnerBundleInfo &newInfo)
766 {
767 ErrCode result = ERR_OK;
768 std::string hspPath = pluginBundleDir + ServiceConstants::PATH_SEPARATOR + moduleName +
769 ServiceConstants::HSP_FILE_SUFFIX;
770 if (!signatureFileDir_.empty()) {
771 result = InstalldClient::GetInstance()->CopyFile(bundlePath, hspPath, signatureFileDir_);
772 CHECK_RESULT(result, "copy hsp to install dir failed %{public}d");
773 } else {
774 result = InstalldClient::GetInstance()->MoveHapToCodeDir(bundlePath, hspPath);
775 CHECK_RESULT(result, "move hsp to install dir failed %{public}d");
776 bool isCompileSdkOpenHarmony = (compileSdkType_ == COMPILE_SDK_TYPE_OPEN_HARMONY);
777 result = VerifyCodeSignatureForHsp(hspPath, appIdentifier_, isEnterpriseBundle_,
778 isCompileSdkOpenHarmony);
779 }
780 newInfo.SetModuleHapPath(hspPath);
781
782 FILE *hspFp = fopen(hspPath.c_str(), "r");
783 if (hspFp == nullptr) {
784 APP_LOGE("fopen %{public}s failed", hspPath.c_str());
785 } else {
786 int32_t hspFd = fileno(hspFp);
787 if (hspFd < 0) {
788 APP_LOGE("open %{public}s failed", hspPath.c_str());
789 } else if (fsync(hspFd) != 0) {
790 APP_LOGE("fsync %{public}s failed", hspPath.c_str());
791 }
792 fclose(hspFp);
793 }
794 CHECK_RESULT(result, "verify code signature failed %{public}d");
795 return ERR_OK;
796 }
797
RemoveEmptyDirs(const std::string & pluginDir) const798 void PluginInstaller::RemoveEmptyDirs(const std::string &pluginDir) const
799 {
800 for (auto &item : parsedBundles_) {
801 std::string moduleDir = pluginDir + ServiceConstants::PATH_SEPARATOR + bundleNameWithTime_
802 + ServiceConstants::PATH_SEPARATOR + item.second.GetCurModuleName();
803 bool isEmpty = false;
804 InstalldClient::GetInstance()->IsDirEmpty(moduleDir, isEmpty);
805 if (isEmpty) {
806 APP_LOGD("remove empty dir : %{public}s", moduleDir.c_str());
807 RemoveDir(moduleDir);
808 }
809 }
810 }
811
RemoveDir(const std::string & dir) const812 void PluginInstaller::RemoveDir(const std::string &dir) const
813 {
814 auto result = InstalldClient::GetInstance()->RemoveDir(dir);
815 if (result != ERR_OK) {
816 APP_LOGW("remove dir %{public}s failed, error is %{public}d", dir.c_str(), result);
817 }
818 }
819
ProcessPluginUninstall(const InnerBundleInfo & hostBundleInfo)820 ErrCode PluginInstaller::ProcessPluginUninstall(const InnerBundleInfo &hostBundleInfo)
821 {
822 ErrCode result = ERR_OK;
823 if (!InitDataMgr()) {
824 return ERR_APPEXECFWK_NULL_PTR;
825 }
826 std::string hostBundleName = hostBundleInfo.GetBundleName();
827 bool isMultiUser = hostBundleInfo.HasMultiUserPlugin(bundleName_);
828 if (isMultiUser) {
829 result = dataMgr_->RemovePluginFromUserInfo(hostBundleName, bundleName_, userId_);
830 if (result != ERR_OK) {
831 APP_LOGE("bundleName:%{public}s remove plugin:%{public}s from userInfo failed",
832 hostBundleName.c_str(), bundleName_.c_str());
833 return ERR_APPEXECFWK_REMOVE_PLUGIN_INFO_ERROR;
834 }
835 return ERR_OK;
836 }
837
838 ScopeGuard removeDataGuard([&] { UninstallRollBack(hostBundleName); });
839 result = dataMgr_->RemovePluginInfo(hostBundleName, bundleName_, userId_);
840 if (result != ERR_OK) {
841 APP_LOGE("bundleName:%{public}s remove plugin info %{public}s failed",
842 hostBundleInfo.GetBundleName().c_str(), bundleName_.c_str());
843 return ERR_APPEXECFWK_REMOVE_PLUGIN_INFO_ERROR;
844 }
845 removeDataGuard.Dismiss();
846
847 std::string pluginBundleDir = oldPluginInfo_.codePath;
848 std::string deleteDir = pluginBundleDir + REMOVE_TMP_SUFFIX;
849 if (!BundleUtil::RenameFile(pluginBundleDir, deleteDir)) {
850 APP_LOGW("rename failed, %{public}s -> %{public}s", pluginBundleDir.c_str(), deleteDir.c_str());
851 result = InstalldClient::GetInstance()->RemoveDir(pluginBundleDir);
852 } else {
853 result = InstalldClient::GetInstance()->RemoveDir(deleteDir);
854 }
855 if (result != ERR_OK) {
856 APP_LOGW("bundleName:%{public}s remove plugin:%{public}s dir failed",
857 hostBundleInfo.GetBundleName().c_str(), bundleName_.c_str());
858 }
859 InstalldClient::GetInstance()->RemoveSignProfile(bundleName_);
860
861 return ERR_OK;
862 }
863
RemoveOldInstallDir()864 void PluginInstaller::RemoveOldInstallDir()
865 {
866 if (!isPluginExist_) {
867 return;
868 }
869 RemoveDir(oldPluginInfo_.codePath);
870 APP_LOGI("remove old install dir:%{public}s", oldPluginInfo_.codePath.c_str());
871 }
872
UninstallRollBack(const std::string & hostBundleName)873 void PluginInstaller::UninstallRollBack(const std::string &hostBundleName)
874 {
875 if (!InitDataMgr()) {
876 return;
877 }
878 ErrCode err = dataMgr_->AddPluginInfo(hostBundleName, oldPluginInfo_, userId_);
879 if (err != ERR_OK) {
880 APP_LOGW("save old pluginInfo failed %{public}d, userId:%{public}d", err, userId_);
881 }
882 }
883
InitDataMgr()884 bool PluginInstaller::InitDataMgr()
885 {
886 if (dataMgr_ == nullptr) {
887 dataMgr_ = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
888 if (dataMgr_ == nullptr) {
889 LOG_E(BMS_TAG_INSTALLER, "Get dataMgr shared_ptr nullptr");
890 return false;
891 }
892 }
893 return true;
894 }
895
GetModuleNames()896 std::string PluginInstaller::GetModuleNames()
897 {
898 if (parsedBundles_.empty()) {
899 APP_LOGW("module name is empty");
900 return Constants::EMPTY_STRING;
901 }
902 std::string moduleNames;
903 for (const auto &item : parsedBundles_) {
904 moduleNames.append(item.second.GetCurrentModulePackage()).append(ServiceConstants::MODULE_NAME_SEPARATOR);
905 }
906 moduleNames.pop_back();
907 APP_LOGD("moduleNames : %{public}s", moduleNames.c_str());
908 return moduleNames;
909 }
910
NotifyPluginEvents(const NotifyType & type,int32_t uid)911 void PluginInstaller::NotifyPluginEvents(const NotifyType &type, int32_t uid)
912 {
913 NotifyBundleEvents event = {
914 .type = type,
915 .uid = uid,
916 .bundleType = static_cast<int32_t>(BundleType::APP_PLUGIN),
917 .bundleName = bundleName_,
918 .modulePackage = GetModuleNames(),
919 };
920 std::shared_ptr<BundleCommonEventMgr> commonEventMgr = std::make_shared<BundleCommonEventMgr>();
921 commonEventMgr->NotifyPluginEvents(event, dataMgr_);
922 }
923 } // AppExecFwk
924 } // OHOS