Fix several accessibility magnification issues.

Clarifying region used for magnification as "magnificationRegion",
both in the public API and in the code. There's been significant
confusion about what "magnfifiedRegion" means. Removing
"availableRegion" from everywhere except where it's required, as
that region was identical to magnified/magnification region.

Trying to shut down magnification was a complex situation where
animations in progress and new magnification requests were tricky to
handle correctly. It was not possible to guarantee that the
magnification callbacks were unregistered consistently. There were
at least two situations that led to phone restarts:
1. If a triple tap was detected between unregistering the callbacks
and shutting down the input filter. In this case the magnification
request would go through.
2. If an animation had just started when magnification was turned
off, so the current magnification was 1.0 but the animator was
about to change it. In this case the callbacks would be unregistered,
and then the animator would start changing the magnification.

This change makes registering and unregistering magnification atomic.
It also makes MagnificationController stick around indefinitely once it
is created, registering and unregistering as needed to support
magnification gestures and services that control magnification. Services
that merely query the status of magnification no longer register for
callbacks.

One part of shutting down is turning off the animation and guaranteeing
that it won't try to make further changes. Adding a flag to
SpecAnimationBridge and a lock in that class so we can guarantee that
nothing happens when we aren't registered for magnification callbacks.

Also reconfiguring all accessibility options when a service stops to
make sure that only the features required by the current configuration
are enabled.

Bug: 27497138
Bug: 27821103
Change-Id: If697cbd34b117d82c8eee1ba7d0254089ee4241d
diff --git a/api/current.txt b/api/current.txt
index 5df8750..ea9deb1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2699,7 +2699,7 @@
     method public void addListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener, android.os.Handler);
     method public float getCenterX();
     method public float getCenterY();
-    method public android.graphics.Region getMagnifiedRegion();
+    method public android.graphics.Region getMagnificationRegion();
     method public float getScale();
     method public boolean removeListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener);
     method public boolean reset(boolean);
diff --git a/api/system-current.txt b/api/system-current.txt
index acb699d..af95d33 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -2803,7 +2803,7 @@
     method public void addListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener, android.os.Handler);
     method public float getCenterX();
     method public float getCenterY();
-    method public android.graphics.Region getMagnifiedRegion();
+    method public android.graphics.Region getMagnificationRegion();
     method public float getScale();
     method public boolean removeListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener);
     method public boolean reset(boolean);
diff --git a/api/test-current.txt b/api/test-current.txt
index e4b11bd..f007d00 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2699,7 +2699,7 @@
     method public void addListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener, android.os.Handler);
     method public float getCenterX();
     method public float getCenterY();
