Merge "Fix several accessibility magnification issues." into nyc-dev

This commit is contained in:
Phil Weaver
2016-04-27 22:50:34 +00:00
committed by Android (Google) Code Review
10 changed files with 313 additions and 241 deletions

View File

@@ -2699,7 +2699,7 @@ package android.accessibilityservice {
method public void addListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener, android.os.Handler); method public void addListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener, android.os.Handler);
method public float getCenterX(); method public float getCenterX();
method public float getCenterY(); method public float getCenterY();
method public android.graphics.Region getMagnifiedRegion(); method public android.graphics.Region getMagnificationRegion();
method public float getScale(); method public float getScale();
method public boolean removeListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener); method public boolean removeListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener);
method public boolean reset(boolean); method public boolean reset(boolean);

View File

@@ -2810,7 +2810,7 @@ package android.accessibilityservice {
method public void addListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener, android.os.Handler); method public void addListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener, android.os.Handler);
method public float getCenterX(); method public float getCenterX();
method public float getCenterY(); method public float getCenterY();
method public android.graphics.Region getMagnifiedRegion(); method public android.graphics.Region getMagnificationRegion();
method public float getScale(); method public float getScale();
method public boolean removeListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener); method public boolean removeListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener);
method public boolean reset(boolean); method public boolean reset(boolean);

View File

@@ -2699,7 +2699,7 @@ package android.accessibilityservice {
method public void addListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener, android.os.Handler); method public void addListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener, android.os.Handler);
method public float getCenterX(); method public float getCenterX();
method public float getCenterY(); method public float getCenterY();
method public android.graphics.Region getMagnifiedRegion(); method public android.graphics.Region getMagnificationRegion();
method public float getScale(); method public float getScale();
method public boolean removeListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener); method public boolean removeListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener);
method public boolean reset(boolean); method public boolean reset(boolean);

View File

