diff options
| author | 2025-01-10 00:09:59 -0800 | |
|---|---|---|
| committer | 2025-01-10 00:09:59 -0800 | |
| commit | 23b0528ae62fbef393e8ea96c25902c76686edc7 (patch) | |
| tree | ddca226edcf121288d9bcaa5201c2956f86bd5c5 | |
| parent | 15b8a9121cd227dbc0281df513817e77cf7ae009 (diff) | |
| parent | 0f2e5645a6fccc53ae17e6f50feb3a09900c427a (diff) | |
Merge "fix(fullscreen magnification): Fix the race condition issues on the magnification border" into main
2 files changed, 204 insertions, 240 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/FullscreenMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/FullscreenMagnificationController.java index 04afd8693e04..caf043a1b1be 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/FullscreenMagnificationController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/FullscreenMagnificationController.java @@ -22,6 +22,8 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; +import android.annotation.IntDef; +import android.annotation.Nullable; import android.annotation.UiContext; import android.content.ComponentCallbacks; import android.content.Context; @@ -44,7 +46,8 @@ import android.view.SurfaceControlViewHost; import android.view.View; import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; -import android.view.animation.AccelerateDecelerateInterpolator; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; import androidx.annotation.NonNull; @@ -57,12 +60,16 @@ import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.res.R; import com.android.systemui.util.leak.RotationUtils; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.concurrent.Executor; import java.util.function.Supplier; public class FullscreenMagnificationController implements ComponentCallbacks { - private static final String TAG = "FullscreenMagnificationController"; + private static final String TAG = "FullscreenMagController"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + private final Context mContext; private final AccessibilityManager mAccessibilityManager; private final WindowManager mWindowManager; @@ -77,12 +84,14 @@ public class FullscreenMagnificationController implements ComponentCallbacks { private int mBorderStoke; private final int mDisplayId; private static final Region sEmptyRegion = new Region(); - private ValueAnimator mShowHideBorderAnimator; + @VisibleForTesting + @Nullable + ValueAnimator mShowHideBorderAnimator; private Handler mHandler; private Executor mExecutor; - private boolean mFullscreenMagnificationActivated = false; private final Configuration mConfiguration; - private final Runnable mShowBorderRunnable = this::showBorderWithNullCheck; + private final Runnable mHideBorderImmediatelyRunnable = this::hideBorderImmediately; + private final Runnable mShowBorderRunnable = this::showBorder; private int mRotation; private final IRotationWatcher mRotationWatcher = new IRotationWatcher.Stub() { @Override @@ -95,6 +104,21 @@ public class FullscreenMagnificationController implements ComponentCallbacks { private final DisplayManager.DisplayListener mDisplayListener; private String mCurrentDisplayUniqueId; + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + DISABLED, + DISABLING, + ENABLING, + ENABLED + }) + @interface FullscreenMagnificationActivationState {} + private static final int DISABLED = 0; + private static final int DISABLING = 1; + private static final int ENABLING = 2; + private static final int ENABLED = 3; + @FullscreenMagnificationActivationState + private int mActivationState = DISABLED; + public FullscreenMagnificationController( @UiContext Context context, @Main Handler handler, @@ -106,7 +130,7 @@ public class FullscreenMagnificationController implements ComponentCallbacks { Supplier<SurfaceControlViewHost> scvhSupplier) { this(context, handler, executor, displayManager, accessibilityManager, windowManager, iWindowManager, scvhSupplier, - new SurfaceControl.Transaction(), null); + new SurfaceControl.Transaction()); } @VisibleForTesting @@ -119,8 +143,7 @@ public class FullscreenMagnificationController implements ComponentCallbacks { WindowManager windowManager, IWindowManager iWindowManager, Supplier<SurfaceControlViewHost> scvhSupplier, - SurfaceControl.Transaction transaction, - ValueAnimator valueAnimator) { + SurfaceControl.Transaction transaction) { mContext = context; mHandler = handler; mExecutor = executor; @@ -135,18 +158,6 @@ public class FullscreenMagnificationController implements ComponentCallbacks { mConfiguration = new Configuration(context.getResources().getConfiguration()); mLongAnimationTimeMs = mContext.getResources().getInteger( com.android.internal.R.integer.config_longAnimTime); - mShowHideBorderAnimator = (valueAnimator == null) - ? createNullTargetObjectAnimator() : valueAnimator; - mShowHideBorderAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(@NonNull Animator animation, boolean isReverse) { - if (isReverse) { - // The animation was played in reverse, which means we are hiding the border. - // We would like to perform clean up after the border is fully hidden. - cleanUpBorder(); - } - } - }); mCurrentDisplayUniqueId = mContext.getDisplayNoVerify().getUniqueId(); mDisplayManager = displayManager; mDisplayListener = new DisplayManager.DisplayListener() { @@ -167,20 +178,51 @@ public class FullscreenMagnificationController implements ComponentCallbacks { // Same unique ID means the physical display doesn't change. Early return. return; } - mCurrentDisplayUniqueId = uniqueId; - applyCornerRadiusToBorder(); + mHandler.post(FullscreenMagnificationController.this::applyCornerRadiusToBorder); } }; } - private ValueAnimator createNullTargetObjectAnimator() { + @VisibleForTesting + @UiThread + ValueAnimator createShowTargetAnimator(@NonNull View target) { + if (mShowHideBorderAnimator != null) { + mShowHideBorderAnimator.cancel(); + } + final ValueAnimator valueAnimator = - ObjectAnimator.ofFloat(/* target= */ null, View.ALPHA, 0f, 1f); - Interpolator interpolator = new AccelerateDecelerateInterpolator(); + ObjectAnimator.ofFloat(target, View.ALPHA, 0f, 1f); + Interpolator interpolator = new AccelerateInterpolator(); valueAnimator.setInterpolator(interpolator); valueAnimator.setDuration(mLongAnimationTimeMs); + valueAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(@NonNull Animator animation) { + mHandler.post(() -> setState(ENABLED)); + }}); + return valueAnimator; + } + + @VisibleForTesting + @UiThread + ValueAnimator createHideTargetAnimator(@NonNull View target) { + if (mShowHideBorderAnimator != null) { + mShowHideBorderAnimator.cancel(); + } + + final ValueAnimator valueAnimator = + ObjectAnimator.ofFloat(target, View.ALPHA, 1f, 0f); + Interpolator interpolator = new DecelerateInterpolator(); + + valueAnimator.setInterpolator(interpolator); + valueAnimator.setDuration(mLongAnimationTimeMs); + valueAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(@NonNull Animator animation) { + mHandler.post(() -> cleanUpBorder()); + }}); return valueAnimator; } @@ -190,14 +232,10 @@ public class FullscreenMagnificationController implements ComponentCallbacks { */ @UiThread public void onFullscreenMagnificationActivationChanged(boolean activated) { - final boolean changed = (mFullscreenMagnificationActivated != activated); - if (changed) { - mFullscreenMagnificationActivated = activated; - if (activated) { - createFullscreenMagnificationBorder(); - } else { - removeFullscreenMagnificationBorder(); - } + if (activated) { + createFullscreenMagnificationBorder(); + } else { + removeFullscreenMagnificationBorder(); } } @@ -207,16 +245,21 @@ public class FullscreenMagnificationController implements ComponentCallbacks { */ @UiThread private void removeFullscreenMagnificationBorder() { - if (mHandler.hasCallbacks(mShowBorderRunnable)) { - mHandler.removeCallbacks(mShowBorderRunnable); + int state = getState(); + if (state == DISABLING || state == DISABLED) { + // If there is an ongoing disable process or it is already disabled, return + return; } - mContext.unregisterComponentCallbacks(this); - - - mShowHideBorderAnimator.reverse(); + setState(DISABLING); + mShowHideBorderAnimator = createHideTargetAnimator(mFullscreenBorder); + mShowHideBorderAnimator.start(); } - private void cleanUpBorder() { + @VisibleForTesting + @UiThread + void cleanUpBorder() { + mContext.unregisterComponentCallbacks(this); + if (Flags.updateCornerRadiusOnDisplayChanged()) { mDisplayManager.unregisterDisplayListener(mDisplayListener); } @@ -227,6 +270,12 @@ public class FullscreenMagnificationController implements ComponentCallbacks { } if (mFullscreenBorder != null) { + if (mHandler.hasCallbacks(mHideBorderImmediatelyRunnable)) { + mHandler.removeCallbacks(mHideBorderImmediatelyRunnable); + } + if (mHandler.hasCallbacks(mShowBorderRunnable)) { + mHandler.removeCallbacks(mShowBorderRunnable); + } mFullscreenBorder = null; try { mIWindowManager.removeRotationWatcher(mRotationWatcher); @@ -234,6 +283,7 @@ public class FullscreenMagnificationController implements ComponentCallbacks { Log.w(TAG, "Failed to remove rotation watcher", e); } } + setState(DISABLED); } /** @@ -242,44 +292,47 @@ public class FullscreenMagnificationController implements ComponentCallbacks { */ @UiThread private void createFullscreenMagnificationBorder() { + int state = getState(); + if (state == ENABLING || state == ENABLED) { + // If there is an ongoing enable process or it is already enabled, return + return; + } + if (mShowHideBorderAnimator != null) { + mShowHideBorderAnimator.cancel(); + } + setState(ENABLING); + onConfigurationChanged(mContext.getResources().getConfiguration()); mContext.registerComponentCallbacks(this); if (mSurfaceControlViewHost == null) { - // Create the view only if it does not exist yet. If we are trying to enable fullscreen - // magnification before it was fully disabled, we use the previous view instead of - // creating a new one. + // Create the view only if it does not exist yet. If we are trying to enable + // fullscreen magnification before it was fully disabled, we use the previous view + // instead of creating a new one. mFullscreenBorder = LayoutInflater.from(mContext) .inflate(R.layout.fullscreen_magnification_border, null); - // Set the initial border view alpha manually so we won't show the border accidentally - // after we apply show() to the SurfaceControl and before the animation starts to run. + // Set the initial border view alpha manually so we won't show the border + // accidentally after we apply show() to the SurfaceControl and before the + // animation starts to run. mFullscreenBorder.setAlpha(0f); - mShowHideBorderAnimator.setTarget(mFullscreenBorder); mSurfaceControlViewHost = mScvhSupplier.get(); mSurfaceControlViewHost.setView(mFullscreenBorder, getBorderLayoutParams()); - mBorderSurfaceControl = mSurfaceControlViewHost.getSurfacePackage().getSurfaceControl(); + mBorderSurfaceControl = + mSurfaceControlViewHost.getSurfacePackage().getSurfaceControl(); try { mIWindowManager.watchRotation(mRotationWatcher, Display.DEFAULT_DISPLAY); } catch (Exception e) { Log.w(TAG, "Failed to register rotation watcher", e); } if (Flags.updateCornerRadiusOnDisplayChanged()) { - mHandler.post(this::applyCornerRadiusToBorder); + applyCornerRadiusToBorder(); } } mTransaction .addTransactionCommittedListener( mExecutor, - () -> { - if (mShowHideBorderAnimator.isRunning()) { - // Since the method is only called when there is an activation - // status change, the running animator is hiding the border. - mShowHideBorderAnimator.reverse(); - } else { - mShowHideBorderAnimator.start(); - } - }) + this::showBorder) .setPosition(mBorderSurfaceControl, -mBorderOffset, -mBorderOffset) .setLayer(mBorderSurfaceControl, Integer.MAX_VALUE) .show(mBorderSurfaceControl) @@ -380,19 +433,25 @@ public class FullscreenMagnificationController implements ComponentCallbacks { mHandler.removeCallbacks(mShowBorderRunnable); } - // We hide the border immediately as early as possible to beat the redrawing of window - // in response to the orientation change so users won't see a weird shape border. - mHandler.postAtFrontOfQueue(() -> { - mFullscreenBorder.setAlpha(0f); - }); - + // We hide the border immediately as early as possible to beat the redrawing of + // window in response to the orientation change so users won't see a weird shape + // border. + mHandler.postAtFrontOfQueue(mHideBorderImmediatelyRunnable); mHandler.postDelayed(mShowBorderRunnable, mLongAnimationTimeMs); } - private void showBorderWithNullCheck() { + @UiThread + private void hideBorderImmediately() { if (mShowHideBorderAnimator != null) { - mShowHideBorderAnimator.start(); + mShowHideBorderAnimator.cancel(); } + mFullscreenBorder.setAlpha(0f); + } + + @UiThread + private void showBorder() { + mShowHideBorderAnimator = createShowTargetAnimator(mFullscreenBorder); + mShowHideBorderAnimator.start(); } private void updateDimensions() { @@ -404,7 +463,9 @@ public class FullscreenMagnificationController implements ComponentCallbacks { R.dimen.magnifier_border_width_fullscreen_with_offset); } - private void applyCornerRadiusToBorder() { + @UiThread + @VisibleForTesting + void applyCornerRadiusToBorder() { if (!isActivated()) { return; } @@ -422,6 +483,20 @@ public class FullscreenMagnificationController implements ComponentCallbacks { backgroundDrawable.setCornerRadius(cornerRadius); } + @UiThread + private void setState(@FullscreenMagnificationActivationState int state) { + if (DEBUG) { + Log.d(TAG, "setState from " + mActivationState + " to " + state); + } + mActivationState = state; + } + + @VisibleForTesting + @UiThread + int getState() { + return mActivationState; + } + @Override public void onLowMemory() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/FullscreenMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/FullscreenMagnificationControllerTest.java index 9d9fb9c23a73..6ad2128759a0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/FullscreenMagnificationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/FullscreenMagnificationControllerTest.java @@ -30,9 +30,6 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; import android.content.pm.ActivityInfo; @@ -51,11 +48,8 @@ import android.view.SurfaceControlViewHost; import android.view.View; import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; -import android.view.animation.DecelerateInterpolator; -import android.view.animation.Interpolator; import android.window.InputTransferToken; -import androidx.annotation.NonNull; import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; @@ -80,19 +74,17 @@ import java.util.function.Supplier; @RunWith(AndroidTestingRunner.class) @FlakyTest(bugId = 385115361) public class FullscreenMagnificationControllerTest extends SysuiTestCase { - private static final long ANIMATION_DURATION_MS = 100L; private static final long WAIT_TIMEOUT_S = 5L * HW_TIMEOUT_MULTIPLIER; - private static final long ANIMATION_TIMEOUT_MS = - 5L * ANIMATION_DURATION_MS * HW_TIMEOUT_MULTIPLIER; private static final String UNIQUE_DISPLAY_ID_PRIMARY = "000"; private static final String UNIQUE_DISPLAY_ID_SECONDARY = "111"; private static final int CORNER_RADIUS_PRIMARY = 10; private static final int CORNER_RADIUS_SECONDARY = 20; + private static final int DISABLED = 0; + private static final int ENABLED = 3; private FullscreenMagnificationController mFullscreenMagnificationController; private SurfaceControlViewHost mSurfaceControlViewHost; - private ValueAnimator mShowHideBorderAnimator; private SurfaceControl.Transaction mTransaction; private TestableWindowManager mWindowManager; @Mock @@ -136,7 +128,6 @@ public class FullscreenMagnificationControllerTest extends SysuiTestCase { mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager); mTransaction = new SurfaceControl.Transaction(); - mShowHideBorderAnimator = spy(newNullTargetObjectAnimator()); mFullscreenMagnificationController = new FullscreenMagnificationController( mContext, mContext.getMainThreadHandler(), @@ -146,141 +137,68 @@ public class FullscreenMagnificationControllerTest extends SysuiTestCase { mContext.getSystemService(WindowManager.class), mIWindowManager, scvhSupplier, - mTransaction, - mShowHideBorderAnimator); + mTransaction); } @After public void tearDown() { - getInstrumentation().runOnMainSync( - () -> mFullscreenMagnificationController - .onFullscreenMagnificationActivationChanged(false)); + getInstrumentation().runOnMainSync(() -> + mFullscreenMagnificationController.cleanUpBorder()); + } + + @Test + public void createShowTargetAnimator_runAnimator_alphaIsEqualToOne() { + View view = new View(mContext); + view.setAlpha(0f); + ValueAnimator animator = mFullscreenMagnificationController.createShowTargetAnimator(view); + animator.end(); + assertThat(view.getAlpha()).isEqualTo(1f); + } + + @Test + public void createHideTargetAnimator_runAnimator_alphaIsEqualToZero() { + View view = new View(mContext); + view.setAlpha(1f); + ValueAnimator animator = mFullscreenMagnificationController.createHideTargetAnimator(view); + animator.end(); + assertThat(view.getAlpha()).isEqualTo(0f); } @Test - public void enableFullscreenMagnification_visibleBorder() + public void enableFullscreenMagnification_stateEnabled() throws InterruptedException, RemoteException { - CountDownLatch transactionCommittedLatch = new CountDownLatch(1); - CountDownLatch animationEndLatch = new CountDownLatch(1); - mTransaction.addTransactionCommittedListener( - Runnable::run, transactionCommittedLatch::countDown); - mShowHideBorderAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - animationEndLatch.countDown(); - } - }); - getInstrumentation().runOnMainSync(() -> - //Enable fullscreen magnification - mFullscreenMagnificationController - .onFullscreenMagnificationActivationChanged(true)); - assertWithMessage("Failed to wait for transaction committed") - .that(transactionCommittedLatch.await(WAIT_TIMEOUT_S, TimeUnit.SECONDS)) - .isTrue(); - assertWithMessage("Failed to wait for animation to be finished") - .that(animationEndLatch.await(ANIMATION_TIMEOUT_MS, TimeUnit.MILLISECONDS)) - .isTrue(); - verify(mShowHideBorderAnimator).start(); + enableFullscreenMagnificationAndWaitForTransactionAndAnimation(); + + assertThat(mFullscreenMagnificationController.getState()).isEqualTo(ENABLED); verify(mIWindowManager) .watchRotation(any(IRotationWatcher.class), eq(Display.DEFAULT_DISPLAY)); - assertThat(mSurfaceControlViewHost.getView().isVisibleToUser()).isTrue(); } @Test - public void disableFullscreenMagnification_reverseAnimationAndReleaseScvh() + public void disableFullscreenMagnification_stateDisabled() throws InterruptedException, RemoteException { - CountDownLatch transactionCommittedLatch = new CountDownLatch(1); - CountDownLatch enableAnimationEndLatch = new CountDownLatch(1); - CountDownLatch disableAnimationEndLatch = new CountDownLatch(1); - mTransaction.addTransactionCommittedListener( - Runnable::run, transactionCommittedLatch::countDown); - mShowHideBorderAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(@NonNull Animator animation, boolean isReverse) { - if (isReverse) { - disableAnimationEndLatch.countDown(); - } else { - enableAnimationEndLatch.countDown(); - } - } - }); - getInstrumentation().runOnMainSync(() -> - //Enable fullscreen magnification - mFullscreenMagnificationController - .onFullscreenMagnificationActivationChanged(true)); - assertWithMessage("Failed to wait for transaction committed") - .that(transactionCommittedLatch.await(WAIT_TIMEOUT_S, TimeUnit.SECONDS)) - .isTrue(); - assertWithMessage("Failed to wait for enabling animation to be finished") - .that(enableAnimationEndLatch.await(ANIMATION_TIMEOUT_MS, TimeUnit.MILLISECONDS)) - .isTrue(); - verify(mShowHideBorderAnimator).start(); + enableFullscreenMagnificationAndWaitForTransactionAndAnimation(); - getInstrumentation().runOnMainSync(() -> - // Disable fullscreen magnification - mFullscreenMagnificationController - .onFullscreenMagnificationActivationChanged(false)); + getInstrumentation().runOnMainSync(() -> { + // Disable fullscreen magnification + mFullscreenMagnificationController + .onFullscreenMagnificationActivationChanged(false); + }); + waitForIdleSync(); + assertThat(mFullscreenMagnificationController.mShowHideBorderAnimator).isNotNull(); + mFullscreenMagnificationController.mShowHideBorderAnimator.end(); + waitForIdleSync(); - assertWithMessage("Failed to wait for disabling animation to be finished") - .that(disableAnimationEndLatch.await(ANIMATION_TIMEOUT_MS, TimeUnit.MILLISECONDS)) - .isTrue(); - verify(mShowHideBorderAnimator).reverse(); + assertThat(mFullscreenMagnificationController.getState()).isEqualTo(DISABLED); verify(mSurfaceControlViewHost).release(); verify(mIWindowManager).removeRotationWatcher(any(IRotationWatcher.class)); } @Test - public void onFullscreenMagnificationActivationChangeTrue_deactivating_reverseAnimator() - throws InterruptedException { - // Simulate the hiding border animation is running - when(mShowHideBorderAnimator.isRunning()).thenReturn(true); - CountDownLatch transactionCommittedLatch = new CountDownLatch(1); - CountDownLatch animationEndLatch = new CountDownLatch(1); - mTransaction.addTransactionCommittedListener( - Runnable::run, transactionCommittedLatch::countDown); - mShowHideBorderAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - animationEndLatch.countDown(); - } - }); - - getInstrumentation().runOnMainSync( - () -> mFullscreenMagnificationController - .onFullscreenMagnificationActivationChanged(true)); - - assertWithMessage("Failed to wait for transaction committed") - .that(transactionCommittedLatch.await(WAIT_TIMEOUT_S, TimeUnit.SECONDS)) - .isTrue(); - assertWithMessage("Failed to wait for animation to be finished") - .that(animationEndLatch.await(ANIMATION_TIMEOUT_MS, TimeUnit.MILLISECONDS)) - .isTrue(); - verify(mShowHideBorderAnimator).reverse(); - } - - @Test public void onScreenSizeChanged_activated_borderChangedToExpectedSize() throws InterruptedException { - CountDownLatch transactionCommittedLatch = new CountDownLatch(1); - CountDownLatch animationEndLatch = new CountDownLatch(1); - mTransaction.addTransactionCommittedListener( - Runnable::run, transactionCommittedLatch::countDown); - mShowHideBorderAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - animationEndLatch.countDown(); - } - }); - getInstrumentation().runOnMainSync(() -> - //Enable fullscreen magnification - mFullscreenMagnificationController - .onFullscreenMagnificationActivationChanged(true)); - assertWithMessage("Failed to wait for transaction committed") - .that(transactionCommittedLatch.await(WAIT_TIMEOUT_S, TimeUnit.SECONDS)) - .isTrue(); - assertWithMessage("Failed to wait for animation to be finished") - .that(animationEndLatch.await(ANIMATION_TIMEOUT_MS, TimeUnit.MILLISECONDS)) - .isTrue(); + enableFullscreenMagnificationAndWaitForTransactionAndAnimation(); + final Rect testWindowBounds = new Rect( mWindowManager.getCurrentWindowMetrics().getBounds()); testWindowBounds.set(testWindowBounds.left, testWindowBounds.top, @@ -304,29 +222,8 @@ public class FullscreenMagnificationControllerTest extends SysuiTestCase { @Test public void enableFullscreenMagnification_applyPrimaryCornerRadius() throws InterruptedException { - CountDownLatch transactionCommittedLatch = new CountDownLatch(1); - CountDownLatch animationEndLatch = new CountDownLatch(1); - mTransaction.addTransactionCommittedListener( - Runnable::run, transactionCommittedLatch::countDown); - mShowHideBorderAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - animationEndLatch.countDown(); - } - }); + enableFullscreenMagnificationAndWaitForTransactionAndAnimation(); - getInstrumentation().runOnMainSync(() -> - //Enable fullscreen magnification - mFullscreenMagnificationController - .onFullscreenMagnificationActivationChanged(true)); - assertWithMessage("Failed to wait for transaction committed") - .that(transactionCommittedLatch.await(WAIT_TIMEOUT_S, TimeUnit.SECONDS)) - .isTrue(); - assertWithMessage("Failed to wait for animation to be finished") - .that(animationEndLatch.await(ANIMATION_TIMEOUT_MS, TimeUnit.MILLISECONDS)) - .isTrue(); - - // Verify the initial corner radius is applied GradientDrawable backgroundDrawable = (GradientDrawable) mSurfaceControlViewHost.getView().getBackground(); assertThat(backgroundDrawable.getCornerRadius()).isEqualTo(CORNER_RADIUS_PRIMARY); @@ -334,28 +231,8 @@ public class FullscreenMagnificationControllerTest extends SysuiTestCase { @EnableFlags(Flags.FLAG_UPDATE_CORNER_RADIUS_ON_DISPLAY_CHANGED) @Test - public void onDisplayChanged_updateCornerRadiusToSecondary() throws InterruptedException { - CountDownLatch transactionCommittedLatch = new CountDownLatch(1); - CountDownLatch animationEndLatch = new CountDownLatch(1); - mTransaction.addTransactionCommittedListener( - Runnable::run, transactionCommittedLatch::countDown); - mShowHideBorderAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - animationEndLatch.countDown(); - } - }); - - getInstrumentation().runOnMainSync(() -> - //Enable fullscreen magnification - mFullscreenMagnificationController - .onFullscreenMagnificationActivationChanged(true)); - assertWithMessage("Failed to wait for transaction committed") - .that(transactionCommittedLatch.await(WAIT_TIMEOUT_S, TimeUnit.SECONDS)) - .isTrue(); - assertWithMessage("Failed to wait for animation to be finished") - .that(animationEndLatch.await(ANIMATION_TIMEOUT_MS, TimeUnit.MILLISECONDS)) - .isTrue(); + public void onDisplayChanged_applyCornerRadiusToBorder() throws InterruptedException { + enableFullscreenMagnificationAndWaitForTransactionAndAnimation(); ArgumentCaptor<DisplayManager.DisplayListener> displayListenerCaptor = ArgumentCaptor.forClass(DisplayManager.DisplayListener.class); @@ -372,22 +249,34 @@ public class FullscreenMagnificationControllerTest extends SysuiTestCase { .addOverride( com.android.internal.R.dimen.rounded_corner_radius, CORNER_RADIUS_SECONDARY); + getInstrumentation().runOnMainSync(() -> displayListenerCaptor.getValue().onDisplayChanged(Display.DEFAULT_DISPLAY)); waitForIdleSync(); + // Verify the corner radius is updated GradientDrawable backgroundDrawable2 = (GradientDrawable) mSurfaceControlViewHost.getView().getBackground(); assertThat(backgroundDrawable2.getCornerRadius()).isEqualTo(CORNER_RADIUS_SECONDARY); } + private void enableFullscreenMagnificationAndWaitForTransactionAndAnimation() + throws InterruptedException { + CountDownLatch transactionCommittedLatch = new CountDownLatch(1); + mTransaction.addTransactionCommittedListener( + Runnable::run, transactionCommittedLatch::countDown); + + getInstrumentation().runOnMainSync(() -> + //Enable fullscreen magnification + mFullscreenMagnificationController + .onFullscreenMagnificationActivationChanged(true)); - private ValueAnimator newNullTargetObjectAnimator() { - final ValueAnimator animator = - ObjectAnimator.ofFloat(/* target= */ null, View.ALPHA, 0f, 1f); - Interpolator interpolator = new DecelerateInterpolator(2.5f); - animator.setInterpolator(interpolator); - animator.setDuration(ANIMATION_DURATION_MS); - return animator; + assertWithMessage("Failed to wait for transaction committed") + .that(transactionCommittedLatch.await(WAIT_TIMEOUT_S, TimeUnit.SECONDS)) + .isTrue(); + waitForIdleSync(); + assertThat(mFullscreenMagnificationController.mShowHideBorderAnimator).isNotNull(); + mFullscreenMagnificationController.mShowHideBorderAnimator.end(); + waitForIdleSync(); } } |