Fix One-handed tutorial looks janky on entering transition
According to systrace, one-handed-tutorial-overlay got jank problem(SurfaceFlinger GPU Deadline Missed, App Deadline Missed, Buffer stuffing). 1.setLayerType(LAYER_TYPE_HARDWARE) when create targetViewContainer setLayerType(LAYER_TYPE_NONE) when removeTutorialFromWindowManager 2.Rename isShowing() to isAttached() 3.Remove redundant float casting 4.Remove redundant increment param Test: manual trigger OHM Test: atest WMShellUnitTests Bug: 193589897 Change-Id: Ieec397795b46dee9ca04375bfc26b09441688d08
This commit is contained in:
@@ -163,6 +163,7 @@ public class OneHandedAnimationController {
|
||||
mOneHandedAnimationCallbacks.forEach(
|
||||
(callback) -> callback.onOneHandedAnimationEnd(tx, this)
|
||||
);
|
||||
mOneHandedAnimationCallbacks.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -171,6 +172,7 @@ public class OneHandedAnimationController {
|
||||
mOneHandedAnimationCallbacks.forEach(
|
||||
(callback) -> callback.onOneHandedAnimationCancel(this)
|
||||
);
|
||||
mOneHandedAnimationCallbacks.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -216,7 +218,7 @@ public class OneHandedAnimationController {
|
||||
}
|
||||
|
||||
float getDestinationOffset() {
|
||||
return ((float) mEndValue - (float) mStartValue);
|
||||
return (mEndValue - mStartValue);
|
||||
}
|
||||
|
||||
@TransitionDirection
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -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 {
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -101,7 +100,7 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback,
|
||||
// no - op
|
||||
break;
|
||||
case STATE_NONE:
|
||||
removeTutorialFromWindowManager(true /* increment */);
|
||||
removeTutorialFromWindowManager();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
try {
|
||||
mWindowManager.addView(mTargetViewContainer, getTutorialTargetLayoutParams());
|
||||
} catch (IllegalStateException e) {
|
||||
// This shouldn't happen, but if the target is already added, just update its
|
||||
// layout params.
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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=");
|
||||
|
||||
@@ -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) {
|
||||
@@ -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());
|
||||
@@ -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) {
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user