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(GetPackageCodeLanguage(GetPluginRequestInfo()));
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->GetOrCreateEventHub<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->GetOrCreateEventHub<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
GetPackageCodeLanguage(const RequestPluginInfo & info) const389 std::string PluginPattern::GetPackageCodeLanguage(const RequestPluginInfo& info) const
390 {
391 std::string codeLanguage;
392
393 std::vector<std::string> strList;
394 SplitString(info.bundleName, '/', strList);
395 if (strList.empty()) {
396 return codeLanguage;
397 }
398
399 std::vector<int32_t> userIds;
400 GetActiveAccountIds(userIds);
401
402 auto bms = PluginComponentManager::GetInstance()->GetBundleManager();
403 if (!bms) {
404 return codeLanguage;
405 }
406
407 AppExecFwk::BundleInfo bundleInfo;
408 bool ret = bms->GetBundleInfo(strList[0], AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo,
409 userIds.size() > 0 ? userIds[0] : AppExecFwk::Constants::UNSPECIFIED_USERID);
410 if (!ret) {
411 return codeLanguage;
412 }
413 return bundleInfo.applicationInfo.arkTSMode;
414 }
415
GetPackagePath(const WeakPtr<PluginPattern> & weak,RequestPluginInfo & info) const416 std::string PluginPattern::GetPackagePath(const WeakPtr<PluginPattern>& weak, RequestPluginInfo& info) const
417 {
418 std::string packagePathStr;
419 size_t pos_ets = info.pluginName.rfind(ETS_EXT);
420 if (pos_ets != std::string::npos && info.pluginName.substr(pos_ets) == ETS_EXT) {
421 info.pluginName = info.pluginName.substr(0, info.pluginName.length() - SIZE_OF_ETS_EXT);
422 info.pluginName = info.pluginName + JS_EXT;
423 }
424 size_t pos = info.pluginName.rfind(JS_EXT);
425 if (info.pluginName.front() == '/' && pos != std::string::npos && info.pluginName.substr(pos) == JS_EXT) {
426 packagePathStr = GetPackagePathByAbsolutePath(weak, info);
427 } else {
428 packagePathStr = GetPackagePathByWant(weak, info);
429 }
430 return packagePathStr;
431 }
432
GetPackagePathByWant(const WeakPtr<PluginPattern> & weak,RequestPluginInfo & info) const433 std::string PluginPattern::GetPackagePathByWant(const WeakPtr<PluginPattern>& weak, RequestPluginInfo& info) const
434 {
435 std::string packagePathStr;
436 auto pluginPattern = weak.Upgrade();
437 CHECK_NULL_RETURN(pluginPattern, packagePathStr);
438 std::vector<std::string> strList;
439 pluginPattern->SplitString(info.bundleName, '/', strList);
440
441 std::vector<int32_t> userIds;
442 ErrCode errCode = GetActiveAccountIds(userIds);
443 if (errCode != ERR_OK) {
444 pluginPattern->FireOnErrorEvent("1", "Query Active OsAccountIds failed!");
445 return packagePathStr;
446 }
447 GetAbilityNameByWant(weak, info);
448 packagePathStr = GetPackagePathByBms(weak, info, strList, userIds);
449
450 return packagePathStr;
451 }
GetPackagePathByAbsolutePath(const WeakPtr<PluginPattern> & weak,RequestPluginInfo & info) const452 std::string PluginPattern::GetPackagePathByAbsolutePath(
453 const WeakPtr<PluginPattern>& weak, RequestPluginInfo& info) const
454 {
455 std::string packagePathStr;
456 auto pluginPattern = weak.Upgrade();
457 CHECK_NULL_RETURN(pluginPattern, packagePathStr);
458 std::string assets = "assets/js/";
459 size_t posAssets = info.pluginName.rfind(assets);
460 if (posAssets != std::string::npos) {
461 packagePathStr = info.pluginName.substr(0, posAssets);
462 size_t posModule = info.pluginName.find("/", posAssets + assets.size());
463 if (posModule != std::string::npos) {
464 info.abilityName =
465 info.pluginName.substr(posAssets + assets.size(), posModule - (posAssets + assets.size()));
466 info.source = info.pluginName.substr(posModule);
467 } else {
468 info.abilityName = "/";
469 info.source = info.pluginName.substr(posAssets + assets.size());
470 }
471 } else {
472 size_t pos = info.pluginName.rfind("/");
473 packagePathStr = info.pluginName.substr(0, pos + 1);
474 info.source = info.pluginName.substr(pos + 1);
475 info.abilityName = "/";
476 }
477 return packagePathStr;
478 }
479
GetAbilityNameByWant(const WeakPtr<PluginPattern> & weak,RequestPluginInfo & info) const480 void PluginPattern::GetAbilityNameByWant(const WeakPtr<PluginPattern>& weak, RequestPluginInfo& info) const
481 {
482 auto pluginPattern = weak.Upgrade();
483 CHECK_NULL_VOID(pluginPattern);
484 std::vector<std::string> strList;
485 pluginPattern->SplitString(info.pluginName, '&', strList);
486 if (strList.empty()) {
487 pluginPattern->FireOnErrorEvent("1", "Template source is empty.");
488 return;
489 }
490 if (strList.size() == 1) {
491 auto pos = info.pluginName.rfind(JS_EXT);
492 if (pos != std::string::npos && (strList[0].substr(pos) == JS_EXT)) {
493 info.source = info.pluginName;
494 } else {
495 info.abilityName = info.pluginName;
496 }
497 } else {
498 size_t pos_ets = strList[0].rfind(ETS_EXT);
499 if (pos_ets != std::string::npos && strList[0].substr(pos_ets) == ETS_EXT) {
500 strList[0] = strList[0].substr(0, strList[0].length() - SIZE_OF_ETS_EXT);
501 strList[0] = strList[0] + JS_EXT;
502 }
503 auto pos = strList[0].rfind(JS_EXT);
504 if (pos != std::string::npos && (strList[0].substr(pos) == JS_EXT)) {
505 info.source = strList[0];
506 } else {
507 info.abilityName = strList[0];
508 }
509 info.moduleName = strList[1];
510 }
511 }
512
GetPackagePathByBms(const WeakPtr<PluginPattern> & weak,RequestPluginInfo & info,const std::vector<std::string> & strList,const std::vector<int32_t> & userIds) const513 std::string PluginPattern::GetPackagePathByBms(const WeakPtr<PluginPattern>& weak, RequestPluginInfo& info,
514 const std::vector<std::string>& strList, const std::vector<int32_t>& userIds) const
515 {
516 std::string packagePathStr;
517 auto pluginPattern = weak.Upgrade();
518 CHECK_NULL_RETURN(pluginPattern, packagePathStr);
519 auto bms = PluginComponentManager::GetInstance()->GetBundleManager();
520 if (!bms) {
521 pluginPattern->FireOnErrorEvent("1", "Bms bundleManager is nullptr.");
522 return packagePathStr;
523 }
524
525 if (strList.empty()) {
526 pluginPattern->FireOnErrorEvent("1", "App bundleName is empty.");
527 return packagePathStr;
528 }
529
530 AppExecFwk::BundleInfo bundleInfo;
531 bool ret = bms->GetBundleInfo(strList[0], AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo,
532 userIds.size() > 0 ? userIds[0] : AppExecFwk::Constants::UNSPECIFIED_USERID);
533 if (!ret) {
534 pluginPattern->FireOnErrorEvent("1", "Bms get bundleName failed!");
535 return packagePathStr;
536 }
537 if (bundleInfo.hapModuleInfos.empty() || bundleInfo.hapModuleInfos[0].hapPath.empty()) {
538 if (strList.size() == 1) {
539 if (bundleInfo.moduleResPaths.size() == 1) {
540 info.moduleResPath = bundleInfo.moduleResPaths[0];
541 } else {
542 pluginPattern->FireOnErrorEvent("1", "Bms moduleResPaths is empty.");
543 return packagePathStr;
544 }
545 packagePathStr = bundleInfo.moduleDirs[0] + "/";
546 } else {
547 AAFwk::Want want;
548 AppExecFwk::AbilityInfo abilityInfo;
549 AppExecFwk::ElementName element("", strList[0], strList[1]);
550 want.SetElement(element);
551 bool ret = bms->QueryAbilityInfo(want, AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_DEFAULT,
552 userIds.size() > 0 ? userIds[0] : AppExecFwk::Constants::UNSPECIFIED_USERID, abilityInfo);
553 if (!ret) {
554 pluginPattern->FireOnErrorEvent("1", "Bms get bundleName failed!");
555 return packagePathStr;
556 }
557 packagePathStr = abilityInfo.applicationInfo.codePath + "/" + abilityInfo.package + "/";
558 info.moduleResPath = abilityInfo.resourcePath;
559 }
560 return packagePathStr;
561 }
562 if (info.moduleName.empty() || info.moduleName == "default") {
563 info.moduleResPath = bundleInfo.hapModuleInfos[0].resourcePath;
564 info.moduleName = bundleInfo.hapModuleInfos[0].name;
565 packagePathStr = bundleInfo.hapModuleInfos[0].hapPath;
566 return packagePathStr;
567 }
568 auto result = std::find_if(bundleInfo.hapModuleInfos.begin(), bundleInfo.hapModuleInfos.end(),
569 [moduleName = info.moduleName](
570 AppExecFwk::HapModuleInfo hapModuleInfo) { return hapModuleInfo.moduleName == moduleName; });
571 if (result != bundleInfo.hapModuleInfos.end()) {
572 info.moduleResPath = result->resourcePath;
573 packagePathStr = result->hapPath;
574 return packagePathStr;
575 }
576 pluginPattern->FireOnErrorEvent(
577 "1", "Bms get hapPath failed! Cannot find hap according to BundleName and ModuleName!");
578 return packagePathStr;
579 }
580
GetPluginSubContainer() const581 const RefPtr<PluginSubContainer>& PluginPattern::GetPluginSubContainer() const
582 {
583 return pluginSubContainer_;
584 };
585
FlushReload() const586 void PluginPattern::FlushReload() const
587 {
588 auto host = GetHost();
589 CHECK_NULL_VOID(host);
590 auto customNode = DynamicCast<CustomNodeBase>(host->GetFirstChild());
591 CHECK_NULL_VOID(customNode);
592 customNode->FireReloadFunction(true);
593 }
594 } // namespace OHOS::Ace::NG
595