Loading libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java +5 −3 Original line number Diff line number Diff line Loading @@ -163,6 +163,7 @@ public class OneHandedAnimationController { mOneHandedAnimationCallbacks.forEach( (callback) -> callback.onOneHandedAnimationEnd(tx, this) ); mOneHandedAnimationCallbacks.clear(); } @Override Loading @@ -171,6 +172,7 @@ public class OneHandedAnimationController { mOneHandedAnimationCallbacks.forEach( (callback) -> callback.onOneHandedAnimationCancel(this) ); mOneHandedAnimationCallbacks.clear(); } @Override Loading @@ -182,7 +184,7 @@ public class OneHandedAnimationController { final SurfaceControl.Transaction tx = newSurfaceControlTransaction(); applySurfaceControlTransaction(mLeash, tx, animation.getAnimatedFraction()); mOneHandedAnimationCallbacks.forEach( (callback) -> callback.onAnimationUpdate(0f, (float) mCurrentValue) (callback) -> callback.onAnimationUpdate(0f, mCurrentValue) ); } Loading Loading @@ -216,7 +218,7 @@ public class OneHandedAnimationController { } float getDestinationOffset() { return ((float) mEndValue - (float) mStartValue); return (mEndValue - mStartValue); } @TransitionDirection Loading Loading @@ -302,7 +304,7 @@ public class OneHandedAnimationController { @Override public float getInterpolation(float input) { return (float) (Math.pow(2, -10 * input) * Math.sin(((input - 4.0f) / 4.0f) * (2.0f * Math.PI) / 4.0f) + 1); * (2.0f * Math.PI) / 4.0f) + 1.0f); } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java +27 −29 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.wm.shell.onehanded; import static android.view.View.LAYER_TYPE_HARDWARE; import static android.view.View.LAYER_TYPE_NONE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static com.android.wm.shell.onehanded.OneHandedState.STATE_ACTIVE; Loading Loading @@ -45,9 +47,8 @@ import java.io.PrintWriter; /** * Handles tutorial visibility and synchronized transition for One Handed operations, * TargetViewContainer only be created and attach to window when * shown counts < {@link MAX_TUTORIAL_SHOW_COUNT}, and detach TargetViewContainer from window * after exiting one handed mode. * TargetViewContainer only be created and always attach to window, * detach TargetViewContainer from window after exiting one handed mode. */ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, OneHandedState.OnStateChangedListener { Loading @@ -58,7 +59,6 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, private final float mTutorialHeightRatio; private final WindowManager mWindowManager; private boolean mIsShowing; private @OneHandedState.State int mCurrentState; private int mTutorialAreaHeight; Loading @@ -80,11 +80,10 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, mAnimationCallback = new OneHandedAnimationCallback() { @Override public void onAnimationUpdate(float xPos, float yPos) { if (!isShowing()) { if (!isAttached()) { return; } mTargetViewContainer.setTransitionGroup(true); mTargetViewContainer.setTranslationY(yPos - mTargetViewContainer.getHeight()); mTargetViewContainer.setTranslationY(yPos - mTutorialAreaHeight); } }; } Loading @@ -101,7 +100,7 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, // no - op break; case STATE_NONE: removeTutorialFromWindowManager(true /* increment */); removeTutorialFromWindowManager(); break; default: break; Loading @@ -124,13 +123,14 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, @VisibleForTesting void createViewAndAttachToWindow(Context context) { if (isShowing()) { if (isAttached()) { return; } mTutorialView = LayoutInflater.from(context).inflate(R.layout.one_handed_tutorial, null); mTargetViewContainer = new FrameLayout(context); mTargetViewContainer.setClipChildren(false); mTargetViewContainer.addView(mTutorialView); mTargetViewContainer.setLayerType(LAYER_TYPE_HARDWARE, null); attachTargetToWindow(); } Loading @@ -139,29 +139,27 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, * Adds the tutorial target view to the WindowManager and update its layout. */ private void attachTargetToWindow() { if (!mTargetViewContainer.isAttachedToWindow()) { try { mWindowManager.addView(mTargetViewContainer, getTutorialTargetLayoutParams()); mIsShowing = true; } catch (IllegalStateException e) { // This shouldn't happen, but if the target is already added, just update its // layout params. mWindowManager.updateViewLayout( mTargetViewContainer, getTutorialTargetLayoutParams()); } mWindowManager.updateViewLayout(mTargetViewContainer, getTutorialTargetLayoutParams()); } } @VisibleForTesting void removeTutorialFromWindowManager(boolean increment) { if (mTargetViewContainer != null && mTargetViewContainer.isAttachedToWindow()) { mWindowManager.removeViewImmediate(mTargetViewContainer); mIsShowing = false; void removeTutorialFromWindowManager() { if (!isAttached()) { return; } mTargetViewContainer.setLayerType(LAYER_TYPE_NONE, null); mWindowManager.removeViewImmediate(mTargetViewContainer); mTargetViewContainer = null; } @Nullable OneHandedAnimationCallback getAnimationCallback() { return isShowing() ? mAnimationCallback : null /* Disabled */; return mAnimationCallback; } /** Loading @@ -183,15 +181,15 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, } @VisibleForTesting boolean isShowing() { return mIsShowing; boolean isAttached() { return mTargetViewContainer != null && mTargetViewContainer.isAttachedToWindow(); } /** * onConfigurationChanged events for updating tutorial text. */ public void onConfigurationChanged() { removeTutorialFromWindowManager(false /* increment */); removeTutorialFromWindowManager(); if (mCurrentState == STATE_ENTERING || mCurrentState == STATE_ACTIVE) { createViewAndAttachToWindow(mContext); } Loading @@ -200,8 +198,8 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, void dump(@NonNull PrintWriter pw) { final String innerPrefix = " "; pw.println(TAG); pw.print(innerPrefix + "mIsShowing="); pw.println(mIsShowing); pw.print(innerPrefix + "isAttached="); pw.println(isAttached()); pw.print(innerPrefix + "mCurrentState="); pw.println(mCurrentState); pw.print(innerPrefix + "mDisplayBounds="); Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java +14 −7 Original line number Diff line number Diff line Loading @@ -77,7 +77,7 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase { @Test public void testOnStateChangedEntering_createViewAndAttachToWindow() { when(mSpiedTutorialHandler.isShowing()).thenReturn(true); when(mSpiedTutorialHandler.isAttached()).thenReturn(true); try { mSpiedTutorialHandler.onStateChanged(STATE_ENTERING); } catch (ClassCastException e) { Loading @@ -89,23 +89,27 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase { @Test public void testOnStateChangedNone_removeViewAndAttachToWindow() { when(mSpiedTutorialHandler.isShowing()).thenReturn(true); when(mSpiedTutorialHandler.isAttached()).thenReturn(true); try { mSpiedTutorialHandler.onStateChanged(STATE_NONE); } catch (ClassCastException e) { // no-op, just assert removeTutorialFromWindowManager() to be called } catch (NullPointerException e) { // no-op, just assert removeTutorialFromWindowManager() to be called } verify(mSpiedTutorialHandler).removeTutorialFromWindowManager(true); verify(mSpiedTutorialHandler).removeTutorialFromWindowManager(); } @Test public void testOnStateChangedNone_shouldNotAttachWindow() { when(mSpiedTutorialHandler.isShowing()).thenReturn(true); when(mSpiedTutorialHandler.isAttached()).thenReturn(true); try { mSpiedTutorialHandler.onStateChanged(STATE_NONE); } catch (ClassCastException e) { // no-op, just assert setTutorialShownCountIncrement() never be called } catch (NullPointerException e) { // no-op, just assert setTutorialShownCountIncrement() never be called } verify(mSpiedTutorialHandler, never()).createViewAndAttachToWindow(any()); Loading @@ -113,7 +117,7 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase { @Test public void testOnConfigurationChanged_shouldUpdateViewContent() { when(mSpiedTutorialHandler.isShowing()).thenReturn(true); when(mSpiedTutorialHandler.isAttached()).thenReturn(true); try { mSpiedTutorialHandler.onStateChanged(STATE_ENTERING); } catch (ClassCastException e) { Loading @@ -122,9 +126,12 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase { try { mSpiedTutorialHandler.onConfigurationChanged(); } catch (ClassCastException e) { // no-op, just assert removeTutorialFromWindowManager() be called } catch (NullPointerException e) { // no-op, just assert removeTutorialFromWindowManager() be called, // and createViewAndAttachToWindow() be called twice } verify(mSpiedTutorialHandler).removeTutorialFromWindowManager(false); verify(mSpiedTutorialHandler).createViewAndAttachToWindow(any()); verify(mSpiedTutorialHandler).removeTutorialFromWindowManager(); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java +5 −3 Original line number Diff line number Diff line Loading @@ -163,6 +163,7 @@ public class OneHandedAnimationController { mOneHandedAnimationCallbacks.forEach( (callback) -> callback.onOneHandedAnimationEnd(tx, this) ); mOneHandedAnimationCallbacks.clear(); } @Override Loading @@ -171,6 +172,7 @@ public class OneHandedAnimationController { mOneHandedAnimationCallbacks.forEach( (callback) -> callback.onOneHandedAnimationCancel(this) ); mOneHandedAnimationCallbacks.clear(); } @Override Loading @@ -182,7 +184,7 @@ public class OneHandedAnimationController { final SurfaceControl.Transaction tx = newSurfaceControlTransaction(); applySurfaceControlTransaction(mLeash, tx, animation.getAnimatedFraction()); mOneHandedAnimationCallbacks.forEach( (callback) -> callback.onAnimationUpdate(0f, (float) mCurrentValue) (callback) -> callback.onAnimationUpdate(0f, mCurrentValue) ); } Loading Loading @@ -216,7 +218,7 @@ public class OneHandedAnimationController { } float getDestinationOffset() { return ((float) mEndValue - (float) mStartValue); return (mEndValue - mStartValue); } @TransitionDirection Loading Loading @@ -302,7 +304,7 @@ public class OneHandedAnimationController { @Override public float getInterpolation(float input) { return (float) (Math.pow(2, -10 * input) * Math.sin(((input - 4.0f) / 4.0f) * (2.0f * Math.PI) / 4.0f) + 1); * (2.0f * Math.PI) / 4.0f) + 1.0f); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java +27 −29 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.wm.shell.onehanded; import static android.view.View.LAYER_TYPE_HARDWARE; import static android.view.View.LAYER_TYPE_NONE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static com.android.wm.shell.onehanded.OneHandedState.STATE_ACTIVE; Loading Loading @@ -45,9 +47,8 @@ import java.io.PrintWriter; /** * Handles tutorial visibility and synchronized transition for One Handed operations, * TargetViewContainer only be created and attach to window when * shown counts < {@link MAX_TUTORIAL_SHOW_COUNT}, and detach TargetViewContainer from window * after exiting one handed mode. * TargetViewContainer only be created and always attach to window, * detach TargetViewContainer from window after exiting one handed mode. */ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, OneHandedState.OnStateChangedListener { Loading @@ -58,7 +59,6 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, private final float mTutorialHeightRatio; private final WindowManager mWindowManager; private boolean mIsShowing; private @OneHandedState.State int mCurrentState; private int mTutorialAreaHeight; Loading @@ -80,11 +80,10 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, mAnimationCallback = new OneHandedAnimationCallback() { @Override public void onAnimationUpdate(float xPos, float yPos) { if (!isShowing()) { if (!isAttached()) { return; } mTargetViewContainer.setTransitionGroup(true); mTargetViewContainer.setTranslationY(yPos - mTargetViewContainer.getHeight()); mTargetViewContainer.setTranslationY(yPos - mTutorialAreaHeight); } }; } Loading @@ -101,7 +100,7 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, // no - op break; case STATE_NONE: removeTutorialFromWindowManager(true /* increment */); removeTutorialFromWindowManager(); break; default: break; Loading @@ -124,13 +123,14 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, @VisibleForTesting void createViewAndAttachToWindow(Context context) { if (isShowing()) { if (isAttached()) { return; } mTutorialView = LayoutInflater.from(context).inflate(R.layout.one_handed_tutorial, null); mTargetViewContainer = new FrameLayout(context); mTargetViewContainer.setClipChildren(false); mTargetViewContainer.addView(mTutorialView); mTargetViewContainer.setLayerType(LAYER_TYPE_HARDWARE, null); attachTargetToWindow(); } Loading @@ -139,29 +139,27 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, * Adds the tutorial target view to the WindowManager and update its layout. */ private void attachTargetToWindow() { if (!mTargetViewContainer.isAttachedToWindow()) { try { mWindowManager.addView(mTargetViewContainer, getTutorialTargetLayoutParams()); mIsShowing = true; } catch (IllegalStateException e) { // This shouldn't happen, but if the target is already added, just update its // layout params. mWindowManager.updateViewLayout( mTargetViewContainer, getTutorialTargetLayoutParams()); } mWindowManager.updateViewLayout(mTargetViewContainer, getTutorialTargetLayoutParams()); } } @VisibleForTesting void removeTutorialFromWindowManager(boolean increment) { if (mTargetViewContainer != null && mTargetViewContainer.isAttachedToWindow()) { mWindowManager.removeViewImmediate(mTargetViewContainer); mIsShowing = false; void removeTutorialFromWindowManager() { if (!isAttached()) { return; } mTargetViewContainer.setLayerType(LAYER_TYPE_NONE, null); mWindowManager.removeViewImmediate(mTargetViewContainer); mTargetViewContainer = null; } @Nullable OneHandedAnimationCallback getAnimationCallback() { return isShowing() ? mAnimationCallback : null /* Disabled */; return mAnimationCallback; } /** Loading @@ -183,15 +181,15 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, } @VisibleForTesting boolean isShowing() { return mIsShowing; boolean isAttached() { return mTargetViewContainer != null && mTargetViewContainer.isAttachedToWindow(); } /** * onConfigurationChanged events for updating tutorial text. */ public void onConfigurationChanged() { removeTutorialFromWindowManager(false /* increment */); removeTutorialFromWindowManager(); if (mCurrentState == STATE_ENTERING || mCurrentState == STATE_ACTIVE) { createViewAndAttachToWindow(mContext); } Loading @@ -200,8 +198,8 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, void dump(@NonNull PrintWriter pw) { final String innerPrefix = " "; pw.println(TAG); pw.print(innerPrefix + "mIsShowing="); pw.println(mIsShowing); pw.print(innerPrefix + "isAttached="); pw.println(isAttached()); pw.print(innerPrefix + "mCurrentState="); pw.println(mCurrentState); pw.print(innerPrefix + "mDisplayBounds="); Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java +14 −7 Original line number Diff line number Diff line Loading @@ -77,7 +77,7 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase { @Test public void testOnStateChangedEntering_createViewAndAttachToWindow() { when(mSpiedTutorialHandler.isShowing()).thenReturn(true); when(mSpiedTutorialHandler.isAttached()).thenReturn(true); try { mSpiedTutorialHandler.onStateChanged(STATE_ENTERING); } catch (ClassCastException e) { Loading @@ -89,23 +89,27 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase { @Test public void testOnStateChangedNone_removeViewAndAttachToWindow() { when(mSpiedTutorialHandler.isShowing()).thenReturn(true); when(mSpiedTutorialHandler.isAttached()).thenReturn(true); try { mSpiedTutorialHandler.onStateChanged(STATE_NONE); } catch (ClassCastException e) { // no-op, just assert removeTutorialFromWindowManager() to be called } catch (NullPointerException e) { // no-op, just assert removeTutorialFromWindowManager() to be called } verify(mSpiedTutorialHandler).removeTutorialFromWindowManager(true); verify(mSpiedTutorialHandler).removeTutorialFromWindowManager(); } @Test public void testOnStateChangedNone_shouldNotAttachWindow() { when(mSpiedTutorialHandler.isShowing()).thenReturn(true); when(mSpiedTutorialHandler.isAttached()).thenReturn(true); try { mSpiedTutorialHandler.onStateChanged(STATE_NONE); } catch (ClassCastException e) { // no-op, just assert setTutorialShownCountIncrement() never be called } catch (NullPointerException e) { // no-op, just assert setTutorialShownCountIncrement() never be called } verify(mSpiedTutorialHandler, never()).createViewAndAttachToWindow(any()); Loading @@ -113,7 +117,7 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase { @Test public void testOnConfigurationChanged_shouldUpdateViewContent() { when(mSpiedTutorialHandler.isShowing()).thenReturn(true); when(mSpiedTutorialHandler.isAttached()).thenReturn(true); try { mSpiedTutorialHandler.onStateChanged(STATE_ENTERING); } catch (ClassCastException e) { Loading @@ -122,9 +126,12 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase { try { mSpiedTutorialHandler.onConfigurationChanged(); } catch (ClassCastException e) { // no-op, just assert removeTutorialFromWindowManager() be called } catch (NullPointerException e) { // no-op, just assert removeTutorialFromWindowManager() be called, // and createViewAndAttachToWindow() be called twice } verify(mSpiedTutorialHandler).removeTutorialFromWindowManager(false); verify(mSpiedTutorialHandler).createViewAndAttachToWindow(any()); verify(mSpiedTutorialHandler).removeTutorialFromWindowManager(); } }