1 /*
2  * Copyright (c) 2024 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/ui_extension/isolated_pattern.h"
17 
18 #include <sys/stat.h>
19 #include <sys/statfs.h>
20 
21 #include "adapter/ohos/osal/want_wrap_ohos.h"
22 #include "base/log/log_wrapper.h"
23 #include "core/common/dynamic_component_renderer.h"
24 #include "base/log/dump_log.h"
25 #include "core/components_ng/render/animation_utils.h"
26 #include "core/event/key_event.h"
27 #include "core/event/pointer_event.h"
28 #include "core/pipeline_ng/pipeline_context.h"
29 #include "display_manager.h"
30 #include "session/host/include/session.h"
31 #include "core/pipeline_ng/pipeline_context.h"
32 
33 namespace OHOS::Ace::NG {
34 namespace {
35 constexpr char RESOURCE_PATH[] = "resourcePath";
36 constexpr char ABC_PATH[] = "abcPath";
37 constexpr char ENTRY_POINT[] = "entryPoint";
38 constexpr char REGISTER_COMPONENTS[] = "registerComponents";
39 constexpr int32_t PARAM_ERR_CODE = 10001;
40 constexpr char PARAM_NAME[] = "paramError";
41 constexpr char PARAM_MSG[] = "The param is empty";
42 }
43 
44 int32_t IsolatedPattern::isolatedIdGenerator_ = 0;
45 
IsolatedPattern()46 IsolatedPattern::IsolatedPattern()
47     : PlatformPattern(AceLogTag::ACE_ISOLATED_COMPONENT, ++isolatedIdGenerator_)
48 {
49     auto pipeline = PipelineContext::GetCurrentContext();
50     CHECK_NULL_VOID(pipeline);
51     auto uiExtensionManager = pipeline->GetUIExtensionManager();
52     CHECK_NULL_VOID(uiExtensionManager);
53     uiExtensionId_ = uiExtensionManager->ApplyExtensionId();
54     PLATFORM_LOGI("The IsolatedPattern is created.");
55 }
56 
~IsolatedPattern()57 IsolatedPattern::~IsolatedPattern()
58 {
59     auto pipeline = PipelineContext::GetCurrentContext();
60     CHECK_NULL_VOID(pipeline);
61     auto uiExtensionManager = pipeline->GetUIExtensionManager();
62     CHECK_NULL_VOID(uiExtensionManager);
63     uiExtensionManager->RecycleExtensionId(uiExtensionId_);
64     PLATFORM_LOGI("The IsolatedPattern is destroyed.");
65 }
66 
GetUiExtensionId()67 int32_t IsolatedPattern::GetUiExtensionId()
68 {
69     return uiExtensionId_;
70 }
71 
WrapExtensionAbilityId(int64_t extensionOffset,int64_t abilityId)72 int64_t IsolatedPattern::WrapExtensionAbilityId(int64_t extensionOffset, int64_t abilityId)
73 {
74     return uiExtensionId_ * extensionOffset + abilityId;
75 }
76 
GetAccessibilitySessionAdapter()77 RefPtr<AccessibilitySessionAdapter> IsolatedPattern::GetAccessibilitySessionAdapter()
78 {
79     return accessibilitySessionAdapter_;
80 }
81 
InitializeDynamicComponent(const std::string & hapPath,const std::string & abcPath,const std::string & entryPoint,void * runtime)82 void IsolatedPattern::InitializeDynamicComponent(
83     const std::string& hapPath, const std::string& abcPath, const std::string& entryPoint, void* runtime)
84 {
85     if (hapPath.empty() || abcPath.empty() || entryPoint.empty() || runtime == nullptr) {
86         PLATFORM_LOGE("The param empty.");
87         return;
88     }
89 
90     curIsolatedInfo_.abcPath = abcPath;
91     curIsolatedInfo_.reourcePath = hapPath;
92     curIsolatedInfo_.entryPoint = entryPoint;
93     InitializeRender(runtime);
94 }
95 
InitializeIsolatedComponent(const RefPtr<OHOS::Ace::WantWrap> & wantWrap,void * runtime)96 void IsolatedPattern::InitializeIsolatedComponent(const RefPtr<OHOS::Ace::WantWrap>& wantWrap, void* runtime)
97 {
98     auto want = AceType::DynamicCast<WantWrapOhos>(wantWrap)->GetWant();
99     auto resourcePath = want.GetStringParam(RESOURCE_PATH);
100     auto abcPath = want.GetStringParam(ABC_PATH);
101     auto entryPoint = want.GetStringParam(ENTRY_POINT);
102     auto registerComponents = want.GetStringArrayParam(REGISTER_COMPONENTS);
103     if (resourcePath.empty() || abcPath.empty() || entryPoint.empty() || runtime == nullptr) {
104         PLATFORM_LOGE("The param empty.");
105         FireOnErrorCallback(PARAM_ERR_CODE, PARAM_NAME, PARAM_MSG);
106         return;
107     }
108 
109     curIsolatedInfo_.abcPath = abcPath;
110     curIsolatedInfo_.reourcePath = resourcePath;
111     curIsolatedInfo_.entryPoint = entryPoint;
112     curIsolatedInfo_.registerComponents = registerComponents;
113     InitializeRender(runtime);
114 }
115 
InitializeRender(void * runtime)116 void IsolatedPattern::InitializeRender(void* runtime)
117 {
118     isolatedDumpInfo_.createLimitedWorkerTime = GetCurrentTimestamp();
119 #if !defined(PREVIEW)
120     if (!dynamicComponentRenderer_) {
121         ContainerScope scope(instanceId_);
122         dynamicComponentRenderer_ = DynamicComponentRenderer::Create(GetHost(), runtime, curIsolatedInfo_);
123         CHECK_NULL_VOID(dynamicComponentRenderer_);
124         dynamicComponentRenderer_->SetAdaptiveSize(adaptiveWidth_, adaptiveHeight_);
125         dynamicComponentRenderer_->CreateContent();
126         accessibilitySessionAdapter_ =
127         AceType::MakeRefPtr<AccessibilitySessionAdapterIsolatedComponent>(dynamicComponentRenderer_);
128     }
129 #else
130     PLATFORM_LOGE("IsolatedComponent not support preview.");
131 #endif
132 }
133 
FireOnErrorCallbackOnUI(int32_t code,const std::string & name,const std::string & msg)134 void IsolatedPattern::FireOnErrorCallbackOnUI(
135     int32_t code, const std::string& name, const std::string& msg)
136 {
137     ContainerScope scope(instanceId_);
138     auto host = GetHost();
139     CHECK_NULL_VOID(host);
140     auto pipeline = host->GetContext();
141     CHECK_NULL_VOID(pipeline);
142     auto uiTaskExecutor = SingleTaskExecutor::Make(
143         pipeline->GetTaskExecutor(), TaskExecutor::TaskType::UI);
144     uiTaskExecutor.PostTask([weak = WeakClaim(this), code, name, msg] {
145         auto pattern = weak.Upgrade();
146         CHECK_NULL_VOID(pattern);
147         pattern->FireOnErrorCallback(code, name, msg);
148         }, "FireOnErrorCallback");
149 }
150 
DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)151 void IsolatedPattern::DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
152 {
153     CHECK_NULL_VOID(pointerEvent);
154     CHECK_NULL_VOID(dynamicComponentRenderer_);
155     dynamicComponentRenderer_->TransferPointerEvent(pointerEvent);
156 }
157 
DispatchFocusActiveEvent(bool isFocusActive)158 void IsolatedPattern::DispatchFocusActiveEvent(bool isFocusActive)
159 {
160     CHECK_NULL_VOID(dynamicComponentRenderer_);
161     dynamicComponentRenderer_->TransferFocusActiveEvent(isFocusActive);
162 }
163 
HandleKeyEvent(const KeyEvent & event)164 bool IsolatedPattern::HandleKeyEvent(const KeyEvent& event)
165 {
166     CHECK_NULL_RETURN(event.rawKeyEvent, false);
167     CHECK_NULL_RETURN(dynamicComponentRenderer_, false);
168     return dynamicComponentRenderer_->TransferKeyEvent(event);
169 }
170 
HandleFocusEvent()171 void IsolatedPattern::HandleFocusEvent()
172 {
173     CHECK_NULL_VOID(dynamicComponentRenderer_);
174     auto host = GetHost();
175     CHECK_NULL_VOID(host);
176     auto pipeline = host->GetContext();
177     CHECK_NULL_VOID(pipeline);
178     if (pipeline->GetIsFocusActive()) {
179         dynamicComponentRenderer_->TransferFocusActiveEvent(true);
180     }
181     dynamicComponentRenderer_->TransferFocusState(true);
182 }
183 
HandleBlurEvent()184 void IsolatedPattern::HandleBlurEvent()
185 {
186     CHECK_NULL_VOID(dynamicComponentRenderer_);
187     dynamicComponentRenderer_->TransferFocusActiveEvent(false);
188     dynamicComponentRenderer_->TransferFocusState(false);
189 }
190 
OnAttachToFrameNode()191 void IsolatedPattern::OnAttachToFrameNode()
192 {
193     ContainerScope scope(instanceId_);
194     auto pipeline = PipelineContext::GetCurrentContext();
195     CHECK_NULL_VOID(pipeline);
196     auto host = GetHost();
197     CHECK_NULL_VOID(host);
198     pipeline->AddOnAreaChangeNode(host->GetId());
199 }
200 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)201 bool IsolatedPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
202 {
203     if (config.skipLayout || config.skipMeasure) {
204         return false;
205     }
206     CHECK_NULL_RETURN(dynamicComponentRenderer_, false);
207     auto& node = dirty->GetGeometryNode();
208     CHECK_NULL_RETURN(node, false);
209     auto size = node->GetContentSize();
210     float density = 1.0f;
211     int32_t orientation = 0;
212     auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
213     if (defaultDisplay) {
214         density = defaultDisplay->GetVirtualPixelRatio();
215         orientation = static_cast<int32_t>(defaultDisplay->GetOrientation());
216     }
217 
218     auto host = GetHost();
219     CHECK_NULL_RETURN(host, false);
220     auto pipeline = host->GetContext();
221     CHECK_NULL_RETURN(pipeline, false);
222     auto animationOption = pipeline->GetSyncAnimationOption();
223     dynamicComponentRenderer_->UpdateViewportConfig(size, density, orientation, animationOption);
224     return false;
225 }
226 
OnDetachFromFrameNode(FrameNode * frameNode)227 void IsolatedPattern::OnDetachFromFrameNode(FrameNode* frameNode)
228 {
229     CHECK_NULL_VOID(dynamicComponentRenderer_);
230     dynamicComponentRenderer_->DestroyContent();
231     dynamicComponentRenderer_ = nullptr;
232 }
233 
SetAdaptiveWidth(bool state)234 void IsolatedPattern::SetAdaptiveWidth(bool state)
235 {
236     adaptiveWidth_ = state;
237     CHECK_NULL_VOID(dynamicComponentRenderer_);
238     dynamicComponentRenderer_->SetAdaptiveSize(adaptiveWidth_, adaptiveHeight_);
239 }
240 
SetAdaptiveHeight(bool state)241 void IsolatedPattern::SetAdaptiveHeight(bool state)
242 {
243     adaptiveHeight_ = state;
244     CHECK_NULL_VOID(dynamicComponentRenderer_);
245     dynamicComponentRenderer_->SetAdaptiveSize(adaptiveWidth_, adaptiveHeight_);
246 }
247 
SearchExtensionElementInfoByAccessibilityId(int64_t elementId,int32_t mode,int64_t baseParent,std::list<Accessibility::AccessibilityElementInfo> & output)248 void IsolatedPattern::SearchExtensionElementInfoByAccessibilityId(int64_t elementId, int32_t mode, int64_t baseParent,
249     std::list<Accessibility::AccessibilityElementInfo>& output)
250 {
251     CHECK_NULL_VOID(dynamicComponentRenderer_);
252     dynamicComponentRenderer_->SearchElementInfoByAccessibilityId(elementId, mode, baseParent, output);
253 }
254 
SearchElementInfosByText(int64_t elementId,const std::string & text,int64_t baseParent,std::list<Accessibility::AccessibilityElementInfo> & output)255 void IsolatedPattern::SearchElementInfosByText(int64_t elementId, const std::string& text, int64_t baseParent,
256     std::list<Accessibility::AccessibilityElementInfo>& output)
257 {
258     CHECK_NULL_VOID(dynamicComponentRenderer_);
259     dynamicComponentRenderer_->SearchElementInfosByText(elementId, text, baseParent, output);
260 }
261 
FindFocusedElementInfo(int64_t elementId,int32_t focusType,int64_t baseParent,Accessibility::AccessibilityElementInfo & output)262 void IsolatedPattern::FindFocusedElementInfo(int64_t elementId, int32_t focusType, int64_t baseParent,
263     Accessibility::AccessibilityElementInfo& output)
264 {
265     CHECK_NULL_VOID(dynamicComponentRenderer_);
266     dynamicComponentRenderer_->FindFocusedElementInfo(elementId, focusType, baseParent, output);
267 }
268 
FocusMoveSearch(int64_t elementId,int32_t direction,int64_t baseParent,Accessibility::AccessibilityElementInfo & output)269 void IsolatedPattern::FocusMoveSearch(int64_t elementId, int32_t direction, int64_t baseParent,
270     Accessibility::AccessibilityElementInfo& output)
271 {
272     CHECK_NULL_VOID(dynamicComponentRenderer_);
273     dynamicComponentRenderer_->FocusMoveSearch(elementId, direction, baseParent, output);
274 }
275 
TransferExecuteAction(int64_t elementId,const std::map<std::string,std::string> & actionArguments,int32_t action,int64_t offset)276 bool IsolatedPattern::TransferExecuteAction(int64_t elementId,
277     const std::map<std::string, std::string>& actionArguments, int32_t action, int64_t offset)
278 {
279     CHECK_NULL_RETURN(dynamicComponentRenderer_, false);
280     return dynamicComponentRenderer_->NotifyExecuteAction(elementId, actionArguments, action, offset);
281 }
282 
DumpInfo()283 void IsolatedPattern::DumpInfo()
284 {
285     DumpLog::GetInstance().AddDesc(std::string("isolatedId: ").append(std::to_string(platformId_)));
286     DumpLog::GetInstance().AddDesc(std::string("abcPath: ").append(curIsolatedInfo_.abcPath));
287     DumpLog::GetInstance().AddDesc(std::string("reourcePath: ").append(curIsolatedInfo_.reourcePath));
288     DumpLog::GetInstance().AddDesc(std::string("entryPoint: ").append(curIsolatedInfo_.entryPoint));
289     DumpLog::GetInstance().AddDesc(std::string("createLimitedWorkerTime: ")
290         .append(std::to_string(isolatedDumpInfo_.createLimitedWorkerTime)));
291     CHECK_NULL_VOID(dynamicComponentRenderer_);
292     RendererDumpInfo rendererDumpInfo;
293     dynamicComponentRenderer_->Dump(rendererDumpInfo);
294     DumpLog::GetInstance().AddDesc(std::string("createUiContenTime: ")
295         .append(std::to_string(rendererDumpInfo.createUiContenTime)));
296     DumpLog::GetInstance().AddDesc(std::string("limitedWorkerInitTime: ")
297         .append(std::to_string(rendererDumpInfo.limitedWorkerInitTime)));
298     DumpLog::GetInstance().AddDesc(std::string("loadAbcTime: ")
299         .append(std::to_string(rendererDumpInfo.loadAbcTime)));
300 }
301 } // namespace OHOS::Ace::NG
302