!10738 悬停态抛滑新增PcFoldScreenManager

Merge pull request !10738 from slarkwayne/remote_throwSlipFix
This commit is contained in:
openharmony_ci 2024-11-13 07:42:49 +00:00 committed by Gitee
commit 13faeff5ec
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 453 additions and 366 deletions

View File

@ -16,9 +16,9 @@
#ifndef OHOS_ROSEN_WM_MATH_H
#define OHOS_ROSEN_WM_MATH_H
#include <chrono>
#include <cmath>
#include <limits>
#include <chrono>
namespace OHOS::Rosen {
namespace MathHelper {

View File

@ -3580,17 +3580,18 @@ napi_value JsSceneSessionManager::OnUpdatePcFoldScreenStatus(napi_env env, napi_
return NapiGetUndefined(env);
}
ScreenFoldStatus status = ScreenFoldStatus::UNKNOWN;
if (!ConvertFromJsValue(env, argv[ARG_INDEX_ONE], status)) {
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to type");
uint32_t statusNum;
if (!ConvertFromJsValue(env, argv[ARG_INDEX_ONE], statusNum)) {
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to status");
napi_throw(env, CreateJsError(env, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
"Input parameter is missing or invalid"));
return NapiGetUndefined(env);
}
ScreenFoldStatus status = static_cast<ScreenFoldStatus>(statusNum);
WSRect defaultDisplayRect;
if (argv[ARG_INDEX_TWO] == nullptr || !ConvertRectInfoFromJs(env, argv[ARG_INDEX_TWO], defaultDisplayRect)) {
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to rect");
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to display rect");
napi_throw(env, CreateJsError(env, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
"Input parameter is missing or invalid"));
return NapiGetUndefined(env);
@ -3598,7 +3599,7 @@ napi_value JsSceneSessionManager::OnUpdatePcFoldScreenStatus(napi_env env, napi_
WSRect virtualDisplayRect;
if (argv[ARG_INDEX_THREE] == nullptr || !ConvertRectInfoFromJs(env, argv[ARG_INDEX_THREE], virtualDisplayRect)) {
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to rect");
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to virtual rect");
napi_throw(env, CreateJsError(env, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
"Input parameter is missing or invalid"));
return NapiGetUndefined(env);
@ -3606,17 +3607,14 @@ napi_value JsSceneSessionManager::OnUpdatePcFoldScreenStatus(napi_env env, napi_
WSRect foldCreaseRect;
if (argv[ARG_INDEX_FOUR] == nullptr || !ConvertRectInfoFromJs(env, argv[ARG_INDEX_FOUR], foldCreaseRect)) {
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to rect");
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to fold crease rect");
napi_throw(env, CreateJsError(env, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
"Input parameter is missing or invalid"));
return NapiGetUndefined(env);
}
PcFoldScreenController::UpdateFoldScreenStatus(displayId, status);
PcFoldScreenController::SetDefaultDisplayRect(defaultDisplayRect);
PcFoldScreenController::SetVirtualDisplayRect(virtualDisplayRect);
PcFoldScreenController::SetFoldCreaseRect(foldCreaseRect);
PcFoldScreenManager::GetInstance().UpdateFoldScreenStatus(displayId, status,
defaultDisplayRect, virtualDisplayRect, foldCreaseRect);
return NapiGetUndefined(env);
}
@ -3641,8 +3639,7 @@ napi_value JsSceneSessionManager::OnResetPcFoldScreenArrangeRule(napi_env env, n
return NapiGetUndefined(env);
}
PcFoldScreenController::ResetArrangeRule(rect);
PcFoldScreenManager::GetInstance().ResetArrangeRule(rect);
return NapiGetUndefined(env);
}

View File

@ -17,10 +17,15 @@
#define PC_FOLD_SCREEN_CONTROLLER_H
#include <chrono>
#include "interfaces/include/ws_common.h"
#include "dm_common.h"
#include <mutex>
#include <shared_mutex>
#include <tuple>
#include "animation/rs_animation_timing_curve.h"
#include "animation/rs_animation_timing_protocol.h"
#include "dm_common.h"
#include "interfaces/include/ws_common.h"
#include "wm_single_instance.h"
namespace OHOS::Rosen {
@ -29,96 +34,114 @@ class SceneSession;
using RectRecordsVector =
std::vector<std::pair<std::chrono::time_point<std::chrono::high_resolution_clock>, WSRect>>;
enum class ScreenFoldStatus {
enum class ScreenFoldStatus : uint8_t {
UNKNOWN = 0,
COVER_CLOSE = 1,
HALF_FOLDED = 2,
HALF_FOLDED_PHYSICAL_KEYBOARD = 3,
FLATTENED = 4,
EXPANDED = 1,
FOLDED = 2,
HALF_FOLDED = 3,
HALF_FOLDED_KEYBOARD = 4,
};
enum class ScreenSide {
enum class ScreenSide : uint8_t {
EXPAND = 0,
FOLD_B = 1,
FOLD_C = 2,
};
class PcFoldScreenController : public RefBase {
class PcFoldScreenManager {
WM_DECLARE_SINGLE_INSTANCE(PcFoldScreenManager);
public:
explicit PcFoldScreenController(wptr<SceneSession> weak);
static bool IsHalfFolded() { return screenFoldStatus_.load() == ScreenFoldStatus::HALF_FOLDED; }
void UpdateFoldScreenStatus(DisplayId displayId, ScreenFoldStatus status,
const WSRect& defaultDisplayRect, const WSRect& virtualDisplayRect, const WSRect& foldCreaseRect);
bool IsHalfFolded(DisplayId displayId);
// screen property
static WSError UpdateFoldScreenStatus(DisplayId displayId, ScreenFoldStatus status);
static inline ScreenFoldStatus GetScreenFoldStatus() { return screenFoldStatus_.load(); }
static inline WSRect GetDefaultDisplayRect() { return defaultDisplayRect_.load(); }
static inline WSRect GetVirtualDisplayRect() { return virtualDisplayRect_.load(); }
static inline WSRect GetFoldCreaseRect() { return foldCreaseRect_.load(); }
static inline void SetDefaultDisplayRect(const WSRect& rect) { defaultDisplayRect_.store(rect); }
static inline void SetVirtualDisplayRect(const WSRect& rect) { virtualDisplayRect_.store(rect); }
static inline void SetFoldCreaseRect(const WSRect& rect) { foldCreaseRect_.store(rect); }
std::tuple<WSRect, WSRect, WSRect> GetDisplayRects();
// animation parameters
static RSAnimationTimingProtocol GetMovingTimingProtocol();
static RSAnimationTimingCurve GetMovingTimingCurve();
static RSAnimationTimingProtocol GetThrowSlipTimingProtocol();
static RSAnimationTimingCurve GetThrowSlipTimingCurve();
RSAnimationTimingProtocol GetMovingTimingProtocol();
RSAnimationTimingCurve GetMovingTimingCurve();
RSAnimationTimingProtocol GetThrowSlipTimingProtocol();
RSAnimationTimingCurve GetThrowSlipTimingCurve();
void RecordStartRect(const WSRect& rect, bool isStartFullScreen);
void RecordMoveRects(const WSRect& rect);
bool ThrowSlip(DisplayId displayId, WSRect& rect, int32_t topAvoidHeight, int32_t botAvoidHeight);
static void ResetArrangeRule(const WSRect& rect);
bool IsStartFullScreen() const;
static void ResizeToFullScreen(WSRect& rect, int32_t topAvoidHeight, int32_t botAvoidHeight);
ScreenSide CalculateScreenSide(const WSRect& rect);
private:
int32_t GetPersistentId() const;
int32_t GetTitleHeight() const;
WSRectF CalculateMovingVelocity();
void RemoveMoveRects();
void ResetArrangeRule();
void ResetArrangeRule(ScreenSide side);
void ResetArrangeRule(const WSRect& rect);
static ScreenSide CalculateScreenSide(const WSRect& rect);
static bool NeedDoThrowSlip(ScreenSide startSide, WSRectF velocity);
void ResizeToFullScreen(WSRect& rect, int32_t topAvoidHeight, int32_t botAvoidHeight);
bool NeedDoThrowSlip(ScreenSide startSide, const WSRectF& velocity);
bool ThrowSlipToOppositeSide(ScreenSide startSide, WSRect& rect,
int32_t topAvoidHeight, int32_t botAvoidHeight);
static void MappingRectInScreenSide(ScreenSide side, WSRect& rect,
int32_t topAvoidHeight, int32_t botAvoidHeight, int32_t titleHeight);
void MappingRectInScreenSide(ScreenSide side, WSRect& rect,
int32_t topAvoidHeight, int32_t botAvoidHeight);
void MappingRectInScreenSideWithArrangeRule(ScreenSide side, WSRect& rect,
int32_t topAvoidHeight, int32_t botAvoidHeight);
int32_t topAvoidHeight, int32_t botAvoidHeight, int32_t titleHeight);
static void ApplyInitArrangeRule(WSRect& rect, std::atomic<WSRect>& lastArrangedRect,
void ApplyInitArrangeRule(WSRect& rect, WSRect& lastArrangedRect,
const WSRect& limitRect, int32_t titleHeight);
static void ApplyArrangeRule(WSRect& rect, std::atomic<WSRect>& lastArrangedRect,
void ApplyArrangeRule(WSRect& rect, WSRect& lastArrangedRect,
const WSRect& limitRect, int32_t titleHeight);
static void ResetArrangeRule();
static void ResetArrangeRule(ScreenSide side);
wptr<SceneSession> weakSceneSession_ = nullptr;
private:
void SetDisplayInfo(DisplayId displayId, ScreenFoldStatus status);
void SetDisplayRects(
const WSRect& defaultDisplayRect, const WSRect& virtualDisplayRect, const WSRect& foldCreaseRect);
float GetVpr();
/*
* fold screen property
* if need, use map for multi fold screen
*/
static std::atomic<DisplayId> displayId_;
static std::atomic<float> vpr_; // display vp ratio
static std::atomic<ScreenFoldStatus> screenFoldStatus_;
static std::atomic<WSRect> defaultDisplayRect_;
static std::atomic<WSRect> virtualDisplayRect_;
static std::atomic<WSRect> foldCreaseRect_;
// use queue to calculate velocity
WSRect startRect_;
bool isStartFullScreen_ { false };
RectRecordsVector movingRectRecords_;
std::shared_mutex displayInfoMutex_; // protect display infos
DisplayId displayId_ { SCREEN_ID_INVALID };
float vpr_ { 1.5f }; // display vp ratio
ScreenFoldStatus screenFoldStatus_ { ScreenFoldStatus::UNKNOWN };
std::shared_mutex rectsMutex_; // protect rects
WSRect defaultDisplayRect_;
WSRect virtualDisplayRect_;
WSRect foldCreaseRect_;
/*
* arranged rect
* x,y: last arranged position
* w,h: offset for next arranged position
*/
static std::atomic<WSRect> defaultArrangedRect_;
static std::atomic<WSRect> virtualArrangedRect_;
std::mutex arrangedRectsMutex_;
WSRect defaultArrangedRect_;
WSRect virtualArrangedRect_;
};
class PcFoldScreenController : public RefBase {
public:
explicit PcFoldScreenController(wptr<SceneSession> weakSession);
bool IsHalfFolded(DisplayId displayId);
void RecordStartMoveRect(const WSRect& rect, bool isStartFullScreen);
void RecordMoveRects(const WSRect& rect);
bool ThrowSlip(DisplayId displayId, WSRect& rect, int32_t topAvoidHeight, int32_t botAvoidHeight);
bool IsStartFullScreen() const;
void ResizeToFullScreen(WSRect& rect, int32_t topAvoidHeight, int32_t botAvoidHeight);
// animation parameters
RSAnimationTimingProtocol GetMovingTimingProtocol();
RSAnimationTimingCurve GetMovingTimingCurve();
RSAnimationTimingProtocol GetThrowSlipTimingProtocol();
RSAnimationTimingCurve GetThrowSlipTimingCurve();
private:
int32_t GetPersistentId() const;
int32_t GetTitleHeight() const;
WSRectF CalculateMovingVelocity();
wptr<SceneSession> weakSceneSession_ = nullptr;
// use queue to calculate velocity
std::mutex moveMutex_;
WSRect startMoveRect_;
bool isStartFullScreen_ { false };
RectRecordsVector movingRectRecords_;
};
} // namespace OHOS::Rosen
#endif // PC_FOLD_SCREEN_CONTROLLER_H
#endif // PC_FOLD_SCREEN_CONTROLLER_H

View File

@ -175,7 +175,7 @@ public:
WSError UpdateActiveStatus(bool isActive) override;
WSError OnSessionEvent(SessionEvent event) override;
WSError OnSessionEvent(SessionEvent event, SessionEventParam param);
WSError OnSessionEvent(SessionEvent event, const SessionEventParam& param);
WSError SyncSessionEvent(SessionEvent event) override;
WSError OnLayoutFullScreenChange(bool isLayoutFullScreen) override;
WSError OnDefaultDensityEnabled(bool isDefaultDensityEnabled) override;
@ -605,7 +605,7 @@ protected:
ClearCallbackMapFunc clearCallbackMapFunc_;
/*
* pc fold screen
* PC Fold Screen
*/
sptr<PcFoldScreenController> pcFoldScreenController_ = nullptr;
@ -672,12 +672,6 @@ private:
bool SaveAspectRatio(float ratio);
void NotifyPropertyWhenConnect();
WSError RaiseAppMainWindowToTop() override;
void SetSurfaceBoundsWithAnimation(
std::pair<RSAnimationTimingProtocol, RSAnimationTimingCurve> animationParam,
const WSRect& rect, std::function<void()>&& finishCallback = nullptr,
bool isGlobal = false, bool needFlush = true
);
void SetSurfaceBounds(const WSRect& rect, bool isGlobal, bool needFlush = true);
void UpdateWinRectForSystemBar(WSRect& rect);
bool UpdateInputMethodSessionRect(const WSRect& rect, WSRect& newWinRect, WSRect& newRequestRect);
bool IsMovableWindowType();
@ -851,6 +845,11 @@ private:
/**
* Window Layout
*/
void SetSurfaceBoundsWithAnimation(
const std::pair<RSAnimationTimingProtocol, RSAnimationTimingCurve>& animationParam,
const WSRect& rect, const std::function<void()>& finishCallback = nullptr,
bool isGlobal = false, bool needFlush = true);
void SetSurfaceBounds(const WSRect& rect, bool isGlobal, bool needFlush = true);
NotifyLayoutFullScreenChangeFunc onLayoutFullScreenChangeFunc_;
/**

View File

@ -48,107 +48,398 @@ constexpr int32_t MAX_DECOR_HEIGHT = 112;
const WSRect RECT_ZERO = { 0, 0, 0, 0 };
} // namespace
std::atomic<DisplayId> PcFoldScreenController::displayId_ = DEFAULT_SCREEN_ID;
std::atomic<float> PcFoldScreenController::vpr_ = 1.5f;
std::atomic<ScreenFoldStatus> PcFoldScreenController::screenFoldStatus_ = ScreenFoldStatus::UNKNOWN;
std::atomic<WSRect> PcFoldScreenController::defaultDisplayRect_ = RECT_ZERO;
std::atomic<WSRect> PcFoldScreenController::virtualDisplayRect_ = RECT_ZERO;
std::atomic<WSRect> PcFoldScreenController::foldCreaseRect_ = RECT_ZERO;
std::atomic<WSRect> PcFoldScreenController::defaultArrangedRect_ = RECT_ZERO;
std::atomic<WSRect> PcFoldScreenController::virtualArrangedRect_ = RECT_ZERO;
WM_IMPLEMENT_SINGLE_INSTANCE(PcFoldScreenManager);
PcFoldScreenController::PcFoldScreenController(wptr<SceneSession> weak) : weakSceneSession_(weak) {}
WSError PcFoldScreenController::UpdateFoldScreenStatus(DisplayId displayId, ScreenFoldStatus status)
void PcFoldScreenManager::UpdateFoldScreenStatus(DisplayId displayId, ScreenFoldStatus status,
const WSRect& defaultDisplayRect, const WSRect& virtualDisplayRect, const WSRect& foldCreaseRect)
{
if (displayId_.load() == displayId && screenFoldStatus_.load() == status) {
return WSError::WS_DO_NOTHING;
SetDisplayInfo(displayId, status);
SetDisplayRects(defaultDisplayRect, virtualDisplayRect, foldCreaseRect);
}
void PcFoldScreenManager::SetDisplayInfo(DisplayId displayId, ScreenFoldStatus status)
{
std::unique_lock<std::shared_mutex> lock(displayInfoMutex_);
if (displayId_ == displayId && screenFoldStatus_ == status) {
return;
}
TLOGI(WmsLogTag::WMS_MAIN, "display: %{public}" PRIu64", fold status: %{public}d",
displayId, static_cast<int32_t>(status));
screenFoldStatus_.store(status);
screenFoldStatus_ = status;
ResetArrangeRule();
displayId_.store(displayId);
displayId_ = displayId;
auto display = DisplayManager::GetInstance().GetDisplayById(displayId);
if (display == nullptr) {
TLOGE(WmsLogTag::WMS_MAIN, "Failed to get display");
return WSError::WS_OK;
return;
}
vpr_.store(display->GetVirtualPixelRatio());
TLOGI(WmsLogTag::WMS_MAIN, "vpr: %{public}f", vpr_.load());
return WSError::WS_OK;
vpr_ = display->GetVirtualPixelRatio();
TLOGI(WmsLogTag::WMS_MAIN, "vpr: %{public}f", vpr_);
}
RSAnimationTimingProtocol PcFoldScreenController::GetMovingTimingProtocol()
void PcFoldScreenManager::SetDisplayRects(
const WSRect& defaultDisplayRect, const WSRect& virtualDisplayRect, const WSRect& foldCreaseRect)
{
std::unique_lock<std::shared_mutex> lock(rectsMutex_);
defaultDisplayRect_ = defaultDisplayRect;
virtualDisplayRect_ = virtualDisplayRect;
foldCreaseRect_ = foldCreaseRect;
}
bool PcFoldScreenManager::IsHalfFolded(DisplayId displayId)
{
std::shared_lock<std::shared_mutex> lock(displayInfoMutex_);
return screenFoldStatus_ == ScreenFoldStatus::HALF_FOLDED && displayId_ == displayId;
}
float PcFoldScreenManager::GetVpr()
{
std::unique_lock<std::shared_mutex> lock(displayInfoMutex_);
return vpr_;
}
std::tuple<WSRect, WSRect, WSRect> PcFoldScreenManager::GetDisplayRects()
{
std::shared_lock<std::shared_mutex> lock(rectsMutex_);
return { defaultDisplayRect_, virtualDisplayRect_, foldCreaseRect_ };
}
RSAnimationTimingProtocol PcFoldScreenManager::GetMovingTimingProtocol()
{
return MOVING_TIMING_PROTOCOL;
}
RSAnimationTimingCurve PcFoldScreenController::GetMovingTimingCurve()
RSAnimationTimingCurve PcFoldScreenManager::GetMovingTimingCurve()
{
return MOVING_CURVE;
}
RSAnimationTimingProtocol PcFoldScreenController::GetThrowSlipTimingProtocol()
RSAnimationTimingProtocol PcFoldScreenManager::GetThrowSlipTimingProtocol()
{
return THROW_SLIP_TIMING_PROTOCOL;
}
RSAnimationTimingCurve PcFoldScreenController::GetThrowSlipTimingCurve()
RSAnimationTimingCurve PcFoldScreenManager::GetThrowSlipTimingCurve()
{
return THROW_SLIP_CURVE;
}
void PcFoldScreenController::RecordStartRect(const WSRect& rect, bool isStartFullScreen)
ScreenSide PcFoldScreenManager::CalculateScreenSide(const WSRect& rect)
{
int32_t midPosY = rect.height_ / 2 + rect.posY_; // 2: center
const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] = GetDisplayRects();
return midPosY <= (defaultDisplayRect.posY_ + defaultDisplayRect.height_) ?
ScreenSide::FOLD_B : ScreenSide::FOLD_C;
}
void PcFoldScreenManager::ResetArrangeRule()
{
std::unique_lock<std::mutex> arrangedRectsMutex_;
defaultArrangedRect_ = RECT_ZERO;
virtualArrangedRect_ = RECT_ZERO;
}
void PcFoldScreenManager::ResetArrangeRule(const WSRect& rect)
{
ResetArrangeRule(CalculateScreenSide(rect));
}
void PcFoldScreenManager::ResetArrangeRule(ScreenSide side)
{
if (side != ScreenSide::FOLD_B && side != ScreenSide::FOLD_C) {
TLOGD(WmsLogTag::WMS_LAYOUT, "invalid side: %{public}d", static_cast<int32_t>(side));
return;
}
std::unique_lock<std::mutex> arrangedRectsMutex_;
if (side == ScreenSide::FOLD_B) {
defaultArrangedRect_ = RECT_ZERO;
} else { // FOLD_C
virtualArrangedRect_ = RECT_ZERO;
}
}
void PcFoldScreenManager::ResizeToFullScreen(WSRect& rect, int32_t topAvoidHeight, int32_t botAvoidHeight)
{
ScreenSide side = CalculateScreenSide(rect);
TLOGD(WmsLogTag::WMS_LAYOUT, "side: %{public}d, rect: %{public}s",
static_cast<int32_t>(side), rect.ToString().c_str());
if (side != ScreenSide::FOLD_B && side != ScreenSide::FOLD_C) {
TLOGW(WmsLogTag::WMS_LAYOUT, "rule not avaliable, side %{public}d", static_cast<int32_t>(side));
return;
}
ResetArrangeRule(side);
// calculate limit rect
const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] = GetDisplayRects();
WSRect limitRect = RECT_ZERO;
if (side == ScreenSide::FOLD_B) {
limitRect.posX_ = defaultDisplayRect.posX_;
limitRect.posY_ = defaultDisplayRect.posY_ + topAvoidHeight;
limitRect.width_ = defaultDisplayRect.width_;
limitRect.height_ = foldCreaseRect.posY_ - limitRect.posY_;
} else { // FOLD_C
limitRect.posX_ = virtualDisplayRect.posX_;
limitRect.posY_ = foldCreaseRect.posY_ + foldCreaseRect.height_;
limitRect.width_ = virtualDisplayRect.width_;
limitRect.height_ = virtualDisplayRect.posY_ + virtualDisplayRect.height_ - botAvoidHeight - limitRect.posY_;
}
rect = limitRect;
}
bool PcFoldScreenManager::NeedDoThrowSlip(ScreenSide startSide, const WSRectF& velocity)
{
TLOGD(WmsLogTag::WMS_LAYOUT, "side: %{public}d, velocity: %{public}s",
static_cast<int32_t>(startSide), velocity.ToString().c_str());
float vpr = GetVpr();
if (startSide == ScreenSide::FOLD_B && velocity.posY_ > VEL_THRESHOLD * vpr &&
std::abs(velocity.posX_ / MathHelper::NonZero(velocity.posY_)) < TAN_25_DEG) {
return true;
}
if (startSide == ScreenSide::FOLD_C && velocity.posY_ < -VEL_THRESHOLD * vpr &&
std::abs(velocity.posX_ / MathHelper::NonZero(velocity.posY_)) < TAN_25_DEG) {
return true;
}
return false;
}
/*
* move rect to other side
* @param rect: current side, moved to other side
* @param titleHeight: used in arrange rule to avoid title bar
*/
bool PcFoldScreenManager::ThrowSlipToOppositeSide(ScreenSide startSide, WSRect& rect,
int32_t topAvoidHeight, int32_t botAvoidHeight, int32_t titleHeight)
{
if (startSide != ScreenSide::FOLD_B && startSide != ScreenSide::FOLD_C) {
return false;
}
ScreenSide endSide = (startSide == ScreenSide::FOLD_B) ? ScreenSide::FOLD_C : ScreenSide::FOLD_B;
MappingRectInScreenSideWithArrangeRule(endSide, rect, topAvoidHeight, botAvoidHeight, titleHeight);
return true;
}
void PcFoldScreenManager::MappingRectInScreenSide(ScreenSide side, WSRect& rect,
int32_t topAvoidHeight, int32_t botAvoidHeight)
{
TLOGD(WmsLogTag::WMS_LAYOUT, "side: %{public}d, rect: %{public}s, avoid heights: [%{public}d,%{public}d]",
static_cast<int32_t>(side), rect.ToString().c_str(), topAvoidHeight, botAvoidHeight);
WSRect topLeftLimit = RECT_ZERO;
WSRect botRightLimit = RECT_ZERO;
const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] = GetDisplayRects();
float vpr = GetVpr();
switch (side) {
case ScreenSide::FOLD_B:
topLeftLimit.posX_ = MathHelper::Ceil(RULE_TRANS_X * vpr) - rect.width_;
topLeftLimit.posY_ = topAvoidHeight;
botRightLimit.posX_ = std::max(0,
MathHelper::Floor(defaultDisplayRect.width_ - RULE_TRANS_X * vpr));
botRightLimit.posY_ = std::max(0, foldCreaseRect.posY_ - rect.height_);
botRightLimit.width_ = defaultDisplayRect.width_;
botRightLimit.height_ = std::max(0, foldCreaseRect.posY_ - topLeftLimit.posY_);
break;
case ScreenSide::FOLD_C:
topLeftLimit.posX_ = MathHelper::Ceil(RULE_TRANS_X * vpr) - rect.width_;
topLeftLimit.posY_ = foldCreaseRect.posY_ + foldCreaseRect.height_;
botRightLimit.posX_ = std::max(0,
MathHelper::Floor(virtualDisplayRect.width_ - RULE_TRANS_X * vpr));
botRightLimit.posY_ = std::max(foldCreaseRect.posY_ + foldCreaseRect.height_,
MathHelper::Floor(virtualDisplayRect.posY_ + virtualDisplayRect.height_ -
botAvoidHeight - MIN_DECOR_HEIGHT * vpr));
botRightLimit.width_ = virtualDisplayRect.width_;
botRightLimit.height_ = std::max(0,
virtualDisplayRect.posY_ + virtualDisplayRect.height_ - topLeftLimit.posY_ - botAvoidHeight);
break;
default:
TLOGW(WmsLogTag::WMS_LAYOUT, "invalid side: %{public}d", static_cast<int32_t>(side));
return;
}
rect.posX_ = std::max(rect.posX_, topLeftLimit.posX_);
rect.posY_ = std::max(rect.posY_, topLeftLimit.posY_);
rect.posX_ = std::min(rect.posX_, botRightLimit.posX_);
rect.posY_ = std::min(rect.posY_, botRightLimit.posY_);
rect.width_ = std::min(rect.width_, botRightLimit.width_);
rect.height_ = std::min(rect.height_, botRightLimit.height_);
TLOGD(WmsLogTag::WMS_LAYOUT, "limit rects: [%{public}s,%{public}s], mapped rect: %{public}s",
topLeftLimit.ToString().c_str(), botRightLimit.ToString().c_str(), rect.ToString().c_str());
}
void PcFoldScreenManager::MappingRectInScreenSideWithArrangeRule(ScreenSide side, WSRect& rect,
int32_t topAvoidHeight, int32_t botAvoidHeight, int32_t titleHeight)
{
TLOGD(WmsLogTag::WMS_LAYOUT, "side: %{public}d, rect: %{public}s",
static_cast<int32_t>(side), rect.ToString().c_str());
if (side != ScreenSide::FOLD_B && side != ScreenSide::FOLD_C) {
TLOGW(WmsLogTag::WMS_LAYOUT, "rule not avaliable, side %{public}d", static_cast<int32_t>(side));
return;
}
// calculate limit rect
const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] = GetDisplayRects();
WSRect limitRect = RECT_ZERO;
if (side == ScreenSide::FOLD_B) {
limitRect.posX_ = defaultDisplayRect.posX_;
limitRect.posY_ = defaultDisplayRect.posY_ + topAvoidHeight;
limitRect.width_ = defaultDisplayRect.width_;
limitRect.height_ = foldCreaseRect.posY_ - limitRect.posY_;
} else { // FOLD_C
limitRect.posX_ = virtualDisplayRect.posX_;
limitRect.posY_ = foldCreaseRect.posY_ + foldCreaseRect.height_;
limitRect.width_ = virtualDisplayRect.width_;
limitRect.height_ = virtualDisplayRect.posY_ + virtualDisplayRect.height_ - botAvoidHeight - limitRect.posY_;
}
{
std::unique_lock<std::mutex> lock(arrangedRectsMutex_);
WSRect& lastArrangedRect = (side == ScreenSide::FOLD_B) ? defaultArrangedRect_ : virtualArrangedRect_;
if (lastArrangedRect.IsEmpty()) {
ApplyInitArrangeRule(rect, lastArrangedRect, limitRect, titleHeight);
TLOGD(WmsLogTag::WMS_LAYOUT, "init rule, limit: %{public}s, arranged: %{public}s, rect: %{public}s",
limitRect.ToString().c_str(), lastArrangedRect.ToString().c_str(), rect.ToString().c_str());
return;
}
ApplyArrangeRule(rect, lastArrangedRect, limitRect, titleHeight);
TLOGD(WmsLogTag::WMS_LAYOUT, "apply rule, limit: %{public}s, arranged: %{public}s, rect: %{public}s",
limitRect.ToString().c_str(), lastArrangedRect.ToString().c_str(), rect.ToString().c_str());
}
}
/*
* init rule: move rect to center of display
* @param titleHeight: in vp
*/
void PcFoldScreenManager::ApplyInitArrangeRule(WSRect& rect, WSRect& lastArrangedRect,
const WSRect& limitRect, int32_t titleHeight)
{
rect.posX_ = std::max(limitRect.posX_, limitRect.posX_ + (limitRect.width_ - rect.width_) / 2); // 2: center align
rect.posY_ = std::max(limitRect.posY_, limitRect.posY_ + (limitRect.height_ - rect.height_) / 2); // 2: center align
float vpr = GetVpr();
lastArrangedRect = { rect.posX_, rect.posY_, RULE_TRANS_X * vpr, titleHeight * vpr };
}
/*
* init rule: move rect to bottom-right of last arranged position
* @param titleHeight: in vp
*/
void PcFoldScreenManager::ApplyArrangeRule(WSRect& rect, WSRect& lastArrangedRect,
const WSRect& limitRect, int32_t titleHeight)
{
rect.posX_ = lastArrangedRect.posX_ + lastArrangedRect.width_;
rect.posY_ = lastArrangedRect.posY_ + lastArrangedRect.height_;
// new column
if (rect.posY_ + rect.height_ > limitRect.posY_ + limitRect.height_) {
rect.posY_ = limitRect.posY_;
}
// reset to top-left
if (rect.posX_ + rect.width_ > limitRect.posX_ + limitRect.width_) {
rect.posX_ = limitRect.posX_;
rect.posY_ = limitRect.posY_;
}
float vpr = GetVpr();
lastArrangedRect = { rect.posX_, rect.posY_, RULE_TRANS_X * vpr, titleHeight * vpr};
}
PcFoldScreenController::PcFoldScreenController(wptr<SceneSession> weakSession)
: weakSceneSession_(std::move(weakSession)) {}
bool PcFoldScreenController::IsHalfFolded(DisplayId displayId)
{
return PcFoldScreenManager::GetInstance().IsHalfFolded(displayId);
}
void PcFoldScreenController::RecordStartMoveRect(const WSRect& rect, bool isStartFullScreen)
{
TLOGI(WmsLogTag::WMS_LAYOUT, "rect: %{public}s, isStartFullScreen: %{public}d",
rect.ToString().c_str(), isStartFullScreen);
startRect_ = rect;
std::unique_lock<std::mutex> moveMutex_;
startMoveRect_ = rect;
isStartFullScreen_ = isStartFullScreen;
}
bool PcFoldScreenController::IsStartFullScreen() const
{
std::unique_lock<std::mutex> moveMutex_;
return isStartFullScreen_;
}
void PcFoldScreenController::RecordMoveRects(const WSRect& rect)
{
auto time = std::chrono::high_resolution_clock::now();
std::unique_lock<std::mutex> moveMutex_;
movingRectRecords_.push_back(std::make_pair(time, rect));
TLOGD(WmsLogTag::WMS_LAYOUT, "id: %{public}d, rect: %{public}s", GetPersistentId(), rect.ToString().c_str());
// pop useless record
while (movingRectRecords_.size() > MOVING_RECORDS_SIZE_LIMIT ||
TimeHelper::GetDuration(movingRectRecords_[0].first, time) > MOVING_RECORDS_TIME_LIMIT) {
TimeHelper::GetDuration(movingRectRecords_[0].first, time) > MOVING_RECORDS_TIME_LIMIT) {
movingRectRecords_.erase(movingRectRecords_.begin());
}
TLOGD(WmsLogTag::WMS_LAYOUT, "records size: %{public}d, duration: %{public}d", movingRectRecords_.size(),
TLOGD(WmsLogTag::WMS_LAYOUT, "records size: %{public}zu, duration: %{public}d", movingRectRecords_.size(),
TimeHelper::GetDuration(movingRectRecords_[0].first, movingRectRecords_[movingRectRecords_.size() - 1].first));
}
/*
* if move fast, window can be throwed to other side
* @param rect: current rect. if throwed, move it to other side
* @param topAvoidHeight: avoid status bar
* @param botAvoidHeight: avoid dock
*/
bool PcFoldScreenController::ThrowSlip(DisplayId displayId, WSRect& rect,
int32_t topAvoidHeight, int32_t botAvoidHeight)
{
if (!IsHalfFolded() || displayId != displayId_.load()) {
ResetArrangeRule();
auto& manager = PcFoldScreenManager::GetInstance();
if (!manager.IsHalfFolded(displayId)) {
manager.ResetArrangeRule();
return false;
}
ResetArrangeRule(CalculateScreenSide(startRect_));
{
std::unique_lock<std::mutex> moveMutex_;
manager.ResetArrangeRule(startMoveRect_);
}
WSRect titleRect = { rect.posX_, rect.posY_, rect.width_, GetTitleHeight() };
ScreenSide startSide = CalculateScreenSide(titleRect);
ScreenSide startSide = manager.CalculateScreenSide(titleRect);
WSRectF velocity = CalculateMovingVelocity();
if (!NeedDoThrowSlip(startSide, velocity)) {
ResetArrangeRule(startSide);
if (!manager.NeedDoThrowSlip(startSide, velocity)) {
manager.ResetArrangeRule(startSide);
TLOGI(WmsLogTag::WMS_LAYOUT, "no throw rect: %{public}s", rect.ToString().c_str());
return false;
}
ThrowSlipToOppositeSide(startSide, rect, topAvoidHeight, botAvoidHeight);
ResetArrangeRule(startSide);
manager.ThrowSlipToOppositeSide(startSide, rect, topAvoidHeight, botAvoidHeight, GetTitleHeight());
manager.ResetArrangeRule(startSide);
TLOGI(WmsLogTag::WMS_LAYOUT, "throw to rect: %{public}s", rect.ToString().c_str());
return true;
}
/*
* resize to fullscreen in one side considering avoid area
* @param rect: resize in its side
*/
void PcFoldScreenController::ResizeToFullScreen(WSRect& rect, int32_t topAvoidHeight, int32_t botAvoidHeight)
{
PcFoldScreenManager::GetInstance().ResizeToFullScreen(rect, topAvoidHeight, botAvoidHeight);
}
RSAnimationTimingProtocol PcFoldScreenController::GetMovingTimingProtocol()
{
return PcFoldScreenManager::GetInstance().GetMovingTimingProtocol();
}
RSAnimationTimingCurve PcFoldScreenController::GetMovingTimingCurve()
{
return PcFoldScreenManager::GetInstance().GetMovingTimingCurve();
}
RSAnimationTimingProtocol PcFoldScreenController::GetThrowSlipTimingProtocol()
{
return PcFoldScreenManager::GetInstance().GetThrowSlipTimingProtocol();
}
RSAnimationTimingCurve PcFoldScreenController::GetThrowSlipTimingCurve()
{
return PcFoldScreenManager::GetInstance().GetThrowSlipTimingCurve();
}
int32_t PcFoldScreenController::GetPersistentId() const
{
auto sceneSession = weakSceneSession_.promote();
@ -174,6 +465,7 @@ int32_t PcFoldScreenController::GetTitleHeight() const
WSRectF PcFoldScreenController::CalculateMovingVelocity()
{
WSRectF velocity = { 0.0f, 0.0f, 0.0f, 0.0f };
std::unique_lock<std::mutex> moveMutex_;
int32_t recordsSize = movingRectRecords_.size();
if (recordsSize <= 1) {
return velocity;
@ -195,221 +487,4 @@ WSRectF PcFoldScreenController::CalculateMovingVelocity()
}
return velocity;
}
void PcFoldScreenController::RemoveMoveRects()
{
RectRecordsVector vec;
movingRectRecords_.swap(vec);
}
ScreenSide PcFoldScreenController::CalculateScreenSide(const WSRect& rect)
{
int32_t midPosY = rect.height_ / 2 + rect.posY_; // 2: center
WSRect defaultDisplayRect = PcFoldScreenController::GetDefaultDisplayRect();
WSRect virtualDisplayRect = PcFoldScreenController::GetVirtualDisplayRect();
return midPosY <= (defaultDisplayRect.posY_ + defaultDisplayRect.height_) ?
ScreenSide::FOLD_B : ScreenSide::FOLD_C;
}
bool PcFoldScreenController::NeedDoThrowSlip(ScreenSide startSide, WSRectF velocity)
{
TLOGD(WmsLogTag::WMS_LAYOUT, "side: %{public}d, velocity: %{public}s", startSide, velocity.ToString().c_str());
if (startSide == ScreenSide::FOLD_B && velocity.posY_ > VEL_THRESHOLD * vpr_.load() &&
std::abs(velocity.posX_ / MathHelper::NonZero(velocity.posY_)) < TAN_25_DEG) {
return true;
}
if (startSide == ScreenSide::FOLD_C && velocity.posY_ < -VEL_THRESHOLD * vpr_.load() &&
std::abs(velocity.posX_ / MathHelper::NonZero(velocity.posY_)) < TAN_25_DEG) {
return true;
}
return false;
}
bool PcFoldScreenController::ThrowSlipToOppositeSide(ScreenSide startSide, WSRect& rect,
int32_t topAvoidHeight, int32_t botAvoidHeight)
{
if (startSide != ScreenSide::FOLD_B && startSide != ScreenSide::FOLD_C) {
return false;
}
ScreenSide endSide = (startSide == ScreenSide::FOLD_B) ? ScreenSide::FOLD_C : ScreenSide::FOLD_B;
MappingRectInScreenSideWithArrangeRule(endSide, rect, topAvoidHeight, botAvoidHeight);
return true;
}
void PcFoldScreenController::MappingRectInScreenSide(ScreenSide side, WSRect& rect,
int32_t topAvoidHeight, int32_t botAvoidHeight)
{
TLOGD(WmsLogTag::WMS_LAYOUT, "side: %{public}d, rect: %{public}s, avoid heights: [%{public}d,%{public}d]",
static_cast<int32_t>(side), rect.ToString().c_str(), topAvoidHeight, botAvoidHeight);
WSRect topLeftLimit = RECT_ZERO;
WSRect botRightLimit = RECT_ZERO;
WSRect defaultDisplayRect = PcFoldScreenController::GetDefaultDisplayRect();
WSRect virtualDisplayRect = PcFoldScreenController::GetVirtualDisplayRect();
WSRect foldCreaseRect = PcFoldScreenController::GetFoldCreaseRect();
switch (side) {
case ScreenSide::FOLD_B:
topLeftLimit.posX_ = MathHelper::Ceil(RULE_TRANS_X * vpr_.load()) - rect.width_;
topLeftLimit.posY_ = topAvoidHeight;
botRightLimit.posX_ = std::max(0,
MathHelper::Floor(defaultDisplayRect.width_ - RULE_TRANS_X * vpr_.load()));
botRightLimit.posY_ = std::max(0, foldCreaseRect.posY_ - rect.height_);
botRightLimit.width_ = defaultDisplayRect.width_;
botRightLimit.height_ = std::max(0, foldCreaseRect.posY_ - topLeftLimit.posY_);
break;
case ScreenSide::FOLD_C:
topLeftLimit.posX_ = MathHelper::Ceil(RULE_TRANS_X * vpr_.load()) - rect.width_;
topLeftLimit.posY_ = foldCreaseRect.posY_ + foldCreaseRect.height_;
botRightLimit.posX_ = std::max(0,
MathHelper::Floor(virtualDisplayRect.width_ - RULE_TRANS_X * vpr_.load()));
botRightLimit.posY_ = std::max(foldCreaseRect.posY_ + foldCreaseRect.height_,
MathHelper::Floor(virtualDisplayRect.posY_ + virtualDisplayRect.height_ -
botAvoidHeight - MIN_DECOR_HEIGHT * vpr_.load()));
botRightLimit.width_ = virtualDisplayRect.width_;
botRightLimit.height_ = std::max(0,
virtualDisplayRect.posY_ + virtualDisplayRect.height_ - topLeftLimit.posY_ - botAvoidHeight);
break;
default:
TLOGW(WmsLogTag::WMS_LAYOUT, "invalid side: %{public}d", static_cast<int32_t>(side));
return;
}
rect.posX_ = std::max(rect.posX_, topLeftLimit.posX_);
rect.posY_ = std::max(rect.posY_, topLeftLimit.posY_);
rect.posX_ = std::min(rect.posX_, botRightLimit.posX_);
rect.posY_ = std::min(rect.posY_, botRightLimit.posY_);
rect.width_ = std::min(rect.width_, botRightLimit.width_);
rect.height_ = std::min(rect.height_, botRightLimit.height_);
TLOGD(WmsLogTag::WMS_LAYOUT, "limit rects: [%{public}s,%{public}s], mapped rect: %{public}s",
topLeftLimit.ToString().c_str(), botRightLimit.ToString().c_str(), rect.ToString().c_str());
}
void PcFoldScreenController::ResizeToFullScreen(WSRect& rect, int32_t topAvoidHeight, int32_t botAvoidHeight)
{
ScreenSide side = CalculateScreenSide(rect);
TLOGD(WmsLogTag::WMS_LAYOUT, "side: %{public}d, rect: %{public}s",
static_cast<int32_t>(side), rect.ToString().c_str());
if (side != ScreenSide::FOLD_B && side != ScreenSide::FOLD_C) {
TLOGW(WmsLogTag::WMS_LAYOUT, "rule not avaliable, side %{public}d", static_cast<int32_t>(side));
return;
}
ResetArrangeRule(side);
// calculate limit rect
WSRect defaultDisplayRect = PcFoldScreenController::GetDefaultDisplayRect();
WSRect virtualDisplayRect = PcFoldScreenController::GetVirtualDisplayRect();
WSRect foldCreaseRect = PcFoldScreenController::GetFoldCreaseRect();
WSRect limitRect = RECT_ZERO;
if (side == ScreenSide::FOLD_B) {
limitRect.posX_ = defaultDisplayRect.posX_;
limitRect.posY_ = defaultDisplayRect.posY_ + topAvoidHeight;
limitRect.width_ = defaultDisplayRect.width_;
limitRect.height_ = foldCreaseRect.posY_ - limitRect.posY_;
} else { // FOLD_C
limitRect.posX_ = virtualDisplayRect.posX_;
limitRect.posY_ = foldCreaseRect.posY_ + foldCreaseRect.height_;
limitRect.width_ = virtualDisplayRect.width_;
limitRect.height_ = virtualDisplayRect.posY_ + virtualDisplayRect.height_ - botAvoidHeight - limitRect.posY_;
}
rect = limitRect;
}
void PcFoldScreenController::MappingRectInScreenSideWithArrangeRule(ScreenSide side, WSRect& rect,
int32_t topAvoidHeight, int32_t botAvoidHeight)
{
TLOGD(WmsLogTag::WMS_LAYOUT, "side: %{public}d, rect: %{public}s",
static_cast<int32_t>(side), rect.ToString().c_str());
if (side != ScreenSide::FOLD_B && side != ScreenSide::FOLD_C) {
TLOGW(WmsLogTag::WMS_LAYOUT, "rule not avaliable, side %{public}d", static_cast<int32_t>(side));
return;
}
// calculate limit rect
WSRect defaultDisplayRect = PcFoldScreenController::GetDefaultDisplayRect();
WSRect virtualDisplayRect = PcFoldScreenController::GetVirtualDisplayRect();
WSRect foldCreaseRect = PcFoldScreenController::GetFoldCreaseRect();
WSRect limitRect = RECT_ZERO;
if (side == ScreenSide::FOLD_B) {
limitRect.posX_ = defaultDisplayRect.posX_;
limitRect.posY_ = defaultDisplayRect.posY_ + topAvoidHeight;
limitRect.width_ = defaultDisplayRect.width_;
limitRect.height_ = foldCreaseRect.posY_ - limitRect.posY_;
} else { // FOLD_C
limitRect.posX_ = virtualDisplayRect.posX_;
limitRect.posY_ = foldCreaseRect.posY_ + foldCreaseRect.height_;
limitRect.width_ = virtualDisplayRect.width_;
limitRect.height_ = virtualDisplayRect.posY_ + virtualDisplayRect.height_ - botAvoidHeight - limitRect.posY_;
}
std::atomic<WSRect>& lastArrangedRect = (side == ScreenSide::FOLD_B) ?
defaultArrangedRect_ : virtualArrangedRect_;
if (lastArrangedRect.load().IsEmpty()) {
ApplyInitArrangeRule(rect, lastArrangedRect, limitRect, GetTitleHeight());
TLOGD(WmsLogTag::WMS_LAYOUT, "init rule, limit: %{public}s, arranged: %{public}s, rect: %{public}s",
limitRect.ToString().c_str(), lastArrangedRect.load().ToString().c_str(), rect.ToString().c_str());
return;
}
ApplyArrangeRule(rect, lastArrangedRect, limitRect, GetTitleHeight());
TLOGD(WmsLogTag::WMS_LAYOUT, "apply rule, limit: %{public}s, arranged: %{public}s, rect: %{public}s",
limitRect.ToString().c_str(), lastArrangedRect.load().ToString().c_str(), rect.ToString().c_str());
}
/*
* init rule: move rect to center of display
* @param titleHeight: in vp
*/
void PcFoldScreenController::ApplyInitArrangeRule(WSRect& rect, std::atomic<WSRect>& lastArrangedRect,
const WSRect& limitRect, int32_t titleHeight)
{
rect.posX_ = std::max(limitRect.posX_, limitRect.posX_ + (limitRect.width_ - rect.width_) / 2); // 2: center align
rect.posY_ = std::max(limitRect.posY_, limitRect.posY_ + (limitRect.height_ - rect.height_) / 2); // 2: center align
lastArrangedRect.store({ rect.posX_, rect.posY_,
RULE_TRANS_X * vpr_.load(), titleHeight * vpr_.load()});
}
/*
* init rule: move rect to bottom-right of last arranged position
* @param titleHeight: in vp
*/
void PcFoldScreenController::ApplyArrangeRule(WSRect& rect, std::atomic<WSRect>& lastArrangedRect,
const WSRect& limitRect, int32_t titleHeight)
{
rect.posX_ = lastArrangedRect.load().posX_ + lastArrangedRect.load().width_;
rect.posY_ = lastArrangedRect.load().posY_ + lastArrangedRect.load().height_;
// new column
if (rect.posY_ + rect.height_ > limitRect.posY_ + limitRect.height_) {
rect.posY_ = limitRect.posY_;
}
// reset to top-left
if (rect.posX_ + rect.width_ > limitRect.posX_ + limitRect.width_) {
rect.posX_ = limitRect.posX_;
rect.posY_ = limitRect.posY_;
}
lastArrangedRect.store({ rect.posX_, rect.posY_,
RULE_TRANS_X * vpr_.load(), titleHeight * vpr_.load()});
}
void PcFoldScreenController::ResetArrangeRule()
{
defaultArrangedRect_.store(RECT_ZERO);
virtualArrangedRect_.store(RECT_ZERO);
}
void PcFoldScreenController::ResetArrangeRule(const WSRect& rect)
{
ResetArrangeRule(CalculateScreenSide(rect));
}
void PcFoldScreenController::ResetArrangeRule(ScreenSide side)
{
if (side != ScreenSide::FOLD_B && side != ScreenSide::FOLD_C) {
TLOGD(WmsLogTag::WMS_LAYOUT, "invalid side: %{public}d", static_cast<int32_t>(side));
return;
}
if (side == ScreenSide::FOLD_B) {
defaultArrangedRect_.store(RECT_ZERO);
} else { // FOLD_C
virtualArrangedRect_.store(RECT_ZERO);
}
}
} // namespace OHOS::Rosen
} // namespace OHOS::Rosen

View File

@ -525,7 +525,7 @@ WSError SceneSession::OnSessionEvent(SessionEvent event)
session->InitializeCrossMoveDrag();
session->moveDragController_->InitMoveDragProperty();
if (session->pcFoldScreenController_) {
session->pcFoldScreenController_->RecordStartRect(session->GetSessionRect(),
session->pcFoldScreenController_->RecordStartMoveRect(session->GetSessionRect(),
session->IsFullScreenMovable());
}
if (session->IsFullScreenMovable()) {
@ -555,25 +555,24 @@ WSError SceneSession::OnSessionEvent(SessionEvent event)
return WSError::WS_OK;
}
WSError SceneSession::OnSessionEvent(SessionEvent event, SessionEventParam param)
WSError SceneSession::OnSessionEvent(SessionEvent event, const SessionEventParam& param)
{
const char* const where = __func__;
auto task = [weakThis = wptr(this), event, param, where]() {
auto task = [weakThis = wptr(this), event, param, where] {
auto session = weakThis.promote();
if (!session) {
TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s session is null", where);
return WSError::WS_ERROR_DESTROYED_OBJECT;
return;
}
if (!(session->sessionChangeCallback_ && session->sessionChangeCallback_->OnSessionEvent_)) {
TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s invalid callback", where);
return WSError::WS_DO_NOTHING;
return;
}
TLOGNI(WmsLogTag::WMS_MAIN,
"%{public}s event: %{public}d, param:[%{public}d,%{public}d,%{public}d,%{public}d]",
where, static_cast<int32_t>(event),
param.pointerX_, param.pointerY_, param.sessionWidth_, param.sessionHeight_);
session->sessionChangeCallback_->OnSessionEvent_(static_cast<uint32_t>(event), param);
return WSError::WS_OK;
};
PostTask(task, "OnSessionEvent:" + std::to_string(static_cast<uint32_t>(event)));
return WSError::WS_OK;
@ -2526,14 +2525,10 @@ void SceneSession::InitializeCrossMoveDrag()
void SceneSession::HandleMoveDragSurfaceBounds(WSRect& rect, WSRect& globalRect, SizeChangeReason reason,
bool isGlobal, bool needFlush)
{
const char* const funcName = __func__;
if (pcFoldScreenController_ && pcFoldScreenController_->IsHalfFolded()) {
SetSurfaceBoundsWithAnimation(
std::make_pair(
pcFoldScreenController_->GetMovingTimingProtocol(),
pcFoldScreenController_->GetMovingTimingCurve()
),
globalRect, nullptr, isGlobal, needFlush);
if (pcFoldScreenController_ && pcFoldScreenController_->IsHalfFolded(GetScreenId())) {
auto movingPair = std::make_pair(pcFoldScreenController_->GetMovingTimingProtocol(),
pcFoldScreenController_->GetMovingTimingCurve());
SetSurfaceBoundsWithAnimation(movingPair, globalRect, nullptr, isGlobal, needFlush);
if (reason == SizeChangeReason::MOVE) {
pcFoldScreenController_->RecordMoveRects(rect);
}
@ -2610,23 +2605,20 @@ bool SceneSession::MoveUnderInteriaAndNotifyRectChange(WSRect& rect, SizeChangeR
bool needSetFullScreen = pcFoldScreenController_->IsStartFullScreen();
if (needSetFullScreen) {
// maximize end rect and notify last rect
PcFoldScreenController::ResizeToFullScreen(endRect, GetStatusBarHeight(), GetDockHeight());
finishCallback = [weakThis = wptr(this), rect]() {
pcFoldScreenController_->ResizeToFullScreen(endRect, GetStatusBarHeight(), GetDockHeight());
finishCallback = [weakThis = wptr(this), rect] {
auto session = weakThis.promote();
if (session == nullptr) {
TLOGW(WmsLogTag::WMS_LAYOUT, "session is nullptr");
TLOGNW(WmsLogTag::WMS_LAYOUT, "session is nullptr");
return;
}
session->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE_WITHOUT_ANIMATION,
SessionEventParam {rect.posX_, rect.posY_, rect.width_, rect.height_});
};
}
SetSurfaceBoundsWithAnimation(
std::make_pair(
pcFoldScreenController_->GetThrowSlipTimingProtocol(),
pcFoldScreenController_->GetThrowSlipTimingCurve()
),
endRect, std::move(finishCallback));
auto throwSlipPair = std::make_pair(pcFoldScreenController_->GetThrowSlipTimingProtocol(),
pcFoldScreenController_->GetThrowSlipTimingCurve());
SetSurfaceBoundsWithAnimation(throwSlipPair, endRect, finishCallback);
return needSetFullScreen;
}
@ -2758,19 +2750,18 @@ void SceneSession::UpdateWinRectForSystemBar(WSRect& rect)
}
void SceneSession::SetSurfaceBoundsWithAnimation(
std::pair<RSAnimationTimingProtocol, RSAnimationTimingCurve> animationParam,
const WSRect& rect, std::function<void()>&& finishCallback, bool isGlobal, bool needFlush)
const std::pair<RSAnimationTimingProtocol, RSAnimationTimingCurve>& animationParam,
const WSRect& rect, const std::function<void()>& finishCallback, bool isGlobal, bool needFlush)
{
auto weakThis = wptr(this);
auto interiaFunc = [weakThis, rect, isGlobal, needFlush]() {
auto interiaFunc = [weakThis = wptr(this), rect, isGlobal, needFlush]() {
auto session = weakThis.promote();
if (session == nullptr) {
TLOGW(WmsLogTag::WMS_EVENT, "session is nullptr");
TLOGNW(WmsLogTag::WMS_LAYOUT, "session is nullptr");
return;
}
session->SetSurfaceBounds(rect, isGlobal, needFlush);
};
RSNode::Animate(animationParam.first, animationParam.second, interiaFunc, std::move(finishCallback));
RSNode::Animate(animationParam.first, animationParam.second, interiaFunc, finishCallback);
}
void SceneSession::SetSurfaceBounds(const WSRect& rect, bool isGlobal, bool needFlush)
@ -5212,9 +5203,11 @@ int32_t SceneSession::GetDockHeight()
std::vector<sptr<SceneSession>> dockVector = specificCallback_->onGetSceneSessionVectorByType_(
WindowType::WINDOW_TYPE_LAUNCHER_DOCK, GetSessionProperty()->GetDisplayId());
for (auto& dock : dockVector) {
if (dock != nullptr && dock->IsVisible() && dock->GetSessionRect().height_ > height &&
dock->GetWindowName().find("SCBSmartDock") != std::string::npos) {
height = dock->GetSessionRect().height_;
if (dock != nullptr && dock->IsVisible() && dock->GetWindowName().find("SCBSmartDock") != std::string::npos) {
int32_t dockHeight = dock->GetSessionRect().height_;
if (dockHeight > height) {
height = dockHeight;
}
}
}
return height;