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