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 "window_listener.h"
17 #include <cstdint>
18 #include "cj_lambda.h"
19 #include "event_handler.h"
20 #include "event_runner.h"
21 #include "window_manager_hilog.h"
22
23 namespace OHOS {
24 namespace Rosen {
CjWindowListener(int64_t callbackObject,CaseType caseType)25 CjWindowListener::CjWindowListener(int64_t callbackObject, CaseType caseType)
26 : caseType_(caseType)
27 {
28 TLOGI(WmsLogTag::DEFAULT, "Create CjWindowListener");
29 weakRef_ = wptr<CjWindowListener>(this);
30 auto func = reinterpret_cast<void(*)(void*)>(callbackObject);
31 cjCallBack_ = CJLambda::Create(func);
32 }
33
~CjWindowListener()34 CjWindowListener::~CjWindowListener()
35 {
36 TLOGI(WmsLogTag::WMS_DIALOG, "~CjWindowListener");
37 }
38
SetMainEventHandler()39 void CjWindowListener::SetMainEventHandler()
40 {
41 auto mainRunner = AppExecFwk::EventRunner::GetMainEventRunner();
42 if (mainRunner == nullptr) {
43 return;
44 }
45 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(mainRunner);
46 }
47
CallCjMethod(const char * methodName,void * argv,size_t argc)48 void CjWindowListener::CallCjMethod(const char* methodName, void* argv, size_t argc)
49 {
50 TLOGD(WmsLogTag::WMS_DIALOG, "[WindowListener]methodName=%{public}s", methodName);
51 if (cjCallBack_ == nullptr) {
52 TLOGE(WmsLogTag::WMS_DIALOG, "[WindowListener]env_ nullptr or jsCallBack_ is nullptr");
53 return;
54 }
55 cjCallBack_(argv);
56 }
57
GetCjRect(const Rect & rect)58 CjRectInfo GetCjRect(const Rect& rect)
59 {
60 CjRectInfo result = {
61 .left = rect.posX_,
62 .top = rect.posY_,
63 .width = rect.width_,
64 .height = rect.height_
65 };
66 return result;
67 }
68
OnSystemBarPropertyChange(DisplayId displayId,const SystemBarRegionTints & tints)69 void CjWindowListener::OnSystemBarPropertyChange(DisplayId displayId, const SystemBarRegionTints& tints)
70 {
71 auto thisListener = weakRef_.promote();
72 if (thisListener == nullptr) {
73 return;
74 }
75
76 std::vector<SystemBarRegionTintInfo> tintInfos;
77 for (const auto& tint : tints) {
78 auto actType = CJ_TO_WINDOW_TYPE_MAP.count(tint.type_) != 0 ?
79 CJ_TO_WINDOW_TYPE_MAP.at(tint.type_) : static_cast<ApiWindowType>(tint.type_);
80 SystemBarRegionTintInfo info = {
81 .type = static_cast<uint32_t>(actType),
82 .isEnable = tint.prop_.enable_,
83 .backgroundColor = tint.prop_.backgroundColor_,
84 .contentColor = tint.prop_.contentColor_,
85 .region = GetCjRect(tint.region_)
86 };
87 tintInfos.push_back(info);
88 }
89
90 struct SystemBarPropertyInfo {
91 uint32_t displayId;
92 std::vector<SystemBarRegionTintInfo> tints;
93 };
94
95 SystemBarPropertyInfo propertyInfo = {
96 .displayId = static_cast<uint32_t>(displayId),
97 .tints = tintInfos
98 };
99
100 thisListener->CallCjMethod(SYSTEM_BAR_TINT_CHANGE_CB.c_str(), &propertyInfo, sizeof(propertyInfo));
101 }
102
OnSizeChange(Rect rect,WindowSizeChangeReason reason,const std::shared_ptr<RSTransaction> & rsTransaction)103 void CjWindowListener::OnSizeChange(Rect rect, WindowSizeChangeReason reason,
104 const std::shared_ptr<RSTransaction>& rsTransaction)
105 {
106 if (currRect_.width_ == rect.width_ && currRect_.height_ == rect.height_ &&
107 reason != WindowSizeChangeReason::DRAG_END) {
108 return;
109 }
110 auto thisListener = weakRef_.promote();
111 if (thisListener == nullptr) {
112 return;
113 }
114 struct SizeChangeInfo {
115 uint32_t width;
116 uint32_t height;
117 };
118 SizeChangeInfo argv = {
119 .width = rect.width_,
120 .height = rect.height_
121 };
122 thisListener->CallCjMethod(WINDOW_SIZE_CHANGE_CB.c_str(), &argv, sizeof(argv));
123 currRect_ = rect;
124 }
125
OnModeChange(WindowMode mode,bool hasDeco)126 void CjWindowListener::OnModeChange(WindowMode mode, bool hasDeco)
127 {
128 }
129
OnAvoidAreaChanged(const AvoidArea avoidArea,AvoidAreaType type)130 void CjWindowListener::OnAvoidAreaChanged(const AvoidArea avoidArea, AvoidAreaType type)
131 {
132 auto thisListener = weakRef_.promote();
133 if (thisListener == nullptr) {
134 return;
135 }
136
137 struct AvoidAreaValue {
138 bool visible;
139 CjRectInfo leftRect;
140 CjRectInfo topRect;
141 CjRectInfo rightRect;
142 CjRectInfo bottomRect;
143 };
144 struct AvoidAreaInfo {
145 uint32_t type;
146 AvoidAreaValue area;
147 };
148 AvoidAreaInfo avoidAreaInfo = {
149 .type = static_cast<uint32_t>(type),
150 .area = {
151 .visible = (type != AvoidAreaType::TYPE_CUTOUT),
152 .leftRect = GetCjRect(avoidArea.leftRect_),
153 .topRect = GetCjRect(avoidArea.topRect_),
154 .rightRect = GetCjRect(avoidArea.rightRect_),
155 .bottomRect = GetCjRect(avoidArea.bottomRect_)
156 }
157 };
158
159 thisListener->CallCjMethod(AVOID_AREA_CHANGE_CB.c_str(), &avoidAreaInfo, sizeof(avoidAreaInfo));
160 }
161
AfterForeground()162 void CjWindowListener::AfterForeground()
163 {
164 if (state_ == WindowState::STATE_INITIAL || state_ == WindowState::STATE_HIDDEN) {
165 LifeCycleCallBack(LifeCycleEventType::FOREGROUND);
166 state_ = WindowState::STATE_SHOWN;
167 }
168 }
169
AfterBackground()170 void CjWindowListener::AfterBackground()
171 {
172 if (state_ == WindowState::STATE_INITIAL || state_ == WindowState::STATE_SHOWN) {
173 LifeCycleCallBack(LifeCycleEventType::BACKGROUND);
174 state_ = WindowState::STATE_HIDDEN;
175 }
176 }
177
AfterFocused()178 void CjWindowListener::AfterFocused()
179 {
180 LifeCycleCallBack(LifeCycleEventType::ACTIVE);
181 }
182
AfterUnfocused()183 void CjWindowListener::AfterUnfocused()
184 {
185 LifeCycleCallBack(LifeCycleEventType::INACTIVE);
186 }
187
AfterResumed()188 void CjWindowListener::AfterResumed()
189 {
190 if (caseType_ == CaseType::CASE_STAGE) {
191 LifeCycleCallBack(LifeCycleEventType::RESUMED);
192 }
193 }
194
AfterPaused()195 void CjWindowListener::AfterPaused()
196 {
197 if (caseType_ == CaseType::CASE_STAGE) {
198 LifeCycleCallBack(LifeCycleEventType::PAUSED);
199 }
200 }
201
AfterDestroyed()202 void CjWindowListener::AfterDestroyed()
203 {
204 if (caseType_ == CaseType::CASE_WINDOW) {
205 LifeCycleCallBack(LifeCycleEventType::DESTROYED);
206 }
207 }
208
LifeCycleCallBack(LifeCycleEventType eventType)209 void CjWindowListener::LifeCycleCallBack(LifeCycleEventType eventType)
210 {
211 uint32_t type = static_cast<uint32_t>(eventType);
212 auto thisListener = weakRef_.promote();
213 if (thisListener == nullptr) {
214 return;
215 }
216
217 thisListener->CallCjMethod(LIFECYCLE_EVENT_CB.c_str(), &type, sizeof(type));
218 }
219
OnSizeChange(const sptr<OccupiedAreaChangeInfo> & info,const std::shared_ptr<RSTransaction> & rsTransaction)220 void CjWindowListener::OnSizeChange(const sptr<OccupiedAreaChangeInfo>& info,
221 const std::shared_ptr<RSTransaction>& rsTransaction)
222 {
223 if (info == nullptr) {
224 TLOGE(WmsLogTag::WMS_DIALOG, "[WindowListener] this changeInfo is nullptr");
225 return;
226 }
227 TLOGI(WmsLogTag::WMS_DIALOG, "[WindowListener]OccupiedAreaChangeInfo, type: %{public}u, " \
228 "input rect: [%{public}d, %{public}d, %{public}u, %{public}u]",
229 static_cast<uint32_t>(info->type_),
230 info->rect_.posX_, info->rect_.posY_, info->rect_.width_, info->rect_.height_);
231 auto thisListener = weakRef_.promote();
232 if (thisListener == nullptr) {
233 TLOGE(WmsLogTag::WMS_DIALOG, "[WindowListener] this listener is nullptr");
234 return;
235 }
236 void* argv = &(info->rect_.height_);
237 size_t argc = 1;
238 thisListener->CallCjMethod(KEYBOARD_HEIGHT_CHANGE_CB.c_str(), argv, argc);
239 }
240
OnTouchOutside() const241 void CjWindowListener::OnTouchOutside() const
242 {
243 auto thisListener = weakRef_.promote();
244 if (thisListener == nullptr) {
245 return;
246 }
247
248 thisListener->CallCjMethod(TOUCH_OUTSIDE_CB.c_str(), nullptr, 0);
249 }
250
OnScreenshot()251 void CjWindowListener::OnScreenshot()
252 {
253 auto thisListener = weakRef_.promote();
254 if (thisListener == nullptr) {
255 return;
256 }
257
258 thisListener->CallCjMethod(SCREENSHOT_EVENT_CB.c_str(), nullptr, 0);
259 }
260
OnDialogTargetTouch() const261 void CjWindowListener::OnDialogTargetTouch() const
262 {
263 auto thisListener = weakRef_.promote();
264 if (thisListener == nullptr) {
265 return;
266 }
267
268 thisListener->CallCjMethod(DIALOG_TARGET_TOUCH_CB.c_str(), nullptr, 0);
269 }
270
OnDialogDeathRecipient() const271 void CjWindowListener::OnDialogDeathRecipient() const
272 {
273 auto thisListener = weakRef_.promote();
274 if (thisListener == nullptr) {
275 return;
276 }
277
278 thisListener->CallCjMethod(DIALOG_DEATH_RECIPIENT_CB.c_str(), nullptr, 0);
279 }
280
OnGestureNavigationEnabledUpdate(bool enable)281 void CjWindowListener::OnGestureNavigationEnabledUpdate(bool enable)
282 {
283 auto thisListener = weakRef_.promote();
284 if (thisListener == nullptr) {
285 return;
286 }
287
288 bool navigationEnabled = enable;
289 thisListener->CallCjMethod(GESTURE_NAVIGATION_ENABLED_CHANGE_CB.c_str(),
290 &navigationEnabled, sizeof(navigationEnabled));
291 }
292
OnWaterMarkFlagUpdate(bool showWaterMark)293 void CjWindowListener::OnWaterMarkFlagUpdate(bool showWaterMark)
294 {
295 auto thisListener = weakRef_.promote();
296 if (thisListener == nullptr) {
297 return;
298 }
299
300 bool waterMarkFlag = showWaterMark;
301 thisListener->CallCjMethod(WATER_MARK_FLAG_CHANGE_CB.c_str(), &waterMarkFlag, sizeof(waterMarkFlag));
302 }
303
OnWindowVisibilityChangedCallback(const bool isVisible)304 void CjWindowListener::OnWindowVisibilityChangedCallback(const bool isVisible)
305 {
306 auto thisListener = weakRef_.promote();
307 if (thisListener == nullptr) {
308 return;
309 }
310
311 bool visibility = isVisible;
312 thisListener->CallCjMethod(WINDOW_VISIBILITY_CHANGE_CB.c_str(), &visibility, sizeof(visibility));
313 }
314
OnWindowStatusChange(WindowStatus status)315 void CjWindowListener::OnWindowStatusChange(WindowStatus status)
316 {
317 auto thisListener = weakRef_.promote();
318 if (thisListener == nullptr) {
319 return;
320 }
321
322 WindowStatus currentStatus = status;
323 thisListener->CallCjMethod(WINDOW_STATUS_CHANGE_CB.c_str(), ¤tStatus, sizeof(currentStatus));
324 }
325
SetTimeout(int64_t timeout)326 void CjWindowListener::SetTimeout(int64_t timeout)
327 {
328 noInteractionTimeout_ = timeout;
329 }
330
GetTimeout() const331 int64_t CjWindowListener::GetTimeout() const
332 {
333 return noInteractionTimeout_;
334 }
335
OnWindowNoInteractionCallback()336 void CjWindowListener::OnWindowNoInteractionCallback()
337 {
338 auto thisListener = weakRef_.promote();
339 if (thisListener == nullptr) {
340 return;
341 }
342 thisListener->CallCjMethod(WINDOW_NO_INTERACTION_DETECTED_CB.c_str(), nullptr, 0);
343 }
344
OnWindowTitleButtonRectChanged(const TitleButtonRect & titleButtonRect)345 void CjWindowListener::OnWindowTitleButtonRectChanged(const TitleButtonRect& titleButtonRect)
346 {
347 auto thisListener = weakRef_.promote();
348 if (thisListener == nullptr) {
349 return;
350 }
351 struct TitleButtonRectInfo {
352 int32_t right;
353 int32_t top;
354 uint32_t width;
355 uint32_t height;
356 };
357 TitleButtonRectInfo argv = {
358 .right = titleButtonRect.posX_,
359 .top = titleButtonRect.posY_,
360 .width = titleButtonRect.width_,
361 .height = titleButtonRect.height_
362 };
363 thisListener->CallCjMethod(WINDOW_TITLE_BUTTON_RECT_CHANGE_CB.c_str(), &argv, sizeof(argv));
364 }
365
OnRectChange(Rect rect,WindowSizeChangeReason reason)366 void CjWindowListener::OnRectChange(Rect rect, WindowSizeChangeReason reason)
367 {
368 if (currRect_ == rect && reason == WindowSizeChangeReason::UNDEFINED) {
369 return;
370 }
371 RectChangeReason rectChangReason = RectChangeReason::UNDEFINED;
372 if (CJ_SIZE_CHANGE_REASON.count(reason) != 0 &&
373 !(reason == WindowSizeChangeReason::MAXIMIZE && rect.posX_ != 0)) {
374 rectChangReason = CJ_SIZE_CHANGE_REASON.at(reason);
375 }
376 if (currentReason_ != RectChangeReason::DRAG && rectChangReason == RectChangeReason::DRAG_END) {
377 rectChangReason = RectChangeReason::MOVE;
378 }
379
380 auto thisListener = weakRef_.promote();
381 if (thisListener == nullptr) {
382 return;
383 }
384
385 struct RectChangeInfo {
386 CjRectInfo rect;
387 WindowSizeChangeReason reason;
388 };
389
390 RectChangeInfo rectChangeInfo = {
391 .rect = GetCjRect(rect),
392 .reason = reason
393 };
394
395 thisListener->CallCjMethod(WINDOW_RECT_CHANGE_CB.c_str(), &rectChangeInfo, sizeof(rectChangeInfo));
396 currRect_ = rect;
397 }
398
OnSubWindowClose(bool & terminateCloseProcess)399 void CjWindowListener::OnSubWindowClose(bool& terminateCloseProcess)
400 {
401 auto thisListener = weakRef_.promote();
402 if (thisListener == nullptr) {
403 return;
404 }
405
406 bool value = terminateCloseProcess;
407 thisListener->CallCjMethod(WINDOW_SUB_WINDOW_CLOSE_CB.c_str(), &value, sizeof(value));
408 terminateCloseProcess = value;
409 }
410
OnMainWindowClose(bool & terminateCloseProcess)411 void CjWindowListener::OnMainWindowClose(bool& terminateCloseProcess)
412 {
413 auto thisListener = weakRef_.promote();
414 if (thisListener == nullptr) {
415 return;
416 }
417
418 bool value = terminateCloseProcess;
419 thisListener->CallCjMethod(WINDOW_STAGE_CLOSE_CB.c_str(), &value, sizeof(value));
420 terminateCloseProcess = value;
421 }
422
423 }
424 }
425