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