diff options
2 files changed, 106 insertions, 10 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/FullscreenMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/FullscreenMagnificationController.java index e37dade22ecf..0bd6d6ede9ef 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/FullscreenMagnificationController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/FullscreenMagnificationController.java @@ -23,7 +23,10 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.UiContext; +import android.content.ComponentCallbacks; import android.content.Context; +import android.content.pm.ActivityInfo; +import android.content.res.Configuration; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.Region; @@ -47,7 +50,7 @@ import com.android.systemui.res.R; import java.util.concurrent.Executor; import java.util.function.Supplier; -class FullscreenMagnificationController { +class FullscreenMagnificationController implements ComponentCallbacks { private final Context mContext; private final AccessibilityManager mAccessibilityManager; @@ -63,6 +66,8 @@ class FullscreenMagnificationController { private static final Region sEmptyRegion = new Region(); private ValueAnimator mShowHideBorderAnimator; private Executor mExecutor; + private boolean mFullscreenMagnificationActivated = false; + private final Configuration mConfiguration; FullscreenMagnificationController( @UiContext Context context, @@ -95,6 +100,7 @@ class FullscreenMagnificationController { - mContext.getResources().getDimensionPixelSize( R.dimen.magnifier_border_width_fullscreen); mDisplayId = mContext.getDisplayId(); + mConfiguration = new Configuration(context.getResources().getConfiguration()); mShowHideBorderAnimator = valueAnimator; mShowHideBorderAnimator.addListener(new AnimatorListenerAdapter() { @Override @@ -121,18 +127,19 @@ class FullscreenMagnificationController { } /** - * In {@link com.android.server.accessibility.magnification.FullScreenMagnificationController - * .DisplayMagnification#setActivated(boolean)}, onFullScreenMagnificationActivationState is - * only called when there is an activation status change. Therefore, we could assume that we - * won't be calling "create border" when another creating border animation is running or - * "remove border" when another removing border animation is running. + * Check the fullscreen magnification activation status, and proceed corresponding actions when + * there is an activation change. */ @UiThread void onFullscreenMagnificationActivationChanged(boolean activated) { - if (activated) { - createFullscreenMagnificationBorder(); - } else { - removeFullscreenMagnificationBorder(); + final boolean changed = (mFullscreenMagnificationActivated != activated); + if (changed) { + mFullscreenMagnificationActivated = activated; + if (activated) { + createFullscreenMagnificationBorder(); + } else { + removeFullscreenMagnificationBorder(); + } } } @@ -142,6 +149,7 @@ class FullscreenMagnificationController { */ @UiThread private void removeFullscreenMagnificationBorder() { + mContext.unregisterComponentCallbacks(this); mShowHideBorderAnimator.reverse(); } @@ -162,6 +170,9 @@ class FullscreenMagnificationController { */ @UiThread private void createFullscreenMagnificationBorder() { + 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 @@ -226,4 +237,41 @@ class FullscreenMagnificationController { // all touch events to go through this view. surfaceControl.setTouchableRegion(sEmptyRegion); } + + @Override + public void onConfigurationChanged(@NonNull Configuration newConfig) { + final int configDiff = newConfig.diff(mConfiguration); + mConfiguration.setTo(newConfig); + onConfigurationChanged(configDiff); + } + + @VisibleForTesting + void onConfigurationChanged(int configDiff) { + boolean reCreateWindow = false; + if ((configDiff & ActivityInfo.CONFIG_DENSITY) != 0 + || (configDiff & ActivityInfo.CONFIG_SCREEN_SIZE) != 0 + || (configDiff & ActivityInfo.CONFIG_ORIENTATION) != 0) { + updateDimensions(); + mWindowBounds.set(mWindowManager.getCurrentWindowMetrics().getBounds()); + reCreateWindow = true; + } + + if (mFullscreenBorder != null && reCreateWindow) { + final int newWidth = mWindowBounds.width() + 2 * mBorderOffset; + final int newHeight = mWindowBounds.height() + 2 * mBorderOffset; + mSurfaceControlViewHost.relayout(newWidth, newHeight); + } + } + + private void updateDimensions() { + mBorderOffset = mContext.getResources().getDimensionPixelSize( + R.dimen.magnifier_border_width_fullscreen_with_offset) + - mContext.getResources().getDimensionPixelSize( + R.dimen.magnifier_border_width_fullscreen); + } + + @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 c86b3489fde7..5bc9aa43e825 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/FullscreenMagnificationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/FullscreenMagnificationControllerTest.java @@ -31,6 +31,9 @@ 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; +import android.graphics.Rect; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.SurfaceControl; @@ -46,6 +49,7 @@ import androidx.annotation.NonNull; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; +import com.android.systemui.res.R; import org.junit.After; import org.junit.Before; @@ -68,6 +72,7 @@ public class FullscreenMagnificationControllerTest extends SysuiTestCase { private SurfaceControlViewHost mSurfaceControlViewHost; private ValueAnimator mShowHideBorderAnimator; private SurfaceControl.Transaction mTransaction; + private TestableWindowManager mWindowManager; @Before public void setUp() { @@ -75,6 +80,9 @@ public class FullscreenMagnificationControllerTest extends SysuiTestCase { spy(new SurfaceControlViewHost(mContext, mContext.getDisplay(), new InputTransferToken(), "FullscreenMagnification"))); Supplier<SurfaceControlViewHost> scvhSupplier = () -> mSurfaceControlViewHost; + final WindowManager wm = mContext.getSystemService(WindowManager.class); + mWindowManager = new TestableWindowManager(wm); + mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager); mTransaction = new SurfaceControl.Transaction(); mShowHideBorderAnimator = spy(newNullTargetObjectAnimator()); @@ -187,6 +195,46 @@ public class FullscreenMagnificationControllerTest extends SysuiTestCase { 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)); + assertTrue("Failed to wait for transaction committed", + transactionCommittedLatch.await(WAIT_TIMEOUT_S, TimeUnit.SECONDS)); + assertTrue("Failed to wait for animation to be finished", + animationEndLatch.await(ANIMATION_TIMEOUT_MS, TimeUnit.MILLISECONDS)); + final Rect testWindowBounds = new Rect( + mWindowManager.getCurrentWindowMetrics().getBounds()); + testWindowBounds.set(testWindowBounds.left, testWindowBounds.top, + testWindowBounds.right + 100, testWindowBounds.bottom + 100); + mWindowManager.setWindowBounds(testWindowBounds); + + getInstrumentation().runOnMainSync(() -> + mFullscreenMagnificationController.onConfigurationChanged( + ActivityInfo.CONFIG_SCREEN_SIZE)); + + int borderOffset = mContext.getResources().getDimensionPixelSize( + R.dimen.magnifier_border_width_fullscreen_with_offset) + - mContext.getResources().getDimensionPixelSize( + R.dimen.magnifier_border_width_fullscreen); + final int newWidth = testWindowBounds.width() + 2 * borderOffset; + final int newHeight = testWindowBounds.height() + 2 * borderOffset; + verify(mSurfaceControlViewHost).relayout(newWidth, newHeight); + } + private ValueAnimator newNullTargetObjectAnimator() { final ValueAnimator animator = ObjectAnimator.ofFloat(/* target= */ null, View.ALPHA, 0f, 1f); |