Splitscreen for minimized state that works with resizable launchers
If a launcher is resizable, going to minimized mode (dock task and then press home) would show a cropped height of the task at the top in a minimized state and the fullscreen stack would show the home launcher which takes the rest of the remaining height. If the launcher is not resizable, it will default the original behavior. To enable this in a launcher, add android:resizeableActivity="true" in the AndroidManifest.xml in the <application/> tag. Test: manual - rotating while minimized, minimizing using dragging task or holding overview nav button, installing resizable launcher with a non-resizable launcher Fixes: 32504542 Change-Id: Idf4015b40f9bec81b70f146f0f2d7df8ccfb4cf0
This commit is contained in:
@@ -40,8 +40,11 @@ oneway interface IDockedStackListener {
|
||||
*
|
||||
* @param minimized Whether the docked stack is currently minimized.
|
||||
* @param animDuration The duration of the animation for changing the minimized state.
|
||||
* @param isHomeStackResizable If the home stack is resizable, a portion of the docked stack
|
||||
* will be shown with the divider
|
||||
*/
|
||||
void onDockedStackMinimizedChanged(boolean minimized, long animDuration);
|
||||
void onDockedStackMinimizedChanged(boolean minimized, long animDuration,
|
||||
boolean isHomeStackResizable);
|
||||
|
||||
/**
|
||||
* Called when window manager decides to adjust the divider for IME. Like the minimized state,
|
||||
|
||||
@@ -53,6 +53,11 @@ public class DividerSnapAlgorithm {
|
||||
*/
|
||||
private static final int SNAP_ONLY_1_1 = 2;
|
||||
|
||||
/**
|
||||
* 1 snap target: minimized height, (1 - minimized height)
|
||||
*/
|
||||
private static final int SNAP_MODE_MINIMIZED = 3;
|
||||
|
||||
private final float mMinFlingVelocityPxPerSecond;
|
||||
private final float mMinDismissVelocityPxPerSecond;
|
||||
private final int mDisplayWidth;
|
||||
@@ -62,6 +67,7 @@ public class DividerSnapAlgorithm {
|
||||
private final Rect mInsets = new Rect();
|
||||
private final int mSnapMode;
|
||||
private final int mMinimalSizeResizableTask;
|
||||
private final int mTaskHeightInMinimizedMode;
|
||||
private final float mFixedRatio;
|
||||
private boolean mIsHorizontalDivision;
|
||||
|
||||
@@ -93,6 +99,11 @@ public class DividerSnapAlgorithm {
|
||||
|
||||
public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize,
|
||||
boolean isHorizontalDivision, Rect insets) {
|
||||
this(res, displayWidth, displayHeight, dividerSize, isHorizontalDivision, insets, false);
|
||||
}
|
||||
|
||||
public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize,
|
||||
boolean isHorizontalDivision, Rect insets, boolean isMinimizedMode) {
|
||||
mMinFlingVelocityPxPerSecond =
|
||||
MIN_FLING_VELOCITY_DP_PER_SECOND * res.getDisplayMetrics().density;
|
||||
mMinDismissVelocityPxPerSecond =
|
||||
@@ -102,12 +113,14 @@ public class DividerSnapAlgorithm {
|
||||
mDisplayHeight = displayHeight;
|
||||
mIsHorizontalDivision = isHorizontalDivision;
|
||||
mInsets.set(insets);
|
||||
mSnapMode = res.getInteger(
|
||||
com.android.internal.R.integer.config_dockedStackDividerSnapMode);
|
||||
mSnapMode = isMinimizedMode ? SNAP_MODE_MINIMIZED :
|
||||
res.getInteger(com.android.internal.R.integer.config_dockedStackDividerSnapMode);
|
||||
mFixedRatio = res.getFraction(
|
||||
com.android.internal.R.fraction.docked_stack_divider_fixed_ratio, 1, 1);
|
||||
mMinimalSizeResizableTask = res.getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.default_minimal_size_resizable_task);
|
||||
mTaskHeightInMinimizedMode = res.getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.task_height_of_minimized_mode);
|
||||
calculateTargets(isHorizontalDivision);
|
||||
mFirstSplitTarget = mTargets.get(1);
|
||||
mLastSplitTarget = mTargets.get(mTargets.size() - 2);
|
||||
@@ -246,6 +259,7 @@ public class DividerSnapAlgorithm {
|
||||
int dividerMax = isHorizontalDivision
|
||||
? mDisplayHeight
|
||||
: mDisplayWidth;
|
||||
int navBarSize = isHorizontalDivision ? mInsets.bottom : mInsets.right;
|
||||
mTargets.add(new SnapTarget(-mDividerSize, -mDividerSize, SnapTarget.FLAG_DISMISS_START,
|
||||
0.35f));
|
||||
switch (mSnapMode) {
|
||||
@@ -258,8 +272,10 @@ public class DividerSnapAlgorithm {
|
||||
case SNAP_ONLY_1_1:
|
||||
addMiddleTarget(isHorizontalDivision);
|
||||
break;
|
||||
case SNAP_MODE_MINIMIZED:
|
||||
addMinimizedTarget(isHorizontalDivision);
|
||||
break;
|
||||
}
|
||||
int navBarSize = isHorizontalDivision ? mInsets.bottom : mInsets.right;
|
||||
mTargets.add(new SnapTarget(dividerMax - navBarSize, dividerMax,
|
||||
SnapTarget.FLAG_DISMISS_END, 0.35f));
|
||||
}
|
||||
@@ -315,6 +331,12 @@ public class DividerSnapAlgorithm {
|
||||
mTargets.add(new SnapTarget(position, position, SnapTarget.FLAG_NONE));
|
||||
}
|
||||
|
||||
private void addMinimizedTarget(boolean isHorizontalDivision) {
|
||||
int position = mTaskHeightInMinimizedMode;
|
||||
position += isHorizontalDivision ? mInsets.top : mInsets.left;
|
||||
mTargets.add(new SnapTarget(position, position, SnapTarget.FLAG_NONE));
|
||||
}
|
||||
|
||||
public SnapTarget getMiddleTarget() {
|
||||
return mMiddleTarget;
|
||||
}
|
||||
|
||||
@@ -488,6 +488,9 @@
|
||||
<!-- The default minimal size of a resizable task, in both dimensions. -->
|
||||
<dimen name="default_minimal_size_resizable_task">220dp</dimen>
|
||||
|
||||
<!-- Height of a task when in minimized mode from the top when launcher is resizable. -->
|
||||
<dimen name="task_height_of_minimized_mode">80dp</dimen>
|
||||
|
||||
<!-- Minimum "smallest width" of the display for cascading menus to be enabled. -->
|
||||
<dimen name="cascading_menus_min_smallest_width">720dp</dimen>
|
||||
|
||||
|
||||
@@ -1772,6 +1772,7 @@
|
||||
<java-symbol type="id" name="replace_message" />
|
||||
<java-symbol type="fraction" name="config_dimBehindFadeDuration" />
|
||||
<java-symbol type="dimen" name="default_minimal_size_resizable_task" />
|
||||
<java-symbol type="dimen" name="task_height_of_minimized_mode" />
|
||||
<java-symbol type="fraction" name="config_screenAutoBrightnessDozeScaleFactor" />
|
||||
<java-symbol type="fraction" name="config_autoBrightnessAdjustmentMaxGamma" />
|
||||
<java-symbol type="integer" name="config_autoBrightnessAmbientLightHorizon"/>
|
||||
|
||||
@@ -44,6 +44,7 @@ public class Divider extends SystemUI {
|
||||
private boolean mVisible = false;
|
||||
private boolean mMinimized = false;
|
||||
private boolean mAdjustedForIme = false;
|
||||
private boolean mHomeStackResizable = false;
|
||||
private ForcedResizableInfoActivityController mForcedResizableController;
|
||||
|
||||
@Override
|
||||
@@ -75,6 +76,7 @@ public class Divider extends SystemUI {
|
||||
mView = (DividerView)
|
||||
LayoutInflater.from(mContext).inflate(R.layout.docked_stack_divider, null);
|
||||
mView.setVisibility(mVisible ? View.VISIBLE : View.INVISIBLE);
|
||||
mView.setMinimizedDockStack(mMinimized, mHomeStackResizable);
|
||||
final int size = mContext.getResources().getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.docked_stack_divider_thickness);
|
||||
final boolean landscape = configuration.orientation == ORIENTATION_LANDSCAPE;
|
||||
@@ -92,7 +94,7 @@ public class Divider extends SystemUI {
|
||||
removeDivider();
|
||||
addDivider(configuration);
|
||||
if (mMinimized) {
|
||||
mView.setMinimizedDockStack(true);
|
||||
mView.setMinimizedDockStack(true, mHomeStackResizable);
|
||||
updateTouchable();
|
||||
}
|
||||
}
|
||||
@@ -106,13 +108,14 @@ public class Divider extends SystemUI {
|
||||
mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
|
||||
|
||||
// Update state because animations won't finish.
|
||||
mView.setMinimizedDockStack(mMinimized);
|
||||
mView.setMinimizedDockStack(mMinimized, mHomeStackResizable);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateMinimizedDockedStack(final boolean minimized, final long animDuration) {
|
||||
private void updateMinimizedDockedStack(final boolean minimized, final long animDuration,
|
||||
final boolean isHomeStackResizable) {
|
||||
mView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -120,9 +123,9 @@ public class Divider extends SystemUI {
|
||||
mMinimized = minimized;
|
||||
updateTouchable();
|
||||
if (animDuration > 0) {
|
||||
mView.setMinimizedDockStack(minimized, animDuration);
|
||||
mView.setMinimizedDockStack(minimized, animDuration, isHomeStackResizable);
|
||||
} else {
|
||||
mView.setMinimizedDockStack(minimized);
|
||||
mView.setMinimizedDockStack(minimized, isHomeStackResizable);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,7 +142,7 @@ public class Divider extends SystemUI {
|
||||
}
|
||||
|
||||
private void updateTouchable() {
|
||||
mWindowManager.setTouchable(!mMinimized && !mAdjustedForIme);
|
||||
mWindowManager.setTouchable((mHomeStackResizable || !mMinimized) && !mAdjustedForIme);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -162,9 +165,10 @@ public class Divider extends SystemUI {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDockedStackMinimizedChanged(boolean minimized, long animDuration)
|
||||
throws RemoteException {
|
||||
updateMinimizedDockedStack(minimized, animDuration);
|
||||
public void onDockedStackMinimizedChanged(boolean minimized, long animDuration,
|
||||
boolean isHomeStackResizable) throws RemoteException {
|
||||
mHomeStackResizable = isHomeStackResizable;
|
||||
updateMinimizedDockedStack(minimized, animDuration, isHomeStackResizable);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -64,6 +64,7 @@ import com.android.systemui.recents.Recents;
|
||||
import com.android.systemui.recents.events.EventBus;
|
||||
import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
|
||||
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
|
||||
import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
|
||||
import com.android.systemui.recents.events.activity.UndockingTaskEvent;
|
||||
import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
|
||||
import com.android.systemui.recents.events.ui.RecentsGrowingEvent;
|
||||
@@ -123,6 +124,8 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
private boolean mMoving;
|
||||
private int mTouchSlop;
|
||||
private boolean mBackgroundLifted;
|
||||
private boolean mIsInMinimizeInteraction;
|
||||
private int mDividerPositionBeforeMinimized;
|
||||
|
||||
private int mDividerInsets;
|
||||
private int mDisplayWidth;
|
||||
@@ -145,6 +148,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
private VelocityTracker mVelocityTracker;
|
||||
private FlingAnimationUtils mFlingAnimationUtils;
|
||||
private DividerSnapAlgorithm mSnapAlgorithm;
|
||||
private DividerSnapAlgorithm mMinimizedSnapAlgorithm;
|
||||
private final Rect mStableInsets = new Rect();
|
||||
|
||||
private boolean mGrowRecents;
|
||||
@@ -154,6 +158,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
private int mExitStartPosition;
|
||||
private GestureDetector mGestureDetector;
|
||||
private boolean mDockedStackMinimized;
|
||||
private boolean mHomeStackResizable;
|
||||
private boolean mAdjustedForIme;
|
||||
private DividerState mState;
|
||||
|
||||
@@ -350,8 +355,9 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
|| mStableInsets.bottom != insets.getStableInsetBottom()) {
|
||||
mStableInsets.set(insets.getStableInsetLeft(), insets.getStableInsetTop(),
|
||||
insets.getStableInsetRight(), insets.getStableInsetBottom());
|
||||
if (mSnapAlgorithm != null) {
|
||||
if (mSnapAlgorithm != null || mMinimizedSnapAlgorithm != null) {
|
||||
mSnapAlgorithm = null;
|
||||
mMinimizedSnapAlgorithm = null;
|
||||
initializeSnapAlgorithm();
|
||||
}
|
||||
}
|
||||
@@ -446,11 +452,17 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
mSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(), mDisplayWidth,
|
||||
mDisplayHeight, mDividerSize, isHorizontalDivision(), mStableInsets);
|
||||
}
|
||||
if (mMinimizedSnapAlgorithm == null) {
|
||||
mMinimizedSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(),
|
||||
mDisplayWidth, mDisplayHeight, mDividerSize, isHorizontalDivision(),
|
||||
mStableInsets, mDockedStackMinimized && mHomeStackResizable);
|
||||
}
|
||||
}
|
||||
|
||||
public DividerSnapAlgorithm getSnapAlgorithm() {
|
||||
initializeSnapAlgorithm();
|
||||
return mSnapAlgorithm;
|
||||
return mDockedStackMinimized && mHomeStackResizable ? mMinimizedSnapAlgorithm :
|
||||
mSnapAlgorithm;
|
||||
}
|
||||
|
||||
public int getCurrentPosition() {
|
||||
@@ -495,7 +507,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
mMoving = true;
|
||||
}
|
||||
if (mMoving && mDockSide != WindowManager.DOCKED_INVALID) {
|
||||
SnapTarget snapTarget = mSnapAlgorithm.calculateSnapTarget(
|
||||
SnapTarget snapTarget = getSnapAlgorithm().calculateSnapTarget(
|
||||
mStartPosition, 0 /* velocity */, false /* hardDismiss */);
|
||||
resizeStackDelayed(calculatePosition(x, y), mStartPosition, snapTarget);
|
||||
}
|
||||
@@ -551,9 +563,10 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
|
||||
private void fling(int position, float velocity, boolean avoidDismissStart,
|
||||
boolean logMetrics) {
|
||||
SnapTarget snapTarget = mSnapAlgorithm.calculateSnapTarget(position, velocity);
|
||||
if (avoidDismissStart && snapTarget == mSnapAlgorithm.getDismissStartTarget()) {
|
||||
snapTarget = mSnapAlgorithm.getFirstSplitTarget();
|
||||
DividerSnapAlgorithm currentSnapAlgorithm = getSnapAlgorithm();
|
||||
SnapTarget snapTarget = currentSnapAlgorithm.calculateSnapTarget(position, velocity);
|
||||
if (avoidDismissStart && snapTarget == currentSnapAlgorithm.getDismissStartTarget()) {
|
||||
snapTarget = currentSnapAlgorithm.getFirstSplitTarget();
|
||||
}
|
||||
if (logMetrics) {
|
||||
logResizeEvent(snapTarget);
|
||||
@@ -574,6 +587,10 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
|
||||
private ValueAnimator getFlingAnimator(int position, final SnapTarget snapTarget,
|
||||
final long endDelay) {
|
||||
if (mCurrentAnimator != null) {
|
||||
cancelFlingAnimation();
|
||||
updateDockSide();
|
||||
}
|
||||
final boolean taskPositionSameAtEnd = snapTarget.flag == SnapTarget.FLAG_NONE;
|
||||
ValueAnimator anim = ValueAnimator.ofInt(position, snapTarget.position);
|
||||
anim.addUpdateListener(animation -> resizeStackDelayed((int) animation.getAnimatedValue(),
|
||||
@@ -590,6 +607,12 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
mExitAnimationRunning = false;
|
||||
EventBus.getDefault().send(new StoppedDragingEvent());
|
||||
};
|
||||
Runnable notCancelledEndAction = () -> {
|
||||
// Reset minimized divider position after unminimized state animation finishes
|
||||
if (!mDockedStackMinimized && mIsInMinimizeInteraction) {
|
||||
mIsInMinimizeInteraction = false;
|
||||
}
|
||||
};
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
|
||||
private boolean mCancelled;
|
||||
@@ -612,8 +635,14 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
}
|
||||
if (delay == 0) {
|
||||
endAction.run();
|
||||
if (!mCancelled) {
|
||||
notCancelledEndAction.run();
|
||||
}
|
||||
} else {
|
||||
mHandler.postDelayed(endAction, delay);
|
||||
if (!mCancelled) {
|
||||
mHandler.postDelayed(notCancelledEndAction, delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -692,57 +721,92 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
}
|
||||
|
||||
|
||||
public void setMinimizedDockStack(boolean minimized) {
|
||||
public void setMinimizedDockStack(boolean minimized, boolean isHomeStackResizable) {
|
||||
mHomeStackResizable = isHomeStackResizable;
|
||||
updateDockSide();
|
||||
mHandle.setAlpha(minimized ? 0f : 1f);
|
||||
if (!minimized) {
|
||||
resetBackground();
|
||||
} else if (mDockSide == WindowManager.DOCKED_TOP) {
|
||||
mBackground.setPivotY(0);
|
||||
mBackground.setScaleY(MINIMIZE_DOCK_SCALE);
|
||||
} else if (mDockSide == WindowManager.DOCKED_LEFT
|
||||
|| mDockSide == WindowManager.DOCKED_RIGHT) {
|
||||
mBackground.setPivotX(mDockSide == WindowManager.DOCKED_LEFT
|
||||
? 0
|
||||
: mBackground.getWidth());
|
||||
mBackground.setScaleX(MINIMIZE_DOCK_SCALE);
|
||||
} else if (!isHomeStackResizable) {
|
||||
if (mDockSide == WindowManager.DOCKED_TOP) {
|
||||
mBackground.setPivotY(0);
|
||||
mBackground.setScaleY(MINIMIZE_DOCK_SCALE);
|
||||
} else if (mDockSide == WindowManager.DOCKED_LEFT
|
||||
|| mDockSide == WindowManager.DOCKED_RIGHT) {
|
||||
mBackground.setPivotX(mDockSide == WindowManager.DOCKED_LEFT
|
||||
? 0
|
||||
: mBackground.getWidth());
|
||||
mBackground.setScaleX(MINIMIZE_DOCK_SCALE);
|
||||
}
|
||||
}
|
||||
mMinimizedShadow.setAlpha(minimized ? 1f : 0f);
|
||||
mDockedStackMinimized = minimized;
|
||||
if (!isHomeStackResizable) {
|
||||
mHandle.setAlpha(minimized ? 0f : 1f);
|
||||
mDockedStackMinimized = minimized;
|
||||
} else if (mDockedStackMinimized != minimized) {
|
||||
if (mStableInsets.isEmpty()) {
|
||||
SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
|
||||
}
|
||||
if (!mIsInMinimizeInteraction && minimized) {
|
||||
mIsInMinimizeInteraction = true;
|
||||
mDividerPositionBeforeMinimized = DockedDividerUtils.calculateMiddlePosition(
|
||||
isHorizontalDivision(), mStableInsets, mDisplayWidth, mDisplayHeight,
|
||||
mDividerSize);
|
||||
}
|
||||
mMinimizedSnapAlgorithm = null;
|
||||
mDockedStackMinimized = minimized;
|
||||
initializeSnapAlgorithm();
|
||||
}
|
||||
}
|
||||
|
||||
public void setMinimizedDockStack(boolean minimized, long animDuration) {
|
||||
public void setMinimizedDockStack(boolean minimized, long animDuration,
|
||||
boolean isHomeStackResizable) {
|
||||
mHomeStackResizable = isHomeStackResizable;
|
||||
updateDockSide();
|
||||
mHandle.animate()
|
||||
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
|
||||
.setDuration(animDuration)
|
||||
.alpha(minimized ? 0f : 1f)
|
||||
.start();
|
||||
if (mDockSide == WindowManager.DOCKED_TOP) {
|
||||
mBackground.setPivotY(0);
|
||||
mBackground.animate()
|
||||
.scaleY(minimized ? MINIMIZE_DOCK_SCALE : 1f);
|
||||
} else if (mDockSide == WindowManager.DOCKED_LEFT
|
||||
|| mDockSide == WindowManager.DOCKED_RIGHT) {
|
||||
mBackground.setPivotX(mDockSide == WindowManager.DOCKED_LEFT
|
||||
? 0
|
||||
: mBackground.getWidth());
|
||||
mBackground.animate()
|
||||
.scaleX(minimized ? MINIMIZE_DOCK_SCALE : 1f);
|
||||
if (!isHomeStackResizable) {
|
||||
mMinimizedShadow.animate()
|
||||
.alpha(minimized ? 1f : 0f)
|
||||
.setInterpolator(Interpolators.ALPHA_IN)
|
||||
.setDuration(animDuration)
|
||||
.start();
|
||||
mHandle.animate()
|
||||
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
|
||||
.setDuration(animDuration)
|
||||
.alpha(minimized ? 0f : 1f)
|
||||
.start();
|
||||
if (mDockSide == WindowManager.DOCKED_TOP) {
|
||||
mBackground.setPivotY(0);
|
||||
mBackground.animate()
|
||||
.scaleY(minimized ? MINIMIZE_DOCK_SCALE : 1f);
|
||||
} else if (mDockSide == WindowManager.DOCKED_LEFT
|
||||
|| mDockSide == WindowManager.DOCKED_RIGHT) {
|
||||
mBackground.setPivotX(mDockSide == WindowManager.DOCKED_LEFT
|
||||
? 0
|
||||
: mBackground.getWidth());
|
||||
mBackground.animate()
|
||||
.scaleX(minimized ? MINIMIZE_DOCK_SCALE : 1f);
|
||||
}
|
||||
mDockedStackMinimized = minimized;
|
||||
} else if (mDockedStackMinimized != minimized) {
|
||||
mIsInMinimizeInteraction = true;
|
||||
if (minimized) {
|
||||
mDividerPositionBeforeMinimized = getCurrentPosition();
|
||||
}
|
||||
mMinimizedSnapAlgorithm = null;
|
||||
mDockedStackMinimized = minimized;
|
||||
initializeSnapAlgorithm();
|
||||
stopDragging(getCurrentPosition(), minimized ?
|
||||
mMinimizedSnapAlgorithm.getMiddleTarget() :
|
||||
mSnapAlgorithm.calculateNonDismissingSnapTarget(
|
||||
mDividerPositionBeforeMinimized),
|
||||
animDuration, Interpolators.FAST_OUT_SLOW_IN, 0);
|
||||
}
|
||||
if (!minimized) {
|
||||
mBackground.animate().withEndAction(mResetBackgroundRunnable);
|
||||
}
|
||||
mMinimizedShadow.animate()
|
||||
.alpha(minimized ? 1f : 0f)
|
||||
.setInterpolator(Interpolators.ALPHA_IN)
|
||||
.setDuration(animDuration)
|
||||
.start();
|
||||
mBackground.animate()
|
||||
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
|
||||
.setDuration(animDuration)
|
||||
.start();
|
||||
mDockedStackMinimized = minimized;
|
||||
}
|
||||
|
||||
public void setAdjustedForIme(boolean adjustedForIme) {
|
||||
@@ -809,6 +873,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
mDisplayWidth = info.logicalWidth;
|
||||
mDisplayHeight = info.logicalHeight;
|
||||
mSnapAlgorithm = null;
|
||||
mMinimizedSnapAlgorithm = null;
|
||||
initializeSnapAlgorithm();
|
||||
}
|
||||
|
||||
@@ -871,6 +936,15 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
}
|
||||
|
||||
mLastResizeRect.set(mDockedRect);
|
||||
if (mHomeStackResizable && mIsInMinimizeInteraction) {
|
||||
calculateBoundsForPosition(mDividerPositionBeforeMinimized, mDockSide, mDockedTaskRect);
|
||||
calculateBoundsForPosition(mDividerPositionBeforeMinimized,
|
||||
DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect);
|
||||
mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, mDockedTaskRect,
|
||||
mOtherTaskRect, null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mEntranceAnimationRunning && taskPosition != TASK_POSITION_SAME) {
|
||||
if (mCurrentAnimator != null) {
|
||||
calculateBoundsForPosition(taskPosition, mDockSide, mDockedTaskRect);
|
||||
@@ -922,7 +996,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
} else {
|
||||
mWindowManagerProxy.resizeDockedStack(mDockedRect, null, null, null, null);
|
||||
}
|
||||
SnapTarget closestDismissTarget = mSnapAlgorithm.getClosestDismissTarget(position);
|
||||
SnapTarget closestDismissTarget = getSnapAlgorithm().getClosestDismissTarget(position);
|
||||
float dimFraction = getDimFraction(position, closestDismissTarget);
|
||||
mWindowManagerProxy.setResizeDimLayer(dimFraction != 0f,
|
||||
getStackIdForDismissTarget(closestDismissTarget),
|
||||
@@ -943,7 +1017,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
if (mEntranceAnimationRunning) {
|
||||
return 0f;
|
||||
}
|
||||
float fraction = mSnapAlgorithm.calculateDismissingFraction(position);
|
||||
float fraction = getSnapAlgorithm().calculateDismissingFraction(position);
|
||||
fraction = Math.max(0, Math.min(fraction, 1f));
|
||||
fraction = DIM_INTERPOLATOR.getInterpolation(fraction);
|
||||
if (hasInsetsAtDismissTarget(dismissTarget)) {
|
||||
@@ -959,13 +1033,13 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
*/
|
||||
private boolean hasInsetsAtDismissTarget(SnapTarget dismissTarget) {
|
||||
if (isHorizontalDivision()) {
|
||||
if (dismissTarget == mSnapAlgorithm.getDismissStartTarget()) {
|
||||
if (dismissTarget == getSnapAlgorithm().getDismissStartTarget()) {
|
||||
return mStableInsets.top != 0;
|
||||
} else {
|
||||
return mStableInsets.bottom != 0;
|
||||
}
|
||||
} else {
|
||||
if (dismissTarget == mSnapAlgorithm.getDismissStartTarget()) {
|
||||
if (dismissTarget == getSnapAlgorithm().getDismissStartTarget()) {
|
||||
return mStableInsets.left != 0;
|
||||
} else {
|
||||
return mStableInsets.right != 0;
|
||||
@@ -1135,6 +1209,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
if (mStableInsets.isEmpty()) {
|
||||
SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
|
||||
mSnapAlgorithm = null;
|
||||
mMinimizedSnapAlgorithm = null;
|
||||
initializeSnapAlgorithm();
|
||||
}
|
||||
|
||||
|
||||
@@ -553,8 +553,8 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDockedStackMinimizedChanged(boolean minimized, long animDuration)
|
||||
throws RemoteException {
|
||||
public void onDockedStackMinimizedChanged(boolean minimized, long animDuration,
|
||||
boolean isHomeStackResizable) throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19598,10 +19598,15 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
|
||||
/** Helper method that requests bounds from WM and applies them to stack. */
|
||||
private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
|
||||
final Rect newBounds = mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration();
|
||||
final Rect newStackBounds = new Rect();
|
||||
final Rect newTempTaskBounds = new Rect();
|
||||
mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds,
|
||||
newTempTaskBounds);
|
||||
mStackSupervisor.resizeStackLocked(
|
||||
stackId, newBounds, null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
|
||||
false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
|
||||
stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
|
||||
!newTempTaskBounds.isEmpty() ? newTempTaskBounds : null /* tempTaskBounds */,
|
||||
null /* tempTaskInsetBounds */, false /* preserveWindows */,
|
||||
false /* allowResizeInDockedMode */, deferResume);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -542,8 +542,10 @@ final class ActivityStack extends ConfigurationContainer implements StackWindowL
|
||||
mWindowContainerController.setPictureInPictureAspectRatio(aspectRatio);
|
||||
}
|
||||
|
||||
void getStackDockedModeBounds(Rect outBounds, boolean ignoreVisibility) {
|
||||
mWindowContainerController.getStackDockedModeBounds(outBounds, ignoreVisibility);
|
||||
void getStackDockedModeBounds(Rect outBounds, Rect outTempBounds, Rect outTempInsetBounds,
|
||||
boolean ignoreVisibility) {
|
||||
mWindowContainerController.getStackDockedModeBounds(outBounds, outTempBounds,
|
||||
outTempInsetBounds, ignoreVisibility);
|
||||
}
|
||||
|
||||
void prepareFreezingTaskBounds() {
|
||||
@@ -562,8 +564,8 @@ final class ActivityStack extends ConfigurationContainer implements StackWindowL
|
||||
outBounds.setEmpty();
|
||||
}
|
||||
|
||||
Rect getBoundsForNewConfiguration() {
|
||||
return mWindowContainerController.getBoundsForNewConfiguration();
|
||||
void getBoundsForNewConfiguration(Rect outBounds, Rect outTempBounds) {
|
||||
mWindowContainerController.getBoundsForNewConfiguration(outBounds, outTempBounds);
|
||||
}
|
||||
|
||||
void positionChildWindowContainerAtTop(TaskRecord child) {
|
||||
|
||||
@@ -418,8 +418,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
|
||||
|
||||
final ActivityMetricsLogger mActivityMetricsLogger;
|
||||
|
||||
private final ResizeDockedStackTimeout mResizeDockedStackTimeout;
|
||||
|
||||
@Override
|
||||
protected int getChildCount() {
|
||||
return mActivityDisplays.size();
|
||||
@@ -529,7 +527,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
|
||||
mService = service;
|
||||
mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
|
||||
mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext);
|
||||
mResizeDockedStackTimeout = new ResizeDockedStackTimeout(service, this, mHandler);
|
||||
mKeyguardController = new KeyguardController(service, this);
|
||||
}
|
||||
|
||||
@@ -2346,13 +2343,19 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
|
||||
// static stacks need to be adjusted so they don't overlap with the docked stack.
|
||||
// We get the bounds to use from window manager which has been adjusted for any
|
||||
// screen controls and is also the same for all stacks.
|
||||
final Rect tempOtherTaskRect = new Rect();
|
||||
final Rect tempOtherTaskInsetRect = new Rect();
|
||||
for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
|
||||
final ActivityStack current = getStack(i);
|
||||
if (current != null && StackId.isResizeableByDockedStack(i)) {
|
||||
current.getStackDockedModeBounds(tempRect, true /* ignoreVisibility */);
|
||||
resizeStackLocked(i, tempRect, tempOtherTaskBounds,
|
||||
tempOtherTaskInsetBounds, preserveWindows,
|
||||
true /* allowResizeInDockedMode */, deferResume);
|
||||
current.getStackDockedModeBounds(tempRect, tempOtherTaskRect,
|
||||
tempOtherTaskInsetRect, true /* ignoreVisibility */);
|
||||
resizeStackLocked(i, tempRect,
|
||||
!tempOtherTaskRect.isEmpty() ? tempOtherTaskRect :
|
||||
tempOtherTaskBounds,
|
||||
!tempOtherTaskInsetRect.isEmpty() ? tempOtherTaskInsetRect :
|
||||
tempOtherTaskInsetBounds,
|
||||
preserveWindows, true /* allowResizeInDockedMode */, deferResume);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2364,12 +2367,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
|
||||
mWindowManager.continueSurfaceLayout();
|
||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||
}
|
||||
|
||||
mResizeDockedStackTimeout.notifyResizing(dockedBounds,
|
||||
tempDockedTaskBounds != null
|
||||
|| tempDockedTaskInsetBounds != null
|
||||
|| tempOtherTaskBounds != null
|
||||
|| tempOtherTaskInsetBounds != null);
|
||||
}
|
||||
|
||||
void resizePinnedStackLocked(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.server.am;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
|
||||
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
|
||||
|
||||
/**
|
||||
* When resizing the docked stack, a caller can temporarily supply task bounds that are different
|
||||
* from the stack bounds. In order to return to a sane state if the caller crashes or has a bug,
|
||||
* this class manages this cycle.
|
||||
*/
|
||||
class ResizeDockedStackTimeout {
|
||||
|
||||
private static final long TIMEOUT_MS = 10 * 1000;
|
||||
private final ActivityManagerService mService;
|
||||
private final ActivityStackSupervisor mSupervisor;
|
||||
private final Handler mHandler;
|
||||
private final Rect mCurrentDockedBounds = new Rect();
|
||||
|
||||
private final Runnable mTimeoutRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (mService) {
|
||||
mSupervisor.resizeDockedStackLocked(mCurrentDockedBounds, null, null, null, null,
|
||||
PRESERVE_WINDOWS);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ResizeDockedStackTimeout(ActivityManagerService service, ActivityStackSupervisor supervisor,
|
||||
Handler handler) {
|
||||
mService = service;
|
||||
mSupervisor = supervisor;
|
||||
mHandler = handler;
|
||||
}
|
||||
|
||||
void notifyResizing(Rect dockedBounds, boolean hasTempBounds) {
|
||||
mHandler.removeCallbacks(mTimeoutRunnable);
|
||||
if (!hasTempBounds) {
|
||||
return;
|
||||
}
|
||||
mCurrentDockedBounds.set(dockedBounds);
|
||||
mHandler.postDelayed(mTimeoutRunnable, TIMEOUT_MS);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -102,12 +102,14 @@ public class DockedStackDividerController implements DimLayerUser {
|
||||
private int mDividerWindowWidth;
|
||||
private int mDividerWindowWidthInactive;
|
||||
private int mDividerInsets;
|
||||
private int mTaskHeightInMinimizedMode;
|
||||
private boolean mResizing;
|
||||
private WindowState mWindow;
|
||||
private final Rect mTmpRect = new Rect();
|
||||
private final Rect mTmpRect2 = new Rect();
|
||||
private final Rect mTmpRect3 = new Rect();
|
||||
private final Rect mLastRect = new Rect();
|
||||
private final Rect mMiddlePositionDockedStackRect = new Rect();
|
||||
private boolean mLastVisibility = false;
|
||||
private final RemoteCallbackList<IDockedStackListener> mDockedStackListeners
|
||||
= new RemoteCallbackList<>();
|
||||
@@ -189,6 +191,40 @@ public class DockedStackDividerController implements DimLayerUser {
|
||||
return (int) (minWidth / mDisplayContent.getDisplayMetrics().density);
|
||||
}
|
||||
|
||||
/**
|
||||
* The middlePositionDockedStackRect is half the screen area that sits at the top (portrait) or
|
||||
* left (landscape).
|
||||
*
|
||||
* @return fixed rect for temp stack
|
||||
*/
|
||||
Rect getMiddlePositionDockedStackRect() {
|
||||
return mMinimizedDock && isHomeStackResizable() ? mMiddlePositionDockedStackRect : null;
|
||||
}
|
||||
|
||||
void getHomeStackBoundsInDockedMode(Rect outBounds) {
|
||||
final DisplayInfo di = mDisplayContent.getDisplayInfo();
|
||||
mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
|
||||
mTmpRect);
|
||||
int dividerSize = mDividerWindowWidth - 2 * mDividerInsets;
|
||||
Configuration configuration = mDisplayContent.getConfiguration();
|
||||
if (configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
outBounds.set(0, mTaskHeightInMinimizedMode + dividerSize + mTmpRect.top,
|
||||
di.logicalWidth, di.logicalHeight);
|
||||
} else {
|
||||
outBounds.set(mTaskHeightInMinimizedMode + dividerSize + mTmpRect.left, 0,
|
||||
di.logicalWidth, di.logicalHeight);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isHomeStackResizable() {
|
||||
final TaskStack homeStack = mDisplayContent.getHomeStack();
|
||||
if (homeStack == null) {
|
||||
return false;
|
||||
}
|
||||
final Task homeTask = homeStack.findHomeTask();
|
||||
return homeTask != null && homeTask.isResizeable();
|
||||
}
|
||||
|
||||
private void initSnapAlgorithmForRotations() {
|
||||
final Configuration baseConfig = mDisplayContent.getConfiguration();
|
||||
|
||||
@@ -228,11 +264,34 @@ public class DockedStackDividerController implements DimLayerUser {
|
||||
com.android.internal.R.dimen.docked_stack_divider_insets);
|
||||
mDividerWindowWidthInactive = WindowManagerService.dipToPixel(
|
||||
DIVIDER_WIDTH_INACTIVE_DP, mDisplayContent.getDisplayMetrics());
|
||||
mTaskHeightInMinimizedMode = context.getResources().getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.task_height_of_minimized_mode);
|
||||
initSnapAlgorithmForRotations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the constant rects {@link mMiddlePositionDockedStackRect} based on orientation,
|
||||
* stable insets and display size.
|
||||
*/
|
||||
private void updateConstantRects() {
|
||||
final DisplayInfo di = mDisplayContent.getDisplayInfo();
|
||||
mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
|
||||
mTmpRect);
|
||||
int dividerSize = mDividerWindowWidth - 2 * mDividerInsets;
|
||||
Configuration configuration = mDisplayContent.getConfiguration();
|
||||
boolean isHorizontal = configuration.orientation == Configuration.ORIENTATION_PORTRAIT;
|
||||
int middlePosition = DockedDividerUtils.calculateMiddlePosition(isHorizontal, mTmpRect,
|
||||
di.logicalWidth, di.logicalHeight, dividerSize);
|
||||
if (isHorizontal) {
|
||||
mMiddlePositionDockedStackRect.set(0, 0, di.logicalWidth, middlePosition);
|
||||
} else {
|
||||
mMiddlePositionDockedStackRect.set(0, 0, middlePosition, di.logicalHeight);
|
||||
}
|
||||
}
|
||||
|
||||
void onConfigurationChanged() {
|
||||
loadDimens();
|
||||
updateConstantRects();
|
||||
}
|
||||
|
||||
boolean isResizing() {
|
||||
@@ -412,7 +471,19 @@ public class DockedStackDividerController implements DimLayerUser {
|
||||
return mImeHideRequested;
|
||||
}
|
||||
|
||||
private void notifyDockedStackMinimizedChanged(boolean minimizedDock, long animDuration) {
|
||||
private void notifyDockedStackMinimizedChanged(boolean minimizedDock, boolean animate,
|
||||
boolean isHomeStackResizable) {
|
||||
long animDuration = 0;
|
||||
if (animate) {
|
||||
final TaskStack stack = mDisplayContent.getStackById(DOCKED_STACK_ID);
|
||||
final long transitionDuration = isAnimationMaximizing()
|
||||
? mService.mAppTransition.getLastClipRevealTransitionDuration()
|
||||
: DEFAULT_APP_TRANSITION_DURATION;
|
||||
mAnimationDuration = (long)
|
||||
(transitionDuration * mService.getTransitionAnimationScaleLocked());
|
||||
mMaximizeMeetFraction = getClipRevealMeetFraction(stack);
|
||||
animDuration = (long) (mAnimationDuration * mMaximizeMeetFraction);
|
||||
}
|
||||
mService.mH.removeMessages(NOTIFY_DOCKED_STACK_MINIMIZED_CHANGED);
|
||||
mService.mH.obtainMessage(NOTIFY_DOCKED_STACK_MINIMIZED_CHANGED,
|
||||
minimizedDock ? 1 : 0, 0).sendToTarget();
|
||||
@@ -420,7 +491,8 @@ public class DockedStackDividerController implements DimLayerUser {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
final IDockedStackListener listener = mDockedStackListeners.getBroadcastItem(i);
|
||||
try {
|
||||
listener.onDockedStackMinimizedChanged(minimizedDock, animDuration);
|
||||
listener.onDockedStackMinimizedChanged(minimizedDock, animDuration,
|
||||
isHomeStackResizable);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG_WM, "Error delivering minimized dock changed event.", e);
|
||||
}
|
||||
@@ -458,7 +530,8 @@ public class DockedStackDividerController implements DimLayerUser {
|
||||
mDockedStackListeners.register(listener);
|
||||
notifyDockedDividerVisibilityChanged(wasVisible());
|
||||
notifyDockedStackExistsChanged(mDisplayContent.getDockedStackIgnoringVisibility() != null);
|
||||
notifyDockedStackMinimizedChanged(mMinimizedDock, 0 /* animDuration */);
|
||||
notifyDockedStackMinimizedChanged(mMinimizedDock, false /* animate */,
|
||||
isHomeStackResizable());
|
||||
notifyAdjustedForImeChanged(mAdjustedForIme, 0 /* animDuration */);
|
||||
|
||||
}
|
||||
@@ -577,17 +650,23 @@ public class DockedStackDividerController implements DimLayerUser {
|
||||
|
||||
final boolean imeChanged = clearImeAdjustAnimation();
|
||||
boolean minimizedChange = false;
|
||||
if (minimizedDock) {
|
||||
if (animate) {
|
||||
startAdjustAnimation(0f, 1f);
|
||||
} else {
|
||||
minimizedChange |= setMinimizedDockedStack(true);
|
||||
}
|
||||
if (isHomeStackResizable()) {
|
||||
notifyDockedStackMinimizedChanged(minimizedDock, true /* animate */,
|
||||
true /* isHomeStackResizable */);
|
||||
minimizedChange = true;
|
||||
} else {
|
||||
if (animate) {
|
||||
startAdjustAnimation(1f, 0f);
|
||||
if (minimizedDock) {
|
||||
if (animate) {
|
||||
startAdjustAnimation(0f, 1f);
|
||||
} else {
|
||||
minimizedChange |= setMinimizedDockedStack(true);
|
||||
}
|
||||
} else {
|
||||
minimizedChange |= setMinimizedDockedStack(false);
|
||||
if (animate) {
|
||||
startAdjustAnimation(1f, 0f);
|
||||
} else {
|
||||
minimizedChange |= setMinimizedDockedStack(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (imeChanged || minimizedChange) {
|
||||
@@ -688,7 +767,7 @@ public class DockedStackDividerController implements DimLayerUser {
|
||||
|
||||
private boolean setMinimizedDockedStack(boolean minimized) {
|
||||
final TaskStack stack = mDisplayContent.getDockedStackIgnoringVisibility();
|
||||
notifyDockedStackMinimizedChanged(minimized, 0);
|
||||
notifyDockedStackMinimizedChanged(minimized, false /* animate */, isHomeStackResizable());
|
||||
return stack != null && stack.setAdjustedForMinimizedDock(minimized ? 1f : 0f);
|
||||
}
|
||||
|
||||
@@ -742,14 +821,8 @@ public class DockedStackDividerController implements DimLayerUser {
|
||||
if (!mAnimationStarted) {
|
||||
mAnimationStarted = true;
|
||||
mAnimationStartTime = now;
|
||||
final long transitionDuration = isAnimationMaximizing()
|
||||
? mService.mAppTransition.getLastClipRevealTransitionDuration()
|
||||
: DEFAULT_APP_TRANSITION_DURATION;
|
||||
mAnimationDuration = (long)
|
||||
(transitionDuration * mService.getTransitionAnimationScaleLocked());
|
||||
mMaximizeMeetFraction = getClipRevealMeetFraction(stack);
|
||||
notifyDockedStackMinimizedChanged(mMinimizedDock,
|
||||
(long) (mAnimationDuration * mMaximizeMeetFraction));
|
||||
notifyDockedStackMinimizedChanged(mMinimizedDock, true /* animate */,
|
||||
isHomeStackResizable() /* isHomeStackResizable */);
|
||||
}
|
||||
float t = Math.min(1f, (float) (now - mAnimationStartTime) / mAnimationDuration);
|
||||
t = (isAnimationMaximizing() ? TOUCH_RESPONSE_INTERPOLATOR : mMinimizedDockInterpolator)
|
||||
|
||||
@@ -619,7 +619,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
|
||||
final InputChannel inputChannel = w.mInputChannel;
|
||||
final InputWindowHandle inputWindowHandle = w.mInputWindowHandle;
|
||||
if (inputChannel == null || inputWindowHandle == null || w.mRemoved
|
||||
|| w.isAdjustedForMinimizedDock()) {
|
||||
|| w.canReceiveTouchInput()) {
|
||||
// Skip this window because it cannot possibly receive input.
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -220,13 +220,17 @@ public class StackWindowController
|
||||
}
|
||||
}
|
||||
|
||||
public void getStackDockedModeBounds(Rect outBounds, boolean ignoreVisibility) {
|
||||
public void getStackDockedModeBounds(Rect outBounds, Rect outTempBounds,
|
||||
Rect outTempInsetBounds, boolean ignoreVisibility) {
|
||||
synchronized (mWindowMap) {
|
||||
if (mContainer != null) {
|
||||
mContainer.getStackDockedModeBoundsLocked(outBounds, ignoreVisibility);
|
||||
mContainer.getStackDockedModeBoundsLocked(outBounds, outTempBounds,
|
||||
outTempInsetBounds, ignoreVisibility);
|
||||
return;
|
||||
}
|
||||
outBounds.setEmpty();
|
||||
outTempBounds.setEmpty();
|
||||
outTempInsetBounds.setEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,11 +273,9 @@ public class StackWindowController
|
||||
}
|
||||
}
|
||||
|
||||
public Rect getBoundsForNewConfiguration() {
|
||||
public void getBoundsForNewConfiguration(Rect outBounds, Rect outTempBounds) {
|
||||
synchronized(mWindowMap) {
|
||||
final Rect outBounds = new Rect();
|
||||
mContainer.getBoundsForNewConfiguration(outBounds);
|
||||
return outBounds;
|
||||
mContainer.getBoundsForNewConfiguration(outBounds, outTempBounds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye
|
||||
mAdjustedBounds.set(bounds);
|
||||
final boolean adjusted = !mAdjustedBounds.isEmpty();
|
||||
Rect insetBounds = null;
|
||||
if (adjusted && isAdjustedForMinimizedDock()) {
|
||||
if (adjusted && isAdjustedForMinimizedDockedStack()) {
|
||||
insetBounds = mBounds;
|
||||
} else if (adjusted && mAdjustedForIme) {
|
||||
if (mImeGoingAway) {
|
||||
@@ -420,9 +420,14 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye
|
||||
return true;
|
||||
}
|
||||
|
||||
void getBoundsForNewConfiguration(Rect outBounds) {
|
||||
void getBoundsForNewConfiguration(Rect outBounds, Rect outTempBounds) {
|
||||
outBounds.set(mBoundsAfterRotation);
|
||||
mBoundsAfterRotation.setEmpty();
|
||||
final DockedStackDividerController controller = getDisplayContent()
|
||||
.mDividerControllerLocked;
|
||||
if (controller.isMinimizedDock() && mStackId == DOCKED_STACK_ID) {
|
||||
outTempBounds.set(controller.getMiddlePositionDockedStackRect());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -482,7 +487,8 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye
|
||||
mService.mPolicy.getStableInsetsLw(rotation, displayWidth, displayHeight, outBounds);
|
||||
final DividerSnapAlgorithm algorithm = new DividerSnapAlgorithm(
|
||||
mService.mContext.getResources(), displayWidth, displayHeight,
|
||||
dividerSize, orientation == Configuration.ORIENTATION_PORTRAIT, outBounds);
|
||||
dividerSize, orientation == Configuration.ORIENTATION_PORTRAIT, outBounds,
|
||||
isMinimizedDockAndHomeStackResizable());
|
||||
final SnapTarget target = algorithm.calculateNonDismissingSnapTarget(dividerPosition);
|
||||
|
||||
// Recalculate the bounds based on the position of the target.
|
||||
@@ -675,7 +681,18 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye
|
||||
super.onDisplayChanged(dc);
|
||||
}
|
||||
|
||||
void getStackDockedModeBoundsLocked(Rect outBounds, boolean ignoreVisibility) {
|
||||
void getStackDockedModeBoundsLocked(Rect outBounds, Rect outTempBounds,
|
||||
Rect outTempInsetBounds, boolean ignoreVisibility) {
|
||||
if (mStackId == HOME_STACK_ID && findHomeTask().isResizeable()) {
|
||||
// Calculate the home stack bounds when in docked mode
|
||||
getDisplayContent().mDividerControllerLocked
|
||||
.getHomeStackBoundsInDockedMode(outTempBounds);
|
||||
outTempInsetBounds.set(outTempBounds);
|
||||
} else {
|
||||
outTempBounds.setEmpty();
|
||||
outTempInsetBounds.setEmpty();
|
||||
}
|
||||
|
||||
if ((mStackId != DOCKED_STACK_ID && !StackId.isResizeableByDockedStack(mStackId))
|
||||
|| mDisplayContent == null) {
|
||||
outBounds.set(mBounds);
|
||||
@@ -789,7 +806,9 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye
|
||||
mService.mDockedStackCreateBounds = null;
|
||||
|
||||
final Rect bounds = new Rect();
|
||||
getStackDockedModeBoundsLocked(bounds, true /*ignoreVisibility*/);
|
||||
final Rect tempBounds = new Rect();
|
||||
final Rect tempInsetBounds = new Rect();
|
||||
getStackDockedModeBoundsLocked(bounds, tempBounds, tempInsetBounds, true /*ignoreVisibility*/);
|
||||
getController().requestResize(bounds);
|
||||
}
|
||||
|
||||
@@ -946,8 +965,9 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye
|
||||
}
|
||||
}
|
||||
|
||||
boolean isAdjustedForMinimizedDock() {
|
||||
return mMinimizeAmount != 0f;
|
||||
boolean shouldIgnoreInput() {
|
||||
return isAdjustedForMinimizedDockedStack() || mStackId == DOCKED_STACK_ID &&
|
||||
isMinimizedDockAndHomeStackResizable();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1075,6 +1095,11 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isMinimizedDockAndHomeStackResizable() {
|
||||
return mDisplayContent.mDividerControllerLocked.isMinimizedDock()
|
||||
&& mDisplayContent.mDividerControllerLocked.isHomeStackResizable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the distance in pixels how much the stack gets minimized from it's original size
|
||||
*/
|
||||
@@ -1344,9 +1369,17 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye
|
||||
* tasks (including the focused).
|
||||
*
|
||||
* We save the focused task region once we find it, and add it back at the end.
|
||||
*
|
||||
* If the task is home stack and it is resizable in the minimized state, we want to
|
||||
* exclude the docked stack from touch so we need the entire screen area and not just a
|
||||
* small portion which the home stack currently is resized to.
|
||||
*/
|
||||
|
||||
task.getDimBounds(mTmpRect);
|
||||
if (task.isHomeTask() && isMinimizedDockAndHomeStackResizable()) {
|
||||
mDisplayContent.getLogicalDisplayRect(mTmpRect);
|
||||
} else {
|
||||
task.getDimBounds(mTmpRect);
|
||||
}
|
||||
|
||||
if (task == focusedTask) {
|
||||
// Add the focused task rect back into the exclude region once we are done
|
||||
|
||||
@@ -1671,11 +1671,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
return !mLastReportedConfiguration.equals(getConfiguration());
|
||||
}
|
||||
|
||||
boolean isAdjustedForMinimizedDock() {
|
||||
return mAppToken != null && mAppToken.mTask != null
|
||||
&& mAppToken.mTask.mStack.isAdjustedForMinimizedDock();
|
||||
}
|
||||
|
||||
void onWindowReplacementTimeout() {
|
||||
if (mWillReplaceWindow) {
|
||||
// Since the window already timed out, remove it immediately now.
|
||||
@@ -2364,7 +2359,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
&& (mViewVisibility == View.VISIBLE) && !mRemoveOnExit
|
||||
&& ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0)
|
||||
&& (mAppToken == null || mAppToken.windowsAreFocusable())
|
||||
&& !isAdjustedForMinimizedDock();
|
||||
&& !canReceiveTouchInput();
|
||||
}
|
||||
|
||||
/** @return true if this window desires touch events. */
|
||||
boolean canReceiveTouchInput() {
|
||||
return mAppToken != null && mAppToken.mTask != null
|
||||
&& mAppToken.mTask.mStack.shouldIgnoreInput();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user