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