-    method public android.graphics.Region getMagnifiedRegion();
+    method public android.graphics.Region getMagnificationRegion();
     method public float getScale();
     method public boolean removeListener(android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener);
     method public boolean reset(boolean);
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 56728ad..8b277b2 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -925,18 +925,25 @@
         }
 
         /**
-         * Returns the region of the screen currently being magnified. If
-         * magnification is not enabled, the returned region will be empty.
+         * Returns the region of the screen currently active for magnification. Changes to
+         * 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>
          * <strong>Note:</strong> If the service is not yet connected (e.g.
          * {@link AccessibilityService#onServiceConnected()} has not yet been
          * called) or the service has been disconnected, this method will
          * 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
-        public Region getMagnifiedRegion() {
+        public Region getMagnificationRegion() {
             final IAccessibilityServiceConnection connection =
                     AccessibilityInteractionClient.getInstance().getConnection(
                             mService.mConnectionId);
@@ -1049,11 +1056,12 @@
              * Called when the magnified region, scale, or center changes.
              *
              * @param controller the magnification controller
-             * @param region the new magnified region, may be empty if
-             *               magnification is not enabled (e.g. scale is 1)
+             * @param region the magnification region
              * @param scale the new scale
-             * @param centerX the new X coordinate around which magnification is focused
-             * @param centerY the new Y coordinate around which magnification is focused
+             * @param centerX the new X coordinate, in unscaled coordinates, around which
+             * magnification is focused
+             * @param centerY the new Y coordinate, in unscaled coordinates, around which
+             * magnification is focused
              */
             void onMagnificationChanged(@NonNull MagnificationController controller,
                     @NonNull Region region, float scale, float centerX, float centerY);
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
index 3ad730b..4b188c4 100644
--- a/core/java/android/view/WindowManagerInternal.java
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -54,13 +54,12 @@
     public interface MagnificationCallbacks {
 
         /**
-         * Called when the bounds of the screen content that is magnified changed.
-         * Note that not the entire screen is magnified.
+         * Called when the region where magnification operates changes. Note that this isn't the
+         * entire screen. For example, IMEs are not magnified.
          *
-         * @param magnifiedBounds the currently magnified region
-         * @param availableBounds the region available for magnification
+         * @param magnificationRegion the current magnification region
          */
-        public void onMagnifiedBoundsChanged(Region magnifiedBounds, Region availableBounds);
+        public void onMagnificationRegionChanged(Region magnificationRegion);
 
         /**
          * Called when an application requests a rectangle on the screen to allow
@@ -158,13 +157,11 @@
     public abstract void setMagnificationSpec(MagnificationSpec spec);
 
     /**
-     * Obtains the magnified and available regions.
+     * Obtains the magnification regions.
      *
-     * @param outMagnified the currently magnified region
-     * @param outAvailable the region available for magnification
+     * @param magnificationRegion the current magnification region
      */
-    public abstract void getMagnificationRegions(@NonNull Region outMagnified,
-            @NonNull Region outAvailable);
+    public abstract void getMagnificationRegion(@NonNull Region magnificationRegion);
 
     /**
      * Gets the magnification and translation applied to a window given its token.
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index d900b37..0311082 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -153,7 +153,10 @@
 
     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;
 
@@ -185,8 +188,6 @@
 
     private MagnificationController mMagnificationController;
 
-    private boolean mUnregisterMagnificationOnReset;
-
     private InteractionBridge mInteractionBridge;
 
     private AlertDialog mEnableTouchExplorationDialog;
@@ -786,11 +787,6 @@
             float scale, float centerX, float centerY) {
         synchronized (mLock) {
             notifyMagnificationChangedLocked(region, scale, centerX, centerY);
-
-            if (mUnregisterMagnificationOnReset && scale == 1.0f) {
-                mUnregisterMagnificationOnReset = false;
-                mMagnificationController.unregister();
-            }
         }
     }
 
@@ -1738,25 +1734,17 @@
     }
 
     private void updateMagnificationLocked(UserState userState) {
-        final int userId = userState.mUserId;
-        if (userId == mCurrentUserId && mMagnificationController != null) {
-            if (userState.mIsDisplayMagnificationEnabled ||
-                    userHasMagnificationServicesLocked(userState)) {
-                mMagnificationController.setUserId(userState.mUserId);
-            } else {
-                // If the user no longer has any magnification-controlling
-                // services and is not using magnification gestures, then
-                // reset the state to normal.
-                if (mMagnificationController.resetIfNeeded(true)) {
-                    // Animations are still running, so wait until we receive a
-                    // callback verifying that we've reset magnification.
-                    mUnregisterMagnificationOnReset = true;
-                } else {
-                    mUnregisterMagnificationOnReset = false;
-                    mMagnificationController.unregister();
-                    mMagnificationController = null;
-                }
-            }
+        if (userState.mUserId != mCurrentUserId) {
+            return;
+        }
+
+        if (userState.mIsDisplayMagnificationEnabled ||
+                userHasMagnificationServicesLocked(userState)) {
+            // Initialize the magnification controller if necessary
+            getMagnificationController();
+            mMagnificationController.register();
+        } else if (mMagnificationController != null) {
+            mMagnificationController.unregister();
         }
     }
 
@@ -2154,7 +2142,6 @@
         synchronized (mLock) {
             if (mMagnificationController == null) {
                 mMagnificationController = new MagnificationController(mContext, this, mLock);
-                mMagnificationController.register();
                 mMagnificationController.setUserId(mCurrentUserId);
             }
             return mMagnificationController;
@@ -2883,7 +2870,7 @@
             final long identity = Binder.clearCallingIdentity();
             try {
                 final Region region = Region.obtain();
-                getMagnificationController().getMagnifiedRegion(region);
+                getMagnificationController().getMagnificationRegion(region);
                 return region;
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -2954,7 +2941,7 @@
             final long identity = Binder.clearCallingIdentity();
             try {
                 return getMagnificationController().setScaleAndCenter(
-                        scale, centerX, centerY, animate);
+                        scale, centerX, centerY, animate, mId);
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -3087,10 +3074,11 @@
                     userState.mInstalledServices.remove(mAccessibilityServiceInfo);
                     userState.mEnabledServices.remove(mComponentName);
                     userState.destroyUiAutomationService();
-                    if (readConfigurationForUserStateLocked(userState)) {
-                        onUserStateChangedLocked(userState);
-                    }
                 }
+                if (mId == getMagnificationController().getIdOfLastServiceToMagnify()) {
+                    getMagnificationController().resetIfNeeded(true);
+                }
+                onUserStateChangedLocked(userState);
             }
         }
 
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
index f1b3722..027b6e2 100644
--- a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
@@ -17,6 +17,7 @@
 package com.android.server.accessibility;
 
 import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.SomeArgs;
 import com.android.server.LocalServices;
 
@@ -60,6 +61,8 @@
 
     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 MIN_SCALE = 1.0f;
@@ -80,9 +83,8 @@
      */
     private final MagnificationSpec mCurrentMagnificationSpec = MagnificationSpec.obtain();
 
-    private final Region mMagnifiedRegion = Region.obtain();
-    private final Region mAvailableRegion = Region.obtain();
-    private final Rect mMagnifiedBounds = new Rect();
+    private final Region mMagnificationRegion = Region.obtain();
+    private final Rect mMagnificationBounds = new Rect();
 
     private final Rect mTempRect = new Rect();
     private final Rect mTempRect1 = new Rect();
@@ -97,35 +99,67 @@
 
     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) {
         mAms = ams;
         mContentResolver = context.getContentResolver();
         mScreenStateObserver = new ScreenStateObserver(context, this);
         mWindowStateObserver = new WindowStateObserver(context, this);
-        mSpecAnimationBridge = new SpecAnimationBridge(context);
         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() {
-        mScreenStateObserver.register();
-        mWindowStateObserver.register();
-
-        // Obtain initial state.
-        mWindowStateObserver.getRegions(mMagnifiedRegion, mAvailableRegion);
-        mMagnifiedRegion.getBounds(mMagnifiedBounds);
+        synchronized (mLock) {
+            if (!mRegistered) {
+                mScreenStateObserver.register();
+                mWindowStateObserver.register();
+                mSpecAnimationBridge.setEnabled(true);
+                // 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() {
-        mSpecAnimationBridge.cancel();
+        synchronized (mLock) {
+            if (!isMagnifying()) {
+                unregisterInternalLocked();
+            } else {
+                mUnregisterPending = true;
+                resetLocked(true);
+            }
+        }
+    }
 
-        mScreenStateObserver.unregister();
-        mWindowStateObserver.unregister();
+    private void unregisterInternalLocked() {
+        if (mRegistered) {
+            mSpecAnimationBridge.setEnabled(false);
+            mScreenStateObserver.unregister();
+            mWindowStateObserver.unregister();
+            mMagnificationRegion.setEmpty();
+            mRegistered = false;
+        }
+        mUnregisterPending = false;
     }
 
     /**
@@ -137,24 +171,22 @@
     }
 
     /**
-     * Sets the magnified and available regions.
+     * Update our copy of the current magnification 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
      *                   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) {
             boolean magnificationChanged = false;
             boolean boundsChanged = false;
 
-            if (!mMagnifiedRegion.equals(magnified)) {
-                mMagnifiedRegion.set(magnified);
-                mMagnifiedRegion.getBounds(mMagnifiedBounds);
+            if (!mMagnificationRegion.equals(magnified)) {
+                mMagnificationRegion.set(magnified);
+                mMagnificationRegion.getBounds(mMagnificationBounds);
                 boundsChanged = true;
             }
-            mAvailableRegion.set(available);
             if (updateSpec) {
                 final MagnificationSpec sentSpec = mSpecAnimationBridge.mSentMagnificationSpec;
                 final float scale = sentSpec.scale;
@@ -162,12 +194,12 @@
                 final float offsetY = sentSpec.offsetY;
 
                 // Compute the new center and update spec as needed.
-                final float centerX = (mMagnifiedBounds.width() / 2.0f
-                        + mMagnifiedBounds.left - offsetX) / scale;
-                final float centerY = (mMagnifiedBounds.height() / 2.0f
-                        + mMagnifiedBounds.top - offsetY) / scale;
+                final float centerX = (mMagnificationBounds.width() / 2.0f
+                        + mMagnificationBounds.left - offsetX) / scale;
+                final float centerY = (mMagnificationBounds.height() / 2.0f
+                        + mMagnificationBounds.top - offsetY) / scale;
                 magnificationChanged = setScaleAndCenterLocked(
-                        scale, centerX, centerY, false);
+                        scale, centerX, centerY, false, INVALID_ID);
             }
 
             // If magnification changed we already notified for the change.
@@ -178,7 +210,7 @@
     }
 
     /**
-     * Returns whether the magnified region contains the specified
+     * Returns whether the magnification region contains the specified
      * screen-relative coordinates.
      *
      * @param x the screen-relative X coordinate to check
@@ -186,51 +218,36 @@
      * @return {@code true} if the coordinate is contained within the
      *         magnified region, or {@code false} otherwise
      */
-    public boolean magnifiedRegionContains(float x, float y) {
+    public boolean magnificationRegionContains(float x, float y) {
         synchronized (mLock) {
-            return mMagnifiedRegion.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);
+            return mMagnificationRegion.contains((int) x, (int) y);
         }
     }
 
     /**
      * 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.
      *
      * @param outBounds rect to populate with the bounds of the magnified
      *                  region
      */
-    public void getMagnifiedBounds(@NonNull Rect outBounds) {
+    public void getMagnificationBounds(@NonNull Rect outBounds) {
         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
      * will be empty.
      *
      * @param outRegion the region to populate
      */
-    public void getMagnifiedRegion(@NonNull Region outRegion) {
+    public void getMagnificationRegion(@NonNull Region outRegion) {
         synchronized (mLock) {
-            outRegion.set(mMagnifiedRegion);
+            outRegion.set(mMagnificationRegion);
         }
     }
 
@@ -263,8 +280,8 @@
      */
     public float getCenterX() {
         synchronized (mLock) {
-            return  (mMagnifiedBounds.width() / 2.0f
-                    + mMagnifiedBounds.left - getOffsetX()) / getScale();
+            return (mMagnificationBounds.width() / 2.0f
+                    + mMagnificationBounds.left - getOffsetX()) / getScale();
         }
     }
 
@@ -286,8 +303,8 @@
      */
     public float getCenterY() {
         synchronized (mLock) {
-            return (mMagnifiedBounds.height() / 2.0f
-                    + mMagnifiedBounds.top - getOffsetY()) / getScale();
+            return (mMagnificationBounds.height() / 2.0f
+                    + mMagnificationBounds.top - getOffsetY()) / getScale();
         }
     }
 
@@ -335,17 +352,25 @@
      */
     public boolean reset(boolean animate) {
         synchronized (mLock) {
-            final MagnificationSpec spec = mCurrentMagnificationSpec;
-            final boolean changed = !spec.isNop();
-            if (changed) {
-                spec.clear();
-                onMagnificationChangedLocked();
-            }
-            mSpecAnimationBridge.updateSentSpec(spec, animate);
-            return changed;
+            return resetLocked(animate);
         }
     }
 
+    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,
      * optionally animating the transition. If animation is disabled, the
@@ -356,16 +381,20 @@
      * @param pivotY the screen-relative Y coordinate around which to scale
      * @param animate {@code true} to animate the transition, {@code false}
      *                to transition immediately
+     * @param id the ID of the service requesting the change
      * @return {@code true} if the magnification spec changed, {@code false} if
      *         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) {
+            if (!mRegistered) {
+                return false;
+            }
             // Constrain scale immediately for use in the pivot calculations.
             scale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
 
             final Rect viewport = mTempRect;
-            mMagnifiedRegion.getBounds(viewport);
+            mMagnificationRegion.getBounds(viewport);
             final MagnificationSpec spec = mCurrentMagnificationSpec;
             final float oldScale = spec.scale;
             final float oldCenterX = (viewport.width() / 2.0f - spec.offsetX) / oldScale;
@@ -376,7 +405,8 @@
             final float offsetY = (oldCenterY - normPivotY) * (oldScale / scale);
             final float centerX = normPivotX + offsetX;
             final float centerY = normPivotY + offsetY;
-            return setScaleAndCenterLocked(scale, centerX, centerY, animate);
+            mIdOfLastServiceToMagnify = id;
+            return setScaleAndCenterLocked(scale, centerX, centerY, animate, id);
         }
     }
 
@@ -390,12 +420,16 @@
      *                center
      * @param animate {@code true} to animate the transition, {@code false}
      *                to transition immediately
+     * @param id the ID of the service requesting the change
      * @return {@code true} if the magnification spec changed, {@code false} if
      *         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) {
-            return setScaleAndCenterLocked(Float.NaN, centerX, centerY, animate);
+            if (!mRegistered) {
+                return false;
+            }
+            return setScaleAndCenterLocked(Float.NaN, centerX, centerY, animate, id);
         }
     }
 
@@ -411,19 +445,27 @@
      *                center and scale, or {@link Float#NaN} to leave unchanged
      * @param animate {@code true} to animate the transition, {@code false}
      *                to transition immediately
+     * @param id the ID of the service requesting the change
      * @return {@code true} if the magnification spec changed, {@code false} if
      *         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) {
-            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,
-            boolean animate) {
+            boolean animate, int id) {
         final boolean changed = updateMagnificationSpecLocked(scale, centerX, centerY);
         mSpecAnimationBridge.updateSentSpec(mCurrentMagnificationSpec, animate);
+        if (isMagnifying() && (id != INVALID_ID)) {
+            mIdOfLastServiceToMagnify = id;
+        }
         return changed;
     }
 
@@ -432,22 +474,42 @@
      *
      * @param offsetX the amount in pixels to offset the X 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) {
+            if (!mRegistered) {
+                return;
+            }
+
             final MagnificationSpec currSpec = mCurrentMagnificationSpec;
             final float nonNormOffsetX = currSpec.offsetX - offsetX;
             currSpec.offsetX = MathUtils.constrain(nonNormOffsetX, getMinOffsetXLocked(), 0);
             final float nonNormOffsetY = currSpec.offsetY - offsetY;
             currSpec.offsetY = MathUtils.constrain(nonNormOffsetY, getMinOffsetYLocked(), 0);
+            if (id != INVALID_ID) {
+                mIdOfLastServiceToMagnify = id;
+            }
             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() {
         mAms.onMagnificationStateChanged();
-        mAms.notifyMagnificationChanged(mMagnifiedRegion,
+        mAms.notifyMagnificationChanged(mMagnificationRegion,
                 getScale(), getCenterX(), getCenterY());
+        if (mUnregisterPending && !isMagnifying()) {
+            unregisterInternalLocked();
+        }
     }
 
     /**
@@ -503,8 +565,8 @@
             scale = getScale();
         }
 
-        // Ensure requested center is within the available region.
-        if (!availableRegionContains(centerX, centerY)) {
+        // Ensure requested center is within the magnification region.
+        if (!magnificationRegionContains(centerX, centerY)) {
             return false;
         }
 
@@ -518,16 +580,16 @@
             changed = true;
         }
 
-        final float nonNormOffsetX = mMagnifiedBounds.width() / 2.0f
-                + mMagnifiedBounds.left - centerX * scale;
+        final float nonNormOffsetX = mMagnificationBounds.width() / 2.0f
+                + mMagnificationBounds.left - centerX * scale;
         final float offsetX = MathUtils.constrain(nonNormOffsetX, getMinOffsetXLocked(), 0);
         if (Float.compare(currSpec.offsetX, offsetX) != 0) {
             currSpec.offsetX = offsetX;
             changed = true;
         }
 
-        final float nonNormOffsetY = mMagnifiedBounds.height() / 2.0f
-                + mMagnifiedBounds.top - centerY * scale;
+        final float nonNormOffsetY = mMagnificationBounds.height() / 2.0f
+                + mMagnificationBounds.top - centerY * scale;
         final float offsetY = MathUtils.constrain(nonNormOffsetY, getMinOffsetYLocked(), 0);
         if (Float.compare(currSpec.offsetY, offsetY) != 0) {
             currSpec.offsetY = offsetY;
@@ -542,12 +604,12 @@
     }
 
     private float getMinOffsetXLocked() {
-        final float viewportWidth = mMagnifiedBounds.width();
+        final float viewportWidth = mMagnificationBounds.width();
         return viewportWidth - viewportWidth * mCurrentMagnificationSpec.scale;
     }
 
     private float getMinOffsetYLocked() {
-        final float viewportHeight = mMagnifiedBounds.height();
+        final float viewportHeight = mMagnificationBounds.height();
         return viewportHeight - viewportHeight * mCurrentMagnificationSpec.scale;
     }
 
@@ -595,7 +657,7 @@
         final float scale = getSentScale();
         final float offsetX = getSentOffsetX();
         final float offsetY = getSentOffsetY();
-        getMagnifiedBounds(outFrame);
+        getMagnificationBounds(outFrame);
         outFrame.offset((int) -offsetX, (int) -offsetY);
         outFrame.scale(1.0f / scale);
     }
@@ -603,7 +665,7 @@
     private void requestRectangleOnScreen(int left, int top, int right, int bottom) {
         synchronized (mLock) {
             final Rect magnifiedFrame = mTempRect;
-            getMagnifiedBounds(magnifiedFrame);
+            getMagnificationBounds(magnifiedFrame);
             if (!magnifiedFrame.intersects(left, top, right, bottom)) {
                 return;
             }
@@ -640,7 +702,7 @@
             }
 
             final float scale = getScale();
-            offsetMagnifiedRegionCenter(scrollX * scale, scrollY * scale);
+            offsetMagnifiedRegionCenter(scrollX * scale, scrollY * scale, INVALID_ID);
         }
     }
 
@@ -656,7 +718,7 @@
 
         /**
          * 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();
 
@@ -667,8 +729,13 @@
         private final ValueAnimator mTransformationAnimator;
 
         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();
             mMainThreadId = mainLooper.getThread().getId();
 
@@ -685,9 +752,19 @@
             mTransformationAnimator.setInterpolator(new DecelerateInterpolator(2.5f));
         }
 
-        public void cancel() {
-            if (mTransformationAnimator != null && mTransformationAnimator.isRunning()) {
-                mTransformationAnimator.cancel();
+        /**
+         * Enabled means the bridge will accept input. When not enabled, the output of the animator
+         * 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 @@
             }
 
             // If the current and sent specs don't match, update the sent spec.
-            final boolean changed = !mSentMagnificationSpec.equals(spec);
-            if (changed) {
-                if (animate) {
-                    animateMagnificationSpec(spec);
-                } else {
-                    setMagnificationSpec(spec);
+            synchronized (mLock) {
+                final boolean changed = !mSentMagnificationSpec.equals(spec);
+                if (changed) {
+                    if (animate) {
+                        animateMagnificationSpecLocked(spec);
+                    } else {
+                        setMagnificationSpecLocked(spec);
+                    }
                 }
             }
         }
 
-        private void animateMagnificationSpec(MagnificationSpec toSpec) {
+        private void animateMagnificationSpecLocked(MagnificationSpec toSpec) {
             mTransformationAnimator.setObjectValues(mSentMagnificationSpec, toSpec);
             mTransformationAnimator.start();
         }
 
-        private void setMagnificationSpec(MagnificationSpec spec) {
-            if (DEBUG_SET_MAGNIFICATION_SPEC) {
-                Slog.i(LOG_TAG, "Sending: " + spec);
-            }
+        private void setMagnificationSpecLocked(MagnificationSpec spec) {
+            if (mEnabled) {
+                if (DEBUG_SET_MAGNIFICATION_SPEC) {
+                    Slog.i(LOG_TAG, "Sending: " + spec);
+                }
 
-            mSentMagnificationSpec.setTo(spec);
-            mWindowManager.setMagnificationSpec(spec);
+                mSentMagnificationSpec.setTo(spec);
+                mWindowManager.setMagnificationSpec(spec);
+            }
         }
 
         private class UpdateHandler extends Handler {
@@ -759,12 +840,16 @@
 
             @Override
             public MagnificationSpec get(SpecAnimationBridge object) {
-                return object.mSentMagnificationSpec;
+                synchronized (object.mLock) {
+                    return object.mSentMagnificationSpec;
+                }
             }
 
             @Override
             public void set(SpecAnimationBridge object, MagnificationSpec value) {
-                object.setMagnificationSpec(value);
+                synchronized (object.mLock) {
+                    object.setMagnificationSpecLocked(value);
+                }
             }
         }
 
@@ -862,15 +947,14 @@
         }
 
         @Override
-        public void onMagnifiedBoundsChanged(Region magnified, Region available) {
+        public void onMagnificationRegionChanged(Region magnificationRegion) {
             final SomeArgs args = SomeArgs.obtain();
-            args.arg1 = Region.obtain(magnified);
-            args.arg2 = Region.obtain(available);
+            args.arg1 = Region.obtain(magnificationRegion);
             mHandler.obtainMessage(MESSAGE_ON_MAGNIFIED_BOUNDS_CHANGED, args).sendToTarget();
         }
 
-        private void handleOnMagnifiedBoundsChanged(Region magnified, Region available) {
-            mController.setMagnifiedRegion(magnified, available, mSpecIsDirty);
+        private void handleOnMagnifiedBoundsChanged(Region magnificationRegion) {
+            mController.onMagnificationRegionChanged(magnificationRegion, mSpecIsDirty);
             mSpecIsDirty = false;
         }
 
@@ -911,8 +995,15 @@
             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 {
@@ -926,10 +1017,8 @@
                     case MESSAGE_ON_MAGNIFIED_BOUNDS_CHANGED: {
                         final SomeArgs args = (SomeArgs) message.obj;
                         final Region magnifiedBounds = (Region) args.arg1;
-                        final Region availableBounds = (Region) args.arg2;
-                        handleOnMagnifiedBoundsChanged(magnifiedBounds, availableBounds);
+                        handleOnMagnifiedBoundsChanged(magnifiedBounds);
                         magnifiedBounds.recycle();
-                        availableBounds.recycle();
                     } break;
                     case MESSAGE_ON_RECTANGLE_ON_SCREEN_REQUESTED: {
                         final SomeArgs args = (SomeArgs) message.obj;
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java
index 818ac81..39bc809 100644
--- a/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java
@@ -237,7 +237,7 @@
         final float eventX = event.getX();
         final float eventY = event.getY();
         if (mMagnificationController.isMagnifying()
-                && mMagnificationController.magnifiedRegionContains(eventX, eventY)) {
+                && mMagnificationController.magnificationRegionContains(eventX, eventY)) {
             final float scale = mMagnificationController.getScale();
             final float scaledOffsetX = mMagnificationController.getOffsetX();
             final float scaledOffsetY = mMagnificationController.getOffsetY();
@@ -381,7 +381,8 @@
                 Slog.i(LOG_TAG, "Panned content by scrollX: " + distanceX
                         + " scrollY: " + distanceY);
             }
-            mMagnificationController.offsetMagnifiedRegionCenter(distanceX, distanceY);
+            mMagnificationController.offsetMagnifiedRegionCenter(distanceX, distanceY,
+                    AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
             return true;
         }
 
@@ -421,7 +422,8 @@
 
             final float pivotX = detector.getFocusX();
             final float pivotY = detector.getFocusY();
-            mMagnificationController.setScale(scale, pivotX, pivotY, false);
+            mMagnificationController.setScale(scale, pivotX, pivotY, false,
+                    AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
             return true;
         }
 
@@ -469,14 +471,14 @@
                     }
                     final float eventX = event.getX();
                     final float eventY = event.getY();
-                    if (mMagnificationController.magnifiedRegionContains(eventX, eventY)) {
+                    if (mMagnificationController.magnificationRegionContains(eventX, eventY)) {
                         if (mLastMoveOutsideMagnifiedRegion) {
                             mLastMoveOutsideMagnifiedRegion = false;
-                            mMagnificationController.setCenter(eventX,
-                                    eventY, true);
+                            mMagnificationController.setCenter(eventX, eventY, true,
+                                    AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
                         } else {
-                            mMagnificationController.setCenter(eventX,
-                                    eventY, false);
+                            mMagnificationController.setCenter(eventX, eventY, false,
+                                    AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
                         }
                     } else {
                         mLastMoveOutsideMagnifiedRegion = true;
@@ -571,7 +573,7 @@
             switch (action) {
                 case MotionEvent.ACTION_DOWN: {
                     mHandler.removeMessages(MESSAGE_TRANSITION_TO_DELEGATING_STATE);
-                    if (!mMagnificationController.magnifiedRegionContains(
+                    if (!mMagnificationController.magnificationRegionContains(
                             event.getX(), event.getY())) {
                         transitionToDelegatingStateAndClear();
                         return;
@@ -616,7 +618,7 @@
                         return;
                     }
                     mHandler.removeMessages(MESSAGE_ON_ACTION_TAP_AND_HOLD);
-                    if (!mMagnificationController.magnifiedRegionContains(
+                    if (!mMagnificationController.magnificationRegionContains(
                             event.getX(), event.getY())) {
                         transitionToDelegatingStateAndClear();
                         return;
@@ -726,7 +728,8 @@
             if (!mMagnificationController.isMagnifying()) {
                 final float targetScale = mMagnificationController.getPersistedScale();
                 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 {
                 mMagnificationController.reset(true);
             }
@@ -742,7 +745,8 @@
 
             final float targetScale = mMagnificationController.getPersistedScale();
             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);
         }
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 3ef077b..101f56f 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -124,9 +124,9 @@
         }
     }
 
-    public void getMagnificationRegionsLocked(Region outMagnified, Region outAvailable) {
+    public void getMagnificationRegionLocked(Region outMagnificationRegion) {
         if (mDisplayMagnifier != null) {
-            mDisplayMagnifier.getMagnificationRegionsLocked(outMagnified, outAvailable);
+            mDisplayMagnifier.getMagnificationRegionLocked(outMagnificationRegion);
         }
     }
 
@@ -400,8 +400,8 @@
             return spec;
         }
 
-        public void getMagnificationRegionsLocked(Region outMagnified, Region outAvailable) {
-            mMagnifedViewport.getBoundsLocked(outMagnified, outAvailable);
+        public void getMagnificationRegionLocked(Region outMagnificationRegion) {
+            mMagnifedViewport.getMagnificationRegionLocked(outMagnificationRegion);
         }
 
         public void destroyLocked() {
@@ -424,10 +424,8 @@
 
             private final Matrix mTempMatrix = new Matrix();
 
-            private final Region mMagnifiedBounds = new Region();
-            private final Region mAvailableBounds = new Region();
-            private final Region mOldMagnifiedBounds = new Region();
-            private final Region mOldAvailableBounds = new Region();
+            private final Region mMagnificationRegion = new Region();
+            private final Region mOldMagnificationRegion = new Region();
 
             private final Path mCircularPath;
 
@@ -463,10 +461,8 @@
                 recomputeBoundsLocked();
             }
 
-            public void getBoundsLocked(@NonNull Region outMagnified,
-                    @NonNull Region outAvailable) {
-                outMagnified.set(mMagnifiedBounds);
-                outAvailable.set(mAvailableBounds);
+            public void getMagnificationRegionLocked(@NonNull Region outMagnificationRegion) {
+                outMagnificationRegion.set(mMagnificationRegion);
             }
 
             public void updateMagnificationSpecLocked(MagnificationSpec spec) {
@@ -488,11 +484,12 @@
                 final int screenWidth = mTempPoint.x;
                 final int screenHeight = mTempPoint.y;
 
-                mMagnifiedBounds.set(0, 0, 0, 0);
-                mAvailableBounds.set(0, 0, screenWidth, screenHeight);
+                mMagnificationRegion.set(0, 0, 0, 0);
+                final Region availableBounds = mTempRegion1;
+                availableBounds.set(0, 0, screenWidth, screenHeight);
 
                 if (mCircularPath != null) {
-                    mAvailableBounds.setPath(mCircularPath, mAvailableBounds);
+                    availableBounds.setPath(mCircularPath, availableBounds);
                 }
 
                 Region nonMagnifiedBounds = mTempRegion4;
@@ -526,21 +523,21 @@
                             (int) windowFrame.right, (int) windowFrame.bottom);
                     // Only update new regions
                     Region portionOfWindowAlreadyAccountedFor = mTempRegion3;
-                    portionOfWindowAlreadyAccountedFor.set(mMagnifiedBounds);
+                    portionOfWindowAlreadyAccountedFor.set(mMagnificationRegion);
                     portionOfWindowAlreadyAccountedFor.op(nonMagnifiedBounds, Region.Op.UNION);
                     windowBounds.op(portionOfWindowAlreadyAccountedFor, Region.Op.DIFFERENCE);
 
                     if (mWindowManagerService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) {
-                        mMagnifiedBounds.op(windowBounds, Region.Op.UNION);
-                        mMagnifiedBounds.op(mAvailableBounds, Region.Op.INTERSECT);
+                        mMagnificationRegion.op(windowBounds, Region.Op.UNION);
+                        mMagnificationRegion.op(availableBounds, Region.Op.INTERSECT);
                     } else {
                         nonMagnifiedBounds.op(windowBounds, Region.Op.UNION);
-                        mAvailableBounds.op(windowBounds, Region.Op.DIFFERENCE);
+                        availableBounds.op(windowBounds, Region.Op.DIFFERENCE);
                     }
 
                     // Update accounted bounds
                     Region accountedBounds = mTempRegion2;
-                    accountedBounds.set(mMagnifiedBounds);
+                    accountedBounds.set(mMagnificationRegion);
                     accountedBounds.op(nonMagnifiedBounds, Region.Op.UNION);
                     accountedBounds.op(0, 0, screenWidth, screenHeight, Region.Op.INTERSECT);
 
@@ -556,43 +553,36 @@
 
                 visibleWindows.clear();
 
-                mMagnifiedBounds.op(mDrawBorderInset, mDrawBorderInset,
+                mMagnificationRegion.op(mDrawBorderInset, mDrawBorderInset,
                         screenWidth - mDrawBorderInset, screenHeight - mDrawBorderInset,
                         Region.Op.INTERSECT);
 
-                final boolean magnifiedChanged = !mOldMagnifiedBounds.equals(mMagnifiedBounds);
-                final boolean availableChanged = !mOldAvailableBounds.equals(mAvailableBounds);
-                if (magnifiedChanged || availableChanged) {
-                    if (magnifiedChanged) {
-                        mWindow.setBounds(mMagnifiedBounds);
-                        Rect dirtyRect = mTempRect1;
-                        if (mFullRedrawNeeded) {
-                            mFullRedrawNeeded = false;
-                            dirtyRect.set(mDrawBorderInset, mDrawBorderInset,
-                                    screenWidth - mDrawBorderInset,
-                                    screenHeight - mDrawBorderInset);
-                            mWindow.invalidate(dirtyRect);
-                        } else {
-                            Region dirtyRegion = mTempRegion3;
-                            dirtyRegion.set(mMagnifiedBounds);
-                            dirtyRegion.op(mOldMagnifiedBounds, Region.Op.UNION);
-                            dirtyRegion.op(nonMagnifiedBounds, Region.Op.INTERSECT);
-                            dirtyRegion.getBounds(dirtyRect);
-                            mWindow.invalidate(dirtyRect);
-                        }
-
-                        mOldMagnifiedBounds.set(mMagnifiedBounds);
+                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.UNION);
+                        dirtyRegion.op(nonMagnifiedBounds, Region.Op.INTERSECT);
+                        dirtyRegion.getBounds(dirtyRect);
+                        mWindow.invalidate(dirtyRect);
                     }
 
-                    if (availableChanged) {
-                        mOldAvailableBounds.set(mAvailableBounds);
-                    }
-
+                    mOldMagnificationRegion.set(mMagnificationRegion);
                     final SomeArgs args = SomeArgs.obtain();
-                    args.arg1 = Region.obtain(mMagnifiedBounds);
-                    args.arg2 = Region.obtain(mAvailableBounds);
+                    args.arg1 = Region.obtain(mMagnificationRegion);
                     mHandler.obtainMessage(
-                            MyHandler.MESSAGE_NOTIFY_MAGNIFIED_BOUNDS_CHANGED, args).sendToTarget();
+                            MyHandler.MESSAGE_NOTIFY_MAGNIFICATION_REGION_CHANGED, args)
+                            .sendToTarget();
                 }
             }
 
@@ -616,14 +606,14 @@
             public void setMagnifiedRegionBorderShownLocked(boolean shown, boolean animate) {
                 if (shown) {
                     mFullRedrawNeeded = true;
-                    mOldMagnifiedBounds.set(0, 0, 0, 0);
+                    mOldMagnificationRegion.set(0, 0, 0, 0);
                 }
                 mWindow.setShown(shown, animate);
             }
 
             public void getMagnifiedFrameInContentCoordsLocked(Rect rect) {
                 MagnificationSpec spec = mMagnificationSpec;
-                mMagnifiedBounds.getBounds(rect);
+                mMagnificationRegion.getBounds(rect);
                 rect.offset((int) -spec.offsetX, (int) -spec.offsetY);
                 rect.scale(1.0f / spec.scale);
             }
@@ -886,7 +876,7 @@
         }
 
         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_USER_CONTEXT_CHANGED = 3;
             public static final int MESSAGE_NOTIFY_ROTATION_CHANGED = 4;
@@ -899,13 +889,11 @@
             @Override
             public void handleMessage(Message message) {
                 switch (message.what) {
-                    case MESSAGE_NOTIFY_MAGNIFIED_BOUNDS_CHANGED: {
+                    case MESSAGE_NOTIFY_MAGNIFICATION_REGION_CHANGED: {
                         final SomeArgs args = (SomeArgs) message.obj;
                         final Region magnifiedBounds = (Region) args.arg1;
-                        final Region availableBounds = (Region) args.arg2;
-                        mCallbacks.onMagnifiedBoundsChanged(magnifiedBounds, availableBounds);
+                        mCallbacks.onMagnificationRegionChanged(magnifiedBounds);
                         magnifiedBounds.recycle();
-                        availableBounds.recycle();
                     } break;
 
                     case MESSAGE_NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED: {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 875ad92..0d8f088 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -10914,12 +10914,10 @@
         }
 
         @Override
-        public void getMagnificationRegions(@NonNull Region outMagnified,
-                @NonNull Region outAvailable) {
+        public void getMagnificationRegion(@NonNull Region magnificationRegion) {
             synchronized (mWindowMap) {
                 if (mAccessibilityController != null) {
-                    mAccessibilityController.getMagnificationRegionsLocked(
-                            outMagnified, outAvailable);
+                    mAccessibilityController.getMagnificationRegionLocked(magnificationRegion);
                 } else {
                     throw new IllegalStateException("Magnification callbacks not set!");
                 }