Loading packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java +6 −307 Original line number Diff line number Diff line Loading @@ -18,15 +18,10 @@ package com.android.systemui.stackdivider; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED; import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED; import static android.view.Display.DEFAULT_DISPLAY; import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.content.Context; Loading @@ -36,15 +31,11 @@ import android.os.Handler; import android.provider.Settings; import android.util.Slog; import android.view.LayoutInflater; import android.view.SurfaceControl; import android.view.View; import android.window.TaskOrganizer; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import android.window.WindowOrganizer; import androidx.annotation.Nullable; import com.android.internal.policy.DividerSnapAlgorithm; import com.android.systemui.R; import com.android.systemui.SystemUI; Loading Loading @@ -81,7 +72,6 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, static final boolean DEBUG = false; static final int DEFAULT_APP_TRANSITION_DURATION = 336; static final float ADJUSTED_NONFOCUS_DIM = 0.3f; private final Optional<Lazy<Recents>> mRecentsOptionalLazy; Loading Loading @@ -139,303 +129,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, } }; private class DividerImeController implements DisplayImeController.ImePositionProcessor { /** * These are the y positions of the top of the IME surface when it is hidden and when it is * shown respectively. These are NOT necessarily the top of the visible IME itself. */ private int mHiddenTop = 0; private int mShownTop = 0; // 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 * adjusted by height of the IME. This happens when the secondary split is the IME target. */ private boolean mTargetAdjusted = false; /** * {@code true} if, at the end of the animation, the IME should be shown/visible * regardless of what has focus. */ 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 /** {@code true} if the secondary split has IME focus. */ private boolean mSecondaryHasFocus = false; /** The dimming currently applied to the primary/secondary splits. */ private float mLastPrimaryDim = 0.f; private float mLastSecondaryDim = 0.f; /** 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. /** {@code true} if the IME was shown/visible by the last-completed animation. */ private boolean mImeWasShown = false; /** {@code true} if the split positions were adjusted by the last-completed animation. */ private boolean mAdjusted = false; /** * When some aspect of split-screen needs to animate independent from the IME, * this will be non-null and control split animation. */ @Nullable private ValueAnimator mAnimation = null; private boolean mPaused = true; private boolean mPausedTargetAdjusted = false; private boolean getSecondaryHasFocus(int displayId) { WindowContainerToken imeSplit = TaskOrganizer.getImeTarget(displayId); return imeSplit != null && (imeSplit.asBinder() == mSplits.mSecondary.token.asBinder()); } private void updateDimTargets() { final boolean splitIsVisible = !mView.isHidden(); mTargetPrimaryDim = (mSecondaryHasFocus && mTargetShown && splitIsVisible) ? ADJUSTED_NONFOCUS_DIM : 0.f; mTargetSecondaryDim = (!mSecondaryHasFocus && mTargetShown && splitIsVisible) ? ADJUSTED_NONFOCUS_DIM : 0.f; } @Override public void onImeStartPositioning(int displayId, int hiddenTop, int shownTop, boolean imeShouldShow, SurfaceControl.Transaction t) { if (!isDividerVisible()) { return; } final boolean splitIsVisible = !mView.isHidden(); mSecondaryHasFocus = getSecondaryHasFocus(displayId); final boolean targetAdjusted = splitIsVisible && imeShouldShow && mSecondaryHasFocus && !mSplitLayout.mDisplayLayout.isLandscape(); mHiddenTop = hiddenTop; mShownTop = shownTop; mTargetShown = imeShouldShow; if (mLastAdjustTop < 0) { mLastAdjustTop = imeShouldShow ? hiddenTop : shownTop; } else if (mLastAdjustTop != (imeShouldShow ? mShownTop : mHiddenTop)) { if (mTargetAdjusted != targetAdjusted && targetAdjusted == mAdjusted) { // Check for an "interruption" of an existing animation. In this case, we // need to fake-flip the last-known state direction so that the animation // completes in the other direction. mAdjusted = mTargetAdjusted; } else if (targetAdjusted && mTargetAdjusted && mAdjusted) { // Already fully adjusted for IME, but IME height has changed; so, force-start // an async animation to the new IME height. mAdjusted = false; } } if (mPaused) { mPausedTargetAdjusted = targetAdjusted; if (DEBUG) Slog.d(TAG, " ime starting but paused " + dumpState()); return; } mTargetAdjusted = targetAdjusted; updateDimTargets(); if (DEBUG) Slog.d(TAG, " ime starting. vis:" + splitIsVisible + " " + dumpState()); 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(); } 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 // 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); wct.setBounds(mSplits.mPrimary.token, mSplitLayout.mAdjustedPrimary); adjustAppBounds = new Rect(mSplits.mPrimary.configuration .windowConfiguration.getAppBounds()); adjustAppBounds.offset(0, mSplitLayout.mAdjustedPrimary.top - mSplitLayout.mPrimary.top); wct.setAppBounds(mSplits.mPrimary.token, adjustAppBounds); wct.setScreenSizeDp(mSplits.mPrimary.token, mSplits.mPrimary.configuration.screenWidthDp, mSplits.mPrimary.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); wct.setBounds(mSplits.mPrimary.token, mSplitLayout.mPrimary); wct.setAppBounds(mSplits.mPrimary.token, null); wct.setScreenSizeDp(mSplits.mPrimary.token, SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED); } WindowOrganizer.applyTransaction(wct); // Update all the adjusted-for-ime states if (!mPaused) { mView.setAdjustedForIme(mTargetShown, mTargetShown ? DisplayImeController.ANIMATION_DURATION_SHOW_MS : DisplayImeController.ANIMATION_DURATION_HIDE_MS); } setAdjustedForIme(mTargetShown && !mPaused); } @Override public void onImePositionChanged(int displayId, int imeTop, SurfaceControl.Transaction t) { if (mAnimation != null || !isDividerVisible() || mPaused) { // 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 || !isDividerVisible() || mPaused) { // Not synchronized with IME anymore, so return. return; } onEnd(cancelled, t); } private void onProgress(float progress, SurfaceControl.Transaction t) { if (mTargetAdjusted != mAdjusted && !mPaused) { 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; mView.setResizeDimLayer(t, true /* primary */, mLastPrimaryDim * invProg + progress * mTargetPrimaryDim); mView.setResizeDimLayer(t, false /* primary */, mLastSecondaryDim * invProg + progress * mTargetSecondaryDim); } private void onEnd(boolean cancelled, SurfaceControl.Transaction t) { if (!cancelled) { onProgress(1.f, t); mAdjusted = mTargetAdjusted; mImeWasShown = mTargetShown; mLastAdjustTop = mAdjusted ? mShownTop : mHiddenTop; mLastPrimaryDim = mTargetPrimaryDim; mLastSecondaryDim = mTargetSecondaryDim; } } 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(); } private String dumpState() { return "top:" + mHiddenTop + "->" + mShownTop + " adj:" + mAdjusted + "->" + mTargetAdjusted + "(" + mLastAdjustTop + ")" + " shw:" + mImeWasShown + "->" + mTargetShown + " dims:" + mLastPrimaryDim + "," + mLastSecondaryDim + "->" + mTargetPrimaryDim + "," + mTargetSecondaryDim + " shf:" + mSecondaryHasFocus + " desync:" + (mAnimation != null) + " paus:" + mPaused + "[" + mPausedTargetAdjusted + "]"; } /** Completely aborts/resets adjustment state */ public void pause(int displayId) { if (DEBUG) Slog.d(TAG, "ime pause posting " + dumpState()); mHandler.post(() -> { if (DEBUG) Slog.d(TAG, "ime pause run posted " + dumpState()); if (mPaused) { return; } mPaused = true; mPausedTargetAdjusted = mTargetAdjusted; mTargetAdjusted = false; mTargetPrimaryDim = mTargetSecondaryDim = 0.f; updateImeAdjustState(); startAsyncAnimation(); if (mAnimation != null) { mAnimation.end(); } }); } public void resume(int displayId) { if (DEBUG) Slog.d(TAG, "ime resume posting " + dumpState()); mHandler.post(() -> { if (DEBUG) Slog.d(TAG, "ime resume run posted " + dumpState()); if (!mPaused) { return; } mPaused = false; mTargetAdjusted = mPausedTargetAdjusted; updateDimTargets(); if ((mTargetAdjusted != mAdjusted) && !mMinimized && mView != null) { // End unminimize animations since they conflict with adjustment animations. mView.finishAnimations(); } updateImeAdjustState(); startAsyncAnimation(); }); } } private final DividerImeController mImePositionProcessor = new DividerImeController(); private final DividerImeController mImePositionProcessor; private TaskStackChangeListener mActivityRestartListener = new TaskStackChangeListener() { @Override Loading Loading @@ -465,6 +159,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, mRecentsOptionalLazy = recentsOptionalLazy; mForcedResizableController = new ForcedResizableInfoActivityController(context, this); mTransactionPool = transactionPool; mImePositionProcessor = new DividerImeController(mSplits, mTransactionPool, mHandler); } @Override Loading Loading @@ -830,6 +525,10 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, } } SplitDisplayLayout getSplitLayout() { return mSplitLayout; } /** @return the container token for the secondary split root task. */ public WindowContainerToken getSecondaryRoot() { if (mSplits == null || mSplits.mSecondary == null) { Loading packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java 0 → 100644 +368 −0 File added.Preview size limit exceeded, changes collapsed. Show changes Loading
packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java +6 −307 Original line number Diff line number Diff line Loading @@ -18,15 +18,10 @@ package com.android.systemui.stackdivider; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED; import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED; import static android.view.Display.DEFAULT_DISPLAY; import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.content.Context; Loading @@ -36,15 +31,11 @@ import android.os.Handler; import android.provider.Settings; import android.util.Slog; import android.view.LayoutInflater; import android.view.SurfaceControl; import android.view.View; import android.window.TaskOrganizer; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import android.window.WindowOrganizer; import androidx.annotation.Nullable; import com.android.internal.policy.DividerSnapAlgorithm; import com.android.systemui.R; import com.android.systemui.SystemUI; Loading Loading @@ -81,7 +72,6 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, static final boolean DEBUG = false; static final int DEFAULT_APP_TRANSITION_DURATION = 336; static final float ADJUSTED_NONFOCUS_DIM = 0.3f; private final Optional<Lazy<Recents>> mRecentsOptionalLazy; Loading Loading @@ -139,303 +129,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, } }; private class DividerImeController implements DisplayImeController.ImePositionProcessor { /** * These are the y positions of the top of the IME surface when it is hidden and when it is * shown respectively. These are NOT necessarily the top of the visible IME itself. */ private int mHiddenTop = 0; private int mShownTop = 0; // 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 * adjusted by height of the IME. This happens when the secondary split is the IME target. */ private boolean mTargetAdjusted = false; /** * {@code true} if, at the end of the animation, the IME should be shown/visible * regardless of what has focus. */ 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 /** {@code true} if the secondary split has IME focus. */ private boolean mSecondaryHasFocus = false; /** The dimming currently applied to the primary/secondary splits. */ private float mLastPrimaryDim = 0.f; private float mLastSecondaryDim = 0.f; /** 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. /** {@code true} if the IME was shown/visible by the last-completed animation. */ private boolean mImeWasShown = false; /** {@code true} if the split positions were adjusted by the last-completed animation. */ private boolean mAdjusted = false; /** * When some aspect of split-screen needs to animate independent from the IME, * this will be non-null and control split animation. */ @Nullable private ValueAnimator mAnimation = null; private boolean mPaused = true; private boolean mPausedTargetAdjusted = false; private boolean getSecondaryHasFocus(int displayId) { WindowContainerToken imeSplit = TaskOrganizer.getImeTarget(displayId); return imeSplit != null && (imeSplit.asBinder() == mSplits.mSecondary.token.asBinder()); } private void updateDimTargets() { final boolean splitIsVisible = !mView.isHidden(); mTargetPrimaryDim = (mSecondaryHasFocus && mTargetShown && splitIsVisible) ? ADJUSTED_NONFOCUS_DIM : 0.f; mTargetSecondaryDim = (!mSecondaryHasFocus && mTargetShown && splitIsVisible) ? ADJUSTED_NONFOCUS_DIM : 0.f; } @Override public void onImeStartPositioning(int displayId, int hiddenTop, int shownTop, boolean imeShouldShow, SurfaceControl.Transaction t) { if (!isDividerVisible()) { return; } final boolean splitIsVisible = !mView.isHidden(); mSecondaryHasFocus = getSecondaryHasFocus(displayId); final boolean targetAdjusted = splitIsVisible && imeShouldShow && mSecondaryHasFocus && !mSplitLayout.mDisplayLayout.isLandscape(); mHiddenTop = hiddenTop; mShownTop = shownTop; mTargetShown = imeShouldShow; if (mLastAdjustTop < 0) { mLastAdjustTop = imeShouldShow ? hiddenTop : shownTop; } else if (mLastAdjustTop != (imeShouldShow ? mShownTop : mHiddenTop)) { if (mTargetAdjusted != targetAdjusted && targetAdjusted == mAdjusted) { // Check for an "interruption" of an existing animation. In this case, we // need to fake-flip the last-known state direction so that the animation // completes in the other direction. mAdjusted = mTargetAdjusted; } else if (targetAdjusted && mTargetAdjusted && mAdjusted) { // Already fully adjusted for IME, but IME height has changed; so, force-start // an async animation to the new IME height. mAdjusted = false; } } if (mPaused) { mPausedTargetAdjusted = targetAdjusted; if (DEBUG) Slog.d(TAG, " ime starting but paused " + dumpState()); return; } mTargetAdjusted = targetAdjusted; updateDimTargets(); if (DEBUG) Slog.d(TAG, " ime starting. vis:" + splitIsVisible + " " + dumpState()); 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(); } 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 // 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); wct.setBounds(mSplits.mPrimary.token, mSplitLayout.mAdjustedPrimary); adjustAppBounds = new Rect(mSplits.mPrimary.configuration .windowConfiguration.getAppBounds()); adjustAppBounds.offset(0, mSplitLayout.mAdjustedPrimary.top - mSplitLayout.mPrimary.top); wct.setAppBounds(mSplits.mPrimary.token, adjustAppBounds); wct.setScreenSizeDp(mSplits.mPrimary.token, mSplits.mPrimary.configuration.screenWidthDp, mSplits.mPrimary.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); wct.setBounds(mSplits.mPrimary.token, mSplitLayout.mPrimary); wct.setAppBounds(mSplits.mPrimary.token, null); wct.setScreenSizeDp(mSplits.mPrimary.token, SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED); } WindowOrganizer.applyTransaction(wct); // Update all the adjusted-for-ime states if (!mPaused) { mView.setAdjustedForIme(mTargetShown, mTargetShown ? DisplayImeController.ANIMATION_DURATION_SHOW_MS : DisplayImeController.ANIMATION_DURATION_HIDE_MS); } setAdjustedForIme(mTargetShown && !mPaused); } @Override public void onImePositionChanged(int displayId, int imeTop, SurfaceControl.Transaction t) { if (mAnimation != null || !isDividerVisible() || mPaused) { // 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 || !isDividerVisible() || mPaused) { // Not synchronized with IME anymore, so return. return; } onEnd(cancelled, t); } private void onProgress(float progress, SurfaceControl.Transaction t) { if (mTargetAdjusted != mAdjusted && !mPaused) { 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; mView.setResizeDimLayer(t, true /* primary */, mLastPrimaryDim * invProg + progress * mTargetPrimaryDim); mView.setResizeDimLayer(t, false /* primary */, mLastSecondaryDim * invProg + progress * mTargetSecondaryDim); } private void onEnd(boolean cancelled, SurfaceControl.Transaction t) { if (!cancelled) { onProgress(1.f, t); mAdjusted = mTargetAdjusted; mImeWasShown = mTargetShown; mLastAdjustTop = mAdjusted ? mShownTop : mHiddenTop; mLastPrimaryDim = mTargetPrimaryDim; mLastSecondaryDim = mTargetSecondaryDim; } } 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(); } private String dumpState() { return "top:" + mHiddenTop + "->" + mShownTop + " adj:" + mAdjusted + "->" + mTargetAdjusted + "(" + mLastAdjustTop + ")" + " shw:" + mImeWasShown + "->" + mTargetShown + " dims:" + mLastPrimaryDim + "," + mLastSecondaryDim + "->" + mTargetPrimaryDim + "," + mTargetSecondaryDim + " shf:" + mSecondaryHasFocus + " desync:" + (mAnimation != null) + " paus:" + mPaused + "[" + mPausedTargetAdjusted + "]"; } /** Completely aborts/resets adjustment state */ public void pause(int displayId) { if (DEBUG) Slog.d(TAG, "ime pause posting " + dumpState()); mHandler.post(() -> { if (DEBUG) Slog.d(TAG, "ime pause run posted " + dumpState()); if (mPaused) { return; } mPaused = true; mPausedTargetAdjusted = mTargetAdjusted; mTargetAdjusted = false; mTargetPrimaryDim = mTargetSecondaryDim = 0.f; updateImeAdjustState(); startAsyncAnimation(); if (mAnimation != null) { mAnimation.end(); } }); } public void resume(int displayId) { if (DEBUG) Slog.d(TAG, "ime resume posting " + dumpState()); mHandler.post(() -> { if (DEBUG) Slog.d(TAG, "ime resume run posted " + dumpState()); if (!mPaused) { return; } mPaused = false; mTargetAdjusted = mPausedTargetAdjusted; updateDimTargets(); if ((mTargetAdjusted != mAdjusted) && !mMinimized && mView != null) { // End unminimize animations since they conflict with adjustment animations. mView.finishAnimations(); } updateImeAdjustState(); startAsyncAnimation(); }); } } private final DividerImeController mImePositionProcessor = new DividerImeController(); private final DividerImeController mImePositionProcessor; private TaskStackChangeListener mActivityRestartListener = new TaskStackChangeListener() { @Override Loading Loading @@ -465,6 +159,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, mRecentsOptionalLazy = recentsOptionalLazy; mForcedResizableController = new ForcedResizableInfoActivityController(context, this); mTransactionPool = transactionPool; mImePositionProcessor = new DividerImeController(mSplits, mTransactionPool, mHandler); } @Override Loading Loading @@ -830,6 +525,10 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, } } SplitDisplayLayout getSplitLayout() { return mSplitLayout; } /** @return the container token for the secondary split root task. */ public WindowContainerToken getSecondaryRoot() { if (mSplits == null || mSplits.mSecondary == null) { Loading
packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java 0 → 100644 +368 −0 File added.Preview size limit exceeded, changes collapsed. Show changes