• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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