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