• 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/dump_log.h"
25 #include "base/log/log_wrapper.h"
26 #include "base/utils/utils.h"
27 #include "core/common/plugin_manager.h"
28 #include "core/components/plugin/plugin_component_manager.h"
29 #include "core/components/plugin/plugin_sub_container.h"
30 #include "core/components/plugin/render_plugin.h"
31 #include "core/components/plugin/resource/plugin_manager_delegate.h"
32 #include "core/components_ng/pattern/plugin/plugin_event_hub.h"
33 #include "core/components_ng/render/adapter/rosen_render_context.h"
34 
35 namespace OHOS::Ace::NG {
36 namespace {
37 #ifndef OS_ACCOUNT_EXISTS
38 constexpr int32_t DEFAULT_OS_ACCOUNT_ID = 0; // 0 is the default id when there is no os_account part
39 #endif                                       // OS_ACCOUNT_EXISTS
40 
GetActiveAccountIds(std::vector<int32_t> & userIds)41 ErrCode GetActiveAccountIds(std::vector<int32_t>& userIds)
42 {
43     userIds.clear();
44 #ifdef OS_ACCOUNT_EXISTS
45     return AccountSA::OsAccountManager::QueryActiveOsAccountIds(userIds);
46 #else  // OS_ACCOUNT_EXISTS
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     } else {
98         // for update pluguin component
99         if (pluginInfo_.allowUpdate != info.allowUpdate) {
100             pluginInfo_.allowUpdate = info.allowUpdate;
101             if (pluginSubContainer_) {
102                 pluginSubContainer_->SetAllowUpdate(pluginInfo_.allowUpdate);
103             }
104         }
105 
106         if (pluginInfo_.width != info.width || pluginInfo_.height != info.height) {
107             pluginInfo_.width = info.width;
108             pluginInfo_.height = info.height;
109             if (pluginSubContainer_) {
110                 pluginSubContainer_->SetPluginPattern(WeakClaim(this));
111                 pluginSubContainer_->UpdateRootElementSize();
112                 pluginSubContainer_->UpdateSurfaceSize();
113             }
114         }
115         return false;
116     }
117     loadFialState_ = false;
118     CreatePluginSubContainer();
119     if (pluginManagerBridge_) {
120         pluginManagerBridge_->AddPlugin(host->GetContextRefPtr(), info);
121     }
122     return false;
123 }
124 
InitPluginManagerDelegate()125 void PluginPattern::InitPluginManagerDelegate()
126 {
127     CHECK_NULL_VOID(!pluginManagerBridge_);
128     auto host = GetHost();
129     CHECK_NULL_VOID(host);
130     auto context = host->GetContextRefPtr();
131     CHECK_NULL_VOID(context);
132     pluginManagerBridge_ = AceType::MakeRefPtr<PluginManagerDelegate>(context);
133     int32_t instanceID = context->GetInstanceId();
134     pluginManagerBridge_->AddPluginCompleteCallback([weak = WeakClaim(this), instanceID]() {
135         ContainerScope scope(instanceID);
136         auto plugin = weak.Upgrade();
137         CHECK_NULL_VOID(plugin);
138         auto host = plugin->GetHost();
139         CHECK_NULL_VOID(host);
140         auto uiTaskExecutor =
141             SingleTaskExecutor::Make(host->GetContext()->GetTaskExecutor(), TaskExecutor::TaskType::UI);
142         uiTaskExecutor.PostTask(
143             [weak, instanceID] {
144                 ContainerScope scope(instanceID);
145                 auto plugin = weak.Upgrade();
146                 CHECK_NULL_VOID(plugin);
147                 plugin->FireOnCompleteEvent();
148             },
149             "ArkUIPluginCompleteEvent");
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(
160             [data, weak] {
161                 auto plugin = weak.Upgrade();
162                 CHECK_NULL_VOID(plugin);
163                 plugin->GetPluginSubContainer()->UpdatePlugin(data);
164             },
165             "ArkUIPluginUpdate");
166     });
167     pluginManagerBridge_->AddPluginErrorCallback(
168         [weak = WeakClaim(this), instanceID](std::string code, std::string msg) {
169             ContainerScope scope(instanceID);
170             auto plugin = weak.Upgrade();
171             CHECK_NULL_VOID(plugin);
172             auto host = plugin->GetHost();
173             CHECK_NULL_VOID(host);
174             auto uiTaskExecutor =
175                 SingleTaskExecutor::Make(host->GetContext()->GetTaskExecutor(), TaskExecutor::TaskType::UI);
176             uiTaskExecutor.PostTask(
177                 [code, msg, weak, instanceID] {
178                     ContainerScope scope(instanceID);
179                     auto plugin = weak.Upgrade();
180                     CHECK_NULL_VOID(plugin);
181                     plugin->FireOnErrorEvent(code, msg);
182                 },
183                 "ArkUIPluginErrorEvent");
184         });
185 }
186 
DumpInfo()187 void PluginPattern::DumpInfo()
188 {
189     DumpLog::GetInstance().AddDesc(std::string("pluginInfo: ").append(pluginInfo_.ToString()));
190     DumpLog::GetInstance().AddDesc(std::string("data: ").append(data_));
191 }
192 
DumpInfo(std::unique_ptr<JsonValue> & json)193 void PluginPattern::DumpInfo(std::unique_ptr<JsonValue>& json)
194 {
195     json->Put("pluginInfo: ", pluginInfo_.ToString().c_str());
196     json->Put("data: ", data_.c_str());
197 }
198 
CreatePluginSubContainer()199 void PluginPattern::CreatePluginSubContainer()
200 {
201     TAG_LOGI(AceLogTag::ACE_PLUGIN_COMPONENT, "CreatePluginSubContainer.");
202     auto host = GetHost();
203     CHECK_NULL_VOID(host);
204     auto context = host->GetContextRefPtr();
205     CHECK_NULL_VOID(context);
206     auto layoutProperty = host->GetLayoutProperty<PluginLayoutProperty>();
207     CHECK_NULL_VOID(layoutProperty);
208 
209     auto parentcontainerId = Container::CurrentId();
210     while (parentcontainerId >= MIN_PLUGIN_SUBCONTAINER_ID) {
211         parentcontainerId = PluginManager::GetInstance().GetPluginParentContainerId(parentcontainerId);
212     }
213 
214     if (pluginSubContainer_) {
215         auto currentId = pluginSubContainer_->GetInstanceId();
216         TAG_LOGI(AceLogTag::ACE_PLUGIN_COMPONENT, "destory old pluginSubContainer: %{public}d.", currentId);
217         PluginManager::GetInstance().RemovePluginSubContainer(currentId);
218         PluginManager::GetInstance().RemovePluginParentContainer(currentId);
219         pluginSubContainer_->Destroy();
220         pluginSubContainer_.Reset();
221     }
222     auto pluginSubContainerId_ = PluginManager::GetInstance().GetPluginSubContainerId();
223     pluginSubContainer_ = AceType::MakeRefPtr<PluginSubContainer>(context, pluginSubContainerId_);
224     CHECK_NULL_VOID(pluginSubContainer_);
225 
226     PluginManager::GetInstance().AddPluginSubContainer(pluginSubContainerId_, pluginSubContainer_);
227     PluginManager::GetInstance().AddPluginParentContainer(pluginSubContainerId_, parentcontainerId);
228     pluginSubContainer_->Initialize();
229     auto weak = WeakClaim(this);
230     pluginSubContainer_->SetPluginPattern(weak);
231     auto pattern = weak.Upgrade();
232     auto host_ = pattern->GetHost();
233     CHECK_NULL_VOID(host_);
234     pluginSubContainer_->SetPluginWindowId(GetHost()->GetId());
235     pluginSubContainer_->SetPluginNode(GetHost());
236 
237     CHECK_NULL_VOID(host_->GetContext());
238     auto uiTaskExecutor = SingleTaskExecutor::Make(host_->GetContext()->GetTaskExecutor(), TaskExecutor::TaskType::UI);
239 
240     int32_t instanceID = context->GetInstanceId();
241     uiTaskExecutor.PostTask(
242         [weak, instanceID] {
243             ContainerScope scope(instanceID);
244             auto pluginPattern = weak.Upgrade();
245             CHECK_NULL_VOID(pluginPattern);
246             auto pluginSubContainer = pluginPattern->GetPluginSubContainer();
247             RequestPluginInfo info = pluginPattern->GetPluginRequestInfo();
248             TAG_LOGI(AceLogTag::ACE_PLUGIN_COMPONENT, "requestPluginInfo: %{public}s.", info.ToString().c_str());
249             CHECK_NULL_VOID(pluginSubContainer);
250             auto packagePathStr = pluginPattern->GetPackagePath(weak, info);
251             if (packagePathStr.empty()) {
252                 pluginPattern->FireOnErrorEvent("1", "package path is empty.");
253                 return;
254             }
255             if (!info.bundleName.empty() && !info.moduleName.empty()) {
256                 pluginPattern->pluginSubContainer_->SetPluginBundleName(info.bundleName);
257                 pluginPattern->pluginSubContainer_->SetPluginModuleName(info.moduleName);
258             }
259             if (packagePathStr.rfind(".hap") != std::string::npos) {
260                 std::string sub = packagePathStr.substr(1, packagePathStr.size() - 5) + "/";
261                 pluginPattern->ReplaceAll(info.source, sub, "");
262                 pluginPattern->pluginSubContainer_->RunDecompressedPlugin(
263                     packagePathStr, info.abilityName, info.source, info.moduleResPath, pluginPattern->GetData());
264             } else {
265                 pluginPattern->pluginSubContainer_->RunPlugin(
266                     packagePathStr, info.abilityName, info.source, info.moduleResPath, pluginPattern->GetData());
267             }
268         },
269         "ArkUIPluginRun");
270         TAG_LOGI(AceLogTag::ACE_PLUGIN_COMPONENT, "CreatePluginSubContainer end.");
271 }
272 
ReplaceAll(std::string & str,const std::string & pattern,const std::string & newPattern)273 void PluginPattern::ReplaceAll(std::string& str, const std::string& pattern, const std::string& newPattern)
274 {
275     const size_t nSize = newPattern.size();
276     const size_t pSize = pattern.size();
277     for (size_t pos = str.find(pattern, 0); pos != std::string::npos; pos = str.find(pattern, pos + nSize)) {
278         str.replace(pos, pSize, newPattern);
279     }
280 }
281 
GetDrawDelegate()282 std::unique_ptr<DrawDelegate> PluginPattern::GetDrawDelegate()
283 {
284     auto drawDelegate = std::make_unique<DrawDelegate>();
285 #ifdef ENABLE_ROSEN_BACKEND
286     drawDelegate->SetDrawRSFrameCallback(
287         [weak = WeakClaim(this)](std::shared_ptr<RSNode>& node, const Rect& /* dirty */) {
288             auto plugin = weak.Upgrade();
289             if (!plugin) {
290                 TAG_LOGE(AceLogTag::ACE_PLUGIN_COMPONENT, "Failed to draw rs frame with invalid plugin pattern.");
291                 return;
292             }
293             auto host = plugin->GetHost();
294             CHECK_NULL_VOID(host);
295             auto context = DynamicCast<NG::RosenRenderContext>(host->GetRenderContext());
296             CHECK_NULL_VOID(context);
297             auto rsNode = context->GetRSNode();
298             CHECK_NULL_VOID(rsNode);
299             if (node) {
300                 node->SetBackgroundColor(Color::TRANSPARENT.GetValue());
301             } else {
302                 TAG_LOGE(AceLogTag::ACE_PLUGIN_COMPONENT, "Failed to draw rs frame with invalid rs node.");
303             }
304             rsNode->AddChild(node, -1);
305             host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
306         });
307 #endif
308     return drawDelegate;
309 }
310 
FireOnCompleteEvent() const311 void PluginPattern::FireOnCompleteEvent() const
312 {
313     TAG_LOGI(AceLogTag::ACE_PLUGIN_COMPONENT, "FireOnCompleteEvent.");
314     if (loadFialState_) {
315         return;
316     }
317     auto host = GetHost();
318     CHECK_NULL_VOID(host);
319     auto eventHub = host->GetEventHub<PluginEventHub>();
320     CHECK_NULL_VOID(eventHub);
321     auto json = JsonUtil::Create(true);
322     eventHub->FireOnComplete(json->ToString());
323 }
324 
FireOnErrorEvent(const std::string & code,const std::string & msg)325 void PluginPattern::FireOnErrorEvent(const std::string& code, const std::string& msg)
326 {
327     loadFialState_ = true;
328     TAG_LOGI(AceLogTag::ACE_PLUGIN_COMPONENT, "code: %{public}s, msg: %{public}s", code.c_str(), msg.c_str());
329     auto host = GetHost();
330     CHECK_NULL_VOID(host);
331     auto eventHub = host->GetEventHub<PluginEventHub>();
332     CHECK_NULL_VOID(eventHub);
333     auto json = JsonUtil::Create(true);
334     json->Put("errcode", code.c_str());
335     json->Put("msg", msg.c_str());
336     eventHub->FireOnError(json->ToString());
337 }
338 
OnActionEvent(const std::string & action) const339 void PluginPattern::OnActionEvent(const std::string& action) const
340 {
341     TAG_LOGI(AceLogTag::ACE_PLUGIN_COMPONENT, "action: %{public}s", action.c_str());
342     auto eventAction = JsonUtil::ParseJsonString(action);
343     if (!eventAction->IsValid()) {
344         return;
345     }
346     auto actionType = eventAction->GetValue("action");
347     if (!actionType->IsValid()) {
348         return;
349     }
350 
351     auto type = actionType->GetString();
352     if (type != "router" && type != "message") {
353         return;
354     }
355 
356     CHECK_NULL_VOID(pluginManagerBridge_);
357     pluginManagerBridge_->OnActionEvent(action);
358 }
359 
ISAllowUpdate() const360 bool PluginPattern::ISAllowUpdate() const
361 {
362     auto host = GetHost();
363     CHECK_NULL_RETURN(host, true);
364     auto property = host->GetLayoutProperty<PluginLayoutProperty>();
365     CHECK_NULL_RETURN(property, true);
366     auto pluginInfo = property->GetRequestPluginInfo();
367     CHECK_NULL_RETURN(property, true);
368     return pluginInfo->allowUpdate;
369 }
370 
SplitString(const std::string & str,char tag,std::vector<std::string> & strList) const371 void PluginPattern::SplitString(const std::string& str, char tag, std::vector<std::string>& strList) const
372 {
373     std::string subStr;
374     for (size_t i = 0; i < str.length(); i++) {
375         if (tag == str[i]) {
376             if (!subStr.empty()) {
377                 strList.push_back(subStr);
378                 subStr.clear();
379             }
380         } else {
381             subStr.push_back(str[i]);
382         }
383     }
384     if (!subStr.empty()) {
385         strList.push_back(subStr);
386     }
387 }
388 
GetPackagePath(const WeakPtr<PluginPattern> & weak,RequestPluginInfo & info) const389 std::string PluginPattern::GetPackagePath(const WeakPtr<PluginPattern>& weak, RequestPluginInfo& info) const
390 {
391     std::string packagePathStr;
392     size_t pos_ets = info.pluginName.rfind(ETS_EXT);
393     if (pos_ets != std::string::npos && info.pluginName.substr(pos_ets) == ETS_EXT) {
394         info.pluginName = info.pluginName.substr(0, info.pluginName.length() - SIZE_OF_ETS_EXT);
395         info.pluginName = info.pluginName + JS_EXT;
396     }
397     size_t pos = info.pluginName.rfind(JS_EXT);
398     if (info.pluginName.front() == '/' && pos != std::string::npos && info.pluginName.substr(pos) == JS_EXT) {
399         packagePathStr = GetPackagePathByAbsolutePath(weak, info);
400     } else {
401         packagePathStr = GetPackagePathByWant(weak, info);
402     }
403     return packagePathStr;
404 }
405 
GetPackagePathByWant(const WeakPtr<PluginPattern> & weak,RequestPluginInfo & info) const406 std::string PluginPattern::GetPackagePathByWant(const WeakPtr<PluginPattern>& weak, RequestPluginInfo& info) const
407 {
408     std::string packagePathStr;
409     auto pluginPattern = weak.Upgrade();
410     CHECK_NULL_RETURN(pluginPattern, packagePathStr);
411     std::vector<std::string> strList;
412     pluginPattern->SplitString(info.bundleName, '/', strList);
413 
414     std::vector<int32_t> userIds;
415     ErrCode errCode = GetActiveAccountIds(userIds);
416     if (errCode != ERR_OK) {
417         pluginPattern->FireOnErrorEvent("1", "Query Active OsAccountIds failed!");
418         return packagePathStr;
419     }
420     GetAbilityNameByWant(weak, info);
421     packagePathStr = GerPackagePathByBms(weak, info, strList, userIds);
422 
423     return packagePathStr;
424 }
GetPackagePathByAbsolutePath(const WeakPtr<PluginPattern> & weak,RequestPluginInfo & info) const425 std::string PluginPattern::GetPackagePathByAbsolutePath(
426     const WeakPtr<PluginPattern>& weak, RequestPluginInfo& info) const
427 {
428     std::string packagePathStr;
429     auto pluginPattern = weak.Upgrade();
430     CHECK_NULL_RETURN(pluginPattern, packagePathStr);
431     std::string assets = "assets/js/";
432     size_t posAssets = info.pluginName.rfind(assets);
433     if (posAssets != std::string::npos) {
434         packagePathStr = info.pluginName.substr(0, posAssets);
435         size_t posModule = info.pluginName.find("/", posAssets + assets.size());
436         if (posModule != std::string::npos) {
437             info.abilityName =
438                 info.pluginName.substr(posAssets + assets.size(), posModule - (posAssets + assets.size()));
439             info.source = info.pluginName.substr(posModule);
440         } else {
441             info.abilityName = "/";
442             info.source = info.pluginName.substr(posAssets + assets.size());
443         }
444     } else {
445         size_t pos = info.pluginName.rfind("/");
446         packagePathStr = info.pluginName.substr(0, pos + 1);
447         info.source = info.pluginName.substr(pos + 1);
448         info.abilityName = "/";
449     }
450     return packagePathStr;
451 }
452 
GetAbilityNameByWant(const WeakPtr<PluginPattern> & weak,RequestPluginInfo & info) const453 void PluginPattern::GetAbilityNameByWant(const WeakPtr<PluginPattern>& weak, RequestPluginInfo& info) const
454 {
455     auto pluginPattern = weak.Upgrade();
456     CHECK_NULL_VOID(pluginPattern);
457     std::vector<std::string> strList;
458     pluginPattern->SplitString(info.pluginName, '&', strList);
459     if (strList.empty()) {
460         pluginPattern->FireOnErrorEvent("1", "Template source is empty.");
461         return;
462     }
463     if (strList.size() == 1) {
464         auto pos = info.pluginName.rfind(JS_EXT);
465         if (pos != std::string::npos && (strList[0].substr(pos) == JS_EXT)) {
466             info.source = info.pluginName;
467         } else {
468             info.abilityName = info.pluginName;
469         }
470     } else {
471         size_t pos_ets = strList[0].rfind(ETS_EXT);
472         if (pos_ets != std::string::npos && strList[0].substr(pos_ets) == ETS_EXT) {
473             strList[0] = strList[0].substr(0, strList[0].length() - SIZE_OF_ETS_EXT);
474             strList[0] = strList[0] + JS_EXT;
475         }
476         auto pos = strList[0].rfind(JS_EXT);
477         if (pos != std::string::npos && (strList[0].substr(pos) == JS_EXT)) {
478             info.source = strList[0];
479         } else {
480             info.abilityName = strList[0];
481         }
482         info.moduleName = strList[1];
483     }
484 }
485 
GerPackagePathByBms(const WeakPtr<PluginPattern> & weak,RequestPluginInfo & info,const std::vector<std::string> & strList,const std::vector<int32_t> & userIds) const486 std::string PluginPattern::GerPackagePathByBms(const WeakPtr<PluginPattern>& weak, RequestPluginInfo& info,
487     const std::vector<std::string>& strList, const std::vector<int32_t>& userIds) const
488 {
489     std::string packagePathStr;
490     auto pluginPattern = weak.Upgrade();
491     CHECK_NULL_RETURN(pluginPattern, packagePathStr);
492     auto bms = PluginComponentManager::GetInstance()->GetBundleManager();
493     if (!bms) {
494         pluginPattern->FireOnErrorEvent("1", "Bms bundleManager is nullptr.");
495         return packagePathStr;
496     }
497 
498     if (strList.empty()) {
499         pluginPattern->FireOnErrorEvent("1", "App bundleName is empty.");
500         return packagePathStr;
501     }
502 
503     AppExecFwk::BundleInfo bundleInfo;
504     bool ret = bms->GetBundleInfo(strList[0], AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo,
505         userIds.size() > 0 ? userIds[0] : AppExecFwk::Constants::UNSPECIFIED_USERID);
506     if (!ret) {
507         pluginPattern->FireOnErrorEvent("1", "Bms get bundleName failed!");
508         return packagePathStr;
509     }
510     if (bundleInfo.hapModuleInfos.empty() || bundleInfo.hapModuleInfos[0].hapPath.empty()) {
511         if (strList.size() == 1) {
512             if (bundleInfo.moduleResPaths.size() == 1) {
513                 info.moduleResPath = bundleInfo.moduleResPaths[0];
514             } else {
515                 pluginPattern->FireOnErrorEvent("1", "Bms moduleResPaths is empty.");
516                 return packagePathStr;
517             }
518             packagePathStr = bundleInfo.moduleDirs[0] + "/";
519         } else {
520             AAFwk::Want want;
521             AppExecFwk::AbilityInfo abilityInfo;
522             AppExecFwk::ElementName element("", strList[0], strList[1]);
523             want.SetElement(element);
524             bool ret = bms->QueryAbilityInfo(want, AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_DEFAULT,
525                 userIds.size() > 0 ? userIds[0] : AppExecFwk::Constants::UNSPECIFIED_USERID, abilityInfo);
526             if (!ret) {
527                 pluginPattern->FireOnErrorEvent("1", "Bms get bundleName failed!");
528                 return packagePathStr;
529             }
530             packagePathStr = abilityInfo.applicationInfo.codePath + "/" + abilityInfo.package + "/";
531             info.moduleResPath = abilityInfo.resourcePath;
532         }
533         return packagePathStr;
534     }
535     if (info.moduleName.empty() || info.moduleName == "default") {
536         info.moduleResPath = bundleInfo.hapModuleInfos[0].resourcePath;
537         info.moduleName = bundleInfo.hapModuleInfos[0].name;
538         packagePathStr = bundleInfo.hapModuleInfos[0].hapPath;
539         return packagePathStr;
540     }
541     auto result = std::find_if(bundleInfo.hapModuleInfos.begin(), bundleInfo.hapModuleInfos.end(),
542         [moduleName = info.moduleName](
543             AppExecFwk::HapModuleInfo hapModuleInfo) { return hapModuleInfo.moduleName == moduleName; });
544     if (result != bundleInfo.hapModuleInfos.end()) {
545         info.moduleResPath = result->resourcePath;
546         packagePathStr = result->hapPath;
547         return packagePathStr;
548     }
549     pluginPattern->FireOnErrorEvent(
550         "1", "Bms get hapPath failed! Cannot find hap according to BundleName and ModuleName!");
551     return packagePathStr;
552 }
553 
GetPluginSubContainer() const554 const RefPtr<PluginSubContainer>& PluginPattern::GetPluginSubContainer() const
555 {
556     return pluginSubContainer_;
557 };
558 
FlushReload() const559 void PluginPattern::FlushReload() const
560 {
561     auto host = GetHost();
562     CHECK_NULL_VOID(host);
563     auto customNode = DynamicCast<CustomNodeBase>(host->GetFirstChild());
564     CHECK_NULL_VOID(customNode);
565     customNode->FireReloadFunction(true);
566 }
567 } // namespace OHOS::Ace::NG
568