Merge "MagnificationProcessor uses MagnificationConfig to control the specified magnifier"

This commit is contained in:
Minche Li
2021-11-23 00:25:06 +00:00
committed by Android (Google) Code Review
10 changed files with 935 additions and 103 deletions

View File

@@ -3255,6 +3255,28 @@ package android.accessibilityservice {
method public boolean willContinue();
}
public final class MagnificationConfig implements android.os.Parcelable {
method public int describeContents();
method public float getCenterX();
method public float getCenterY();
method public int getMode();
method public float getScale();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.accessibilityservice.MagnificationConfig> CREATOR;
field public static final int DEFAULT_MODE = 0; // 0x0
field public static final int FULLSCREEN_MODE = 1; // 0x1
field public static final int WINDOW_MODE = 2; // 0x2
}
public static final class MagnificationConfig.Builder {
ctor public MagnificationConfig.Builder();
method @NonNull public android.accessibilityservice.MagnificationConfig build();
method @NonNull public android.accessibilityservice.MagnificationConfig.Builder setCenterX(float);
method @NonNull public android.accessibilityservice.MagnificationConfig.Builder setCenterY(float);
method @NonNull public android.accessibilityservice.MagnificationConfig.Builder setMode(int);
method @NonNull public android.accessibilityservice.MagnificationConfig.Builder setScale(float);
}
public final class TouchInteractionController {
method public int getDisplayId();
method public int getMaxPointerCount();

View File

@@ -0,0 +1,19 @@
/*
* Copyright (C) 2021 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 android.accessibilityservice;
parcelable MagnificationConfig;

View File

@@ -0,0 +1,250 @@
/*
* Copyright (C) 2021 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 android.accessibilityservice;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* This class describes the magnification config for {@link AccessibilityService} to control the
* magnification.
*
* <p>
* When the magnification config uses {@link #DEFAULT_MODE},
* {@link AccessibilityService} will be able to control the activated magnifier on the display.
* If there is no magnifier activated, it controls the last-activated magnification mode.
* If there is no magnifier activated before, it controls full-screen magnifier by default.
* </p>
*
* <p>
* When the magnification config uses {@link #FULLSCREEN_MODE}. {@link AccessibilityService} will
* be able to control full-screen magnifier on the display.
* </p>
*
* <p>
* When the magnification config uses {@link #WINDOW_MODE}. {@link AccessibilityService} will be
* able to control the activated window magnifier on the display.
* </p>
*
* <p>
* If the other magnification configs, scale centerX and centerY, are not set by the
* {@link Builder}, the configs should be current values or default values. And the center
* position ordinarily is the center of the screen.
* </p>
*/
public final class MagnificationConfig implements Parcelable {
/** The controlling magnification mode. It controls the activated magnifier. */
public static final int DEFAULT_MODE = 0;
/** The controlling magnification mode. It controls fullscreen magnifier. */
public static final int FULLSCREEN_MODE = 1;
/** The controlling magnification mode. It controls window magnifier. */
public static final int WINDOW_MODE = 2;
@IntDef(prefix = {"MAGNIFICATION_MODE"}, value = {
DEFAULT_MODE,
FULLSCREEN_MODE,
WINDOW_MODE,
})
@Retention(RetentionPolicy.SOURCE)
@interface MAGNIFICATION_MODE {
}
private int mMode = DEFAULT_MODE;
private float mScale = Float.NaN;
private float mCenterX = Float.NaN;
private float mCenterY = Float.NaN;
private MagnificationConfig() {
/* do nothing */
}
private MagnificationConfig(@NonNull Parcel parcel) {
mMode = parcel.readInt();
mScale = parcel.readFloat();
mCenterX = parcel.readFloat();
mCenterY = parcel.readFloat();
}
/**
* Returns the magnification mode that is the current activated mode or the controlling mode of
* the config.
*
* @return The magnification mode
*/
public int getMode() {
return mMode;
}
/**
* Returns the magnification scale of the controlling magnifier
*
* @return the scale If the controlling magnifier is not activated, it returns 1 by default
*/
public float getScale() {
return mScale;
}
/**
* Returns the screen-relative X coordinate of the center of the magnification viewport.
*
* @return the X coordinate. If the controlling magnifier is {@link #WINDOW_MODE} but not
* enabled, it returns {@link Float#NaN}. If the controlling magnifier is {@link
* #FULLSCREEN_MODE} but not enabled, it returns 0
*/
public float getCenterX() {
return mCenterX;
}
/**
* Returns the screen-relative Y coordinate of the center of the magnification viewport.
*
* @return the Y coordinate If the controlling magnifier is {@link #WINDOW_MODE} but not
* enabled, it returns {@link Float#NaN}. If the controlling magnifier is {@link
* #FULLSCREEN_MODE} but not enabled, it returns 0
*/
public float getCenterY() {
return mCenterY;
}
@NonNull
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder("MagnificationConfig[");
stringBuilder.append("mode: ").append(getMode());
stringBuilder.append(", ");
stringBuilder.append("scale: ").append(getScale());
stringBuilder.append(", ");
stringBuilder.append("centerX: ").append(getCenterX());
stringBuilder.append(", ");
stringBuilder.append("centerY: ").append(getCenterY());
stringBuilder.append("] ");
return stringBuilder.toString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel parcel, int flags) {
parcel.writeInt(mMode);
parcel.writeFloat(mScale);
parcel.writeFloat(mCenterX);
parcel.writeFloat(mCenterY);
}
/**
* Builder for creating {@link MagnificationConfig} objects.
*/
public static final class Builder {
private int mMode = DEFAULT_MODE;
private float mScale = Float.NaN;
private float mCenterX = Float.NaN;
private float mCenterY = Float.NaN;
/**
* Creates a new Builder.
*/
public Builder() {
}
/**
* Sets the magnification mode.
*
* @param mode The magnification mode
* @return This builder
*/
@NonNull
public MagnificationConfig.Builder setMode(@MAGNIFICATION_MODE int mode) {
mMode = mode;
return this;
}
/**
* Sets the magnification scale.
*
* @param scale The magnification scale
* @return This builder
*/
@NonNull
public MagnificationConfig.Builder setScale(float scale) {
mScale = scale;
return this;
}
/**
* Sets the X coordinate of the center of the magnification viewport.
*
* @param centerX the screen-relative X coordinate around which to
* center and scale, or {@link Float#NaN} to leave unchanged
* @return This builder
*/
@NonNull
public MagnificationConfig.Builder setCenterX(float centerX) {
mCenterX = centerX;
return this;
}
/**
* Sets the Y coordinate of the center of the magnification viewport.
*
* @param centerY the screen-relative Y coordinate around which to
* center and scale, or {@link Float#NaN} to leave unchanged
* @return This builder
*/
@NonNull
public MagnificationConfig.Builder setCenterY(float centerY) {
mCenterY = centerY;
return this;
}
/**
* Builds and returns a {@link MagnificationConfig}
*/
@NonNull
public MagnificationConfig build() {
MagnificationConfig magnificationConfig = new MagnificationConfig();
magnificationConfig.mMode = mMode;
magnificationConfig.mScale = mScale;
magnificationConfig.mCenterX = mCenterX;
magnificationConfig.mCenterY = mCenterY;
return magnificationConfig;
}
}
/**
* @see Parcelable.Creator
*/
public static final @NonNull Parcelable.Creator<MagnificationConfig> CREATOR =
new Parcelable.Creator<MagnificationConfig>() {
public MagnificationConfig createFromParcel(Parcel parcel) {
return new MagnificationConfig(parcel);
}
public MagnificationConfig[] newArray(int size) {
return new MagnificationConfig[size];
}
};
}

