• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 "core/components_ng/pattern/plugin/plugin_pattern.h"
17 
18 #include <string>
19 
20 #ifdef OS_ACCOUNT_EXISTS
21 #include "os_account_manager.h"
22 #endif // OS_ACCOUNT_EXISTS
23 
24 #include "base/log/log_wrapper.h"
25 #include "base/utils/utils.h"
26 #include "core/common/plugin_manager.h"
27 #include "core/components/plugin/plugin_component_manager.h"
28 #include "core/components/plugin/plugin_sub_container.h"
29 #include "core/components/plugin/render_plugin.h"
30 #include "core/components/plugin/resource/plugin_manager_delegate.h"
31 #include "core/components_ng/pattern/plugin/plugin_event_hub.h"
32 #include "core/components_ng/render/adapter/rosen_render_context.h"
33 
34 namespace OHOS::Ace::NG {
35 namespace {
36 #ifndef OS_ACCOUNT_EXISTS
37 constexpr int32_t DEFAULT_OS_ACCOUNT_ID = 0; // 0 is the default id when there is no os_account part
38 #endif                                       // OS_ACCOUNT_EXISTS
39 
GetActiveAccountIds(std::vector<int32_t> & userIds)40 ErrCode GetActiveAccountIds(std::vector<int32_t>& userIds)
41 {
42     userIds.clear();
43 #ifdef OS_ACCOUNT_EXISTS
44     return AccountSA::OsAccountManager::QueryActiveOsAccountIds(userIds);
45 #else  // OS_ACCOUNT_EXISTS
46     LOGE("os account part not exists, use default id.");
47     userIds.push_back(DEFAULT_OS_ACCOUNT_ID);
48     return ERR_OK;
49 #endif // OS_ACCOUNT_EXISTS
50 }
51 constexpr char JS_EXT[] = ".js";
52 constexpr char ETS_EXT[] = ".ets";
53 constexpr size_t SIZE_OF_ETS_EXT = 4;
54 } // namespace
55 
~PluginPattern()56 PluginPattern::~PluginPattern()
57 {
58     pluginManagerBridge_.Reset();
59     if (pluginSubContainer_) {
60         auto currentId = pluginSubContainer_->GetInstanceId();
61         PluginManager::GetInstance().RemovePluginSubContainer(currentId);
62         PluginManager::GetInstance().RemovePluginParentContainer(currentId);
63         pluginSubContainer_->Destroy();
64         pluginSubContainer_.Reset();
65     }
66 }
67 
OnAttachToFrameNode()68 void PluginPattern::OnAttachToFrameNode()
69 {
70     auto host = GetHost();
71     CHECK_NULL_VOID(host);
72     host->GetRenderContext()->SetClipToFrame(true);
73     InitPluginManagerDelegate();
74 }
75 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)76 bool PluginPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
77 {
78     if (config.skipMeasure && config.skipLayout) {
79         return false;
80     }
81 
82     auto size = dirty->GetGeometryNode()->GetFrameSize();
83     auto host = GetHost();
84     CHECK_NULL_RETURN(host, false);
85     auto layoutProperty = host->GetLayoutProperty<PluginLayoutProperty>();
86     CHECK_NULL_RETURN(layoutProperty, false);
87     auto info = layoutProperty->GetRequestPluginInfo().value_or(RequestPluginInfo());
88     info.width = Dimension(size.Width());
89     info.height = Dimension(size.Height());
90     layoutProperty->UpdateRequestPluginInfo(info);
91     auto data = layoutProperty->GetData().value_or("");
92     if (info.bundleName != pluginInfo_.bundleName || info.abilityName != pluginInfo_.abilityName ||
93         info.moduleName != pluginInfo_.moduleName || info.pluginName != pluginInfo_.pluginName ||
94         info.dimension != pluginInfo_.dimension || data_ != data) {
95         pluginInfo_ = info;
96         data_ = data;
97         LOGI(" pluginInfo_ = info; pluginInfo_.width:: %{public}lf, pluginInfo_.height:: %{public}lf",
98             pluginInfo_.width.Value(), pluginInfo_.height.Value());
99     } else {
100         // for update pluguin component
101         if (pluginInfo_.allowUpdate != info.allowUpdate) {
102             pluginInfo_.allowUpdate = info.allowUpdate;
103             if (pluginSubContainer_) {
104                 pluginSubContainer_->SetAllowUpdate(pluginInfo_.allowUpdate);
105             }
106         }
107 
108         if (pluginInfo_.width != info.width || pluginInfo_.height != info.height) {
109             pluginInfo_.width = info.width;
110             pluginInfo_.height = info.height;
111             if (pluginSubContainer_) {
112                 pluginSubContainer_->SetPluginPattern(WeakClaim(this));
113                 pluginSubContainer_->UpdateRootElementSize();
114                 pluginSubContainer_->UpdateSurfaceSize();
115             }
116         }
117         return false;
118     }
119     loadFialState_ = false;
120     CreatePluginSubContainer();
121     if (pluginManagerBridge_) {
122         pluginManagerBridge_->AddPlugin(host->GetContext(), info);
123     }
124     return false;
125 }
126 
InitPluginManagerDelegate()127 void PluginPattern::InitPluginManagerDelegate()
128 {
129     CHECK_NULL_VOID(!pluginManagerBridge_);
130     auto host = GetHost();
131     CHECK_NULL_VOID(host);
132     auto context = host->GetContext();
133     CHECK_NULL_VOID(context);
134     pluginManagerBridge_ = AceType::MakeRefPtr<PluginManagerDelegate>(context);
135     int32_t instanceID = context->GetInstanceId();
136     pluginManagerBridge_->AddPluginCompleteCallback([weak = WeakClaim(this), instanceID]() {
137         ContainerScope scope(instanceID);
138         auto plugin = weak.Upgrade();
139         CHECK_NULL_VOID(plugin);
140         auto host = plugin->GetHost();
141         CHECK_NULL_VOID(host);
142         auto uiTaskExecutor =
143             SingleTaskExecutor::Make(host->GetContext()->GetTaskExecutor(), TaskExecutor::TaskType::UI);
144         uiTaskExecutor.PostTask([weak, instanceID] {
145             ContainerScope scope(instanceID);
146             auto plugin = weak.Upgrade();
147             CHECK_NULL_VOID(plugin);
148             plugin->FireOnCompleteEvent();
149         });
150     });
151     pluginManagerBridge_->AddPluginUpdateCallback([weak = WeakClaim(this), instanceID](int64_t id, std::string data) {
152         ContainerScope scope(instanceID);
153         auto plugin = weak.Upgrade();
154         CHECK_NULL_VOID(plugin);
155         auto host = plugin->GetHost();
156         CHECK_NULL_VOID(host);
157         auto uiTaskExecutor =
158             SingleTaskExecutor::Make(host->GetContext()->GetTaskExecutor(), TaskExecutor::TaskType::UI);
159         uiTaskExecutor.PostTask([id, data, weak] {
160             auto plugin = weak.Upgrade();
161             CHECK_NULL_VOID(plugin);
162             plugin->GetPluginSubContainer()->UpdatePlugin(data);
163         });
164     });
165     pluginManagerBridge_->AddPluginErrorCallback(
166         [weak = WeakClaim(this), instanceID](std::string code, std::string msg) {
167             ContainerScope scope(instanceID);
168             auto plugin = weak.Upgrade();
169             CHECK_NULL_VOID(plugin);
170             auto host = plugin->GetHost();
171             CHECK_NULL_VOID(host);
172             auto uiTaskExecutor =
173                 SingleTaskExecutor::Make(host->GetContext()->GetTaskExecutor(), TaskExecutor::TaskType::UI);
174             uiTaskExecutor.PostTask([code, msg, weak, instanceID] {
175                 ContainerScope scope(instanceID);
176                 auto plugin = weak.Upgrade();
177                 CHECK_NULL_VOID(plugin);
178                 plugin->FireOnErrorEvent(code, msg);
179             });
180         });
181 }
182 
CreatePluginSubContainer()183 void PluginPattern::CreatePluginSubContainer()
184 {
185     auto host = GetHost();
186     CHECK_NULL_VOID(host);
187     auto context = host->GetContext();
188     CHECK_NULL_VOID(context);
189     auto layoutProperty = host->GetLayoutProperty<PluginLayoutProperty>();
190     CHECK_NULL_VOID(layoutProperty);
191 
192     auto parentcontainerId = Container::CurrentId();
193     while (parentcontainerId >= MIN_PLUGIN_SUBCONTAINER_ID) {
194         parentcontainerId = PluginManager::GetInstance().GetPluginParentContainerId(parentcontainerId);
195     }
196 
197     if (pluginSubContainer_) {
198         auto currentId = pluginSubContainer_->GetInstanceId();
199         PluginManager::GetInstance().RemovePluginSubContainer(currentId);
200         PluginManager::GetInstance().RemovePluginParentContainer(currentId);
201         pluginSubContainer_->Destroy();
202         pluginSubContainer_.Reset();
203     }
204     auto pluginSubContainerId_ = PluginManager::GetInstance().GetPluginSubContainerId();
205     pluginSubContainer_ = AceType::MakeRefPtr<PluginSubContainer>(context, pluginSubContainerId_);
206     CHECK_NULL_VOID(pluginSubContainer_);
207 
208     PluginManager::GetInstance().AddPluginSubContainer(pluginSubContainerId_, pluginSubContainer_);
209     PluginManager::GetInstance().AddPluginParentContainer(pluginSubContainerId_, parentcontainerId);
210     pluginSubContainer_->Initialize();
211     auto weak = WeakClaim(this);
212     pluginSubContainer_->SetPluginPattern(weak);
213     auto pattern = weak.Upgrade();
214     auto host_ = pattern->GetHost();
215     CHECK_NULL_VOID(host_);
216     pluginSubContainer_->SetPluginWindowId(GetHost()->GetId());
217     pluginSubContainer_->SetPluginNode(GetHost());
218 
219     auto uiTaskExecutor = SingleTaskExecutor::Make(host_->GetContext()->GetTaskExecutor(), TaskExecutor::TaskType::UI);
220 
221     int32_t instanceID = context->GetInstanceId();
222     uiTaskExecutor.PostTask([this, weak, instanceID] {
223         ContainerScope scope(instanceID);
224         auto pluginPattern = weak.Upgrade();
225         CHECK_NULL_VOID(pluginPattern);
226         auto pluginSubContainer = pluginPattern->GetPluginSubContainer();
227         RequestPluginInfo info = pluginPattern->GetPluginRequestInfo();
228         CHECK_NULL_VOID(pluginSubContainer);
229         auto packagePathStr = pluginPattern->GetPackagePath(weak, info);
230         if (packagePathStr.empty()) {
231             LOGE("package path is empty.");
232             pluginPattern->FireOnErrorEvent("1", "package path is empty.");
233             return;
234         }
235         if (!info.bundleName.empty() && !info.moduleName.empty()) {
236             pluginSubContainer_->SetPluginBundleName(info.bundleName);
237             pluginSubContainer_->SetPluginModuleName(info.moduleName);
238         }
239         if (packagePathStr.rfind(".hap") != std::string::npos) {
240             std::string sub = packagePathStr.substr(1, packagePathStr.size() - 5) + "/";
241             ReplaceAll(info.source, sub, "");
242             pluginSubContainer_->RunDecompressedPlugin(
243                 packagePathStr, info.abilityName, info.source, info.moduleResPath, pluginPattern->GetData());
244         } else {
245             pluginSubContainer_->RunPlugin(
246                 packagePathStr, info.abilityName, info.source, info.moduleResPath, pluginPattern->GetData());
247         }
248     });
249 }
250 
ReplaceAll(std::string & str,const std::string & pattern,const std::string & newPattern)251 void PluginPattern::ReplaceAll(std::string& str, const std::string& pattern, const std::string& newPattern)
252 {
253     const size_t nSize = newPattern.size();
254     const size_t pSize = pattern.size();
255     for (size_t pos = str.find(pattern, 0); pos != std::string::npos; pos = str.find(pattern, pos + nSize)) {
256         str.replace(pos, pSize, newPattern);
257     }
258 }
259 
GetDrawDelegate()260 std::unique_ptr<DrawDelegate> PluginPattern::GetDrawDelegate()
261 {
262     auto drawDelegate = std::make_unique<DrawDelegate>();
263 #ifdef ENABLE_ROSEN_BACKEND
264     drawDelegate->SetDrawRSFrameCallback(
265         [weak = WeakClaim(this)](std::shared_ptr<RSNode>& node, const Rect& /* dirty */) {
266             auto plugin = weak.Upgrade();
267             CHECK_NULL_VOID(plugin);
268             auto host = plugin->GetHost();
269             CHECK_NULL_VOID(host);
270             auto context = DynamicCast<NG::RosenRenderContext>(host->GetRenderContext());
271             CHECK_NULL_VOID(context);
272             auto rsNode = context->GetRSNode();
273             CHECK_NULL_VOID(rsNode);
274             if (node) {
275                 node->SetBackgroundColor(Color::TRANSPARENT.GetValue());
276             }
277             rsNode->AddChild(node, -1);
278             host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
279         });
280 #endif
281     return drawDelegate;
282 }
283 
FireOnCompleteEvent() const284 void PluginPattern::FireOnCompleteEvent() const
285 {
286     LOGI("FireOnCompleteEvent");
287     if (loadFialState_) {
288         return;
289     }
290     auto host = GetHost();
291     CHECK_NULL_VOID(host);
292     auto eventHub = host->GetEventHub<PluginEventHub>();
293     CHECK_NULL_VOID(eventHub);
294     auto json = JsonUtil::Create(true);
295     eventHub->FireOnComplete(json->ToString());
296 }
297 
FireOnErrorEvent(const std::string & code,const std::string & msg)298 void PluginPattern::FireOnErrorEvent(const std::string& code, const std::string& msg)
299 {
300     loadFialState_ = true;
301     LOGI("FireOnErrorEvent code: %{public}s, msg: %{public}s", code.c_str(), msg.c_str());
302     auto host = GetHost();
303     CHECK_NULL_VOID(host);
304     auto eventHub = host->GetEventHub<PluginEventHub>();
305     CHECK_NULL_VOID(eventHub);
306     auto json = JsonUtil::Create(true);
307     json->Put("errcode", code.c_str());
308     json->Put("msg", msg.c_str());
309     eventHub->FireOnError(json->ToString());
310 }
311 
OnActionEvent(const std::string & action) const312 void PluginPattern::OnActionEvent(const std::string& action) const
313 {
314     LOGI("OnActionEvent action: %{public}s", action.c_str());
315     auto eventAction = JsonUtil::ParseJsonString(action);
316     if (!eventAction->IsValid()) {
317         LOGE("get event action failed");
318         return;
319     }
320     auto actionType = eventAction->GetValue("action");
321     if (!actionType->IsValid()) {
322         LOGE("get event key failed");
323         return;
324     }
325 
326     auto type = actionType->GetString();
327     if (type != "router" && type != "message") {
328         LOGE("undefined event type");
329         return;
330     }
331 
332     CHECK_NULL_VOID_NOLOG(pluginManagerBridge_);
333     pluginManagerBridge_->OnActionEvent(action);
334 }
335 
ISAllowUpdate() const336 bool PluginPattern::ISAllowUpdate() const
337 {
338     auto host = GetHost();
339     CHECK_NULL_RETURN(host, true);
340     auto property = host->GetLayoutProperty<PluginLayoutProperty>();
341     CHECK_NULL_RETURN(property, true);
342     auto pluginInfo = property->GetRequestPluginInfo();
343     CHECK_NULL_RETURN(property, true);
344     return pluginInfo->allowUpdate;
345 }
346 
SplitString(const std::string & str,char tag,std::vector<std::string> & strList) const347 void PluginPattern::SplitString(const std::string& str, char tag, std::vector<std::string>& strList) const
348 {
349     std::string subStr;
350     for (size_t i = 0; i < str.length(); i++) {
351         if (tag == str[i]) {
352             if (!subStr.empty()) {
353                 strList.push_back(subStr);
354                 subStr.clear();
355             }
356         } else {
357             subStr.push_back(str[i]);
358         }
359     }
360     if (!subStr.empty()) {
361         strList.push_back(subStr);
362     }
363 }
364 
GetPackagePath(const WeakPtr<PluginPattern> & weak,RequestPluginInfo & info) const365 std::string PluginPattern::GetPackagePath(const WeakPtr<PluginPattern>& weak, RequestPluginInfo& info) const
366 {
367     std::string packagePathStr;
368     size_t pos_ets = info.pluginName.rfind(ETS_EXT);
369     if (pos_ets != std::string::npos && info.pluginName.substr(pos_ets) == ETS_EXT) {
370         info.pluginName = info.pluginName.substr(0, info.pluginName.length() - SIZE_OF_ETS_EXT);
371         info.pluginName = info.pluginName + JS_EXT;
372     }
373     size_t pos = info.pluginName.rfind(JS_EXT);
374     if (info.pluginName.front() == '/' && pos != std::string::npos && info.pluginName.substr(pos) == JS_EXT) {
375         packagePathStr = GetPackagePathByAbsolutePath(weak, info);
376     } else {
377         packagePathStr = GetPackagePathByWant(weak, info);
378     }
379     return packagePathStr;
380 }
381 
GetPackagePathByWant(const WeakPtr<PluginPattern> & weak,RequestPluginInfo & info) const382 std::string PluginPattern::GetPackagePathByWant(const WeakPtr<PluginPattern>& weak, RequestPluginInfo& info) const
383 {
384     std::string packagePathStr;
385     auto pluginPattern = weak.Upgrade();
386     CHECK_NULL_RETURN(pluginPattern, packagePathStr);
387     std::vector<std::string> strList;
388     pluginPattern->SplitString(info.bundleName, '/', strList);
389 
390     std::vector<int32_t> userIds;
391     ErrCode errCode = GetActiveAccountIds(userIds);
392     if (errCode != ERR_OK) {
393         LOGE("Query Active OsAccountIds failed!");
394         pluginPattern->FireOnErrorEvent("1", "Query Active OsAccountIds failed!");
395         return packagePathStr;
396     }
397     GetAbilityNameByWant(weak, info);
398     packagePathStr = GerPackagePathByBms(weak, info, strList, userIds);
399 
400     return packagePathStr;
401 }
GetPackagePathByAbsolutePath(const WeakPtr<PluginPattern> & weak,RequestPluginInfo & info) const402 std::string PluginPattern::GetPackagePathByAbsolutePath(
403     const WeakPtr<PluginPattern>& weak, RequestPluginInfo& info) const
404 {
405     std::string packagePathStr;
406     auto pluginPattern = weak.Upgrade();
407     CHECK_NULL_RETURN_NOLOG(pluginPattern, packagePathStr);
408     std::string assets = "assets/js/";
409     size_t posAssets = info.pluginName.rfind(assets);
410     if (posAssets != std::string::npos) {
411         packagePathStr = info.pluginName.substr(0, posAssets);
412         size_t posModule = info.pluginName.find("/", posAssets + assets.size());
413         if (posModule != std::string::npos) {
414             info.abilityName =
415                 info.pluginName.substr(posAssets + assets.size(), posModule - (posAssets + assets.size()));
416             info.source = info.pluginName.substr(posModule);
417         } else {
418             info.abilityName = "/";
419             info.source = info.pluginName.substr(posAssets + assets.size());
420         }
421     } else {
422         size_t pos = info.pluginName.rfind("/");
423         packagePathStr = info.pluginName.substr(0, pos + 1);
424         info.source = info.pluginName.substr(pos + 1);
425         info.abilityName = "/";
426     }
427     return packagePathStr;
428 }
429 
GetAbilityNameByWant(const WeakPtr<PluginPattern> & weak,RequestPluginInfo & info) const430 void PluginPattern::GetAbilityNameByWant(const WeakPtr<PluginPattern>& weak, RequestPluginInfo& info) const
431 {
432     auto pluginPattern = weak.Upgrade();
433     CHECK_NULL_VOID(pluginPattern);
434     std::vector<std::string> strList;
435     pluginPattern->SplitString(info.pluginName, '&', strList);
436     if (strList.empty()) {
437         LOGE("Template source is empty.");
438         pluginPattern->FireOnErrorEvent("1", "Template source is empty.");
439         return;
440     }
441     if (strList.size() == 1) {
442         auto pos = info.pluginName.rfind(JS_EXT);
443         if (pos != std::string::npos && (strList[0].substr(pos) == JS_EXT)) {
444             info.source = info.pluginName;
445         } else {
446             info.abilityName = info.pluginName;
447         }
448     } else {
449         size_t pos_ets = strList[0].rfind(ETS_EXT);
450         if (pos_ets != std::string::npos && strList[0].substr(pos_ets) == ETS_EXT) {
451             strList[0] = strList[0].substr(0, strList[0].length() - SIZE_OF_ETS_EXT);
452             strList[0] = strList[0] + JS_EXT;
453         }
454         auto pos = strList[0].rfind(JS_EXT);
455         if (pos != std::string::npos && (strList[0].substr(pos) == JS_EXT)) {
456             info.source = strList[0];
457         } else {
458             info.abilityName = strList[0];
459         }
460         info.moduleName = strList[1];
461     }
462 }
463 
GerPackagePathByBms(const WeakPtr<PluginPattern> & weak,RequestPluginInfo & info,const std::vector<std::string> & strList,const std::vector<int32_t> & userIds) const464 std::string PluginPattern::GerPackagePathByBms(const WeakPtr<PluginPattern>& weak, RequestPluginInfo& info,
465     const std::vector<std::string>& strList, const std::vector<int32_t>& userIds) const
466 {
467     std::string packagePathStr;
468     auto pluginPattern = weak.Upgrade();
469     CHECK_NULL_RETURN(pluginPattern, packagePathStr);
470     auto bms = PluginComponentManager::GetInstance()->GetBundleManager();
471     if (!bms) {
472         LOGE("Bms bundleManager is nullptr.");
473         pluginPattern->FireOnErrorEvent("1", "Bms bundleManager is nullptr.");
474         return packagePathStr;
475     }
476 
477     if (strList.empty()) {
478         LOGE("App bundleName or abilityName is empty.");
479         pluginPattern->FireOnErrorEvent("1", "App bundleName is empty.");
480         return packagePathStr;
481     }
482 
483     AppExecFwk::BundleInfo bundleInfo;
484     bool ret = bms->GetBundleInfo(strList[0], AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo,
485         userIds.size() > 0 ? userIds[0] : AppExecFwk::Constants::UNSPECIFIED_USERID);
486     if (!ret) {
487         LOGE("Bms get bundleName failed!");
488         pluginPattern->FireOnErrorEvent("1", "Bms get bundleName failed!");
489         return packagePathStr;
490     }
491     if (bundleInfo.hapModuleInfos.empty() || bundleInfo.hapModuleInfos[0].hapPath.empty()) {
492         if (strList.size() == 1) {
493             if (bundleInfo.moduleResPaths.size() == 1) {
494                 info.moduleResPath = bundleInfo.moduleResPaths[0];
495             } else {
496                 LOGE("Bms moduleResPaths is empty.");
497                 pluginPattern->FireOnErrorEvent("1", "Bms moduleResPaths is empty.");
498                 return packagePathStr;
499             }
500             packagePathStr = bundleInfo.moduleDirs[0] + "/";
501         } else {
502             AAFwk::Want want;
503             AppExecFwk::AbilityInfo abilityInfo;
504             AppExecFwk::ElementName element("", strList[0], strList[1]);
505             want.SetElement(element);
506             bool ret = bms->QueryAbilityInfo(want, AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_DEFAULT,
507                 userIds.size() > 0 ? userIds[0] : AppExecFwk::Constants::UNSPECIFIED_USERID, abilityInfo);
508             if (!ret) {
509                 LOGE("Bms get abilityInfo failed!");
510                 pluginPattern->FireOnErrorEvent("1", "Bms get bundleName failed!");
511                 return packagePathStr;
512             }
513             packagePathStr = abilityInfo.applicationInfo.codePath + "/" + abilityInfo.package + "/";
514             info.moduleResPath = abilityInfo.resourcePath;
515         }
516         return packagePathStr;
517     }
518     if (info.moduleName.empty() || info.moduleName == "default") {
519         info.moduleResPath = bundleInfo.hapModuleInfos[0].resourcePath;
520         info.moduleName = bundleInfo.hapModuleInfos[0].name;
521         packagePathStr = bundleInfo.hapModuleInfos[0].hapPath;
522         return packagePathStr;
523     }
524     auto result = std::find_if(bundleInfo.hapModuleInfos.begin(), bundleInfo.hapModuleInfos.end(),
525         [moduleName = info.moduleName](
526             AppExecFwk::HapModuleInfo hapModuleInfo) { return hapModuleInfo.moduleName == moduleName; });
527     if (result != bundleInfo.hapModuleInfos.end()) {
528         info.moduleResPath = result->resourcePath;
529         packagePathStr = result->hapPath;
530         return packagePathStr;
531     }
532     LOGE("Bms get hapInfo failed!");
533     pluginPattern->FireOnErrorEvent(
534         "1", "Bms get hapPath failed! Cannot find hap according to BundleName and ModuleName!");
535     return packagePathStr;
536 }
537 
GetPluginSubContainer() const538 const RefPtr<PluginSubContainer>& PluginPattern::GetPluginSubContainer() const
539 {
540     return pluginSubContainer_;
541 };
542 
FlushReload() const543 void PluginPattern::FlushReload() const
544 {
545     auto host = GetHost();
546     CHECK_NULL_VOID(host);
547     auto customNode = DynamicCast<CustomNodeBase>(host->GetFirstChild());
548     CHECK_NULL_VOID(customNode);
549     customNode->FireReloadFunction(true);
550 }
551 } // namespace OHOS::Ace::NG
552