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
16 #include "session/host/include/scene_session.h"
17
18 #include <iterator>
19 #include <pointer_event.h>
20 #include <transaction/rs_transaction.h>
21
22 #include "common/include/session_permission.h"
23 #include "interfaces/include/ws_common.h"
24 #include "session/host/include/scene_persistent_storage.h"
25 #include "session/host/include/session_utils.h"
26 #include "session_manager/include/screen_session_manager.h"
27 #include "session_manager/include/scene_session_manager.h"
28 #include "session_helper.h"
29 #include "window_helper.h"
30 #include "window_manager_hilog.h"
31 #include "wm_math.h"
32 #include <running_lock.h>
33
34 namespace OHOS::Rosen {
35 namespace {
36 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSession" };
37 }
38 MaximizeMode SceneSession::maximizeMode_ = MaximizeMode::MODE_RECOVER;
39 wptr<SceneSession> SceneSession::enterSession_ = nullptr;
40 std::mutex SceneSession::enterSessionMutex_;
41
SceneSession(const SessionInfo & info,const sptr<SpecificSessionCallback> & specificCallback)42 SceneSession::SceneSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)
43 : Session(info)
44 {
45 GeneratePersistentId(false, info);
46 if (!info.bundleName_.empty()) {
47 scenePersistence_ = new (std::nothrow) ScenePersistence(info, GetPersistentId());
48 }
49 specificCallback_ = specificCallback;
50 moveDragController_ = new (std::nothrow) MoveDragController(GetPersistentId());
51 SetSessionRectChangeCallback();
52 std::string key = GetRatioPreferenceKey();
53 if (!key.empty()) {
54 if (ScenePersistentStorage::HasKey(key, ScenePersistentStorageType::ASPECT_RATIO)) {
55 ScenePersistentStorage::Get(key, aspectRatio_, ScenePersistentStorageType::ASPECT_RATIO);
56 WLOGD("SceneSession init aspectRatio , key %{public}s, value: %{public}f", key.c_str(), aspectRatio_);
57 if (moveDragController_) {
58 moveDragController_->SetAspectRatio(aspectRatio_);
59 }
60 }
61 }
62 property_ = new(std::nothrow) WindowSessionProperty();
63 if (property_) {
64 property_->SetWindowType(static_cast<WindowType>(info.windowType_));
65 }
66
67 if (sessionInfo_.isSystem_) {
68 auto name = sessionInfo_.bundleName_;
69 auto pos = name.find_last_of('.');
70 name = (pos == std::string::npos) ? name : name.substr(pos + 1); // skip '.'
71
72 Rosen::RSSurfaceNodeConfig config;
73 config.SurfaceNodeName = name;
74 surfaceNode_ = Rosen::RSSurfaceNode::Create(config, Rosen::RSSurfaceNodeType::APP_WINDOW_NODE);
75 }
76 }
77
Connect(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,SystemSessionConfig & systemConfig,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token)78 WSError SceneSession::Connect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel,
79 const std::shared_ptr<RSSurfaceNode>& surfaceNode, SystemSessionConfig& systemConfig, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token)
80 {
81 WSError ret = Session::Connect(sessionStage, eventChannel, surfaceNode, systemConfig, property, token);
82 if (ret != WSError::WS_OK) {
83 return ret;
84 }
85 NotifyPropertyWhenConnect();
86 return WSError::WS_OK;
87 }
88
Foreground(sptr<WindowSessionProperty> property)89 WSError SceneSession::Foreground(sptr<WindowSessionProperty> property)
90 {
91 // use property from client
92 if (property && property->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
93 property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::CUSTOM));
94 NotifyIsCustomAnimatiomPlaying(true);
95 if (setWindowScenePatternFunc_ && setWindowScenePatternFunc_->setOpacityFunc_) {
96 setWindowScenePatternFunc_->setOpacityFunc_(0.0f);
97 }
98 }
99 WSError ret = Session::Foreground(property);
100 if (ret != WSError::WS_OK) {
101 return ret;
102 }
103 NotifyForeground();
104 UpdateCameraFloatWindowStatus(true);
105 if (specificCallback_ != nullptr) {
106 specificCallback_->onUpdateAvoidArea_(GetPersistentId());
107 specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
108 }
109 return WSError::WS_OK;
110 }
111
Background()112 WSError SceneSession::Background()
113 {
114 // background will remove surfaceNode, custom not execute
115 // not animation playing when already background; inactive may be animation playing
116 if (property_ && property_->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
117 NotifyIsCustomAnimatiomPlaying(true);
118 return WSError::WS_OK;
119 }
120 WSError ret = Session::Background();
121 if (ret != WSError::WS_OK) {
122 return ret;
123 }
124 snapshot_ = Snapshot();
125 if (scenePersistence_ && snapshot_) {
126 scenePersistence_->SaveSnapshot(snapshot_);
127 }
128 NotifyBackground();
129 snapshot_.reset();
130 UpdateCameraFloatWindowStatus(false);
131 if (specificCallback_ != nullptr) {
132 specificCallback_->onUpdateAvoidArea_(GetPersistentId());
133 specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
134 }
135 return WSError::WS_OK;
136 }
137
OnSessionEvent(SessionEvent event)138 WSError SceneSession::OnSessionEvent(SessionEvent event)
139 {
140 WLOGFD("SceneSession OnSessionEvent event: %{public}d", static_cast<int32_t>(event));
141 if (event == SessionEvent::EVENT_START_MOVE && moveDragController_) {
142 moveDragController_->InitMoveDragProperty();
143 moveDragController_->SetStartMoveFlag(true);
144 }
145 if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->OnSessionEvent_) {
146 sessionChangeCallback_->OnSessionEvent_(static_cast<uint32_t>(event));
147 }
148 return WSError::WS_OK;
149 }
150
RegisterSessionChangeCallback(const sptr<SceneSession::SessionChangeCallback> & sessionChangeCallback)151 void SceneSession::RegisterSessionChangeCallback(const sptr<SceneSession::SessionChangeCallback>&
152 sessionChangeCallback)
153 {
154 sessionChangeCallback_ = sessionChangeCallback;
155 }
156
SetGlobalMaximizeMode(MaximizeMode mode)157 WSError SceneSession::SetGlobalMaximizeMode(MaximizeMode mode)
158 {
159 WLOGFI("SceneSession SetGlobalMaximizeMode mode: %{public}u", static_cast<uint32_t>(mode));
160 maximizeMode_ = mode;
161 ScenePersistentStorage::Insert("maximize_state", static_cast<int32_t>(maximizeMode_),
162 ScenePersistentStorageType::MAXIMIZE_STATE);
163 return WSError::WS_OK;
164 }
165
GetGlobalMaximizeMode(MaximizeMode & mode)166 WSError SceneSession::GetGlobalMaximizeMode(MaximizeMode &mode)
167 {
168 WLOGFD("SceneSession GetGlobalMaximizeMode");
169 mode = maximizeMode_;
170 return WSError::WS_OK;
171 }
172
SetAspectRatio(float ratio)173 WSError SceneSession::SetAspectRatio(float ratio)
174 {
175 if (!property_) {
176 WLOGE("SetAspectRatio failed because property is null");
177 return WSError::WS_ERROR_NULLPTR;
178 }
179 float vpr = 1.5f; // 1.5f: default virtual pixel ratio
180 auto display = ScreenSessionManager::GetInstance().GetDefaultDisplayInfo();
181 if (display) {
182 vpr = display->GetVirtualPixelRatio();
183 WLOGD("vpr = %{public}f", vpr);
184 }
185 if (!MathHelper::NearZero(ratio)) {
186 auto limits = property_->GetWindowLimits();
187 if (IsDecorEnable()) {
188 if (limits.minWidth_ && limits.maxHeight_ &&
189 MathHelper::LessNotEqual(ratio, static_cast<float>(SessionUtils::ToLayoutWidth(limits.minWidth_, vpr)) /
190 SessionUtils::ToLayoutHeight(limits.maxHeight_, vpr))) {
191 WLOGE("Failed, because aspectRatio is smaller than minWidth/maxHeight");
192 return WSError::WS_ERROR_INVALID_PARAM;
193 } else if (limits.minHeight_ && limits.maxWidth_ &&
194 MathHelper::GreatNotEqual(ratio,
195 static_cast<float>(SessionUtils::ToLayoutWidth(limits.maxWidth_, vpr)) /
196 SessionUtils::ToLayoutHeight(limits.minHeight_, vpr))) {
197 WLOGE("Failed, because aspectRatio is bigger than maxWidth/minHeight");
198 return WSError::WS_ERROR_INVALID_PARAM;
199 }
200 } else {
201 if (limits.minWidth_ && limits.maxHeight_ && MathHelper::LessNotEqual(ratio,
202 static_cast<float>(limits.minWidth_) / limits.maxHeight_)) {
203 WLOGE("Failed, because aspectRatio is smaller than minWidth/maxHeight");
204 return WSError::WS_ERROR_INVALID_PARAM;
205 } else if (limits.minHeight_ && limits.maxWidth_ && MathHelper::GreatNotEqual(ratio,
206 static_cast<float>(limits.maxWidth_) / limits.minHeight_)) {
207 WLOGE("Failed, because aspectRatio is bigger than maxWidth/minHeight");
208 return WSError::WS_ERROR_INVALID_PARAM;
209 }
210 }
211 }
212 aspectRatio_ = ratio;
213 if (moveDragController_) {
214 moveDragController_->SetAspectRatio(ratio);
215 }
216 SaveAspectRatio(aspectRatio_);
217 if (FixRectByAspectRatio(winRect_)) {
218 NotifySessionRectChange(winRect_);
219 UpdateRect(winRect_, SizeChangeReason::RESIZE);
220 }
221 return WSError::WS_OK;
222 }
223
UpdateRect(const WSRect & rect,SizeChangeReason reason)224 WSError SceneSession::UpdateRect(const WSRect& rect, SizeChangeReason reason)
225 {
226 WLOGFD("Id: %{public}d, reason: %{public}d, rect: [%{public}d, %{public}d, %{public}u, %{public}u]",
227 GetPersistentId(), reason, rect.posX_, rect.posY_, rect.width_, rect.height_);
228 if (moveDragController_->GetStartMoveFlag()) {
229 reason = SizeChangeReason::MOVE;
230 } else if (moveDragController_->GetStartDragFlag()) {
231 reason = SizeChangeReason::DRAG;
232 }
233 WSError ret = Session::UpdateRect(rect, reason);
234 if (ret == WSError::WS_OK) {
235 specificCallback_->onUpdateAvoidArea_(GetPersistentId());
236 }
237 return ret;
238 }
239
UpdateSessionRect(const WSRect & rect,const SizeChangeReason & reason)240 WSError SceneSession::UpdateSessionRect(const WSRect& rect, const SizeChangeReason& reason)
241 {
242 auto newWinRect = winRect_;
243 auto newRequestRect = GetSessionRequestRect();
244 if (reason == SizeChangeReason::MOVE) {
245 newWinRect.posX_ = rect.posX_;
246 newWinRect.posY_ = rect.posY_;
247 newRequestRect.posX_ = rect.posX_;
248 newRequestRect.posY_ = rect.posY_;
249 SetSessionRect(newWinRect);
250 SetSessionRequestRect(newRequestRect);
251 NotifySessionRectChange(newRequestRect, reason);
252 } else if (reason == SizeChangeReason::RESIZE) {
253 newWinRect.width_ = rect.width_;
254 newWinRect.height_ = rect.height_;
255 newRequestRect.width_ = rect.width_;
256 newRequestRect.height_ = rect.height_;
257 SetSessionRect(newWinRect);
258 SetSessionRequestRect(newRequestRect);
259 NotifySessionRectChange(newRequestRect, reason);
260 } else {
261 SetSessionRect(rect);
262 NotifySessionRectChange(rect, reason);
263 }
264
265 WLOGFI("Id: %{public}d, reason: %{public}d, rect: [%{public}d, %{public}d, %{public}u, %{public}u], "
266 "newRequestRect: [%{public}d, %{public}d, %{public}u, %{public}u], newWinRect: [%{public}d, "
267 "%{public}d, %{public}u, %{public}u]", GetPersistentId(), reason, rect.posX_, rect.posY_, rect.width_,
268 rect.height_, newRequestRect.posX_, newRequestRect.posY_, newRequestRect.width_, newRequestRect.height_,
269 newWinRect.posX_, newWinRect.posY_, newWinRect.width_, newWinRect.height_);
270 return WSError::WS_OK;
271 }
272
RaiseToAppTop()273 WSError SceneSession::RaiseToAppTop()
274 {
275 if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->onRaiseToTop_) {
276 sessionChangeCallback_->onRaiseToTop_();
277 }
278 return WSError::WS_OK;
279 }
280
RaiseAboveTarget(int32_t subWindowId)281 WSError SceneSession::RaiseAboveTarget(int32_t subWindowId)
282 {
283 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
284 WLOGFE("RaiseAboveTarget permission denied!");
285 return WSError::WS_ERROR_NOT_SYSTEM_APP;
286 }
287 if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->onRaiseAboveTarget_) {
288 sessionChangeCallback_->onRaiseAboveTarget_(subWindowId);
289 }
290 return WSError::WS_OK;
291 }
292
CreateAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,int32_t & persistentId,sptr<ISession> & session,sptr<IRemoteObject> token)293 WSError SceneSession::CreateAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
294 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
295 sptr<WindowSessionProperty> property, int32_t& persistentId, sptr<ISession>& session, sptr<IRemoteObject> token)
296 {
297 WLOGFI("CreateAndConnectSpecificSession id: %{public}d", GetPersistentId());
298 sptr<SceneSession> sceneSession;
299 if (specificCallback_ != nullptr) {
300 SessionInfo sessionInfo;
301 sceneSession = specificCallback_->onCreate_(sessionInfo, property);
302 }
303 if (sceneSession == nullptr) {
304 return WSError::WS_ERROR_NULLPTR;
305 }
306 // connect specific session and sessionStage
307 WSError errCode = sceneSession->Connect(sessionStage, eventChannel, surfaceNode, systemConfig_, property, token);
308 if (property) {
309 persistentId = property->GetPersistentId();
310 }
311 if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->onCreateSpecificSession_) {
312 sessionChangeCallback_->onCreateSpecificSession_(sceneSession);
313 }
314 session = sceneSession;
315 return errCode;
316 }
317
BindDialogTarget(const sptr<SceneSession> & sceneSession)318 WSError SceneSession::BindDialogTarget(const sptr<SceneSession>& sceneSession)
319 {
320 if (sceneSession == nullptr) {
321 WLOGFE("dialog session is null");
322 return WSError::WS_ERROR_NULLPTR;
323 }
324 if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->onBindDialogTarget_) {
325 sessionChangeCallback_->onBindDialogTarget_(sceneSession);
326 }
327 return WSError::WS_OK;
328 }
329
DestroyAndDisconnectSpecificSession(const int32_t & persistentId)330 WSError SceneSession::DestroyAndDisconnectSpecificSession(const int32_t& persistentId)
331 {
332 WSError ret = WSError::WS_OK;
333 if (specificCallback_ != nullptr) {
334 ret = specificCallback_->onDestroy_(persistentId);
335 }
336 return ret;
337 }
338
UpdateCameraFloatWindowStatus(bool isShowing)339 void SceneSession::UpdateCameraFloatWindowStatus(bool isShowing)
340 {
341 if (GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA && specificCallback_ != nullptr) {
342 specificCallback_->onCameraFloatSessionChange_(property_->GetAccessTokenId(), isShowing);
343 }
344 }
345
SetSystemBarProperty(WindowType type,SystemBarProperty systemBarProperty)346 WSError SceneSession::SetSystemBarProperty(WindowType type, SystemBarProperty systemBarProperty)
347 {
348 if (property_ == nullptr) {
349 return WSError::WS_ERROR_NULLPTR;
350 }
351 property_->SetSystemBarProperty(type, systemBarProperty);
352 WLOGFD("SceneSession SetSystemBarProperty status:%{public}d", static_cast<int32_t>(type));
353 if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->OnSystemBarPropertyChange_) {
354 sessionChangeCallback_->OnSystemBarPropertyChange_(property_->GetSystemBarProperty());
355 }
356 return WSError::WS_OK;
357 }
358
NotifyPropertyWhenConnect()359 void SceneSession::NotifyPropertyWhenConnect()
360 {
361 WLOGFI("Notify property when connect.");
362 if (property_ == nullptr) {
363 WLOGFD("id: %{public}d property is nullptr", persistentId_);
364 return;
365 }
366 NotifySessionFocusableChange(property_->GetFocusable());
367 NotifySessionTouchableChange(property_->GetTouchable());
368 OnShowWhenLocked(IsShowWhenLocked());
369 }
370
OnNeedAvoid(bool status)371 WSError SceneSession::OnNeedAvoid(bool status)
372 {
373 WLOGFD("SceneSession OnNeedAvoid status:%{public}d", static_cast<int32_t>(status));
374 if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->OnNeedAvoid_) {
375 sessionChangeCallback_->OnNeedAvoid_(status);
376 }
377 return WSError::WS_OK;
378 }
379
OnShowWhenLocked(bool showWhenLocked)380 WSError SceneSession::OnShowWhenLocked(bool showWhenLocked)
381 {
382 WLOGFD("SceneSession ShowWhenLocked status:%{public}d", static_cast<int32_t>(showWhenLocked));
383 if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->OnShowWhenLocked_) {
384 sessionChangeCallback_->OnShowWhenLocked_(showWhenLocked);
385 }
386 return WSError::WS_OK;
387 }
388
IsShowWhenLocked() const389 bool SceneSession::IsShowWhenLocked() const
390 {
391 return property_->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
392 }
393
CalculateAvoidAreaRect(WSRect & rect,WSRect & avoidRect,AvoidArea & avoidArea)394 void SceneSession::CalculateAvoidAreaRect(WSRect& rect, WSRect& avoidRect, AvoidArea& avoidArea)
395 {
396 if (SessionHelper::IsEmptyRect(rect) || SessionHelper::IsEmptyRect(avoidRect)) {
397 return;
398 }
399 Rect avoidAreaRect = SessionHelper::TransferToRect(SessionHelper::GetOverlap(rect, avoidRect, 0, 0));
400 if (WindowHelper::IsEmptyRect(avoidAreaRect)) {
401 return;
402 }
403
404 uint32_t avoidAreaCenterX = static_cast<uint32_t>(avoidAreaRect.posX_) + (avoidAreaRect.width_ >> 1);
405 uint32_t avoidAreaCenterY = static_cast<uint32_t>(avoidAreaRect.posY_) + (avoidAreaRect.height_ >> 1);
406 float res1 = float(avoidAreaCenterY) - float(rect.height_) / float(rect.width_) *
407 float(avoidAreaCenterX);
408 float res2 = float(avoidAreaCenterY) + float(rect.height_) / float(rect.width_) *
409 float(avoidAreaCenterX) - float(rect.height_);
410 if (res1 < 0) {
411 if (res2 < 0) {
412 avoidArea.topRect_ = avoidAreaRect;
413 } else {
414 avoidArea.rightRect_ = avoidAreaRect;
415 }
416 } else {
417 if (res2 < 0) {
418 avoidArea.leftRect_ = avoidAreaRect;
419 } else {
420 avoidArea.bottomRect_ = avoidAreaRect;
421 }
422 }
423 }
424
GetSystemAvoidArea(WSRect & rect,AvoidArea & avoidArea)425 void SceneSession::GetSystemAvoidArea(WSRect& rect, AvoidArea& avoidArea)
426 {
427 if (property_->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID)) {
428 return;
429 }
430 std::vector<sptr<SceneSession>> statusBarVector =
431 specificCallback_->onGetSceneSessionVectorByType_(WindowType::WINDOW_TYPE_STATUS_BAR);
432 for (auto& statusBar : statusBarVector) {
433 if (!(statusBar->isVisible_)) {
434 continue;
435 }
436 WSRect statusBarRect = statusBar->GetSessionRect();
437 CalculateAvoidAreaRect(rect, statusBarRect, avoidArea);
438 }
439
440 return;
441 }
442
GetKeyboardAvoidArea(WSRect & rect,AvoidArea & avoidArea)443 void SceneSession::GetKeyboardAvoidArea(WSRect& rect, AvoidArea& avoidArea)
444 {
445 std::vector<sptr<SceneSession>> inputMethodVector =
446 specificCallback_->onGetSceneSessionVectorByType_(WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
447 for (auto& inputMethod : inputMethodVector) {
448 if (inputMethod->GetSessionState() != SessionState::STATE_FOREGROUND &&
449 inputMethod->GetSessionState() != SessionState::STATE_ACTIVE) {
450 continue;
451 }
452 WSRect inputMethodRect = inputMethod->GetSessionRect();
453 CalculateAvoidAreaRect(rect, inputMethodRect, avoidArea);
454 }
455
456 return;
457 }
458
GetCutoutAvoidArea(WSRect & rect,AvoidArea & avoidArea)459 void SceneSession::GetCutoutAvoidArea(WSRect& rect, AvoidArea& avoidArea)
460 {
461 sptr<CutoutInfo> cutoutInfo = ScreenSessionManager::GetInstance().
462 GetCutoutInfo(property_->GetDisplayId());
463 if (cutoutInfo == nullptr) {
464 WLOGFI("GetCutoutAvoidArea There is no CutoutInfo");
465 return;
466 }
467 std::vector<DMRect> cutoutAreas = cutoutInfo->GetBoundingRects();
468 if (cutoutAreas.empty()) {
469 WLOGFI("GetCutoutAvoidArea There is no cutoutAreas");
470 return;
471 }
472 for (auto& cutoutArea : cutoutAreas) {
473 WSRect cutoutAreaRect = {
474 cutoutArea.posX_,
475 cutoutArea.posY_,
476 cutoutArea.width_,
477 cutoutArea.height_
478 };
479 CalculateAvoidAreaRect(rect, cutoutAreaRect, avoidArea);
480 }
481
482 return;
483 }
484
GetAvoidAreaByType(AvoidAreaType type)485 AvoidArea SceneSession::GetAvoidAreaByType(AvoidAreaType type)
486 {
487 AvoidArea avoidArea;
488 WSRect rect = GetSessionRect();
489 WLOGFD("GetAvoidAreaByType avoidAreaType:%{public}u", type);
490 switch (type) {
491 case AvoidAreaType::TYPE_SYSTEM : {
492 GetSystemAvoidArea(rect, avoidArea);
493 return avoidArea;
494 }
495 case AvoidAreaType::TYPE_KEYBOARD : {
496 GetKeyboardAvoidArea(rect, avoidArea);
497 return avoidArea;
498 }
499 case AvoidAreaType::TYPE_CUTOUT : {
500 GetCutoutAvoidArea(rect, avoidArea);
501 return avoidArea;
502 }
503 default : {
504 WLOGFD("cannot find avoidAreaType: %{public}u", type);
505 return avoidArea;
506 }
507 }
508 }
509
UpdateAvoidArea(const sptr<AvoidArea> & avoidArea,AvoidAreaType type)510 WSError SceneSession::UpdateAvoidArea(const sptr<AvoidArea>& avoidArea, AvoidAreaType type)
511 {
512 if (!sessionStage_) {
513 return WSError::WS_ERROR_NULLPTR;
514 }
515 return sessionStage_->UpdateAvoidArea(avoidArea, type);
516 }
517
TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)518 WSError SceneSession::TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
519 {
520 WLOGFD("SceneSession TransferPointEvent");
521 if (pointerEvent == nullptr) {
522 WLOGFE("pointerEvent is null");
523 return WSError::WS_ERROR_NULLPTR;
524 }
525 {
526 if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW) {
527 std::lock_guard<std::mutex> guard(enterSessionMutex_);
528 enterSession_ = wptr<SceneSession>(this);
529 }
530 }
531
532 if (property_ && property_->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING &&
533 WindowHelper::IsMainWindow(property_->GetWindowType()) &&
534 property_->GetMaximizeMode() != MaximizeMode::MODE_AVOID_SYSTEM_BAR) {
535 if (!moveDragController_) {
536 WLOGE("moveDragController_ is null");
537 return Session::TransferPointerEvent(pointerEvent);
538 }
539 if (property_->GetDragEnabled()) {
540 moveDragController_->HandleMouseStyle(pointerEvent, winRect_);
541 if (moveDragController_->ConsumeDragEvent(pointerEvent, winRect_, property_, systemConfig_)) {
542 return WSError::WS_OK;
543 }
544 }
545
546 if (moveDragController_->GetStartMoveFlag()) {
547 return moveDragController_->ConsumeMoveEvent(pointerEvent, winRect_);
548 }
549 }
550
551 auto action = pointerEvent->GetPointerAction();
552 bool raiseEnabled = WindowHelper::IsSubWindow(property_->GetWindowType()) && property_->GetRaiseEnabled() &&
553 (action == MMI::PointerEvent::POINTER_ACTION_DOWN || action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
554 if (raiseEnabled) {
555 RaiseToAppTop();
556 }
557 return Session::TransferPointerEvent(pointerEvent);
558 }
559
GetEnterWindow()560 const wptr<SceneSession> SceneSession::GetEnterWindow()
561 {
562 std::lock_guard<std::mutex> guard(enterSessionMutex_);
563 return enterSession_;
564 }
565
ClearEnterWindow()566 void SceneSession::ClearEnterWindow()
567 {
568 std::lock_guard<std::mutex> guard(enterSessionMutex_);
569 enterSession_ = nullptr;
570 }
571
NotifySessionRectChange(const WSRect & rect,const SizeChangeReason & reason)572 void SceneSession::NotifySessionRectChange(const WSRect& rect, const SizeChangeReason& reason)
573 {
574 if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->onRectChange_) {
575 sessionChangeCallback_->onRectChange_(rect, reason);
576 }
577 }
578
IsDecorEnable()579 bool SceneSession::IsDecorEnable()
580 {
581 return WindowHelper::IsMainWindow(property_->GetWindowType()) && systemConfig_.isSystemDecorEnable_ &&
582 WindowHelper::IsWindowModeSupported(systemConfig_.decorModeSupportInfo_, property_->GetWindowMode());
583 }
584
GetRatioPreferenceKey()585 std::string SceneSession::GetRatioPreferenceKey()
586 {
587 std::string key = sessionInfo_.bundleName_ + sessionInfo_.moduleName_ + sessionInfo_.abilityName_;
588 if (key.length() > ScenePersistentStorage::MAX_KEY_LEN) {
589 return key.substr(key.length() - ScenePersistentStorage::MAX_KEY_LEN);
590 }
591 return key;
592 }
593
SaveAspectRatio(float ratio)594 bool SceneSession::SaveAspectRatio(float ratio)
595 {
596 std::string key = GetRatioPreferenceKey();
597 if (!key.empty()) {
598 ScenePersistentStorage::Insert(key, ratio, ScenePersistentStorageType::ASPECT_RATIO);
599 WLOGD("SceneSession save aspectRatio , key %{public}s, value: %{public}f", key.c_str(), aspectRatio_);
600 return true;
601 }
602 return false;
603 }
604
FixRectByAspectRatio(WSRect & rect)605 bool SceneSession::FixRectByAspectRatio(WSRect& rect)
606 {
607 const int tolerancePx = 2; // 2: tolerance delta pixel value, unit: px
608 WSRect originalRect = rect;
609 if (!property_ || property_->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING ||
610 !WindowHelper::IsMainWindow(property_->GetWindowType())) {
611 return false;
612 }
613
614 if (MathHelper::NearZero(aspectRatio_)) {
615 return false;
616 }
617 float vpr = 1.5f; // 1.5f: default virtual pixel ratio
618 auto display = ScreenSessionManager::GetInstance().GetDefaultDisplayInfo();
619 if (display) {
620 vpr = display->GetVirtualPixelRatio();
621 }
622 int32_t minW;
623 int32_t maxW;
624 int32_t minH;
625 int32_t maxH;
626 SessionUtils::CalcFloatWindowRectLimits(property_->GetWindowLimits(), systemConfig_.maxFloatingWindowSize_, vpr,
627 minW, maxW, minH, maxH);
628 rect.width_ = std::max(minW, static_cast<int32_t>(rect.width_));
629 rect.width_ = std::min(maxW, static_cast<int32_t>(rect.width_));
630 rect.height_ = std::max(minH, static_cast<int32_t>(rect.height_));
631 rect.height_ = std::min(maxH, static_cast<int32_t>(rect.height_));
632 if (IsDecorEnable()) {
633 if (SessionUtils::ToLayoutWidth(rect.width_, vpr) >
634 SessionUtils::ToLayoutHeight(rect.height_, vpr) * aspectRatio_) {
635 rect.width_ = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(rect.height_, vpr)* aspectRatio_, vpr);
636 } else {
637 rect.height_ = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(rect.width_, vpr) / aspectRatio_, vpr);
638 }
639 } else {
640 if (rect.width_ > rect.height_ * aspectRatio_) {
641 rect.width_ = rect.height_ * aspectRatio_;
642 } else {
643 rect.height_ = rect.width_ / aspectRatio_;
644 }
645 }
646 if (std::abs(static_cast<int32_t>(originalRect.width_) - static_cast<int32_t>(rect.width_)) <= tolerancePx &&
647 std::abs(static_cast<int32_t>(originalRect.height_) - static_cast<int32_t>(rect.height_)) <= tolerancePx) {
648 rect = originalRect;
649 return false;
650 }
651 return true;
652 }
653
SetSessionRectChangeCallback()654 void SceneSession::SetSessionRectChangeCallback()
655 {
656 if (moveDragController_) {
657 SessionRectChangeCallBack callBack = [this](void) {
658 this->OnSessionRectChange();
659 };
660 moveDragController_->RegisterSessionRectChangeCallback(callBack);
661 }
662 }
663
OnSessionRectChange()664 void SceneSession::OnSessionRectChange()
665 {
666 WSRect rect = moveDragController_->GetTargetRect();
667 WLOGFD("rect: [%{public}d, %{public}d, %{public}u, %{public}u]", rect.posX_, rect.posY_, rect.width_, rect.height_);
668 NotifySessionRectChange(rect);
669 if (!(moveDragController_->GetStartMoveFlag() || moveDragController_->GetStartDragFlag())) {
670 OnSessionEvent(SessionEvent::EVENT_END_MOVE);
671 }
672 }
673
SetZOrder(uint32_t zOrder)674 void SceneSession::SetZOrder(uint32_t zOrder)
675 {
676 if (zOrder_ != zOrder) {
677 Session::SetZOrder(zOrder);
678 if (specificCallback_ != nullptr) {
679 specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
680 }
681 }
682 }
683
GetWindowName() const684 const std::string& SceneSession::GetWindowName() const
685 {
686 return property_->GetWindowName();
687 }
688
SetTurnScreenOn(bool turnScreenOn)689 WSError SceneSession::SetTurnScreenOn(bool turnScreenOn)
690 {
691 property_->SetTurnScreenOn(turnScreenOn);
692 return WSError::WS_OK;
693 }
694
IsTurnScreenOn() const695 bool SceneSession::IsTurnScreenOn() const
696 {
697 return property_->IsTurnScreenOn();
698 }
699
SetKeepScreenOn(bool keepScreenOn)700 WSError SceneSession::SetKeepScreenOn(bool keepScreenOn)
701 {
702 property_->SetKeepScreenOn(keepScreenOn);
703 return WSError::WS_OK;
704 }
705
IsKeepScreenOn() const706 bool SceneSession::IsKeepScreenOn() const
707 {
708 return property_->IsKeepScreenOn();
709 }
710
GetSessionSnapshotFilePath()711 std::string SceneSession::GetSessionSnapshotFilePath()
712 {
713 WLOGFI("GetSessionSnapshotFilePath id %{public}d", GetPersistentId());
714 if (Session::GetSessionState() < SessionState::STATE_BACKGROUND) {
715 WLOGFI("GetSessionSnapshotFilePath UpdateSnapshot");
716 auto snapshot = Snapshot();
717 scenePersistence_->SaveSnapshot(snapshot);
718 }
719 if (scenePersistence_ != nullptr) {
720 return scenePersistence_->GetSnapshotFilePath();
721 }
722 return "";
723 }
724
UpdateNativeVisibility(bool visible)725 void SceneSession::UpdateNativeVisibility(bool visible)
726 {
727 isVisible_ = visible;
728 if (specificCallback_ == nullptr) {
729 WLOGFW("specific callback is null.");
730 return;
731 }
732
733 if (visible) {
734 specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
735 } else {
736 specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
737 }
738 specificCallback_->onUpdateAvoidArea_(GetPersistentId());
739 // update private state
740 if (!property_) {
741 WLOGFE("property_ is null");
742 return;
743 }
744 auto screenSession = ScreenSessionManager::GetInstance().GetScreenSession(0);
745 if (screenSession == nullptr) {
746 WLOGFE("screen session is null");
747 return;
748 }
749 if (property_->GetPrivacyMode() || property_->GetSystemPrivacyMode()) {
750 ScreenSessionManager::GetInstance().UpdatePrivateStateAndNotify(screenSession, visible);
751 }
752 }
753
IsVisible() const754 bool SceneSession::IsVisible() const
755 {
756 return isVisible_;
757 }
758
SetPrivacyMode(bool isPrivacy)759 void SceneSession::SetPrivacyMode(bool isPrivacy)
760 {
761 if (!property_) {
762 WLOGFE("property_ is null");
763 return;
764 }
765 if (!surfaceNode_) {
766 WLOGFE("surfaceNode_ is null");
767 return;
768 }
769 bool lastPrivacyMode = property_->GetPrivacyMode() || property_->GetSystemPrivacyMode();
770 if (lastPrivacyMode == isPrivacy) {
771 WLOGFW("privacy mode is not change, do nothing");
772 return;
773 }
774 property_->SetPrivacyMode(isPrivacy);
775 property_->SetSystemPrivacyMode(isPrivacy);
776 surfaceNode_->SetSecurityLayer(isPrivacy);
777 RSTransaction::FlushImplicitTransaction();
778 auto screenSession = ScreenSessionManager::GetInstance().GetScreenSession(0);
779 if (screenSession == nullptr) {
780 WLOGFE("screen session is null");
781 return;
782 }
783 if (GetSessionState() == SessionState::STATE_FOREGROUND || GetSessionState() == SessionState::STATE_ACTIVE
784 || (GetSessionInfo().isSystem_ && isVisible_)) {
785 ScreenSessionManager::GetInstance().UpdatePrivateStateAndNotify(screenSession, isPrivacy);
786 }
787 }
788
UpdateWindowAnimationFlag(bool needDefaultAnimationFlag)789 WSError SceneSession::UpdateWindowAnimationFlag(bool needDefaultAnimationFlag)
790 {
791 if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->onWindowAnimationFlagChange_) {
792 sessionChangeCallback_ -> onWindowAnimationFlagChange_(needDefaultAnimationFlag);
793 }
794 return WSError::WS_OK;
795 }
796
NotifyIsCustomAnimatiomPlaying(bool isPlaying)797 void SceneSession::NotifyIsCustomAnimatiomPlaying(bool isPlaying)
798 {
799 WLOGFI("id %{public}d %{public}u", GetPersistentId(), isPlaying);
800 if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->onIsCustomAnimationPlaying_) {
801 sessionChangeCallback_->onIsCustomAnimationPlaying_(isPlaying);
802 }
803 }
804
UpdateWindowSceneAfterCustomAnimation(bool isAdd)805 WSError SceneSession::UpdateWindowSceneAfterCustomAnimation(bool isAdd)
806 {
807 WLOGFI("id %{public}d", GetPersistentId());
808 if (isAdd) {
809 if (!setWindowScenePatternFunc_ || !setWindowScenePatternFunc_->setOpacityFunc_) {
810 WLOGFE("SetOpacityFunc not register %{public}d", GetPersistentId());
811 return WSError::WS_ERROR_INVALID_OPERATION;
812 }
813 setWindowScenePatternFunc_->setOpacityFunc_(1.0f);
814 } else {
815 WLOGFI("background after custom animation id %{public}d", GetPersistentId());
816 // since background will remove surfaceNode
817 Background();
818 NotifyIsCustomAnimatiomPlaying(false);
819 }
820 return WSError::WS_OK;
821 }
822
IsFloatingWindowAppType() const823 bool SceneSession::IsFloatingWindowAppType() const
824 {
825 if (property_ == nullptr) {
826 return false;
827 }
828
829 return property_->IsFloatingWindowAppType();
830 }
831
GetTouchHotAreas() const832 std::vector<Rect> SceneSession::GetTouchHotAreas() const
833 {
834 std::vector<Rect> touchHotAreas;
835 if (property_) {
836 property_->GetTouchHotAreas(touchHotAreas);
837 }
838 return touchHotAreas;
839 }
DumpSessionElementInfo(const std::vector<std::string> & params)840 void SceneSession::DumpSessionElementInfo(const std::vector<std::string>& params)
841 {
842 if (!sessionStage_) {
843 return;
844 }
845 return sessionStage_->DumpSessionElementInfo(params);
846 }
847
GetHotAreaRect(int32_t action)848 Rect SceneSession::GetHotAreaRect(int32_t action)
849 {
850 Rect hotAreaRect;
851 WSRect rect = GetSessionRect();
852
853 float vpr = 1.5f; // 1.5f: default virtual pixel ratio
854 auto display = ScreenSessionManager::GetInstance().GetDefaultDisplayInfo();
855 if (display) {
856 vpr = display->GetVirtualPixelRatio();
857 WLOGD("vpr = %{public}f", vpr);
858 }
859
860 float hotZone = 0.0;
861 if (action == MMI::PointerEvent::POINTER_ACTION_DOWN) {
862 hotZone = HOTZONE_TOUCH;
863 } else if (action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
864 hotZone = HOTZONE_POINTER;
865 }
866 hotAreaRect.posX_ = rect.posX_ - static_cast<int32_t>(vpr * hotZone);
867 hotAreaRect.posY_ = rect.posY_ - static_cast<int32_t>(vpr * hotZone);
868 hotAreaRect.width_ = rect.width_ + static_cast<uint32_t>(vpr * hotZone * 2); // 2: double hotZone
869 hotAreaRect.height_ = rect.height_ + static_cast<uint32_t>(vpr * hotZone * 2); // 2: double hotZone
870
871 return hotAreaRect;
872 }
873
NotifyTouchOutside()874 WSError SceneSession::NotifyTouchOutside()
875 {
876 if (!sessionStage_) {
877 return WSError::WS_ERROR_NULLPTR;
878 }
879 return sessionStage_->NotifyTouchOutside();
880 }
881
SetRequestedOrientation(Orientation orientation)882 void SceneSession::SetRequestedOrientation(Orientation orientation)
883 {
884 WLOGFI("id: %{public}d orientation: %{public}u", GetPersistentId(), static_cast<uint32_t>(orientation));
885 property_->SetRequestedOrientation(orientation);
886 if (sessionChangeCallback_ && sessionChangeCallback_->OnRequestedOrientationChange_) {
887 sessionChangeCallback_->OnRequestedOrientationChange_(static_cast<uint32_t>(orientation));
888 }
889 }
890
GetRequestedOrientation() const891 Orientation SceneSession::GetRequestedOrientation() const
892 {
893 return property_->GetRequestedOrientation();
894 }
895
GetCollaboratorType() const896 int32_t SceneSession::GetCollaboratorType() const
897 {
898 return collaboratorType_;
899 }
900
SetCollaboratorType(int32_t collaboratorType)901 void SceneSession::SetCollaboratorType(int32_t collaboratorType)
902 {
903 collaboratorType_ = collaboratorType;
904 }
905
GetAbilityInfo()906 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSession::GetAbilityInfo()
907 {
908 SessionInfo& sessionInfo = GetSessionInfo();
909 return sessionInfo.abilityInfo;
910 }
911
SetAbilitySessionInfo(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)912 void SceneSession::SetAbilitySessionInfo(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
913 {
914 SessionInfo& sessionInfo = GetSessionInfo();
915 sessionInfo.abilityInfo = abilityInfo;
916 }
917
UpdateBrokerPersistentId(int32_t persistendId)918 void SceneSession::UpdateBrokerPersistentId(int32_t persistendId)
919 {
920 brokerPersistentId_ = persistendId;
921 }
922
GetBrokerPersistentId()923 int32_t SceneSession::GetBrokerPersistentId()
924 {
925 return brokerPersistentId_;
926 }
927 } // namespace OHOS::Rosen
928