@@ -925,18 +925,25 @@ public abstract class AccessibilityService extends Service {
} }
/** /**
* Returns the region of the screen currently being magnified. If * Returns the region of the screen currently active for magnification. Changes to
* magnification is not enabled, the returned region will be empty. * magnification scale and center only affect this portion of the screen. The rest of the
* screen, for example input methods, cannot be magnified. This region is relative to the
* unscaled screen and is independent of the scale and center point.
* <p>
* The returned region will be empty if magnification is not active. Magnification is active
* if magnification gestures are enabled or if a service is running that can control
* magnification.
* <p> * <p>
* <strong>Note:</strong> If the service is not yet connected (e.g. * <strong>Note:</strong> If the service is not yet connected (e.g.
* {@link AccessibilityService#onServiceConnected()} has not yet been * {@link AccessibilityService#onServiceConnected()} has not yet been
* called) or the service has been disconnected, this method will * called) or the service has been disconnected, this method will
* return an empty region. * return an empty region.
* *
* @return the screen-relative bounds of the magnified region * @return the region of the screen currently active for magnification, or an empty region
* if magnification is not active.
*/ */
@NonNull @NonNull
public Region getMagnifiedRegion() { public Region getMagnificationRegion() {
final IAccessibilityServiceConnection connection = final IAccessibilityServiceConnection connection =
AccessibilityInteractionClient.getInstance().getConnection( AccessibilityInteractionClient.getInstance().getConnection(
mService.mConnectionId); mService.mConnectionId);
@@ -1049,11 +1056,12 @@ public abstract class AccessibilityService extends Service {
* Called when the magnified region, scale, or center changes. * Called when the magnified region, scale, or center changes.
* *
* @param controller the magnification controller * @param controller the magnification controller
* @param region the new magnified region, may be empty if * @param region the magnification region
* magnification is not enabled (e.g. scale is 1)
* @param scale the new scale * @param scale the new scale
* @param centerX the new X coordinate around which magnification is focused * @param centerX the new X coordinate, in unscaled coordinates, around which
* @param centerY the new Y coordinate around which magnification is focused * magnification is focused
* @param centerY the new Y coordinate, in unscaled coordinates, around which
* magnification is focused
*/ */
void onMagnificationChanged(@NonNull MagnificationController controller, void onMagnificationChanged(@NonNull MagnificationController controller,
@NonNull Region region, float scale, float centerX, float centerY); @NonNull Region region, float scale, float centerX, float centerY);

View File

@@ -54,13 +54,12 @@ public abstract class WindowManagerInternal {
public interface MagnificationCallbacks { public interface MagnificationCallbacks {
/** /**
* Called when the bounds of the screen content that is magnified changed. * Called when the region where magnification operates changes. Note that this isn't the
* Note that not the entire screen is magnified. * entire screen. For example, IMEs are not magnified.
* *
* @param magnifiedBounds the currently magnified region * @param magnificationRegion the current magnification region
* @param availableBounds the region available for magnification
*/ */
public void onMagnifiedBoundsChanged(Region magnifiedBounds, Region availableBounds); public void onMagnificationRegionChanged(Region magnificationRegion);
/** /**
* Called when an application requests a rectangle on the screen to allow * Called when an application requests a rectangle on the screen to allow
@@ -158,13 +157,11 @@ public abstract class WindowManagerInternal {
public abstract void setMagnificationSpec(MagnificationSpec spec); public abstract void setMagnificationSpec(MagnificationSpec spec);
/** /**
* Obtains the magnified and available regions. * Obtains the magnification regions.
* *
* @param outMagnified the currently magnified region * @param magnificationRegion the current magnification region
* @param outAvailable the region available for magnification
*/ */
public abstract void getMagnificationRegions(@NonNull Region outMagnified, public abstract void getMagnificationRegion(@NonNull Region magnificationRegion);
@NonNull Region outAvailable);
/** /**
* Gets the magnification and translation applied to a window given its token. * Gets the magnification and translation applied to a window given its token.

View File

@@ -151,7 +151,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private static final int WINDOW_ID_UNKNOWN = -1; private static final int WINDOW_ID_UNKNOWN = -1;
private static int sIdCounter = 0; // Each service has an ID. Also provide one for magnification gesture handling
public static final int MAGNIFICATION_GESTURE_HANDLER_ID = 0;
private static int sIdCounter = MAGNIFICATION_GESTURE_HANDLER_ID + 1;
private static int sNextWindowId; private static int sNextWindowId;
@@ -183,8 +186,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private MagnificationController mMagnificationController; private MagnificationController mMagnificationController;
private boolean mUnregisterMagnificationOnReset;
private InteractionBridge mInteractionBridge; private InteractionBridge mInteractionBridge;
private AlertDialog mEnableTouchExplorationDialog; private AlertDialog mEnableTouchExplorationDialog;
@@ -784,11 +785,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
float scale, float centerX, float centerY) { float scale, float centerX, float centerY) {
synchronized (mLock) { synchronized (mLock) {
notifyMagnificationChangedLocked(region, scale, centerX, centerY); notifyMagnificationChangedLocked(region, scale, centerX, centerY);
if (mUnregisterMagnificationOnReset && scale == 1.0f) {
mUnregisterMagnificationOnReset = false;
mMagnificationController.unregister();
}
} }
} }
@@ -1736,25 +1732,17 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
} }
private void updateMagnificationLocked(UserState userState) { private void updateMagnificationLocked(UserState userState) {
final int userId = userState.mUserId; if (userState.mUserId != mCurrentUserId) {
if (userId == mCurrentUserId && mMagnificationController != null) { return;
if (userState.mIsDisplayMagnificationEnabled || }
userHasMagnificationServicesLocked(userState)) {
mMagnificationController.setUserId(userState.mUserId); if (userState.mIsDisplayMagnificationEnabled ||
} else { userHasMagnificationServicesLocked(userState)) {
// If the user no longer has any magnification-controlling // Initialize the magnification controller if necessary
// services and is not using magnification gestures, then getMagnificationController();
// reset the state to normal. mMagnificationController.register();
if (mMagnificationController.resetIfNeeded(true)) { } else if (mMagnificationController != null) {
// Animations are still running, so wait until we receive a mMagnificationController.unregister();
// callback verifying that we've reset magnification.
mUnregisterMagnificationOnReset = true;
} else {
mUnregisterMagnificationOnReset = false;
mMagnificationController.unregister();
mMagnificationController = null;
}
}
} }
} }
@@ -2152,7 +2140,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
synchronized (mLock) { synchronized (mLock) {
if (mMagnificationController == null) { if (mMagnificationController == null) {
mMagnificationController = new MagnificationController(mContext, this, mLock); mMagnificationController = new MagnificationController(mContext, this, mLock);
mMagnificationController.register();
mMagnificationController.setUserId(mCurrentUserId); mMagnificationController.setUserId(mCurrentUserId);
} }
return mMagnificationController; return mMagnificationController;
@@ -2886,7 +2873,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
final long identity = Binder.clearCallingIdentity(); final long identity = Binder.clearCallingIdentity();
try { try {
final Region region = Region.obtain(); final Region region = Region.obtain();
getMagnificationController().getMagnifiedRegion(region); getMagnificationController().getMagnificationRegion(region);
return region; return region;
} finally { } finally {
Binder.restoreCallingIdentity(identity); Binder.restoreCallingIdentity(identity);
@@ -2957,7 +2944,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
final long identity = Binder.clearCallingIdentity(); final long identity = Binder.clearCallingIdentity();
try { try {
return getMagnificationController().setScaleAndCenter( return getMagnificationController().setScaleAndCenter(
scale, centerX, centerY, animate); scale, centerX, centerY, animate, mId);
} finally { } finally {
Binder.restoreCallingIdentity(identity); Binder.restoreCallingIdentity(identity);
} }
@@ -3090,10 +3077,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
userState.mInstalledServices.remove(mAccessibilityServiceInfo); userState.mInstalledServices.remove(mAccessibilityServiceInfo);
userState.mEnabledServices.remove(mComponentName); userState.mEnabledServices.remove(mComponentName);
userState.destroyUiAutomationService(); userState.destroyUiAutomationService();
if (readConfigurationForUserStateLocked(userState)) {
onUserStateChangedLocked(userState);
}
} }
if (mId == getMagnificationController().getIdOfLastServiceToMagnify()) {
getMagnificationController().resetIfNeeded(true);
}
onUserStateChangedLocked(userState);
} }
} }

View File

@@ -17,6 +17,7 @@
package com.android.server.accessibility; package com.android.server.accessibility;
import com.android.internal.R; import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.SomeArgs; import com.android.internal.os.SomeArgs;
import com.android.server.LocalServices; import com.android.server.LocalServices;
@@ -60,6 +61,8 @@ class MagnificationController {
private static final int DEFAULT_SCREEN_MAGNIFICATION_AUTO_UPDATE = 1; private static final int DEFAULT_SCREEN_MAGNIFICATION_AUTO_UPDATE = 1;
private static final int INVALID_ID = -1;
private static final float DEFAULT_MAGNIFICATION_SCALE = 2.0f; private static final float DEFAULT_MAGNIFICATION_SCALE = 2.0f;
private static final float MIN_SCALE = 1.0f; private static final float MIN_SCALE = 1.0f;
@@ -80,9 +83,8 @@ class MagnificationController {
*/ */
private final MagnificationSpec mCurrentMagnificationSpec = MagnificationSpec.obtain(); private final MagnificationSpec mCurrentMagnificationSpec = MagnificationSpec.obtain();
private final Region mMagnifiedRegion = Region.obtain(); private final Region mMagnificationRegion = Region.obtain();
private final Region mAvailableRegion = Region.obtain(); private final Rect mMagnificationBounds = new Rect();
private final Rect mMagnifiedBounds = new Rect();
private final Rect mTempRect = new Rect(); private final Rect mTempRect = new Rect();
private final Rect mTempRect1 = new Rect(); private final Rect mTempRect1 = new Rect();
@@ -97,35 +99,67 @@ class MagnificationController {
private int mUserId; private int mUserId;
private int mIdOfLastServiceToMagnify = INVALID_ID;
// Flag indicating that we are registered with window manager.
private boolean mRegistered;
private boolean mUnregisterPending;
public MagnificationController(Context context, AccessibilityManagerService ams, Object lock) { public MagnificationController(Context context, AccessibilityManagerService ams, Object lock) {
mAms = ams; mAms = ams;
mContentResolver = context.getContentResolver(); mContentResolver = context.getContentResolver();
mScreenStateObserver = new ScreenStateObserver(context, this); mScreenStateObserver = new ScreenStateObserver(context, this);
mWindowStateObserver = new WindowStateObserver(context, this); mWindowStateObserver = new WindowStateObserver(context, this);
mSpecAnimationBridge = new SpecAnimationBridge(context);
mLock = lock; mLock = lock;
mSpecAnimationBridge = new SpecAnimationBridge(context, mLock);
} }
/** /**
* Registers magnification-related observers. * Start tracking the magnification region for services that control magnification and the
* magnification gesture handler.
*
* This tracking imposes a cost on the system, so we avoid tracking this data
* unless it's required.
*/ */
public void register() { public void register() {
mScreenStateObserver.register(); synchronized (mLock) {
mWindowStateObserver.register(); if (!mRegistered) {
mScreenStateObserver.register();
// Obtain initial state. mWindowStateObserver.register();
mWindowStateObserver.getRegions(mMagnifiedRegion, mAvailableRegion); mSpecAnimationBridge.setEnabled(true);
mMagnifiedRegion.getBounds(mMagnifiedBounds); // Obtain initial state.
mWindowStateObserver.getMagnificationRegion(mMagnificationRegion);
mMagnificationRegion.getBounds(mMagnificationBounds);
mRegistered = true;
}
}
} }
/** /**
* Unregisters magnification-related observers. * Stop requiring tracking the magnification region. We may remain registered while we
* reset magnification.
*/ */
public void unregister() { public void unregister() {
mSpecAnimationBridge.cancel(); synchronized (mLock) {
if (!isMagnifying()) {
unregisterInternalLocked();
} else {
mUnregisterPending = true;
resetLocked(true);
}
}
}
mScreenStateObserver.unregister(); private void unregisterInternalLocked() {
mWindowStateObserver.unregister(); if (mRegistered) {
mSpecAnimationBridge.setEnabled(false);
mScreenStateObserver.unregister();
mWindowStateObserver.unregister();
mMagnificationRegion.setEmpty();
mRegistered = false;
}
mUnregisterPending = false;
} }
/** /**
@@ -137,24 +171,22 @@ class MagnificationController {
} }
/** /**
* Sets the magnified and available regions. * Update our copy of the current magnification region
* *
* @param magnified the magnified region * @param magnified the magnified region
* @param available the region available for magnification
* @param updateSpec {@code true} to update the scale and center based on * @param updateSpec {@code true} to update the scale and center based on
* the region bounds, {@code false} to leave them as-is * the region bounds, {@code false} to leave them as-is
*/ */
private void setMagnifiedRegion(Region magnified, Region available, boolean updateSpec) { private void onMagnificationRegionChanged(Region magnified, boolean updateSpec) {
synchronized (mLock) { synchronized (mLock) {
boolean magnificationChanged = false; boolean magnificationChanged = false;
boolean boundsChanged = false; boolean boundsChanged = false;
if (!mMagnifiedRegion.equals(magnified)) { if (!mMagnificationRegion.equals(magnified)) {
mMagnifiedRegion.set(magnified); mMagnificationRegion.set(magnified);
mMagnifiedRegion.getBounds(mMagnifiedBounds); mMagnificationRegion.getBounds(mMagnificationBounds);
boundsChanged = true; boundsChanged = true;
} }
mAvailableRegion.set(available);
if (updateSpec) { if (updateSpec) {
final MagnificationSpec sentSpec = mSpecAnimationBridge.mSentMagnificationSpec; final MagnificationSpec sentSpec = mSpecAnimationBridge.mSentMagnificationSpec;
final float scale = sentSpec.scale; final float scale = sentSpec.scale;
@@ -162,12 +194,12 @@ class MagnificationController {
final float offsetY = sentSpec.offsetY; final float offsetY = sentSpec.offsetY;
// Compute the new center and update spec as needed. // Compute the new center and update spec as needed.
final float centerX = (mMagnifiedBounds.width() / 2.0f final float centerX = (mMagnificationBounds.width() / 2.0f
+ mMagnifiedBounds.left - offsetX) / scale; + mMagnificationBounds.left - offsetX) / scale;
final float centerY = (mMagnifiedBounds.height() / 2.0f final float centerY = (mMagnificationBounds.height() / 2.0f
+ mMagnifiedBounds.top - offsetY) / scale; + mMagnificationBounds.top - offsetY) / scale;
magnificationChanged = setScaleAndCenterLocked( magnificationChanged = setScaleAndCenterLocked(
scale, centerX, centerY, false); scale, centerX, centerY, false, INVALID_ID);
} }
// If magnification changed we already notified for the change. // If magnification changed we already notified for the change.
@@ -178,7 +210,7 @@ class MagnificationController {
} }
/** /**
* Returns whether the magnified region contains the specified * Returns whether the magnification region contains the specified
* screen-relative coordinates. * screen-relative coordinates.
* *
* @param x the screen-relative X coordinate to check * @param x the screen-relative X coordinate to check
@@ -186,51 +218,36 @@ class MagnificationController {
* @return {@code true} if the coordinate is contained within the * @return {@code true} if the coordinate is contained within the
* magnified region, or {@code false} otherwise * magnified region, or {@code false} otherwise
*/ */
public boolean magnifiedRegionContains(float x, float y) { public boolean magnificationRegionContains(float x, float y) {
synchronized (mLock) { synchronized (mLock) {
return mMagnifiedRegion.contains((int) x, (int) y); return mMagnificationRegion.contains((int) x, (int) y);
}
}
/**
* Returns whether the region available for magnification contains the
* specified screen-relative coordinates.
*
* @param x the screen-relative X coordinate to check
* @param y the screen-relative Y coordinate to check
* @return {@code true} if the coordinate is contained within the
* region available for magnification, or {@code false} otherwise
*/
private boolean availableRegionContains(float x, float y) {
synchronized (mLock) {
return mAvailableRegion.contains((int) x, (int) y);
} }
} }
/** /**
* Populates the specified rect with the screen-relative bounds of the * Populates the specified rect with the screen-relative bounds of the
* magnified region. If magnification is not enabled, the returned * magnification region. If magnification is not enabled, the returned
* bounds will be empty. * bounds will be empty.
* *
* @param outBounds rect to populate with the bounds of the magnified * @param outBounds rect to populate with the bounds of the magnified
* region * region
*/ */
public void getMagnifiedBounds(@NonNull Rect outBounds) { public void getMagnificationBounds(@NonNull Rect outBounds) {
synchronized (mLock) { synchronized (mLock) {
outBounds.set(mMagnifiedBounds); outBounds.set(mMagnificationBounds);
} }
} }
/** /**
* Populates the specified region with the screen-relative magnified * Populates the specified region with the screen-relative magnification
* region. If magnification is not enabled, then the returned region * region. If magnification is not enabled, then the returned region
* will be empty. * will be empty.
* *
* @param outRegion the region to populate * @param outRegion the region to populate
*/ */
public void getMagnifiedRegion(@NonNull Region outRegion) { public void getMagnificationRegion(@NonNull Region outRegion) {
synchronized (mLock) { synchronized (mLock) {
outRegion.set(mMagnifiedRegion); outRegion.set(mMagnificationRegion);
} }
} }
@@ -263,8 +280,8 @@ class MagnificationController {
*/ */
public float getCenterX() { public float getCenterX() {
synchronized (mLock) { synchronized (mLock) {
return (mMagnifiedBounds.width() / 2.0f return (mMagnificationBounds.width() / 2.0f
+ mMagnifiedBounds.left - getOffsetX()) / getScale(); + mMagnificationBounds.left - getOffsetX()) / getScale();
} }
} }
@@ -286,8 +303,8 @@ class MagnificationController {
*/ */
public float getCenterY() { public float getCenterY() {
synchronized (mLock) { synchronized (mLock) {
return (mMagnifiedBounds.height() / 2.0f return (mMagnificationBounds.height() / 2.0f
+ mMagnifiedBounds.top - getOffsetY()) / getScale(); + mMagnificationBounds.top - getOffsetY()) / getScale();
} }
} }
@@ -335,17 +352,25 @@ class MagnificationController {
*/ */
public boolean reset(boolean animate) { public boolean reset(boolean animate) {
synchronized (mLock) { synchronized (mLock) {
final MagnificationSpec spec = mCurrentMagnificationSpec; return resetLocked(animate);
final boolean changed = !spec.isNop();
if (changed) {
spec.clear();
onMagnificationChangedLocked();
}
mSpecAnimationBridge.updateSentSpec(spec, animate);
return changed;
} }
} }
private boolean resetLocked(boolean animate) {
if (!mRegistered) {
return false;
}
final MagnificationSpec spec = mCurrentMagnificationSpec;
final boolean changed = !spec.isNop();
if (changed) {
spec.clear();
onMagnificationChangedLocked();
}
mIdOfLastServiceToMagnify = INVALID_ID;
mSpecAnimationBridge.updateSentSpec(spec, animate);
return changed;
}
/** /**
* Scales the magnified region around the specified pivot point, * Scales the magnified region around the specified pivot point,
* optionally animating the transition. If animation is disabled, the * optionally animating the transition. If animation is disabled, the
@@ -356,16 +381,20 @@ class MagnificationController {
* @param pivotY the screen-relative Y coordinate around which to scale * @param pivotY the screen-relative Y coordinate around which to scale
* @param animate {@code true} to animate the transition, {@code false} * @param animate {@code true} to animate the transition, {@code false}
* to transition immediately * to transition immediately
* @param id the ID of the service requesting the change
* @return {@code true} if the magnification spec changed, {@code false} if * @return {@code true} if the magnification spec changed, {@code false} if
* the spec did not change * the spec did not change
*/ */
public boolean setScale(float scale, float pivotX, float pivotY, boolean animate) { public boolean setScale(float scale, float pivotX, float pivotY, boolean animate, int id) {
synchronized (mLock) { synchronized (mLock) {
if (!mRegistered) {
return false;
}
// Constrain scale immediately for use in the pivot calculations. // Constrain scale immediately for use in the pivot calculations.
scale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE); scale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
final Rect viewport = mTempRect; final Rect viewport = mTempRect;
mMagnifiedRegion.getBounds(viewport); mMagnificationRegion.getBounds(viewport);
final MagnificationSpec spec = mCurrentMagnificationSpec; final MagnificationSpec spec = mCurrentMagnificationSpec;
final float oldScale = spec.scale; final float oldScale = spec.scale;
final float oldCenterX = (viewport.width() / 2.0f - spec.offsetX) / oldScale; final float oldCenterX = (viewport.width() / 2.0f - spec.offsetX) / oldScale;
@@ -376,7 +405,8 @@ class MagnificationController {
final float offsetY = (oldCenterY - normPivotY) * (oldScale / scale); final float offsetY = (oldCenterY - normPivotY) * (oldScale / scale);
final float centerX = normPivotX + offsetX; final float centerX = normPivotX + offsetX;
final float centerY = normPivotY + offsetY; final float centerY = normPivotY + offsetY;
return setScaleAndCenterLocked(scale, centerX, centerY, animate); mIdOfLastServiceToMagnify = id;
return setScaleAndCenterLocked(scale, centerX, centerY, animate, id);
} }
} }
@@ -390,12 +420,16 @@ class MagnificationController {
* center * center
* @param animate {@code true} to animate the transition, {@code false} * @param animate {@code true} to animate the transition, {@code false}
* to transition immediately * to transition immediately
* @param id the ID of the service requesting the change
* @return {@code true} if the magnification spec changed, {@code false} if * @return {@code true} if the magnification spec changed, {@code false} if
* the spec did not change * the spec did not change
*/ */
public boolean setCenter(float centerX, float centerY, boolean animate) { public boolean setCenter(float centerX, float centerY, boolean animate, int id) {
synchronized (mLock) { synchronized (mLock) {
return setScaleAndCenterLocked(Float.NaN, centerX, centerY, animate); if (!mRegistered) {
return false;
}
return setScaleAndCenterLocked(Float.NaN, centerX, centerY, animate, id);
} }
} }
@@ -411,19 +445,27 @@ class MagnificationController {
* center and scale, or {@link Float#NaN} to leave unchanged * center and scale, or {@link Float#NaN} to leave unchanged
* @param animate {@code true} to animate the transition, {@code false} * @param animate {@code true} to animate the transition, {@code false}
* to transition immediately * to transition immediately
* @param id the ID of the service requesting the change
* @return {@code true} if the magnification spec changed, {@code false} if * @return {@code true} if the magnification spec changed, {@code false} if
* the spec did not change * the spec did not change
*/ */
public boolean setScaleAndCenter(float scale, float centerX, float centerY, boolean animate) { public boolean setScaleAndCenter(
float scale, float centerX, float centerY, boolean animate, int id) {
synchronized (mLock) { synchronized (mLock) {
return setScaleAndCenterLocked(scale, centerX, centerY, animate); if (!mRegistered) {
return false;
}
return setScaleAndCenterLocked(scale, centerX, centerY, animate, id);
} }
} }
private boolean setScaleAndCenterLocked(float scale, float centerX, float centerY, private boolean setScaleAndCenterLocked(float scale, float centerX, float centerY,
boolean animate) { boolean animate, int id) {
final boolean changed = updateMagnificationSpecLocked(scale, centerX, centerY); final boolean changed = updateMagnificationSpecLocked(scale, centerX, centerY);
mSpecAnimationBridge.updateSentSpec(mCurrentMagnificationSpec, animate); mSpecAnimationBridge.updateSentSpec(mCurrentMagnificationSpec, animate);
if (isMagnifying() && (id != INVALID_ID)) {
mIdOfLastServiceToMagnify = id;
}
return changed; return changed;
} }
@@ -432,22 +474,42 @@ class MagnificationController {
* *
* @param offsetX the amount in pixels to offset the X center * @param offsetX the amount in pixels to offset the X center
* @param offsetY the amount in pixels to offset the Y center * @param offsetY the amount in pixels to offset the Y center
* @param id the ID of the service requesting the change
*/ */
public void offsetMagnifiedRegionCenter(float offsetX, float offsetY) { public void offsetMagnifiedRegionCenter(float offsetX, float offsetY, int id) {
synchronized (mLock) { synchronized (mLock) {
if (!mRegistered) {
return;
}
final MagnificationSpec currSpec = mCurrentMagnificationSpec; final MagnificationSpec currSpec = mCurrentMagnificationSpec;
final float nonNormOffsetX = currSpec.offsetX - offsetX; final float nonNormOffsetX = currSpec.offsetX - offsetX;
currSpec.offsetX = MathUtils.constrain(nonNormOffsetX, getMinOffsetXLocked(), 0); currSpec.offsetX = MathUtils.constrain(nonNormOffsetX, getMinOffsetXLocked(), 0);
final float nonNormOffsetY = currSpec.offsetY - offsetY; final float nonNormOffsetY = currSpec.offsetY - offsetY;
currSpec.offsetY = MathUtils.constrain(nonNormOffsetY, getMinOffsetYLocked(), 0); currSpec.offsetY = MathUtils.constrain(nonNormOffsetY, getMinOffsetYLocked(), 0);
if (id != INVALID_ID) {
mIdOfLastServiceToMagnify = id;
}
mSpecAnimationBridge.updateSentSpec(currSpec, false); mSpecAnimationBridge.updateSentSpec(currSpec, false);
} }
} }
/**
* Get the ID of the last service that changed the magnification spec.
*
* @return The id
*/
public int getIdOfLastServiceToMagnify() {
return mIdOfLastServiceToMagnify;
}
private void onMagnificationChangedLocked() { private void onMagnificationChangedLocked() {
mAms.onMagnificationStateChanged(); mAms.onMagnificationStateChanged();
mAms.notifyMagnificationChanged(mMagnifiedRegion, mAms.notifyMagnificationChanged(mMagnificationRegion,
getScale(), getCenterX(), getCenterY()); getScale(), getCenterX(), getCenterY());
if (mUnregisterPending && !isMagnifying()) {
unregisterInternalLocked();
}
} }
/** /**
@@ -503,8 +565,8 @@ class MagnificationController {
scale = getScale(); scale = getScale();
} }
// Ensure requested center is within the available region. // Ensure requested center is within the magnification region.
if (!availableRegionContains(centerX, centerY)) { if (!magnificationRegionContains(centerX, centerY)) {
return false; return false;
} }
@@ -518,16 +580,16 @@ class MagnificationController {
changed = true; changed = true;
} }
final float nonNormOffsetX = mMagnifiedBounds.width() / 2.0f final float nonNormOffsetX = mMagnificationBounds.width() / 2.0f
+ mMagnifiedBounds.left - centerX * scale; + mMagnificationBounds.left - centerX * scale;
final float offsetX = MathUtils.constrain(nonNormOffsetX, getMinOffsetXLocked(), 0); final float offsetX = MathUtils.constrain(nonNormOffsetX, getMinOffsetXLocked(), 0);
if (Float.compare(currSpec.offsetX, offsetX) != 0) { if (Float.compare(currSpec.offsetX, offsetX) != 0) {
currSpec.offsetX = offsetX; currSpec.offsetX = offsetX;
changed = true; changed = true;
} }
final float nonNormOffsetY = mMagnifiedBounds.height() / 2.0f final float nonNormOffsetY = mMagnificationBounds.height() / 2.0f
+ mMagnifiedBounds.top - centerY * scale; + mMagnificationBounds.top - centerY * scale;
final float offsetY = MathUtils.constrain(nonNormOffsetY, getMinOffsetYLocked(), 0); final float offsetY = MathUtils.constrain(nonNormOffsetY, getMinOffsetYLocked(), 0);
if (Float.compare(currSpec.offsetY, offsetY) != 0) { if (Float.compare(currSpec.offsetY, offsetY) != 0) {
currSpec.offsetY = offsetY; currSpec.offsetY = offsetY;
@@ -542,12 +604,12 @@ class MagnificationController {
} }
private float getMinOffsetXLocked() { private float getMinOffsetXLocked() {
final float viewportWidth = mMagnifiedBounds.width(); final float viewportWidth = mMagnificationBounds.width();
return viewportWidth - viewportWidth * mCurrentMagnificationSpec.scale; return viewportWidth - viewportWidth * mCurrentMagnificationSpec.scale;
} }
private float getMinOffsetYLocked() { private float getMinOffsetYLocked() {
final float viewportHeight = mMagnifiedBounds.height(); final float viewportHeight = mMagnificationBounds.height();
return viewportHeight - viewportHeight * mCurrentMagnificationSpec.scale; return viewportHeight - viewportHeight * mCurrentMagnificationSpec.scale;
} }
@@ -595,7 +657,7 @@ class MagnificationController {
final float scale = getSentScale(); final float scale = getSentScale();
final float offsetX = getSentOffsetX(); final float offsetX = getSentOffsetX();
final float offsetY = getSentOffsetY(); final float offsetY = getSentOffsetY();
getMagnifiedBounds(outFrame); getMagnificationBounds(outFrame);
outFrame.offset((int) -offsetX, (int) -offsetY); outFrame.offset((int) -offsetX, (int) -offsetY);
outFrame.scale(1.0f / scale); outFrame.scale(1.0f / scale);
} }
@@ -603,7 +665,7 @@ class MagnificationController {
private void requestRectangleOnScreen(int left, int top, int right, int bottom) { private void requestRectangleOnScreen(int left, int top, int right, int bottom) {
synchronized (mLock) { synchronized (mLock) {
final Rect magnifiedFrame = mTempRect; final Rect magnifiedFrame = mTempRect;
getMagnifiedBounds(magnifiedFrame); getMagnificationBounds(magnifiedFrame);
if (!magnifiedFrame.intersects(left, top, right, bottom)) { if (!magnifiedFrame.intersects(left, top, right, bottom)) {
return; return;
} }
@@ -640,7 +702,7 @@ class MagnificationController {
} }
final float scale = getScale(); final float scale = getScale();
offsetMagnifiedRegionCenter(scrollX * scale, scrollY * scale); offsetMagnifiedRegionCenter(scrollX * scale, scrollY * scale, INVALID_ID);
} }
} }
@@ -656,7 +718,7 @@ class MagnificationController {
/** /**
* The magnification spec that was sent to the window manager. This should * The magnification spec that was sent to the window manager. This should
* only be accessed and modified on the main (e.g. animation) thread. * only be accessed with the lock held.
*/ */
private final MagnificationSpec mSentMagnificationSpec = MagnificationSpec.obtain(); private final MagnificationSpec mSentMagnificationSpec = MagnificationSpec.obtain();
@@ -667,8 +729,13 @@ class MagnificationController {
private final ValueAnimator mTransformationAnimator; private final ValueAnimator mTransformationAnimator;
private final long mMainThreadId; private final long mMainThreadId;
private final Object mLock;
private SpecAnimationBridge(Context context) { @GuardedBy("mLock")
private boolean mEnabled = false;
private SpecAnimationBridge(Context context, Object lock) {
mLock = lock;
final Looper mainLooper = context.getMainLooper(); final Looper mainLooper = context.getMainLooper();
mMainThreadId = mainLooper.getThread().getId(); mMainThreadId = mainLooper.getThread().getId();
@@ -685,9 +752,19 @@ class MagnificationController {
mTransformationAnimator.setInterpolator(new DecelerateInterpolator(2.5f)); mTransformationAnimator.setInterpolator(new DecelerateInterpolator(2.5f));
} }
public void cancel() { /**
if (mTransformationAnimator != null && mTransformationAnimator.isRunning()) { * Enabled means the bridge will accept input. When not enabled, the output of the animator
mTransformationAnimator.cancel(); * will be ignored
*/
public void setEnabled(boolean enabled) {
synchronized (mLock) {
if (enabled != mEnabled) {
mEnabled = enabled;
if (!mEnabled) {
mSentMagnificationSpec.clear();
mWindowManager.setMagnificationSpec(mSentMagnificationSpec);
}
}
} }
} }
@@ -710,28 +787,32 @@ class MagnificationController {
} }
// If the current and sent specs don't match, update the sent spec. // If the current and sent specs don't match, update the sent spec.
final boolean changed = !mSentMagnificationSpec.equals(spec); synchronized (mLock) {
if (changed) { final boolean changed = !mSentMagnificationSpec.equals(spec);
if (animate) { if (changed) {
animateMagnificationSpec(spec); if (animate) {
} else { animateMagnificationSpecLocked(spec);
setMagnificationSpec(spec); } else {
setMagnificationSpecLocked(spec);
}
} }
} }
} }
private void animateMagnificationSpec(MagnificationSpec toSpec) { private void animateMagnificationSpecLocked(MagnificationSpec toSpec) {
mTransformationAnimator.setObjectValues(mSentMagnificationSpec, toSpec); mTransformationAnimator.setObjectValues(mSentMagnificationSpec, toSpec);
mTransformationAnimator.start(); mTransformationAnimator.start();
} }
private void setMagnificationSpec(MagnificationSpec spec) { private void setMagnificationSpecLocked(MagnificationSpec spec) {
if (DEBUG_SET_MAGNIFICATION_SPEC) { if (mEnabled) {
Slog.i(LOG_TAG, "Sending: " + spec); if (DEBUG_SET_MAGNIFICATION_SPEC) {
} Slog.i(LOG_TAG, "Sending: " + spec);
}
mSentMagnificationSpec.setTo(spec); mSentMagnificationSpec.setTo(spec);
mWindowManager.setMagnificationSpec(spec); mWindowManager.setMagnificationSpec(spec);
}
} }
private class UpdateHandler extends Handler { private class UpdateHandler extends Handler {
@@ -759,12 +840,16 @@ class MagnificationController {
@Override @Override
public MagnificationSpec get(SpecAnimationBridge object) { public MagnificationSpec get(SpecAnimationBridge object) {
return object.mSentMagnificationSpec; synchronized (object.mLock) {
return object.mSentMagnificationSpec;
}
} }
@Override @Override
public void set(SpecAnimationBridge object, MagnificationSpec value) { public void set(SpecAnimationBridge object, MagnificationSpec value) {
object.setMagnificationSpec(value); synchronized (object.mLock) {
object.setMagnificationSpecLocked(value);
}
} }
} }
@@ -862,15 +947,14 @@ class MagnificationController {
} }
@Override @Override
public void onMagnifiedBoundsChanged(Region magnified, Region available) { public void onMagnificationRegionChanged(Region magnificationRegion) {
final SomeArgs args = SomeArgs.obtain(); final SomeArgs args = SomeArgs.obtain();
args.arg1 = Region.obtain(magnified); args.arg1 = Region.obtain(magnificationRegion);
args.arg2 = Region.obtain(available);
mHandler.obtainMessage(MESSAGE_ON_MAGNIFIED_BOUNDS_CHANGED, args).sendToTarget(); mHandler.obtainMessage(MESSAGE_ON_MAGNIFIED_BOUNDS_CHANGED, args).sendToTarget();
} }
private void handleOnMagnifiedBoundsChanged(Region magnified, Region available) { private void handleOnMagnifiedBoundsChanged(Region magnificationRegion) {
mController.setMagnifiedRegion(magnified, available, mSpecIsDirty); mController.onMagnificationRegionChanged(magnificationRegion, mSpecIsDirty);
mSpecIsDirty = false; mSpecIsDirty = false;
} }
@@ -911,8 +995,15 @@ class MagnificationController {
mController.resetIfNeeded(true); mController.resetIfNeeded(true);
} }
public void getRegions(@NonNull Region outMagnified, @NonNull Region outAvailable) { /**
mWindowManager.getMagnificationRegions(outMagnified, outAvailable); * This method is used to get the magnification region in the tiny time slice between
* registering the callbacks and handling the message.
* TODO: Elimiante this extra path, perhaps by processing the message immediately
*
* @param outMagnificationRegion
*/
public void getMagnificationRegion(@NonNull Region outMagnificationRegion) {
mWindowManager.getMagnificationRegion(outMagnificationRegion);
} }
private class CallbackHandler extends Handler { private class CallbackHandler extends Handler {
@@ -926,10 +1017,8 @@ class MagnificationController {
case MESSAGE_ON_MAGNIFIED_BOUNDS_CHANGED: { case MESSAGE_ON_MAGNIFIED_BOUNDS_CHANGED: {
final SomeArgs args = (SomeArgs) message.obj; final SomeArgs args = (SomeArgs) message.obj;
final Region magnifiedBounds = (Region) args.arg1; final Region magnifiedBounds = (Region) args.arg1;
final Region availableBounds = (Region) args.arg2; handleOnMagnifiedBoundsChanged(magnifiedBounds);
handleOnMagnifiedBoundsChanged(magnifiedBounds, availableBounds);
magnifiedBounds.recycle(); magnifiedBounds.recycle();
availableBounds.recycle();
} break; } break;
case MESSAGE_ON_RECTANGLE_ON_SCREEN_REQUESTED: { case MESSAGE_ON_RECTANGLE_ON_SCREEN_REQUESTED: {
final SomeArgs args = (SomeArgs) message.obj; final SomeArgs args = (SomeArgs) message.obj;

View File

@@ -237,7 +237,7 @@ class MagnificationGestureHandler implements EventStreamTransformation {
final float eventX = event.getX(); final float eventX = event.getX();
final float eventY = event.getY(); final float eventY = event.getY();
if (mMagnificationController.isMagnifying() if (mMagnificationController.isMagnifying()
&& mMagnificationController.magnifiedRegionContains(eventX, eventY)) { && mMagnificationController.magnificationRegionContains(eventX, eventY)) {
final float scale = mMagnificationController.getScale(); final float scale = mMagnificationController.getScale();
final float scaledOffsetX = mMagnificationController.getOffsetX(); final float scaledOffsetX = mMagnificationController.getOffsetX();
final float scaledOffsetY = mMagnificationController.getOffsetY(); final float scaledOffsetY = mMagnificationController.getOffsetY();
@@ -381,7 +381,8 @@ class MagnificationGestureHandler implements EventStreamTransformation {
Slog.i(LOG_TAG, "Panned content by scrollX: " + distanceX Slog.i(LOG_TAG, "Panned content by scrollX: " + distanceX
+ " scrollY: " + distanceY); + " scrollY: " + distanceY);
} }
mMagnificationController.offsetMagnifiedRegionCenter(distanceX, distanceY); mMagnificationController.offsetMagnifiedRegionCenter(distanceX, distanceY,
AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
return true; return true;
} }
@@ -421,7 +422,8 @@ class MagnificationGestureHandler implements EventStreamTransformation {
final float pivotX = detector.getFocusX(); final float pivotX = detector.getFocusX();
final float pivotY = detector.getFocusY(); final float pivotY = detector.getFocusY();
mMagnificationController.setScale(scale, pivotX, pivotY, false); mMagnificationController.setScale(scale, pivotX, pivotY, false,
AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
return true; return true;
} }
@@ -469,14 +471,14 @@ class MagnificationGestureHandler implements EventStreamTransformation {
} }
final float eventX = event.getX(); final float eventX = event.getX();
final float eventY = event.getY(); final float eventY = event.getY();
if (mMagnificationController.magnifiedRegionContains(eventX, eventY)) { if (mMagnificationController.magnificationRegionContains(eventX, eventY)) {
if (mLastMoveOutsideMagnifiedRegion) { if (mLastMoveOutsideMagnifiedRegion) {
mLastMoveOutsideMagnifiedRegion = false; mLastMoveOutsideMagnifiedRegion = false;
mMagnificationController.setCenter(eventX, mMagnificationController.setCenter(eventX, eventY, true,
eventY, true); AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
} else { } else {
mMagnificationController.setCenter(eventX, mMagnificationController.setCenter(eventX, eventY, false,
eventY, false); AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
} }
} else { } else {
mLastMoveOutsideMagnifiedRegion = true; mLastMoveOutsideMagnifiedRegion = true;
@@ -571,7 +573,7 @@ class MagnificationGestureHandler implements EventStreamTransformation {
switch (action) { switch (action) {
case MotionEvent.ACTION_DOWN: { case MotionEvent.ACTION_DOWN: {
mHandler.removeMessages(MESSAGE_TRANSITION_TO_DELEGATING_STATE); mHandler.removeMessages(MESSAGE_TRANSITION_TO_DELEGATING_STATE);
if (!mMagnificationController.magnifiedRegionContains( if (!mMagnificationController.magnificationRegionContains(
event.getX(), event.getY())) { event.getX(), event.getY())) {
transitionToDelegatingStateAndClear(); transitionToDelegatingStateAndClear();
return; return;
@@ -616,7 +618,7 @@ class MagnificationGestureHandler implements EventStreamTransformation {
return; return;
} }
mHandler.removeMessages(MESSAGE_ON_ACTION_TAP_AND_HOLD); mHandler.removeMessages(MESSAGE_ON_ACTION_TAP_AND_HOLD);
if (!mMagnificationController.magnifiedRegionContains( if (!mMagnificationController.magnificationRegionContains(
event.getX(), event.getY())) { event.getX(), event.getY())) {
transitionToDelegatingStateAndClear(); transitionToDelegatingStateAndClear();
return; return;
@@ -726,7 +728,8 @@ class MagnificationGestureHandler implements EventStreamTransformation {
if (!mMagnificationController.isMagnifying()) { if (!mMagnificationController.isMagnifying()) {
final float targetScale = mMagnificationController.getPersistedScale(); final float targetScale = mMagnificationController.getPersistedScale();
final float scale = MathUtils.constrain(targetScale, MIN_SCALE, MAX_SCALE); final float scale = MathUtils.constrain(targetScale, MIN_SCALE, MAX_SCALE);
mMagnificationController.setScaleAndCenter(scale, up.getX(), up.getY(), true); mMagnificationController.setScaleAndCenter(scale, up.getX(), up.getY(), true,
AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
} else { } else {
mMagnificationController.reset(true); mMagnificationController.reset(true);
} }
@@ -742,7 +745,8 @@ class MagnificationGestureHandler implements EventStreamTransformation {
final float targetScale = mMagnificationController.getPersistedScale(); final float targetScale = mMagnificationController.getPersistedScale();
final float scale = MathUtils.constrain(targetScale, MIN_SCALE, MAX_SCALE); final float scale = MathUtils.constrain(targetScale, MIN_SCALE, MAX_SCALE);
mMagnificationController.setScaleAndCenter(scale, down.getX(), down.getY(), true); mMagnificationController.setScaleAndCenter(scale, down.getX(), down.getY(), true,
AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
transitionToState(STATE_VIEWPORT_DRAGGING); transitionToState(STATE_VIEWPORT_DRAGGING);
} }

View File

@@ -124,9 +124,9 @@ final class AccessibilityController {
} }
} }
public void getMagnificationRegionsLocked(Region outMagnified, Region outAvailable) { public void getMagnificationRegionLocked(Region outMagnificationRegion) {
if (mDisplayMagnifier != null) { if (mDisplayMagnifier != null) {
mDisplayMagnifier.getMagnificationRegionsLocked(outMagnified, outAvailable); mDisplayMagnifier.getMagnificationRegionLocked(outMagnificationRegion);
} }
} }
@@ -400,8 +400,8 @@ final class AccessibilityController {
return spec; return spec;
} }
public void getMagnificationRegionsLocked(Region outMagnified, Region outAvailable) { public void getMagnificationRegionLocked(Region outMagnificationRegion) {
mMagnifedViewport.getBoundsLocked(outMagnified, outAvailable); mMagnifedViewport.getMagnificationRegionLocked(outMagnificationRegion);
} }
public void destroyLocked() { public void destroyLocked() {
@@ -424,10 +424,8 @@ final class AccessibilityController {
private final Matrix mTempMatrix = new Matrix(); private final Matrix mTempMatrix = new Matrix();
private final Region mMagnifiedBounds = new Region(); private final Region mMagnificationRegion = new Region();
private final Region mAvailableBounds = new Region(); private final Region mOldMagnificationRegion = new Region();
private final Region mOldMagnifiedBounds = new Region();
private final Region mOldAvailableBounds = new Region();
private final Path mCircularPath; private final Path mCircularPath;
@@ -463,10 +461,8 @@ final class AccessibilityController {
recomputeBoundsLocked(); recomputeBoundsLocked();
} }
public void getBoundsLocked(@NonNull Region outMagnified, public void getMagnificationRegionLocked(@NonNull Region outMagnificationRegion) {
@NonNull Region outAvailable) { outMagnificationRegion.set(mMagnificationRegion);
outMagnified.set(mMagnifiedBounds);
outAvailable.set(mAvailableBounds);
} }
public void updateMagnificationSpecLocked(MagnificationSpec spec) { public void updateMagnificationSpecLocked(MagnificationSpec spec) {
@@ -488,11 +484,12 @@ final class AccessibilityController {
final int screenWidth = mTempPoint.x; final int screenWidth = mTempPoint.x;
final int screenHeight = mTempPoint.y; final int screenHeight = mTempPoint.y;
mMagnifiedBounds.set(0, 0, 0, 0); mMagnificationRegion.set(0, 0, 0, 0);
mAvailableBounds.set(0, 0, screenWidth, screenHeight); final Region availableBounds = mTempRegion1;
availableBounds.set(0, 0, screenWidth, screenHeight);
if (mCircularPath != null) { if (mCircularPath != null) {
mAvailableBounds.setPath(mCircularPath, mAvailableBounds); availableBounds.setPath(mCircularPath, availableBounds);
} }
Region nonMagnifiedBounds = mTempRegion4; Region nonMagnifiedBounds = mTempRegion4;
@@ -526,21 +523,21 @@ final class AccessibilityController {
(int) windowFrame.right, (int) windowFrame.bottom); (int) windowFrame.right, (int) windowFrame.bottom);
// Only update new regions // Only update new regions
Region portionOfWindowAlreadyAccountedFor = mTempRegion3; Region portionOfWindowAlreadyAccountedFor = mTempRegion3;
portionOfWindowAlreadyAccountedFor.set(mMagnifiedBounds); portionOfWindowAlreadyAccountedFor.set(mMagnificationRegion);
portionOfWindowAlreadyAccountedFor.op(nonMagnifiedBounds, Region.Op.UNION); portionOfWindowAlreadyAccountedFor.op(nonMagnifiedBounds, Region.Op.UNION);
windowBounds.op(portionOfWindowAlreadyAccountedFor, Region.Op.DIFFERENCE); windowBounds.op(portionOfWindowAlreadyAccountedFor, Region.Op.DIFFERENCE);
if (mWindowManagerService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) { if (mWindowManagerService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) {
mMagnifiedBounds.op(windowBounds, Region.Op.UNION); mMagnificationRegion.op(windowBounds, Region.Op.UNION);
mMagnifiedBounds.op(mAvailableBounds, Region.Op.INTERSECT); mMagnificationRegion.op(availableBounds, Region.Op.INTERSECT);
} else { } else {
nonMagnifiedBounds.op(windowBounds, Region.Op.UNION); nonMagnifiedBounds.op(windowBounds, Region.Op.UNION);
mAvailableBounds.op(windowBounds, Region.Op.DIFFERENCE); availableBounds.op(windowBounds, Region.Op.DIFFERENCE);
} }
// Update accounted bounds // Update accounted bounds
Region accountedBounds = mTempRegion2; Region accountedBounds = mTempRegion2;
accountedBounds.set(mMagnifiedBounds); accountedBounds.set(mMagnificationRegion);
accountedBounds.op(nonMagnifiedBounds, Region.Op.UNION); accountedBounds.op(nonMagnifiedBounds, Region.Op.UNION);
accountedBounds.op(0, 0, screenWidth, screenHeight, Region.Op.INTERSECT); accountedBounds.op(0, 0, screenWidth, screenHeight, Region.Op.INTERSECT);
@@ -556,43 +553,36 @@ final class AccessibilityController {
visibleWindows.clear(); visibleWindows.clear();
mMagnifiedBounds.op(mDrawBorderInset, mDrawBorderInset, mMagnificationRegion.op(mDrawBorderInset, mDrawBorderInset,
screenWidth - mDrawBorderInset, screenHeight - mDrawBorderInset, screenWidth - mDrawBorderInset, screenHeight - mDrawBorderInset,
Region.Op.INTERSECT); Region.Op.INTERSECT);
final boolean magnifiedChanged = !mOldMagnifiedBounds.equals(mMagnifiedBounds); final boolean magnifiedChanged =
final boolean availableChanged = !mOldAvailableBounds.equals(mAvailableBounds); !mOldMagnificationRegion.equals(mMagnificationRegion);
if (magnifiedChanged || availableChanged) { if (magnifiedChanged) {
if (magnifiedChanged) { mWindow.setBounds(mMagnificationRegion);
mWindow.setBounds(mMagnifiedBounds); final Rect dirtyRect = mTempRect1;
Rect dirtyRect = mTempRect1; if (mFullRedrawNeeded) {
if (mFullRedrawNeeded) { mFullRedrawNeeded = false;
mFullRedrawNeeded = false; dirtyRect.set(mDrawBorderInset, mDrawBorderInset,
dirtyRect.set(mDrawBorderInset, mDrawBorderInset, screenWidth - mDrawBorderInset,
screenWidth - mDrawBorderInset, screenHeight - mDrawBorderInset);
screenHeight - mDrawBorderInset); mWindow.invalidate(dirtyRect);
mWindow.invalidate(dirtyRect); } else {
} else { final Region dirtyRegion = mTempRegion3;
Region dirtyRegion = mTempRegion3; dirtyRegion.set(mMagnificationRegion);
dirtyRegion.set(mMagnifiedBounds); dirtyRegion.op(mOldMagnificationRegion, Region.Op.UNION);
dirtyRegion.op(mOldMagnifiedBounds, Region.Op.UNION); dirtyRegion.op(nonMagnifiedBounds, Region.Op.INTERSECT);
dirtyRegion.op(nonMagnifiedBounds, Region.Op.INTERSECT); dirtyRegion.getBounds(dirtyRect);
dirtyRegion.getBounds(dirtyRect); mWindow.invalidate(dirtyRect);
mWindow.invalidate(dirtyRect);
}
mOldMagnifiedBounds.set(mMagnifiedBounds);
}
if (availableChanged) {
mOldAvailableBounds.set(mAvailableBounds);
} }
mOldMagnificationRegion.set(mMagnificationRegion);
final SomeArgs args = SomeArgs.obtain(); final SomeArgs args = SomeArgs.obtain();
args.arg1 = Region.obtain(mMagnifiedBounds); args.arg1 = Region.obtain(mMagnificationRegion);
args.arg2 = Region.obtain(mAvailableBounds);
mHandler.obtainMessage( mHandler.obtainMessage(
MyHandler.MESSAGE_NOTIFY_MAGNIFIED_BOUNDS_CHANGED, args).sendToTarget(); MyHandler.MESSAGE_NOTIFY_MAGNIFICATION_REGION_CHANGED, args)
.sendToTarget();
} }
} }
@@ -616,14 +606,14 @@ final class AccessibilityController {
public void setMagnifiedRegionBorderShownLocked(boolean shown, boolean animate) { public void setMagnifiedRegionBorderShownLocked(boolean shown, boolean animate) {
if (shown) { if (shown) {
mFullRedrawNeeded = true; mFullRedrawNeeded = true;
mOldMagnifiedBounds.set(0, 0, 0, 0); mOldMagnificationRegion.set(0, 0, 0, 0);
} }
mWindow.setShown(shown, animate); mWindow.setShown(shown, animate);
} }
public void getMagnifiedFrameInContentCoordsLocked(Rect rect) { public void getMagnifiedFrameInContentCoordsLocked(Rect rect) {
MagnificationSpec spec = mMagnificationSpec; MagnificationSpec spec = mMagnificationSpec;
mMagnifiedBounds.getBounds(rect); mMagnificationRegion.getBounds(rect);
rect.offset((int) -spec.offsetX, (int) -spec.offsetY); rect.offset((int) -spec.offsetX, (int) -spec.offsetY);
rect.scale(1.0f / spec.scale); rect.scale(1.0f / spec.scale);
} }
@@ -886,7 +876,7 @@ final class AccessibilityController {
} }
private class MyHandler extends Handler { private class MyHandler extends Handler {
public static final int MESSAGE_NOTIFY_MAGNIFIED_BOUNDS_CHANGED = 1; public static final int MESSAGE_NOTIFY_MAGNIFICATION_REGION_CHANGED = 1;
public static final int MESSAGE_NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED = 2; public static final int MESSAGE_NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED = 2;
public static final int MESSAGE_NOTIFY_USER_CONTEXT_CHANGED = 3; public static final int MESSAGE_NOTIFY_USER_CONTEXT_CHANGED = 3;
public static final int MESSAGE_NOTIFY_ROTATION_CHANGED = 4; public static final int MESSAGE_NOTIFY_ROTATION_CHANGED = 4;
@@ -899,13 +889,11 @@ final class AccessibilityController {
@Override @Override
public void handleMessage(Message message) { public void handleMessage(Message message) {
switch (message.what) { switch (message.what) {
case MESSAGE_NOTIFY_MAGNIFIED_BOUNDS_CHANGED: { case MESSAGE_NOTIFY_MAGNIFICATION_REGION_CHANGED: {
final SomeArgs args = (SomeArgs) message.obj; final SomeArgs args = (SomeArgs) message.obj;
final Region magnifiedBounds = (Region) args.arg1; final Region magnifiedBounds = (Region) args.arg1;
final Region availableBounds = (Region) args.arg2; mCallbacks.onMagnificationRegionChanged(magnifiedBounds);
mCallbacks.onMagnifiedBoundsChanged(magnifiedBounds, availableBounds);
magnifiedBounds.recycle(); magnifiedBounds.recycle();
availableBounds.recycle();
} break; } break;
case MESSAGE_NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED: { case MESSAGE_NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED: {

View File

@@ -10975,12 +10975,10 @@ public class WindowManagerService extends IWindowManager.Stub
} }
@Override @Override
public void getMagnificationRegions(@NonNull Region outMagnified, public void getMagnificationRegion(@NonNull Region magnificationRegion) {
@NonNull Region outAvailable) {
synchronized (mWindowMap) { synchronized (mWindowMap) {
if (mAccessibilityController != null) { if (mAccessibilityController != null) {
mAccessibilityController.getMagnificationRegionsLocked( mAccessibilityController.getMagnificationRegionLocked(magnificationRegion);
outMagnified, outAvailable);
} else { } else {
throw new IllegalStateException("Magnification callbacks not set!"); throw new IllegalStateException("Magnification callbacks not set!");
} }