summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Alan Viverette <alanv@google.com> 2015-11-02 18:46:48 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2015-11-02 18:46:48 +0000
commit978db40983bd4ba2a9cb3502fd7c82c6f6311d64 (patch)
tree7a1bad70fef3841bea8816e98a0e499c9d0357ca
parent723b5d90df6a1acbb56bf8fc6c93e58ff105e599 (diff)
parent57525a7054f16c198f463b1cf27988243bb96248 (diff)
Merge "Refactor MagnificationController out to its own class"
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java10
-rw-r--r--services/accessibility/java/com/android/server/accessibility/MagnificationController.java367
-rw-r--r--services/accessibility/java/com/android/server/accessibility/ScreenMagnifier.java236
3 files changed, 393 insertions, 220 deletions
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 749a0807151a..535a8efc496b 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -91,7 +91,6 @@ import android.view.accessibility.IAccessibilityManagerClient;
import com.android.internal.R;
import com.android.internal.content.PackageMonitor;
import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.widget.LockPatternUtils;
import com.android.server.LocalServices;
import org.xmlpull.v1.XmlPullParserException;
@@ -180,6 +179,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private final MainHandler mMainHandler;
+ private MagnificationController mMagnificationController;
+
private InteractionBridge mInteractionBridge;
private AlertDialog mEnableTouchExplorationDialog;
@@ -1936,6 +1937,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
}
+ MagnificationController getMagnificationController() {
+ if (mMagnificationController == null) {
+ mMagnificationController = new MagnificationController(mContext, this);
+ }
+ return mMagnificationController;
+ }
+
/**
* This class represents an accessibility service. It stores all per service
* data required for the service management, provides API for starting/stopping the
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
new file mode 100644
index 000000000000..b4411cf28487
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.accessibility;
+
+import com.android.internal.R;
+import com.android.server.LocalServices;
+
+import android.animation.ObjectAnimator;
+import android.animation.TypeEvaluator;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.util.Property;
+import android.util.Slog;
+import android.view.MagnificationSpec;
+import android.view.WindowManagerInternal;
+import android.view.animation.DecelerateInterpolator;
+
+/**
+ * This class is used to control and query the state of display magnification
+ * from the accessibility manager and related classes. It is responsible for
+ * holding the current state of magnification and animation, and it handles
+ * communication between the accessibility manager and window manager.
+ */
+class MagnificationController {
+ private static final String LOG_TAG = ScreenMagnifier.class.getSimpleName();
+
+ private static final boolean DEBUG_SET_MAGNIFICATION_SPEC = false;
+ private static final boolean DEBUG_MAGNIFICATION_CONTROLLER = false;
+
+ private static final String PROPERTY_NAME_MAGNIFICATION_SPEC = "magnificationSpec";
+
+ private final MagnificationSpec mSentMagnificationSpec = MagnificationSpec.obtain();
+ private final MagnificationSpec mCurrentMagnificationSpec = MagnificationSpec.obtain();
+
+ private final Region mMagnifiedBounds = new Region();
+ private final Rect mTempRect = new Rect();
+
+ private final AccessibilityManagerService mAms;
+ private final WindowManagerInternal mWindowManager;
+ private final ValueAnimator mTransformationAnimator;
+
+ public MagnificationController(Context context, AccessibilityManagerService ams) {
+ mAms = ams;
+ mWindowManager = LocalServices.getService(WindowManagerInternal.class);
+
+ final Property<MagnificationController, MagnificationSpec> property =
+ Property.of(MagnificationController.class, MagnificationSpec.class,
+ PROPERTY_NAME_MAGNIFICATION_SPEC);
+ final MagnificationSpecEvaluator evaluator = new MagnificationSpecEvaluator();
+ final long animationDuration = context.getResources().getInteger(
+ R.integer.config_longAnimTime);
+ mTransformationAnimator = ObjectAnimator.ofObject(this, property, evaluator,
+ mSentMagnificationSpec, mCurrentMagnificationSpec);
+ mTransformationAnimator.setDuration(animationDuration);
+ mTransformationAnimator.setInterpolator(new DecelerateInterpolator(2.5f));
+ }
+
+ /**
+ * @return {@code true} if magnification is active, e.g. the scale
+ * is > 1, {@code false} otherwise
+ */
+ public boolean isMagnifying() {
+ return mCurrentMagnificationSpec.scale > 1.0f;
+ }
+
+ /**
+ * Sets the magnified region.
+ *
+ * @param region the region to set
+ * @param updateSpec {@code true} to update the scale and center based on
+ * the region bounds, {@code false} to leave them as-is
+ */
+ public void setMagnifiedRegion(Region region, boolean updateSpec) {
+ mMagnifiedBounds.set(region);
+
+ if (updateSpec) {
+ final Rect magnifiedFrame = mTempRect;
+ region.getBounds(magnifiedFrame);
+ final float scale = mSentMagnificationSpec.scale;
+ final float offsetX = mSentMagnificationSpec.offsetX;
+ final float offsetY = mSentMagnificationSpec.offsetY;
+ final float centerX = (-offsetX + magnifiedFrame.width() / 2) / scale;
+ final float centerY = (-offsetY + magnifiedFrame.height() / 2) / scale;
+ setScaleAndMagnifiedRegionCenter(scale, centerX, centerY, false);
+ } else {
+ mAms.onMagnificationStateChanged();
+ }
+ }
+
+ /**
+ * Returns whether the magnified region 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
+ * magnified region, or {@code false} otherwise
+ */
+ public boolean magnifiedRegionContains(float x, float y) {
+ return mMagnifiedBounds.contains((int) x, (int) y);
+ }
+
+ /**
+ * Populates the specified rect with the bounds of the magnified
+ * region.
+ *
+ * @param outBounds rect to populate with the bounds of the magnified
+ * region
+ */
+ public void getMagnifiedBounds(Rect outBounds) {
+ mMagnifiedBounds.getBounds(outBounds);
+ }
+
+ /**
+ * Returns the magnification scale. If an animation is in progress,
+ * this reflects the end state of the animation.
+ *
+ * @return the scale
+ */
+ public float getScale() {
+ return mCurrentMagnificationSpec.scale;
+ }
+
+ /**
+ * Returns the X offset of the magnification viewport. If an animation
+ * is in progress, this reflects the end state of the animation.
+ *
+ * @return the X offset
+ */
+ public float getOffsetX() {
+ return mCurrentMagnificationSpec.offsetX;
+ }
+
+ /**
+ * Returns the Y offset of the magnification viewport. If an animation
+ * is in progress, this reflects the end state of the animation.
+ *
+ * @return the Y offset
+ */
+ public float getOffsetY() {
+ return mCurrentMagnificationSpec.offsetY;
+ }
+
+ /**
+ * Returns the scale currently used by the window manager. If an
+ * animation is in progress, this reflects the current state of the
+ * animation.
+ *
+ * @return the scale currently used by the window manager
+ */
+ public float getSentScale() {
+ return mSentMagnificationSpec.scale;
+ }
+
+ /**
+ * Returns the X offset currently used by the window manager. If an
+ * animation is in progress, this reflects the current state of the
+ * animation.
+ *
+ * @return the X offset currently used by the window manager
+ */
+ public float getSentOffsetX() {
+ return mSentMagnificationSpec.offsetX;
+ }
+
+ /**
+ * Returns the Y offset currently used by the window manager. If an
+ * animation is in progress, this reflects the current state of the
+ * animation.
+ *
+ * @return the Y offset currently used by the window manager
+ */
+ public float getSentOffsetY() {
+ return mSentMagnificationSpec.offsetY;
+ }
+
+ /**
+ * Resets the magnification scale and center, optionally animating the
+ * transition.
+ *
+ * @param animate {@code true} to animate the transition, {@code false}
+ * to transition immediately
+ */
+ public void reset(boolean animate) {
+ if (mTransformationAnimator.isRunning()) {
+ mTransformationAnimator.cancel();
+ }
+ mCurrentMagnificationSpec.clear();
+ if (animate) {
+ animateMagnificationSpec(mSentMagnificationSpec,
+ mCurrentMagnificationSpec);
+ } else {
+ setMagnificationSpec(mCurrentMagnificationSpec);
+ }
+ final Rect bounds = mTempRect;
+ bounds.setEmpty();
+ mAms.onMagnificationStateChanged();
+ }
+
+ /**
+ * Scales the magnified region around the specified pivot point,
+ * optionally animating the transition. If animation is disabled, the
+ * transition is immediate.
+ *
+ * @param scale the target scale, must be >= 1
+ * @param animate {@code true} to animate the transition, {@code false}
+ * to transition immediately
+ */
+ public void setScale(float scale, float pivotX, float pivotY, boolean animate) {
+ final Rect magnifiedFrame = mTempRect;
+ mMagnifiedBounds.getBounds(magnifiedFrame);
+ final MagnificationSpec spec = mCurrentMagnificationSpec;
+ final float oldScale = spec.scale;
+ final float oldCenterX = (-spec.offsetX + magnifiedFrame.width() / 2) / oldScale;
+ final float oldCenterY = (-spec.offsetY + magnifiedFrame.height() / 2) / oldScale;
+ final float normPivotX = (-spec.offsetX + pivotX) / oldScale;
+ final float normPivotY = (-spec.offsetY + pivotY) / oldScale;
+ final float offsetX = (oldCenterX - normPivotX) * (oldScale / scale);
+ final float offsetY = (oldCenterY - normPivotY) * (oldScale / scale);
+ final float centerX = normPivotX + offsetX;
+ final float centerY = normPivotY + offsetY;
+ setScaleAndMagnifiedRegionCenter(scale, centerX, centerY, animate);
+ }
+
+ /**
+ * Sets the center of the magnified region, optionally animating the
+ * transition. If animation is disabled, the transition is immediate.
+ *
+ * @param centerX the screen-relative X coordinate around which to
+ * center
+ * @param centerY the screen-relative Y coordinate around which to
+ * center
+ * @param animate {@code true} to animate the transition, {@code false}
+ * to transition immediately
+ */
+ public void setMagnifiedRegionCenter(float centerX, float centerY, boolean animate) {
+ setScaleAndMagnifiedRegionCenter(mCurrentMagnificationSpec.scale, centerX, centerY,
+ animate);
+ }
+
+ /**
+ * Sets the scale and center of the magnified region, optionally
+ * animating the transition. If animation is disabled, the transition
+ * is immediate.
+ *
+ * @param scale the target scale, must be >= 1
+ * @param centerX the screen-relative X coordinate around which to
+ * center and scale
+ * @param centerY the screen-relative Y coordinate around which to
+ * center and scale
+ * @param animate {@code true} to animate the transition, {@code false}
+ * to transition immediately
+ */
+ public void setScaleAndMagnifiedRegionCenter(float scale, float centerX, float centerY,
+ boolean animate) {
+ if (Float.compare(mCurrentMagnificationSpec.scale, scale) == 0
+ && Float.compare(mCurrentMagnificationSpec.offsetX, centerX) == 0
+ && Float.compare(mCurrentMagnificationSpec.offsetY, centerY) == 0) {
+ return;
+ }
+ if (mTransformationAnimator.isRunning()) {
+ mTransformationAnimator.cancel();
+ }
+ if (DEBUG_MAGNIFICATION_CONTROLLER) {
+ Slog.i(LOG_TAG, "scale: " + scale + " offsetX: " + centerX + " offsetY: " + centerY);
+ }
+ updateMagnificationSpec(scale, centerX, centerY);
+ if (animate) {
+ animateMagnificationSpec(mSentMagnificationSpec,
+ mCurrentMagnificationSpec);
+ } else {
+ setMagnificationSpec(mCurrentMagnificationSpec);
+ }
+ mAms.onMagnificationStateChanged();
+ }
+
+ /**
+ * Offsets the center of the magnified region.
+ *
+ * @param offsetX the amount in pixels to offset the X center
+ * @param offsetY the amount in pixels to offset the Y center
+ */
+ public void offsetMagnifiedRegionCenter(float offsetX, float offsetY) {
+ final float nonNormOffsetX = mCurrentMagnificationSpec.offsetX - offsetX;
+ mCurrentMagnificationSpec.offsetX = Math.min(Math.max(nonNormOffsetX,
+ getMinOffsetX()), 0);
+ final float nonNormOffsetY = mCurrentMagnificationSpec.offsetY - offsetY;
+ mCurrentMagnificationSpec.offsetY = Math.min(Math.max(nonNormOffsetY,
+ getMinOffsetY()), 0);
+ setMagnificationSpec(mCurrentMagnificationSpec);
+ }
+
+ private void updateMagnificationSpec(float scale, float magnifiedCenterX,
+ float magnifiedCenterY) {
+ final Rect magnifiedFrame = mTempRect;
+ mMagnifiedBounds.getBounds(magnifiedFrame);
+ mCurrentMagnificationSpec.scale = scale;
+ final int viewportWidth = magnifiedFrame.width();
+ final float nonNormOffsetX = viewportWidth / 2 - magnifiedCenterX * scale;
+ mCurrentMagnificationSpec.offsetX = Math.min(Math.max(nonNormOffsetX,
+ getMinOffsetX()), 0);
+ final int viewportHeight = magnifiedFrame.height();
+ final float nonNormOffsetY = viewportHeight / 2 - magnifiedCenterY * scale;
+ mCurrentMagnificationSpec.offsetY = Math.min(Math.max(nonNormOffsetY,
+ getMinOffsetY()), 0);
+ }
+
+ private float getMinOffsetX() {
+ final Rect magnifiedFrame = mTempRect;
+ mMagnifiedBounds.getBounds(magnifiedFrame);
+ final float viewportWidth = magnifiedFrame.width();
+ return viewportWidth - viewportWidth * mCurrentMagnificationSpec.scale;
+ }
+
+ private float getMinOffsetY() {
+ final Rect magnifiedFrame = mTempRect;
+ mMagnifiedBounds.getBounds(magnifiedFrame);
+ final float viewportHeight = magnifiedFrame.height();
+ return viewportHeight - viewportHeight * mCurrentMagnificationSpec.scale;
+ }
+
+ private void animateMagnificationSpec(MagnificationSpec fromSpec,
+ MagnificationSpec toSpec) {
+ mTransformationAnimator.setObjectValues(fromSpec, toSpec);
+ mTransformationAnimator.start();
+ }
+
+ private void setMagnificationSpec(MagnificationSpec spec) {
+ if (DEBUG_SET_MAGNIFICATION_SPEC) {
+ Slog.i(LOG_TAG, "Sending: " + spec);
+ }
+ mSentMagnificationSpec.scale = spec.scale;
+ mSentMagnificationSpec.offsetX = spec.offsetX;
+ mSentMagnificationSpec.offsetY = spec.offsetY;
+ mWindowManager.setMagnificationSpec(MagnificationSpec.obtain(spec));
+ }
+
+ private static class MagnificationSpecEvaluator implements TypeEvaluator<MagnificationSpec> {
+ private final MagnificationSpec mTempTransformationSpec = MagnificationSpec.obtain();
+
+ @Override
+ public MagnificationSpec evaluate(float fraction, MagnificationSpec fromSpec,
+ MagnificationSpec toSpec) {
+ final MagnificationSpec result = mTempTransformationSpec;
+ result.scale = fromSpec.scale + (toSpec.scale - fromSpec.scale) * fraction;
+ result.offsetX = fromSpec.offsetX + (toSpec.offsetX - fromSpec.offsetX) * fraction;
+ result.offsetY = fromSpec.offsetY + (toSpec.offsetY - fromSpec.offsetY) * fraction;
+ return result;
+ }
+ }
+}
diff --git a/services/accessibility/java/com/android/server/accessibility/ScreenMagnifier.java b/services/accessibility/java/com/android/server/accessibility/ScreenMagnifier.java
index 8845bc0246ba..8feb167f4c99 100644
--- a/services/accessibility/java/com/android/server/accessibility/ScreenMagnifier.java
+++ b/services/accessibility/java/com/android/server/accessibility/ScreenMagnifier.java
@@ -16,9 +16,6 @@
package com.android.server.accessibility;
-import android.animation.ObjectAnimator;
-import android.animation.TypeEvaluator;
-import android.animation.ValueAnimator;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -31,14 +28,12 @@ import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.text.TextUtils;
-import android.util.Property;
import android.util.Slog;
import android.util.TypedValue;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.InputDevice;
import android.view.KeyEvent;
-import android.view.MagnificationSpec;
import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords;
import android.view.MotionEvent.PointerProperties;
@@ -48,7 +43,6 @@ import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManagerInternal;
import android.view.accessibility.AccessibilityEvent;
-import android.view.animation.DecelerateInterpolator;
import com.android.internal.os.SomeArgs;
import com.android.server.LocalServices;
@@ -101,10 +95,8 @@ public final class ScreenMagnifier implements WindowManagerInternal.Magnificatio
private static final boolean DEBUG_STATE_TRANSITIONS = false;
private static final boolean DEBUG_DETECTING = false;
- private static final boolean DEBUG_SET_MAGNIFICATION_SPEC = false;
private static final boolean DEBUG_PANNING = false;
private static final boolean DEBUG_SCALING = false;
- private static final boolean DEBUG_MAGNIFICATION_CONTROLLER = false;
private static final int STATE_DELEGATING = 1;
private static final int STATE_DETECTING = 2;
@@ -134,8 +126,6 @@ public final class ScreenMagnifier implements WindowManagerInternal.Magnificatio
private final MagnifiedContentInteractonStateHandler mMagnifiedContentInteractonStateHandler;
private final StateViewportDraggingHandler mStateViewportDraggingHandler;
- private final AccessibilityManagerService mAms;
-
private final int mUserId;
private final int mTapTimeSlop = ViewConfiguration.getJumpTapTimeout();
@@ -143,10 +133,6 @@ public final class ScreenMagnifier implements WindowManagerInternal.Magnificatio
private final int mTapDistanceSlop;
private final int mMultiTapDistanceSlop;
- private final long mLongAnimationDuration;
-
- private final Region mMagnifiedBounds = new Region();
-
private EventStreamTransformation mNext;
private int mCurrentState;
@@ -194,13 +180,10 @@ public final class ScreenMagnifier implements WindowManagerInternal.Magnificatio
mContext = context;
mUserId = userId;
mWindowManager = LocalServices.getService(WindowManagerInternal.class);
- mAms = service;
mMultiTapTimeSlop = ViewConfiguration.getDoubleTapTimeout()
+ mContext.getResources().getInteger(
com.android.internal.R.integer.config_screen_magnification_multi_tap_adjustment);
- mLongAnimationDuration = context.getResources().getInteger(
- com.android.internal.R.integer.config_longAnimTime);
mTapDistanceSlop = ViewConfiguration.get(context).getScaledTouchSlop();
mMultiTapDistanceSlop = ViewConfiguration.get(context).getScaledDoubleTapSlop();
@@ -209,7 +192,7 @@ public final class ScreenMagnifier implements WindowManagerInternal.Magnificatio
mMagnifiedContentInteractonStateHandler = new MagnifiedContentInteractonStateHandler(
context);
- mMagnificationController = new MagnificationController(mLongAnimationDuration);
+ mMagnificationController = service.getMagnificationController();
mScreenStateObserver = new ScreenStateObserver(context, mMagnificationController);
mWindowManager.setMagnificationCallbacks(this);
@@ -230,19 +213,9 @@ public final class ScreenMagnifier implements WindowManagerInternal.Magnificatio
// If there was a rotation we have to update the center of the magnified
// region since the old offset X/Y may be out of its acceptable range for
// the new display width and height.
- if (mUpdateMagnificationSpecOnNextBoundsChange) {
- mUpdateMagnificationSpecOnNextBoundsChange = false;
- MagnificationSpec spec = mMagnificationController.getMagnificationSpec();
- Rect magnifiedFrame = mTempRect;
- mMagnifiedBounds.getBounds(magnifiedFrame);
- final float scale = spec.scale;
- final float centerX = (-spec.offsetX + magnifiedFrame.width() / 2) / scale;
- final float centerY = (-spec.offsetY + magnifiedFrame.height() / 2) / scale;
- mMagnificationController.setScaleAndMagnifiedRegionCenter(scale, centerX,
- centerY, false);
- }
- mMagnifiedBounds.set(bounds);
- mAms.onMagnificationStateChanged();
+ mMagnificationController.setMagnifiedRegion(
+ bounds, mUpdateMagnificationSpecOnNextBoundsChange);
+ mUpdateMagnificationSpecOnNextBoundsChange = false;
}
@Override
@@ -257,7 +230,7 @@ public final class ScreenMagnifier implements WindowManagerInternal.Magnificatio
private void handleOnRectangleOnScreenRequested(int left, int top, int right, int bottom) {
Rect magnifiedFrame = mTempRect;
- mMagnifiedBounds.getBounds(magnifiedFrame);
+ mMagnificationController.getMagnifiedBounds(magnifiedFrame);
if (!magnifiedFrame.intersects(left, top, right, bottom)) {
return;
}
@@ -314,10 +287,12 @@ public final class ScreenMagnifier implements WindowManagerInternal.Magnificatio
}
private void getMagnifiedFrameInContentCoords(Rect rect) {
- MagnificationSpec spec = mMagnificationController.getMagnificationSpec();
- mMagnifiedBounds.getBounds(rect);
- rect.offset((int) -spec.offsetX, (int) -spec.offsetY);
- rect.scale(1.0f / spec.scale);
+ final float scale = mMagnificationController.getSentScale();
+ final float offsetX = mMagnificationController.getSentOffsetX();
+ final float offsetY = mMagnificationController.getSentOffsetY();
+ mMagnificationController.getMagnifiedBounds(rect);
+ rect.offset((int) -offsetX, (int) -offsetY);
+ rect.scale(1.0f / scale);
}
private void resetMagnificationIfNeeded() {
@@ -421,7 +396,7 @@ public final class ScreenMagnifier implements WindowManagerInternal.Magnificatio
final float eventX = event.getX();
final float eventY = event.getY();
if (mMagnificationController.isMagnifying()
- && mMagnifiedBounds.contains((int) eventX, (int) eventY)) {
+ && mMagnificationController.magnifiedRegionContains(eventX, eventY)) {
final float scale = mMagnificationController.getScale();
final float scaledOffsetX = mMagnificationController.getOffsetX();
final float scaledOffsetY = mMagnificationController.getOffsetY();
@@ -623,7 +598,7 @@ public final class ScreenMagnifier implements WindowManagerInternal.Magnificatio
}
final float eventX = event.getX();
final float eventY = event.getY();
- if (mMagnifiedBounds.contains((int) eventX, (int) eventY)) {
+ if (mMagnificationController.magnifiedRegionContains(eventX, eventY)) {
if (mLastMoveOutsideMagnifiedRegion) {
mLastMoveOutsideMagnifiedRegion = false;
mMagnificationController.setMagnifiedRegionCenter(eventX,
@@ -696,8 +671,8 @@ public final class ScreenMagnifier implements WindowManagerInternal.Magnificatio
switch (action) {
case MotionEvent.ACTION_DOWN: {
mHandler.removeMessages(MESSAGE_TRANSITION_TO_DELEGATING_STATE);
- if (!mMagnifiedBounds.contains((int) event.getX(),
- (int) event.getY())) {
+ if (!mMagnificationController.magnifiedRegionContains(
+ event.getX(), event.getY())) {
transitionToDelegatingStateAndClear();
return;
}
@@ -738,7 +713,8 @@ public final class ScreenMagnifier implements WindowManagerInternal.Magnificatio
return;
}
mHandler.removeMessages(MESSAGE_ON_ACTION_TAP_AND_HOLD);
- if (!mMagnifiedBounds.contains((int) event.getX(), (int) event.getY())) {
+ if (!mMagnificationController.magnifiedRegionContains(
+ event.getX(), event.getY())) {
transitionToDelegatingStateAndClear();
return;
}
@@ -947,184 +923,6 @@ public final class ScreenMagnifier implements WindowManagerInternal.Magnificatio
}
}
- private final class MagnificationController {
-
- private static final String PROPERTY_NAME_MAGNIFICATION_SPEC =
- "magnificationSpec";
-
- private final MagnificationSpec mSentMagnificationSpec = MagnificationSpec.obtain();
-
- private final MagnificationSpec mCurrentMagnificationSpec = MagnificationSpec.obtain();
-
- private final Rect mTempRect = new Rect();
-
- private final ValueAnimator mTransformationAnimator;
-
- public MagnificationController(long animationDuration) {
- Property<MagnificationController, MagnificationSpec> property =
- Property.of(MagnificationController.class, MagnificationSpec.class,
- PROPERTY_NAME_MAGNIFICATION_SPEC);
- TypeEvaluator<MagnificationSpec> evaluator = new TypeEvaluator<MagnificationSpec>() {
- private final MagnificationSpec mTempTransformationSpec =
- MagnificationSpec.obtain();
- @Override
- public MagnificationSpec evaluate(float fraction, MagnificationSpec fromSpec,
- MagnificationSpec toSpec) {
- MagnificationSpec result = mTempTransformationSpec;
- result.scale = fromSpec.scale
- + (toSpec.scale - fromSpec.scale) * fraction;
- result.offsetX = fromSpec.offsetX + (toSpec.offsetX - fromSpec.offsetX)
- * fraction;
- result.offsetY = fromSpec.offsetY + (toSpec.offsetY - fromSpec.offsetY)
- * fraction;
- return result;
- }
- };
- mTransformationAnimator = ObjectAnimator.ofObject(this, property,
- evaluator, mSentMagnificationSpec, mCurrentMagnificationSpec);
- mTransformationAnimator.setDuration((long) (animationDuration));
- mTransformationAnimator.setInterpolator(new DecelerateInterpolator(2.5f));
- }
-
- public boolean isMagnifying() {
- return mCurrentMagnificationSpec.scale > 1.0f;
- }
-
- public void reset(boolean animate) {
- if (mTransformationAnimator.isRunning()) {
- mTransformationAnimator.cancel();
- }
- mCurrentMagnificationSpec.clear();
- if (animate) {
- animateMangificationSpec(mSentMagnificationSpec,
- mCurrentMagnificationSpec);
- } else {
- setMagnificationSpec(mCurrentMagnificationSpec);
- }
- Rect bounds = mTempRect;
- bounds.setEmpty();
- mAms.onMagnificationStateChanged();
- }
-
- public float getScale() {
- return mCurrentMagnificationSpec.scale;
- }
-
- public float getOffsetX() {
- return mCurrentMagnificationSpec.offsetX;
- }
-
- public float getOffsetY() {
- return mCurrentMagnificationSpec.offsetY;
- }
-
- public void setScale(float scale, float pivotX, float pivotY, boolean animate) {
- Rect magnifiedFrame = mTempRect;
- mMagnifiedBounds.getBounds(magnifiedFrame);
- MagnificationSpec spec = mCurrentMagnificationSpec;
- final float oldScale = spec.scale;
- final float oldCenterX = (-spec.offsetX + magnifiedFrame.width() / 2) / oldScale;
- final float oldCenterY = (-spec.offsetY + magnifiedFrame.height() / 2) / oldScale;
- final float normPivotX = (-spec.offsetX + pivotX) / oldScale;
- final float normPivotY = (-spec.offsetY + pivotY) / oldScale;
- final float offsetX = (oldCenterX - normPivotX) * (oldScale / scale);
- final float offsetY = (oldCenterY - normPivotY) * (oldScale / scale);
- final float centerX = normPivotX + offsetX;
- final float centerY = normPivotY + offsetY;
- setScaleAndMagnifiedRegionCenter(scale, centerX, centerY, animate);
- }
-
- public void setMagnifiedRegionCenter(float centerX, float centerY, boolean animate) {
- setScaleAndMagnifiedRegionCenter(mCurrentMagnificationSpec.scale, centerX, centerY,
- animate);
- }
-
- public void offsetMagnifiedRegionCenter(float offsetX, float offsetY) {
- final float nonNormOffsetX = mCurrentMagnificationSpec.offsetX - offsetX;
- mCurrentMagnificationSpec.offsetX = Math.min(Math.max(nonNormOffsetX,
- getMinOffsetX()), 0);
- final float nonNormOffsetY = mCurrentMagnificationSpec.offsetY - offsetY;
- mCurrentMagnificationSpec.offsetY = Math.min(Math.max(nonNormOffsetY,
- getMinOffsetY()), 0);
- setMagnificationSpec(mCurrentMagnificationSpec);
- }
-
- public void setScaleAndMagnifiedRegionCenter(float scale, float centerX, float centerY,
- boolean animate) {
- if (Float.compare(mCurrentMagnificationSpec.scale, scale) == 0
- && Float.compare(mCurrentMagnificationSpec.offsetX,
- centerX) == 0
- && Float.compare(mCurrentMagnificationSpec.offsetY,
- centerY) == 0) {
- return;
- }
- if (mTransformationAnimator.isRunning()) {
- mTransformationAnimator.cancel();
- }
- if (DEBUG_MAGNIFICATION_CONTROLLER) {
- Slog.i(LOG_TAG, "scale: " + scale + " offsetX: " + centerX
- + " offsetY: " + centerY);
- }
- updateMagnificationSpec(scale, centerX, centerY);
- if (animate) {
- animateMangificationSpec(mSentMagnificationSpec,
- mCurrentMagnificationSpec);
- } else {
- setMagnificationSpec(mCurrentMagnificationSpec);
- }
- mAms.onMagnificationStateChanged();
- }
-
- public void updateMagnificationSpec(float scale, float magnifiedCenterX,
- float magnifiedCenterY) {
- Rect magnifiedFrame = mTempRect;
- mMagnifiedBounds.getBounds(magnifiedFrame);
- mCurrentMagnificationSpec.scale = scale;
- final int viewportWidth = magnifiedFrame.width();
- final float nonNormOffsetX = viewportWidth / 2 - magnifiedCenterX * scale;
- mCurrentMagnificationSpec.offsetX = Math.min(Math.max(nonNormOffsetX,
- getMinOffsetX()), 0);
- final int viewportHeight = magnifiedFrame.height();
- final float nonNormOffsetY = viewportHeight / 2 - magnifiedCenterY * scale;
- mCurrentMagnificationSpec.offsetY = Math.min(Math.max(nonNormOffsetY,
- getMinOffsetY()), 0);
- }
-
- private float getMinOffsetX() {
- Rect magnifiedFrame = mTempRect;
- mMagnifiedBounds.getBounds(magnifiedFrame);
- final float viewportWidth = magnifiedFrame.width();
- return viewportWidth - viewportWidth * mCurrentMagnificationSpec.scale;
- }
-
- private float getMinOffsetY() {
- Rect magnifiedFrame = mTempRect;
- mMagnifiedBounds.getBounds(magnifiedFrame);
- final float viewportHeight = magnifiedFrame.height();
- return viewportHeight - viewportHeight * mCurrentMagnificationSpec.scale;
- }
-
- private void animateMangificationSpec(MagnificationSpec fromSpec,
- MagnificationSpec toSpec) {
- mTransformationAnimator.setObjectValues(fromSpec, toSpec);
- mTransformationAnimator.start();
- }
-
- public MagnificationSpec getMagnificationSpec() {
- return mSentMagnificationSpec;
- }
-
- public void setMagnificationSpec(MagnificationSpec spec) {
- if (DEBUG_SET_MAGNIFICATION_SPEC) {
- Slog.i(LOG_TAG, "Sending: " + spec);
- }
- mSentMagnificationSpec.scale = spec.scale;
- mSentMagnificationSpec.offsetX = spec.offsetX;
- mSentMagnificationSpec.offsetY = spec.offsetY;
- mWindowManager.setMagnificationSpec(MagnificationSpec.obtain(spec));
- }
- }
-
private final class ScreenStateObserver extends BroadcastReceiver {
private static final int MESSAGE_ON_SCREEN_STATE_CHANGE = 1;