Loading packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java +110 −6 Original line number Diff line number Diff line Loading @@ -16,13 +16,22 @@ package com.android.systemui.accessibility; import android.annotation.MainThread; import android.annotation.NonNull; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.database.ContentObserver; import android.graphics.Rect; import android.os.Handler; import android.os.RemoteException; import android.provider.Settings; import android.util.Log; import android.view.Display; import android.view.accessibility.IWindowMagnificationConnection; import android.view.accessibility.IWindowMagnificationConnectionCallback; import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.systemui.dagger.qualifiers.Main; Loading @@ -33,12 +42,15 @@ import javax.inject.Singleton; * Class to handle changes to setting window_magnification value. */ @Singleton public class WindowMagnification extends SystemUI { public class WindowMagnification extends SystemUI implements WindowMagnifierCallback { private static final String TAG = "WindowMagnification"; private static final int CONFIG_MASK = ActivityInfo.CONFIG_DENSITY | ActivityInfo.CONFIG_ORIENTATION; private WindowMagnificationController mWindowMagnificationController; private final Handler mHandler; //TODO:Set it by the request from AccessibilityManager. private WindowMagnificationConnectionImpl mWindowMagnificationConnectionImpl; private Configuration mLastConfiguration; Loading Loading @@ -78,7 +90,8 @@ public class WindowMagnification extends SystemUI { boolean enable = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.WINDOW_MAGNIFICATION) != 0; if (enable) { enableMagnification(); enableMagnification( mContext.getResources().getInteger(R.integer.magnification_default_scale)); } else { disableMagnification(); } Loading @@ -87,17 +100,108 @@ public class WindowMagnification extends SystemUI { } } private void enableMagnification() { private void enableMagnification(float scale) { enableWindowMagnification(Display.DEFAULT_DISPLAY, scale, Float.NaN, Float.NaN); } private void disableMagnification() { disableWindowMagnification(Display.DEFAULT_DISPLAY); } @MainThread 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, null, this); } mWindowMagnificationController.createWindowMagnification(); mWindowMagnificationController.enableWindowMagnification(scale, centerX, centerY); } private void disableMagnification() { @MainThread void setScale(int displayId, float scale) { //TODO: b/144080869 support multi-display. if (mWindowMagnificationController != null) { mWindowMagnificationController.setScale(scale); } } @MainThread void moveWindowMagnifier(int displayId, float offsetX, float offsetY) { //TODO: b/144080869 support multi-display. if (mWindowMagnificationController != null) { mWindowMagnificationController.moveWindowMagnifier(offsetX, offsetY); } } @MainThread void disableWindowMagnification(int displayId) { //TODO: b/144080869 support multi-display. if (mWindowMagnificationController != null) { mWindowMagnificationController.deleteWindowMagnification(); } mWindowMagnificationController = null; } @Override public void onWindowMagnifierBoundsChanged(int displayId, Rect frame) { if (mWindowMagnificationConnectionImpl != null) { mWindowMagnificationConnectionImpl.onWindowMagnifierBoundsChanged(displayId, frame); } } private static class WindowMagnificationConnectionImpl extends IWindowMagnificationConnection.Stub { private static final String TAG = "WindowMagnificationConnectionImpl"; private IWindowMagnificationConnectionCallback mConnectionCallback; private final WindowMagnification mWindowMagnification; private final Handler mHandler; WindowMagnificationConnectionImpl(@NonNull WindowMagnification windowMagnification, @Main Handler mainHandler) { mWindowMagnification = windowMagnification; mHandler = mainHandler; } @Override public void enableWindowMagnification(int displayId, float scale, float centerX, float centerY) { mHandler.post( () -> mWindowMagnification.enableWindowMagnification(displayId, scale, centerX, centerY)); } @Override public void setScale(int displayId, float scale) { mHandler.post(() -> mWindowMagnification.setScale(displayId, scale)); } @Override public void disableWindowMagnification(int displayId) { mHandler.post(() -> mWindowMagnification.disableWindowMagnification(displayId)); } @Override public void moveWindowMagnifier(int displayId, float offsetX, float offsetY) { mHandler.post( () -> mWindowMagnification.moveWindowMagnifier(displayId, offsetX, offsetY)); } @Override public void setConnectionCallback(IWindowMagnificationConnectionCallback callback) { mConnectionCallback = callback; } void onWindowMagnifierBoundsChanged(int displayId, Rect frame) { if (mConnectionCallback != null) { try { mConnectionCallback.onWindowMagnifierBoundsChanged(displayId, frame); } catch (RemoteException e) { Log.e(TAG, "Failed to inform bounds changed", e); } } } } } packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java +77 −33 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.accessibility; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.pm.ActivityInfo; Loading @@ -29,6 +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.Binder; import android.os.RemoteException; import android.util.Log; Loading @@ -53,7 +55,7 @@ import com.android.systemui.shared.system.WindowManagerWrapper; /** * Class to handle adding and removing a window magnification. */ public class WindowMagnificationController implements View.OnTouchListener, SurfaceHolder.Callback, class WindowMagnificationController implements View.OnTouchListener, SurfaceHolder.Callback, MirrorWindowControl.MirrorWindowDelegate { private static final String TAG = "WindowMagnificationController"; Loading @@ -71,6 +73,7 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf private float mScale; private final Rect mTmpRect = new Rect(); private final Rect mMirrorViewBounds = new Rect(); // The root of the mirrored content private SurfaceControl mMirrorSurface; Loading @@ -82,6 +85,7 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf private View mBottomDrag; private final PointF mLastDrag = new PointF(); @NonNull private final WindowMagnifierCallback mWindowMagnifierCallback; private View mMirrorView; private SurfaceView mMirrorSurfaceView; Loading @@ -95,8 +99,10 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf @Nullable private MirrorWindowControl mMirrorWindowControl; WindowMagnificationController(Context context, MirrorWindowControl mirrorWindowControl) { WindowMagnificationController(Context context, MirrorWindowControl mirrorWindowControl, @NonNull WindowMagnifierCallback callback) { mContext = context; mWindowMagnifierCallback = callback; Display display = mContext.getDisplay(); display.getRealSize(mDisplaySize); mDisplayId = mContext.getDisplayId(); Loading @@ -112,6 +118,7 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf if (mMirrorWindowControl != null) { mMirrorWindowControl.setWindowDelegate(this); } setInitialStartBounds(); } private void updateDimensions() { Loading @@ -123,18 +130,6 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf R.dimen.magnification_outer_border_margin); } /** * Creates a magnification window if it doesn't already exist. */ void createWindowMagnification() { if (mMirrorView != null) { return; } setInitialStartBounds(); setMagnificationFrameBoundary(); createOverlayWindow(); } private void createOverlayWindow() { WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, Loading Loading @@ -240,9 +235,8 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf mTmpRect.set(params.x, params.y, params.x + params.width, params.y + params.height); final RectF transformedRect = new RectF(mTmpRect); matrix.mapRect(transformedRect); final int offsetX = (int) transformedRect.left - mTmpRect.left; final int offsetY = (int) transformedRect.top - mTmpRect.top; moveMirrorWindow(offsetX, offsetY); moveWindowMagnifier(transformedRect.left - mTmpRect.left, transformedRect.top - mTmpRect.top); } /** Returns the rotation degree change of two {@link Surface.Rotation} */ Loading Loading @@ -289,6 +283,14 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf | 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); })); mWm.addView(mMirrorView, params); SurfaceHolder holder = mMirrorSurfaceView.getHolder(); Loading Loading @@ -323,9 +325,10 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf private void setInitialStartBounds() { // Sets the initial frame area for the mirror and places it in the center of the display. int initSize = Math.min(mDisplaySize.x, mDisplaySize.y) / 2 + 2 * mMirrorSurfaceMargin; int initX = mDisplaySize.x / 2 - initSize / 2; int initY = mDisplaySize.y / 2 - initSize / 2; final int initSize = Math.min(mDisplaySize.x, mDisplaySize.y) / 2 + 2 * mMirrorSurfaceMargin; final int initX = mDisplaySize.x / 2 - initSize / 2; final int initY = mDisplaySize.y / 2 - initSize / 2; mMagnificationFrame.set(initX, initY, initX + initSize, initY + initSize); } Loading Loading @@ -423,22 +426,13 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf mLastDrag.set(event.getRawX(), event.getRawY()); return true; case MotionEvent.ACTION_MOVE: int xDiff = (int) (event.getRawX() - mLastDrag.x); int yDiff = (int) (event.getRawY() - mLastDrag.y); moveMirrorWindow(xDiff, yDiff); moveWindowMagnifier(event.getRawX() - mLastDrag.x, event.getRawY() - mLastDrag.y); mLastDrag.set(event.getRawX(), event.getRawY()); return true; } return false; } private void moveMirrorWindow(int xOffset, int yOffset) { if (updateMagnificationFramePosition(xOffset, yOffset)) { modifyWindowMagnification(mTransaction); mTransaction.apply(); } } /** * Calculates the desired source bounds. This will be the area under from the center of the * displayFrame, factoring in scale. Loading Loading @@ -515,11 +509,61 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf @Override public void move(int xOffset, int yOffset) { moveWindowMagnifier(xOffset, yOffset); } /** * Enables window magnification with specified parameters. * * @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, * or {@link Float#NaN} to leave unchanged. */ void enableWindowMagnification(float scale, float centerX, float centerY) { final float offsetX = Float.isNaN(centerX) ? 0 : centerX - mMagnificationFrame.exactCenterX(); final float offsetY = Float.isNaN(centerY) ? 0 : centerY - mMagnificationFrame.exactCenterY(); mScale = scale; setMagnificationFrameBoundary(); updateMagnificationFramePosition((int) offsetX, (int) offsetY); if (mMirrorView == null) { createOverlayWindow(); } else { modifyWindowMagnification(mTransaction); mTransaction.apply(); } } /** * Sets the scale of the magnified region if it's visible. * * @param scale the target scale */ void setScale(float scale) { if (mMirrorView == null || mScale == scale) { return; } enableWindowMagnification(scale, Float.NaN, Float.NaN); } /** * Moves the window magnifier with specified offset in pixels unit. * * @param offsetX the amount in pixels to offset the window magnifier in the X direction, in * current screen pixels. * @param offsetY the amount in pixels to offset the window magnifier in the Y direction, in * current screen pixels. */ void moveWindowMagnifier(float offsetX, float offsetY) { if (mMirrorSurfaceView == null) { return; } mMagnificationFrame.offset(xOffset, yOffset); if (updateMagnificationFramePosition((int) offsetX, (int) offsetY)) { modifyWindowMagnification(mTransaction); mTransaction.apply(); } } } packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java 0 → 100644 +32 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.accessibility; import android.graphics.Rect; /** * A callback to inform {@link com.android.server.accessibility.AccessibilityManagerService} about * the UI state change or the user interaction. */ interface WindowMagnifierCallback { /** * Called when the bounds of window magnifier is changed. * @param displayId The logical display id. * @param bounds The bounds of window magnifier on the screen. */ void onWindowMagnifierBoundsChanged(int displayId, Rect bounds); } packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java +7 −3 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ public class WindowMagnificationControllerTest extends SysuiTestCase { @Mock MirrorWindowControl mMirrorWindowControl; @Mock WindowMagnifierCallback mWindowMagnifierCallback; private WindowMagnificationController mWindowMagnificationController; private Instrumentation mInstrumentation; Loading @@ -50,7 +52,7 @@ public class WindowMagnificationControllerTest extends SysuiTestCase { MockitoAnnotations.initMocks(this); mInstrumentation = InstrumentationRegistry.getInstrumentation(); mWindowMagnificationController = new WindowMagnificationController(getContext(), mMirrorWindowControl); mMirrorWindowControl, mWindowMagnifierCallback); verify(mMirrorWindowControl).setWindowDelegate( any(MirrorWindowControl.MirrorWindowDelegate.class)); } Loading @@ -66,7 +68,8 @@ public class WindowMagnificationControllerTest extends SysuiTestCase { @Test public void createWindowMagnification_showControl() { mInstrumentation.runOnMainSync(() -> { mWindowMagnificationController.createWindowMagnification(); mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN, Float.NaN); }); mInstrumentation.waitForIdleSync(); verify(mMirrorWindowControl).showControl(any(IBinder.class)); Loading @@ -75,7 +78,8 @@ public class WindowMagnificationControllerTest extends SysuiTestCase { @Test public void deleteWindowMagnification_destroyControl() { mInstrumentation.runOnMainSync(() -> { mWindowMagnificationController.createWindowMagnification(); mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN, Float.NaN); }); mInstrumentation.waitForIdleSync(); Loading Loading
packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java +110 −6 Original line number Diff line number Diff line Loading @@ -16,13 +16,22 @@ package com.android.systemui.accessibility; import android.annotation.MainThread; import android.annotation.NonNull; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.database.ContentObserver; import android.graphics.Rect; import android.os.Handler; import android.os.RemoteException; import android.provider.Settings; import android.util.Log; import android.view.Display; import android.view.accessibility.IWindowMagnificationConnection; import android.view.accessibility.IWindowMagnificationConnectionCallback; import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.systemui.dagger.qualifiers.Main; Loading @@ -33,12 +42,15 @@ import javax.inject.Singleton; * Class to handle changes to setting window_magnification value. */ @Singleton public class WindowMagnification extends SystemUI { public class WindowMagnification extends SystemUI implements WindowMagnifierCallback { private static final String TAG = "WindowMagnification"; private static final int CONFIG_MASK = ActivityInfo.CONFIG_DENSITY | ActivityInfo.CONFIG_ORIENTATION; private WindowMagnificationController mWindowMagnificationController; private final Handler mHandler; //TODO:Set it by the request from AccessibilityManager. private WindowMagnificationConnectionImpl mWindowMagnificationConnectionImpl; private Configuration mLastConfiguration; Loading Loading @@ -78,7 +90,8 @@ public class WindowMagnification extends SystemUI { boolean enable = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.WINDOW_MAGNIFICATION) != 0; if (enable) { enableMagnification(); enableMagnification( mContext.getResources().getInteger(R.integer.magnification_default_scale)); } else { disableMagnification(); } Loading @@ -87,17 +100,108 @@ public class WindowMagnification extends SystemUI { } } private void enableMagnification() { private void enableMagnification(float scale) { enableWindowMagnification(Display.DEFAULT_DISPLAY, scale, Float.NaN, Float.NaN); } private void disableMagnification() { disableWindowMagnification(Display.DEFAULT_DISPLAY); } @MainThread 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, null, this); } mWindowMagnificationController.createWindowMagnification(); mWindowMagnificationController.enableWindowMagnification(scale, centerX, centerY); } private void disableMagnification() { @MainThread void setScale(int displayId, float scale) { //TODO: b/144080869 support multi-display. if (mWindowMagnificationController != null) { mWindowMagnificationController.setScale(scale); } } @MainThread void moveWindowMagnifier(int displayId, float offsetX, float offsetY) { //TODO: b/144080869 support multi-display. if (mWindowMagnificationController != null) { mWindowMagnificationController.moveWindowMagnifier(offsetX, offsetY); } } @MainThread void disableWindowMagnification(int displayId) { //TODO: b/144080869 support multi-display. if (mWindowMagnificationController != null) { mWindowMagnificationController.deleteWindowMagnification(); } mWindowMagnificationController = null; } @Override public void onWindowMagnifierBoundsChanged(int displayId, Rect frame) { if (mWindowMagnificationConnectionImpl != null) { mWindowMagnificationConnectionImpl.onWindowMagnifierBoundsChanged(displayId, frame); } } private static class WindowMagnificationConnectionImpl extends IWindowMagnificationConnection.Stub { private static final String TAG = "WindowMagnificationConnectionImpl"; private IWindowMagnificationConnectionCallback mConnectionCallback; private final WindowMagnification mWindowMagnification; private final Handler mHandler; WindowMagnificationConnectionImpl(@NonNull WindowMagnification windowMagnification, @Main Handler mainHandler) { mWindowMagnification = windowMagnification; mHandler = mainHandler; } @Override public void enableWindowMagnification(int displayId, float scale, float centerX, float centerY) { mHandler.post( () -> mWindowMagnification.enableWindowMagnification(displayId, scale, centerX, centerY)); } @Override public void setScale(int displayId, float scale) { mHandler.post(() -> mWindowMagnification.setScale(displayId, scale)); } @Override public void disableWindowMagnification(int displayId) { mHandler.post(() -> mWindowMagnification.disableWindowMagnification(displayId)); } @Override public void moveWindowMagnifier(int displayId, float offsetX, float offsetY) { mHandler.post( () -> mWindowMagnification.moveWindowMagnifier(displayId, offsetX, offsetY)); } @Override public void setConnectionCallback(IWindowMagnificationConnectionCallback callback) { mConnectionCallback = callback; } void onWindowMagnifierBoundsChanged(int displayId, Rect frame) { if (mConnectionCallback != null) { try { mConnectionCallback.onWindowMagnifierBoundsChanged(displayId, frame); } catch (RemoteException e) { Log.e(TAG, "Failed to inform bounds changed", e); } } } } }
packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java +77 −33 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.accessibility; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.pm.ActivityInfo; Loading @@ -29,6 +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.Binder; import android.os.RemoteException; import android.util.Log; Loading @@ -53,7 +55,7 @@ import com.android.systemui.shared.system.WindowManagerWrapper; /** * Class to handle adding and removing a window magnification. */ public class WindowMagnificationController implements View.OnTouchListener, SurfaceHolder.Callback, class WindowMagnificationController implements View.OnTouchListener, SurfaceHolder.Callback, MirrorWindowControl.MirrorWindowDelegate { private static final String TAG = "WindowMagnificationController"; Loading @@ -71,6 +73,7 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf private float mScale; private final Rect mTmpRect = new Rect(); private final Rect mMirrorViewBounds = new Rect(); // The root of the mirrored content private SurfaceControl mMirrorSurface; Loading @@ -82,6 +85,7 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf private View mBottomDrag; private final PointF mLastDrag = new PointF(); @NonNull private final WindowMagnifierCallback mWindowMagnifierCallback; private View mMirrorView; private SurfaceView mMirrorSurfaceView; Loading @@ -95,8 +99,10 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf @Nullable private MirrorWindowControl mMirrorWindowControl; WindowMagnificationController(Context context, MirrorWindowControl mirrorWindowControl) { WindowMagnificationController(Context context, MirrorWindowControl mirrorWindowControl, @NonNull WindowMagnifierCallback callback) { mContext = context; mWindowMagnifierCallback = callback; Display display = mContext.getDisplay(); display.getRealSize(mDisplaySize); mDisplayId = mContext.getDisplayId(); Loading @@ -112,6 +118,7 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf if (mMirrorWindowControl != null) { mMirrorWindowControl.setWindowDelegate(this); } setInitialStartBounds(); } private void updateDimensions() { Loading @@ -123,18 +130,6 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf R.dimen.magnification_outer_border_margin); } /** * Creates a magnification window if it doesn't already exist. */ void createWindowMagnification() { if (mMirrorView != null) { return; } setInitialStartBounds(); setMagnificationFrameBoundary(); createOverlayWindow(); } private void createOverlayWindow() { WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, Loading Loading @@ -240,9 +235,8 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf mTmpRect.set(params.x, params.y, params.x + params.width, params.y + params.height); final RectF transformedRect = new RectF(mTmpRect); matrix.mapRect(transformedRect); final int offsetX = (int) transformedRect.left - mTmpRect.left; final int offsetY = (int) transformedRect.top - mTmpRect.top; moveMirrorWindow(offsetX, offsetY); moveWindowMagnifier(transformedRect.left - mTmpRect.left, transformedRect.top - mTmpRect.top); } /** Returns the rotation degree change of two {@link Surface.Rotation} */ Loading Loading @@ -289,6 +283,14 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf | 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); })); mWm.addView(mMirrorView, params); SurfaceHolder holder = mMirrorSurfaceView.getHolder(); Loading Loading @@ -323,9 +325,10 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf private void setInitialStartBounds() { // Sets the initial frame area for the mirror and places it in the center of the display. int initSize = Math.min(mDisplaySize.x, mDisplaySize.y) / 2 + 2 * mMirrorSurfaceMargin; int initX = mDisplaySize.x / 2 - initSize / 2; int initY = mDisplaySize.y / 2 - initSize / 2; final int initSize = Math.min(mDisplaySize.x, mDisplaySize.y) / 2 + 2 * mMirrorSurfaceMargin; final int initX = mDisplaySize.x / 2 - initSize / 2; final int initY = mDisplaySize.y / 2 - initSize / 2; mMagnificationFrame.set(initX, initY, initX + initSize, initY + initSize); } Loading Loading @@ -423,22 +426,13 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf mLastDrag.set(event.getRawX(), event.getRawY()); return true; case MotionEvent.ACTION_MOVE: int xDiff = (int) (event.getRawX() - mLastDrag.x); int yDiff = (int) (event.getRawY() - mLastDrag.y); moveMirrorWindow(xDiff, yDiff); moveWindowMagnifier(event.getRawX() - mLastDrag.x, event.getRawY() - mLastDrag.y); mLastDrag.set(event.getRawX(), event.getRawY()); return true; } return false; } private void moveMirrorWindow(int xOffset, int yOffset) { if (updateMagnificationFramePosition(xOffset, yOffset)) { modifyWindowMagnification(mTransaction); mTransaction.apply(); } } /** * Calculates the desired source bounds. This will be the area under from the center of the * displayFrame, factoring in scale. Loading Loading @@ -515,11 +509,61 @@ public class WindowMagnificationController implements View.OnTouchListener, Surf @Override public void move(int xOffset, int yOffset) { moveWindowMagnifier(xOffset, yOffset); } /** * Enables window magnification with specified parameters. * * @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, * or {@link Float#NaN} to leave unchanged. */ void enableWindowMagnification(float scale, float centerX, float centerY) { final float offsetX = Float.isNaN(centerX) ? 0 : centerX - mMagnificationFrame.exactCenterX(); final float offsetY = Float.isNaN(centerY) ? 0 : centerY - mMagnificationFrame.exactCenterY(); mScale = scale; setMagnificationFrameBoundary(); updateMagnificationFramePosition((int) offsetX, (int) offsetY); if (mMirrorView == null) { createOverlayWindow(); } else { modifyWindowMagnification(mTransaction); mTransaction.apply(); } } /** * Sets the scale of the magnified region if it's visible. * * @param scale the target scale */ void setScale(float scale) { if (mMirrorView == null || mScale == scale) { return; } enableWindowMagnification(scale, Float.NaN, Float.NaN); } /** * Moves the window magnifier with specified offset in pixels unit. * * @param offsetX the amount in pixels to offset the window magnifier in the X direction, in * current screen pixels. * @param offsetY the amount in pixels to offset the window magnifier in the Y direction, in * current screen pixels. */ void moveWindowMagnifier(float offsetX, float offsetY) { if (mMirrorSurfaceView == null) { return; } mMagnificationFrame.offset(xOffset, yOffset); if (updateMagnificationFramePosition((int) offsetX, (int) offsetY)) { modifyWindowMagnification(mTransaction); mTransaction.apply(); } } }
packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java 0 → 100644 +32 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.accessibility; import android.graphics.Rect; /** * A callback to inform {@link com.android.server.accessibility.AccessibilityManagerService} about * the UI state change or the user interaction. */ interface WindowMagnifierCallback { /** * Called when the bounds of window magnifier is changed. * @param displayId The logical display id. * @param bounds The bounds of window magnifier on the screen. */ void onWindowMagnifierBoundsChanged(int displayId, Rect bounds); }
packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java +7 −3 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ public class WindowMagnificationControllerTest extends SysuiTestCase { @Mock MirrorWindowControl mMirrorWindowControl; @Mock WindowMagnifierCallback mWindowMagnifierCallback; private WindowMagnificationController mWindowMagnificationController; private Instrumentation mInstrumentation; Loading @@ -50,7 +52,7 @@ public class WindowMagnificationControllerTest extends SysuiTestCase { MockitoAnnotations.initMocks(this); mInstrumentation = InstrumentationRegistry.getInstrumentation(); mWindowMagnificationController = new WindowMagnificationController(getContext(), mMirrorWindowControl); mMirrorWindowControl, mWindowMagnifierCallback); verify(mMirrorWindowControl).setWindowDelegate( any(MirrorWindowControl.MirrorWindowDelegate.class)); } Loading @@ -66,7 +68,8 @@ public class WindowMagnificationControllerTest extends SysuiTestCase { @Test public void createWindowMagnification_showControl() { mInstrumentation.runOnMainSync(() -> { mWindowMagnificationController.createWindowMagnification(); mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN, Float.NaN); }); mInstrumentation.waitForIdleSync(); verify(mMirrorWindowControl).showControl(any(IBinder.class)); Loading @@ -75,7 +78,8 @@ public class WindowMagnificationControllerTest extends SysuiTestCase { @Test public void deleteWindowMagnification_destroyControl() { mInstrumentation.runOnMainSync(() -> { mWindowMagnificationController.createWindowMagnification(); mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN, Float.NaN); }); mInstrumentation.waitForIdleSync(); Loading