diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java index 351760bd886539a708fc68b2defe5df255e18a9e..a5bbc7efcb23f48af130396c2a6089bc1a173ff9 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java @@ -599,7 +599,7 @@ public class FullScreenMagnificationController implements callback.onFullScreenMagnificationActivationState( mDisplayId, mMagnificationActivated); }); - mControllerCtx.getWindowManager().setForceShowMagnifiableBounds( + mControllerCtx.getWindowManager().setFullscreenMagnificationActivated( mDisplayId, activated); } diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index ee865d3a588ac209c1d84516e16f272de68b1f95..7ccc250a5bfd0cb665dfb5b46672c21704cdd23c 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -523,15 +523,15 @@ final class AccessibilityController { || mWindowsForAccessibilityObserver.size() > 0); } - void setForceShowMagnifiableBounds(int displayId, boolean show) { + void setFullscreenMagnificationActivated(int displayId, boolean activated) { if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) { - mAccessibilityTracing.logTrace(TAG + ".setForceShowMagnifiableBounds", - FLAGS_MAGNIFICATION_CALLBACK, "displayId=" + displayId + "; show=" + show); + mAccessibilityTracing.logTrace(TAG + ".setFullscreenMagnificationActivated", + FLAGS_MAGNIFICATION_CALLBACK, + "displayId=" + displayId + "; activated=" + activated); } final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId); if (displayMagnifier != null) { - displayMagnifier.setForceShowMagnifiableBounds(show); - displayMagnifier.showMagnificationBoundsIfNeeded(); + displayMagnifier.setFullscreenMagnificationActivated(activated); } } @@ -624,10 +624,21 @@ final class AccessibilityController { private final long mLongAnimationDuration; - private boolean mForceShowMagnifiableBounds = false; + private boolean mIsFullscreenMagnificationActivated = false; + private final Region mMagnificationRegion = new Region(); + private final Region mOldMagnificationRegion = new Region(); private final MagnificationSpec mMagnificationSpec = new MagnificationSpec(); + // Following fields are used for computing magnification region + private final Path mCircularPath; + private int mTempLayer = 0; + private final Point mScreenSize = new Point(); + private final SparseArray<WindowState> mTempWindowStates = + new SparseArray<WindowState>(); + private final RectF mTempRectF = new RectF(); + private final Matrix mTempMatrix = new Matrix(); + DisplayMagnifier(WindowManagerService windowManagerService, DisplayContent displayContent, Display display, @@ -643,6 +654,15 @@ final class AccessibilityController { AccessibilityController.getAccessibilityControllerInternal(mService); mLongAnimationDuration = mDisplayContext.getResources().getInteger( com.android.internal.R.integer.config_longAnimTime); + if (mDisplayContext.getResources().getConfiguration().isScreenRound()) { + mCircularPath = new Path(); + + getDisplaySizeLocked(mScreenSize); + final int centerXY = mScreenSize.x / 2; + mCircularPath.addCircle(centerXY, centerXY, centerXY, Path.Direction.CW); + } else { + mCircularPath = null; + } if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) { mAccessibilityTracing.logTrace(LOG_TAG + ".DisplayMagnifier.constructor", FLAGS_MAGNIFICATION_CALLBACK, @@ -650,6 +670,7 @@ final class AccessibilityController { + displayContent + "}; display={" + display + "}; callbacks={" + callbacks + "}"); } + recomputeBounds(); } void setMagnificationSpec(MagnificationSpec spec) { @@ -658,7 +679,7 @@ final class AccessibilityController { FLAGS_MAGNIFICATION_CALLBACK, "spec={" + spec + "}"); } updateMagnificationSpec(spec); - mMagnifedViewport.recomputeBounds(); + recomputeBounds(); mService.applyMagnificationSpecLocked(mDisplay.getDisplayId(), spec); mService.scheduleAnimationLocked(); @@ -670,30 +691,26 @@ final class AccessibilityController { } else { mMagnificationSpec.clear(); } - // If this message is pending we are in a rotation animation and do not want - // to show the border. We will do so when the pending message is handled. - if (!mHandler.hasMessages( - MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED)) { - mMagnifedViewport.setMagnifiedRegionBorderShown( - isForceShowingMagnifiableBounds(), true); - } + + mMagnifedViewport.setShowMagnifiedBorderIfNeeded(); } - void setForceShowMagnifiableBounds(boolean show) { + void setFullscreenMagnificationActivated(boolean activated) { if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) { - mAccessibilityTracing.logTrace(LOG_TAG + ".setForceShowMagnifiableBounds", - FLAGS_MAGNIFICATION_CALLBACK, "show=" + show); + mAccessibilityTracing.logTrace(LOG_TAG + ".setFullscreenMagnificationActivated", + FLAGS_MAGNIFICATION_CALLBACK, "activated=" + activated); } - mForceShowMagnifiableBounds = show; - mMagnifedViewport.setMagnifiedRegionBorderShown(show, true); + mIsFullscreenMagnificationActivated = activated; + mMagnifedViewport.setMagnifiedRegionBorderShown(activated, true); + mMagnifedViewport.showMagnificationBoundsIfNeeded(); } - boolean isForceShowingMagnifiableBounds() { + boolean isFullscreenMagnificationActivated() { if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) { - mAccessibilityTracing.logTrace(LOG_TAG + ".isForceShowingMagnifiableBounds", + mAccessibilityTracing.logTrace(LOG_TAG + ".isFullscreenMagnificationActivated", FLAGS_MAGNIFICATION_CALLBACK); } - return mForceShowMagnifiableBounds; + return mIsFullscreenMagnificationActivated; } void onWindowLayersChanged() { @@ -704,7 +721,7 @@ final class AccessibilityController { if (DEBUG_LAYERS) { Slog.i(LOG_TAG, "Layers changed."); } - mMagnifedViewport.recomputeBounds(); + recomputeBounds(); mService.scheduleAnimationLocked(); } @@ -718,6 +735,8 @@ final class AccessibilityController { Slog.i(LOG_TAG, "Rotation: " + Surface.rotationToString(rotation) + " displayId: " + displayContent.getDisplayId()); } + + recomputeBounds(); mMagnifedViewport.onDisplaySizeChanged(); mHandler.sendEmptyMessage(MyHandler.MESSAGE_NOTIFY_DISPLAY_SIZE_CHANGED); } @@ -733,7 +752,7 @@ final class AccessibilityController { + AppTransition.appTransitionOldToString(transition) + " displayId: " + displayId); } - final boolean isMagnifierActivated = isForceShowingMagnifiableBounds(); + final boolean isMagnifierActivated = isFullscreenMagnificationActivated(); if (isMagnifierActivated) { switch (transition) { case WindowManager.TRANSIT_OLD_ACTIVITY_OPEN: @@ -758,7 +777,7 @@ final class AccessibilityController { Slog.i(LOG_TAG, "Window transition: " + WindowManager.transitTypeToString(type) + " displayId: " + displayId); } - final boolean isMagnifierActivated = isForceShowingMagnifiableBounds(); + final boolean isMagnifierActivated = isFullscreenMagnificationActivated(); if (isMagnifierActivated) { // All opening/closing situations. switch (type) { @@ -782,7 +801,7 @@ final class AccessibilityController { + AppTransition.appTransitionOldToString(transition) + " displayId: " + windowState.getDisplayId()); } - final boolean isMagnifierActivated = isForceShowingMagnifiableBounds(); + final boolean isMagnifierActivated = isFullscreenMagnificationActivated(); final int type = windowState.mAttrs.type; switch (transition) { case WindowManagerPolicy.TRANSIT_ENTER: @@ -835,9 +854,7 @@ final class AccessibilityController { } void getMagnifiedFrameInContentCoords(Rect rect) { - Region magnificationRegion = new Region(); - mMagnifedViewport.getMagnificationRegion(magnificationRegion); - magnificationRegion.getBounds(rect); + mMagnificationRegion.getBounds(rect); rect.offset((int) -mMagnificationSpec.offsetX, (int) -mMagnificationSpec.offsetY); rect.scale(1.0f / mMagnificationSpec.scale); } @@ -872,8 +889,8 @@ final class AccessibilityController { "outMagnificationRegion={" + outMagnificationRegion + "}"); } // Make sure we're working with the most current bounds - mMagnifedViewport.recomputeBounds(); - mMagnifedViewport.getMagnificationRegion(outMagnificationRegion); + recomputeBounds(); + outMagnificationRegion.set(mMagnificationRegion); } boolean isMagnifying() { @@ -887,16 +904,6 @@ final class AccessibilityController { mMagnifedViewport.destroyWindow(); } - // Can be called outside of a surface transaction - void showMagnificationBoundsIfNeeded() { - if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) { - mAccessibilityTracing.logTrace(LOG_TAG + ".showMagnificationBoundsIfNeeded", - FLAGS_MAGNIFICATION_CALLBACK); - } - mHandler.obtainMessage(MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED) - .sendToTarget(); - } - void drawMagnifiedRegionBorderIfNeeded() { if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) { mAccessibilityTracing.logTrace(LOG_TAG + ".drawMagnifiedRegionBorderIfNeeded", @@ -905,221 +912,236 @@ final class AccessibilityController { mMagnifedViewport.drawWindowIfNeeded(); } - void dump(PrintWriter pw, String prefix) { - mMagnifedViewport.dump(pw, prefix); - } - - private final class MagnifiedViewport { + void recomputeBounds() { + getDisplaySizeLocked(mScreenSize); + final int screenWidth = mScreenSize.x; + final int screenHeight = mScreenSize.y; - private final SparseArray<WindowState> mTempWindowStates = - new SparseArray<WindowState>(); + mMagnificationRegion.set(0, 0, 0, 0); + final Region availableBounds = mTempRegion1; + availableBounds.set(0, 0, screenWidth, screenHeight); - private final RectF mTempRectF = new RectF(); + if (mCircularPath != null) { + availableBounds.setPath(mCircularPath, availableBounds); + } - private final Point mScreenSize = new Point(); + Region nonMagnifiedBounds = mTempRegion4; + nonMagnifiedBounds.set(0, 0, 0, 0); - private final Matrix mTempMatrix = new Matrix(); + SparseArray<WindowState> visibleWindows = mTempWindowStates; + visibleWindows.clear(); + populateWindowsOnScreen(visibleWindows); - private final Region mMagnificationRegion = new Region(); - private final Region mOldMagnificationRegion = new Region(); + final int visibleWindowCount = visibleWindows.size(); + for (int i = visibleWindowCount - 1; i >= 0; i--) { + WindowState windowState = visibleWindows.valueAt(i); + final int windowType = windowState.mAttrs.type; + if (isExcludedWindowType(windowType) + || ((windowState.mAttrs.privateFlags + & PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION) != 0) + || ((windowState.mAttrs.privateFlags + & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0)) { + continue; + } - private final Path mCircularPath; + // Consider the touchable portion of the window + Matrix matrix = mTempMatrix; + populateTransformationMatrix(windowState, matrix); + Region touchableRegion = mTempRegion3; + windowState.getTouchableRegion(touchableRegion); + Rect touchableFrame = mTempRect1; + touchableRegion.getBounds(touchableFrame); + RectF windowFrame = mTempRectF; + windowFrame.set(touchableFrame); + windowFrame.offset(-windowState.getFrame().left, + -windowState.getFrame().top); + matrix.mapRect(windowFrame); + Region windowBounds = mTempRegion2; + windowBounds.set((int) windowFrame.left, (int) windowFrame.top, + (int) windowFrame.right, (int) windowFrame.bottom); + // Only update new regions + Region portionOfWindowAlreadyAccountedFor = mTempRegion3; + portionOfWindowAlreadyAccountedFor.set(mMagnificationRegion); + portionOfWindowAlreadyAccountedFor.op(nonMagnifiedBounds, Region.Op.UNION); + windowBounds.op(portionOfWindowAlreadyAccountedFor, Region.Op.DIFFERENCE); + + if (windowState.shouldMagnify()) { + mMagnificationRegion.op(windowBounds, Region.Op.UNION); + mMagnificationRegion.op(availableBounds, Region.Op.INTERSECT); + } else { + nonMagnifiedBounds.op(windowBounds, Region.Op.UNION); + availableBounds.op(windowBounds, Region.Op.DIFFERENCE); + } - private final float mBorderWidth; - private final int mHalfBorderWidth; - private final int mDrawBorderInset; + // If the navigation bar window doesn't have touchable region, count + // navigation bar insets into nonMagnifiedBounds. It happens when + // navigation mode is gestural. + if (isUntouchableNavigationBar(windowState, mTempRegion3)) { + final Rect navBarInsets = getSystemBarInsetsFrame(windowState); + nonMagnifiedBounds.op(navBarInsets, Region.Op.UNION); + availableBounds.op(navBarInsets, Region.Op.DIFFERENCE); + } - private final ViewportWindow mWindow; + // Count letterbox into nonMagnifiedBounds + if (windowState.areAppWindowBoundsLetterboxed()) { + Region letterboxBounds = getLetterboxBounds(windowState); + nonMagnifiedBounds.op(letterboxBounds, Region.Op.UNION); + availableBounds.op(letterboxBounds, Region.Op.DIFFERENCE); + } - private boolean mFullRedrawNeeded; - private int mTempLayer = 0; + // Update accounted bounds + Region accountedBounds = mTempRegion2; + accountedBounds.set(mMagnificationRegion); + accountedBounds.op(nonMagnifiedBounds, Region.Op.UNION); + accountedBounds.op(0, 0, screenWidth, screenHeight, Region.Op.INTERSECT); + + if (accountedBounds.isRect()) { + Rect accountedFrame = mTempRect1; + accountedBounds.getBounds(accountedFrame); + if (accountedFrame.width() == screenWidth + && accountedFrame.height() == screenHeight) { + break; + } + } + } + visibleWindows.clear(); - MagnifiedViewport() { - mBorderWidth = mDisplayContext.getResources().getDimension( - com.android.internal.R.dimen.accessibility_magnification_indicator_width); - mHalfBorderWidth = (int) Math.ceil(mBorderWidth / 2); - mDrawBorderInset = (int) mBorderWidth / 2; - mWindow = new ViewportWindow(mDisplayContext); + mMagnifedViewport.intersectWithDrawBorderInset(screenWidth, screenHeight); - if (mDisplayContext.getResources().getConfiguration().isScreenRound()) { - mCircularPath = new Path(); - getDisplaySizeLocked(mScreenSize); - final int centerXY = mScreenSize.x / 2; - mCircularPath.addCircle(centerXY, centerXY, centerXY, Path.Direction.CW); - } else { - mCircularPath = null; - } + final boolean magnifiedChanged = + !mOldMagnificationRegion.equals(mMagnificationRegion); + if (magnifiedChanged) { + mMagnifedViewport.updateBorderDrawingStatus(screenWidth, screenHeight); - recomputeBounds(); + mOldMagnificationRegion.set(mMagnificationRegion); + final SomeArgs args = SomeArgs.obtain(); + args.arg1 = Region.obtain(mMagnificationRegion); + mHandler.obtainMessage( + MyHandler.MESSAGE_NOTIFY_MAGNIFICATION_REGION_CHANGED, args) + .sendToTarget(); } + } - void getMagnificationRegion(@NonNull Region outMagnificationRegion) { - outMagnificationRegion.set(mMagnificationRegion); + private Region getLetterboxBounds(WindowState windowState) { + final ActivityRecord appToken = windowState.mActivityRecord; + if (appToken == null) { + return new Region(); } - void recomputeBounds() { - getDisplaySizeLocked(mScreenSize); - final int screenWidth = mScreenSize.x; - final int screenHeight = mScreenSize.y; + final Rect boundsWithoutLetterbox = windowState.getBounds(); + final Rect letterboxInsets = appToken.getLetterboxInsets(); - mMagnificationRegion.set(0, 0, 0, 0); - final Region availableBounds = mTempRegion1; - availableBounds.set(0, 0, screenWidth, screenHeight); + final Rect boundsIncludingLetterbox = Rect.copyOrNull(boundsWithoutLetterbox); + // Letterbox insets from mActivityRecord are positive, so we negate them to grow the + // bounds to include the letterbox. + boundsIncludingLetterbox.inset( + Insets.subtract(Insets.NONE, Insets.of(letterboxInsets))); - if (mCircularPath != null) { - availableBounds.setPath(mCircularPath, availableBounds); + final Region letterboxBounds = new Region(); + letterboxBounds.set(boundsIncludingLetterbox); + letterboxBounds.op(boundsWithoutLetterbox, Region.Op.DIFFERENCE); + return letterboxBounds; + } + + private boolean isExcludedWindowType(int windowType) { + return windowType == TYPE_MAGNIFICATION_OVERLAY + // Omit the touch region of window magnification to avoid the cut out of the + // magnification and the magnified center of window magnification could be + // in the bounds + || windowType == TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY; + } + + private void populateWindowsOnScreen(SparseArray<WindowState> outWindows) { + mTempLayer = 0; + mDisplayContent.forAllWindows((w) -> { + if (w.isOnScreen() && w.isVisible() + && (w.mAttrs.alpha != 0)) { + mTempLayer++; + outWindows.put(mTempLayer, w); } + }, /* traverseTopToBottom= */ false); + } - Region nonMagnifiedBounds = mTempRegion4; - nonMagnifiedBounds.set(0, 0, 0, 0); - - SparseArray<WindowState> visibleWindows = mTempWindowStates; - visibleWindows.clear(); - populateWindowsOnScreen(visibleWindows); - - final int visibleWindowCount = visibleWindows.size(); - for (int i = visibleWindowCount - 1; i >= 0; i--) { - WindowState windowState = visibleWindows.valueAt(i); - final int windowType = windowState.mAttrs.type; - if (isExcludedWindowType(windowType) - || ((windowState.mAttrs.privateFlags - & PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION) != 0) - || ((windowState.mAttrs.privateFlags - & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0)) { - continue; - } + private void getDisplaySizeLocked(Point outSize) { + final Rect bounds = + mDisplayContent.getConfiguration().windowConfiguration.getBounds(); + outSize.set(bounds.width(), bounds.height()); + } - // Consider the touchable portion of the window - Matrix matrix = mTempMatrix; - populateTransformationMatrix(windowState, matrix); - Region touchableRegion = mTempRegion3; - windowState.getTouchableRegion(touchableRegion); - Rect touchableFrame = mTempRect1; - touchableRegion.getBounds(touchableFrame); - RectF windowFrame = mTempRectF; - windowFrame.set(touchableFrame); - windowFrame.offset(-windowState.getFrame().left, - -windowState.getFrame().top); - matrix.mapRect(windowFrame); - Region windowBounds = mTempRegion2; - windowBounds.set((int) windowFrame.left, (int) windowFrame.top, - (int) windowFrame.right, (int) windowFrame.bottom); - // Only update new regions - Region portionOfWindowAlreadyAccountedFor = mTempRegion3; - portionOfWindowAlreadyAccountedFor.set(mMagnificationRegion); - portionOfWindowAlreadyAccountedFor.op(nonMagnifiedBounds, Region.Op.UNION); - windowBounds.op(portionOfWindowAlreadyAccountedFor, Region.Op.DIFFERENCE); - - if (windowState.shouldMagnify()) { - mMagnificationRegion.op(windowBounds, Region.Op.UNION); - mMagnificationRegion.op(availableBounds, Region.Op.INTERSECT); - } else { - nonMagnifiedBounds.op(windowBounds, Region.Op.UNION); - availableBounds.op(windowBounds, Region.Op.DIFFERENCE); - } + void dump(PrintWriter pw, String prefix) { + mMagnifedViewport.dump(pw, prefix); + } - // If the navigation bar window doesn't have touchable region, count - // navigation bar insets into nonMagnifiedBounds. It happens when - // navigation mode is gestural. - if (isUntouchableNavigationBar(windowState, mTempRegion3)) { - final Rect navBarInsets = getSystemBarInsetsFrame(windowState); - nonMagnifiedBounds.op(navBarInsets, Region.Op.UNION); - availableBounds.op(navBarInsets, Region.Op.DIFFERENCE); - } + private final class MagnifiedViewport { - // Count letterbox into nonMagnifiedBounds - if (windowState.areAppWindowBoundsLetterboxed()) { - Region letterboxBounds = getLetterboxBounds(windowState); - nonMagnifiedBounds.op(letterboxBounds, Region.Op.UNION); - availableBounds.op(letterboxBounds, Region.Op.DIFFERENCE); - } + private final float mBorderWidth; + private final int mHalfBorderWidth; + private final int mDrawBorderInset; - // Update accounted bounds - Region accountedBounds = mTempRegion2; - accountedBounds.set(mMagnificationRegion); - accountedBounds.op(nonMagnifiedBounds, Region.Op.UNION); - accountedBounds.op(0, 0, screenWidth, screenHeight, Region.Op.INTERSECT); - - if (accountedBounds.isRect()) { - Rect accountedFrame = mTempRect1; - accountedBounds.getBounds(accountedFrame); - if (accountedFrame.width() == screenWidth - && accountedFrame.height() == screenHeight) { - break; - } - } - } - visibleWindows.clear(); + private final ViewportWindow mWindow; - mMagnificationRegion.op(mDrawBorderInset, mDrawBorderInset, - screenWidth - mDrawBorderInset, screenHeight - mDrawBorderInset, - Region.Op.INTERSECT); + private boolean mFullRedrawNeeded; - final boolean magnifiedChanged = - !mOldMagnificationRegion.equals(mMagnificationRegion); - if (magnifiedChanged) { - mWindow.setBounds(mMagnificationRegion); - final Rect dirtyRect = mTempRect1; - if (mFullRedrawNeeded) { - mFullRedrawNeeded = false; - dirtyRect.set(mDrawBorderInset, mDrawBorderInset, - screenWidth - mDrawBorderInset, - screenHeight - mDrawBorderInset); - mWindow.invalidate(dirtyRect); - } else { - final Region dirtyRegion = mTempRegion3; - dirtyRegion.set(mMagnificationRegion); - dirtyRegion.op(mOldMagnificationRegion, Region.Op.XOR); - dirtyRegion.getBounds(dirtyRect); - mWindow.invalidate(dirtyRect); - } + MagnifiedViewport() { + mBorderWidth = mDisplayContext.getResources().getDimension( + com.android.internal.R.dimen.accessibility_magnification_indicator_width); + mHalfBorderWidth = (int) Math.ceil(mBorderWidth / 2); + mDrawBorderInset = (int) mBorderWidth / 2; + mWindow = new ViewportWindow(mDisplayContext); + } - mOldMagnificationRegion.set(mMagnificationRegion); - final SomeArgs args = SomeArgs.obtain(); - args.arg1 = Region.obtain(mMagnificationRegion); - mHandler.obtainMessage( - MyHandler.MESSAGE_NOTIFY_MAGNIFICATION_REGION_CHANGED, args) - .sendToTarget(); + void updateBorderDrawingStatus(int screenWidth, int screenHeight) { + mWindow.setBounds(mMagnificationRegion); + final Rect dirtyRect = mTempRect1; + if (mFullRedrawNeeded) { + mFullRedrawNeeded = false; + dirtyRect.set(mDrawBorderInset, mDrawBorderInset, + screenWidth - mDrawBorderInset, + screenHeight - mDrawBorderInset); + mWindow.invalidate(dirtyRect); + } else { + final Region dirtyRegion = mTempRegion3; + dirtyRegion.set(mMagnificationRegion); + dirtyRegion.op(mOldMagnificationRegion, Region.Op.XOR); + dirtyRegion.getBounds(dirtyRect); + mWindow.invalidate(dirtyRect); } } - private Region getLetterboxBounds(WindowState windowState) { - final ActivityRecord appToken = windowState.mActivityRecord; - if (appToken == null) { - return new Region(); + void setShowMagnifiedBorderIfNeeded() { + // If this message is pending, we are in a rotation animation and do not want + // to show the border. We will do so when the pending message is handled. + if (!mHandler.hasMessages( + MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED)) { + setMagnifiedRegionBorderShown( + isFullscreenMagnificationActivated(), true); } + } - final Rect boundsWithoutLetterbox = windowState.getBounds(); - final Rect letterboxInsets = appToken.getLetterboxInsets(); - - final Rect boundsIncludingLetterbox = Rect.copyOrNull(boundsWithoutLetterbox); - // Letterbox insets from mActivityRecord are positive, so we negate them to grow the - // bounds to include the letterbox. - boundsIncludingLetterbox.inset( - Insets.subtract(Insets.NONE, Insets.of(letterboxInsets))); - - final Region letterboxBounds = new Region(); - letterboxBounds.set(boundsIncludingLetterbox); - letterboxBounds.op(boundsWithoutLetterbox, Region.Op.DIFFERENCE); - return letterboxBounds; + // Can be called outside of a surface transaction + void showMagnificationBoundsIfNeeded() { + if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) { + mAccessibilityTracing.logTrace(LOG_TAG + ".showMagnificationBoundsIfNeeded", + FLAGS_MAGNIFICATION_CALLBACK); + } + mHandler.obtainMessage(MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED) + .sendToTarget(); } - private boolean isExcludedWindowType(int windowType) { - return windowType == TYPE_MAGNIFICATION_OVERLAY - // Omit the touch region of window magnification to avoid the cut out of the - // magnification and the magnified center of window magnification could be - // in the bounds - || windowType == TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY; + void intersectWithDrawBorderInset(int screenWidth, int screenHeight) { + mMagnificationRegion.op(mDrawBorderInset, mDrawBorderInset, + screenWidth - mDrawBorderInset, screenHeight - mDrawBorderInset, + Region.Op.INTERSECT); } void onDisplaySizeChanged() { - // If we are showing the magnification border, hide it immediately so + // If fullscreen magnification is activated, hide the border immediately so // the user does not see strange artifacts during display size changed caused by // rotation or folding/unfolding the device. In the rotation case, the screenshot // used for rotation already has the border. After the rotation is complete // we will show the border. - if (isForceShowingMagnifiableBounds()) { + if (isFullscreenMagnificationActivated()) { setMagnifiedRegionBorderShown(false, false); final long delay = (long) (mLongAnimationDuration * mService.getWindowAnimationScaleLocked()); @@ -1127,7 +1149,6 @@ final class AccessibilityController { MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED); mHandler.sendMessageDelayed(message, delay); } - recomputeBounds(); mWindow.updateSize(); } @@ -1148,23 +1169,6 @@ final class AccessibilityController { mWindow.releaseSurface(); } - private void populateWindowsOnScreen(SparseArray<WindowState> outWindows) { - mTempLayer = 0; - mDisplayContent.forAllWindows((w) -> { - if (w.isOnScreen() && w.isVisible() - && (w.mAttrs.alpha != 0)) { - mTempLayer++; - outWindows.put(mTempLayer, w); - } - }, false /* traverseTopToBottom */ ); - } - - private void getDisplaySizeLocked(Point outSize) { - final Rect bounds = - mDisplayContent.getConfiguration().windowConfiguration.getBounds(); - outSize.set(bounds.width(), bounds.height()); - } - void dump(PrintWriter pw, String prefix) { mWindow.dump(pw, prefix); } @@ -1490,7 +1494,7 @@ final class AccessibilityController { case MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED : { synchronized (mService.mGlobalLock) { - if (isForceShowingMagnifiableBounds()) { + if (isFullscreenMagnificationActivated()) { mMagnifedViewport.setMagnifiedRegionBorderShown(true, true); mService.scheduleAnimationLocked(); } diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index 669c61c4b40ced72201704a93d95f71e0f18ec5f..ddda3f45b0614b301201925d0234a15392a85886 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -409,13 +409,12 @@ public abstract class WindowManagerInternal { public abstract void setMagnificationSpec(int displayId, MagnificationSpec spec); /** - * Set by the accessibility framework to indicate whether the magnifiable regions of the display - * should be shown. + * Set by the accessibility framework to indicate whether fullscreen magnification is activated. * * @param displayId The logical display id. - * @param show {@code true} to show magnifiable region bounds, {@code false} to hide + * @param activated The activation of fullscreen magnification */ - public abstract void setForceShowMagnifiableBounds(int displayId, boolean show); + public abstract void setFullscreenMagnificationActivated(int displayId, boolean activated); /** * Obtains the magnification regions. diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 61480d25336499c336b1854fd04cc32942c25d13..8ebe82656cc5f5781441d1a9f9f029bb5b3d266d 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -7858,10 +7858,11 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public void setForceShowMagnifiableBounds(int displayId, boolean show) { + public void setFullscreenMagnificationActivated(int displayId, boolean activated) { synchronized (mGlobalLock) { if (mAccessibilityController.hasCallbacks()) { - mAccessibilityController.setForceShowMagnifiableBounds(displayId, show); + mAccessibilityController + .setFullscreenMagnificationActivated(displayId, activated); } else { throw new IllegalStateException("Magnification callbacks not set!"); } diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java index b224773a9eb15e227af14fbb86dafd93e84d72b6..f3cd0d6b961e48c04e2a2b0853999e0c07bebf21 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java @@ -1360,7 +1360,7 @@ public class FullScreenMagnificationControllerTest { DISPLAY_0, scale, Float.NaN, Float.NaN, true, SERVICE_ID_1); checkActivatedAndMagnifying(/* activated= */ true, /* magnifying= */ false, DISPLAY_0); - verify(mMockWindowManager).setForceShowMagnifiableBounds(DISPLAY_0, true); + verify(mMockWindowManager).setFullscreenMagnificationActivated(DISPLAY_0, true); } @Test