From 09bc4789671bc0391193b37456055642ebbb6e61 Mon Sep 17 00:00:00 2001 From: mincheli Date: Fri, 13 Mar 2020 15:52:09 +0800 Subject: [PATCH] Replaces AsyncTask with main handler for WindowMagnification AsyncTask is deprecated so we use main handler instead to return callback, onWindowMagnifierBoundsChanged. And this change also add a null protection and unregister OnLayoutChangeListener when window magnification is disabled. And it can prevent null pointer exception. Bug: 151394161 Bug: 151571627 Test: manual test, atest WindowMagnificationTest WindowMagnificationControllerTest Change-Id: I421424582d8bad9e58fe5aca11feb75a31bd5b35 --- .../accessibility/WindowMagnification.java | 3 +- .../WindowMagnificationController.java | 53 ++++++++++++------- .../WindowMagnificationControllerTest.java | 4 ++ 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java index 8cd7293d27342..c4d2efaa77a20 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java @@ -126,7 +126,8 @@ public class WindowMagnification extends SystemUI implements WindowMagnifierCall void enableWindowMagnification(int displayId, float scale, float centerX, float centerY) { //TODO: b/144080869 support multi-display. if (mWindowMagnificationController == null) { - mWindowMagnificationController = new WindowMagnificationController(mContext, null, + mWindowMagnificationController = new WindowMagnificationController(mContext, + mHandler, null, this); } mWindowMagnificationController.enableWindowMagnification(scale, centerX, centerY); diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java index 6031ccc49d05b..18e7778383918 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java @@ -30,7 +30,7 @@ import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; -import android.os.AsyncTask; +import android.os.Handler; import android.os.RemoteException; import android.util.Log; import android.view.Display; @@ -59,6 +59,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold private static final String TAG = "WindowMagnificationController"; private final Context mContext; private final Resources mResources; + private final Handler mHandler; private final Point mDisplaySize = new Point(); private final int mDisplayId; @Surface.Rotation @@ -83,8 +84,12 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold private View mBottomDrag; private final PointF mLastDrag = new PointF(); - @NonNull private final WindowMagnifierCallback mWindowMagnifierCallback; + @NonNull + private final WindowMagnifierCallback mWindowMagnifierCallback; + private final View.OnLayoutChangeListener mMirrorViewLayoutChangeListener; + private final View.OnLayoutChangeListener mMirrorSurfaceViewLayoutChangeListener; + private final Runnable mMirrorViewRunnable; private View mMirrorView; private SurfaceView mMirrorSurfaceView; private int mMirrorSurfaceMargin; @@ -96,9 +101,12 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold @Nullable private MirrorWindowControl mMirrorWindowControl; - WindowMagnificationController(Context context, MirrorWindowControl mirrorWindowControl, + WindowMagnificationController(Context context, + @NonNull Handler handler, + MirrorWindowControl mirrorWindowControl, @NonNull WindowMagnifierCallback callback) { mContext = context; + mHandler = handler; mWindowMagnifierCallback = callback; Display display = mContext.getDisplay(); display.getRealSize(mDisplaySize); @@ -116,6 +124,21 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold mMirrorWindowControl.setWindowDelegate(this); } setInitialStartBounds(); + + // Initialize listeners. + mMirrorViewRunnable = () -> { + if (mMirrorView != null) { + mMirrorView.getBoundsOnScreen(mMirrorViewBounds); + mWindowMagnifierCallback.onWindowMagnifierBoundsChanged( + mDisplayId, mMirrorViewBounds); + } + }; + mMirrorViewLayoutChangeListener = + (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> + mHandler.post(mMirrorViewRunnable); + mMirrorSurfaceViewLayoutChangeListener = + (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) + -> applyTapExcludeRegion(); } private void updateDimensions() { @@ -136,7 +159,13 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold mMirrorSurface = null; } + if (mMirrorSurfaceView != null) { + mMirrorSurfaceView.removeOnLayoutChangeListener(mMirrorSurfaceViewLayoutChangeListener); + } + if (mMirrorView != null) { + mHandler.removeCallbacks(mMirrorViewRunnable); + mMirrorView.removeOnLayoutChangeListener(mMirrorViewLayoutChangeListener); mWm.removeView(mMirrorView); mMirrorView = null; } @@ -224,12 +253,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold mMirrorSurfaceView = mMirrorView.findViewById(R.id.surface_view); // Allow taps to go through to the mirror SurfaceView below. - mMirrorSurfaceView.addOnLayoutChangeListener( - (View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, - int oldRight, int oldBottom) - -> { - applyTapExcludeRegion(); - }); + mMirrorSurfaceView.addOnLayoutChangeListener(mMirrorSurfaceViewLayoutChangeListener); mMirrorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION @@ -237,14 +261,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); - mMirrorView.addOnLayoutChangeListener( - (View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, - int oldRight, int oldBottom) - -> AsyncTask.execute(() -> { - mMirrorView.getBoundsOnScreen(mMirrorViewBounds); - mWindowMagnifierCallback.onWindowMagnifierBoundsChanged(mDisplayId, - mMirrorViewBounds); - })); + mMirrorView.addOnLayoutChangeListener(mMirrorViewLayoutChangeListener); mWm.addView(mMirrorView, params); SurfaceHolder holder = mMirrorSurfaceView.getHolder(); @@ -469,7 +486,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold /** * Enables window magnification with specified parameters. * - * @param scale the target scale + * @param scale the target scale * @param centerX the screen-relative X coordinate around which to center, * or {@link Float#NaN} to leave unchanged. * @param centerY the screen-relative Y coordinate around which to center, diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java index 8818f8d735eb8..bfb95b0db3e38 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java @@ -21,6 +21,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import android.app.Instrumentation; +import android.os.Handler; import android.testing.AndroidTestingRunner; import androidx.test.InstrumentationRegistry; @@ -39,6 +40,8 @@ import org.mockito.MockitoAnnotations; @RunWith(AndroidTestingRunner.class) public class WindowMagnificationControllerTest extends SysuiTestCase { + @Mock + Handler mHandler; @Mock MirrorWindowControl mMirrorWindowControl; @Mock @@ -51,6 +54,7 @@ public class WindowMagnificationControllerTest extends SysuiTestCase { MockitoAnnotations.initMocks(this); mInstrumentation = InstrumentationRegistry.getInstrumentation(); mWindowMagnificationController = new WindowMagnificationController(getContext(), + mHandler, mMirrorWindowControl, mWindowMagnifierCallback); verify(mMirrorWindowControl).setWindowDelegate( any(MirrorWindowControl.MirrorWindowDelegate.class));