Merge "Various fixes for MagnificationController" into nyc-dev

This commit is contained in:
Alan Viverette
2016-03-29 15:13:02 +00:00
committed by Android (Google) Code Review
4 changed files with 100 additions and 46 deletions

View File

@@ -16,6 +16,7 @@
package android.view; package android.view;
import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.Region; import android.graphics.Region;
@@ -156,6 +157,15 @@ public abstract class WindowManagerInternal {
*/ */
public abstract void setMagnificationSpec(MagnificationSpec spec); public abstract void setMagnificationSpec(MagnificationSpec spec);
/**
* Obtains the magnified and available regions.
*
* @param outMagnified the currently magnified region
* @param outAvailable the region available for magnification
*/
public abstract void getMagnificationRegions(@NonNull Region outMagnified,
@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.
* Not all windows are magnified and the window manager policy determines which * Not all windows are magnified and the window manager policy determines which

View File

@@ -111,12 +111,18 @@ class MagnificationController {
public void register() { public void register() {
mScreenStateObserver.register(); mScreenStateObserver.register();
mWindowStateObserver.register(); mWindowStateObserver.register();
// Obtain initial state.
mWindowStateObserver.getRegions(mMagnifiedRegion, mAvailableRegion);
mMagnifiedRegion.getBounds(mMagnifiedBounds);
} }
/** /**
* Unregisters magnification-related observers. * Unregisters magnification-related observers.
*/ */
public void unregister() { public void unregister() {
mSpecAnimationBridge.cancel();
mScreenStateObserver.unregister(); mScreenStateObserver.unregister();
mWindowStateObserver.unregister(); mWindowStateObserver.unregister();
} }
@@ -149,8 +155,10 @@ 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 - offsetX) / scale; final float centerX = (mMagnifiedBounds.width() / 2.0f
final float centerY = (mMagnifiedBounds.height() / 2.0f - offsetY) / scale; + mMagnifiedBounds.left - offsetX) / scale;
final float centerY = (mMagnifiedBounds.height() / 2.0f
+ mMagnifiedBounds.top - offsetY) / scale;
if (updateSpec) { if (updateSpec) {
setScaleAndCenter(scale, centerX, centerY, false); setScaleAndCenter(scale, centerX, centerY, false);
} else { } else {
@@ -246,7 +254,8 @@ class MagnificationController {
*/ */
public float getCenterX() { public float getCenterX() {
synchronized (mLock) { synchronized (mLock) {
return (mMagnifiedBounds.width() / 2.0f - getOffsetX()) / getScale(); return (mMagnifiedBounds.width() / 2.0f
+ mMagnifiedBounds.left - getOffsetX()) / getScale();
} }
} }
@@ -268,7 +277,8 @@ class MagnificationController {
*/ */
public float getCenterY() { public float getCenterY() {
synchronized (mLock) { synchronized (mLock) {
return (mMagnifiedBounds.height() / 2.0f - getOffsetY()) / getScale(); return (mMagnifiedBounds.height() / 2.0f
+ mMagnifiedBounds.top - getOffsetY()) / getScale();
} }
} }
@@ -471,18 +481,25 @@ class MagnificationController {
* otherwise * otherwise
*/ */
private boolean updateMagnificationSpecLocked(float scale, float centerX, float centerY) { private boolean updateMagnificationSpecLocked(float scale, float centerX, float centerY) {
// Handle defaults.
if (Float.isNaN(centerX)) {
centerX = getCenterX();
}
if (Float.isNaN(centerY)) {
centerY = getCenterY();
}
if (Float.isNaN(scale)) {
scale = getScale();
}
// Ensure requested center is within the available region.
if (!availableRegionContains(centerX, centerY)) { if (!availableRegionContains(centerX, centerY)) {
return false; return false;
} }
boolean changed = false; // Compute changes.
final MagnificationSpec currSpec = mCurrentMagnificationSpec; final MagnificationSpec currSpec = mCurrentMagnificationSpec;
boolean changed = false;
// Handle scale.
if (Float.isNaN(scale)) {
scale = getScale();
}
final float normScale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE); final float normScale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
if (Float.compare(currSpec.scale, normScale) != 0) { if (Float.compare(currSpec.scale, normScale) != 0) {
@@ -490,24 +507,16 @@ class MagnificationController {
changed = true; changed = true;
} }
// Handle X offset. final float nonNormOffsetX = mMagnifiedBounds.width() / 2.0f
if (Float.isNaN(centerX)) { + mMagnifiedBounds.left - centerX * scale;
centerX = getCenterX();
}
final float nonNormOffsetX = mMagnifiedBounds.width() / 2.0f - 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;
} }
// Handle Y offset. final float nonNormOffsetY = mMagnifiedBounds.height() / 2.0f
if (Float.isNaN(centerY)) { + mMagnifiedBounds.top - centerY * scale;
centerY = getCenterY();
}
final float nonNormOffsetY = mMagnifiedBounds.height() / 2.0f - 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;
@@ -661,6 +670,12 @@ class MagnificationController {
mTransformationAnimator.setInterpolator(new DecelerateInterpolator(2.5f)); mTransformationAnimator.setInterpolator(new DecelerateInterpolator(2.5f));
} }
public void cancel() {
if (mTransformationAnimator != null && mTransformationAnimator.isRunning()) {
mTransformationAnimator.cancel();
}
}
public void updateSentSpec(MagnificationSpec spec, boolean animate) { public void updateSentSpec(MagnificationSpec spec, boolean animate) {
if (Thread.currentThread().getId() == mMainThreadId) { if (Thread.currentThread().getId() == mMainThreadId) {
// Already on the main thread, don't bother proxying. // Already on the main thread, don't bother proxying.
@@ -811,9 +826,6 @@ class MagnificationController {
private static final int MESSAGE_ON_USER_CONTEXT_CHANGED = 3; private static final int MESSAGE_ON_USER_CONTEXT_CHANGED = 3;
private static final int MESSAGE_ON_ROTATION_CHANGED = 4; private static final int MESSAGE_ON_ROTATION_CHANGED = 4;
private final Rect mTempRect = new Rect();
private final Rect mTempRect1 = new Rect();
private final MagnificationController mController; private final MagnificationController mController;
private final WindowManagerInternal mWindowManager; private final WindowManagerInternal mWindowManager;
private final Handler mHandler; private final Handler mHandler;
@@ -884,6 +896,10 @@ class MagnificationController {
mController.resetIfNeeded(true); mController.resetIfNeeded(true);
} }
public void getRegions(@NonNull Region outMagnified, @NonNull Region outAvailable) {
mWindowManager.getMagnificationRegions(outMagnified, outAvailable);
}
private class CallbackHandler extends Handler { private class CallbackHandler extends Handler {
public CallbackHandler(Context context) { public CallbackHandler(Context context) {
super(context.getMainLooper()); super(context.getMainLooper());

View File

@@ -21,6 +21,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.app.Service; import android.app.Service;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
@@ -122,6 +123,12 @@ final class AccessibilityController {
} }
} }
public void getMagnificationRegionsLocked(Region outMagnified, Region outAvailable) {
if (mDisplayMagnifier != null) {
mDisplayMagnifier.getMagnificationRegionsLocked(outMagnified, outAvailable);
}
}
public void onRectangleOnScreenRequestedLocked(Rect rectangle) { public void onRectangleOnScreenRequestedLocked(Rect rectangle) {
if (mDisplayMagnifier != null) { if (mDisplayMagnifier != null) {
mDisplayMagnifier.onRectangleOnScreenRequestedLocked(rectangle); mDisplayMagnifier.onRectangleOnScreenRequestedLocked(rectangle);
@@ -392,6 +399,10 @@ final class AccessibilityController {
return spec; return spec;
} }
public void getMagnificationRegionsLocked(Region outMagnified, Region outAvailable) {
mMagnifedViewport.getBoundsLocked(outMagnified, outAvailable);
}
public void destroyLocked() { public void destroyLocked() {
mMagnifedViewport.destroyWindow(); mMagnifedViewport.destroyWindow();
} }
@@ -413,6 +424,7 @@ final class AccessibilityController {
private final Matrix mTempMatrix = new Matrix(); private final Matrix mTempMatrix = new Matrix();
private final Region mMagnifiedBounds = new Region(); private final Region mMagnifiedBounds = new Region();
private final Region mAvailableBounds = new Region();
private final Region mOldMagnifiedBounds = new Region(); private final Region mOldMagnifiedBounds = new Region();
private final Region mOldAvailableBounds = new Region(); private final Region mOldAvailableBounds = new Region();
@@ -450,6 +462,12 @@ final class AccessibilityController {
recomputeBoundsLocked(); recomputeBoundsLocked();
} }
public void getBoundsLocked(@NonNull Region outMagnified,
@NonNull Region outAvailable) {
outMagnified.set(mMagnifiedBounds);
outAvailable.set(mAvailableBounds);
}
public void updateMagnificationSpecLocked(MagnificationSpec spec) { public void updateMagnificationSpecLocked(MagnificationSpec spec) {
if (spec != null) { if (spec != null) {
mMagnificationSpec.initialize(spec.scale, spec.offsetX, spec.offsetY); mMagnificationSpec.initialize(spec.scale, spec.offsetX, spec.offsetY);
@@ -469,14 +487,11 @@ final class AccessibilityController {
final int screenWidth = mTempPoint.x; final int screenWidth = mTempPoint.x;
final int screenHeight = mTempPoint.y; final int screenHeight = mTempPoint.y;
Region magnifiedBounds = mMagnifiedBounds; mMagnifiedBounds.set(0, 0, 0, 0);
magnifiedBounds.set(0, 0, 0, 0); mAvailableBounds.set(0, 0, screenWidth, screenHeight);
Region availableBounds = mTempRegion1;
availableBounds.set(0, 0, screenWidth, screenHeight);
if (mCircularPath != null) { if (mCircularPath != null) {
availableBounds.setPath(mCircularPath, availableBounds); mAvailableBounds.setPath(mCircularPath, mAvailableBounds);
} }
Region nonMagnifiedBounds = mTempRegion4; Region nonMagnifiedBounds = mTempRegion4;
@@ -505,8 +520,8 @@ final class AccessibilityController {
matrix.mapRect(windowFrame); matrix.mapRect(windowFrame);
windowBounds.set((int) windowFrame.left, (int) windowFrame.top, windowBounds.set((int) windowFrame.left, (int) windowFrame.top,
(int) windowFrame.right, (int) windowFrame.bottom); (int) windowFrame.right, (int) windowFrame.bottom);
magnifiedBounds.op(windowBounds, Region.Op.UNION); mMagnifiedBounds.op(windowBounds, Region.Op.UNION);
magnifiedBounds.op(availableBounds, Region.Op.INTERSECT); mMagnifiedBounds.op(mAvailableBounds, Region.Op.INTERSECT);
} else { } else {
Region touchableRegion = mTempRegion3; Region touchableRegion = mTempRegion3;
windowState.getTouchableRegion(touchableRegion); windowState.getTouchableRegion(touchableRegion);
@@ -518,12 +533,12 @@ final class AccessibilityController {
windowBounds.set((int) windowFrame.left, (int) windowFrame.top, windowBounds.set((int) windowFrame.left, (int) windowFrame.top,
(int) windowFrame.right, (int) windowFrame.bottom); (int) windowFrame.right, (int) windowFrame.bottom);
nonMagnifiedBounds.op(windowBounds, Region.Op.UNION); nonMagnifiedBounds.op(windowBounds, Region.Op.UNION);
windowBounds.op(magnifiedBounds, Region.Op.DIFFERENCE); windowBounds.op(mMagnifiedBounds, Region.Op.DIFFERENCE);
availableBounds.op(windowBounds, Region.Op.DIFFERENCE); mAvailableBounds.op(windowBounds, Region.Op.DIFFERENCE);
} }
Region accountedBounds = mTempRegion2; Region accountedBounds = mTempRegion2;
accountedBounds.set(magnifiedBounds); accountedBounds.set(mMagnifiedBounds);
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);
@@ -539,15 +554,15 @@ final class AccessibilityController {
visibleWindows.clear(); visibleWindows.clear();
magnifiedBounds.op(mDrawBorderInset, mDrawBorderInset, mMagnifiedBounds.op(mDrawBorderInset, mDrawBorderInset,
screenWidth - mDrawBorderInset, screenHeight - mDrawBorderInset, screenWidth - mDrawBorderInset, screenHeight - mDrawBorderInset,
Region.Op.INTERSECT); Region.Op.INTERSECT);
final boolean magnifiedChanged = !mOldMagnifiedBounds.equals(magnifiedBounds); final boolean magnifiedChanged = !mOldMagnifiedBounds.equals(mMagnifiedBounds);
final boolean availableChanged = !mOldAvailableBounds.equals(availableBounds); final boolean availableChanged = !mOldAvailableBounds.equals(mAvailableBounds);
if (magnifiedChanged || availableChanged) { if (magnifiedChanged || availableChanged) {
if (magnifiedChanged) { if (magnifiedChanged) {
mWindow.setBounds(magnifiedBounds); mWindow.setBounds(mMagnifiedBounds);
Rect dirtyRect = mTempRect1; Rect dirtyRect = mTempRect1;
if (mFullRedrawNeeded) { if (mFullRedrawNeeded) {
mFullRedrawNeeded = false; mFullRedrawNeeded = false;
@@ -557,23 +572,23 @@ final class AccessibilityController {
mWindow.invalidate(dirtyRect); mWindow.invalidate(dirtyRect);
} else { } else {
Region dirtyRegion = mTempRegion3; Region dirtyRegion = mTempRegion3;
dirtyRegion.set(magnifiedBounds); dirtyRegion.set(mMagnifiedBounds);
dirtyRegion.op(mOldMagnifiedBounds, 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(magnifiedBounds); mOldMagnifiedBounds.set(mMagnifiedBounds);
} }
if (availableChanged) { if (availableChanged) {
mOldAvailableBounds.set(availableBounds); mOldAvailableBounds.set(mAvailableBounds);
} }
final SomeArgs args = SomeArgs.obtain(); final SomeArgs args = SomeArgs.obtain();
args.arg1 = Region.obtain(magnifiedBounds); args.arg1 = Region.obtain(mMagnifiedBounds);
args.arg2 = Region.obtain(availableBounds); args.arg2 = Region.obtain(mAvailableBounds);
mHandler.obtainMessage( mHandler.obtainMessage(
MyHandler.MESSAGE_NOTIFY_MAGNIFIED_BOUNDS_CHANGED, args).sendToTarget(); MyHandler.MESSAGE_NOTIFY_MAGNIFIED_BOUNDS_CHANGED, args).sendToTarget();
} }

View File

@@ -10724,6 +10724,19 @@ public class WindowManagerService extends IWindowManager.Stub
} }
} }
@Override
public void getMagnificationRegions(@NonNull Region outMagnified,
@NonNull Region outAvailable) {
synchronized (mWindowMap) {
if (mAccessibilityController != null) {
mAccessibilityController.getMagnificationRegionsLocked(
outMagnified, outAvailable);
} else {
throw new IllegalStateException("Magnification callbacks not set!");
}
}
}
@Override @Override
public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) { public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) {
synchronized (mWindowMap) { synchronized (mWindowMap) {