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/ability_component/ability_component_pattern.h"
17
18 #include "session_manager/include/extension_session_manager.h"
19
20 #include "adapter/ohos/entrance/ace_container.h"
21 #include "adapter/ohos/entrance/mmi_event_convertor.h"
22 #include "adapter/ohos/osal/want_wrap_ohos.h"
23 #include "core/pipeline_ng/pipeline_context.h"
24
25 namespace OHOS::Ace::NG {
AbilityComponentPattern(const std::string & bundleName,const std::string & abilityName)26 AbilityComponentPattern::AbilityComponentPattern(const std::string& bundleName, const std::string& abilityName)
27 {
28 auto container = AceType::DynamicCast<Platform::AceContainer>(Container::Current());
29 if (container && container->IsSceneBoardEnabled()) {
30 auto wantWrap = Ace::WantWrap::CreateWantWrap(bundleName, abilityName);
31 auto want = AceType::DynamicCast<WantWrapOhos>(wantWrap)->GetWant();
32 Rosen::SessionInfo extensionSessionInfo = {
33 .bundleName_ = bundleName,
34 .abilityName_ = abilityName,
35 .callerToken_ = container->GetToken(),
36 .want = std::make_shared<Want>(want),
37 };
38 session_ = Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSession(extensionSessionInfo);
39 }
40 }
41
OnAttachToFrameNode()42 void AbilityComponentPattern::OnAttachToFrameNode()
43 {
44 auto container = AceType::DynamicCast<Platform::AceContainer>(Container::Current());
45 if (!container || !container->IsSceneBoardEnabled()) {
46 return;
47 }
48 WindowPattern::OnAttachToFrameNode();
49 }
50
OnModifyDone()51 void AbilityComponentPattern::OnModifyDone()
52 {
53 auto container = Container::Current();
54 if (container && container->IsSceneBoardEnabled()) {
55 Pattern::OnModifyDone();
56 auto host = GetHost();
57 CHECK_NULL_VOID(host);
58 auto hub = host->GetOrCreateEventHub<EventHub>();
59 CHECK_NULL_VOID(hub);
60 auto gestureHub = hub->GetOrCreateGestureEventHub();
61 CHECK_NULL_VOID(gestureHub);
62 InitTouchEvent(gestureHub);
63 auto inputHub = hub->GetOrCreateInputEventHub();
64 CHECK_NULL_VOID(inputHub);
65 InitMouseEvent(inputHub);
66 auto focusHub = host->GetFocusHub();
67 CHECK_NULL_VOID(focusHub);
68 InitOnKeyEvent(focusHub);
69 }
70 if (adapter_) {
71 UpdateWindowRect();
72 } else {
73 auto host = GetHost();
74 CHECK_NULL_VOID(host);
75 auto pipelineContext = host->GetContext();
76 CHECK_NULL_VOID(pipelineContext);
77 auto windowId = pipelineContext->GetWindowId();
78 adapter_ = WindowExtensionConnectionProxyNG::CreateAdapter();
79 CHECK_NULL_VOID(adapter_);
80 if (container && container->IsSceneBoardEnabled()) {
81 CHECK_NULL_VOID(session_);
82 sptr<Rosen::ExtensionSession> extensionSession(static_cast<Rosen::ExtensionSession*>(session_.GetRefPtr()));
83 CHECK_NULL_VOID(extensionSession);
84 adapter_->SetExtensionSession(extensionSession);
85 }
86 adapter_->ConnectExtension(GetHost(), windowId);
87 pipelineContext->AddOnAreaChangeNode(host->GetId());
88 pipelineContext->AddWindowStateChangedCallback(host->GetId());
89 LOGI("connect to windows extension begin %{public}s", GetHost()->GetTag().c_str());
90 }
91 }
92
FireConnect()93 void AbilityComponentPattern::FireConnect()
94 {
95 hasConnectionToAbility_ = true;
96 UpdateWindowRect();
97 auto pipeline = PipelineBase::GetCurrentContext();
98 TransferFocusState(IsCurrentFocus());
99
100 auto abilityComponentEventHub = GetOrCreateEventHub<AbilityComponentEventHub>();
101 CHECK_NULL_VOID(abilityComponentEventHub);
102 abilityComponentEventHub->FireOnConnect();
103 }
104
FireDisConnect()105 void AbilityComponentPattern::FireDisConnect()
106 {
107 hasConnectionToAbility_ = false;
108 auto abilityComponentEventHub = GetOrCreateEventHub<AbilityComponentEventHub>();
109 CHECK_NULL_VOID(abilityComponentEventHub);
110 abilityComponentEventHub->FireOnDisConnect();
111 }
112
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> &,const DirtySwapConfig & config)113 bool AbilityComponentPattern::OnDirtyLayoutWrapperSwap(
114 const RefPtr<LayoutWrapper>& /*dirty*/, const DirtySwapConfig& config)
115 {
116 if (config.frameSizeChange || config.frameOffsetChange) {
117 UpdateWindowRect();
118 }
119 return false;
120 }
121
GetFocusPattern() const122 FocusPattern AbilityComponentPattern::GetFocusPattern() const
123 {
124 return { FocusType::NODE, true, FocusStyleType::NONE };
125 }
126
UpdateWindowRect()127 void AbilityComponentPattern::UpdateWindowRect()
128 {
129 if (!hasConnectionToAbility_) {
130 return;
131 }
132 auto host = GetHost();
133 CHECK_NULL_VOID(host);
134 auto size = host->GetGeometryNode()->GetFrameSize();
135 auto offset = host->GetTransformRelativeOffset();
136 auto pipeline = host->GetContext();
137 CHECK_NULL_VOID(pipeline);
138 Rect rect = pipeline->GetDisplayWindowRectInfo();
139 rect = Rect(offset.GetX() + rect.Left(), offset.GetY() + rect.Top(), size.Width(), size.Height());
140 if (adapter_ && rect != lastRect_) {
141 LOGI("ConnectExtension: %{public}f %{public}f %{public}f %{public}f", offset.GetX(), offset.GetY(),
142 size.Width(), size.Height());
143 adapter_->UpdateRect(rect);
144 lastRect_ = rect;
145 }
146 }
147
OnAreaChangedInner()148 void AbilityComponentPattern::OnAreaChangedInner()
149 {
150 UpdateWindowRect();
151 }
152
InitTouchEvent(const RefPtr<GestureEventHub> & gestureHub)153 void AbilityComponentPattern::InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub)
154 {
155 if (touchEvent_) {
156 return;
157 }
158 auto callback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
159 auto pattern = weak.Upgrade();
160 if (pattern) {
161 pattern->HandleTouchEvent(info);
162 }
163 };
164 if (touchEvent_) {
165 gestureHub->RemoveTouchEvent(touchEvent_);
166 }
167 touchEvent_ = MakeRefPtr<TouchEventImpl>(std::move(callback));
168 gestureHub->AddTouchEvent(touchEvent_);
169 }
170
InitMouseEvent(const RefPtr<InputEventHub> & inputHub)171 void AbilityComponentPattern::InitMouseEvent(const RefPtr<InputEventHub>& inputHub)
172 {
173 if (mouseEvent_) {
174 return;
175 }
176 auto callback = [weak = WeakClaim(this)](MouseInfo& info) {
177 auto pattern = weak.Upgrade();
178 if (pattern) {
179 pattern->HandleMouseEvent(info);
180 }
181 };
182 if (mouseEvent_) {
183 inputHub->RemoveOnMouseEvent(mouseEvent_);
184 }
185 mouseEvent_ = MakeRefPtr<InputEvent>(std::move(callback));
186 inputHub->AddOnMouseEvent(mouseEvent_);
187 }
188
HandleTouchEvent(const TouchEventInfo & info)189 void AbilityComponentPattern::HandleTouchEvent(const TouchEventInfo& info)
190 {
191 if (info.GetSourceDevice() != SourceType::TOUCH) {
192 return;
193 }
194 const auto pointerEvent = info.GetPointerEvent();
195 CHECK_NULL_VOID(pointerEvent);
196 auto host = GetHost();
197 CHECK_NULL_VOID(host);
198 Platform::CalculatePointerEvent(pointerEvent, host);
199 WindowPattern::DispatchPointerEvent(pointerEvent);
200 auto hub = host->GetFocusHub();
201 CHECK_NULL_VOID(hub);
202 hub->RequestFocusImmediately();
203 }
204
HandleMouseEvent(const MouseInfo & info)205 void AbilityComponentPattern::HandleMouseEvent(const MouseInfo& info)
206 {
207 if (info.GetSourceDevice() != SourceType::MOUSE) {
208 return;
209 }
210 const auto pointerEvent = info.GetPointerEvent();
211 CHECK_NULL_VOID(pointerEvent);
212 auto host = GetHost();
213 CHECK_NULL_VOID(host);
214 auto selfGlobalOffset = host->GetTransformRelativeOffset();
215 auto scale = host->GetTransformScale();
216 Platform::CalculatePointerEvent(selfGlobalOffset, pointerEvent, scale);
217 if (info.GetAction() == MouseAction::PRESS) {
218 auto hub = host->GetFocusHub();
219 CHECK_NULL_VOID(hub);
220 hub->RequestFocusImmediately();
221 }
222 WindowPattern::DispatchPointerEvent(pointerEvent);
223 }
224
InitOnKeyEvent(const RefPtr<FocusHub> & focusHub)225 void AbilityComponentPattern::InitOnKeyEvent(const RefPtr<FocusHub>& focusHub)
226 {
227 focusHub->SetOnFocusInternal([weak = WeakClaim(this)](FocusReason reason) {
228 auto pattern = weak.Upgrade();
229 if (pattern) {
230 pattern->HandleFocusEvent();
231 }
232 });
233
234 focusHub->SetOnBlurInternal([weak = WeakClaim(this)]() {
235 auto pattern = weak.Upgrade();
236 if (pattern) {
237 pattern->HandleBlurEvent();
238 }
239 });
240
241 focusHub->SetOnClearFocusStateInternal([weak = WeakClaim(this)]() {
242 auto pattern = weak.Upgrade();
243 if (pattern) {
244 pattern->DisPatchFocusActiveEvent(false);
245 }
246 });
247 focusHub->SetOnPaintFocusStateInternal([weak = WeakClaim(this)]() -> bool {
248 auto pattern = weak.Upgrade();
249 if (pattern) {
250 pattern->DisPatchFocusActiveEvent(true);
251 return true;
252 }
253 return false;
254 });
255
256 focusHub->SetOnKeyEventInternal([wp = WeakClaim(this)](const KeyEvent& event) -> bool {
257 auto pattern = wp.Upgrade();
258 if (pattern) {
259 return pattern->OnKeyEvent(event);
260 }
261 return false;
262 });
263 }
264
HandleFocusEvent()265 void AbilityComponentPattern::HandleFocusEvent()
266 {
267 auto host = GetHost();
268 CHECK_NULL_VOID(host);
269 auto pipeline = host->GetContext();
270 CHECK_NULL_VOID(pipeline);
271 if (pipeline->GetIsFocusActive()) {
272 WindowPattern::DisPatchFocusActiveEvent(true);
273 }
274 TransferFocusState(true);
275 }
276
HandleBlurEvent()277 void AbilityComponentPattern::HandleBlurEvent()
278 {
279 WindowPattern::DisPatchFocusActiveEvent(false);
280 TransferFocusState(false);
281 }
282
KeyEventConsumed(const KeyEvent & event)283 bool AbilityComponentPattern::KeyEventConsumed(const KeyEvent& event)
284 {
285 bool isConsumed = false;
286 WindowPattern::DispatchKeyEventForConsumed(event.rawKeyEvent, isConsumed);
287 return isConsumed;
288 }
289
OnKeyEvent(const KeyEvent & event)290 bool AbilityComponentPattern::OnKeyEvent(const KeyEvent& event)
291 {
292 if (event.code == KeyCode::KEY_TAB && event.action == KeyAction::DOWN) {
293 auto host = GetHost();
294 CHECK_NULL_RETURN(host, false);
295 auto pipeline = host->GetContext();
296 CHECK_NULL_RETURN(pipeline, false);
297 // tab trigger consume the key event
298 return pipeline->IsTabJustTriggerOnKeyEvent();
299 } else {
300 return KeyEventConsumed(event);
301 }
302 }
303
IsCurrentFocus() const304 bool AbilityComponentPattern::IsCurrentFocus() const
305 {
306 auto host = GetHost();
307 CHECK_NULL_RETURN(host, false);
308 auto focusHub = host->GetFocusHub();
309 CHECK_NULL_RETURN(focusHub, false);
310 return focusHub->IsCurrentFocus();
311 }
312 } // namespace OHOS::Ace::NG
313