2021-02-22 14:49:27 -08:00
|
|
|
/*
|
|
|
|
|
* Copyright 2021 The Android Open Source Project
|
|
|
|
|
*
|
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
|
*
|
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
*
|
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
|
* limitations under the License.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package com.android.launcher3.util;
|
|
|
|
|
|
|
|
|
|
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
|
|
|
|
|
2021-08-05 12:54:58 -07:00
|
|
|
import android.graphics.Rect;
|
|
|
|
|
|
2021-02-22 14:49:27 -08:00
|
|
|
import androidx.annotation.IntDef;
|
|
|
|
|
|
|
|
|
|
import java.lang.annotation.Retention;
|
|
|
|
|
|
|
|
|
|
public final class SplitConfigurationOptions {
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////
|
|
|
|
|
// Taken from
|
|
|
|
|
// frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
|
|
|
|
|
/**
|
|
|
|
|
* Stage position isn't specified normally meaning to use what ever it is currently set to.
|
|
|
|
|
*/
|
|
|
|
|
public static final int STAGE_POSITION_UNDEFINED = -1;
|
|
|
|
|
/**
|
|
|
|
|
* Specifies that a stage is positioned at the top half of the screen if
|
|
|
|
|
* in portrait mode or at the left half of the screen if in landscape mode.
|
|
|
|
|
*/
|
|
|
|
|
public static final int STAGE_POSITION_TOP_OR_LEFT = 0;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Specifies that a stage is positioned at the bottom half of the screen if
|
|
|
|
|
* in portrait mode or at the right half of the screen if in landscape mode.
|
|
|
|
|
*/
|
|
|
|
|
public static final int STAGE_POSITION_BOTTOM_OR_RIGHT = 1;
|
|
|
|
|
|
|
|
|
|
@Retention(SOURCE)
|
|
|
|
|
@IntDef({STAGE_POSITION_UNDEFINED, STAGE_POSITION_TOP_OR_LEFT, STAGE_POSITION_BOTTOM_OR_RIGHT})
|
|
|
|
|
public @interface StagePosition {}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Stage type isn't specified normally meaning to use what ever the default is.
|
|
|
|
|
* E.g. exit split-screen and launch the app in fullscreen.
|
|
|
|
|
*/
|
|
|
|
|
public static final int STAGE_TYPE_UNDEFINED = -1;
|
|
|
|
|
/**
|
|
|
|
|
* The main stage type.
|
|
|
|
|
*/
|
|
|
|
|
public static final int STAGE_TYPE_MAIN = 0;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The side stage type.
|
|
|
|
|
*/
|
|
|
|
|
public static final int STAGE_TYPE_SIDE = 1;
|
|
|
|
|
|
|
|
|
|
@IntDef({STAGE_TYPE_UNDEFINED, STAGE_TYPE_MAIN, STAGE_TYPE_SIDE})
|
|
|
|
|
public @interface StageType {}
|
|
|
|
|
///////////////////////////////////
|
|
|
|
|
|
2021-11-24 12:18:34 +08:00
|
|
|
/**
|
|
|
|
|
* Default split ratio for launching app pair from overview.
|
|
|
|
|
*/
|
|
|
|
|
public static final float DEFAULT_SPLIT_RATIO = 0.5f;
|
|
|
|
|
|
2021-02-22 14:49:27 -08:00
|
|
|
public static class SplitPositionOption {
|
2021-08-25 11:59:43 -07:00
|
|
|
public final int iconResId;
|
|
|
|
|
public final int textResId;
|
2021-02-22 14:49:27 -08:00
|
|
|
@StagePosition
|
2021-08-25 11:59:43 -07:00
|
|
|
public final int stagePosition;
|
2021-02-22 14:49:27 -08:00
|
|
|
|
|
|
|
|
@StageType
|
|
|
|
|
public final int mStageType;
|
|
|
|
|
|
|
|
|
|
public SplitPositionOption(int iconResId, int textResId, int stagePosition, int stageType) {
|
2021-08-25 11:59:43 -07:00
|
|
|
this.iconResId = iconResId;
|
|
|
|
|
this.textResId = textResId;
|
|
|
|
|
this.stagePosition = stagePosition;
|
2021-02-22 14:49:27 -08:00
|
|
|
mStageType = stageType;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-08-05 12:54:58 -07:00
|
|
|
|
2021-10-27 12:39:21 -07:00
|
|
|
/**
|
|
|
|
|
* NOTE: Engineers complained about too little ambiguity in the last survey, so there is a class
|
|
|
|
|
* with the same name/functionality in wm.shell.util (which launcher3 cannot be built against)
|
|
|
|
|
*
|
|
|
|
|
* If you make changes here, consider making the same changes there
|
|
|
|
|
*/
|
2021-08-05 12:54:58 -07:00
|
|
|
public static class StagedSplitBounds {
|
2021-08-25 11:59:43 -07:00
|
|
|
public final Rect leftTopBounds;
|
|
|
|
|
public final Rect rightBottomBounds;
|
2021-09-07 16:50:21 -07:00
|
|
|
/** This rect represents the actual gap between the two apps */
|
|
|
|
|
public final Rect visualDividerBounds;
|
2021-08-24 17:24:49 -07:00
|
|
|
// This class is orientation-agnostic, so we compute both for later use
|
2021-08-25 11:59:43 -07:00
|
|
|
public final float topTaskPercent;
|
|
|
|
|
public final float leftTaskPercent;
|
2021-11-17 08:09:49 +00:00
|
|
|
public final float dividerWidthPercent;
|
|
|
|
|
public final float dividerHeightPercent;
|
2021-09-13 18:00:52 -07:00
|
|
|
/**
|
|
|
|
|
* If {@code true}, that means at the time of creation of this object, the
|
|
|
|
|
* split-screened apps were vertically stacked. This is useful in scenarios like
|
|
|
|
|
* rotation where the bounds won't change, but this variable can indicate what orientation
|
|
|
|
|
* the bounds were originally in
|
|
|
|
|
*/
|
|
|
|
|
public final boolean appsStackedVertically;
|
2022-02-20 17:39:51 -08:00
|
|
|
/**
|
|
|
|
|
* If {@code true}, that means at the time of creation of this object, the phone was in
|
|
|
|
|
* seascape orientation. This is important on devices with insets, because they do not split
|
|
|
|
|
* evenly -- one of the insets must be slightly larger to account for the inset.
|
|
|
|
|
* From landscape, it is the leftTop task that expands slightly.
|
|
|
|
|
* From seascape, it is the rightBottom task that expands slightly.
|
|
|
|
|
*/
|
|
|
|
|
public final boolean initiatedFromSeascape;
|
2021-10-27 12:39:21 -07:00
|
|
|
public final int leftTopTaskId;
|
|
|
|
|
public final int rightBottomTaskId;
|
2021-08-05 12:54:58 -07:00
|
|
|
|
2021-10-27 12:39:21 -07:00
|
|
|
public StagedSplitBounds(Rect leftTopBounds, Rect rightBottomBounds, int leftTopTaskId,
|
|
|
|
|
int rightBottomTaskId) {
|
2021-08-25 11:59:43 -07:00
|
|
|
this.leftTopBounds = leftTopBounds;
|
|
|
|
|
this.rightBottomBounds = rightBottomBounds;
|
2021-10-27 12:39:21 -07:00
|
|
|
this.leftTopTaskId = leftTopTaskId;
|
|
|
|
|
this.rightBottomTaskId = rightBottomTaskId;
|
2021-09-07 16:50:21 -07:00
|
|
|
|
|
|
|
|
if (rightBottomBounds.top > leftTopBounds.top) {
|
|
|
|
|
// vertical apps, horizontal divider
|
|
|
|
|
this.visualDividerBounds = new Rect(leftTopBounds.left, leftTopBounds.bottom,
|
|
|
|
|
leftTopBounds.right, rightBottomBounds.top);
|
2021-09-13 18:00:52 -07:00
|
|
|
appsStackedVertically = true;
|
2022-02-20 17:39:51 -08:00
|
|
|
initiatedFromSeascape = false;
|
2021-09-07 16:50:21 -07:00
|
|
|
} else {
|
|
|
|
|
// horizontal apps, vertical divider
|
|
|
|
|
this.visualDividerBounds = new Rect(leftTopBounds.right, leftTopBounds.top,
|
|
|
|
|
rightBottomBounds.left, leftTopBounds.bottom);
|
2021-09-13 18:00:52 -07:00
|
|
|
appsStackedVertically = false;
|
2022-02-20 17:39:51 -08:00
|
|
|
// The following check is unreliable on devices without insets
|
|
|
|
|
// (initiatedFromSeascape will always be set to false.) This happens to be OK for
|
|
|
|
|
// all our current uses, but should be refactored.
|
|
|
|
|
// TODO: Create a more reliable check, or refactor how splitting works on devices
|
|
|
|
|
// with insets.
|
|
|
|
|
if (rightBottomBounds.width() > leftTopBounds.width()) {
|
|
|
|
|
initiatedFromSeascape = true;
|
|
|
|
|
} else {
|
|
|
|
|
initiatedFromSeascape = false;
|
|
|
|
|
}
|
2021-09-07 16:50:21 -07:00
|
|
|
}
|
|
|
|
|
|
2022-03-30 11:20:28 +00:00
|
|
|
float totalWidth = rightBottomBounds.right - leftTopBounds.left;
|
|
|
|
|
float totalHeight = rightBottomBounds.bottom - leftTopBounds.top;
|
|
|
|
|
leftTaskPercent = leftTopBounds.width() / totalWidth;
|
|
|
|
|
topTaskPercent = leftTopBounds.height() / totalHeight;
|
|
|
|
|
dividerWidthPercent = visualDividerBounds.width() / totalWidth;
|
|
|
|
|
dividerHeightPercent = visualDividerBounds.height() / totalHeight;
|
2021-08-05 12:54:58 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static class StagedSplitTaskPosition {
|
|
|
|
|
public int taskId = -1;
|
|
|
|
|
@StagePosition
|
|
|
|
|
public int stagePosition = STAGE_POSITION_UNDEFINED;
|
|
|
|
|
@StageType
|
|
|
|
|
public int stageType = STAGE_TYPE_UNDEFINED;
|
|
|
|
|
}
|
2021-02-22 14:49:27 -08:00
|
|
|
}
|