1 /*
2 * Copyright (c) 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 #include "form_renderer_dispatcher_impl.h"
16 #include <transaction/rs_interfaces.h>
17 #include <transaction/rs_transaction.h>
18 #include "base/log/ace_trace.h"
19
20 #include <condition_variable>
21 #include <mutex>
22
23 #include "form_renderer.h"
24 #include "form_renderer_hilog.h"
25 #include "wm_common.h"
26 #include "core/components_ng/gestures/gesture_group.h"
27
28 namespace OHOS {
29 namespace Ace {
30 constexpr int32_t PROCESS_WAIT_TIME = 20;
31 constexpr float DOUBLE = 2.0;
32 constexpr int32_t DEFAULT_FORM_ROTATION_ANIM_DURATION = 600;
FormRendererDispatcherImpl(const std::shared_ptr<UIContent> uiContent,const std::shared_ptr<FormRenderer> formRenderer,std::weak_ptr<OHOS::AppExecFwk::EventHandler> eventHandler)33 FormRendererDispatcherImpl::FormRendererDispatcherImpl(
34 const std::shared_ptr<UIContent> uiContent,
35 const std::shared_ptr<FormRenderer> formRenderer,
36 std::weak_ptr<OHOS::AppExecFwk::EventHandler> eventHandler)
37 : uiContent_(uiContent), formRenderer_(formRenderer), eventHandler_(eventHandler)
38 {}
39
40 std::recursive_mutex FormRendererDispatcherImpl::globalLock_;
41
DispatchPointerEvent(const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent,SerializedGesture & serializedGesture)42 void FormRendererDispatcherImpl::DispatchPointerEvent(
43 const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent,
44 SerializedGesture& serializedGesture)
45 {
46 auto handler = eventHandler_.lock();
47 if (!handler) {
48 HILOG_ERROR("eventHandler is nullptr");
49 return;
50 }
51 serializedGesture.data.clear();
52
53 if (pointerEvent && pointerEvent->GetPointerAction() == OHOS::MMI::PointerEvent::POINTER_ACTION_DOWN) {
54 HILOG_INFO("renderer receive down event");
55 auto uiContent = uiContent_.lock();
56 if (!uiContent) {
57 HILOG_ERROR("uiContent is nullptr");
58 return;
59 }
60
61 struct FormSerializedResultData {
62 std::mutex mtx;
63 std::condition_variable cv;
64 };
65
66 std::shared_ptr<FormSerializedResultData> serializedResultData = std::make_shared<FormSerializedResultData>();
67 auto callback = [serializedResultData]() {
68 std::unique_lock<std::mutex> lock(serializedResultData->mtx);
69 serializedResultData->cv.notify_all();
70 };
71 {
72 std::unique_lock<std::mutex> lock(serializedResultData->mtx);
73 uiContent->ProcessPointerEventWithCallback(pointerEvent, callback);
74 if (serializedResultData->cv.wait_for(lock, std::chrono::milliseconds(PROCESS_WAIT_TIME)) ==
75 std::cv_status::timeout) {
76 HILOG_ERROR("formRender ProcessPointerEvent dispatch timeout");
77 } else {
78 serializedGesture = uiContent->GetFormSerializedGesture();
79 }
80 }
81 } else {
82 handler->PostTask([content = uiContent_, pointerEvent]() {
83 auto uiContent = content.lock();
84 if (!uiContent) {
85 HILOG_ERROR("uiContent is nullptr");
86 return;
87 }
88
89 uiContent->ProcessPointerEvent(pointerEvent);
90 });
91 }
92 }
93
IsAllowUpdate()94 bool FormRendererDispatcherImpl::IsAllowUpdate()
95 {
96 return allowUpdate_;
97 }
98
SetAllowUpdate(bool allowUpdate)99 void FormRendererDispatcherImpl::SetAllowUpdate(bool allowUpdate)
100 {
101 allowUpdate_ = allowUpdate;
102 }
103
SetVisible(bool isVisible)104 void FormRendererDispatcherImpl::SetVisible(bool isVisible)
105 {
106 isVisible_ = isVisible;
107 }
108
IsVisible()109 bool FormRendererDispatcherImpl::IsVisible()
110 {
111 return isVisible_;
112 }
113
DispatchSurfaceChangeEvent(float width,float height,uint32_t reason,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction,float borderWidth)114 void FormRendererDispatcherImpl::DispatchSurfaceChangeEvent(float width, float height, uint32_t reason,
115 const std::shared_ptr<Rosen::RSTransaction>& rsTransaction, float borderWidth)
116 {
117 auto handler = eventHandler_.lock();
118 if (!handler) {
119 HILOG_ERROR("eventHandler is nullptr");
120 return;
121 }
122
123 // form existed in Sceneboard window always get undefined sizeChangeReason, use Visible to control anim instead
124 reason = isVisible_ ? static_cast<uint32_t>(Rosen::WindowSizeChangeReason::ROTATION) :
125 static_cast<uint32_t>(Rosen::WindowSizeChangeReason::UNDEFINED);
126 handler->PostTask([content = uiContent_, width, height, reason, rsTransaction, borderWidth, this]() {
127 auto uiContent = content.lock();
128 if (!uiContent) {
129 HILOG_ERROR("uiContent is nullptr");
130 return;
131 }
132
133 HandleSurfaceChangeEvent(uiContent, width, height, reason, rsTransaction, borderWidth);
134 });
135
136 auto formRenderer = formRenderer_.lock();
137 if (!formRenderer) {
138 return;
139 }
140 formRenderer->OnSurfaceChange(width, height, borderWidth);
141 }
142
HandleSurfaceChangeEvent(const std::shared_ptr<UIContent> & uiContent,float width,float height,uint32_t reason,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction,float borderWidth)143 void FormRendererDispatcherImpl::HandleSurfaceChangeEvent(const std::shared_ptr<UIContent>& uiContent, float width,
144 float height, uint32_t reason, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction, float borderWidth)
145 {
146 int32_t duration = DEFAULT_FORM_ROTATION_ANIM_DURATION;
147 bool needSync = false;
148 if (rsTransaction && rsTransaction->GetSyncId() > 0) {
149 // extract high 32 bits of SyncId as pid
150 auto SyncTransactionPid = static_cast<int32_t>(rsTransaction->GetSyncId() >> 32);
151 if (rsTransaction->IsOpenSyncTransaction() || SyncTransactionPid != rsTransaction->GetParentPid()) {
152 needSync = true;
153 }
154 }
155
156 if (needSync) {
157 duration = rsTransaction->GetDuration() ? rsTransaction->GetDuration() : duration;
158 globalLock_.lock();
159 Rosen::RSTransaction::FlushImplicitTransaction();
160 rsTransaction->Begin();
161 }
162 Rosen::RSAnimationTimingProtocol protocol;
163 protocol.SetDuration(duration);
164 // animation curve: cubic [0.2, 0.0, 0.2, 1.0]
165 auto curve = Rosen::RSAnimationTimingCurve::CreateCubicCurve(0.2, 0.0, 0.2, 1.0);
166 Rosen::RSNode::OpenImplicitAnimation(protocol, curve, []() {});
167
168 float uiWidth = width - borderWidth * DOUBLE;
169 float uiHeight = height - borderWidth * DOUBLE;
170 uiContent->SetFormWidth(uiWidth);
171 uiContent->SetFormHeight(uiHeight);
172 uiContent->OnFormSurfaceChange(uiWidth, uiHeight, static_cast<OHOS::Rosen::WindowSizeChangeReason>(reason),
173 rsTransaction);
174 Rosen::RSNode::CloseImplicitAnimation();
175 if (needSync) {
176 rsTransaction->Commit();
177 globalLock_.unlock();
178 } else {
179 Rosen::RSTransaction::FlushImplicitTransaction();
180 }
181 }
182
SetObscured(bool isObscured)183 void FormRendererDispatcherImpl::SetObscured(bool isObscured)
184 {
185 auto handler = eventHandler_.lock();
186 if (!handler) {
187 HILOG_ERROR("eventHandler is nullptr");
188 return;
189 }
190 handler->PostTask([content = uiContent_, isObscured]() {
191 auto uiContent = content.lock();
192 if (!uiContent) {
193 HILOG_ERROR("uiContent is nullptr");
194 return;
195 }
196 HILOG_INFO("Update ChangeSensitiveNodes: %{public}s", isObscured ? "true" : "false");
197 uiContent->ChangeSensitiveNodes(isObscured);
198 });
199 }
200
OnAccessibilityChildTreeRegister(uint32_t windowId,int32_t treeId,int64_t accessibilityId)201 void FormRendererDispatcherImpl::OnAccessibilityChildTreeRegister(
202 uint32_t windowId, int32_t treeId, int64_t accessibilityId)
203 {
204 auto handler = eventHandler_.lock();
205 if (!handler) {
206 HILOG_ERROR("eventHandler is nullptr");
207 return;
208 }
209
210 handler->PostTask([content = uiContent_, formRenderer = formRenderer_, windowId, treeId, accessibilityId]() {
211 auto uiContent = content.lock();
212 if (!uiContent) {
213 HILOG_ERROR("uiContent is nullptr");
214 return;
215 }
216 HILOG_INFO("OnAccessibilityChildTreeRegister: %{public}d %{public}" PRId64, treeId, accessibilityId);
217 uiContent->RegisterAccessibilityChildTree(windowId, treeId, accessibilityId);
218 uiContent->SetAccessibilityGetParentRectHandler([formRenderer](int32_t &top, int32_t &left) {
219 auto formRendererPtr = formRenderer.lock();
220 if (!formRendererPtr) {
221 HILOG_ERROR("formRenderer is nullptr");
222 return;
223 }
224 formRendererPtr->GetRectRelativeToWindow(top, left);
225 });
226 });
227 }
228
OnAccessibilityChildTreeDeregister()229 void FormRendererDispatcherImpl::OnAccessibilityChildTreeDeregister()
230 {
231 auto handler = eventHandler_.lock();
232 if (!handler) {
233 HILOG_ERROR("eventHandler is nullptr");
234 return;
235 }
236 handler->PostTask([content = uiContent_]() {
237 auto uiContent = content.lock();
238 if (!uiContent) {
239 HILOG_ERROR("uiContent is nullptr");
240 return;
241 }
242 HILOG_INFO("OnAccessibilityChildTreeDeregister");
243 uiContent->DeregisterAccessibilityChildTree();
244 });
245 }
246
OnAccessibilityDumpChildInfo(const std::vector<std::string> & params,std::vector<std::string> & info)247 void FormRendererDispatcherImpl::OnAccessibilityDumpChildInfo(
248 const std::vector<std::string>& params, std::vector<std::string>& info)
249 {
250 auto handler = eventHandler_.lock();
251 if (!handler) {
252 HILOG_ERROR("eventHandler is nullptr");
253 return;
254 }
255 handler->PostSyncTask([content = uiContent_, params, &info]() {
256 auto uiContent = content.lock();
257 if (!uiContent) {
258 HILOG_ERROR("uiContent is nullptr");
259 return;
260 }
261 HILOG_INFO("OnAccessibilityDumpChildInfo");
262 uiContent->AccessibilityDumpChildInfo(params, info);
263 });
264 }
265
OnAccessibilityTransferHoverEvent(float pointX,float pointY,int32_t sourceType,int32_t eventType,int64_t timeMs)266 void FormRendererDispatcherImpl::OnAccessibilityTransferHoverEvent(float pointX, float pointY, int32_t sourceType,
267 int32_t eventType, int64_t timeMs)
268 {
269 auto handler = eventHandler_.lock();
270 if (!handler) {
271 HILOG_ERROR("eventHandler is nullptr");
272 return;
273 }
274 handler->PostTask([content = uiContent_, pointX, pointY, sourceType, eventType, timeMs]() {
275 auto uiContent = content.lock();
276 if (!uiContent) {
277 HILOG_ERROR("uiContent is nullptr");
278 return;
279 }
280 HILOG_INFO("OnAccessibilityTransferHoverEvent");
281 uiContent->HandleAccessibilityHoverEvent(pointX, pointY, sourceType, eventType, timeMs);
282 });
283 }
284 } // namespace Ace
285 } // namespace OHOS
286