Loading packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java +247 −258 Original line number Original line Diff line number Diff line Loading @@ -129,12 +129,10 @@ 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 * These are the y positions of the top of the IME surface when it is hidden and when it is * when it is shown respectively. These are NOT necessarily the top of the visible * shown respectively. These are NOT necessarily the top of the visible IME itself. * IME itself. */ */ private int mHiddenTop = 0; private int mHiddenTop = 0; private int mShownTop = 0; private int mShownTop = 0; Loading @@ -142,8 +140,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, // 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; /** /** Loading @@ -151,11 +148,11 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, * regardless of what has focus. * regardless of what has focus. */ */ private boolean mTargetShown = false; private boolean mTargetShown = false; private float mTargetPrimaryDim = 0.f; private float mTargetSecondaryDim = 0.f; // 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; private boolean mSecondaryHasFocus = false; /** The dimming currently applied to the primary/secondary splits. */ /** The dimming currently applied to the primary/secondary splits. */ private float mLastPrimaryDim = 0.f; private float mLastPrimaryDim = 0.f; Loading @@ -166,10 +163,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, // 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 * animation. */ private boolean mAdjusted = false; private boolean mAdjusted = false; /** /** Loading @@ -194,8 +188,12 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, @Override @Override public void onImeStartPositioning(int displayId, int hiddenTop, int shownTop, public void onImeStartPositioning(int displayId, int hiddenTop, int shownTop, boolean imeShouldShow, SurfaceControl.Transaction t) { boolean imeShouldShow, SurfaceControl.Transaction t) { if (!inSplitMode()) { return; } final boolean splitIsVisible = !mView.isHidden(); mSecondaryHasFocus = getSecondaryHasFocus(displayId); mSecondaryHasFocus = getSecondaryHasFocus(displayId); mTargetAdjusted = imeShouldShow && mSecondaryHasFocus mTargetAdjusted = splitIsVisible && imeShouldShow && mSecondaryHasFocus && !mSplitLayout.mDisplayLayout.isLandscape(); && !mSplitLayout.mDisplayLayout.isLandscape(); mHiddenTop = hiddenTop; mHiddenTop = hiddenTop; mShownTop = shownTop; mShownTop = shownTop; Loading @@ -203,6 +201,10 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, if (mLastAdjustTop < 0) { if (mLastAdjustTop < 0) { mLastAdjustTop = imeShouldShow ? hiddenTop : shownTop; mLastAdjustTop = imeShouldShow ? hiddenTop : shownTop; } } mTargetPrimaryDim = (mSecondaryHasFocus && mTargetShown && splitIsVisible) ? ADJUSTED_NONFOCUS_DIM : 0.f; mTargetSecondaryDim = (!mSecondaryHasFocus && mTargetShown && splitIsVisible) ? ADJUSTED_NONFOCUS_DIM : 0.f; if (mAnimation != null || (mImeWasShown && imeShouldShow if (mAnimation != null || (mImeWasShown && imeShouldShow && mTargetAdjusted != mAdjusted)) { && mTargetAdjusted != mAdjusted)) { // We need to animate adjustment independently of the IME position, so // We need to animate adjustment independently of the IME position, so Loading @@ -210,6 +212,14 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, // different split's editor has gained focus while the IME is still visible. // different split's editor has gained focus while the IME is still visible. startAsyncAnimation(); startAsyncAnimation(); } } if (splitIsVisible) { // If split is hidden, we don't want to trigger any relayouts that would cause the // divider to show again. updateImeAdjustState(); } } private void updateImeAdjustState() { // Reposition the server's secondary split position so that it evaluates // Reposition the server's secondary split position so that it evaluates // insets properly. // insets properly. WindowContainerTransaction wct = new WindowContainerTransaction(); WindowContainerTransaction wct = new WindowContainerTransaction(); Loading Loading @@ -249,7 +259,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, @Override @Override public void onImePositionChanged(int displayId, int imeTop, public void onImePositionChanged(int displayId, int imeTop, SurfaceControl.Transaction t) { SurfaceControl.Transaction t) { if (mAnimation != null) { if (mAnimation != null || !inSplitMode()) { // Not synchronized with IME anymore, so return. // Not synchronized with IME anymore, so return. return; return; } } Loading @@ -261,7 +271,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, @Override @Override public void onImeEndPositioning(int displayId, boolean cancelled, public void onImeEndPositioning(int displayId, boolean cancelled, SurfaceControl.Transaction t) { SurfaceControl.Transaction t) { if (mAnimation != null) { if (mAnimation != null || !inSplitMode()) { // Not synchronized with IME anymore, so return. // Not synchronized with IME anymore, so return. return; return; } } Loading @@ -271,21 +281,16 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, private void onProgress(float progress, SurfaceControl.Transaction t) { private void onProgress(float progress, SurfaceControl.Transaction t) { if (mTargetAdjusted != mAdjusted) { if (mTargetAdjusted != mAdjusted) { final float fraction = mTargetAdjusted ? progress : 1.f - progress; final float fraction = mTargetAdjusted ? progress : 1.f - progress; mLastAdjustTop = mLastAdjustTop = (int) (fraction * mShownTop + (1.f - fraction) * mHiddenTop); (int) (fraction * mShownTop + (1.f - fraction) * mHiddenTop); mSplitLayout.updateAdjustedBounds(mLastAdjustTop, mHiddenTop, mShownTop); mSplitLayout.updateAdjustedBounds(mLastAdjustTop, mHiddenTop, mShownTop); mView.resizeSplitSurfaces(t, mSplitLayout.mAdjustedPrimary, mView.resizeSplitSurfaces(t, mSplitLayout.mAdjustedPrimary, mSplitLayout.mAdjustedSecondary); mSplitLayout.mAdjustedSecondary); } } final float invProg = 1.f - progress; 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 */, mView.setResizeDimLayer(t, true /* primary */, mLastPrimaryDim * invProg + progress * targetPrimaryDim); mLastPrimaryDim * invProg + progress * mTargetPrimaryDim); mView.setResizeDimLayer(t, false /* primary */, mView.setResizeDimLayer(t, false /* primary */, mLastSecondaryDim * invProg + progress * targetSecondaryDim); mLastSecondaryDim * invProg + progress * mTargetSecondaryDim); } } private void onEnd(boolean cancelled, SurfaceControl.Transaction t) { private void onEnd(boolean cancelled, SurfaceControl.Transaction t) { Loading @@ -294,10 +299,8 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, mAdjusted = mTargetAdjusted; mAdjusted = mTargetAdjusted; mImeWasShown = mTargetShown; mImeWasShown = mTargetShown; mLastAdjustTop = mAdjusted ? mShownTop : mHiddenTop; mLastAdjustTop = mAdjusted ? mShownTop : mHiddenTop; mLastPrimaryDim = mLastPrimaryDim = mTargetPrimaryDim; (mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f; mLastSecondaryDim = mTargetSecondaryDim; mLastSecondaryDim = (!mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f; } } } } Loading Loading @@ -339,7 +342,8 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, }); }); mAnimation.start(); mAnimation.start(); } } }; } private final DividerImeController mImePositionProcessor = new DividerImeController(); public Divider(Context context, Optional<Lazy<Recents>> recentsOptionalLazy, public Divider(Context context, Optional<Lazy<Recents>> recentsOptionalLazy, DisplayController displayController, SystemWindows systemWindows, DisplayController displayController, SystemWindows systemWindows, Loading Loading @@ -513,42 +517,43 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, } } } } private void setHomeStackResizable(boolean resizable) { /** Switch to minimized state if appropriate */ if (mHomeStackResizable == resizable) { public void setMinimized(final boolean minimized) { return; mHandler.post(() -> { WindowContainerTransaction wct = new WindowContainerTransaction(); if (setHomeMinimized(minimized, mHomeStackResizable, wct)) { WindowManagerProxy.applyContainerTransaction(wct); } } mHomeStackResizable = resizable; }); if (!inSplitMode()) { return; } } WindowManagerProxy.applyHomeTasksMinimized(mSplitLayout, mSplits.mSecondary.token); private boolean setHomeMinimized(final boolean minimized, boolean homeStackResizable, WindowContainerTransaction wct) { boolean transact = false; // Update minimized state if (mMinimized != minimized) { mMinimized = minimized; wct.setFocusable(mSplits.mPrimary.token, !mMinimized); transact = true; } } private void updateMinimizedDockedStack(final boolean minimized, final long animDuration, // Update home-stack resizability final boolean isHomeStackResizable) { if (mHomeStackResizable != homeStackResizable) { setHomeStackResizable(isHomeStackResizable); mHomeStackResizable = homeStackResizable; if (animDuration > 0) { if (inSplitMode()) { mView.setMinimizedDockStack(minimized, animDuration, isHomeStackResizable); WindowManagerProxy.applyHomeTasksMinimized( } else { mSplitLayout, mSplits.mSecondary.token, wct); mView.setMinimizedDockStack(minimized, isHomeStackResizable); transact = true; } } updateTouchable(); } } /** Switch to minimized state if appropriate */ // Sync state to DividerView if it exists. public void setMinimized(final boolean minimized) { if (mView != null) { mHandler.post(() -> { mView.setMinimizedDockStack(minimized, getAnimDuration(), homeStackResizable); if (!inSplitMode()) { return; } if (mMinimized == minimized) { return; } } mMinimized = minimized; WindowManagerProxy.applyPrimaryFocusable(mSplits, !mMinimized); mView.setMinimizedDockStack(minimized, getAnimDuration(), mHomeStackResizable); updateTouchable(); updateTouchable(); }); return transact; } } void setAdjustedForIme(boolean adjustedForIme) { void setAdjustedForIme(boolean adjustedForIme) { Loading Loading @@ -646,46 +651,30 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, } } void ensureMinimizedSplit() { void ensureMinimizedSplit() { final boolean wasMinimized = mMinimized; WindowContainerTransaction wct = new WindowContainerTransaction(); mMinimized = true; if (setHomeMinimized(true, mSplits.mSecondary.isResizable(), wct)) { setHomeStackResizable(mSplits.mSecondary.isResizable()); WindowManagerProxy.applyContainerTransaction(wct); 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) { WindowContainerTransaction wct = new WindowContainerTransaction(); WindowManagerProxy.applyPrimaryFocusable(mSplits, true /* focusable */); if (setHomeMinimized(false /* minimized */, mHomeStackResizable, wct)) { WindowManagerProxy.applyContainerTransaction(wct); } } 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); } } } } } packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java +13 −1 Original line number Original line Diff line number Diff line Loading @@ -165,6 +165,10 @@ public class DividerView extends FrameLayout implements OnTouchListener, // The view is removed or in the process of been removed from the system. // The view is removed or in the process of been removed from the system. private boolean mRemoved; private boolean mRemoved; // Whether the surface for this view has been hidden regardless of actual visibility. This is // used interact with keyguard. private boolean mSurfaceHidden = false; private final Handler mHandler = new Handler() { private final Handler mHandler = new Handler() { @Override @Override public void handleMessage(Message msg) { public void handleMessage(Message msg) { Loading Loading @@ -414,6 +418,10 @@ public class DividerView extends FrameLayout implements OnTouchListener, /** Unlike setVisible, this directly hides the surface without changing view visibility. */ /** Unlike setVisible, this directly hides the surface without changing view visibility. */ void setHidden(boolean hidden) { void setHidden(boolean hidden) { if (mSurfaceHidden == hidden) { return; } mSurfaceHidden = hidden; post(() -> { post(() -> { final SurfaceControl sc = getWindowSurfaceControl(); final SurfaceControl sc = getWindowSurfaceControl(); if (sc == null) { if (sc == null) { Loading @@ -430,6 +438,10 @@ public class DividerView extends FrameLayout implements OnTouchListener, }); }); } } boolean isHidden() { return mSurfaceHidden; } public boolean startDragging(boolean animate, boolean touching) { public boolean startDragging(boolean animate, boolean touching) { cancelFlingAnimation(); cancelFlingAnimation(); if (touching) { if (touching) { Loading Loading @@ -1071,7 +1083,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, void setResizeDimLayer(Transaction t, boolean primary, float alpha) { void setResizeDimLayer(Transaction t, boolean primary, float alpha) { SurfaceControl dim = primary ? mTiles.mPrimaryDim : mTiles.mSecondaryDim; SurfaceControl dim = primary ? mTiles.mPrimaryDim : mTiles.mSecondaryDim; if (alpha <= 0.f) { if (alpha <= 0.001f) { t.hide(dim); t.hide(dim); } else { } else { t.setAlpha(dim, alpha); t.setAlpha(dim, alpha); Loading packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java +3 −0 Original line number Original line Diff line number Diff line Loading @@ -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; Loading packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java +3 −18 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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<>(); Loading @@ -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; } } Loading Loading @@ -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) { Loading Loading
packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java +247 −258 Original line number Original line Diff line number Diff line Loading @@ -129,12 +129,10 @@ 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 * These are the y positions of the top of the IME surface when it is hidden and when it is * when it is shown respectively. These are NOT necessarily the top of the visible * shown respectively. These are NOT necessarily the top of the visible IME itself. * IME itself. */ */ private int mHiddenTop = 0; private int mHiddenTop = 0; private int mShownTop = 0; private int mShownTop = 0; Loading @@ -142,8 +140,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, // 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; /** /** Loading @@ -151,11 +148,11 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, * regardless of what has focus. * regardless of what has focus. */ */ private boolean mTargetShown = false; private boolean mTargetShown = false; private float mTargetPrimaryDim = 0.f; private float mTargetSecondaryDim = 0.f; // 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; private boolean mSecondaryHasFocus = false; /** The dimming currently applied to the primary/secondary splits. */ /** The dimming currently applied to the primary/secondary splits. */ private float mLastPrimaryDim = 0.f; private float mLastPrimaryDim = 0.f; Loading @@ -166,10 +163,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, // 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 * animation. */ private boolean mAdjusted = false; private boolean mAdjusted = false; /** /** Loading @@ -194,8 +188,12 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, @Override @Override public void onImeStartPositioning(int displayId, int hiddenTop, int shownTop, public void onImeStartPositioning(int displayId, int hiddenTop, int shownTop, boolean imeShouldShow, SurfaceControl.Transaction t) { boolean imeShouldShow, SurfaceControl.Transaction t) { if (!inSplitMode()) { return; } final boolean splitIsVisible = !mView.isHidden(); mSecondaryHasFocus = getSecondaryHasFocus(displayId); mSecondaryHasFocus = getSecondaryHasFocus(displayId); mTargetAdjusted = imeShouldShow && mSecondaryHasFocus mTargetAdjusted = splitIsVisible && imeShouldShow && mSecondaryHasFocus && !mSplitLayout.mDisplayLayout.isLandscape(); && !mSplitLayout.mDisplayLayout.isLandscape(); mHiddenTop = hiddenTop; mHiddenTop = hiddenTop; mShownTop = shownTop; mShownTop = shownTop; Loading @@ -203,6 +201,10 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, if (mLastAdjustTop < 0) { if (mLastAdjustTop < 0) { mLastAdjustTop = imeShouldShow ? hiddenTop : shownTop; mLastAdjustTop = imeShouldShow ? hiddenTop : shownTop; } } mTargetPrimaryDim = (mSecondaryHasFocus && mTargetShown && splitIsVisible) ? ADJUSTED_NONFOCUS_DIM : 0.f; mTargetSecondaryDim = (!mSecondaryHasFocus && mTargetShown && splitIsVisible) ? ADJUSTED_NONFOCUS_DIM : 0.f; if (mAnimation != null || (mImeWasShown && imeShouldShow if (mAnimation != null || (mImeWasShown && imeShouldShow && mTargetAdjusted != mAdjusted)) { && mTargetAdjusted != mAdjusted)) { // We need to animate adjustment independently of the IME position, so // We need to animate adjustment independently of the IME position, so Loading @@ -210,6 +212,14 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, // different split's editor has gained focus while the IME is still visible. // different split's editor has gained focus while the IME is still visible. startAsyncAnimation(); startAsyncAnimation(); } } if (splitIsVisible) { // If split is hidden, we don't want to trigger any relayouts that would cause the // divider to show again. updateImeAdjustState(); } } private void updateImeAdjustState() { // Reposition the server's secondary split position so that it evaluates // Reposition the server's secondary split position so that it evaluates // insets properly. // insets properly. WindowContainerTransaction wct = new WindowContainerTransaction(); WindowContainerTransaction wct = new WindowContainerTransaction(); Loading Loading @@ -249,7 +259,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, @Override @Override public void onImePositionChanged(int displayId, int imeTop, public void onImePositionChanged(int displayId, int imeTop, SurfaceControl.Transaction t) { SurfaceControl.Transaction t) { if (mAnimation != null) { if (mAnimation != null || !inSplitMode()) { // Not synchronized with IME anymore, so return. // Not synchronized with IME anymore, so return. return; return; } } Loading @@ -261,7 +271,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, @Override @Override public void onImeEndPositioning(int displayId, boolean cancelled, public void onImeEndPositioning(int displayId, boolean cancelled, SurfaceControl.Transaction t) { SurfaceControl.Transaction t) { if (mAnimation != null) { if (mAnimation != null || !inSplitMode()) { // Not synchronized with IME anymore, so return. // Not synchronized with IME anymore, so return. return; return; } } Loading @@ -271,21 +281,16 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, private void onProgress(float progress, SurfaceControl.Transaction t) { private void onProgress(float progress, SurfaceControl.Transaction t) { if (mTargetAdjusted != mAdjusted) { if (mTargetAdjusted != mAdjusted) { final float fraction = mTargetAdjusted ? progress : 1.f - progress; final float fraction = mTargetAdjusted ? progress : 1.f - progress; mLastAdjustTop = mLastAdjustTop = (int) (fraction * mShownTop + (1.f - fraction) * mHiddenTop); (int) (fraction * mShownTop + (1.f - fraction) * mHiddenTop); mSplitLayout.updateAdjustedBounds(mLastAdjustTop, mHiddenTop, mShownTop); mSplitLayout.updateAdjustedBounds(mLastAdjustTop, mHiddenTop, mShownTop); mView.resizeSplitSurfaces(t, mSplitLayout.mAdjustedPrimary, mView.resizeSplitSurfaces(t, mSplitLayout.mAdjustedPrimary, mSplitLayout.mAdjustedSecondary); mSplitLayout.mAdjustedSecondary); } } final float invProg = 1.f - progress; 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 */, mView.setResizeDimLayer(t, true /* primary */, mLastPrimaryDim * invProg + progress * targetPrimaryDim); mLastPrimaryDim * invProg + progress * mTargetPrimaryDim); mView.setResizeDimLayer(t, false /* primary */, mView.setResizeDimLayer(t, false /* primary */, mLastSecondaryDim * invProg + progress * targetSecondaryDim); mLastSecondaryDim * invProg + progress * mTargetSecondaryDim); } } private void onEnd(boolean cancelled, SurfaceControl.Transaction t) { private void onEnd(boolean cancelled, SurfaceControl.Transaction t) { Loading @@ -294,10 +299,8 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, mAdjusted = mTargetAdjusted; mAdjusted = mTargetAdjusted; mImeWasShown = mTargetShown; mImeWasShown = mTargetShown; mLastAdjustTop = mAdjusted ? mShownTop : mHiddenTop; mLastAdjustTop = mAdjusted ? mShownTop : mHiddenTop; mLastPrimaryDim = mLastPrimaryDim = mTargetPrimaryDim; (mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f; mLastSecondaryDim = mTargetSecondaryDim; mLastSecondaryDim = (!mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f; } } } } Loading Loading @@ -339,7 +342,8 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, }); }); mAnimation.start(); mAnimation.start(); } } }; } private final DividerImeController mImePositionProcessor = new DividerImeController(); public Divider(Context context, Optional<Lazy<Recents>> recentsOptionalLazy, public Divider(Context context, Optional<Lazy<Recents>> recentsOptionalLazy, DisplayController displayController, SystemWindows systemWindows, DisplayController displayController, SystemWindows systemWindows, Loading Loading @@ -513,42 +517,43 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, } } } } private void setHomeStackResizable(boolean resizable) { /** Switch to minimized state if appropriate */ if (mHomeStackResizable == resizable) { public void setMinimized(final boolean minimized) { return; mHandler.post(() -> { WindowContainerTransaction wct = new WindowContainerTransaction(); if (setHomeMinimized(minimized, mHomeStackResizable, wct)) { WindowManagerProxy.applyContainerTransaction(wct); } } mHomeStackResizable = resizable; }); if (!inSplitMode()) { return; } } WindowManagerProxy.applyHomeTasksMinimized(mSplitLayout, mSplits.mSecondary.token); private boolean setHomeMinimized(final boolean minimized, boolean homeStackResizable, WindowContainerTransaction wct) { boolean transact = false; // Update minimized state if (mMinimized != minimized) { mMinimized = minimized; wct.setFocusable(mSplits.mPrimary.token, !mMinimized); transact = true; } } private void updateMinimizedDockedStack(final boolean minimized, final long animDuration, // Update home-stack resizability final boolean isHomeStackResizable) { if (mHomeStackResizable != homeStackResizable) { setHomeStackResizable(isHomeStackResizable); mHomeStackResizable = homeStackResizable; if (animDuration > 0) { if (inSplitMode()) { mView.setMinimizedDockStack(minimized, animDuration, isHomeStackResizable); WindowManagerProxy.applyHomeTasksMinimized( } else { mSplitLayout, mSplits.mSecondary.token, wct); mView.setMinimizedDockStack(minimized, isHomeStackResizable); transact = true; } } updateTouchable(); } } /** Switch to minimized state if appropriate */ // Sync state to DividerView if it exists. public void setMinimized(final boolean minimized) { if (mView != null) { mHandler.post(() -> { mView.setMinimizedDockStack(minimized, getAnimDuration(), homeStackResizable); if (!inSplitMode()) { return; } if (mMinimized == minimized) { return; } } mMinimized = minimized; WindowManagerProxy.applyPrimaryFocusable(mSplits, !mMinimized); mView.setMinimizedDockStack(minimized, getAnimDuration(), mHomeStackResizable); updateTouchable(); updateTouchable(); }); return transact; } } void setAdjustedForIme(boolean adjustedForIme) { void setAdjustedForIme(boolean adjustedForIme) { Loading Loading @@ -646,46 +651,30 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, } } void ensureMinimizedSplit() { void ensureMinimizedSplit() { final boolean wasMinimized = mMinimized; WindowContainerTransaction wct = new WindowContainerTransaction(); mMinimized = true; if (setHomeMinimized(true, mSplits.mSecondary.isResizable(), wct)) { setHomeStackResizable(mSplits.mSecondary.isResizable()); WindowManagerProxy.applyContainerTransaction(wct); 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) { WindowContainerTransaction wct = new WindowContainerTransaction(); WindowManagerProxy.applyPrimaryFocusable(mSplits, true /* focusable */); if (setHomeMinimized(false /* minimized */, mHomeStackResizable, wct)) { WindowManagerProxy.applyContainerTransaction(wct); } } 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); } } } } }
packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java +13 −1 Original line number Original line Diff line number Diff line Loading @@ -165,6 +165,10 @@ public class DividerView extends FrameLayout implements OnTouchListener, // The view is removed or in the process of been removed from the system. // The view is removed or in the process of been removed from the system. private boolean mRemoved; private boolean mRemoved; // Whether the surface for this view has been hidden regardless of actual visibility. This is // used interact with keyguard. private boolean mSurfaceHidden = false; private final Handler mHandler = new Handler() { private final Handler mHandler = new Handler() { @Override @Override public void handleMessage(Message msg) { public void handleMessage(Message msg) { Loading Loading @@ -414,6 +418,10 @@ public class DividerView extends FrameLayout implements OnTouchListener, /** Unlike setVisible, this directly hides the surface without changing view visibility. */ /** Unlike setVisible, this directly hides the surface without changing view visibility. */ void setHidden(boolean hidden) { void setHidden(boolean hidden) { if (mSurfaceHidden == hidden) { return; } mSurfaceHidden = hidden; post(() -> { post(() -> { final SurfaceControl sc = getWindowSurfaceControl(); final SurfaceControl sc = getWindowSurfaceControl(); if (sc == null) { if (sc == null) { Loading @@ -430,6 +438,10 @@ public class DividerView extends FrameLayout implements OnTouchListener, }); }); } } boolean isHidden() { return mSurfaceHidden; } public boolean startDragging(boolean animate, boolean touching) { public boolean startDragging(boolean animate, boolean touching) { cancelFlingAnimation(); cancelFlingAnimation(); if (touching) { if (touching) { Loading Loading @@ -1071,7 +1083,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, void setResizeDimLayer(Transaction t, boolean primary, float alpha) { void setResizeDimLayer(Transaction t, boolean primary, float alpha) { SurfaceControl dim = primary ? mTiles.mPrimaryDim : mTiles.mSecondaryDim; SurfaceControl dim = primary ? mTiles.mPrimaryDim : mTiles.mSecondaryDim; if (alpha <= 0.f) { if (alpha <= 0.001f) { t.hide(dim); t.hide(dim); } else { } else { t.setAlpha(dim, alpha); t.setAlpha(dim, alpha); Loading
packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java +3 −0 Original line number Original line Diff line number Diff line Loading @@ -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; Loading
packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java +3 −18 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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<>(); Loading @@ -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; } } Loading Loading @@ -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) { Loading