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