Merge "Some clean-up of divider code in preparation for bugfixes" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
fcebe7dc6c
@@ -129,217 +129,213 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private DisplayImeController.ImePositionProcessor mImePositionProcessor =
|
private class DividerImeController implements DisplayImeController.ImePositionProcessor {
|
||||||
new DisplayImeController.ImePositionProcessor() {
|
/**
|
||||||
/**
|
* These are the y positions of the top of the IME surface when it is hidden and when it is
|
||||||
* These are the y positions of the top of the IME surface when it is hidden and
|
* shown respectively. These are NOT necessarily the top of the visible IME itself.
|
||||||
* when it is shown respectively. These are NOT necessarily the top of the visible
|
*/
|
||||||
* IME itself.
|
private int mHiddenTop = 0;
|
||||||
*/
|
private int mShownTop = 0;
|
||||||
private int mHiddenTop = 0;
|
|
||||||
private int mShownTop = 0;
|
|
||||||
|
|
||||||
// The following are target states (what we are curretly animating towards).
|
// The following are target states (what we are curretly animating towards).
|
||||||
/**
|
/**
|
||||||
* {@code true} if, at the end of the animation, the split task positions should be
|
* {@code true} if, at the end of the animation, the split task positions should be
|
||||||
* adjusted by height of the IME. This happens when the secondary split is the IME
|
* adjusted by height of the IME. This happens when the secondary split is the IME target.
|
||||||
* target.
|
*/
|
||||||
*/
|
private boolean mTargetAdjusted = false;
|
||||||
private boolean mTargetAdjusted = false;
|
/**
|
||||||
/**
|
* {@code true} if, at the end of the animation, the IME should be shown/visible
|
||||||
* {@code true} if, at the end of the animation, the IME should be shown/visible
|
* regardless of what has focus.
|
||||||
* regardless of what has focus.
|
*/
|
||||||
*/
|
private boolean mTargetShown = false;
|
||||||
private boolean mTargetShown = false;
|
|
||||||
|
|
||||||
// The following are the current (most recent) states set during animation
|
// The following are the current (most recent) states set during animation
|
||||||
/**
|
/** {@code true} if the secondary split has IME focus. */
|
||||||
* {@code true} if the secondary split has IME focus.
|
private boolean mSecondaryHasFocus = false;
|
||||||
*/
|
/** The dimming currently applied to the primary/secondary splits. */
|
||||||
private boolean mSecondaryHasFocus = false;
|
private float mLastPrimaryDim = 0.f;
|
||||||
/** The dimming currently applied to the primary/secondary splits. */
|
private float mLastSecondaryDim = 0.f;
|
||||||
private float mLastPrimaryDim = 0.f;
|
/** The most recent y position of the top of the IME surface */
|
||||||
private float mLastSecondaryDim = 0.f;
|
private int mLastAdjustTop = -1;
|
||||||
/** The most recent y position of the top of the IME surface */
|
|
||||||
private int mLastAdjustTop = -1;
|
|
||||||
|
|
||||||
// The following are states reached last time an animation fully completed.
|
// The following are states reached last time an animation fully completed.
|
||||||
/** {@code true} if the IME was shown/visible by the last-completed animation. */
|
/** {@code true} if the IME was shown/visible by the last-completed animation. */
|
||||||
private boolean mImeWasShown = false;
|
private boolean mImeWasShown = false;
|
||||||
/**
|
/** {@code true} if the split positions were adjusted by the last-completed animation. */
|
||||||
* {@code true} if the split positions were adjusted by the last-completed
|
private boolean mAdjusted = false;
|
||||||
* animation.
|
|
||||||
*/
|
|
||||||
private boolean mAdjusted = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When some aspect of split-screen needs to animate independent from the IME,
|
* When some aspect of split-screen needs to animate independent from the IME,
|
||||||
* this will be non-null and control split animation.
|
* this will be non-null and control split animation.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
private ValueAnimator mAnimation = null;
|
private ValueAnimator mAnimation = null;
|
||||||
|
|
||||||
private boolean getSecondaryHasFocus(int displayId) {
|
private boolean getSecondaryHasFocus(int displayId) {
|
||||||
try {
|
try {
|
||||||
IWindowContainer imeSplit = ActivityTaskManager.getTaskOrganizerController()
|
IWindowContainer imeSplit = ActivityTaskManager.getTaskOrganizerController()
|
||||||
.getImeTarget(displayId);
|
.getImeTarget(displayId);
|
||||||
return imeSplit != null
|
return imeSplit != null
|
||||||
&& (imeSplit.asBinder() == mSplits.mSecondary.token.asBinder());
|
&& (imeSplit.asBinder() == mSplits.mSecondary.token.asBinder());
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Slog.w(TAG, "Failed to get IME target", e);
|
Slog.w(TAG, "Failed to get IME target", e);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onImeStartPositioning(int displayId, int hiddenTop, int shownTop,
|
||||||
|
boolean imeShouldShow, SurfaceControl.Transaction t) {
|
||||||
|
mSecondaryHasFocus = getSecondaryHasFocus(displayId);
|
||||||
|
mTargetAdjusted = imeShouldShow && mSecondaryHasFocus
|
||||||
|
&& !mSplitLayout.mDisplayLayout.isLandscape();
|
||||||
|
mHiddenTop = hiddenTop;
|
||||||
|
mShownTop = shownTop;
|
||||||
|
mTargetShown = imeShouldShow;
|
||||||
|
if (mLastAdjustTop < 0) {
|
||||||
|
mLastAdjustTop = imeShouldShow ? hiddenTop : shownTop;
|
||||||
|
}
|
||||||
|
if (mAnimation != null || (mImeWasShown && imeShouldShow
|
||||||
|
&& mTargetAdjusted != mAdjusted)) {
|
||||||
|
// We need to animate adjustment independently of the IME position, so
|
||||||
|
// start our own animation to drive adjustment. This happens when a
|
||||||
|
// different split's editor has gained focus while the IME is still visible.
|
||||||
|
startAsyncAnimation();
|
||||||
|
}
|
||||||
|
updateImeAdjustState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateImeAdjustState() {
|
||||||
|
// Reposition the server's secondary split position so that it evaluates
|
||||||
|
// insets properly.
|
||||||
|
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||||
|
if (mTargetAdjusted) {
|
||||||
|
mSplitLayout.updateAdjustedBounds(mShownTop, mHiddenTop, mShownTop);
|
||||||
|
wct.setBounds(mSplits.mSecondary.token, mSplitLayout.mAdjustedSecondary);
|
||||||
|
// "Freeze" the configuration size so that the app doesn't get a config
|
||||||
|
// or relaunch. This is required because normally nav-bar contributes
|
||||||
|
// to configuration bounds (via nondecorframe).
|
||||||
|
Rect adjustAppBounds = new Rect(mSplits.mSecondary.configuration
|
||||||
|
.windowConfiguration.getAppBounds());
|
||||||
|
adjustAppBounds.offset(0, mSplitLayout.mAdjustedSecondary.top
|
||||||
|
- mSplitLayout.mSecondary.top);
|
||||||
|
wct.setAppBounds(mSplits.mSecondary.token, adjustAppBounds);
|
||||||
|
wct.setScreenSizeDp(mSplits.mSecondary.token,
|
||||||
|
mSplits.mSecondary.configuration.screenWidthDp,
|
||||||
|
mSplits.mSecondary.configuration.screenHeightDp);
|
||||||
|
} else {
|
||||||
|
wct.setBounds(mSplits.mSecondary.token, mSplitLayout.mSecondary);
|
||||||
|
wct.setAppBounds(mSplits.mSecondary.token, null);
|
||||||
|
wct.setScreenSizeDp(mSplits.mSecondary.token,
|
||||||
|
SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
ActivityTaskManager.getTaskOrganizerController()
|
||||||
|
.applyContainerTransaction(wct, null /* organizer */);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update all the adjusted-for-ime states
|
||||||
|
mView.setAdjustedForIme(mTargetShown, mTargetShown
|
||||||
|
? DisplayImeController.ANIMATION_DURATION_SHOW_MS
|
||||||
|
: DisplayImeController.ANIMATION_DURATION_HIDE_MS);
|
||||||
|
setAdjustedForIme(mTargetShown);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onImePositionChanged(int displayId, int imeTop,
|
||||||
|
SurfaceControl.Transaction t) {
|
||||||
|
if (mAnimation != null) {
|
||||||
|
// Not synchronized with IME anymore, so return.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final float fraction = ((float) imeTop - mHiddenTop) / (mShownTop - mHiddenTop);
|
||||||
|
final float progress = mTargetShown ? fraction : 1.f - fraction;
|
||||||
|
onProgress(progress, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onImeEndPositioning(int displayId, boolean cancelled,
|
||||||
|
SurfaceControl.Transaction t) {
|
||||||
|
if (mAnimation != null) {
|
||||||
|
// Not synchronized with IME anymore, so return.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onEnd(cancelled, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onProgress(float progress, SurfaceControl.Transaction t) {
|
||||||
|
if (mTargetAdjusted != mAdjusted) {
|
||||||
|
final float fraction = mTargetAdjusted ? progress : 1.f - progress;
|
||||||
|
mLastAdjustTop = (int) (fraction * mShownTop + (1.f - fraction) * mHiddenTop);
|
||||||
|
mSplitLayout.updateAdjustedBounds(mLastAdjustTop, mHiddenTop, mShownTop);
|
||||||
|
mView.resizeSplitSurfaces(t, mSplitLayout.mAdjustedPrimary,
|
||||||
|
mSplitLayout.mAdjustedSecondary);
|
||||||
|
}
|
||||||
|
final float invProg = 1.f - progress;
|
||||||
|
final float targetPrimaryDim =
|
||||||
|
(mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f;
|
||||||
|
final float targetSecondaryDim =
|
||||||
|
(!mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f;
|
||||||
|
mView.setResizeDimLayer(t, true /* primary */,
|
||||||
|
mLastPrimaryDim * invProg + progress * targetPrimaryDim);
|
||||||
|
mView.setResizeDimLayer(t, false /* primary */,
|
||||||
|
mLastSecondaryDim * invProg + progress * targetSecondaryDim);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onEnd(boolean cancelled, SurfaceControl.Transaction t) {
|
||||||
|
if (!cancelled) {
|
||||||
|
onProgress(1.f, t);
|
||||||
|
mAdjusted = mTargetAdjusted;
|
||||||
|
mImeWasShown = mTargetShown;
|
||||||
|
mLastAdjustTop = mAdjusted ? mShownTop : mHiddenTop;
|
||||||
|
mLastPrimaryDim =
|
||||||
|
(mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f;
|
||||||
|
mLastSecondaryDim =
|
||||||
|
(!mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startAsyncAnimation() {
|
||||||
|
if (mAnimation != null) {
|
||||||
|
mAnimation.cancel();
|
||||||
|
}
|
||||||
|
mAnimation = ValueAnimator.ofFloat(0.f, 1.f);
|
||||||
|
mAnimation.setDuration(DisplayImeController.ANIMATION_DURATION_SHOW_MS);
|
||||||
|
if (mTargetAdjusted != mAdjusted) {
|
||||||
|
final float fraction =
|
||||||
|
((float) mLastAdjustTop - mHiddenTop) / (mShownTop - mHiddenTop);
|
||||||
|
final float progress = mTargetAdjusted ? fraction : 1.f - fraction;
|
||||||
|
mAnimation.setCurrentFraction(progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
mAnimation.addUpdateListener(animation -> {
|
||||||
|
SurfaceControl.Transaction t = mTransactionPool.acquire();
|
||||||
|
float value = (float) animation.getAnimatedValue();
|
||||||
|
onProgress(value, t);
|
||||||
|
t.apply();
|
||||||
|
mTransactionPool.release(t);
|
||||||
|
});
|
||||||
|
mAnimation.setInterpolator(DisplayImeController.INTERPOLATOR);
|
||||||
|
mAnimation.addListener(new AnimatorListenerAdapter() {
|
||||||
|
private boolean mCancel = false;
|
||||||
@Override
|
@Override
|
||||||
public void onImeStartPositioning(int displayId, int hiddenTop, int shownTop,
|
public void onAnimationCancel(Animator animation) {
|
||||||
boolean imeShouldShow, SurfaceControl.Transaction t) {
|
mCancel = true;
|
||||||
mSecondaryHasFocus = getSecondaryHasFocus(displayId);
|
|
||||||
mTargetAdjusted = imeShouldShow && mSecondaryHasFocus
|
|
||||||
&& !mSplitLayout.mDisplayLayout.isLandscape();
|
|
||||||
mHiddenTop = hiddenTop;
|
|
||||||
mShownTop = shownTop;
|
|
||||||
mTargetShown = imeShouldShow;
|
|
||||||
if (mLastAdjustTop < 0) {
|
|
||||||
mLastAdjustTop = imeShouldShow ? hiddenTop : shownTop;
|
|
||||||
}
|
|
||||||
if (mAnimation != null || (mImeWasShown && imeShouldShow
|
|
||||||
&& mTargetAdjusted != mAdjusted)) {
|
|
||||||
// We need to animate adjustment independently of the IME position, so
|
|
||||||
// start our own animation to drive adjustment. This happens when a
|
|
||||||
// different split's editor has gained focus while the IME is still visible.
|
|
||||||
startAsyncAnimation();
|
|
||||||
}
|
|
||||||
// Reposition the server's secondary split position so that it evaluates
|
|
||||||
// insets properly.
|
|
||||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
|
||||||
if (mTargetAdjusted) {
|
|
||||||
mSplitLayout.updateAdjustedBounds(mShownTop, mHiddenTop, mShownTop);
|
|
||||||
wct.setBounds(mSplits.mSecondary.token, mSplitLayout.mAdjustedSecondary);
|
|
||||||
// "Freeze" the configuration size so that the app doesn't get a config
|
|
||||||
// or relaunch. This is required because normally nav-bar contributes
|
|
||||||
// to configuration bounds (via nondecorframe).
|
|
||||||
Rect adjustAppBounds = new Rect(mSplits.mSecondary.configuration
|
|
||||||
.windowConfiguration.getAppBounds());
|
|
||||||
adjustAppBounds.offset(0, mSplitLayout.mAdjustedSecondary.top
|
|
||||||
- mSplitLayout.mSecondary.top);
|
|
||||||
wct.setAppBounds(mSplits.mSecondary.token, adjustAppBounds);
|
|
||||||
wct.setScreenSizeDp(mSplits.mSecondary.token,
|
|
||||||
mSplits.mSecondary.configuration.screenWidthDp,
|
|
||||||
mSplits.mSecondary.configuration.screenHeightDp);
|
|
||||||
} else {
|
|
||||||
wct.setBounds(mSplits.mSecondary.token, mSplitLayout.mSecondary);
|
|
||||||
wct.setAppBounds(mSplits.mSecondary.token, null);
|
|
||||||
wct.setScreenSizeDp(mSplits.mSecondary.token,
|
|
||||||
SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
ActivityTaskManager.getTaskOrganizerController()
|
|
||||||
.applyContainerTransaction(wct, null /* organizer */);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update all the adjusted-for-ime states
|
|
||||||
mView.setAdjustedForIme(mTargetShown, mTargetShown
|
|
||||||
? DisplayImeController.ANIMATION_DURATION_SHOW_MS
|
|
||||||
: DisplayImeController.ANIMATION_DURATION_HIDE_MS);
|
|
||||||
setAdjustedForIme(mTargetShown);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onImePositionChanged(int displayId, int imeTop,
|
public void onAnimationEnd(Animator animation) {
|
||||||
SurfaceControl.Transaction t) {
|
SurfaceControl.Transaction t = mTransactionPool.acquire();
|
||||||
if (mAnimation != null) {
|
onEnd(mCancel, t);
|
||||||
// Not synchronized with IME anymore, so return.
|
t.apply();
|
||||||
return;
|
mTransactionPool.release(t);
|
||||||
}
|
mAnimation = null;
|
||||||
final float fraction = ((float) imeTop - mHiddenTop) / (mShownTop - mHiddenTop);
|
|
||||||
final float progress = mTargetShown ? fraction : 1.f - fraction;
|
|
||||||
onProgress(progress, t);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
@Override
|
mAnimation.start();
|
||||||
public void onImeEndPositioning(int displayId, boolean cancelled,
|
}
|
||||||
SurfaceControl.Transaction t) {
|
}
|
||||||
if (mAnimation != null) {
|
private final DividerImeController mImePositionProcessor = new DividerImeController();
|
||||||
// Not synchronized with IME anymore, so return.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
onEnd(cancelled, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onProgress(float progress, SurfaceControl.Transaction t) {
|
|
||||||
if (mTargetAdjusted != mAdjusted) {
|
|
||||||
final float fraction = mTargetAdjusted ? progress : 1.f - progress;
|
|
||||||
mLastAdjustTop =
|
|
||||||
(int) (fraction * mShownTop + (1.f - fraction) * mHiddenTop);
|
|
||||||
mSplitLayout.updateAdjustedBounds(mLastAdjustTop, mHiddenTop, mShownTop);
|
|
||||||
mView.resizeSplitSurfaces(t, mSplitLayout.mAdjustedPrimary,
|
|
||||||
mSplitLayout.mAdjustedSecondary);
|
|
||||||
}
|
|
||||||
final float invProg = 1.f - progress;
|
|
||||||
final float targetPrimaryDim = (mSecondaryHasFocus && mTargetShown)
|
|
||||||
? ADJUSTED_NONFOCUS_DIM : 0.f;
|
|
||||||
final float targetSecondaryDim = (!mSecondaryHasFocus && mTargetShown)
|
|
||||||
? ADJUSTED_NONFOCUS_DIM : 0.f;
|
|
||||||
mView.setResizeDimLayer(t, true /* primary */,
|
|
||||||
mLastPrimaryDim * invProg + progress * targetPrimaryDim);
|
|
||||||
mView.setResizeDimLayer(t, false /* primary */,
|
|
||||||
mLastSecondaryDim * invProg + progress * targetSecondaryDim);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onEnd(boolean cancelled, SurfaceControl.Transaction t) {
|
|
||||||
if (!cancelled) {
|
|
||||||
onProgress(1.f, t);
|
|
||||||
mAdjusted = mTargetAdjusted;
|
|
||||||
mImeWasShown = mTargetShown;
|
|
||||||
mLastAdjustTop = mAdjusted ? mShownTop : mHiddenTop;
|
|
||||||
mLastPrimaryDim =
|
|
||||||
(mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f;
|
|
||||||
mLastSecondaryDim =
|
|
||||||
(!mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startAsyncAnimation() {
|
|
||||||
if (mAnimation != null) {
|
|
||||||
mAnimation.cancel();
|
|
||||||
}
|
|
||||||
mAnimation = ValueAnimator.ofFloat(0.f, 1.f);
|
|
||||||
mAnimation.setDuration(DisplayImeController.ANIMATION_DURATION_SHOW_MS);
|
|
||||||
if (mTargetAdjusted != mAdjusted) {
|
|
||||||
final float fraction =
|
|
||||||
((float) mLastAdjustTop - mHiddenTop) / (mShownTop - mHiddenTop);
|
|
||||||
final float progress = mTargetAdjusted ? fraction : 1.f - fraction;
|
|
||||||
mAnimation.setCurrentFraction(progress);
|
|
||||||
}
|
|
||||||
|
|
||||||
mAnimation.addUpdateListener(animation -> {
|
|
||||||
SurfaceControl.Transaction t = mTransactionPool.acquire();
|
|
||||||
float value = (float) animation.getAnimatedValue();
|
|
||||||
onProgress(value, t);
|
|
||||||
t.apply();
|
|
||||||
mTransactionPool.release(t);
|
|
||||||
});
|
|
||||||
mAnimation.setInterpolator(DisplayImeController.INTERPOLATOR);
|
|
||||||
mAnimation.addListener(new AnimatorListenerAdapter() {
|
|
||||||
private boolean mCancel = false;
|
|
||||||
@Override
|
|
||||||
public void onAnimationCancel(Animator animation) {
|
|
||||||
mCancel = true;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void onAnimationEnd(Animator animation) {
|
|
||||||
SurfaceControl.Transaction t = mTransactionPool.acquire();
|
|
||||||
onEnd(mCancel, t);
|
|
||||||
t.apply();
|
|
||||||
mTransactionPool.release(t);
|
|
||||||
mAnimation = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mAnimation.start();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public Divider(Context context, Optional<Lazy<Recents>> recentsOptionalLazy,
|
public Divider(Context context, Optional<Lazy<Recents>> recentsOptionalLazy,
|
||||||
DisplayController displayController, SystemWindows systemWindows,
|
DisplayController displayController, SystemWindows systemWindows,
|
||||||
@@ -513,44 +509,39 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setHomeStackResizable(boolean resizable) {
|
|
||||||
if (mHomeStackResizable == resizable) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mHomeStackResizable = resizable;
|
|
||||||
if (!inSplitMode()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
WindowManagerProxy.applyHomeTasksMinimized(mSplitLayout, mSplits.mSecondary.token);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateMinimizedDockedStack(final boolean minimized, final long animDuration,
|
|
||||||
final boolean isHomeStackResizable) {
|
|
||||||
setHomeStackResizable(isHomeStackResizable);
|
|
||||||
if (animDuration > 0) {
|
|
||||||
mView.setMinimizedDockStack(minimized, animDuration, isHomeStackResizable);
|
|
||||||
} else {
|
|
||||||
mView.setMinimizedDockStack(minimized, isHomeStackResizable);
|
|
||||||
}
|
|
||||||
updateTouchable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Switch to minimized state if appropriate */
|
/** Switch to minimized state if appropriate */
|
||||||
public void setMinimized(final boolean minimized) {
|
public void setMinimized(final boolean minimized) {
|
||||||
mHandler.post(() -> {
|
mHandler.post(() -> {
|
||||||
if (!inSplitMode()) {
|
setHomeMinimized(minimized, mHomeStackResizable);
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mMinimized == minimized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mMinimized = minimized;
|
|
||||||
WindowManagerProxy.applyPrimaryFocusable(mSplits, !mMinimized);
|
|
||||||
mView.setMinimizedDockStack(minimized, getAnimDuration(), mHomeStackResizable);
|
|
||||||
updateTouchable();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setHomeMinimized(final boolean minimized, boolean homeStackResizable) {
|
||||||
|
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||||
|
// Update minimized state
|
||||||
|
if (mMinimized != minimized) {
|
||||||
|
mMinimized = minimized;
|
||||||
|
}
|
||||||
|
// Always set this because we could be entering split when mMinimized is already true
|
||||||
|
wct.setFocusable(mSplits.mPrimary.token, !mMinimized);
|
||||||
|
|
||||||
|
// Update home-stack resizability
|
||||||
|
if (mHomeStackResizable != homeStackResizable) {
|
||||||
|
mHomeStackResizable = homeStackResizable;
|
||||||
|
if (inSplitMode()) {
|
||||||
|
WindowManagerProxy.applyHomeTasksMinimized(
|
||||||
|
mSplitLayout, mSplits.mSecondary.token, wct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync state to DividerView if it exists.
|
||||||
|
if (mView != null) {
|
||||||
|
mView.setMinimizedDockStack(minimized, getAnimDuration(), homeStackResizable);
|
||||||
|
}
|
||||||
|
updateTouchable();
|
||||||
|
WindowManagerProxy.applyContainerTransaction(wct);
|
||||||
|
}
|
||||||
|
|
||||||
void setAdjustedForIme(boolean adjustedForIme) {
|
void setAdjustedForIme(boolean adjustedForIme) {
|
||||||
if (mAdjustedForIme == adjustedForIme) {
|
if (mAdjustedForIme == adjustedForIme) {
|
||||||
return;
|
return;
|
||||||
@@ -646,46 +637,24 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ensureMinimizedSplit() {
|
void ensureMinimizedSplit() {
|
||||||
final boolean wasMinimized = mMinimized;
|
setHomeMinimized(true /* minimized */, mSplits.mSecondary.isResizable());
|
||||||
mMinimized = true;
|
|
||||||
setHomeStackResizable(mSplits.mSecondary.isResizable());
|
|
||||||
WindowManagerProxy.applyPrimaryFocusable(mSplits, false /* focusable */);
|
|
||||||
if (!inSplitMode()) {
|
if (!inSplitMode()) {
|
||||||
// Wasn't in split-mode yet, so enter now.
|
// Wasn't in split-mode yet, so enter now.
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, " entering split mode with minimized=true");
|
Log.d(TAG, " entering split mode with minimized=true");
|
||||||
}
|
}
|
||||||
updateVisibility(true /* visible */);
|
updateVisibility(true /* visible */);
|
||||||
} else if (!wasMinimized) {
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, " in split mode, but minimizing ");
|
|
||||||
}
|
|
||||||
// Was already in split-mode, update just minimized state.
|
|
||||||
updateMinimizedDockedStack(mMinimized, getAnimDuration(),
|
|
||||||
mHomeStackResizable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ensureNormalSplit() {
|
void ensureNormalSplit() {
|
||||||
if (mMinimized) {
|
setHomeMinimized(false /* minimized */, mHomeStackResizable);
|
||||||
WindowManagerProxy.applyPrimaryFocusable(mSplits, true /* focusable */);
|
|
||||||
}
|
|
||||||
if (!inSplitMode()) {
|
if (!inSplitMode()) {
|
||||||
// Wasn't in split-mode, so enter now.
|
// Wasn't in split-mode, so enter now.
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, " enter split mode unminimized ");
|
Log.d(TAG, " enter split mode unminimized ");
|
||||||
}
|
}
|
||||||
mMinimized = false;
|
|
||||||
updateVisibility(true /* visible */);
|
updateVisibility(true /* visible */);
|
||||||
}
|
}
|
||||||
if (mMinimized) {
|
|
||||||
// Was in minimized state, so leave that.
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, " in split mode already, but unminimizing ");
|
|
||||||
}
|
|
||||||
mMinimized = false;
|
|
||||||
updateMinimizedDockedStack(mMinimized, getAnimDuration(),
|
|
||||||
mHomeStackResizable);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,6 +88,9 @@ public class DividerWindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setTouchable(boolean touchable) {
|
public void setTouchable(boolean touchable) {
|
||||||
|
if (mView == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
if (!touchable && (mLp.flags & FLAG_NOT_TOUCHABLE) == 0) {
|
if (!touchable && (mLp.flags & FLAG_NOT_TOUCHABLE) == 0) {
|
||||||
mLp.flags |= FLAG_NOT_TOUCHABLE;
|
mLp.flags |= FLAG_NOT_TOUCHABLE;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
|||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||||
import static android.view.Display.DEFAULT_DISPLAY;
|
import static android.view.Display.DEFAULT_DISPLAY;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.ActivityTaskManager;
|
import android.app.ActivityTaskManager;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
@@ -137,17 +138,13 @@ public class WindowManagerProxy {
|
|||||||
return resizable;
|
return resizable;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void applyHomeTasksMinimized(SplitDisplayLayout layout, IWindowContainer parent) {
|
|
||||||
applyHomeTasksMinimized(layout, parent, null /* transaction */);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign a fixed override-bounds to home tasks that reflect their geometry while the primary
|
* Assign a fixed override-bounds to home tasks that reflect their geometry while the primary
|
||||||
* split is minimized. This actually "sticks out" of the secondary split area, but when in
|
* split is minimized. This actually "sticks out" of the secondary split area, but when in
|
||||||
* minimized mode, the secondary split gets a 'negative' crop to expose it.
|
* minimized mode, the secondary split gets a 'negative' crop to expose it.
|
||||||
*/
|
*/
|
||||||
static boolean applyHomeTasksMinimized(SplitDisplayLayout layout, IWindowContainer parent,
|
static boolean applyHomeTasksMinimized(SplitDisplayLayout layout, IWindowContainer parent,
|
||||||
WindowContainerTransaction t) {
|
@NonNull WindowContainerTransaction wct) {
|
||||||
// Resize the home/recents stacks to the larger minimized-state size
|
// Resize the home/recents stacks to the larger minimized-state size
|
||||||
final Rect homeBounds;
|
final Rect homeBounds;
|
||||||
final ArrayList<IWindowContainer> homeStacks = new ArrayList<>();
|
final ArrayList<IWindowContainer> homeStacks = new ArrayList<>();
|
||||||
@@ -158,19 +155,9 @@ public class WindowManagerProxy {
|
|||||||
homeBounds = new Rect(0, 0, layout.mDisplayLayout.width(),
|
homeBounds = new Rect(0, 0, layout.mDisplayLayout.width(),
|
||||||
layout.mDisplayLayout.height());
|
layout.mDisplayLayout.height());
|
||||||
}
|
}
|
||||||
WindowContainerTransaction wct = t != null ? t : new WindowContainerTransaction();
|
|
||||||
for (int i = homeStacks.size() - 1; i >= 0; --i) {
|
for (int i = homeStacks.size() - 1; i >= 0; --i) {
|
||||||
wct.setBounds(homeStacks.get(i), homeBounds);
|
wct.setBounds(homeStacks.get(i), homeBounds);
|
||||||
}
|
}
|
||||||
if (t != null) {
|
|
||||||
return isHomeResizable;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
ActivityTaskManager.getTaskOrganizerController().applyContainerTransaction(wct,
|
|
||||||
null /* organizer */);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Failed to resize home stacks ", e);
|
|
||||||
}
|
|
||||||
return isHomeResizable;
|
return isHomeResizable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,10 +288,8 @@ public class WindowManagerProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void applyPrimaryFocusable(SplitScreenTaskOrganizer splits, boolean focusable) {
|
static void applyContainerTransaction(WindowContainerTransaction wct) {
|
||||||
try {
|
try {
|
||||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
|
||||||
wct.setFocusable(splits.mPrimary.token, focusable);
|
|
||||||
ActivityTaskManager.getTaskOrganizerController().applyContainerTransaction(wct,
|
ActivityTaskManager.getTaskOrganizerController().applyContainerTransaction(wct,
|
||||||
null /* organizer */);
|
null /* organizer */);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
|
|||||||
Reference in New Issue
Block a user