View File

@@ -39,6 +39,7 @@ import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.AccessibilityTrace;
import android.accessibilityservice.IAccessibilityServiceClient;
import android.accessibilityservice.IAccessibilityServiceConnection;
import android.accessibilityservice.MagnificationConfig;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.PendingIntent;
@@ -1101,8 +1102,12 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
try {
MagnificationProcessor magnificationProcessor =
mSystemSupport.getMagnificationProcessor();
return magnificationProcessor
.setScaleAndCenter(displayId, scale, centerX, centerY, animate, mId);
final MagnificationConfig config = new MagnificationConfig.Builder()
.setScale(scale)
.setCenterX(centerX)
.setCenterY(centerY).build();
return magnificationProcessor.setMagnificationConfig(displayId, config, animate,
mId);
} finally {
Binder.restoreCallingIdentity(identity);
}

View File

@@ -84,6 +84,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb
@GuardedBy("mLock")
private int mActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
@GuardedBy("mLock")
private int mLastActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
// Track the active user to reset the magnification and get the associated user settings.
private @UserIdInt int mUserId = UserHandle.USER_SYSTEM;
@GuardedBy("mLock")
@@ -239,6 +241,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
synchronized (mLock) {
mActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
mLastActivatedMode = mActivatedMode;
}
logMagnificationModeWithImeOnIfNeeded();
disableFullScreenMagnificationIfNeeded(displayId);
@@ -276,6 +279,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
synchronized (mLock) {
mActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
mLastActivatedMode = mActivatedMode;
}
logMagnificationModeWithImeOnIfNeeded();
} else {
@@ -297,6 +301,16 @@ public class MagnificationController implements WindowMagnificationManager.Callb
logMagnificationModeWithImeOnIfNeeded();
}
/**
* Returns the last activated magnification mode. If there is no activated magnifier before, it
* returns fullscreen mode by default.
*/
public int getLastActivatedMode() {
synchronized (mLock) {
return mLastActivatedMode;
}
}
/**
* Wrapper method of logging the magnification activated mode and its duration of the usage
* when the magnification is disabled.
@@ -336,6 +350,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
synchronized (mLock) {
fullMagnificationController = mFullScreenMagnificationController;
windowMagnificationManager = mWindowMagnificationMgr;
mLastActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
}
mScaleProvider.onUserChanged(userId);
@@ -462,7 +477,15 @@ public class MagnificationController implements WindowMagnificationManager.Callb
return mTempPoint;
}
private boolean isActivated(int displayId, int mode) {
/**
* Return {@code true} if the specified magnification mode on the given display is activated
* or not.
*
* @param displayId The logical displayId.
* @param mode It's either ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN or
* ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW.
*/
public boolean isActivated(int displayId, int mode) {
boolean isActivated = false;
if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) {
synchronized (mLock) {

View File

@@ -16,6 +16,13 @@
package com.android.server.accessibility.magnification;
import static android.accessibilityservice.MagnificationConfig.DEFAULT_MODE;
import static android.accessibilityservice.MagnificationConfig.FULLSCREEN_MODE;
import static android.accessibilityservice.MagnificationConfig.WINDOW_MODE;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
import android.accessibilityservice.MagnificationConfig;
import android.annotation.NonNull;
import android.graphics.Region;
@@ -23,6 +30,22 @@ import android.graphics.Region;
* Processor class for AccessibilityService connection to control magnification on the specified
* display. This wraps the function of magnification controller.
*
* <p>
* If the magnification config uses {@link DEFAULT_MODE}. This processor will control the current
* activated magnifier on the display. If there is no magnifier activated, it controls
* full-screen magnifier by default.
* </p>
*
* <p>
* If the magnification config uses {@link FULLSCREEN_MODE}. This processor will control
* full-screen magnifier on the display.
* </p>
*
* <p>
* If the magnification config uses {@link WINDOW_MODE}. This processor will control
* the activated window magnifier on the display.
* </p>
*
* @see MagnificationController
* @see FullScreenMagnificationController
*/
@@ -35,53 +58,166 @@ public class MagnificationProcessor {
}
/**
* {@link FullScreenMagnificationController#getScale(int)}
* Gets the magnification config of the display.
*
* @param displayId The logical display id
* @return the magnification config
*/
public @NonNull MagnificationConfig getMagnificationConfig(int displayId) {
final int mode = getControllingMode(displayId);
MagnificationConfig.Builder builder = new MagnificationConfig.Builder();
if (mode == FULLSCREEN_MODE) {
final FullScreenMagnificationController fullScreenMagnificationController =
mController.getFullScreenMagnificationController();
builder.setMode(mode)
.setScale(fullScreenMagnificationController.getScale(displayId))
.setCenterX(fullScreenMagnificationController.getCenterX(displayId))
.setCenterY(fullScreenMagnificationController.getCenterY(displayId));
} else if (mode == WINDOW_MODE) {
final WindowMagnificationManager windowMagnificationManager =
mController.getWindowMagnificationMgr();
builder.setMode(mode)
.setScale(windowMagnificationManager.getScale(displayId))
.setCenterX(windowMagnificationManager.getCenterX(displayId))
.setCenterY(windowMagnificationManager.getCenterY(displayId));
}
return builder.build();
}
/**
* Sets the magnification config of the display. If animation is disabled, the transition
* is immediate.
*
* @param displayId The logical display id
* @param config The magnification config
* @param animate {@code true} to animate from the current config or
* {@code false} to set the config 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 setMagnificationConfig(int displayId, @NonNull MagnificationConfig config,
boolean animate, int id) {
int configMode = config.getMode();
if (configMode == DEFAULT_MODE) {
configMode = getControllingMode(displayId);
}
if (configMode == FULLSCREEN_MODE) {
return setScaleAndCenterForFullScreenMagnification(displayId, config.getScale(),
config.getCenterX(), config.getCenterY(),
animate, id);
} else if (configMode == WINDOW_MODE) {
return mController.getWindowMagnificationMgr().enableWindowMagnification(displayId,
config.getScale(), config.getCenterX(), config.getCenterY());
}
return false;
}
/**
* Returns the magnification scale. If an animation is in progress,
* this reflects the end state of the animation.
*
* @param displayId The logical display id.
* @return the scale
*/
public float getScale(int displayId) {
return mController.getFullScreenMagnificationController().getScale(displayId);
int mode = getControllingMode(displayId);
if (mode == FULLSCREEN_MODE) {
return mController.getFullScreenMagnificationController().getScale(displayId);
} else if (mode == WINDOW_MODE) {
return mController.getWindowMagnificationMgr().getScale(displayId);
}
return 0;
}
/**
* {@link FullScreenMagnificationController#getCenterX(int)}
* Returns the magnification center in X coordinate of the controlling magnification mode.
* If the service can control magnification but fullscreen magnifier is not registered, it will
* register the magnifier for this call then unregister the magnifier finally to make the
* magnification center correct.
*
* @param displayId The logical display id
* @param canControlMagnification Whether the service can control magnification
* @return the X coordinate
*/
public float getCenterX(int displayId, boolean canControlMagnification) {
boolean registeredJustForThisCall = registerMagnificationIfNeeded(displayId,
canControlMagnification);
try {
return mController.getFullScreenMagnificationController().getCenterX(displayId);
} finally {
if (registeredJustForThisCall) {
unregister(displayId);
int mode = getControllingMode(displayId);
if (mode == FULLSCREEN_MODE) {
boolean registeredJustForThisCall = registerDisplayMagnificationIfNeeded(displayId,
canControlMagnification);
try {
return mController.getFullScreenMagnificationController().getCenterX(displayId);
} finally {
if (registeredJustForThisCall) {
unregister(displayId);
}
}
} else if (mode == WINDOW_MODE) {
return mController.getWindowMagnificationMgr().getCenterX(displayId);
}
return 0;
}
/**
* {@link FullScreenMagnificationController#getCenterY(int)}
* Returns the magnification center in Y coordinate of the controlling magnification mode.
* If the service can control magnification but fullscreen magnifier is not registered, it will
* register the magnifier for this call then unregister the magnifier finally to make the
* magnification center correct.
*
* @param displayId The logical display id
* @param canControlMagnification Whether the service can control magnification
* @return the Y coordinate
*/
public float getCenterY(int displayId, boolean canControlMagnification) {
boolean registeredJustForThisCall = registerMagnificationIfNeeded(displayId,
canControlMagnification);
try {
return mController.getFullScreenMagnificationController().getCenterY(displayId);
} finally {
if (registeredJustForThisCall) {
unregister(displayId);
int mode = getControllingMode(displayId);
if (mode == FULLSCREEN_MODE) {
boolean registeredJustForThisCall = registerDisplayMagnificationIfNeeded(displayId,
canControlMagnification);
try {
return mController.getFullScreenMagnificationController().getCenterY(displayId);
} finally {
if (registeredJustForThisCall) {
unregister(displayId);
}
}
} else if (mode == WINDOW_MODE) {
return mController.getWindowMagnificationMgr().getCenterY(displayId);
}
return 0;
}
/**
* {@link FullScreenMagnificationController#getMagnificationRegion(int, Region)}
* Return the magnification bounds of the current controlling magnification on the given
* display. If the magnifier is not enabled, it returns an empty region.
* If the service can control magnification but fullscreen magnifier is not registered, it will
* register the magnifier for this call then unregister the magnifier finally to make
* the magnification region correct.
*
* @param displayId The logical display id
* @param outRegion the region to populate
* @param canControlMagnification Whether the service can control magnification
* @return outRegion the magnification bounds of full-screen magnifier or the magnification
* source bounds of window magnifier
*/
public Region getMagnificationRegion(int displayId, @NonNull Region outRegion,
boolean canControlMagnification) {
boolean registeredJustForThisCall = registerMagnificationIfNeeded(displayId,
int mode = getControllingMode(displayId);
if (mode == FULLSCREEN_MODE) {
getFullscreenMagnificationRegion(displayId, outRegion, canControlMagnification);
} else if (mode == WINDOW_MODE) {
mController.getWindowMagnificationMgr().getMagnificationSourceBounds(displayId,
outRegion);
}
return outRegion;
}
private void getFullscreenMagnificationRegion(int displayId, @NonNull Region outRegion,
boolean canControlMagnification) {
boolean registeredJustForThisCall = registerDisplayMagnificationIfNeeded(displayId,
canControlMagnification);
try {
mController.getFullScreenMagnificationController().getMagnificationRegion(displayId,
outRegion);
return outRegion;
} finally {
if (registeredJustForThisCall) {
unregister(displayId);
@@ -89,67 +225,105 @@ public class MagnificationProcessor {
}
}
/**
* {@link FullScreenMagnificationController#setScaleAndCenter(int, float, float, float, boolean,
* int)}
*/
public boolean setScaleAndCenter(int displayId, float scale, float centerX, float centerY,
private boolean setScaleAndCenterForFullScreenMagnification(int displayId, float scale,
float centerX, float centerY,
boolean animate, int id) {
if (!isRegistered(displayId)) {
register(displayId);
}
return mController.getFullScreenMagnificationController().setScaleAndCenter(displayId,
return mController.getFullScreenMagnificationController().setScaleAndCenter(
displayId,
scale,
centerX, centerY, animate, id);
}
/**
* {@link FullScreenMagnificationController#reset(int, boolean)}
* Resets the magnification on the given display. The reset mode could be full-screen or
* window if it is activated.
*
* @param displayId The logical display id.
* @param animate {@code true} to animate the transition, {@code false}
* to transition immediately
* @return {@code true} if the magnification spec changed, {@code false} if
* the spec did not change
*/
public boolean reset(int displayId, boolean animate) {
return mController.getFullScreenMagnificationController().reset(displayId, animate);
int mode = getControllingMode(displayId);
if (mode == FULLSCREEN_MODE) {
return mController.getFullScreenMagnificationController().reset(displayId, animate);
} else if (mode == WINDOW_MODE) {
return mController.getWindowMagnificationMgr().reset(displayId);
}
return false;
}
/**
* {@link FullScreenMagnificationController#resetIfNeeded(int, boolean)}
*/
// TODO: support window magnification
public void resetAllIfNeeded(int connectionId) {
mController.getFullScreenMagnificationController().resetAllIfNeeded(connectionId);
}
/**
* {@link FullScreenMagnificationController#register(int)}
*/
public void register(int displayId) {
mController.getFullScreenMagnificationController().register(displayId);
}
/**
* {@link FullScreenMagnificationController#unregister(int)} (int)}
*/
public void unregister(int displayId) {
mController.getFullScreenMagnificationController().unregister(displayId);
}
/**
* {@link FullScreenMagnificationController#isMagnifying(int)}
* {@link WindowMagnificationManager#isWindowMagnifierEnabled(int)}
*/
public boolean isMagnifying(int displayId) {
return mController.getFullScreenMagnificationController().isMagnifying(displayId);
int mode = getControllingMode(displayId);
if (mode == FULLSCREEN_MODE) {
return mController.getFullScreenMagnificationController().isMagnifying(displayId);
} else if (mode == WINDOW_MODE) {
return mController.getWindowMagnificationMgr().isWindowMagnifierEnabled(displayId);
}
return false;
}
/**
* {@link FullScreenMagnificationController#isRegistered(int)}
* Returns the current controlling magnification mode on the given display.
* If there is no magnifier activated, it fallbacks to the last activated mode.
* And the last activated mode is {@link FULLSCREEN_MODE} by default.
*
* @param displayId The logical display id
*/
public boolean isRegistered(int displayId) {
return mController.getFullScreenMagnificationController().isRegistered(displayId);
public int getControllingMode(int displayId) {
if (mController.isActivated(displayId,
ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW)) {
return WINDOW_MODE;
} else if (mController.isActivated(displayId,
ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN)) {
return FULLSCREEN_MODE;
} else {
return (mController.getLastActivatedMode() == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW)
? WINDOW_MODE
: FULLSCREEN_MODE;
}
}
private boolean registerMagnificationIfNeeded(int displayId, boolean canControlMagnification) {
private boolean registerDisplayMagnificationIfNeeded(int displayId,
boolean canControlMagnification) {
if (!isRegistered(displayId) && canControlMagnification) {
register(displayId);
return true;
}
return false;
}
private boolean isRegistered(int displayId) {
return mController.getFullScreenMagnificationController().isRegistered(displayId);
}
/**
* {@link FullScreenMagnificationController#register(int)}
*/
private void register(int displayId) {
mController.getFullScreenMagnificationController().register(displayId);
}
/**
* {@link FullScreenMagnificationController#unregister(int)} (int)}
*/
private void unregister(int displayId) {
mController.getFullScreenMagnificationController().unregister(displayId);
}
}

View File

@@ -27,6 +27,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
@@ -271,9 +272,12 @@ public class WindowMagnificationManager implements
* or {@link Float#NaN} to leave unchanged.
* @param centerY The screen-relative Y coordinate around which to center,
* or {@link Float#NaN} to leave unchanged.
* @return {@code true} if the magnification is enabled successfully.
*/
void enableWindowMagnification(int displayId, float scale, float centerX, float centerY) {
enableWindowMagnification(displayId, scale, centerX, centerY, STUB_ANIMATION_CALLBACK);
public boolean enableWindowMagnification(int displayId, float scale, float centerX,
float centerY) {
return enableWindowMagnification(displayId, scale, centerX, centerY,
STUB_ANIMATION_CALLBACK);
}
/**
@@ -287,25 +291,29 @@ public class WindowMagnificationManager implements
* @param centerY The screen-relative Y coordinate around which to center,
* or {@link Float#NaN} to leave unchanged.
* @param animationCallback Called when the animation result is valid.
* @return {@code true} if the magnification is enabled successfully.
*/
void enableWindowMagnification(int displayId, float scale, float centerX, float centerY,
@Nullable MagnificationAnimationCallback animationCallback) {
public boolean enableWindowMagnification(int displayId, float scale, float centerX,
float centerY, @Nullable MagnificationAnimationCallback animationCallback) {
final boolean enabled;
boolean previousEnabled;
synchronized (mLock) {
if (mConnectionWrapper == null) {
return;
return false;
}
WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
if (magnifier == null) {
magnifier = createWindowMagnifier(displayId);
}
previousEnabled = magnifier.mEnabled;
enabled = magnifier.enableWindowMagnificationInternal(scale, centerX, centerY,
animationCallback);
}
if (enabled) {
if (enabled && !previousEnabled) {
mCallback.onWindowMagnificationActivationState(displayId, true);
}
return enabled;
}
/**
@@ -464,7 +472,7 @@ public class WindowMagnificationManager implements
* @param displayId The logical display id
* @return the X coordinate. {@link Float#NaN} if the window magnification is not enabled.
*/
float getCenterX(int displayId) {
public float getCenterX(int displayId) {
synchronized (mLock) {
WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
if (magnifier == null) {
@@ -480,7 +488,7 @@ public class WindowMagnificationManager implements
* @param displayId The logical display id
* @return the Y coordinate. {@link Float#NaN} if the window magnification is not enabled.
*/
float getCenterY(int displayId) {
public float getCenterY(int displayId) {
synchronized (mLock) {
WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
if (magnifier == null) {
@@ -490,6 +498,42 @@ public class WindowMagnificationManager implements
}
}
/**
* Populates magnified bounds on the screen. And the populated magnified bounds would be
* empty If window magnifier is not activated.
*
* @param displayId The logical display id.
* @param outRegion the region to populate
*/
public void getMagnificationSourceBounds(int displayId, @NonNull Region outRegion) {
synchronized (mLock) {
WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
if (magnifier == null) {
outRegion.setEmpty();
} else {
outRegion.set(magnifier.mSourceBounds);
}
}
}
/**
* Resets the magnification scale and center.
*
* @param displayId The logical display id.
* @return {@code true} if the magnification spec changed, {@code false} if
* the spec did not change
*/
public boolean reset(int displayId) {
synchronized (mLock) {
WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
if (magnifier == null) {
return false;
}
magnifier.reset();
return true;
}
}
/**
* Creates the windowMagnifier based on the specified display and stores it.
*
@@ -626,8 +670,9 @@ public class WindowMagnificationManager implements
@GuardedBy("mLock")
boolean enableWindowMagnificationInternal(float scale, float centerX, float centerY,
@Nullable MagnificationAnimationCallback animationCallback) {
if (mEnabled) {
return false;
// Handle defaults. The scale may be NAN when just updating magnification center.
if (Float.isNaN(scale)) {
scale = getScale();
}
final float normScale = MagnificationScaleProvider.constrainScale(scale);
if (mWindowMagnificationManager.enableWindowMagnificationInternal(mDisplayId, normScale,

View File

@@ -68,6 +68,7 @@ import static org.mockito.Mockito.when;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.AccessibilityTrace;
import android.accessibilityservice.IAccessibilityServiceClient;
import android.accessibilityservice.MagnificationConfig;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -650,8 +651,12 @@ public class AbstractAccessibilityServiceConnectionTest {
final float scale = 1.8f;
final float centerX = 50.5f;
final float centerY = 100.5f;
when(mMockMagnificationProcessor.setScaleAndCenter(displayId,
scale, centerX, centerY, true, SERVICE_ID)).thenReturn(true);
MagnificationConfig config = new MagnificationConfig.Builder()
.setScale(scale)
.setCenterX(centerX)
.setCenterY(centerY).build();
when(mMockMagnificationProcessor.setMagnificationConfig(displayId, config, true,
SERVICE_ID)).thenReturn(true);
when(mMockSecurityPolicy.canControlMagnification(mServiceConnection)).thenReturn(false);
final boolean result = mServiceConnection.setMagnificationScaleAndCenter(
@@ -665,8 +670,12 @@ public class AbstractAccessibilityServiceConnectionTest {
final float scale = 1.8f;
final float centerX = 50.5f;
final float centerY = 100.5f;
when(mMockMagnificationProcessor.setScaleAndCenter(displayId,
scale, centerX, centerY, true, SERVICE_ID)).thenReturn(true);
MagnificationConfig config = new MagnificationConfig.Builder()
.setScale(scale)
.setCenterX(centerX)
.setCenterY(centerY).build();
when(mMockMagnificationProcessor.setMagnificationConfig(displayId, config, true,
SERVICE_ID)).thenReturn(true);
when(mMockSystemSupport.getCurrentUserIdLocked()).thenReturn(USER_ID2);
final boolean result = mServiceConnection.setMagnificationScaleAndCenter(

View File

@@ -16,25 +16,32 @@
package com.android.server.accessibility;
import static android.accessibilityservice.MagnificationConfig.FULLSCREEN_MODE;
import static android.accessibilityservice.MagnificationConfig.WINDOW_MODE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.accessibilityservice.MagnificationConfig;
import android.graphics.Region;
import com.android.server.accessibility.magnification.FullScreenMagnificationController;
import com.android.server.accessibility.magnification.MagnificationController;
import com.android.server.accessibility.magnification.MagnificationProcessor;
import com.android.server.accessibility.magnification.WindowMagnificationManager;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
/**
* Tests for the {@link MagnificationProcessor}
@@ -42,57 +49,115 @@ import org.mockito.MockitoAnnotations;
public class MagnificationProcessorTest {
private static final int TEST_DISPLAY = 0;
private static final int SERVICE_ID = 42;
private static final float TEST_SCALE = 1.8f;
private static final float TEST_CENTER_X = 50.5f;
private static final float TEST_CENTER_Y = 100.5f;
private MagnificationProcessor mMagnificationProcessor;
@Mock
private MagnificationController mMockMagnificationController;
@Mock
private FullScreenMagnificationController mMockFullScreenMagnificationController;
@Mock
private WindowMagnificationManager mMockWindowMagnificationManager;
FullScreenMagnificationControllerStub mFullScreenMagnificationControllerStub;
WindowMagnificationManagerStub mWindowMagnificationManagerStub;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mFullScreenMagnificationControllerStub = new FullScreenMagnificationControllerStub(
mMockFullScreenMagnificationController);
mWindowMagnificationManagerStub = new WindowMagnificationManagerStub(
mMockWindowMagnificationManager);
when(mMockMagnificationController.getFullScreenMagnificationController()).thenReturn(
mMockFullScreenMagnificationController);
when(mMockMagnificationController.getWindowMagnificationMgr()).thenReturn(
mMockWindowMagnificationManager);
mMagnificationProcessor = new MagnificationProcessor(mMockMagnificationController);
}
@Test
public void getScale() {
final float result = 2;
when(mMockFullScreenMagnificationController.getScale(TEST_DISPLAY)).thenReturn(result);
public void getScale_fullscreenMode_expectedValue() {
final MagnificationConfig config = new MagnificationConfig.Builder()
.setMode(FULLSCREEN_MODE)
.setScale(TEST_SCALE).build();
setMagnificationActivated(TEST_DISPLAY, config);
float scale = mMagnificationProcessor.getScale(TEST_DISPLAY);
assertEquals(scale, result, 0);
assertEquals(scale, TEST_SCALE, 0);
}
@Test
public void getCenterX_canControlMagnification_returnCenterX() {
final float result = 200;
when(mMockFullScreenMagnificationController.getCenterX(TEST_DISPLAY)).thenReturn(result);
public void getScale_windowMode_expectedValue() {
final MagnificationConfig config = new MagnificationConfig.Builder()
.setMode(WINDOW_MODE)
.setScale(TEST_SCALE).build();
setMagnificationActivated(TEST_DISPLAY, config);
float scale = mMagnificationProcessor.getScale(TEST_DISPLAY);
assertEquals(scale, TEST_SCALE, 0);
}
@Test
public void getCenterX_canControlFullscreenMagnification_returnCenterX() {
final MagnificationConfig config = new MagnificationConfig.Builder()
.setMode(FULLSCREEN_MODE)
.setCenterX(TEST_CENTER_X).build();
setMagnificationActivated(TEST_DISPLAY, config);
float centerX = mMagnificationProcessor.getCenterX(
TEST_DISPLAY, /* canControlMagnification= */true);
assertEquals(centerX, result, 0);
assertEquals(centerX, TEST_CENTER_X, 0);
}
@Test
public void getCenterY_canControlMagnification_returnCenterY() {
final float result = 300;
when(mMockFullScreenMagnificationController.getCenterY(TEST_DISPLAY)).thenReturn(result);
public void getCenterX_canControlWindowMagnification_returnCenterX() {
final MagnificationConfig config = new MagnificationConfig.Builder()
.setMode(WINDOW_MODE)
.setCenterX(TEST_CENTER_X).build();
setMagnificationActivated(TEST_DISPLAY, config);
float centerX = mMagnificationProcessor.getCenterX(
TEST_DISPLAY, /* canControlMagnification= */true);
assertEquals(centerX, TEST_CENTER_X, 0);
}
@Test
public void getCenterY_canControlFullscreenMagnification_returnCenterY() {
final MagnificationConfig config = new MagnificationConfig.Builder()
.setMode(FULLSCREEN_MODE)
.setCenterY(TEST_CENTER_Y).build();
setMagnificationActivated(TEST_DISPLAY, config);
float centerY = mMagnificationProcessor.getCenterY(
TEST_DISPLAY, /* canControlMagnification= */false);
assertEquals(centerY, result, 0);
assertEquals(centerY, TEST_CENTER_Y, 0);
}
@Test
public void getMagnificationRegion_canControlMagnification_returnRegion() {
public void getCenterY_canControlWindowMagnification_returnCenterY() {
final MagnificationConfig config = new MagnificationConfig.Builder()
.setMode(WINDOW_MODE)
.setCenterY(TEST_CENTER_Y).build();
setMagnificationActivated(TEST_DISPLAY, config);
float centerY = mMagnificationProcessor.getCenterY(
TEST_DISPLAY, /* canControlMagnification= */false);
assertEquals(centerY, TEST_CENTER_Y, 0);
}
@Test
public void getMagnificationRegion_canControlFullscreenMagnification_returnRegion() {
final Region region = new Region(10, 20, 100, 200);
setMagnificationActivated(TEST_DISPLAY, FULLSCREEN_MODE);
mMagnificationProcessor.getMagnificationRegion(TEST_DISPLAY,
region, /* canControlMagnification= */true);
@@ -101,14 +166,25 @@ public class MagnificationProcessorTest {
}
@Test
public void getMagnificationRegion_notRegistered_shouldRegisterThenUnregister() {
public void getMagnificationRegion_canControlWindowMagnification_returnRegion() {
final Region region = new Region(10, 20, 100, 200);
setMagnificationActivated(TEST_DISPLAY, WINDOW_MODE);
mMagnificationProcessor.getMagnificationRegion(TEST_DISPLAY,
region, /* canControlMagnification= */true);
verify(mMockWindowMagnificationManager).getMagnificationSourceBounds(eq(TEST_DISPLAY),
eq(region));
}
@Test
public void getMagnificationRegion_fullscreenModeNotRegistered_shouldRegisterThenUnregister() {
final Region region = new Region(10, 20, 100, 200);
setMagnificationActivated(TEST_DISPLAY, FULLSCREEN_MODE);
doAnswer((invocation) -> {
((Region) invocation.getArguments()[1]).set(region);
return null;
}).when(mMockFullScreenMagnificationController).getMagnificationRegion(eq(TEST_DISPLAY),
any());
when(mMockFullScreenMagnificationController.isRegistered(TEST_DISPLAY)).thenReturn(false);
final Region result = new Region();
mMagnificationProcessor.getMagnificationRegion(TEST_DISPLAY,
@@ -119,44 +195,242 @@ public class MagnificationProcessorTest {
}
@Test
public void getMagnificationCenterX_notRegistered_shouldRegisterThenUnregister() {
final float centerX = 480.0f;
when(mMockFullScreenMagnificationController.getCenterX(TEST_DISPLAY)).thenReturn(centerX);
when(mMockFullScreenMagnificationController.isRegistered(TEST_DISPLAY)).thenReturn(false);
public void getMagnificationCenterX_fullscreenModeNotRegistered_shouldRegisterThenUnregister() {
final MagnificationConfig config = new MagnificationConfig.Builder()
.setMode(FULLSCREEN_MODE)
.setCenterX(TEST_CENTER_X).build();
setMagnificationActivated(TEST_DISPLAY, config);
final float result = mMagnificationProcessor.getCenterX(
TEST_DISPLAY, /* canControlMagnification= */ true);
assertEquals(centerX, result, 0);
assertEquals(TEST_CENTER_X, result, 0);
verify(mMockFullScreenMagnificationController).register(TEST_DISPLAY);
verify(mMockFullScreenMagnificationController).unregister(TEST_DISPLAY);
}
@Test
public void getMagnificationCenterY_notRegistered_shouldRegisterThenUnregister() {
final float centerY = 640.0f;
when(mMockFullScreenMagnificationController.getCenterY(TEST_DISPLAY)).thenReturn(centerY);
when(mMockFullScreenMagnificationController.isRegistered(TEST_DISPLAY)).thenReturn(false);
public void getMagnificationCenterY_fullscreenModeNotRegistered_shouldRegisterThenUnregister() {
final MagnificationConfig config = new MagnificationConfig.Builder()
.setMode(FULLSCREEN_MODE)
.setCenterY(TEST_CENTER_Y).build();
setMagnificationActivated(TEST_DISPLAY, config);
final float result = mMagnificationProcessor.getCenterY(
TEST_DISPLAY, /* canControlMagnification= */ true);
assertEquals(centerY, result, 0);
assertEquals(TEST_CENTER_Y, result, 0);
verify(mMockFullScreenMagnificationController).register(TEST_DISPLAY);
verify(mMockFullScreenMagnificationController).unregister(TEST_DISPLAY);
}
@Test
public void setMagnificationScaleAndCenter_notRegistered_shouldRegister() {
final int serviceId = 42;
final float scale = 1.8f;
final float centerX = 50.5f;
final float centerY = 100.5f;
when(mMockFullScreenMagnificationController.setScaleAndCenter(TEST_DISPLAY,
scale, centerX, centerY, true, serviceId)).thenReturn(true);
when(mMockFullScreenMagnificationController.isRegistered(TEST_DISPLAY)).thenReturn(false);
public void getCurrentMode_configDefaultMode_returnActivatedMode() {
final int targetMode = WINDOW_MODE;
setMagnificationActivated(TEST_DISPLAY, targetMode);
final boolean result = mMagnificationProcessor.setScaleAndCenter(
TEST_DISPLAY, scale, centerX, centerY, true, serviceId);
int currentMode = mMagnificationProcessor.getControllingMode(TEST_DISPLAY);
assertEquals(WINDOW_MODE, currentMode);
}
@Test
public void reset_fullscreenMagnificationActivated() {
setMagnificationActivated(TEST_DISPLAY, FULLSCREEN_MODE);
mMagnificationProcessor.reset(TEST_DISPLAY, /* animate= */false);
verify(mMockFullScreenMagnificationController).reset(TEST_DISPLAY, false);
}
@Test
public void reset_windowMagnificationActivated() {
setMagnificationActivated(TEST_DISPLAY, WINDOW_MODE);
mMagnificationProcessor.reset(TEST_DISPLAY, /* animate= */false);
verify(mMockWindowMagnificationManager).reset(TEST_DISPLAY);
}
@Test
public void setMagnificationConfig_fullscreenModeNotRegistered_shouldRegister() {
final MagnificationConfig config = new MagnificationConfig.Builder()
.setMode(FULLSCREEN_MODE)
.setScale(TEST_SCALE)
.setCenterX(TEST_CENTER_X)
.setCenterY(TEST_CENTER_Y).build();
setMagnificationActivated(TEST_DISPLAY, config);
final boolean result = mMagnificationProcessor.setMagnificationConfig(
TEST_DISPLAY, config, true, SERVICE_ID);
assertTrue(result);
verify(mMockFullScreenMagnificationController).register(TEST_DISPLAY);
}
@Test
public void setMagnificationConfig_windowMode_enableMagnification() {
final MagnificationConfig config = new MagnificationConfig.Builder()
.setMode(WINDOW_MODE)
.setScale(TEST_SCALE)
.setCenterX(TEST_CENTER_X)
.setCenterY(TEST_CENTER_Y).build();
setMagnificationActivated(TEST_DISPLAY, config);
final boolean result = mMagnificationProcessor.setMagnificationConfig(
TEST_DISPLAY, config, true, SERVICE_ID);
assertTrue(result);
}
@Test
public void setMagnificationConfig_fullscreenEnabled_expectedConfigValues() {
final MagnificationConfig config = new MagnificationConfig.Builder()
.setMode(FULLSCREEN_MODE)
.setScale(TEST_SCALE)
.setCenterX(TEST_CENTER_X)
.setCenterY(TEST_CENTER_Y).build();
setMagnificationActivated(TEST_DISPLAY, config);
// mMockFullScreenMagnificationController.unregister(TEST_DISPLAY);
mMagnificationProcessor.setMagnificationConfig(
TEST_DISPLAY, config, true, SERVICE_ID);
final MagnificationConfig result = mMagnificationProcessor.getMagnificationConfig(
TEST_DISPLAY);
assertConfigEquals(config, result);
}
@Test
public void setMagnificationConfig_windowEnabled_expectedConfigValues() {
final MagnificationConfig config = new MagnificationConfig.Builder()
.setMode(WINDOW_MODE)
.setScale(TEST_SCALE)
.setCenterX(TEST_CENTER_X)
.setCenterY(TEST_CENTER_Y).build();
setMagnificationActivated(TEST_DISPLAY, config);
mMagnificationProcessor.setMagnificationConfig(
TEST_DISPLAY, config, true, SERVICE_ID);
final MagnificationConfig result = mMagnificationProcessor.getMagnificationConfig(
TEST_DISPLAY);
assertConfigEquals(config, result);
}
private void setMagnificationActivated(int displayId, int configMode) {
setMagnificationActivated(displayId,
new MagnificationConfig.Builder().setMode(configMode).build());
}
private void setMagnificationActivated(int displayId, MagnificationConfig config) {
when(mMockMagnificationController.isActivated(displayId, config.getMode())).thenReturn(
true);
mMagnificationProcessor.setMagnificationConfig(displayId, config, false, SERVICE_ID);
if (config.getMode() == FULLSCREEN_MODE) {
when(mMockMagnificationController.isActivated(displayId, WINDOW_MODE)).thenReturn(
false);
mFullScreenMagnificationControllerStub.resetAndStubMethods();
mMockFullScreenMagnificationController.setScaleAndCenter(displayId, config.getScale(),
config.getCenterX(), config.getCenterY(), true, SERVICE_ID);
} else if (config.getMode() == WINDOW_MODE) {
when(mMockMagnificationController.isActivated(displayId, FULLSCREEN_MODE)).thenReturn(
false);
mWindowMagnificationManagerStub.resetAndStubMethods();
mMockWindowMagnificationManager.enableWindowMagnification(displayId, config.getScale(),
config.getCenterX(), config.getCenterY());
}
}
private void assertConfigEquals(MagnificationConfig expected, MagnificationConfig actual) {
assertEquals(expected.getMode(), actual.getMode());
assertEquals(expected.getScale(), actual.getScale(), 0);
assertEquals(expected.getCenterX(), actual.getCenterX(), 0);
assertEquals(expected.getCenterY(), actual.getCenterY(), 0);
}
private static class FullScreenMagnificationControllerStub {
private final FullScreenMagnificationController mScreenMagnificationController;
private float mScale = 1.0f;
private float mCenterX = 0;
private float mCenterY = 0;
private boolean mIsRegistered = false;
FullScreenMagnificationControllerStub(
FullScreenMagnificationController screenMagnificationController) {
mScreenMagnificationController = screenMagnificationController;
}
private void stubMethods() {
doAnswer(invocation -> mScale).when(mScreenMagnificationController).getScale(
TEST_DISPLAY);
doAnswer(invocation -> mCenterX).when(mScreenMagnificationController).getCenterX(
TEST_DISPLAY);
doAnswer(invocation -> mCenterY).when(mScreenMagnificationController).getCenterY(
TEST_DISPLAY);
doAnswer(invocation -> mIsRegistered).when(mScreenMagnificationController).isRegistered(
TEST_DISPLAY);
Answer enableMagnificationStubAnswer = invocation -> {
mScale = invocation.getArgument(1);
mCenterX = invocation.getArgument(2);
mCenterY = invocation.getArgument(3);
return true;
};
doAnswer(enableMagnificationStubAnswer).when(
mScreenMagnificationController).setScaleAndCenter(eq(TEST_DISPLAY), anyFloat(),
anyFloat(), anyFloat(), eq(true), eq(SERVICE_ID));
Answer registerStubAnswer = invocation -> {
mIsRegistered = true;
return true;
};
doAnswer(registerStubAnswer).when(
mScreenMagnificationController).register(eq(TEST_DISPLAY));
Answer unregisterStubAnswer = invocation -> {
mIsRegistered = false;
return true;
};
doAnswer(unregisterStubAnswer).when(
mScreenMagnificationController).unregister(eq(TEST_DISPLAY));
}
public void resetAndStubMethods() {
Mockito.reset(mScreenMagnificationController);
stubMethods();
}
}
private static class WindowMagnificationManagerStub {
private final WindowMagnificationManager mWindowMagnificationManager;
private float mScale = 1.0f;
private float mCenterX = 0;
private float mCenterY = 0;
WindowMagnificationManagerStub(
WindowMagnificationManager windowMagnificationManager) {
mWindowMagnificationManager = windowMagnificationManager;
}
private void stubMethods() {
doAnswer(invocation -> mScale).when(mWindowMagnificationManager).getScale(
TEST_DISPLAY);
doAnswer(invocation -> mCenterX).when(mWindowMagnificationManager).getCenterX(
TEST_DISPLAY);
doAnswer(invocation -> mCenterY).when(mWindowMagnificationManager).getCenterY(
TEST_DISPLAY);
Answer enableWindowMagnificationStubAnswer = invocation -> {
mScale = invocation.getArgument(1);
mCenterX = invocation.getArgument(2);
mCenterY = invocation.getArgument(3);
return true;
};
doAnswer(enableWindowMagnificationStubAnswer).when(
mWindowMagnificationManager).enableWindowMagnification(eq(TEST_DISPLAY),
anyFloat(), anyFloat(), anyFloat());
}
public void resetAndStubMethods() {
Mockito.reset(mWindowMagnificationManager);
stubMethods();
}
}
}

View File

@@ -376,6 +376,17 @@ public class WindowMagnificationManagerTest {
verify(mContext).unregisterReceiver(any(BroadcastReceiver.class));
}
@Test
public void resetMagnification_enabled_windowMagnifierDisabled() {
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
mWindowMagnificationManager.reset(TEST_DISPLAY);
assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
}
@Test
public void onScreenOff_windowMagnifierIsEnabled_removeButtonAndDisableWindowMagnification()
throws RemoteException {