From b0fecc88ec82487b15006f44ef865296785dfa07 Mon Sep 17 00:00:00 2001 From: Candice Lo Date: Fri, 10 Nov 2023 07:24:29 +0000 Subject: refactor(magnification): Renaming WindowMagnificationManager class as MagnificationConnectionManager The class WindowMagnificationManager handles stuffs more than magnification window mode. Therefore, we would like to rename the class to improve the readability of our codebase and avoid confusion. Since the class targets at managing the magnification connection operations, we will name it MagnificationConnectionManager. Bug: 310109308 Test: manually. Renaming the class atest MagnificationProcessorTest atest MagnificationControllerTest atest MagnificationConnectionManagerTest atest WindowMagnificationGestureHandlerTest atest AccessibilityManagerServiceTest Flag: NA Change-Id: Ie4d53ba63aa6d6cadf4cf455f1ece534a54cad0a --- .../accessibility/AccessibilityInputFilter.java | 2 +- .../accessibility/AccessibilityManagerService.java | 18 +- .../MagnificationConnectionManager.java | 1316 ++++++++++++++++++++ .../magnification/MagnificationController.java | 115 +- .../magnification/MagnificationProcessor.java | 38 +- .../WindowMagnificationGestureHandler.java | 52 +- .../magnification/WindowMagnificationManager.java | 1300 ------------------- .../AccessibilityManagerServiceTest.java | 30 +- .../accessibility/MagnificationProcessorTest.java | 58 +- .../MagnificationConnectionManagerTest.java | 854 +++++++++++++ .../MagnificationConnectionWrapperTest.java | 2 +- .../magnification/MagnificationControllerTest.java | 153 +-- .../WindowMagnificationGestureHandlerTest.java | 23 +- .../WindowMagnificationManagerTest.java | 847 ------------- 14 files changed, 2426 insertions(+), 2382 deletions(-) create mode 100644 services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java delete mode 100644 services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java create mode 100644 services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java delete mode 100644 services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java index 74538ac02289..6cac6a47c77b 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java @@ -668,7 +668,7 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo final Context uiContext = displayContext.createWindowContext( TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, null /* options */); magnificationGestureHandler = new WindowMagnificationGestureHandler(uiContext, - mAms.getWindowMagnificationMgr(), mAms.getTraceManager(), + mAms.getMagnificationConnectionManager(), mAms.getTraceManager(), mAms.getMagnificationController(), detectControlGestures, detectTwoFingerTripleTap, diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index b5e8c849517b..2186a82f3267 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -158,10 +158,10 @@ import com.android.internal.util.Preconditions; import com.android.server.AccessibilityManagerInternal; import com.android.server.LocalServices; import com.android.server.SystemService; +import com.android.server.accessibility.magnification.MagnificationConnectionManager; import com.android.server.accessibility.magnification.MagnificationController; import com.android.server.accessibility.magnification.MagnificationProcessor; import com.android.server.accessibility.magnification.MagnificationScaleProvider; -import com.android.server.accessibility.magnification.WindowMagnificationManager; import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.pm.UserManagerInternal; import com.android.server.policy.WindowManagerPolicy; @@ -3442,7 +3442,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub && (userState.getMagnificationCapabilitiesLocked() != Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) || userHasMagnificationServicesLocked(userState); - getWindowMagnificationMgr().requestConnection(connect); + getMagnificationConnectionManager().requestConnection(connect); } /** @@ -4122,17 +4122,17 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mSecurityPolicy.enforceCallingOrSelfPermission( android.Manifest.permission.STATUS_BAR_SERVICE); - getWindowMagnificationMgr().setConnection(connection); + getMagnificationConnectionManager().setConnection(connection); } /** - * Getter of {@link WindowMagnificationManager}. + * Getter of {@link MagnificationConnectionManager}. * - * @return WindowMagnificationManager + * @return MagnificationManager */ - public WindowMagnificationManager getWindowMagnificationMgr() { + public MagnificationConnectionManager getMagnificationConnectionManager() { synchronized (mLock) { - return mMagnificationController.getWindowMagnificationMgr(); + return mMagnificationController.getMagnificationConnectionManager(); } } @@ -4423,7 +4423,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub pw.println(); } pw.append("hasWindowMagnificationConnection=").append( - String.valueOf(getWindowMagnificationMgr().isConnected())); + String.valueOf(getMagnificationConnectionManager().isConnected())); pw.println(); mMagnificationProcessor.dump(pw, getValidDisplayList()); final int userCount = mUserStates.size(); @@ -5144,7 +5144,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub for (int i = 0; i < displays.size(); i++) { final int displayId = displays.get(i).getDisplayId(); - getWindowMagnificationMgr().removeMagnificationButton(displayId); + getMagnificationConnectionManager().removeMagnificationButton(displayId); } } } diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java new file mode 100644 index 000000000000..975b3d5eb91a --- /dev/null +++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java @@ -0,0 +1,1316 @@ +/* + * Copyright (C) 2019 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.magnification; + +import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MAGNIFICATION_CONNECTION; +import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK; +import static android.view.accessibility.MagnificationAnimationCallback.STUB_ANIMATION_CALLBACK; + +import static com.android.server.accessibility.AccessibilityManagerService.INVALID_SERVICE_ID; +import static com.android.server.accessibility.AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.graphics.PointF; +import android.graphics.Rect; +import android.graphics.Region; +import android.os.Binder; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.SystemClock; +import android.util.MathUtils; +import android.util.Slog; +import android.util.SparseArray; +import android.util.SparseBooleanArray; +import android.view.MotionEvent; +import android.view.accessibility.IWindowMagnificationConnection; +import android.view.accessibility.IWindowMagnificationConnectionCallback; +import android.view.accessibility.MagnificationAnimationCallback; + +import com.android.internal.accessibility.common.MagnificationConstants; +import com.android.internal.accessibility.util.AccessibilityStatsLogUtils; +import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; +import com.android.server.LocalServices; +import com.android.server.accessibility.AccessibilityTraceManager; +import com.android.server.statusbar.StatusBarManagerInternal; +import com.android.server.wm.WindowManagerInternal; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.concurrent.atomic.AtomicLongFieldUpdater; + +/** + * A class to manipulate magnification through {@link MagnificationConnectionWrapper} + * create by {@link #setConnection(IWindowMagnificationConnection)}. To set the connection with + * SysUI, call {@code StatusBarManagerInternal#requestWindowMagnificationConnection(boolean)}. + * The applied magnification scale is constrained by + * {@link MagnificationScaleProvider#constrainScale(float)} + */ +public class MagnificationConnectionManager implements + PanningScalingHandler.MagnificationDelegate, + WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks { + + private static final boolean DBG = false; + + private static final String TAG = "MagnificationConnectionManager"; + + /** + * Indicate that the magnification window is at the magnification center. + */ + public static final int WINDOW_POSITION_AT_CENTER = 0; + + /** + * Indicate that the magnification window is at the top-left side of the magnification + * center. The offset is equal to a half of MirrorSurfaceView. So, the bottom-right corner + * of the window is at the magnification center. + */ + public static final int WINDOW_POSITION_AT_TOP_LEFT = 1; + + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "WINDOW_POSITION_AT_" }, value = { + WINDOW_POSITION_AT_CENTER, + WINDOW_POSITION_AT_TOP_LEFT + }) + public @interface WindowPosition {} + + /** Window magnification connection is connecting. */ + private static final int CONNECTING = 0; + /** Window magnification connection is connected. */ + private static final int CONNECTED = 1; + /** Window magnification connection is disconnecting. */ + private static final int DISCONNECTING = 2; + /** Window magnification connection is disconnected. */ + private static final int DISCONNECTED = 3; + + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"CONNECTION_STATE"}, value = { + CONNECTING, + CONNECTED, + DISCONNECTING, + DISCONNECTED + }) + private @interface ConnectionState { + } + + private static String connectionStateToString(@ConnectionState int state) { + switch (state) { + case CONNECTING: return "CONNECTING"; + case CONNECTED: return "CONNECTED"; + case DISCONNECTING: return "DISCONNECTING"; + case DISCONNECTED: return "DISCONNECTED"; + default: + return "UNKNOWN:" + state; + } + } + + @ConnectionState + private int mConnectionState = DISCONNECTED; + + private static final int WAIT_CONNECTION_TIMEOUT_MILLIS = 100; + + private final Object mLock; + private final Context mContext; + @VisibleForTesting + @GuardedBy("mLock") + @Nullable + MagnificationConnectionWrapper mConnectionWrapper; + @GuardedBy("mLock") + private ConnectionCallback mConnectionCallback; + @GuardedBy("mLock") + private SparseArray mWindowMagnifiers = new SparseArray<>(); + // Whether the following typing focus feature for magnification is enabled. + private boolean mMagnificationFollowTypingEnabled = true; + @GuardedBy("mLock") + private final SparseBooleanArray mIsImeVisibleArray = new SparseBooleanArray(); + @GuardedBy("mLock") + private final SparseArray mLastActivatedScale = new SparseArray<>(); + + private boolean mReceiverRegistered = false; + @VisibleForTesting + protected final BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final int displayId = context.getDisplayId(); + removeMagnificationButton(displayId); + disableWindowMagnification(displayId, false, null); + } + }; + + /** + * Callback to handle magnification actions from system UI. + */ + public interface Callback { + + /** + * Called when the accessibility action of scale requests to be performed. + * It is invoked from System UI. And the action is provided by the mirror window. + * + * @param displayId The logical display id. + * @param scale the target scale, or {@link Float#NaN} to leave unchanged + * @param updatePersistence whether the scale should be persisted + */ + void onPerformScaleAction(int displayId, float scale, boolean updatePersistence); + + /** + * Called when the accessibility action is performed. + * + * @param displayId The logical display id. + */ + void onAccessibilityActionPerformed(int displayId); + + /** + * Called when the state of the magnification activation is changed. + * + * @param displayId The logical display id. + * @param activated {@code true} if the magnification is activated, otherwise {@code false}. + */ + void onWindowMagnificationActivationState(int displayId, boolean activated); + + /** + * Called when the magnification source bounds are changed. + * + * @param displayId The logical display id. + * @param bounds The magnified source bounds on the display. + */ + void onSourceBoundsChanged(int displayId, Rect bounds); + + /** + * Called from {@link IWindowMagnificationConnection} to request changing the magnification + * mode on the given display. + * + * @param displayId the logical display id + * @param magnificationMode the target magnification mode + */ + void onChangeMagnificationMode(int displayId, int magnificationMode); + } + + private final Callback mCallback; + private final AccessibilityTraceManager mTrace; + private final MagnificationScaleProvider mScaleProvider; + + public MagnificationConnectionManager(Context context, Object lock, @NonNull Callback callback, + AccessibilityTraceManager trace, MagnificationScaleProvider scaleProvider) { + mContext = context; + mLock = lock; + mCallback = callback; + mTrace = trace; + mScaleProvider = scaleProvider; + } + + /** + * Sets {@link IWindowMagnificationConnection}. + * + * @param connection {@link IWindowMagnificationConnection} + */ + public void setConnection(@Nullable IWindowMagnificationConnection connection) { + if (DBG) { + Slog.d(TAG, "setConnection :" + connection + ", mConnectionState=" + + connectionStateToString(mConnectionState)); + } + synchronized (mLock) { + // Reset connectionWrapper. + if (mConnectionWrapper != null) { + mConnectionWrapper.setConnectionCallback(null); + if (mConnectionCallback != null) { + mConnectionCallback.mExpiredDeathRecipient = true; + } + mConnectionWrapper.unlinkToDeath(mConnectionCallback); + mConnectionWrapper = null; + // The connection is still connecting so it is no need to reset the + // connection state to disconnected. + // TODO b/220086369 will reset the connection immediately when requestConnection + // is called + if (mConnectionState != CONNECTING) { + setConnectionState(DISCONNECTED); + } + } + if (connection != null) { + mConnectionWrapper = new MagnificationConnectionWrapper(connection, mTrace); + } + + if (mConnectionWrapper != null) { + try { + mConnectionCallback = new ConnectionCallback(); + mConnectionWrapper.linkToDeath(mConnectionCallback); + mConnectionWrapper.setConnectionCallback(mConnectionCallback); + setConnectionState(CONNECTED); + } catch (RemoteException e) { + Slog.e(TAG, "setConnection failed", e); + mConnectionWrapper = null; + setConnectionState(DISCONNECTED); + } finally { + mLock.notify(); + } + } + } + } + + /** + * @return {@code true} if {@link IWindowMagnificationConnection} is available + */ + public boolean isConnected() { + synchronized (mLock) { + return mConnectionWrapper != null; + } + } + + /** + * Requests {@link IWindowMagnificationConnection} through + * {@link StatusBarManagerInternal#requestWindowMagnificationConnection(boolean)} and + * destroys all window magnifications if necessary. + * + * @param connect {@code true} if needs connection, otherwise set the connection to null and + * destroy all window magnifications. + * @return {@code true} if {@link IWindowMagnificationConnection} state is going to change. + */ + public boolean requestConnection(boolean connect) { + if (DBG) { + Slog.d(TAG, "requestConnection :" + connect); + } + if (mTrace.isA11yTracingEnabledForTypes(FLAGS_WINDOW_MAGNIFICATION_CONNECTION)) { + mTrace.logTrace(TAG + ".requestWindowMagnificationConnection", + FLAGS_WINDOW_MAGNIFICATION_CONNECTION, "connect=" + connect); + } + synchronized (mLock) { + if ((connect && (mConnectionState == CONNECTED || mConnectionState == CONNECTING)) + || (!connect && (mConnectionState == DISCONNECTED + || mConnectionState == DISCONNECTING))) { + Slog.w(TAG, "requestConnection duplicated request: connect=" + connect + + ", mConnectionState=" + connectionStateToString(mConnectionState)); + return false; + } + + if (connect) { + final IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF); + if (!mReceiverRegistered) { + mContext.registerReceiver(mScreenStateReceiver, intentFilter); + mReceiverRegistered = true; + } + } else { + disableAllWindowMagnifiers(); + if (mReceiverRegistered) { + mContext.unregisterReceiver(mScreenStateReceiver); + mReceiverRegistered = false; + } + } + } + if (requestConnectionInternal(connect)) { + setConnectionState(connect ? CONNECTING : DISCONNECTING); + return true; + } else { + setConnectionState(DISCONNECTED); + return false; + } + } + + private boolean requestConnectionInternal(boolean connect) { + final long identity = Binder.clearCallingIdentity(); + try { + final StatusBarManagerInternal service = LocalServices.getService( + StatusBarManagerInternal.class); + if (service != null) { + return service.requestWindowMagnificationConnection(connect); + } + } finally { + Binder.restoreCallingIdentity(identity); + } + return false; + } + + /** + * Returns window magnification connection state. + */ + public String getConnectionState() { + return connectionStateToString(mConnectionState); + } + + private void setConnectionState(@ConnectionState int state) { + if (DBG) { + Slog.d(TAG, "setConnectionState : state=" + state + ", mConnectionState=" + + connectionStateToString(mConnectionState)); + } + mConnectionState = state; + } + + /** + * Disables window magnifier on all displays without animation. + */ + void disableAllWindowMagnifiers() { + synchronized (mLock) { + for (int i = 0; i < mWindowMagnifiers.size(); i++) { + final WindowMagnifier magnifier = mWindowMagnifiers.valueAt(i); + magnifier.disableWindowMagnificationInternal(null); + } + mWindowMagnifiers.clear(); + } + } + + /** + * Resets the window magnifier on all displays that had been controlled by the + * specified service connection. Called when the service connection is unbound + * or binder died. + * + * @param connectionId The connection id + */ + public void resetAllIfNeeded(int connectionId) { + synchronized (mLock) { + for (int i = 0; i < mWindowMagnifiers.size(); i++) { + final WindowMagnifier magnifier = mWindowMagnifiers.valueAt(i); + if (magnifier != null + && magnifier.mEnabled + && connectionId == magnifier.getIdOfLastServiceToControl()) { + magnifier.disableWindowMagnificationInternal(null); + } + } + } + } + + private void resetWindowMagnifiers() { + synchronized (mLock) { + for (int i = 0; i < mWindowMagnifiers.size(); i++) { + WindowMagnifier magnifier = mWindowMagnifiers.valueAt(i); + magnifier.reset(); + } + } + } + + @Override + public void onRectangleOnScreenRequested(int displayId, int left, int top, int right, + int bottom) { + if (!mMagnificationFollowTypingEnabled) { + return; + } + + float toCenterX = (float) (left + right) / 2; + float toCenterY = (float) (top + bottom) / 2; + + synchronized (mLock) { + if (mIsImeVisibleArray.get(displayId, false) + && !isPositionInSourceBounds(displayId, toCenterX, toCenterY) + && isTrackingTypingFocusEnabled(displayId)) { + moveWindowMagnifierToPositionInternal(displayId, toCenterX, toCenterY, + STUB_ANIMATION_CALLBACK); + } + } + } + + void setMagnificationFollowTypingEnabled(boolean enabled) { + mMagnificationFollowTypingEnabled = enabled; + } + + boolean isMagnificationFollowTypingEnabled() { + return mMagnificationFollowTypingEnabled; + } + + /** + * Get the ID of the last service that changed the magnification config. + * + * @param displayId The logical display id. + * @return The id + */ + public int getIdOfLastServiceToMagnify(int displayId) { + synchronized (mLock) { + final WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); + if (magnifier != null) { + return magnifier.mIdOfLastServiceToControl; + } + } + return INVALID_SERVICE_ID; + } + + /** + * Enable or disable tracking typing focus for the specific magnification window. + * + * The tracking typing focus should be set to enabled with the following conditions: + * 1. IME is shown. + * + * The tracking typing focus should be set to disabled with the following conditions: + * 1. A user drags the magnification window by 1 finger. + * 2. A user scroll the magnification window by 2 fingers. + * + * @param displayId The logical display id. + * @param trackingTypingFocusEnabled Enabled or disable the function of tracking typing focus. + */ + void setTrackingTypingFocusEnabled(int displayId, boolean trackingTypingFocusEnabled) { + synchronized (mLock) { + WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); + if (magnifier == null) { + return; + } + magnifier.setTrackingTypingFocusEnabled(trackingTypingFocusEnabled); + } + } + + /** + * Enable tracking typing focus function for all magnifications. + */ + private void enableAllTrackingTypingFocus() { + synchronized (mLock) { + for (int i = 0; i < mWindowMagnifiers.size(); i++) { + WindowMagnifier magnifier = mWindowMagnifiers.valueAt(i); + magnifier.setTrackingTypingFocusEnabled(true); + } + } + } + + private void pauseTrackingTypingFocusRecord(int displayId) { + WindowMagnifier magnifier; + synchronized (mLock) { + magnifier = mWindowMagnifiers.get(displayId); + if (magnifier == null) { + return; + } + } + magnifier.pauseTrackingTypingFocusRecord(); + } + + /** + * Called when the IME window visibility changed. + * + * @param shown {@code true} means the IME window shows on the screen. Otherwise, it's hidden. + */ + void onImeWindowVisibilityChanged(int displayId, boolean shown) { + synchronized (mLock) { + mIsImeVisibleArray.put(displayId, shown); + } + if (shown) { + enableAllTrackingTypingFocus(); + } else { + pauseTrackingTypingFocusRecord(displayId); + } + } + + boolean isImeVisible(int displayId) { + synchronized (mLock) { + return mIsImeVisibleArray.get(displayId); + } + } + + void logTrackingTypingFocus(long duration) { + AccessibilityStatsLogUtils.logMagnificationFollowTypingFocusSession(duration); + } + + @Override + public boolean processScroll(int displayId, float distanceX, float distanceY) { + moveWindowMagnification(displayId, -distanceX, -distanceY); + setTrackingTypingFocusEnabled(displayId, false); + return /* event consumed: */ true; + } + + /** + * Scales the magnified region on the specified display if window magnification is initiated. + * + * @param displayId The logical display id. + * @param scale The target scale, must be >= 1 + */ + @Override + public void setScale(int displayId, float scale) { + synchronized (mLock) { + WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); + if (magnifier == null) { + return; + } + magnifier.setScale(scale); + mLastActivatedScale.put(displayId, scale); + } + } + + /** + * Enables window magnification with specified center and scale on the given display and + * animating the transition. + * + * @param displayId The logical display id. + * @param scale The target scale, must be >= 1. + * @param centerX The screen-relative X coordinate around which to center, + * 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. + */ + public boolean enableWindowMagnification(int displayId, float scale, float centerX, + float centerY) { + return enableWindowMagnification(displayId, scale, centerX, centerY, + STUB_ANIMATION_CALLBACK, MAGNIFICATION_GESTURE_HANDLER_ID); + } + + /** + * Enables window magnification with specified center and scale on the given display and + * animating the transition. + * + * @param displayId The logical display id. + * @param scale The target scale, must be >= 1. + * @param centerX The screen-relative X coordinate around which to center for magnification, + * or {@link Float#NaN} to leave unchanged. + * @param centerY The screen-relative Y coordinate around which to center for magnification, + * or {@link Float#NaN} to leave unchanged. + * @param animationCallback Called when the animation result is valid. + * @param id The connection ID + * @return {@code true} if the magnification is enabled successfully. + */ + public boolean enableWindowMagnification(int displayId, float scale, float centerX, + float centerY, @Nullable MagnificationAnimationCallback animationCallback, int id) { + return enableWindowMagnification(displayId, scale, centerX, centerY, animationCallback, + WINDOW_POSITION_AT_CENTER, id); + } + + /** + * Enables window magnification with specified center and scale on the given display and + * animating the transition. + * + * @param displayId The logical display id. + * @param scale The target scale, must be >= 1. + * @param centerX The screen-relative X coordinate around which to center for magnification, + * or {@link Float#NaN} to leave unchanged. + * @param centerY The screen-relative Y coordinate around which to center for magnification, + * or {@link Float#NaN} to leave unchanged. + * @param windowPosition Indicate the offset between window position and (centerX, centerY). + * @return {@code true} if the magnification is enabled successfully. + */ + public boolean enableWindowMagnification(int displayId, float scale, float centerX, + float centerY, @WindowPosition int windowPosition) { + return enableWindowMagnification(displayId, scale, centerX, centerY, + STUB_ANIMATION_CALLBACK, windowPosition, MAGNIFICATION_GESTURE_HANDLER_ID); + } + + /** + * Enables window magnification with specified center and scale on the given display and + * animating the transition. + * + * @param displayId The logical display id. + * @param scale The target scale, must be >= 1. + * @param centerX The screen-relative X coordinate around which to center for + * magnification, or {@link Float#NaN} to leave unchanged. + * @param centerY The screen-relative Y coordinate around which to center for + * magnification, or {@link Float#NaN} to leave unchanged. + * @param animationCallback Called when the animation result is valid. + * @param windowPosition Indicate the offset between window position and (centerX, centerY). + * @return {@code true} if the magnification is enabled successfully. + */ + public boolean enableWindowMagnification(int displayId, float scale, float centerX, + float centerY, @Nullable MagnificationAnimationCallback animationCallback, + @WindowPosition int windowPosition, int id) { + final boolean enabled; + boolean previousEnabled; + synchronized (mLock) { + WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); + if (magnifier == null) { + magnifier = createWindowMagnifier(displayId); + } + previousEnabled = magnifier.mEnabled; + enabled = magnifier.enableWindowMagnificationInternal(scale, centerX, centerY, + animationCallback, windowPosition, id); + if (enabled) { + mLastActivatedScale.put(displayId, getScale(displayId)); + } + } + + if (enabled) { + setTrackingTypingFocusEnabled(displayId, true); + if (!previousEnabled) { + mCallback.onWindowMagnificationActivationState(displayId, true); + } + } + return enabled; + } + + /** + * Disables window magnification on the given display. + * + * @param displayId The logical display id. + * @param clear {@true} Clears the state of window magnification. + * @return {@code true} if the magnification is turned to be disabled successfully + */ + public boolean disableWindowMagnification(int displayId, boolean clear) { + return disableWindowMagnification(displayId, clear, STUB_ANIMATION_CALLBACK); + } + + /** + * Disables window magnification on the specified display and animating the transition. + * + * @param displayId The logical display id. + * @param clear {@true} Clears the state of window magnification. + * @param animationCallback Called when the animation result is valid. + * @return {@code true} if the magnification is turned to be disabled successfully + */ + public boolean disableWindowMagnification(int displayId, boolean clear, + MagnificationAnimationCallback animationCallback) { + final boolean disabled; + synchronized (mLock) { + WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); + if (magnifier == null) { + return false; + } + + disabled = magnifier.disableWindowMagnificationInternal(animationCallback); + if (clear) { + mWindowMagnifiers.delete(displayId); + } + } + + if (disabled) { + mCallback.onWindowMagnificationActivationState(displayId, false); + } + return disabled; + } + + /** + * Calculates the number of fingers in the window. + * + * @param displayId The logical display id. + * @param motionEvent The motion event + * @return the number of fingers in the window. + */ + int pointersInWindow(int displayId, MotionEvent motionEvent) { + synchronized (mLock) { + WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); + if (magnifier == null) { + return 0; + } + return magnifier.pointersInWindow(motionEvent); + } + } + + @GuardedBy("mLock") + boolean isPositionInSourceBounds(int displayId, float x, float y) { + WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); + if (magnifier == null) { + return false; + } + return magnifier.isPositionInSourceBounds(x, y); + } + + /** + * Indicates whether window magnification is enabled on specified display. + * + * @param displayId The logical display id. + * @return {@code true} if the window magnification is enabled. + */ + public boolean isWindowMagnifierEnabled(int displayId) { + synchronized (mLock) { + WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); + if (magnifier == null) { + return false; + } + return magnifier.isEnabled(); + } + } + + /** + * Retrieves a previously magnification scale from the current + * user's settings. Only the value of the default display is persisted. + * + * @return the previously magnification scale, or the default + * scale if none is available + */ + float getPersistedScale(int displayId) { + return MathUtils.constrain(mScaleProvider.getScale(displayId), + MagnificationConstants.PERSISTED_SCALE_MIN_VALUE, + MagnificationScaleProvider.MAX_SCALE); + } + + /** + * Persists the default display magnification scale to the current user's settings + * if scale is >= {@link MagnificationConstants.PERSISTED_SCALE_MIN_VALUE}. + * We assume if the scale is < {@link MagnificationConstants.PERSISTED_SCALE_MIN_VALUE}, there + * will be no obvious magnification effect. + * Only the value of the default display is persisted in user's settings. + */ + void persistScale(int displayId) { + float scale = getScale(displayId); + if (scale < MagnificationConstants.PERSISTED_SCALE_MIN_VALUE) { + return; + } + mScaleProvider.putScale(scale, displayId); + } + + /** + * Returns the magnification scale. + * + * @param displayId The logical display id. + * @return the scale + */ + public float getScale(int displayId) { + synchronized (mLock) { + WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); + if (magnifier == null || !magnifier.mEnabled) { + return 1.0f; + } + return magnifier.getScale(); + } + } + + protected float getLastActivatedScale(int displayId) { + synchronized (mLock) { + if (!mLastActivatedScale.contains(displayId)) { + return -1.0f; + } + return mLastActivatedScale.get(displayId); + } + } + + /** + * Moves window magnification on the specified display with the specified offset. + * + * @param displayId The logical display id. + * @param offsetX the amount in pixels to offset the region in the X direction, in current + * screen pixels. + * @param offsetY the amount in pixels to offset the region in the Y direction, in current + * screen pixels. + */ + void moveWindowMagnification(int displayId, float offsetX, float offsetY) { + synchronized (mLock) { + WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); + if (magnifier == null) { + return; + } + magnifier.move(offsetX, offsetY); + } + } + + /** + * Requests System UI show magnification mode button UI on the specified display. + * + * @param displayId The logical display id. + * @param magnificationMode the current magnification mode. + * @return {@code true} if the event was handled, {@code false} otherwise + */ + public boolean showMagnificationButton(int displayId, int magnificationMode) { + synchronized (mLock) { + return mConnectionWrapper != null + && mConnectionWrapper.showMagnificationButton(displayId, magnificationMode); + } + } + + /** + * Requests System UI remove magnification mode button UI on the specified display. + * + * @param displayId The logical display id. + * @return {@code true} if the event was handled, {@code false} otherwise + */ + public boolean removeMagnificationButton(int displayId) { + synchronized (mLock) { + return mConnectionWrapper != null + && mConnectionWrapper.removeMagnificationButton(displayId); + } + } + + /** + * Requests System UI remove magnification settings panel on the specified display. + * + * @param displayId The logical display id. + * @return {@code true} if the event was handled, {@code false} otherwise + */ + public boolean removeMagnificationSettingsPanel(int displayId) { + synchronized (mLock) { + return mConnectionWrapper != null + && mConnectionWrapper.removeMagnificationSettingsPanel(displayId); + } + } + + /** + * Notify System UI the magnification scale on the specified display for userId is changed. + * + * @param userId the user id. + * @param displayId the logical display id. + * @param scale magnification scale. + */ + public boolean onUserMagnificationScaleChanged(int userId, int displayId, float scale) { + synchronized (mLock) { + return mConnectionWrapper != null + && mConnectionWrapper.onUserMagnificationScaleChanged(userId, displayId, scale); + } + } + + /** + * Returns the screen-relative X coordinate of the center of the magnified bounds. + * + * @param displayId The logical display id + * @return the X coordinate. {@link Float#NaN} if the window magnification is not enabled. + */ + public float getCenterX(int displayId) { + synchronized (mLock) { + WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); + if (magnifier == null || !magnifier.mEnabled) { + return Float.NaN; + } + return magnifier.getCenterX(); + } + } + + /** + * Returns the screen-relative Y coordinate of the center of the magnified bounds. + * + * @param displayId The logical display id + * @return the Y coordinate. {@link Float#NaN} if the window magnification is not enabled. + */ + public float getCenterY(int displayId) { + synchronized (mLock) { + WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); + if (magnifier == null || !magnifier.mEnabled) { + return Float.NaN; + } + return magnifier.getCenterY(); + } + } + + boolean isTrackingTypingFocusEnabled(int displayId) { + synchronized (mLock) { + WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); + if (magnifier == null) { + return false; + } + return magnifier.isTrackingTypingFocusEnabled(); + } + } + + /** + * 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 || !magnifier.mEnabled) { + outRegion.setEmpty(); + } else { + outRegion.set(magnifier.mSourceBounds); + } + } + } + + /** + * Creates the windowMagnifier based on the specified display and stores it. + * + * @param displayId logical display id. + */ + @GuardedBy("mLock") + private WindowMagnifier createWindowMagnifier(int displayId) { + final WindowMagnifier magnifier = new WindowMagnifier(displayId, this); + mWindowMagnifiers.put(displayId, magnifier); + return magnifier; + } + + /** + * Removes the window magnifier with given id. + * + * @param displayId The logical display id. + */ + public void onDisplayRemoved(int displayId) { + disableWindowMagnification(displayId, true); + } + + private class ConnectionCallback extends IWindowMagnificationConnectionCallback.Stub implements + IBinder.DeathRecipient { + private boolean mExpiredDeathRecipient = false; + + @Override + public void onWindowMagnifierBoundsChanged(int displayId, Rect bounds) { + if (mTrace.isA11yTracingEnabledForTypes( + FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK)) { + mTrace.logTrace(TAG + "ConnectionCallback.onWindowMagnifierBoundsChanged", + FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK, + "displayId=" + displayId + ";bounds=" + bounds); + } + synchronized (mLock) { + WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); + if (magnifier == null) { + magnifier = createWindowMagnifier(displayId); + } + if (DBG) { + Slog.i(TAG, + "onWindowMagnifierBoundsChanged -" + displayId + " bounds = " + bounds); + } + magnifier.setMagnifierLocation(bounds); + } + } + + @Override + public void onChangeMagnificationMode(int displayId, int magnificationMode) + throws RemoteException { + if (mTrace.isA11yTracingEnabledForTypes( + FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK)) { + mTrace.logTrace(TAG + "ConnectionCallback.onChangeMagnificationMode", + FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK, + "displayId=" + displayId + ";mode=" + magnificationMode); + } + mCallback.onChangeMagnificationMode(displayId, magnificationMode); + } + + @Override + public void onSourceBoundsChanged(int displayId, Rect sourceBounds) { + if (mTrace.isA11yTracingEnabledForTypes( + FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK)) { + mTrace.logTrace(TAG + "ConnectionCallback.onSourceBoundsChanged", + FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK, + "displayId=" + displayId + ";source=" + sourceBounds); + } + synchronized (mLock) { + WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); + if (magnifier == null) { + magnifier = createWindowMagnifier(displayId); + } + magnifier.onSourceBoundsChanged(sourceBounds); + } + mCallback.onSourceBoundsChanged(displayId, sourceBounds); + } + + @Override + public void onPerformScaleAction(int displayId, float scale, boolean updatePersistence) { + if (mTrace.isA11yTracingEnabledForTypes( + FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK)) { + mTrace.logTrace(TAG + "ConnectionCallback.onPerformScaleAction", + FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK, + "displayId=" + displayId + ";scale=" + scale + + ";updatePersistence=" + updatePersistence); + } + mCallback.onPerformScaleAction(displayId, scale, updatePersistence); + } + + @Override + public void onAccessibilityActionPerformed(int displayId) { + if (mTrace.isA11yTracingEnabledForTypes( + FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK)) { + mTrace.logTrace(TAG + "ConnectionCallback.onAccessibilityActionPerformed", + FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK, + "displayId=" + displayId); + } + mCallback.onAccessibilityActionPerformed(displayId); + } + + @Override + public void onMove(int displayId) { + if (mTrace.isA11yTracingEnabledForTypes( + FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK)) { + mTrace.logTrace(TAG + "ConnectionCallback.onMove", + FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK, + "displayId=" + displayId); + } + setTrackingTypingFocusEnabled(displayId, false); + } + + @Override + public void binderDied() { + synchronized (mLock) { + Slog.w(TAG, "binderDied DeathRecipient :" + mExpiredDeathRecipient); + if (mExpiredDeathRecipient) { + return; + } + mConnectionWrapper.unlinkToDeath(this); + mConnectionWrapper = null; + mConnectionCallback = null; + setConnectionState(DISCONNECTED); + resetWindowMagnifiers(); + } + } + } + + /** + * A class manipulates window magnification per display and contains the magnification + * information. + *

+ * This class requires to hold the lock when controlling the magnifier. + *

+ */ + private static class WindowMagnifier { + + private final int mDisplayId; + private float mScale = MagnificationScaleProvider.MIN_SCALE; + private boolean mEnabled; + + private final MagnificationConnectionManager mMagnificationConnectionManager; + // Records the bounds of window magnification. + private final Rect mBounds = new Rect(); + // The magnified bounds on the screen. + private final Rect mSourceBounds = new Rect(); + + private int mIdOfLastServiceToControl = INVALID_SERVICE_ID; + + private final PointF mMagnificationFrameOffsetRatio = new PointF(0f, 0f); + + private boolean mTrackingTypingFocusEnabled = true; + + private volatile long mTrackingTypingFocusStartTime = 0; + private static final AtomicLongFieldUpdater SUM_TIME_UPDATER = + AtomicLongFieldUpdater.newUpdater(WindowMagnifier.class, + "mTrackingTypingFocusSumTime"); + private volatile long mTrackingTypingFocusSumTime = 0; + + WindowMagnifier(int displayId, + MagnificationConnectionManager magnificationConnectionManager) { + mDisplayId = displayId; + mMagnificationConnectionManager = magnificationConnectionManager; + } + + // TODO(b/312324808): Investigating whether + // mMagnificationConnectionManager#enableWindowMagnificationInternal requires a sync lock + @SuppressWarnings("GuardedBy") + boolean enableWindowMagnificationInternal(float scale, float centerX, float centerY, + @Nullable MagnificationAnimationCallback animationCallback, + @WindowPosition int windowPosition, int id) { + // Handle defaults. The scale may be NAN when just updating magnification center. + if (Float.isNaN(scale)) { + scale = getScale(); + } + final float normScale = MagnificationScaleProvider.constrainScale(scale); + setMagnificationFrameOffsetRatioByWindowPosition(windowPosition); + if (mMagnificationConnectionManager.enableWindowMagnificationInternal(mDisplayId, + normScale, centerX, centerY, mMagnificationFrameOffsetRatio.x, + mMagnificationFrameOffsetRatio.y, animationCallback)) { + mScale = normScale; + mEnabled = true; + mIdOfLastServiceToControl = id; + return true; + } + return false; + } + + void setMagnificationFrameOffsetRatioByWindowPosition(@WindowPosition int windowPosition) { + switch (windowPosition) { + case WINDOW_POSITION_AT_CENTER: { + mMagnificationFrameOffsetRatio.set(0f, 0f); + } + break; + case WINDOW_POSITION_AT_TOP_LEFT: { + mMagnificationFrameOffsetRatio.set(-1f, -1f); + } + break; + } + } + + // TODO(b/312324808): Investigating whether + // mMagnificationConnectionManager#disableWindowMagnificationInternal requires a sync lock + @SuppressWarnings("GuardedBy") + boolean disableWindowMagnificationInternal( + @Nullable MagnificationAnimationCallback animationResultCallback) { + if (!mEnabled) { + return false; + } + if (mMagnificationConnectionManager.disableWindowMagnificationInternal( + mDisplayId, animationResultCallback)) { + mEnabled = false; + mIdOfLastServiceToControl = INVALID_SERVICE_ID; + mTrackingTypingFocusEnabled = false; + pauseTrackingTypingFocusRecord(); + return true; + } + return false; + } + + // ErrorProne says the access of mMagnificationConnectionManager#setScaleInternal should + // be guarded by 'this.mMagnificationConnectionManager.mLock' which is the same one as + // 'mLock'. Therefore, we'll put @SuppressWarnings here. + @SuppressWarnings("GuardedBy") + @GuardedBy("mLock") + void setScale(float scale) { + if (!mEnabled) { + return; + } + final float normScale = MagnificationScaleProvider.constrainScale(scale); + if (Float.compare(mScale, normScale) != 0 + && mMagnificationConnectionManager.setScaleInternal(mDisplayId, scale)) { + mScale = normScale; + } + } + + @GuardedBy("mLock") + float getScale() { + return mScale; + } + + @GuardedBy("mLock") + void setMagnifierLocation(Rect rect) { + mBounds.set(rect); + } + + /** + * Returns the ID of the last service that changed the magnification config. + */ + int getIdOfLastServiceToControl() { + return mIdOfLastServiceToControl; + } + + int pointersInWindow(MotionEvent motionEvent) { + int count = 0; + final int pointerCount = motionEvent.getPointerCount(); + for (int i = 0; i < pointerCount; i++) { + final float x = motionEvent.getX(i); + final float y = motionEvent.getY(i); + if (mBounds.contains((int) x, (int) y)) { + count++; + } + } + return count; + } + + boolean isPositionInSourceBounds(float x, float y) { + return mSourceBounds.contains((int) x, (int) y); + } + + void setTrackingTypingFocusEnabled(boolean trackingTypingFocusEnabled) { + if (mMagnificationConnectionManager.isWindowMagnifierEnabled(mDisplayId) + && mMagnificationConnectionManager.isImeVisible(mDisplayId) + && trackingTypingFocusEnabled) { + startTrackingTypingFocusRecord(); + } + if (mTrackingTypingFocusEnabled && !trackingTypingFocusEnabled) { + stopAndLogTrackingTypingFocusRecordIfNeeded(); + } + mTrackingTypingFocusEnabled = trackingTypingFocusEnabled; + } + + boolean isTrackingTypingFocusEnabled() { + return mTrackingTypingFocusEnabled; + } + + void startTrackingTypingFocusRecord() { + if (mTrackingTypingFocusStartTime == 0) { + mTrackingTypingFocusStartTime = SystemClock.uptimeMillis(); + if (DBG) { + Slog.d(TAG, "start: mTrackingTypingFocusStartTime = " + + mTrackingTypingFocusStartTime); + } + } + } + + void pauseTrackingTypingFocusRecord() { + if (mTrackingTypingFocusStartTime != 0) { + final long elapsed = (SystemClock.uptimeMillis() - mTrackingTypingFocusStartTime); + // update mTrackingTypingFocusSumTime value in an atomic operation + SUM_TIME_UPDATER.addAndGet(this, elapsed); + mTrackingTypingFocusStartTime = 0; + if (DBG) { + Slog.d(TAG, "pause: mTrackingTypingFocusSumTime = " + + mTrackingTypingFocusSumTime + ", elapsed = " + elapsed); + } + } + } + + void stopAndLogTrackingTypingFocusRecordIfNeeded() { + if (mTrackingTypingFocusStartTime != 0 || mTrackingTypingFocusSumTime != 0) { + final long elapsed = mTrackingTypingFocusStartTime != 0 + ? (SystemClock.uptimeMillis() - mTrackingTypingFocusStartTime) : 0; + final long duration = mTrackingTypingFocusSumTime + elapsed; + if (DBG) { + Slog.d(TAG, "stop and log: session duration = " + duration + + ", elapsed = " + elapsed); + } + mMagnificationConnectionManager.logTrackingTypingFocus(duration); + mTrackingTypingFocusStartTime = 0; + mTrackingTypingFocusSumTime = 0; + } + } + + boolean isEnabled() { + return mEnabled; + } + + // ErrorProne says the access of mMagnificationConnectionManager#moveWindowMagnifierInternal + // should be guarded by 'this.mMagnificationConnectionManager.mLock' which is the same one + // as 'mLock'. Therefore, we'll put @SuppressWarnings here. + @SuppressWarnings("GuardedBy") + @GuardedBy("mLock") + void move(float offsetX, float offsetY) { + mMagnificationConnectionManager.moveWindowMagnifierInternal( + mDisplayId, offsetX, offsetY); + } + + @GuardedBy("mLock") + void reset() { + mEnabled = false; + mIdOfLastServiceToControl = INVALID_SERVICE_ID; + mSourceBounds.setEmpty(); + } + + @GuardedBy("mLock") + public void onSourceBoundsChanged(Rect sourceBounds) { + mSourceBounds.set(sourceBounds); + } + + @GuardedBy("mLock") + float getCenterX() { + return mSourceBounds.exactCenterX(); + } + + @GuardedBy("mLock") + float getCenterY() { + return mSourceBounds.exactCenterY(); + } + } + + @GuardedBy("mLock") + private boolean enableWindowMagnificationInternal(int displayId, float scale, float centerX, + float centerY, float magnificationFrameOffsetRatioX, + float magnificationFrameOffsetRatioY, + MagnificationAnimationCallback animationCallback) { + // Wait for the connection with a timeout. + final long endMillis = SystemClock.uptimeMillis() + WAIT_CONNECTION_TIMEOUT_MILLIS; + while (mConnectionState == CONNECTING && (SystemClock.uptimeMillis() < endMillis)) { + try { + mLock.wait(endMillis - SystemClock.uptimeMillis()); + } catch (InterruptedException ie) { + /* ignore */ + } + } + if (mConnectionWrapper == null) { + Slog.w(TAG, + "enableWindowMagnificationInternal mConnectionWrapper is null. " + + "mConnectionState=" + connectionStateToString(mConnectionState)); + return false; + } + return mConnectionWrapper.enableWindowMagnification( + displayId, scale, centerX, centerY, + magnificationFrameOffsetRatioX, magnificationFrameOffsetRatioY, + animationCallback); + } + + private boolean setScaleInternal(int displayId, float scale) { + return mConnectionWrapper != null && mConnectionWrapper.setScale(displayId, scale); + } + + @GuardedBy("mLock") + private boolean disableWindowMagnificationInternal(int displayId, + MagnificationAnimationCallback animationCallback) { + if (mConnectionWrapper == null) { + Slog.w(TAG, "mConnectionWrapper is null"); + return false; + } + return mConnectionWrapper.disableWindowMagnification( + displayId, animationCallback); + } + + @GuardedBy("mLock") + private boolean moveWindowMagnifierInternal(int displayId, float offsetX, float offsetY) { + return mConnectionWrapper != null && mConnectionWrapper.moveWindowMagnifier( + displayId, offsetX, offsetY); + } + + @GuardedBy("mLock") + private boolean moveWindowMagnifierToPositionInternal(int displayId, float positionX, + float positionY, MagnificationAnimationCallback animationCallback) { + return mConnectionWrapper != null && mConnectionWrapper.moveWindowMagnifierToPosition( + displayId, positionX, positionY, animationCallback); + } +} diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java index effd8732d086..52e123a5e70c 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java @@ -77,7 +77,7 @@ import java.util.concurrent.Executor; * Note Updates magnification switch UI when magnification mode transition * is done and before invoking {@link TransitionCallBack#onResult}. */ -public class MagnificationController implements WindowMagnificationManager.Callback, +public class MagnificationController implements MagnificationConnectionManager.Callback, MagnificationGestureHandler.Callback, FullScreenMagnificationController.MagnificationInfoChangedCallback, WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks { @@ -96,7 +96,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb private final AlwaysOnMagnificationFeatureFlag mAlwaysOnMagnificationFeatureFlag; private final MagnificationScaleProvider mScaleProvider; private FullScreenMagnificationController mFullScreenMagnificationController; - private WindowMagnificationManager mWindowMagnificationMgr; + private MagnificationConnectionManager mMagnificationConnectionManager; private int mMagnificationCapabilities = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN; /** Whether the platform supports window magnification feature. */ private final boolean mSupportWindowMagnification; @@ -164,11 +164,11 @@ public class MagnificationController implements WindowMagnificationManager.Callb @VisibleForTesting public MagnificationController(AccessibilityManagerService ams, Object lock, Context context, FullScreenMagnificationController fullScreenMagnificationController, - WindowMagnificationManager windowMagnificationManager, + MagnificationConnectionManager magnificationConnectionManager, MagnificationScaleProvider scaleProvider, Executor backgroundExecutor) { this(ams, lock, context, scaleProvider, backgroundExecutor); mFullScreenMagnificationController = fullScreenMagnificationController; - mWindowMagnificationMgr = windowMagnificationManager; + mMagnificationConnectionManager = magnificationConnectionManager; } @Override @@ -179,10 +179,10 @@ public class MagnificationController implements WindowMagnificationManager.Callb if (updatePersistence) { getFullScreenMagnificationController().persistScale(displayId); } - } else if (getWindowMagnificationMgr().isWindowMagnifierEnabled(displayId)) { - getWindowMagnificationMgr().setScale(displayId, scale); + } else if (getMagnificationConnectionManager().isWindowMagnifierEnabled(displayId)) { + getMagnificationConnectionManager().setScale(displayId, scale); if (updatePersistence) { - getWindowMagnificationMgr().persistScale(displayId); + getMagnificationConnectionManager().persistScale(displayId); } } } @@ -222,15 +222,15 @@ public class MagnificationController implements WindowMagnificationManager.Callb } if (showModeSwitchButton) { - getWindowMagnificationMgr().showMagnificationButton(displayId, mode); + getMagnificationConnectionManager().showMagnificationButton(displayId, mode); } else { - getWindowMagnificationMgr().removeMagnificationButton(displayId); + getMagnificationConnectionManager().removeMagnificationButton(displayId); } if (!enableSettingsPanel) { // Whether the settings panel needs to be shown is controlled in system UI. // Here, we only guarantee that the settings panel is closed when it is not needed. - getWindowMagnificationMgr().removeMagnificationSettingsPanel(displayId); + getMagnificationConnectionManager().removeMagnificationSettingsPanel(displayId); } } @@ -284,7 +284,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb final FullScreenMagnificationController screenMagnificationController = getFullScreenMagnificationController(); - final WindowMagnificationManager windowMagnificationMgr = getWindowMagnificationMgr(); + final MagnificationConnectionManager magnificationConnectionManager = + getMagnificationConnectionManager(); final float scale = getTargetModeScaleFromCurrentMagnification(displayId, targetMode); final DisableMagnificationCallback animationEndCallback = new DisableMagnificationCallback(transitionCallBack, displayId, targetMode, @@ -295,7 +296,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) { screenMagnificationController.reset(displayId, animationEndCallback); } else { - windowMagnificationMgr.disableWindowMagnification(displayId, false, + magnificationConnectionManager.disableWindowMagnification(displayId, false, animationEndCallback); } } @@ -340,7 +341,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb } final FullScreenMagnificationController screenMagnificationController = getFullScreenMagnificationController(); - final WindowMagnificationManager windowMagnificationMgr = getWindowMagnificationMgr(); + final MagnificationConnectionManager magnificationConnectionManager = + getMagnificationConnectionManager(); final float targetScale = Float.isNaN(config.getScale()) ? getTargetModeScaleFromCurrentMagnification(displayId, targetMode) : config.getScale(); @@ -353,14 +355,15 @@ public class MagnificationController implements WindowMagnificationManager.Callb if (targetMode == MAGNIFICATION_MODE_WINDOW) { screenMagnificationController.reset(displayId, false); if (targetActivated) { - windowMagnificationMgr.enableWindowMagnification(displayId, + magnificationConnectionManager.enableWindowMagnification(displayId, targetScale, magnificationCenter.x, magnificationCenter.y, magnificationAnimationCallback, id); } else { - windowMagnificationMgr.disableWindowMagnification(displayId, false); + magnificationConnectionManager.disableWindowMagnification(displayId, false); } } else if (targetMode == MAGNIFICATION_MODE_FULLSCREEN) { - windowMagnificationMgr.disableWindowMagnification(displayId, false, null); + magnificationConnectionManager.disableWindowMagnification( + displayId, false, null); if (targetActivated) { if (!screenMagnificationController.isRegistered(displayId)) { screenMagnificationController.register(displayId); @@ -409,7 +412,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) { return getFullScreenMagnificationController().getScale(displayId); } else { - return getWindowMagnificationMgr().getScale(displayId); + return getMagnificationConnectionManager().getScale(displayId); } } @@ -441,7 +444,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb mAccessibilityCallbacksDelegateArray.put(displayId, getFullScreenMagnificationController()); } else if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) { - mAccessibilityCallbacksDelegateArray.put(displayId, getWindowMagnificationMgr()); + mAccessibilityCallbacksDelegateArray.put( + displayId, getMagnificationConnectionManager()); } else { mAccessibilityCallbacksDelegateArray.delete(displayId); } @@ -462,13 +466,13 @@ public class MagnificationController implements WindowMagnificationManager.Callb @Override public void onRequestMagnificationSpec(int displayId, int serviceId) { - final WindowMagnificationManager windowMagnificationManager; + final MagnificationConnectionManager magnificationConnectionManager; synchronized (mLock) { updateMagnificationUIControls(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN); - windowMagnificationManager = mWindowMagnificationMgr; + magnificationConnectionManager = mMagnificationConnectionManager; } - if (windowMagnificationManager != null) { - mWindowMagnificationMgr.disableWindowMagnification(displayId, false); + if (magnificationConnectionManager != null) { + mMagnificationConnectionManager.disableWindowMagnification(displayId, false); } } @@ -491,7 +495,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb setCurrentMagnificationModeAndSwitchDelegate(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_NONE); duration = SystemClock.uptimeMillis() - mWindowModeEnabledTimeArray.get(displayId); - scale = mWindowMagnificationMgr.getLastActivatedScale(displayId); + scale = mMagnificationConnectionManager.getLastActivatedScale(displayId); } logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW, duration, scale); } @@ -507,13 +511,14 @@ public class MagnificationController implements WindowMagnificationManager.Callb public void onSourceBoundsChanged(int displayId, Rect bounds) { if (shouldNotifyMagnificationChange(displayId, MAGNIFICATION_MODE_WINDOW)) { // notify sysui the magnification scale changed on window magnifier - mWindowMagnificationMgr.onUserMagnificationScaleChanged( - mUserId, displayId, getWindowMagnificationMgr().getScale(displayId)); + mMagnificationConnectionManager.onUserMagnificationScaleChanged( + mUserId, displayId, getMagnificationConnectionManager().getScale(displayId)); final MagnificationConfig config = new MagnificationConfig.Builder() .setMode(MAGNIFICATION_MODE_WINDOW) - .setActivated(getWindowMagnificationMgr().isWindowMagnifierEnabled(displayId)) - .setScale(getWindowMagnificationMgr().getScale(displayId)) + .setActivated( + getMagnificationConnectionManager().isWindowMagnifierEnabled(displayId)) + .setScale(getMagnificationConnectionManager().getScale(displayId)) .setCenterX(bounds.exactCenterX()) .setCenterY(bounds.exactCenterY()).build(); mAms.notifyMagnificationChanged(displayId, new Region(bounds), config); @@ -525,7 +530,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb @NonNull MagnificationConfig config) { if (shouldNotifyMagnificationChange(displayId, MAGNIFICATION_MODE_FULLSCREEN)) { // notify sysui the magnification scale changed on fullscreen magnifier - mWindowMagnificationMgr.onUserMagnificationScaleChanged( + mMagnificationConnectionManager.onUserMagnificationScaleChanged( mUserId, displayId, config.getScale()); mAms.notifyMagnificationChanged(displayId, region, config); @@ -548,8 +553,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb synchronized (mLock) { final boolean fullScreenActivated = mFullScreenMagnificationController != null && mFullScreenMagnificationController.isActivated(displayId); - final boolean windowEnabled = mWindowMagnificationMgr != null - && mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId); + final boolean windowEnabled = mMagnificationConnectionManager != null + && mMagnificationConnectionManager.isWindowMagnifierEnabled(displayId); final Integer transitionMode = mTransitionModes.get(displayId); if (((changeMode == MAGNIFICATION_MODE_FULLSCREEN && fullScreenActivated) || (changeMode == MAGNIFICATION_MODE_WINDOW && windowEnabled)) @@ -608,10 +613,10 @@ public class MagnificationController implements WindowMagnificationManager.Callb } private void disableWindowMagnificationIfNeeded(int displayId) { - final WindowMagnificationManager windowMagnificationManager = - getWindowMagnificationMgr(); + final MagnificationConnectionManager magnificationConnectionManager = + getMagnificationConnectionManager(); if (isActivated(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW)) { - windowMagnificationManager.disableWindowMagnification(displayId, false); + magnificationConnectionManager.disableWindowMagnification(displayId, false); } } @@ -620,7 +625,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb synchronized (mLock) { mIsImeVisibleArray.put(displayId, shown); } - getWindowMagnificationMgr().onImeWindowVisibilityChanged(displayId, shown); + getMagnificationConnectionManager().onImeWindowVisibilityChanged(displayId, shown); logMagnificationModeWithImeOnIfNeeded(displayId); } @@ -661,7 +666,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb /** * Updates the active user ID of {@link FullScreenMagnificationController} and {@link - * WindowMagnificationManager}. + * MagnificationConnectionManager}. * * @param userId the currently active user ID */ @@ -671,10 +676,10 @@ public class MagnificationController implements WindowMagnificationManager.Callb } mUserId = userId; final FullScreenMagnificationController fullMagnificationController; - final WindowMagnificationManager windowMagnificationManager; + final MagnificationConnectionManager magnificationConnectionManager; synchronized (mLock) { fullMagnificationController = mFullScreenMagnificationController; - windowMagnificationManager = mWindowMagnificationMgr; + magnificationConnectionManager = mMagnificationConnectionManager; mAccessibilityCallbacksDelegateArray.clear(); mCurrentMagnificationModeArray.clear(); mLastMagnificationActivatedModeArray.clear(); @@ -685,8 +690,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb if (fullMagnificationController != null) { fullMagnificationController.resetAllIfNeeded(false); } - if (windowMagnificationManager != null) { - windowMagnificationManager.disableAllWindowMagnifiers(); + if (magnificationConnectionManager != null) { + magnificationConnectionManager.disableAllWindowMagnifiers(); } } @@ -700,8 +705,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb if (mFullScreenMagnificationController != null) { mFullScreenMagnificationController.onDisplayRemoved(displayId); } - if (mWindowMagnificationMgr != null) { - mWindowMagnificationMgr.onDisplayRemoved(displayId); + if (mMagnificationConnectionManager != null) { + mMagnificationConnectionManager.onDisplayRemoved(displayId); } mAccessibilityCallbacksDelegateArray.delete(displayId); mCurrentMagnificationModeArray.delete(displayId); @@ -728,7 +733,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb * @param enabled Enable the following typing focus feature */ public void setMagnificationFollowTypingEnabled(boolean enabled) { - getWindowMagnificationMgr().setMagnificationFollowTypingEnabled(enabled); + getMagnificationConnectionManager().setMagnificationFollowTypingEnabled(enabled); getFullScreenMagnificationController().setMagnificationFollowTypingEnabled(enabled); } @@ -805,29 +810,29 @@ public class MagnificationController implements WindowMagnificationManager.Callb } /** - * Getter of {@link WindowMagnificationManager}. + * Getter of {@link MagnificationConnectionManager}. * - * @return {@link WindowMagnificationManager}. + * @return {@link MagnificationConnectionManager}. */ - public WindowMagnificationManager getWindowMagnificationMgr() { + public MagnificationConnectionManager getMagnificationConnectionManager() { synchronized (mLock) { - if (mWindowMagnificationMgr == null) { - mWindowMagnificationMgr = new WindowMagnificationManager(mContext, + if (mMagnificationConnectionManager == null) { + mMagnificationConnectionManager = new MagnificationConnectionManager(mContext, mLock, this, mAms.getTraceManager(), mScaleProvider); } - return mWindowMagnificationMgr; + return mMagnificationConnectionManager; } } private @Nullable PointF getCurrentMagnificationCenterLocked(int displayId, int targetMode) { if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) { - if (mWindowMagnificationMgr == null - || !mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId)) { + if (mMagnificationConnectionManager == null + || !mMagnificationConnectionManager.isWindowMagnifierEnabled(displayId)) { return null; } - mTempPoint.set(mWindowMagnificationMgr.getCenterX(displayId), - mWindowMagnificationMgr.getCenterY(displayId)); + mTempPoint.set(mMagnificationConnectionManager.getCenterX(displayId), + mMagnificationConnectionManager.getCenterY(displayId)); } else { if (mFullScreenMagnificationController == null || !mFullScreenMagnificationController.isActivated(displayId)) { @@ -858,10 +863,10 @@ public class MagnificationController implements WindowMagnificationManager.Callb } } else if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) { synchronized (mLock) { - if (mWindowMagnificationMgr == null) { + if (mMagnificationConnectionManager == null) { return false; } - isActivated = mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId); + isActivated = mMagnificationConnectionManager.isWindowMagnifierEnabled(displayId); } } return isActivated; @@ -980,7 +985,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb mCurrentCenter.x, mCurrentCenter.y, mAnimate, MAGNIFICATION_GESTURE_HANDLER_ID); } else { - getWindowMagnificationMgr().enableWindowMagnification(mDisplayId, + getMagnificationConnectionManager().enableWindowMagnification(mDisplayId, mCurrentScale, mCurrentCenter.x, mCurrentCenter.y, mAnimate ? STUB_ANIMATION_CALLBACK : null, MAGNIFICATION_GESTURE_HANDLER_ID); diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java index 5cf2a638fa3e..ed8f1ab3a1b2 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java @@ -84,13 +84,13 @@ public class MagnificationProcessor { .setCenterX(fullScreenMagnificationController.getCenterX(displayId)) .setCenterY(fullScreenMagnificationController.getCenterY(displayId)); } else if (mode == MAGNIFICATION_MODE_WINDOW) { - final WindowMagnificationManager windowMagnificationManager = - mController.getWindowMagnificationMgr(); + final MagnificationConnectionManager magnificationConnectionManager = + mController.getMagnificationConnectionManager(); builder.setMode(mode) .setActivated(mController.isActivated(displayId, MAGNIFICATION_MODE_WINDOW)) - .setScale(windowMagnificationManager.getScale(displayId)) - .setCenterX(windowMagnificationManager.getCenterX(displayId)) - .setCenterY(windowMagnificationManager.getCenterY(displayId)); + .setScale(magnificationConnectionManager.getScale(displayId)) + .setCenterX(magnificationConnectionManager.getCenterX(displayId)) + .setCenterY(magnificationConnectionManager.getCenterY(displayId)); } else { // For undefined mode, set enabled to false builder.setActivated(false); @@ -135,12 +135,12 @@ public class MagnificationProcessor { } } else if (configMode == MAGNIFICATION_MODE_WINDOW) { if (configActivated) { - return mController.getWindowMagnificationMgr().enableWindowMagnification(displayId, - config.getScale(), config.getCenterX(), config.getCenterY(), + return mController.getMagnificationConnectionManager().enableWindowMagnification( + displayId, config.getScale(), config.getCenterX(), config.getCenterY(), animate ? STUB_ANIMATION_CALLBACK : null, id); } else { - return mController.getWindowMagnificationMgr() + return mController.getMagnificationConnectionManager() .disableWindowMagnification(displayId, false); } } @@ -256,7 +256,7 @@ public class MagnificationProcessor { if (currentMode == MAGNIFICATION_MODE_FULLSCREEN) { getFullscreenMagnificationRegion(displayId, outRegion, canControlMagnification); } else if (currentMode == MAGNIFICATION_MODE_WINDOW) { - mController.getWindowMagnificationMgr().getMagnificationSourceBounds(displayId, + mController.getMagnificationConnectionManager().getMagnificationSourceBounds(displayId, outRegion); } } @@ -297,8 +297,8 @@ public class MagnificationProcessor { if (mode == MAGNIFICATION_MODE_FULLSCREEN) { return mController.getFullScreenMagnificationController().reset(displayId, animate); } else if (mode == MAGNIFICATION_MODE_WINDOW) { - return mController.getWindowMagnificationMgr().disableWindowMagnification(displayId, - false, animate ? STUB_ANIMATION_CALLBACK : null); + return mController.getMagnificationConnectionManager().disableWindowMagnification( + displayId, false, animate ? STUB_ANIMATION_CALLBACK : null); } return false; } @@ -325,19 +325,20 @@ public class MagnificationProcessor { */ public void resetAllIfNeeded(int connectionId) { mController.getFullScreenMagnificationController().resetAllIfNeeded(connectionId); - mController.getWindowMagnificationMgr().resetAllIfNeeded(connectionId); + mController.getMagnificationConnectionManager().resetAllIfNeeded(connectionId); } /** * {@link FullScreenMagnificationController#isActivated(int)} - * {@link WindowMagnificationManager#isWindowMagnifierEnabled(int)} + * {@link MagnificationConnectionManager#isWindowMagnifierEnabled(int)} */ public boolean isMagnifying(int displayId) { int mode = getControllingMode(displayId); if (mode == MAGNIFICATION_MODE_FULLSCREEN) { return mController.getFullScreenMagnificationController().isActivated(displayId); } else if (mode == MAGNIFICATION_MODE_WINDOW) { - return mController.getWindowMagnificationMgr().isWindowMagnifierEnabled(displayId); + return mController.getMagnificationConnectionManager().isWindowMagnifierEnabled( + displayId); } return false; } @@ -416,22 +417,23 @@ public class MagnificationProcessor { pw.append(" SupportWindowMagnification=" + mController.supportWindowMagnification()).println(); pw.append(" WindowMagnificationConnectionState=" - + mController.getWindowMagnificationMgr().getConnectionState()).println(); + + mController.getMagnificationConnectionManager().getConnectionState()).println(); } private int getIdOfLastServiceToMagnify(int mode, int displayId) { return (mode == MAGNIFICATION_MODE_FULLSCREEN) ? mController.getFullScreenMagnificationController() .getIdOfLastServiceToMagnify(displayId) - : mController.getWindowMagnificationMgr().getIdOfLastServiceToMagnify( + : mController.getMagnificationConnectionManager().getIdOfLastServiceToMagnify( displayId); } private void dumpTrackingTypingFocusEnabledState(final PrintWriter pw, int displayId, int mode) { if (mode == MAGNIFICATION_MODE_WINDOW) { - pw.append(" TrackingTypingFocusEnabled=" + mController - .getWindowMagnificationMgr().isTrackingTypingFocusEnabled(displayId)) + pw.append(" TrackingTypingFocusEnabled=" + + mController.getMagnificationConnectionManager() + .isTrackingTypingFocusEnabled(displayId)) .println(); } } diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java index 36e751181cfd..73c267a6e262 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java @@ -79,7 +79,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl private static final float MIN_SCALE = 1.0f; private static final float MAX_SCALE = MagnificationScaleProvider.MAX_SCALE; - private final WindowMagnificationManager mWindowMagnificationMgr; + private final MagnificationConnectionManager mMagnificationConnectionManager; @VisibleForTesting final DelegatingState mDelegatingState; @VisibleForTesting @@ -101,7 +101,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl private long mTripleTapAndHoldStartedTime = 0; public WindowMagnificationGestureHandler(@UiContext Context context, - WindowMagnificationManager windowMagnificationMgr, + MagnificationConnectionManager magnificationConnectionManager, AccessibilityTraceManager trace, Callback callback, boolean detectSingleFingerTripleTap, @@ -115,7 +115,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl "WindowMagnificationGestureHandler() , displayId = " + displayId + ")"); } mContext = context; - mWindowMagnificationMgr = windowMagnificationMgr; + mMagnificationConnectionManager = magnificationConnectionManager; mMotionEventDispatcherDelegate = new MotionEventDispatcherDelegate(context, (event, rawEvent, policyFlags) -> dispatchTransformedEvent(event, rawEvent, policyFlags)); @@ -128,18 +128,18 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl @Override public boolean processScroll(int displayId, float distanceX, float distanceY) { - return mWindowMagnificationMgr.processScroll(displayId, distanceX, - distanceY); + return mMagnificationConnectionManager.processScroll( + displayId, distanceX, distanceY); } @Override public void setScale(int displayId, float scale) { - mWindowMagnificationMgr.setScale(displayId, scale); + mMagnificationConnectionManager.setScale(displayId, scale); } @Override public float getScale(int displayId) { - return mWindowMagnificationMgr.getScale(displayId); + return mMagnificationConnectionManager.getScale(displayId); } })); @@ -167,7 +167,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl Slog.i(mLogTag, "onDestroy(); delayed = " + mDetectingState.toString()); } - mWindowMagnificationMgr.disableWindowMagnification(mDisplayId, true); + mMagnificationConnectionManager.disableWindowMagnification(mDisplayId, true); resetToDetectState(); } @@ -176,7 +176,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl final Point screenSize = mTempPoint; getScreenSize(mTempPoint); toggleMagnification(screenSize.x / 2.0f, screenSize.y / 2.0f, - WindowMagnificationManager.WINDOW_POSITION_AT_CENTER); + MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER); } private void getScreenSize(Point outSize) { @@ -190,28 +190,29 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl } private void enableWindowMagnifier(float centerX, float centerY, - @WindowMagnificationManager.WindowPosition int windowPosition) { + @MagnificationConnectionManager.WindowPosition int windowPosition) { if (DEBUG_ALL) { Slog.i(mLogTag, "enableWindowMagnifier :" + centerX + ", " + centerY + ", " + windowPosition); } final float scale = MathUtils.constrain( - mWindowMagnificationMgr.getPersistedScale(mDisplayId), MIN_SCALE, MAX_SCALE); - mWindowMagnificationMgr.enableWindowMagnification(mDisplayId, scale, centerX, centerY, - windowPosition); + mMagnificationConnectionManager.getPersistedScale(mDisplayId), + MIN_SCALE, MAX_SCALE); + mMagnificationConnectionManager.enableWindowMagnification( + mDisplayId, scale, centerX, centerY, windowPosition); } private void disableWindowMagnifier() { if (DEBUG_ALL) { Slog.i(mLogTag, "disableWindowMagnifier()"); } - mWindowMagnificationMgr.disableWindowMagnification(mDisplayId, false); + mMagnificationConnectionManager.disableWindowMagnification(mDisplayId, false); } private void toggleMagnification(float centerX, float centerY, - @WindowMagnificationManager.WindowPosition int windowPosition) { - if (mWindowMagnificationMgr.isWindowMagnifierEnabled(mDisplayId)) { + @MagnificationConnectionManager.WindowPosition int windowPosition) { + if (mMagnificationConnectionManager.isWindowMagnifierEnabled(mDisplayId)) { disableWindowMagnifier(); } else { enableWindowMagnifier(centerX, centerY, windowPosition); @@ -223,7 +224,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl Slog.i(mLogTag, "onTripleTap()"); } toggleMagnification(up.getX(), up.getY(), - WindowMagnificationManager.WINDOW_POSITION_AT_CENTER); + MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER); } @VisibleForTesting @@ -232,9 +233,9 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl Slog.i(mLogTag, "onTripleTapAndHold()"); } mViewportDraggingState.mEnabledBeforeDrag = - mWindowMagnificationMgr.isWindowMagnifierEnabled(mDisplayId); + mMagnificationConnectionManager.isWindowMagnifierEnabled(mDisplayId); enableWindowMagnifier(up.getX(), up.getY(), - WindowMagnificationManager.WINDOW_POSITION_AT_TOP_LEFT); + MagnificationConnectionManager.WINDOW_POSITION_AT_TOP_LEFT); mTripleTapAndHoldStartedTime = SystemClock.uptimeMillis(); transitionTo(mViewportDraggingState); } @@ -242,7 +243,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl @VisibleForTesting void releaseTripleTapAndHold() { if (!mViewportDraggingState.mEnabledBeforeDrag) { - mWindowMagnificationMgr.disableWindowMagnification(mDisplayId, true); + mMagnificationConnectionManager.disableWindowMagnification(mDisplayId, true); } transitionTo(mDetectingState); if (mTripleTapAndHoldStartedTime != 0) { @@ -331,7 +332,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl @Override public void onExit() { mPanningScalingHandler.setEnabled(false); - mWindowMagnificationMgr.persistScale(mDisplayId); + mMagnificationConnectionManager.persistScale(mDisplayId); clear(); } @@ -404,7 +405,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl if (!Float.isNaN(mLastX) && !Float.isNaN(mLastY)) { float offsetX = event.getX() - mLastX; float offsetY = event.getY() - mLastY; - mWindowMagnificationMgr.moveWindowMagnification(mDisplayId, offsetX, + mMagnificationConnectionManager.moveWindowMagnification(mDisplayId, offsetX, offsetY); } mLastX = event.getX(); @@ -522,7 +523,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl @Override public boolean shouldStopDetection(MotionEvent motionEvent) { - return !mWindowMagnificationMgr.isWindowMagnifierEnabled(mDisplayId) + return !mMagnificationConnectionManager.isWindowMagnifierEnabled(mDisplayId) && !mDetectSingleFingerTripleTap && !(mDetectTwoFingerTripleTap && Flags.enableMagnificationMultipleFingerMultipleTapGesture()); @@ -540,7 +541,8 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl "onGestureDetected : delayedEventQueue = " + delayedEventQueue); } if (gestureId == MagnificationGestureMatcher.GESTURE_TWO_FINGERS_DOWN_OR_SWIPE - && mWindowMagnificationMgr.pointersInWindow(mDisplayId, motionEvent) > 0) { + && mMagnificationConnectionManager + .pointersInWindow(mDisplayId, motionEvent) > 0) { transitionTo(mObservePanningScalingState); } else if (gestureId == MagnificationGestureMatcher.GESTURE_TRIPLE_TAP) { onTripleTap(motionEvent); @@ -584,7 +586,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl + ", mMagnifiedInteractionState=" + mObservePanningScalingState + ", mCurrentState=" + State.nameOf(mCurrentState) + ", mPreviousState=" + State.nameOf(mPreviousState) - + ", mWindowMagnificationMgr=" + mWindowMagnificationMgr + + ", mMagnificationConnectionManager=" + mMagnificationConnectionManager + ", mDisplayId=" + mDisplayId + '}'; } diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java deleted file mode 100644 index 3ea805bbb4a6..000000000000 --- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java +++ /dev/null @@ -1,1300 +0,0 @@ -/* - * Copyright (C) 2019 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.magnification; - -import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MAGNIFICATION_CONNECTION; -import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK; -import static android.view.accessibility.MagnificationAnimationCallback.STUB_ANIMATION_CALLBACK; - -import static com.android.server.accessibility.AccessibilityManagerService.INVALID_SERVICE_ID; -import static com.android.server.accessibility.AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.graphics.PointF; -import android.graphics.Rect; -import android.graphics.Region; -import android.os.Binder; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.SystemClock; -import android.util.MathUtils; -import android.util.Slog; -import android.util.SparseArray; -import android.util.SparseBooleanArray; -import android.view.MotionEvent; -import android.view.accessibility.IWindowMagnificationConnection; -import android.view.accessibility.IWindowMagnificationConnectionCallback; -import android.view.accessibility.MagnificationAnimationCallback; - -import com.android.internal.accessibility.common.MagnificationConstants; -import com.android.internal.accessibility.util.AccessibilityStatsLogUtils; -import com.android.internal.annotations.GuardedBy; -import com.android.internal.annotations.VisibleForTesting; -import com.android.server.LocalServices; -import com.android.server.accessibility.AccessibilityTraceManager; -import com.android.server.statusbar.StatusBarManagerInternal; -import com.android.server.wm.WindowManagerInternal; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.concurrent.atomic.AtomicLongFieldUpdater; - -/** - * A class to manipulate window magnification through {@link MagnificationConnectionWrapper} - * create by {@link #setConnection(IWindowMagnificationConnection)}. To set the connection with - * SysUI, call {@code StatusBarManagerInternal#requestWindowMagnificationConnection(boolean)}. - * The applied magnification scale is constrained by - * {@link MagnificationScaleProvider#constrainScale(float)} - */ -public class WindowMagnificationManager implements - PanningScalingHandler.MagnificationDelegate, - WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks { - - private static final boolean DBG = false; - - private static final String TAG = "WindowMagnificationMgr"; - - /** - * Indicate that the magnification window is at the magnification center. - */ - public static final int WINDOW_POSITION_AT_CENTER = 0; - - /** - * Indicate that the magnification window is at the top-left side of the magnification - * center. The offset is equal to a half of MirrorSurfaceView. So, the bottom-right corner - * of the window is at the magnification center. - */ - public static final int WINDOW_POSITION_AT_TOP_LEFT = 1; - - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = { "WINDOW_POSITION_AT_" }, value = { - WINDOW_POSITION_AT_CENTER, - WINDOW_POSITION_AT_TOP_LEFT - }) - public @interface WindowPosition {} - - /** Window magnification connection is connecting. */ - private static final int CONNECTING = 0; - /** Window magnification connection is connected. */ - private static final int CONNECTED = 1; - /** Window magnification connection is disconnecting. */ - private static final int DISCONNECTING = 2; - /** Window magnification connection is disconnected. */ - private static final int DISCONNECTED = 3; - - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = {"CONNECTION_STATE"}, value = { - CONNECTING, - CONNECTED, - DISCONNECTING, - DISCONNECTED - }) - private @interface ConnectionState { - } - - private static String connectionStateToString(@ConnectionState int state) { - switch (state) { - case CONNECTING: return "CONNECTING"; - case CONNECTED: return "CONNECTED"; - case DISCONNECTING: return "DISCONNECTING"; - case DISCONNECTED: return "DISCONNECTED"; - default: - return "UNKNOWN:" + state; - } - } - - @ConnectionState - private int mConnectionState = DISCONNECTED; - - private static final int WAIT_CONNECTION_TIMEOUT_MILLIS = 100; - - private final Object mLock; - private final Context mContext; - @VisibleForTesting - @GuardedBy("mLock") - @Nullable - MagnificationConnectionWrapper mConnectionWrapper; - @GuardedBy("mLock") - private ConnectionCallback mConnectionCallback; - @GuardedBy("mLock") - private SparseArray mWindowMagnifiers = new SparseArray<>(); - // Whether the following typing focus feature for magnification is enabled. - private boolean mMagnificationFollowTypingEnabled = true; - @GuardedBy("mLock") - private final SparseBooleanArray mIsImeVisibleArray = new SparseBooleanArray(); - @GuardedBy("mLock") - private final SparseArray mLastActivatedScale = new SparseArray<>(); - - private boolean mReceiverRegistered = false; - @VisibleForTesting - protected final BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - final int displayId = context.getDisplayId(); - removeMagnificationButton(displayId); - disableWindowMagnification(displayId, false, null); - } - }; - - /** - * Callback to handle magnification actions from system UI. - */ - public interface Callback { - - /** - * Called when the accessibility action of scale requests to be performed. - * It is invoked from System UI. And the action is provided by the mirror window. - * - * @param displayId The logical display id. - * @param scale the target scale, or {@link Float#NaN} to leave unchanged - * @param updatePersistence whether the scale should be persisted - */ - void onPerformScaleAction(int displayId, float scale, boolean updatePersistence); - - /** - * Called when the accessibility action is performed. - * - * @param displayId The logical display id. - */ - void onAccessibilityActionPerformed(int displayId); - - /** - * Called when the state of the magnification activation is changed. - * - * @param displayId The logical display id. - * @param activated {@code true} if the magnification is activated, otherwise {@code false}. - */ - void onWindowMagnificationActivationState(int displayId, boolean activated); - - /** - * Called when the magnification source bounds are changed. - * - * @param displayId The logical display id. - * @param bounds The magnified source bounds on the display. - */ - void onSourceBoundsChanged(int displayId, Rect bounds); - - /** - * Called from {@link IWindowMagnificationConnection} to request changing the magnification - * mode on the given display. - * - * @param displayId the logical display id - * @param magnificationMode the target magnification mode - */ - void onChangeMagnificationMode(int displayId, int magnificationMode); - } - - private final Callback mCallback; - private final AccessibilityTraceManager mTrace; - private final MagnificationScaleProvider mScaleProvider; - - public WindowMagnificationManager(Context context, Object lock, @NonNull Callback callback, - AccessibilityTraceManager trace, MagnificationScaleProvider scaleProvider) { - mContext = context; - mLock = lock; - mCallback = callback; - mTrace = trace; - mScaleProvider = scaleProvider; - } - - /** - * Sets {@link IWindowMagnificationConnection}. - * - * @param connection {@link IWindowMagnificationConnection} - */ - public void setConnection(@Nullable IWindowMagnificationConnection connection) { - if (DBG) { - Slog.d(TAG, "setConnection :" + connection + ", mConnectionState=" - + connectionStateToString(mConnectionState)); - } - synchronized (mLock) { - // Reset connectionWrapper. - if (mConnectionWrapper != null) { - mConnectionWrapper.setConnectionCallback(null); - if (mConnectionCallback != null) { - mConnectionCallback.mExpiredDeathRecipient = true; - } - mConnectionWrapper.unlinkToDeath(mConnectionCallback); - mConnectionWrapper = null; - // The connection is still connecting so it is no need to reset the - // connection state to disconnected. - // TODO b/220086369 will reset the connection immediately when requestConnection - // is called - if (mConnectionState != CONNECTING) { - setConnectionState(DISCONNECTED); - } - } - if (connection != null) { - mConnectionWrapper = new MagnificationConnectionWrapper(connection, mTrace); - } - - if (mConnectionWrapper != null) { - try { - mConnectionCallback = new ConnectionCallback(); - mConnectionWrapper.linkToDeath(mConnectionCallback); - mConnectionWrapper.setConnectionCallback(mConnectionCallback); - setConnectionState(CONNECTED); - } catch (RemoteException e) { - Slog.e(TAG, "setConnection failed", e); - mConnectionWrapper = null; - setConnectionState(DISCONNECTED); - } finally { - mLock.notify(); - } - } - } - } - - /** - * @return {@code true} if {@link IWindowMagnificationConnection} is available - */ - public boolean isConnected() { - synchronized (mLock) { - return mConnectionWrapper != null; - } - } - - /** - * Requests {@link IWindowMagnificationConnection} through - * {@link StatusBarManagerInternal#requestWindowMagnificationConnection(boolean)} and - * destroys all window magnifications if necessary. - * - * @param connect {@code true} if needs connection, otherwise set the connection to null and - * destroy all window magnifications. - * @return {@code true} if {@link IWindowMagnificationConnection} state is going to change. - */ - public boolean requestConnection(boolean connect) { - if (DBG) { - Slog.d(TAG, "requestConnection :" + connect); - } - if (mTrace.isA11yTracingEnabledForTypes(FLAGS_WINDOW_MAGNIFICATION_CONNECTION)) { - mTrace.logTrace(TAG + ".requestWindowMagnificationConnection", - FLAGS_WINDOW_MAGNIFICATION_CONNECTION, "connect=" + connect); - } - synchronized (mLock) { - if ((connect && (mConnectionState == CONNECTED || mConnectionState == CONNECTING)) - || (!connect && (mConnectionState == DISCONNECTED - || mConnectionState == DISCONNECTING))) { - Slog.w(TAG, "requestConnection duplicated request: connect=" + connect - + ", mConnectionState=" + connectionStateToString(mConnectionState)); - return false; - } - - if (connect) { - final IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF); - if (!mReceiverRegistered) { - mContext.registerReceiver(mScreenStateReceiver, intentFilter); - mReceiverRegistered = true; - } - } else { - disableAllWindowMagnifiers(); - if (mReceiverRegistered) { - mContext.unregisterReceiver(mScreenStateReceiver); - mReceiverRegistered = false; - } - } - } - if (requestConnectionInternal(connect)) { - setConnectionState(connect ? CONNECTING : DISCONNECTING); - return true; - } else { - setConnectionState(DISCONNECTED); - return false; - } - } - - private boolean requestConnectionInternal(boolean connect) { - final long identity = Binder.clearCallingIdentity(); - try { - final StatusBarManagerInternal service = LocalServices.getService( - StatusBarManagerInternal.class); - if (service != null) { - return service.requestWindowMagnificationConnection(connect); - } - } finally { - Binder.restoreCallingIdentity(identity); - } - return false; - } - - /** - * Returns window magnification connection state. - */ - public String getConnectionState() { - return connectionStateToString(mConnectionState); - } - - private void setConnectionState(@ConnectionState int state) { - if (DBG) { - Slog.d(TAG, "setConnectionState : state=" + state + ", mConnectionState=" - + connectionStateToString(mConnectionState)); - } - mConnectionState = state; - } - - /** - * Disables window magnifier on all displays without animation. - */ - void disableAllWindowMagnifiers() { - synchronized (mLock) { - for (int i = 0; i < mWindowMagnifiers.size(); i++) { - final WindowMagnifier magnifier = mWindowMagnifiers.valueAt(i); - magnifier.disableWindowMagnificationInternal(null); - } - mWindowMagnifiers.clear(); - } - } - - /** - * Resets the window magnifier on all displays that had been controlled by the - * specified service connection. Called when the service connection is unbound - * or binder died. - * - * @param connectionId The connection id - */ - public void resetAllIfNeeded(int connectionId) { - synchronized (mLock) { - for (int i = 0; i < mWindowMagnifiers.size(); i++) { - final WindowMagnifier magnifier = mWindowMagnifiers.valueAt(i); - if (magnifier != null - && magnifier.mEnabled - && connectionId == magnifier.getIdOfLastServiceToControl()) { - magnifier.disableWindowMagnificationInternal(null); - } - } - } - } - - private void resetWindowMagnifiers() { - synchronized (mLock) { - for (int i = 0; i < mWindowMagnifiers.size(); i++) { - WindowMagnifier magnifier = mWindowMagnifiers.valueAt(i); - magnifier.reset(); - } - } - } - - @Override - public void onRectangleOnScreenRequested(int displayId, int left, int top, int right, - int bottom) { - if (!mMagnificationFollowTypingEnabled) { - return; - } - - float toCenterX = (float) (left + right) / 2; - float toCenterY = (float) (top + bottom) / 2; - - synchronized (mLock) { - if (mIsImeVisibleArray.get(displayId, false) - && !isPositionInSourceBounds(displayId, toCenterX, toCenterY) - && isTrackingTypingFocusEnabled(displayId)) { - moveWindowMagnifierToPositionInternal(displayId, toCenterX, toCenterY, - STUB_ANIMATION_CALLBACK); - } - } - } - - void setMagnificationFollowTypingEnabled(boolean enabled) { - mMagnificationFollowTypingEnabled = enabled; - } - - boolean isMagnificationFollowTypingEnabled() { - return mMagnificationFollowTypingEnabled; - } - - /** - * Get the ID of the last service that changed the magnification config. - * - * @param displayId The logical display id. - * @return The id - */ - public int getIdOfLastServiceToMagnify(int displayId) { - synchronized (mLock) { - final WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier != null) { - return magnifier.mIdOfLastServiceToControl; - } - } - return INVALID_SERVICE_ID; - } - - /** - * Enable or disable tracking typing focus for the specific magnification window. - * - * The tracking typing focus should be set to enabled with the following conditions: - * 1. IME is shown. - * - * The tracking typing focus should be set to disabled with the following conditions: - * 1. A user drags the magnification window by 1 finger. - * 2. A user scroll the magnification window by 2 fingers. - * - * @param displayId The logical display id. - * @param trackingTypingFocusEnabled Enabled or disable the function of tracking typing focus. - */ - void setTrackingTypingFocusEnabled(int displayId, boolean trackingTypingFocusEnabled) { - synchronized (mLock) { - WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null) { - return; - } - magnifier.setTrackingTypingFocusEnabled(trackingTypingFocusEnabled); - } - } - - /** - * Enable tracking typing focus function for all magnifications. - */ - private void enableAllTrackingTypingFocus() { - synchronized (mLock) { - for (int i = 0; i < mWindowMagnifiers.size(); i++) { - WindowMagnifier magnifier = mWindowMagnifiers.valueAt(i); - magnifier.setTrackingTypingFocusEnabled(true); - } - } - } - - private void pauseTrackingTypingFocusRecord(int displayId) { - WindowMagnifier magnifier; - synchronized (mLock) { - magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null) { - return; - } - } - magnifier.pauseTrackingTypingFocusRecord(); - } - - /** - * Called when the IME window visibility changed. - * - * @param shown {@code true} means the IME window shows on the screen. Otherwise, it's hidden. - */ - void onImeWindowVisibilityChanged(int displayId, boolean shown) { - synchronized (mLock) { - mIsImeVisibleArray.put(displayId, shown); - } - if (shown) { - enableAllTrackingTypingFocus(); - } else { - pauseTrackingTypingFocusRecord(displayId); - } - } - - boolean isImeVisible(int displayId) { - synchronized (mLock) { - return mIsImeVisibleArray.get(displayId); - } - } - - void logTrackingTypingFocus(long duration) { - AccessibilityStatsLogUtils.logMagnificationFollowTypingFocusSession(duration); - } - - @Override - public boolean processScroll(int displayId, float distanceX, float distanceY) { - moveWindowMagnification(displayId, -distanceX, -distanceY); - setTrackingTypingFocusEnabled(displayId, false); - return /* event consumed: */ true; - } - - /** - * Scales the magnified region on the specified display if window magnification is initiated. - * - * @param displayId The logical display id. - * @param scale The target scale, must be >= 1 - */ - @Override - public void setScale(int displayId, float scale) { - synchronized (mLock) { - WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null) { - return; - } - magnifier.setScale(scale); - mLastActivatedScale.put(displayId, scale); - } - } - - /** - * Enables window magnification with specified center and scale on the given display and - * animating the transition. - * - * @param displayId The logical display id. - * @param scale The target scale, must be >= 1. - * @param centerX The screen-relative X coordinate around which to center, - * 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. - */ - public boolean enableWindowMagnification(int displayId, float scale, float centerX, - float centerY) { - return enableWindowMagnification(displayId, scale, centerX, centerY, - STUB_ANIMATION_CALLBACK, MAGNIFICATION_GESTURE_HANDLER_ID); - } - - /** - * Enables window magnification with specified center and scale on the given display and - * animating the transition. - * - * @param displayId The logical display id. - * @param scale The target scale, must be >= 1. - * @param centerX The screen-relative X coordinate around which to center for magnification, - * or {@link Float#NaN} to leave unchanged. - * @param centerY The screen-relative Y coordinate around which to center for magnification, - * or {@link Float#NaN} to leave unchanged. - * @param animationCallback Called when the animation result is valid. - * @param id The connection ID - * @return {@code true} if the magnification is enabled successfully. - */ - public boolean enableWindowMagnification(int displayId, float scale, float centerX, - float centerY, @Nullable MagnificationAnimationCallback animationCallback, int id) { - return enableWindowMagnification(displayId, scale, centerX, centerY, animationCallback, - WINDOW_POSITION_AT_CENTER, id); - } - - /** - * Enables window magnification with specified center and scale on the given display and - * animating the transition. - * - * @param displayId The logical display id. - * @param scale The target scale, must be >= 1. - * @param centerX The screen-relative X coordinate around which to center for magnification, - * or {@link Float#NaN} to leave unchanged. - * @param centerY The screen-relative Y coordinate around which to center for magnification, - * or {@link Float#NaN} to leave unchanged. - * @param windowPosition Indicate the offset between window position and (centerX, centerY). - * @return {@code true} if the magnification is enabled successfully. - */ - public boolean enableWindowMagnification(int displayId, float scale, float centerX, - float centerY, @WindowPosition int windowPosition) { - return enableWindowMagnification(displayId, scale, centerX, centerY, - STUB_ANIMATION_CALLBACK, windowPosition, MAGNIFICATION_GESTURE_HANDLER_ID); - } - - /** - * Enables window magnification with specified center and scale on the given display and - * animating the transition. - * - * @param displayId The logical display id. - * @param scale The target scale, must be >= 1. - * @param centerX The screen-relative X coordinate around which to center for - * magnification, or {@link Float#NaN} to leave unchanged. - * @param centerY The screen-relative Y coordinate around which to center for - * magnification, or {@link Float#NaN} to leave unchanged. - * @param animationCallback Called when the animation result is valid. - * @param windowPosition Indicate the offset between window position and (centerX, centerY). - * @return {@code true} if the magnification is enabled successfully. - */ - public boolean enableWindowMagnification(int displayId, float scale, float centerX, - float centerY, @Nullable MagnificationAnimationCallback animationCallback, - @WindowPosition int windowPosition, int id) { - final boolean enabled; - boolean previousEnabled; - synchronized (mLock) { - WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null) { - magnifier = createWindowMagnifier(displayId); - } - previousEnabled = magnifier.mEnabled; - enabled = magnifier.enableWindowMagnificationInternal(scale, centerX, centerY, - animationCallback, windowPosition, id); - if (enabled) { - mLastActivatedScale.put(displayId, getScale(displayId)); - } - } - - if (enabled) { - setTrackingTypingFocusEnabled(displayId, true); - if (!previousEnabled) { - mCallback.onWindowMagnificationActivationState(displayId, true); - } - } - return enabled; - } - - /** - * Disables window magnification on the given display. - * - * @param displayId The logical display id. - * @param clear {@true} Clears the state of window magnification. - * @return {@code true} if the magnification is turned to be disabled successfully - */ - public boolean disableWindowMagnification(int displayId, boolean clear) { - return disableWindowMagnification(displayId, clear, STUB_ANIMATION_CALLBACK); - } - - /** - * Disables window magnification on the specified display and animating the transition. - * - * @param displayId The logical display id. - * @param clear {@true} Clears the state of window magnification. - * @param animationCallback Called when the animation result is valid. - * @return {@code true} if the magnification is turned to be disabled successfully - */ - public boolean disableWindowMagnification(int displayId, boolean clear, - MagnificationAnimationCallback animationCallback) { - final boolean disabled; - synchronized (mLock) { - WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null) { - return false; - } - - disabled = magnifier.disableWindowMagnificationInternal(animationCallback); - if (clear) { - mWindowMagnifiers.delete(displayId); - } - } - - if (disabled) { - mCallback.onWindowMagnificationActivationState(displayId, false); - } - return disabled; - } - - /** - * Calculates the number of fingers in the window. - * - * @param displayId The logical display id. - * @param motionEvent The motion event - * @return the number of fingers in the window. - */ - int pointersInWindow(int displayId, MotionEvent motionEvent) { - synchronized (mLock) { - WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null) { - return 0; - } - return magnifier.pointersInWindow(motionEvent); - } - } - - @GuardedBy("mLock") - boolean isPositionInSourceBounds(int displayId, float x, float y) { - WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null) { - return false; - } - return magnifier.isPositionInSourceBounds(x, y); - } - - /** - * Indicates whether window magnification is enabled on specified display. - * - * @param displayId The logical display id. - * @return {@code true} if the window magnification is enabled. - */ - public boolean isWindowMagnifierEnabled(int displayId) { - synchronized (mLock) { - WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null) { - return false; - } - return magnifier.isEnabled(); - } - } - - /** - * Retrieves a previously magnification scale from the current - * user's settings. Only the value of the default display is persisted. - * - * @return the previously magnification scale, or the default - * scale if none is available - */ - float getPersistedScale(int displayId) { - return MathUtils.constrain(mScaleProvider.getScale(displayId), - MagnificationConstants.PERSISTED_SCALE_MIN_VALUE, - MagnificationScaleProvider.MAX_SCALE); - } - - /** - * Persists the default display magnification scale to the current user's settings - * if scale is >= {@link MagnificationConstants.PERSISTED_SCALE_MIN_VALUE}. - * We assume if the scale is < {@link MagnificationConstants.PERSISTED_SCALE_MIN_VALUE}, there - * will be no obvious magnification effect. - * Only the value of the default display is persisted in user's settings. - */ - void persistScale(int displayId) { - float scale = getScale(displayId); - if (scale < MagnificationConstants.PERSISTED_SCALE_MIN_VALUE) { - return; - } - mScaleProvider.putScale(scale, displayId); - } - - /** - * Returns the magnification scale. - * - * @param displayId The logical display id. - * @return the scale - */ - public float getScale(int displayId) { - synchronized (mLock) { - WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null || !magnifier.mEnabled) { - return 1.0f; - } - return magnifier.getScale(); - } - } - - protected float getLastActivatedScale(int displayId) { - synchronized (mLock) { - if (!mLastActivatedScale.contains(displayId)) { - return -1.0f; - } - return mLastActivatedScale.get(displayId); - } - } - - /** - * Moves window magnification on the specified display with the specified offset. - * - * @param displayId The logical display id. - * @param offsetX the amount in pixels to offset the region in the X direction, in current - * screen pixels. - * @param offsetY the amount in pixels to offset the region in the Y direction, in current - * screen pixels. - */ - void moveWindowMagnification(int displayId, float offsetX, float offsetY) { - synchronized (mLock) { - WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null) { - return; - } - magnifier.move(offsetX, offsetY); - } - } - - /** - * Requests System UI show magnification mode button UI on the specified display. - * - * @param displayId The logical display id. - * @param magnificationMode the current magnification mode. - * @return {@code true} if the event was handled, {@code false} otherwise - */ - public boolean showMagnificationButton(int displayId, int magnificationMode) { - synchronized (mLock) { - return mConnectionWrapper != null - && mConnectionWrapper.showMagnificationButton(displayId, magnificationMode); - } - } - - /** - * Requests System UI remove magnification mode button UI on the specified display. - * - * @param displayId The logical display id. - * @return {@code true} if the event was handled, {@code false} otherwise - */ - public boolean removeMagnificationButton(int displayId) { - synchronized (mLock) { - return mConnectionWrapper != null - && mConnectionWrapper.removeMagnificationButton(displayId); - } - } - - /** - * Requests System UI remove magnification settings panel on the specified display. - * - * @param displayId The logical display id. - * @return {@code true} if the event was handled, {@code false} otherwise - */ - public boolean removeMagnificationSettingsPanel(int displayId) { - synchronized (mLock) { - return mConnectionWrapper != null - && mConnectionWrapper.removeMagnificationSettingsPanel(displayId); - } - } - - /** - * Notify System UI the magnification scale on the specified display for userId is changed. - * - * @param userId the user id. - * @param displayId the logical display id. - * @param scale magnification scale. - */ - public boolean onUserMagnificationScaleChanged(int userId, int displayId, float scale) { - synchronized (mLock) { - return mConnectionWrapper != null - && mConnectionWrapper.onUserMagnificationScaleChanged(userId, displayId, scale); - } - } - - /** - * Returns the screen-relative X coordinate of the center of the magnified bounds. - * - * @param displayId The logical display id - * @return the X coordinate. {@link Float#NaN} if the window magnification is not enabled. - */ - public float getCenterX(int displayId) { - synchronized (mLock) { - WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null || !magnifier.mEnabled) { - return Float.NaN; - } - return magnifier.getCenterX(); - } - } - - /** - * Returns the screen-relative Y coordinate of the center of the magnified bounds. - * - * @param displayId The logical display id - * @return the Y coordinate. {@link Float#NaN} if the window magnification is not enabled. - */ - public float getCenterY(int displayId) { - synchronized (mLock) { - WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null || !magnifier.mEnabled) { - return Float.NaN; - } - return magnifier.getCenterY(); - } - } - - boolean isTrackingTypingFocusEnabled(int displayId) { - synchronized (mLock) { - WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null) { - return false; - } - return magnifier.isTrackingTypingFocusEnabled(); - } - } - - /** - * 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 || !magnifier.mEnabled) { - outRegion.setEmpty(); - } else { - outRegion.set(magnifier.mSourceBounds); - } - } - } - - /** - * Creates the windowMagnifier based on the specified display and stores it. - * - * @param displayId logical display id. - */ - @GuardedBy("mLock") - private WindowMagnifier createWindowMagnifier(int displayId) { - final WindowMagnifier magnifier = new WindowMagnifier(displayId, this); - mWindowMagnifiers.put(displayId, magnifier); - return magnifier; - } - - /** - * Removes the window magnifier with given id. - * - * @param displayId The logical display id. - */ - public void onDisplayRemoved(int displayId) { - disableWindowMagnification(displayId, true); - } - - private class ConnectionCallback extends IWindowMagnificationConnectionCallback.Stub implements - IBinder.DeathRecipient { - private boolean mExpiredDeathRecipient = false; - - @Override - public void onWindowMagnifierBoundsChanged(int displayId, Rect bounds) { - if (mTrace.isA11yTracingEnabledForTypes( - FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK)) { - mTrace.logTrace(TAG + "ConnectionCallback.onWindowMagnifierBoundsChanged", - FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK, - "displayId=" + displayId + ";bounds=" + bounds); - } - synchronized (mLock) { - WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null) { - magnifier = createWindowMagnifier(displayId); - } - if (DBG) { - Slog.i(TAG, - "onWindowMagnifierBoundsChanged -" + displayId + " bounds = " + bounds); - } - magnifier.setMagnifierLocation(bounds); - } - } - - @Override - public void onChangeMagnificationMode(int displayId, int magnificationMode) - throws RemoteException { - if (mTrace.isA11yTracingEnabledForTypes( - FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK)) { - mTrace.logTrace(TAG + "ConnectionCallback.onChangeMagnificationMode", - FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK, - "displayId=" + displayId + ";mode=" + magnificationMode); - } - mCallback.onChangeMagnificationMode(displayId, magnificationMode); - } - - @Override - public void onSourceBoundsChanged(int displayId, Rect sourceBounds) { - if (mTrace.isA11yTracingEnabledForTypes( - FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK)) { - mTrace.logTrace(TAG + "ConnectionCallback.onSourceBoundsChanged", - FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK, - "displayId=" + displayId + ";source=" + sourceBounds); - } - synchronized (mLock) { - WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null) { - magnifier = createWindowMagnifier(displayId); - } - magnifier.onSourceBoundsChanged(sourceBounds); - } - mCallback.onSourceBoundsChanged(displayId, sourceBounds); - } - - @Override - public void onPerformScaleAction(int displayId, float scale, boolean updatePersistence) { - if (mTrace.isA11yTracingEnabledForTypes( - FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK)) { - mTrace.logTrace(TAG + "ConnectionCallback.onPerformScaleAction", - FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK, - "displayId=" + displayId + ";scale=" + scale - + ";updatePersistence=" + updatePersistence); - } - mCallback.onPerformScaleAction(displayId, scale, updatePersistence); - } - - @Override - public void onAccessibilityActionPerformed(int displayId) { - if (mTrace.isA11yTracingEnabledForTypes( - FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK)) { - mTrace.logTrace(TAG + "ConnectionCallback.onAccessibilityActionPerformed", - FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK, - "displayId=" + displayId); - } - mCallback.onAccessibilityActionPerformed(displayId); - } - - @Override - public void onMove(int displayId) { - if (mTrace.isA11yTracingEnabledForTypes( - FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK)) { - mTrace.logTrace(TAG + "ConnectionCallback.onMove", - FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK, - "displayId=" + displayId); - } - setTrackingTypingFocusEnabled(displayId, false); - } - - @Override - public void binderDied() { - synchronized (mLock) { - Slog.w(TAG, "binderDied DeathRecipient :" + mExpiredDeathRecipient); - if (mExpiredDeathRecipient) { - return; - } - mConnectionWrapper.unlinkToDeath(this); - mConnectionWrapper = null; - mConnectionCallback = null; - setConnectionState(DISCONNECTED); - resetWindowMagnifiers(); - } - } - } - - /** - * A class manipulates window magnification per display and contains the magnification - * information. - *

- * This class requires to hold the lock when controlling the magnifier. - *

- */ - private static class WindowMagnifier { - - private final int mDisplayId; - private float mScale = MagnificationScaleProvider.MIN_SCALE; - private boolean mEnabled; - - private final WindowMagnificationManager mWindowMagnificationManager; - // Records the bounds of window magnification. - private final Rect mBounds = new Rect(); - // The magnified bounds on the screen. - private final Rect mSourceBounds = new Rect(); - - private int mIdOfLastServiceToControl = INVALID_SERVICE_ID; - - private final PointF mMagnificationFrameOffsetRatio = new PointF(0f, 0f); - - private boolean mTrackingTypingFocusEnabled = true; - - private volatile long mTrackingTypingFocusStartTime = 0; - private static final AtomicLongFieldUpdater SUM_TIME_UPDATER = - AtomicLongFieldUpdater.newUpdater(WindowMagnifier.class, - "mTrackingTypingFocusSumTime"); - private volatile long mTrackingTypingFocusSumTime = 0; - - WindowMagnifier(int displayId, WindowMagnificationManager windowMagnificationManager) { - mDisplayId = displayId; - mWindowMagnificationManager = windowMagnificationManager; - } - - boolean enableWindowMagnificationInternal(float scale, float centerX, float centerY, - @Nullable MagnificationAnimationCallback animationCallback, - @WindowPosition int windowPosition, int id) { - // Handle defaults. The scale may be NAN when just updating magnification center. - if (Float.isNaN(scale)) { - scale = getScale(); - } - final float normScale = MagnificationScaleProvider.constrainScale(scale); - setMagnificationFrameOffsetRatioByWindowPosition(windowPosition); - if (mWindowMagnificationManager.enableWindowMagnificationInternal(mDisplayId, normScale, - centerX, centerY, mMagnificationFrameOffsetRatio.x, - mMagnificationFrameOffsetRatio.y, animationCallback)) { - mScale = normScale; - mEnabled = true; - mIdOfLastServiceToControl = id; - return true; - } - return false; - } - - void setMagnificationFrameOffsetRatioByWindowPosition(@WindowPosition int windowPosition) { - switch (windowPosition) { - case WINDOW_POSITION_AT_CENTER: { - mMagnificationFrameOffsetRatio.set(0f, 0f); - } - break; - case WINDOW_POSITION_AT_TOP_LEFT: { - mMagnificationFrameOffsetRatio.set(-1f, -1f); - } - break; - } - } - - boolean disableWindowMagnificationInternal( - @Nullable MagnificationAnimationCallback animationResultCallback) { - if (!mEnabled) { - return false; - } - if (mWindowMagnificationManager.disableWindowMagnificationInternal( - mDisplayId, animationResultCallback)) { - mEnabled = false; - mIdOfLastServiceToControl = INVALID_SERVICE_ID; - mTrackingTypingFocusEnabled = false; - pauseTrackingTypingFocusRecord(); - return true; - } - return false; - } - - @GuardedBy("mLock") - void setScale(float scale) { - if (!mEnabled) { - return; - } - final float normScale = MagnificationScaleProvider.constrainScale(scale); - if (Float.compare(mScale, normScale) != 0 - && mWindowMagnificationManager.setScaleInternal(mDisplayId, scale)) { - mScale = normScale; - } - } - - @GuardedBy("mLock") - float getScale() { - return mScale; - } - - @GuardedBy("mLock") - void setMagnifierLocation(Rect rect) { - mBounds.set(rect); - } - - /** - * Returns the ID of the last service that changed the magnification config. - */ - int getIdOfLastServiceToControl() { - return mIdOfLastServiceToControl; - } - - int pointersInWindow(MotionEvent motionEvent) { - int count = 0; - final int pointerCount = motionEvent.getPointerCount(); - for (int i = 0; i < pointerCount; i++) { - final float x = motionEvent.getX(i); - final float y = motionEvent.getY(i); - if (mBounds.contains((int) x, (int) y)) { - count++; - } - } - return count; - } - - boolean isPositionInSourceBounds(float x, float y) { - return mSourceBounds.contains((int) x, (int) y); - } - - void setTrackingTypingFocusEnabled(boolean trackingTypingFocusEnabled) { - if (mWindowMagnificationManager.isWindowMagnifierEnabled(mDisplayId) - && mWindowMagnificationManager.isImeVisible(mDisplayId) - && trackingTypingFocusEnabled) { - startTrackingTypingFocusRecord(); - } - if (mTrackingTypingFocusEnabled && !trackingTypingFocusEnabled) { - stopAndLogTrackingTypingFocusRecordIfNeeded(); - } - mTrackingTypingFocusEnabled = trackingTypingFocusEnabled; - } - - boolean isTrackingTypingFocusEnabled() { - return mTrackingTypingFocusEnabled; - } - - void startTrackingTypingFocusRecord() { - if (mTrackingTypingFocusStartTime == 0) { - mTrackingTypingFocusStartTime = SystemClock.uptimeMillis(); - if (DBG) { - Slog.d(TAG, "start: mTrackingTypingFocusStartTime = " - + mTrackingTypingFocusStartTime); - } - } - } - - void pauseTrackingTypingFocusRecord() { - if (mTrackingTypingFocusStartTime != 0) { - final long elapsed = (SystemClock.uptimeMillis() - mTrackingTypingFocusStartTime); - // update mTrackingTypingFocusSumTime value in an atomic operation - SUM_TIME_UPDATER.addAndGet(this, elapsed); - mTrackingTypingFocusStartTime = 0; - if (DBG) { - Slog.d(TAG, "pause: mTrackingTypingFocusSumTime = " - + mTrackingTypingFocusSumTime + ", elapsed = " + elapsed); - } - } - } - - void stopAndLogTrackingTypingFocusRecordIfNeeded() { - if (mTrackingTypingFocusStartTime != 0 || mTrackingTypingFocusSumTime != 0) { - final long elapsed = mTrackingTypingFocusStartTime != 0 - ? (SystemClock.uptimeMillis() - mTrackingTypingFocusStartTime) : 0; - final long duration = mTrackingTypingFocusSumTime + elapsed; - if (DBG) { - Slog.d(TAG, "stop and log: session duration = " + duration - + ", elapsed = " + elapsed); - } - mWindowMagnificationManager.logTrackingTypingFocus(duration); - mTrackingTypingFocusStartTime = 0; - mTrackingTypingFocusSumTime = 0; - } - } - - boolean isEnabled() { - return mEnabled; - } - - @GuardedBy("mLock") - void move(float offsetX, float offsetY) { - mWindowMagnificationManager.moveWindowMagnifierInternal(mDisplayId, offsetX, offsetY); - } - - @GuardedBy("mLock") - void reset() { - mEnabled = false; - mIdOfLastServiceToControl = INVALID_SERVICE_ID; - mSourceBounds.setEmpty(); - } - - @GuardedBy("mLock") - public void onSourceBoundsChanged(Rect sourceBounds) { - mSourceBounds.set(sourceBounds); - } - - @GuardedBy("mLock") - float getCenterX() { - return mSourceBounds.exactCenterX(); - } - - @GuardedBy("mLock") - float getCenterY() { - return mSourceBounds.exactCenterY(); - } - } - - @GuardedBy("mLock") - private boolean enableWindowMagnificationInternal(int displayId, float scale, float centerX, - float centerY, float magnificationFrameOffsetRatioX, - float magnificationFrameOffsetRatioY, - MagnificationAnimationCallback animationCallback) { - // Wait for the connection with a timeout. - final long endMillis = SystemClock.uptimeMillis() + WAIT_CONNECTION_TIMEOUT_MILLIS; - while (mConnectionState == CONNECTING && (SystemClock.uptimeMillis() < endMillis)) { - try { - mLock.wait(endMillis - SystemClock.uptimeMillis()); - } catch (InterruptedException ie) { - /* ignore */ - } - } - if (mConnectionWrapper == null) { - Slog.w(TAG, - "enableWindowMagnificationInternal mConnectionWrapper is null. " - + "mConnectionState=" + connectionStateToString(mConnectionState)); - return false; - } - return mConnectionWrapper.enableWindowMagnification( - displayId, scale, centerX, centerY, - magnificationFrameOffsetRatioX, magnificationFrameOffsetRatioY, - animationCallback); - } - - private boolean setScaleInternal(int displayId, float scale) { - return mConnectionWrapper != null && mConnectionWrapper.setScale(displayId, scale); - } - - @GuardedBy("mLock") - private boolean disableWindowMagnificationInternal(int displayId, - MagnificationAnimationCallback animationCallback) { - if (mConnectionWrapper == null) { - Slog.w(TAG, "mConnectionWrapper is null"); - return false; - } - return mConnectionWrapper.disableWindowMagnification( - displayId, animationCallback); - } - - @GuardedBy("mLock") - private boolean moveWindowMagnifierInternal(int displayId, float offsetX, float offsetY) { - return mConnectionWrapper != null && mConnectionWrapper.moveWindowMagnifier( - displayId, offsetX, offsetY); - } - - @GuardedBy("mLock") - private boolean moveWindowMagnifierToPositionInternal(int displayId, float positionX, - float positionY, MagnificationAnimationCallback animationCallback) { - return mConnectionWrapper != null && mConnectionWrapper.moveWindowMagnifierToPosition( - displayId, positionX, positionY, animationCallback); - } -} diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java index 82efdd3ce40a..800350a7d326 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java @@ -85,9 +85,9 @@ import com.android.internal.compat.IPlatformCompat; import com.android.server.LocalServices; import com.android.server.accessibility.AccessibilityManagerService.AccessibilityDisplayListener; import com.android.server.accessibility.magnification.FullScreenMagnificationController; +import com.android.server.accessibility.magnification.MagnificationConnectionManager; import com.android.server.accessibility.magnification.MagnificationController; import com.android.server.accessibility.magnification.MagnificationProcessor; -import com.android.server.accessibility.magnification.WindowMagnificationManager; import com.android.server.accessibility.test.MessageCapturingHandler; import com.android.server.pm.UserManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal; @@ -156,7 +156,7 @@ public class AccessibilityManagerServiceTest { @Mock private UserManagerInternal mMockUserManagerInternal; @Mock private IBinder mMockBinder; @Mock private IAccessibilityServiceClient mMockServiceClient; - @Mock private WindowMagnificationManager mMockWindowMagnificationMgr; + @Mock private MagnificationConnectionManager mMockMagnificationConnectionManager; @Mock private MagnificationController mMockMagnificationController; @Mock private FullScreenMagnificationController mMockFullScreenMagnificationController; @Mock private ProxyManager mProxyManager; @@ -180,8 +180,8 @@ public class AccessibilityManagerServiceTest { UserManagerInternal.class, mMockUserManagerInternal); mInputFilter = Mockito.mock(FakeInputFilter.class); - when(mMockMagnificationController.getWindowMagnificationMgr()).thenReturn( - mMockWindowMagnificationMgr); + when(mMockMagnificationController.getMagnificationConnectionManager()).thenReturn( + mMockMagnificationConnectionManager); when(mMockMagnificationController.getFullScreenMagnificationController()).thenReturn( mMockFullScreenMagnificationController); when(mMockMagnificationController.supportWindowMagnification()).thenReturn(true); @@ -530,7 +530,7 @@ public class AccessibilityManagerServiceTest { // Invokes client change to trigger onUserStateChanged. mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false); - verify(mMockWindowMagnificationMgr).requestConnection(true); + verify(mMockMagnificationConnectionManager).requestConnection(true); } @SmallTest @@ -547,7 +547,7 @@ public class AccessibilityManagerServiceTest { // Invokes client change to trigger onUserStateChanged. mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false); - verify(mMockWindowMagnificationMgr).requestConnection(true); + verify(mMockMagnificationConnectionManager).requestConnection(true); } @SmallTest @@ -565,7 +565,7 @@ public class AccessibilityManagerServiceTest { // Invokes client change to trigger onUserStateChanged. mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false); - verify(mMockWindowMagnificationMgr).requestConnection(false); + verify(mMockMagnificationConnectionManager).requestConnection(false); } @SmallTest @@ -583,7 +583,7 @@ public class AccessibilityManagerServiceTest { // Invokes client change to trigger onUserStateChanged. mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false); - verify(mMockWindowMagnificationMgr).requestConnection(true); + verify(mMockMagnificationConnectionManager).requestConnection(true); } @SmallTest @@ -602,7 +602,7 @@ public class AccessibilityManagerServiceTest { // Invokes client change to trigger onUserStateChanged. mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false); - verify(mMockWindowMagnificationMgr).requestConnection(false); + verify(mMockMagnificationConnectionManager).requestConnection(false); } @SmallTest @@ -616,7 +616,7 @@ public class AccessibilityManagerServiceTest { // Invokes client change to trigger onUserStateChanged. mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false); - verify(mMockWindowMagnificationMgr).requestConnection(true); + verify(mMockMagnificationConnectionManager).requestConnection(true); } @SmallTest @@ -630,7 +630,8 @@ public class AccessibilityManagerServiceTest { // Invokes client change to trigger onUserStateChanged. mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false); - verify(mMockWindowMagnificationMgr, atLeastOnce()).removeMagnificationButton(anyInt()); + verify(mMockMagnificationConnectionManager, atLeastOnce()) + .removeMagnificationButton(anyInt()); } @SmallTest @@ -644,7 +645,7 @@ public class AccessibilityManagerServiceTest { // Invokes client change to trigger onUserStateChanged. mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false); - verify(mMockWindowMagnificationMgr, never()).removeMagnificationButton(anyInt()); + verify(mMockMagnificationConnectionManager, never()).removeMagnificationButton(anyInt()); } @SmallTest @@ -659,7 +660,8 @@ public class AccessibilityManagerServiceTest { // Invokes client change to trigger onUserStateChanged. mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false); - verify(mMockWindowMagnificationMgr, atLeastOnce()).removeMagnificationButton(anyInt()); + verify(mMockMagnificationConnectionManager, atLeastOnce()) + .removeMagnificationButton(anyInt()); } @SmallTest @@ -674,7 +676,7 @@ public class AccessibilityManagerServiceTest { // Invokes client change to trigger onUserStateChanged. mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false); - verify(mMockWindowMagnificationMgr, never()).removeMagnificationButton(anyInt()); + verify(mMockMagnificationConnectionManager, never()).removeMagnificationButton(anyInt()); } @Test diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java index a02807fe766c..7829fcc4b44d 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java @@ -39,9 +39,9 @@ import android.accessibilityservice.MagnificationConfig; import android.graphics.Region; import com.android.server.accessibility.magnification.FullScreenMagnificationController; +import com.android.server.accessibility.magnification.MagnificationConnectionManager; 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; @@ -66,21 +66,21 @@ public class MagnificationProcessorTest { @Mock private FullScreenMagnificationController mMockFullScreenMagnificationController; @Mock - private WindowMagnificationManager mMockWindowMagnificationManager; + private MagnificationConnectionManager mMockMagnificationConnectionManager; FullScreenMagnificationControllerStub mFullScreenMagnificationControllerStub; - WindowMagnificationManagerStub mWindowMagnificationManagerStub; + MagnificationManagerStub mMagnificationManagerStub; @Before public void setup() { MockitoAnnotations.initMocks(this); mFullScreenMagnificationControllerStub = new FullScreenMagnificationControllerStub( mMockFullScreenMagnificationController); - mWindowMagnificationManagerStub = new WindowMagnificationManagerStub( - mMockWindowMagnificationManager); + mMagnificationManagerStub = new MagnificationManagerStub( + mMockMagnificationConnectionManager); when(mMockMagnificationController.getFullScreenMagnificationController()).thenReturn( mMockFullScreenMagnificationController); - when(mMockMagnificationController.getWindowMagnificationMgr()).thenReturn( - mMockWindowMagnificationManager); + when(mMockMagnificationController.getMagnificationConnectionManager()).thenReturn( + mMockMagnificationConnectionManager); mMagnificationProcessor = new MagnificationProcessor(mMockMagnificationController); } @@ -194,7 +194,7 @@ public class MagnificationProcessorTest { doAnswer((invocation) -> { ((Region) invocation.getArguments()[1]).set(region); return null; - }).when(mMockWindowMagnificationManager).getMagnificationSourceBounds(eq(TEST_DISPLAY), + }).when(mMockMagnificationConnectionManager).getMagnificationSourceBounds(eq(TEST_DISPLAY), any()); final Region result = new Region(); @@ -286,7 +286,7 @@ public class MagnificationProcessorTest { mMagnificationProcessor.resetCurrentMagnification(TEST_DISPLAY, /* animate= */false); - verify(mMockWindowMagnificationManager).disableWindowMagnification(TEST_DISPLAY, false, + verify(mMockMagnificationConnectionManager).disableWindowMagnification(TEST_DISPLAY, false, null); } @@ -296,7 +296,7 @@ public class MagnificationProcessorTest { mMagnificationProcessor.resetAllIfNeeded(connectionId); verify(mMockFullScreenMagnificationController).resetAllIfNeeded(eq(connectionId)); - verify(mMockWindowMagnificationManager).resetAllIfNeeded(eq(connectionId)); + verify(mMockMagnificationConnectionManager).resetAllIfNeeded(eq(connectionId)); } @Test @@ -450,7 +450,7 @@ public class MagnificationProcessorTest { .setActivated(false).build(); mMagnificationProcessor.setMagnificationConfig(TEST_DISPLAY, config, false, SERVICE_ID); - verify(mMockWindowMagnificationManager) + verify(mMockMagnificationConnectionManager) .disableWindowMagnification(eq(TEST_DISPLAY), anyBoolean()); } @@ -481,11 +481,11 @@ public class MagnificationProcessorTest { mFullScreenMagnificationControllerStub.resetAndStubMethods(); mMockFullScreenMagnificationController.setScaleAndCenter(displayId, config.getScale(), config.getCenterX(), config.getCenterY(), false, SERVICE_ID); - mWindowMagnificationManagerStub.deactivateIfNeed(); + mMagnificationManagerStub.deactivateIfNeed(); } else if (config.getMode() == MAGNIFICATION_MODE_WINDOW) { - mWindowMagnificationManagerStub.resetAndStubMethods(); - mMockWindowMagnificationManager.enableWindowMagnification(displayId, config.getScale(), - config.getCenterX(), config.getCenterY()); + mMagnificationManagerStub.resetAndStubMethods(); + mMockMagnificationConnectionManager.enableWindowMagnification( + displayId, config.getScale(), config.getCenterX(), config.getCenterY()); mFullScreenMagnificationControllerStub.deactivateIfNeed(); } } @@ -568,26 +568,26 @@ public class MagnificationProcessorTest { } } - private static class WindowMagnificationManagerStub { - private final WindowMagnificationManager mWindowMagnificationManager; + private static class MagnificationManagerStub { + private final MagnificationConnectionManager mMagnificationConnectionManager; private float mScale = 1.0f; private float mCenterX = 0; private float mCenterY = 0; private boolean mIsEnabled = false; - WindowMagnificationManagerStub( - WindowMagnificationManager windowMagnificationManager) { - mWindowMagnificationManager = windowMagnificationManager; + MagnificationManagerStub( + MagnificationConnectionManager magnificationConnectionManager) { + mMagnificationConnectionManager = magnificationConnectionManager; } private void stubMethods() { - doAnswer(invocation -> mScale).when(mWindowMagnificationManager).getScale( + doAnswer(invocation -> mScale).when(mMagnificationConnectionManager).getScale( TEST_DISPLAY); - doAnswer(invocation -> mCenterX).when(mWindowMagnificationManager).getCenterX( + doAnswer(invocation -> mCenterX).when(mMagnificationConnectionManager).getCenterX( TEST_DISPLAY); - doAnswer(invocation -> mCenterY).when(mWindowMagnificationManager).getCenterY( + doAnswer(invocation -> mCenterY).when(mMagnificationConnectionManager).getCenterY( TEST_DISPLAY); - doAnswer(invocation -> mIsEnabled).when(mWindowMagnificationManager) + doAnswer(invocation -> mIsEnabled).when(mMagnificationConnectionManager) .isWindowMagnifierEnabled(TEST_DISPLAY); Answer enableWindowMagnificationStubAnswer = invocation -> { @@ -598,10 +598,10 @@ public class MagnificationProcessorTest { return true; }; doAnswer(enableWindowMagnificationStubAnswer).when( - mWindowMagnificationManager).enableWindowMagnification(eq(TEST_DISPLAY), + mMagnificationConnectionManager).enableWindowMagnification(eq(TEST_DISPLAY), anyFloat(), anyFloat(), anyFloat()); doAnswer(enableWindowMagnificationStubAnswer).when( - mWindowMagnificationManager).enableWindowMagnification(eq(TEST_DISPLAY), + mMagnificationConnectionManager).enableWindowMagnification(eq(TEST_DISPLAY), anyFloat(), anyFloat(), anyFloat(), any(), anyInt()); Answer disableWindowMagnificationStubAnswer = invocation -> { @@ -609,15 +609,15 @@ public class MagnificationProcessorTest { return true; }; doAnswer(disableWindowMagnificationStubAnswer).when( - mWindowMagnificationManager).disableWindowMagnification(eq(TEST_DISPLAY), + mMagnificationConnectionManager).disableWindowMagnification(eq(TEST_DISPLAY), anyBoolean()); doAnswer(disableWindowMagnificationStubAnswer).when( - mWindowMagnificationManager).disableWindowMagnification(eq(TEST_DISPLAY), + mMagnificationConnectionManager).disableWindowMagnification(eq(TEST_DISPLAY), anyBoolean(), any()); } public void resetAndStubMethods() { - Mockito.reset(mWindowMagnificationManager); + Mockito.reset(mMagnificationConnectionManager); stubMethods(); } diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java new file mode 100644 index 000000000000..3843e2507df6 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java @@ -0,0 +1,854 @@ +/* + * Copyright (C) 2019 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.magnification; + +import static com.android.server.accessibility.magnification.MockWindowMagnificationConnection.TEST_DISPLAY; +import static com.android.server.accessibility.magnification.MockWindowMagnificationConnection.TEST_DISPLAY_2; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyFloat; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.notNull; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import static java.lang.Float.NaN; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.graphics.PointF; +import android.graphics.Rect; +import android.graphics.Region; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.SystemClock; +import android.os.UserHandle; +import android.provider.Settings; +import android.test.mock.MockContentResolver; +import android.view.InputDevice; +import android.view.MotionEvent; +import android.view.accessibility.IRemoteMagnificationAnimationCallback; +import android.view.accessibility.IWindowMagnificationConnectionCallback; +import android.view.accessibility.MagnificationAnimationCallback; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.filters.FlakyTest; + +import com.android.internal.util.test.FakeSettingsProvider; +import com.android.server.LocalServices; +import com.android.server.accessibility.AccessibilityTraceManager; +import com.android.server.statusbar.StatusBarManagerInternal; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.invocation.InvocationOnMock; + +/** + * Tests for WindowMagnificationManager. + */ +public class MagnificationConnectionManagerTest { + + private static final int CURRENT_USER_ID = UserHandle.USER_SYSTEM; + private static final int SERVICE_ID = 1; + + private MockWindowMagnificationConnection mMockConnection; + @Mock + private Context mContext; + @Mock + private AccessibilityTraceManager mMockTrace; + @Mock + private StatusBarManagerInternal mMockStatusBarManagerInternal; + @Mock + private MagnificationAnimationCallback mAnimationCallback; + @Mock + private MagnificationConnectionManager.Callback mMockCallback; + private MockContentResolver mResolver; + private MagnificationConnectionManager mMagnificationConnectionManager; + + @Before + public void setUp() throws RemoteException { + MockitoAnnotations.initMocks(this); + LocalServices.removeServiceForTest(StatusBarManagerInternal.class); + LocalServices.addService(StatusBarManagerInternal.class, mMockStatusBarManagerInternal); + mResolver = new MockContentResolver(); + mMockConnection = new MockWindowMagnificationConnection(); + mMagnificationConnectionManager = new MagnificationConnectionManager(mContext, new Object(), + mMockCallback, mMockTrace, new MagnificationScaleProvider(mContext)); + + when(mContext.getContentResolver()).thenReturn(mResolver); + stubSetConnection(false); + + mResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); + Settings.Secure.putFloatForUser(mResolver, + Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 2.5f, + CURRENT_USER_ID); + } + + private void stubSetConnection(boolean needDelay) { + doAnswer((InvocationOnMock invocation) -> { + final boolean connect = (Boolean) invocation.getArguments()[0]; + // Simulates setConnection() called by another process. + if (needDelay) { + final Context context = ApplicationProvider.getApplicationContext(); + context.getMainThreadHandler().postDelayed( + () -> { + mMagnificationConnectionManager.setConnection( + connect ? mMockConnection.getConnection() : null); + }, 10); + } else { + mMagnificationConnectionManager.setConnection( + connect ? mMockConnection.getConnection() : null); + } + return true; + }).when(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(anyBoolean()); + } + + @Test + public void setConnection_connectionIsNull_wrapperIsNullAndLinkToDeath() { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + assertTrue(mMagnificationConnectionManager.isConnected()); + verify(mMockConnection.asBinder()).linkToDeath(any(IBinder.DeathRecipient.class), eq(0)); + } + + @Test + public void setConnection_connectionIsNull_setMirrorWindowCallbackAndHasWrapper() + throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + + assertTrue(mMagnificationConnectionManager.isConnected()); + verify(mMockConnection.asBinder()).linkToDeath(any(IBinder.DeathRecipient.class), eq(0)); + verify(mMockConnection.getConnection()).setConnectionCallback( + any(IWindowMagnificationConnectionCallback.class)); + } + + @Test + public void binderDied_hasConnection_wrapperIsNullAndUnlinkToDeath() { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + + mMockConnection.getDeathRecipient().binderDied(); + + assertFalse(mMagnificationConnectionManager.isConnected()); + verify(mMockConnection.asBinder()).unlinkToDeath(mMockConnection.getDeathRecipient(), + 0); + } + + /** + * This test simulates {@link MagnificationConnectionManager#setConnection} is called by thread + * A and then the former connection is called by thread B. In this situation we should keep the + * new connection. + */ + @Test + public void setSecondConnectionAndFormerConnectionBinderDead_hasWrapperAndNotCallUnlinkToDeath() + throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + MockWindowMagnificationConnection secondConnection = + new MockWindowMagnificationConnection(); + + mMagnificationConnectionManager.setConnection(secondConnection.getConnection()); + mMockConnection.getDeathRecipient().binderDied(); + + assertTrue(mMagnificationConnectionManager.isConnected()); + verify(mMockConnection.asBinder()).unlinkToDeath(mMockConnection.getDeathRecipient(), 0); + verify(secondConnection.asBinder(), never()).unlinkToDeath( + secondConnection.getDeathRecipient(), 0); + } + + @Test + public void setNullConnection_hasConnection_wrapperIsNull() throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + + mMagnificationConnectionManager.setConnection(null); + + assertFalse(mMagnificationConnectionManager.isConnected()); + verify(mMockConnection.getConnection()).setConnectionCallback(null); + } + + @Test + public void enableWithAnimation_hasConnection_enableWindowMagnification() + throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2f, 200f, 300f); + + verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(2f), + eq(200f), eq(300f), eq(0f), eq(0f), notNull()); + } + + @Test + public void enableWithCallback_hasConnection_enableWindowMagnification() + throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2f, 200f, 300f, + mAnimationCallback, SERVICE_ID); + + verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(2f), + eq(200f), eq(300f), eq(0f), eq(0f), + any(IRemoteMagnificationAnimationCallback.class)); + verify(mAnimationCallback).onResult(true); + } + + @Test + public void disable_hasConnectionAndEnabled_disableWindowMagnification() + throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN); + + mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false); + + verify(mMockConnection.getConnection()).disableWindowMagnification(eq(TEST_DISPLAY), + notNull()); + } + + @Test + public void disableWithCallback_hasConnectionAndEnabled_disableWindowMagnification() + throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN); + + mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false, + mAnimationCallback); + + verify(mMockConnection.getConnection()).disableWindowMagnification(eq(TEST_DISPLAY), + any(IRemoteMagnificationAnimationCallback.class)); + verify(mAnimationCallback).onResult(true); + } + + @Test + public void isWindowMagnifierEnabled_hasConnectionAndEnabled_returnExpectedValue() { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2f, NaN, NaN); + + assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + } + + @Test + public void getPersistedScale() { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + + assertEquals(mMagnificationConnectionManager.getPersistedScale(TEST_DISPLAY), 2.5f); + } + + @Test + public void persistScale_setValue_expectedValueInProvider() { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2.0f, NaN, NaN); + mMagnificationConnectionManager.setScale(TEST_DISPLAY, 2.5f); + + mMagnificationConnectionManager.persistScale(TEST_DISPLAY); + + assertEquals(Settings.Secure.getFloatForUser(mResolver, + Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 0f, + CURRENT_USER_ID), 2.5f); + } + + @Test + public void persistScale_setValueWhenScaleIsOne_nothingChanged() { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + final float persistedScale = + mMagnificationConnectionManager.getPersistedScale(TEST_DISPLAY); + + mMagnificationConnectionManager.setScale(TEST_DISPLAY, 1.0f); + mMagnificationConnectionManager.persistScale(TEST_DISPLAY); + + assertEquals(Settings.Secure.getFloatForUser(mResolver, + Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 0f, + CURRENT_USER_ID), persistedScale); + } + + @Test + public void scaleSetterGetter_enabledOnTestDisplay_expectedValue() { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2.0f, NaN, NaN); + + mMagnificationConnectionManager.setScale(TEST_DISPLAY, 2.5f); + + assertEquals(mMagnificationConnectionManager.getScale(TEST_DISPLAY), 2.5f); + } + + @Test + public void scaleSetterGetter_scaleIsOutOfRang_getNormalizeValue() { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2.5f, NaN, NaN); + + mMagnificationConnectionManager.setScale(TEST_DISPLAY, 10.0f); + + assertEquals(mMagnificationConnectionManager.getScale(TEST_DISPLAY), + MagnificationScaleProvider.MAX_SCALE); + } + + @FlakyTest(bugId = 297879435) + @Test + public void logTrackingTypingFocus_processScroll_logDuration() { + MagnificationConnectionManager spyMagnificationConnectionManager = spy( + mMagnificationConnectionManager); + spyMagnificationConnectionManager.enableWindowMagnification( + TEST_DISPLAY, 3.0f, 50f, 50f); + spyMagnificationConnectionManager.onImeWindowVisibilityChanged( + TEST_DISPLAY, /* shown */ true); + + spyMagnificationConnectionManager.processScroll(TEST_DISPLAY, 10f, 10f); + + verify(spyMagnificationConnectionManager).logTrackingTypingFocus(anyLong()); + } + + @Test + public void onRectangleOnScreenRequested_trackingDisabledByOnDrag_withoutMovingMagnifier() + throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); + final Region outRegion = new Region(); + mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); + final Rect requestedRect = outRegion.getBounds(); + requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); + mMockConnection.getConnectionCallback().onMove(TEST_DISPLAY); + + mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY, + requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); + + verify(mMockConnection.getConnection(), never()) + .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any()); + } + + + @Test + public void onRectangleOnScreenRequested_trackingDisabledByScroll_withoutMovingMagnifier() + throws RemoteException { + final float distanceX = 10f; + final float distanceY = 10f; + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); + final Region outRegion = new Region(); + mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); + final Rect requestedRect = outRegion.getBounds(); + requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); + mMagnificationConnectionManager.processScroll(TEST_DISPLAY, distanceX, distanceY); + + mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY, + requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); + + verify(mMockConnection.getConnection(), never()) + .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any()); + } + + @Test + public void onRectangleOnScreenRequested_requestRectangleInBound_withoutMovingMagnifier() + throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); + final Region outRegion = new Region(); + mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); + final Rect requestedRect = outRegion.getBounds(); + requestedRect.inset(-10, -10); + + mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY, + requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); + + verify(mMockConnection.getConnection(), never()) + .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any()); + } + @Test + public void onRectangleOnScreenRequested_imeVisibilityDefaultInvisible_withoutMovingMagnifier() + throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + final Region outRegion = new Region(); + mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); + final Rect requestedRect = outRegion.getBounds(); + requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); + + mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY, + requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); + + verify(mMockConnection.getConnection(), never()) + .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any()); + } + + @Test + public void onRectangleOnScreenRequested_trackingEnabledByDefault_movingMagnifier() + throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); + final Region outRegion = new Region(); + mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); + final Rect requestedRect = outRegion.getBounds(); + requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); + + mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY, + requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); + + verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY), + eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()), + any(IRemoteMagnificationAnimationCallback.class)); + } + + @Test + public void onRectangleOnScreenRequested_imeInvisible_withoutMovingMagnifier() + throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); + final Region outRegion = new Region(); + mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); + final Rect requestedRect = outRegion.getBounds(); + requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); + mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, false); + + mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY, + requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); + + verify(mMockConnection.getConnection(), never()) + .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any()); + } + + @Test + public void onRectangleOnScreenRequested_trackingEnabledByDragAndReset_movingMagnifier() + throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); + mMockConnection.getConnectionCallback().onMove(TEST_DISPLAY); + mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); + final Region outRegion = new Region(); + mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); + final Rect requestedRect = outRegion.getBounds(); + requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); + + mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY, + requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); + + verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY), + eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()), + any(IRemoteMagnificationAnimationCallback.class)); + } + + @Test + public void onRectangleOnScreenRequested_followTypingIsDisabled_withoutMovingMagnifier() { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); + final Region beforeRegion = new Region(); + mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion); + final Rect requestedRect = beforeRegion.getBounds(); + requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); + mMagnificationConnectionManager.setMagnificationFollowTypingEnabled(false); + + mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY, + requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); + + final Region afterRegion = new Region(); + mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, afterRegion); + assertEquals(afterRegion, beforeRegion); + } + + @Test + public void onRectangleOnScreenRequested_trackingDisabled_withoutMovingMagnifier() { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); + mMagnificationConnectionManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false); + final Region beforeRegion = new Region(); + mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion); + final Rect requestedRect = beforeRegion.getBounds(); + requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); + + mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY, + requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); + + final Region afterRegion = new Region(); + mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, afterRegion); + assertEquals(afterRegion, beforeRegion); + } + + @Test + public void onRectangleOnScreenRequested_trackingDisabledAndEnabledMagnifier_movingMagnifier() + throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); + mMagnificationConnectionManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false); + final Region beforeRegion = new Region(); + mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion); + final Rect requestedRect = beforeRegion.getBounds(); + requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); + mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false); + // Enabling a window magnifier again will turn on the tracking typing focus functionality. + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, NaN, NaN, NaN); + + mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY, + requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); + + verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY), + eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()), + any(IRemoteMagnificationAnimationCallback.class)); + } + + @Test + public void moveWindowMagnifier_enabled_invokeConnectionMethod() throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2f, NaN, NaN); + + mMagnificationConnectionManager.moveWindowMagnification(TEST_DISPLAY, 200, 300); + verify(mMockConnection.getConnection()).moveWindowMagnifier(TEST_DISPLAY, 200, 300); + } + + @Test + public void showMagnificationButton_hasConnection_invokeConnectionMethod() + throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + + mMagnificationConnectionManager.showMagnificationButton(TEST_DISPLAY, + Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN); + verify(mMockConnection.getConnection()).showMagnificationButton(TEST_DISPLAY, + Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN); + + mMagnificationConnectionManager.removeMagnificationButton(TEST_DISPLAY); + verify(mMockConnection.getConnection()).removeMagnificationButton(TEST_DISPLAY); + } + + @Test + public void removeMagnificationSettingsPanel_hasConnection_invokeConnectionMethod() + throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + + mMagnificationConnectionManager.removeMagnificationSettingsPanel(TEST_DISPLAY); + verify(mMockConnection.getConnection()).removeMagnificationSettingsPanel(TEST_DISPLAY); + } + + @Test + public void onUserMagnificationScaleChanged_hasConnection_invokeConnectionMethod() + throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + + final float testScale = 3f; + mMagnificationConnectionManager.onUserMagnificationScaleChanged( + CURRENT_USER_ID, TEST_DISPLAY, testScale); + verify(mMockConnection.getConnection()).onUserMagnificationScaleChanged( + eq(CURRENT_USER_ID), eq(TEST_DISPLAY), eq(testScale)); + } + + @Test + public void pointersInWindow_magnifierEnabled_returnCorrectValue() throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN); + mMockConnection.getConnectionCallback().onWindowMagnifierBoundsChanged(TEST_DISPLAY, + new Rect(0, 0, 500, 500)); + PointF[] pointersLocation = new PointF[2]; + pointersLocation[0] = new PointF(600, 700); + pointersLocation[1] = new PointF(300, 400); + MotionEvent event = generatePointersDownEvent(pointersLocation); + + assertEquals(mMagnificationConnectionManager.pointersInWindow(TEST_DISPLAY, event), 1); + } + + @Test + public void onPerformScaleAction_magnifierEnabled_notifyAction() throws RemoteException { + final float newScale = 4.0f; + final boolean updatePersistence = true; + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN); + + mMockConnection.getConnectionCallback().onPerformScaleAction( + TEST_DISPLAY, newScale, updatePersistence); + + verify(mMockCallback).onPerformScaleAction( + eq(TEST_DISPLAY), eq(newScale), eq(updatePersistence)); + } + + @Test + public void onAccessibilityActionPerformed_magnifierEnabled_notifyAction() + throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN); + + mMockConnection.getConnectionCallback().onAccessibilityActionPerformed(TEST_DISPLAY); + + verify(mMockCallback).onAccessibilityActionPerformed(eq(TEST_DISPLAY)); + } + + @Test + public void binderDied_windowMagnifierIsEnabled_resetState() throws RemoteException { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN); + + mMockConnection.getDeathRecipient().binderDied(); + + assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + } + + @Test + public void + requestConnectionToNull_disableAllMagnifiersAndRequestWindowMagnificationConnection() + throws RemoteException { + assertTrue(mMagnificationConnectionManager.requestConnection(true)); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN); + + assertTrue(mMagnificationConnectionManager.requestConnection(false)); + + verify(mMockConnection.getConnection()).disableWindowMagnification(TEST_DISPLAY, null); + verify(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(false); + } + + @Test + public void requestConnection_requestWindowMagnificationConnection() throws RemoteException { + assertTrue(mMagnificationConnectionManager.requestConnection(true)); + verify(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(true); + } + + @Test + public void isConnected_requestConnection_expectedValue() throws RemoteException { + mMagnificationConnectionManager.requestConnection(true); + assertTrue(mMagnificationConnectionManager.isConnected()); + + mMagnificationConnectionManager.requestConnection(false); + assertFalse(mMagnificationConnectionManager.isConnected()); + } + + @Test + public void requestConnection_registerAndUnregisterBroadcastReceiver() { + assertTrue(mMagnificationConnectionManager.requestConnection(true)); + verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class)); + + assertTrue(mMagnificationConnectionManager.requestConnection(false)); + verify(mContext).unregisterReceiver(any(BroadcastReceiver.class)); + } + + @Test + public void requestConnectionToNull_expectedGetterResults() { + mMagnificationConnectionManager.requestConnection(true); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, 1, 1); + + mMagnificationConnectionManager.requestConnection(false); + + assertEquals(1f, mMagnificationConnectionManager.getScale(TEST_DISPLAY), 0); + assertTrue(Float.isNaN(mMagnificationConnectionManager.getCenterX(TEST_DISPLAY))); + assertTrue(Float.isNaN(mMagnificationConnectionManager.getCenterY(TEST_DISPLAY))); + final Region bounds = new Region(); + mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, bounds); + assertTrue(bounds.isEmpty()); + } + + @Test + public void enableWindowMagnification_connecting_invokeConnectionMethodAfterConnected() + throws RemoteException { + stubSetConnection(true); + mMagnificationConnectionManager.requestConnection(true); + + assertTrue(mMagnificationConnectionManager.enableWindowMagnification( + TEST_DISPLAY, 3f, 1, 1)); + + // Invoke enableWindowMagnification if the connection is connected. + verify(mMockConnection.getConnection()).enableWindowMagnification( + eq(TEST_DISPLAY), eq(3f), + eq(1f), eq(1f), eq(0f), eq(0f), notNull()); + } + + @Test + public void resetAllMagnification_enabledBySameId_windowMagnifiersDisabled() { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, + 100f, 200f, null, + MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY_2, 3f, + 100f, 200f, null, + MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID); + assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY_2)); + + mMagnificationConnectionManager.resetAllIfNeeded(SERVICE_ID); + + assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY_2)); + } + + @Test + public void resetAllMagnification_enabledByDifferentId_windowMagnifierDisabled() { + final int serviceId2 = SERVICE_ID + 1; + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, + 100f, 200f, null, + MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY_2, 3f, + 100f, 200f, null, + MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER, serviceId2); + assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY_2)); + + mMagnificationConnectionManager.resetAllIfNeeded(SERVICE_ID); + + assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY_2)); + } + + @Test + public void onScreenOff_windowMagnifierIsEnabled_removeButtonAndDisableWindowMagnification() + throws RemoteException { + mMagnificationConnectionManager.requestConnection(true); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2.5f, NaN, NaN); + + mMagnificationConnectionManager.mScreenStateReceiver.onReceive(mContext, + new Intent(Intent.ACTION_SCREEN_OFF)); + + verify(mMockConnection.getConnection()).removeMagnificationButton(TEST_DISPLAY); + verify(mMockConnection.getConnection()).disableWindowMagnification(TEST_DISPLAY, null); + assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + } + + @Test + public void centerGetter_enabledOnTestDisplay_expectedValues() { + mMagnificationConnectionManager.requestConnection(true); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, 100f, 200f); + + assertEquals(mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 100f); + assertEquals(mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 200f); + } + + @Test + public void centerGetter_enabledOnTestDisplayWindowAtCenter_expectedValues() + throws RemoteException { + mMagnificationConnectionManager.requestConnection(true); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, + 100f, 200f, MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER); + + assertEquals(mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 100f); + assertEquals(mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 200f); + + verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(3f), + eq(100f), eq(200f), eq(0f), eq(0f), notNull()); + } + + @Test + public void centerGetter_enabledOnTestDisplayWindowAtLeftTop_expectedValues() + throws RemoteException { + mMagnificationConnectionManager.requestConnection(true); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, + 100f, 200f, MagnificationConnectionManager.WINDOW_POSITION_AT_TOP_LEFT); + + assertEquals(mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 100f); + assertEquals(mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 200f); + + verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(3f), + eq(100f), eq(200f), eq(-1f), eq(-1f), notNull()); + } + + @Test + public void magnifierGetters_disabled_expectedValues() { + mMagnificationConnectionManager.requestConnection(true); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, + 100f, 200f, MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER); + + mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false); + + assertEquals(1f, mMagnificationConnectionManager.getScale(TEST_DISPLAY), 0); + assertTrue(Float.isNaN(mMagnificationConnectionManager.getCenterX(TEST_DISPLAY))); + assertTrue(Float.isNaN(mMagnificationConnectionManager.getCenterY(TEST_DISPLAY))); + final Region bounds = new Region(); + mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, bounds); + assertTrue(bounds.isEmpty()); + } + + @Test + public void onDisplayRemoved_enabledOnTestDisplay_disabled() { + mMagnificationConnectionManager.requestConnection(true); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, 100f, 200f); + + mMagnificationConnectionManager.onDisplayRemoved(TEST_DISPLAY); + + assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + } + + @Test + public void onWindowMagnificationActivationState_magnifierEnabled_notifyActivatedState() { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN); + + verify(mMockCallback).onWindowMagnificationActivationState(TEST_DISPLAY, true); + } + + @Test + public void onWindowMagnificationActivationState_magnifierDisabled_notifyDeactivatedState() { + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN); + mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false); + + verify(mMockCallback).onWindowMagnificationActivationState(TEST_DISPLAY, false); + + Mockito.reset(mMockCallback); + mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false); + + verify(mMockCallback, never()).onWindowMagnificationActivationState(eq(TEST_DISPLAY), + anyBoolean()); + } + + private MotionEvent generatePointersDownEvent(PointF[] pointersLocation) { + final int len = pointersLocation.length; + + final MotionEvent.PointerProperties[] pp = new MotionEvent.PointerProperties[len]; + for (int i = 0; i < len; i++) { + MotionEvent.PointerProperties pointerProperty = new MotionEvent.PointerProperties(); + pointerProperty.id = i; + pointerProperty.toolType = MotionEvent.TOOL_TYPE_FINGER; + pp[i] = pointerProperty; + } + + final MotionEvent.PointerCoords[] pc = new MotionEvent.PointerCoords[len]; + for (int i = 0; i < len; i++) { + MotionEvent.PointerCoords pointerCoord = new MotionEvent.PointerCoords(); + pointerCoord.x = pointersLocation[i].x; + pointerCoord.y = pointersLocation[i].y; + pc[i] = pointerCoord; + } + + return MotionEvent.obtain( + /* downTime */ SystemClock.uptimeMillis(), + /* eventTime */ SystemClock.uptimeMillis(), + /* action */ MotionEvent.ACTION_POINTER_DOWN, + /* pointerCount */ pc.length, + /* pointerProperties */ pp, + /* pointerCoords */ pc, + /* metaState */ 0, + /* buttonState */ 0, + /* xPrecision */ 1.0f, + /* yPrecision */ 1.0f, + /* deviceId */ 0, + /* edgeFlags */ 0, + /* source */ InputDevice.SOURCE_TOUCHSCREEN, + /* flags */ 0); + } + + +} diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java index cfd0289e5650..a83cca1d44db 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java @@ -39,7 +39,7 @@ import org.mockito.MockitoAnnotations; /** * Tests for MagnificationConnectionWrapper. We don't test {@code * MagnificationConnectionWrapper#linkToDeath(IBinder.DeathRecipient)} since it's tested in - * {@link WindowMagnificationManagerTest}. + * {@link MagnificationConnectionManagerTest}. */ public class MagnificationConnectionWrapperTest { diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java index d4c6fad99645..e8cdf35dee13 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java @@ -131,7 +131,7 @@ public class MagnificationControllerTest { private ArgumentCaptor mCallbackArgumentCaptor; private MockWindowMagnificationConnection mMockConnection; - private WindowMagnificationManager mWindowMagnificationManager; + private MagnificationConnectionManager mMagnificationConnectionManager; private MockContentResolver mMockResolver; private MagnificationController mMagnificationController; private final WindowMagnificationMgrCallbackDelegate @@ -205,13 +205,14 @@ public class MagnificationControllerTest { )); mScreenMagnificationController.register(TEST_DISPLAY); - mWindowMagnificationManager = spy(new WindowMagnificationManager(mContext, globalLock, - mWindowMagnificationCallbackDelegate, mTraceManager, mScaleProvider)); + mMagnificationConnectionManager = spy( + new MagnificationConnectionManager(mContext, globalLock, + mWindowMagnificationCallbackDelegate, mTraceManager, mScaleProvider)); mMockConnection = new MockWindowMagnificationConnection(true); - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); mMagnificationController = spy(new MagnificationController(mService, globalLock, mContext, - mScreenMagnificationController, mWindowMagnificationManager, mScaleProvider, + mScreenMagnificationController, mMagnificationConnectionManager, mScaleProvider, ConcurrentUtils.DIRECT_EXECUTOR)); mMagnificationController.setMagnificationCapabilities( Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL); @@ -254,8 +255,10 @@ public class MagnificationControllerTest { mCallbackArgumentCaptor.getValue().onResult(true); mMockConnection.invokeCallbacks(); verify(mTransitionCallBack).onResult(TEST_DISPLAY, true); - assertEquals(MAGNIFIED_CENTER_X, mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 0); - assertEquals(MAGNIFIED_CENTER_Y, mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 0); + assertEquals(MAGNIFIED_CENTER_X, + mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 0); + assertEquals(MAGNIFIED_CENTER_Y, + mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 0); } @Test @@ -297,8 +300,10 @@ public class MagnificationControllerTest { mMockConnection.invokeCallbacks(); verify(mTransitionCallBack).onResult(TEST_DISPLAY, true); - assertEquals(MAGNIFIED_CENTER_X, mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 0); - assertEquals(MAGNIFIED_CENTER_Y, mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 0); + assertEquals(MAGNIFIED_CENTER_X, + mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 0); + assertEquals(MAGNIFIED_CENTER_Y, + mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 0); } @Test @@ -316,7 +321,7 @@ public class MagnificationControllerTest { // The first time is triggered when window mode is activated. // The second time is triggered when activating the window mode again. // The third time is triggered when the transition is completed. - verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY), + verify(mMagnificationConnectionManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY), eq(MODE_WINDOW)); } @@ -330,7 +335,7 @@ public class MagnificationControllerTest { mTransitionCallBack); mMockConnection.invokeCallbacks(); - assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY)); verify(mScreenMagnificationController).setScaleAndCenter(TEST_DISPLAY, DEFAULT_SCALE, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y, true, MAGNIFICATION_GESTURE_HANDLER_ID); @@ -350,7 +355,7 @@ public class MagnificationControllerTest { mTransitionCallBack); mMockConnection.invokeCallbacks(); - assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY)); verify(mScreenMagnificationController).setScaleAndCenter(TEST_DISPLAY, DEFAULT_SCALE, magnificationBounds.exactCenterX(), magnificationBounds.exactCenterY(), true, MAGNIFICATION_GESTURE_HANDLER_ID); @@ -386,11 +391,11 @@ public class MagnificationControllerTest { mTransitionCallBack); // Enable window magnification while animating. - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, DEFAULT_SCALE, + mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, DEFAULT_SCALE, Float.NaN, Float.NaN, null, TEST_SERVICE_ID); mMockConnection.invokeCallbacks(); - assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY)); verify(mScreenMagnificationController, never()).setScaleAndCenter(TEST_DISPLAY, DEFAULT_SCALE, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y, true, MAGNIFICATION_GESTURE_HANDLER_ID); @@ -408,8 +413,10 @@ public class MagnificationControllerTest { verify(mScreenMagnificationController).reset(eq(TEST_DISPLAY), eq(false)); mMockConnection.invokeCallbacks(); - assertEquals(MAGNIFIED_CENTER_X, mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 0); - assertEquals(MAGNIFIED_CENTER_Y, mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 0); + assertEquals(MAGNIFIED_CENTER_X, + mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 0); + assertEquals(MAGNIFIED_CENTER_Y, + mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 0); } @Test @@ -438,7 +445,7 @@ public class MagnificationControllerTest { animate, TEST_SERVICE_ID); mMockConnection.invokeCallbacks(); - assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY)); verify(mScreenMagnificationController).setScaleAndCenter(eq(TEST_DISPLAY), eq(DEFAULT_SCALE), eq(MAGNIFIED_CENTER_X), eq(MAGNIFIED_CENTER_Y), any(MagnificationAnimationCallback.class), eq(TEST_SERVICE_ID)); @@ -564,7 +571,7 @@ public class MagnificationControllerTest { mMagnificationController.onDisplayRemoved(TEST_DISPLAY); verify(mScreenMagnificationController).onDisplayRemoved(TEST_DISPLAY); - verify(mWindowMagnificationManager).onDisplayRemoved(TEST_DISPLAY); + verify(mMagnificationConnectionManager).onDisplayRemoved(TEST_DISPLAY); verify(mScaleProvider).onDisplayRemoved(TEST_DISPLAY); } @@ -573,7 +580,7 @@ public class MagnificationControllerTest { mMagnificationController.updateUserIdIfNeeded(SECOND_USER_ID); verify(mScreenMagnificationController).resetAllIfNeeded(false); - verify(mWindowMagnificationManager).disableAllWindowMagnifiers(); + verify(mMagnificationConnectionManager).disableAllWindowMagnifiers(); verify(mScaleProvider).onUserChanged(SECOND_USER_ID); } @@ -584,7 +591,7 @@ public class MagnificationControllerTest { mMagnificationController.onRequestMagnificationSpec(TEST_DISPLAY, TEST_SERVICE_ID); mMockConnection.invokeCallbacks(); - assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY)); } @Test @@ -594,11 +601,11 @@ public class MagnificationControllerTest { // The first time is trigger when fullscreen mode is activated. // The second time is triggered when magnification spec is changed. - verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY), + verify(mMagnificationConnectionManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY), eq(MODE_FULLSCREEN)); // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel // in current capability and mode, and the magnification is activated. - verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel( + verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel( eq(TEST_DISPLAY)); } @@ -625,8 +632,8 @@ public class MagnificationControllerTest { mMagnificationController.onPerformScaleAction(TEST_DISPLAY, newScale, updatePersistence); - verify(mWindowMagnificationManager).setScale(eq(TEST_DISPLAY), eq(newScale)); - verify(mWindowMagnificationManager, never()).persistScale(eq(TEST_DISPLAY)); + verify(mMagnificationConnectionManager).setScale(eq(TEST_DISPLAY), eq(newScale)); + verify(mMagnificationConnectionManager, never()).persistScale(eq(TEST_DISPLAY)); } @Test @@ -669,7 +676,7 @@ public class MagnificationControllerTest { assertEquals(config.getCenterY(), actualConfig.getCenterY(), 0); assertEquals(config.getScale(), actualConfig.getScale(), 0); - verify(mWindowMagnificationManager).onUserMagnificationScaleChanged( + verify(mMagnificationConnectionManager).onUserMagnificationScaleChanged( /* userId= */ anyInt(), eq(TEST_DISPLAY), eq(config.getScale())); } @@ -677,11 +684,11 @@ public class MagnificationControllerTest { public void onSourceBoundChanged_windowEnabled_notifyMagnificationChanged() throws RemoteException { setMagnificationEnabled(MODE_WINDOW); - reset(mWindowMagnificationManager); + reset(mMagnificationConnectionManager); mMagnificationController.onSourceBoundsChanged(TEST_DISPLAY, TEST_RECT); - verify(mWindowMagnificationManager).onUserMagnificationScaleChanged( + verify(mMagnificationConnectionManager).onUserMagnificationScaleChanged( /* userId= */ anyInt(), eq(TEST_DISPLAY), eq(DEFAULT_SCALE)); } @@ -780,11 +787,11 @@ public class MagnificationControllerTest { // The first time is triggered when window mode is activated. // The second time is triggered when accessibility action performed. - verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY), + verify(mMagnificationConnectionManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY), eq(MODE_WINDOW)); // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel // in current capability and mode, and the magnification is activated. - verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel( + verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel( eq(TEST_DISPLAY)); } @@ -799,10 +806,11 @@ public class MagnificationControllerTest { // The first time is triggered when window mode is activated. // The second time is triggered when accessibility action performed. - verify(mWindowMagnificationManager, times(2)).removeMagnificationButton(eq(TEST_DISPLAY)); + verify(mMagnificationConnectionManager, times(2)) + .removeMagnificationButton(eq(TEST_DISPLAY)); // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel // in current capability and mode, and the magnification is activated. - verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel( + verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel( eq(TEST_DISPLAY)); } @@ -816,7 +824,7 @@ public class MagnificationControllerTest { public void deactivateWindowMagnification_windowActivated_triggerCallbackAndLogUsage() throws RemoteException { setMagnificationEnabled(MODE_WINDOW); - mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, /* clear= */ true); + mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, /* clear= */ true); verify(mMagnificationController).onWindowMagnificationActivationState( eq(TEST_DISPLAY), eq(false)); @@ -828,7 +836,7 @@ public class MagnificationControllerTest { public void setPreferenceMagnificationFollowTypingEnabled_setPrefDisabled_disableAll() { mMagnificationController.setMagnificationFollowTypingEnabled(false); - verify(mWindowMagnificationManager).setMagnificationFollowTypingEnabled(eq(false)); + verify(mMagnificationConnectionManager).setMagnificationFollowTypingEnabled(eq(false)); verify(mScreenMagnificationController).setMagnificationFollowTypingEnabled(eq(false)); } @@ -850,7 +858,7 @@ public class MagnificationControllerTest { verify(mScreenMagnificationController).onRectangleOnScreenRequested(eq(TEST_DISPLAY), eq(TEST_RECT.left), eq(TEST_RECT.top), eq(TEST_RECT.right), eq(TEST_RECT.bottom)); - verify(mWindowMagnificationManager, never()).onRectangleOnScreenRequested(anyInt(), + verify(mMagnificationConnectionManager, never()).onRectangleOnScreenRequested(anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); } @@ -867,7 +875,7 @@ public class MagnificationControllerTest { verify(mScreenMagnificationController, never()).onRectangleOnScreenRequested(anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); - verify(mWindowMagnificationManager, never()).onRectangleOnScreenRequested(anyInt(), + verify(mMagnificationConnectionManager, never()).onRectangleOnScreenRequested(anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); } @@ -880,7 +888,7 @@ public class MagnificationControllerTest { verify(mScreenMagnificationController, never()).onRectangleOnScreenRequested( eq(TEST_DISPLAY), anyInt(), anyInt(), anyInt(), anyInt()); - verify(mWindowMagnificationManager, never()).onRectangleOnScreenRequested(anyInt(), + verify(mMagnificationConnectionManager, never()).onRectangleOnScreenRequested(anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); } @@ -895,7 +903,7 @@ public class MagnificationControllerTest { verify(mScreenMagnificationController, never()).onRectangleOnScreenRequested( eq(TEST_DISPLAY), anyInt(), anyInt(), anyInt(), anyInt()); - verify(mWindowMagnificationManager, never()).onRectangleOnScreenRequested(anyInt(), + verify(mMagnificationConnectionManager, never()).onRectangleOnScreenRequested(anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); } @@ -970,7 +978,8 @@ public class MagnificationControllerTest { mMagnificationController.onFullScreenMagnificationActivationState(TEST_DISPLAY, true); - verify(mWindowMagnificationManager).disableWindowMagnification(eq(TEST_DISPLAY), eq(false)); + verify(mMagnificationConnectionManager) + .disableWindowMagnification(eq(TEST_DISPLAY), eq(false)); } @Test @@ -983,11 +992,11 @@ public class MagnificationControllerTest { // The first time is triggered when fullscreen mode is activated. // The second time is triggered when magnification spec is changed. // The third time is triggered when user interaction changed. - verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY), + verify(mMagnificationConnectionManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY), eq(MODE_FULLSCREEN)); // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel // in current capability and mode, and the magnification is activated. - verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel( + verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel( eq(TEST_DISPLAY)); } @@ -1001,11 +1010,11 @@ public class MagnificationControllerTest { // The first time is triggered when fullscreen mode is activated. // The second time is triggered when magnification spec is changed. // The third time is triggered when user interaction changed. - verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY), + verify(mMagnificationConnectionManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY), eq(MODE_FULLSCREEN)); // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel // in current capability and mode, and the magnification is activated. - verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel( + verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel( eq(TEST_DISPLAY)); } @@ -1018,11 +1027,11 @@ public class MagnificationControllerTest { // The first time is triggered when the window mode is activated. // The second time is triggered when user interaction changed. - verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY), + verify(mMagnificationConnectionManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY), eq(MODE_WINDOW)); // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel // in current capability and mode, and the magnification is activated. - verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel( + verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel( eq(TEST_DISPLAY)); } @@ -1035,11 +1044,11 @@ public class MagnificationControllerTest { // The first time is triggered when the window mode is activated. // The second time is triggered when user interaction changed. - verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY), + verify(mMagnificationConnectionManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY), eq(MODE_WINDOW)); // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel // in current capability and mode, and the magnification is activated. - verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel( + verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel( eq(TEST_DISPLAY)); } @@ -1053,11 +1062,11 @@ public class MagnificationControllerTest { mMagnificationController.onTouchInteractionStart(TEST_DISPLAY, MODE_FULLSCREEN); mMagnificationController.onTouchInteractionEnd(TEST_DISPLAY, MODE_FULLSCREEN); - verify(mWindowMagnificationManager, never()).showMagnificationButton(eq(TEST_DISPLAY), + verify(mMagnificationConnectionManager, never()).showMagnificationButton(eq(TEST_DISPLAY), eq(MODE_FULLSCREEN)); // The first time is triggered when fullscreen mode is activated. // The second time is triggered when magnification spec is changed. - verify(mWindowMagnificationManager, times(2)).removeMagnificationSettingsPanel( + verify(mMagnificationConnectionManager, times(2)).removeMagnificationSettingsPanel( eq(TEST_DISPLAY)); } @@ -1071,9 +1080,9 @@ public class MagnificationControllerTest { mMagnificationController.onTouchInteractionStart(TEST_DISPLAY, MODE_FULLSCREEN); mMagnificationController.onTouchInteractionEnd(TEST_DISPLAY, MODE_FULLSCREEN); - verify(mWindowMagnificationManager, never()).showMagnificationButton(eq(TEST_DISPLAY), + verify(mMagnificationConnectionManager, never()).showMagnificationButton(eq(TEST_DISPLAY), eq(MODE_FULLSCREEN)); - verify(mWindowMagnificationManager, times(2)).removeMagnificationSettingsPanel( + verify(mMagnificationConnectionManager, times(2)).removeMagnificationSettingsPanel( eq(TEST_DISPLAY)); } @@ -1082,11 +1091,11 @@ public class MagnificationControllerTest { throws RemoteException { setMagnificationEnabled(MODE_WINDOW); - verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY), + verify(mMagnificationConnectionManager).showMagnificationButton(eq(TEST_DISPLAY), eq(MODE_WINDOW)); // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel // in current capability and mode, and the magnification is activated. - verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel( + verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel( eq(TEST_DISPLAY)); } @@ -1100,11 +1109,11 @@ public class MagnificationControllerTest { // The first time is triggered when fullscreen mode is activated. // The second time is triggered when magnification spec is changed. // The third time is triggered when fullscreen mode activation state is updated. - verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY), + verify(mMagnificationConnectionManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY), eq(MODE_FULLSCREEN)); // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel // in current capability and mode, and the magnification is activated. - verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel( + verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel( eq(TEST_DISPLAY)); } @@ -1113,10 +1122,10 @@ public class MagnificationControllerTest { throws RemoteException { setMagnificationEnabled(MODE_WINDOW); - mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false); + mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false); - verify(mWindowMagnificationManager).removeMagnificationButton(eq(TEST_DISPLAY)); - verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY)); + verify(mMagnificationConnectionManager).removeMagnificationButton(eq(TEST_DISPLAY)); + verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY)); } @Test @@ -1126,8 +1135,8 @@ public class MagnificationControllerTest { setMagnificationEnabled(MODE_FULLSCREEN); mScreenMagnificationController.reset(TEST_DISPLAY, /* animate= */ true); - verify(mWindowMagnificationManager).removeMagnificationButton(eq(TEST_DISPLAY)); - verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY)); + verify(mMagnificationConnectionManager).removeMagnificationButton(eq(TEST_DISPLAY)); + verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY)); } @Test @@ -1142,10 +1151,10 @@ public class MagnificationControllerTest { // The first time is triggered when fullscreen mode is activated. // The second time is triggered when magnification spec is changed. // The third time is triggered when the disable-magnification callback is triggered. - verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY), + verify(mMagnificationConnectionManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY), eq(MODE_FULLSCREEN)); // It is triggered when the disable-magnification callback is triggered. - verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY)); + verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY)); } @Test @@ -1163,10 +1172,10 @@ public class MagnificationControllerTest { // The first time is triggered when window mode is activated. // The second time is triggered when the disable-magnification callback is triggered. - verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY), + verify(mMagnificationConnectionManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY), eq(MODE_WINDOW)); // It is triggered when the disable-magnification callback is triggered. - verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY)); + verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY)); } @Test @@ -1174,9 +1183,9 @@ public class MagnificationControllerTest { throws RemoteException { setMagnificationEnabled(MODE_WINDOW); - mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false); + mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false); - verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY)); + verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY)); } @Test @@ -1185,7 +1194,7 @@ public class MagnificationControllerTest { setMagnificationEnabled(MODE_FULLSCREEN); mScreenMagnificationController.reset(TEST_DISPLAY, /* animate= */ true); - verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY)); + verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY)); } @Test @@ -1260,17 +1269,17 @@ public class MagnificationControllerTest { private void activateMagnifier(int displayId, int mode, float centerX, float centerY) throws RemoteException { - final boolean windowMagnifying = mWindowMagnificationManager.isWindowMagnifierEnabled( + final boolean windowMagnifying = mMagnificationConnectionManager.isWindowMagnifierEnabled( displayId); if (windowMagnifying) { - mWindowMagnificationManager.disableWindowMagnification(displayId, false); + mMagnificationConnectionManager.disableWindowMagnification(displayId, false); mMockConnection.invokeCallbacks(); } if (mode == MODE_FULLSCREEN) { mScreenMagnificationController.setScaleAndCenter(displayId, DEFAULT_SCALE, centerX, centerY, true, AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID); } else { - mWindowMagnificationManager.enableWindowMagnification(displayId, DEFAULT_SCALE, + mMagnificationConnectionManager.enableWindowMagnification(displayId, DEFAULT_SCALE, centerX, centerY, null, TEST_SERVICE_ID); mMockConnection.invokeCallbacks(); } @@ -1304,10 +1313,10 @@ public class MagnificationControllerTest { } private static class WindowMagnificationMgrCallbackDelegate implements - WindowMagnificationManager.Callback { - private WindowMagnificationManager.Callback mCallback; + MagnificationConnectionManager.Callback { + private MagnificationConnectionManager.Callback mCallback; - public void setDelegate(WindowMagnificationManager.Callback callback) { + public void setDelegate(MagnificationConnectionManager.Callback callback) { mCallback = callback; } diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java index 612a091a6b1b..c4be51f9ecbd 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java @@ -92,7 +92,7 @@ public class WindowMagnificationGestureHandlerTest { public final TestableContext mContext = new TestableContext( InstrumentationRegistry.getInstrumentation().getContext()); - private WindowMagnificationManager mWindowMagnificationManager; + private MagnificationConnectionManager mMagnificationConnectionManager; private MockWindowMagnificationConnection mMockConnection; private SpyWindowMagnificationGestureHandler mWindowMagnificationGestureHandler; private WindowMagnificationGestureHandler mMockWindowMagnificationGestureHandler; @@ -104,23 +104,23 @@ public class WindowMagnificationGestureHandlerTest { @Before public void setUp() throws RemoteException { MockitoAnnotations.initMocks(this); - mWindowMagnificationManager = new WindowMagnificationManager(mContext, new Object(), - mock(WindowMagnificationManager.Callback.class), mMockTrace, + mMagnificationConnectionManager = new MagnificationConnectionManager(mContext, new Object(), + mock(MagnificationConnectionManager.Callback.class), mMockTrace, new MagnificationScaleProvider(mContext)); mMockConnection = new MockWindowMagnificationConnection(); mWindowMagnificationGestureHandler = new SpyWindowMagnificationGestureHandler( - mContext, mWindowMagnificationManager, mMockTrace, mMockCallback, + mContext, mMagnificationConnectionManager, mMockTrace, mMockCallback, /** detectSingleFingerTripleTap= */ true, /** detectTwoFingerTripleTap= */ true, /** detectShortcutTrigger= */ true, DISPLAY_0); mMockWindowMagnificationGestureHandler = mWindowMagnificationGestureHandler.getMockGestureHandler(); - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); + mMagnificationConnectionManager.setConnection(mMockConnection.getConnection()); mWindowMagnificationGestureHandler.setNext(strictMock(EventStreamTransformation.class)); } @After public void tearDown() { - mWindowMagnificationManager.disableWindowMagnification(DISPLAY_0, true); + mMagnificationConnectionManager.disableWindowMagnification(DISPLAY_0, true); } @Test @@ -378,7 +378,7 @@ public class WindowMagnificationGestureHandlerTest { } break; case STATE_SHOW_MAGNIFIER_SHORTCUT: { - mWindowMagnificationManager.disableWindowMagnification(DISPLAY_0, false); + mMagnificationConnectionManager.disableWindowMagnification(DISPLAY_0, false); } break; case STATE_TWO_FINGERS_DOWN: { @@ -423,7 +423,7 @@ public class WindowMagnificationGestureHandlerTest { } private boolean isWindowMagnifierEnabled(int displayId) { - return mWindowMagnificationManager.isWindowMagnifierEnabled(displayId); + return mMagnificationConnectionManager.isWindowMagnifierEnabled(displayId); } private static String stateToString(int state) { @@ -495,13 +495,14 @@ public class WindowMagnificationGestureHandlerTest { private final WindowMagnificationGestureHandler mMockWindowMagnificationGestureHandler; SpyWindowMagnificationGestureHandler(@UiContext Context context, - WindowMagnificationManager windowMagnificationMgr, + MagnificationConnectionManager magnificationConnectionManager, AccessibilityTraceManager trace, Callback callback, boolean detectSingleFingerTripleTap, boolean detectTwoFingerTripleTap, boolean detectShortcutTrigger, int displayId) { - super(context, windowMagnificationMgr, trace, callback, detectSingleFingerTripleTap, - detectTwoFingerTripleTap, detectShortcutTrigger, displayId); + super(context, magnificationConnectionManager, trace, callback, + detectSingleFingerTripleTap, detectTwoFingerTripleTap, + detectShortcutTrigger, displayId); mMockWindowMagnificationGestureHandler = mock(WindowMagnificationGestureHandler.class); } diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java deleted file mode 100644 index 24ad976f6e45..000000000000 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java +++ /dev/null @@ -1,847 +0,0 @@ -/* - * Copyright (C) 2019 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.magnification; - -import static com.android.server.accessibility.magnification.MockWindowMagnificationConnection.TEST_DISPLAY; -import static com.android.server.accessibility.magnification.MockWindowMagnificationConnection.TEST_DISPLAY_2; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyFloat; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.notNull; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertTrue; - -import static java.lang.Float.NaN; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.graphics.PointF; -import android.graphics.Rect; -import android.graphics.Region; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.SystemClock; -import android.os.UserHandle; -import android.provider.Settings; -import android.test.mock.MockContentResolver; -import android.view.InputDevice; -import android.view.MotionEvent; -import android.view.accessibility.IRemoteMagnificationAnimationCallback; -import android.view.accessibility.IWindowMagnificationConnectionCallback; -import android.view.accessibility.MagnificationAnimationCallback; - -import androidx.test.core.app.ApplicationProvider; -import androidx.test.filters.FlakyTest; - -import com.android.internal.util.test.FakeSettingsProvider; -import com.android.server.LocalServices; -import com.android.server.accessibility.AccessibilityTraceManager; -import com.android.server.statusbar.StatusBarManagerInternal; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.mockito.invocation.InvocationOnMock; - -/** - * Tests for WindowMagnificationManager. - */ -public class WindowMagnificationManagerTest { - - private static final int CURRENT_USER_ID = UserHandle.USER_SYSTEM; - private static final int SERVICE_ID = 1; - - private MockWindowMagnificationConnection mMockConnection; - @Mock - private Context mContext; - @Mock - private AccessibilityTraceManager mMockTrace; - @Mock - private StatusBarManagerInternal mMockStatusBarManagerInternal; - @Mock - private MagnificationAnimationCallback mAnimationCallback; - @Mock - private WindowMagnificationManager.Callback mMockCallback; - private MockContentResolver mResolver; - private WindowMagnificationManager mWindowMagnificationManager; - - @Before - public void setUp() throws RemoteException { - MockitoAnnotations.initMocks(this); - LocalServices.removeServiceForTest(StatusBarManagerInternal.class); - LocalServices.addService(StatusBarManagerInternal.class, mMockStatusBarManagerInternal); - mResolver = new MockContentResolver(); - mMockConnection = new MockWindowMagnificationConnection(); - mWindowMagnificationManager = new WindowMagnificationManager(mContext, new Object(), - mMockCallback, mMockTrace, new MagnificationScaleProvider(mContext)); - - when(mContext.getContentResolver()).thenReturn(mResolver); - stubSetConnection(false); - - mResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); - Settings.Secure.putFloatForUser(mResolver, - Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 2.5f, - CURRENT_USER_ID); - } - - private void stubSetConnection(boolean needDelay) { - doAnswer((InvocationOnMock invocation) -> { - final boolean connect = (Boolean) invocation.getArguments()[0]; - // Simulates setConnection() called by another process. - if (needDelay) { - final Context context = ApplicationProvider.getApplicationContext(); - context.getMainThreadHandler().postDelayed( - () -> { - mWindowMagnificationManager.setConnection( - connect ? mMockConnection.getConnection() : null); - }, 10); - } else { - mWindowMagnificationManager.setConnection( - connect ? mMockConnection.getConnection() : null); - } - return true; - }).when(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(anyBoolean()); - } - - @Test - public void setConnection_connectionIsNull_wrapperIsNullAndLinkToDeath() { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - assertNotNull(mWindowMagnificationManager.mConnectionWrapper); - verify(mMockConnection.asBinder()).linkToDeath(any(IBinder.DeathRecipient.class), eq(0)); - } - - @Test - public void setConnection_connectionIsNull_setMirrorWindowCallbackAndHasWrapper() - throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - - assertNotNull(mWindowMagnificationManager.mConnectionWrapper); - verify(mMockConnection.asBinder()).linkToDeath(any(IBinder.DeathRecipient.class), eq(0)); - verify(mMockConnection.getConnection()).setConnectionCallback( - any(IWindowMagnificationConnectionCallback.class)); - } - - @Test - public void binderDied_hasConnection_wrapperIsNullAndUnlinkToDeath() { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - - mMockConnection.getDeathRecipient().binderDied(); - - assertNull(mWindowMagnificationManager.mConnectionWrapper); - verify(mMockConnection.asBinder()).unlinkToDeath(mMockConnection.getDeathRecipient(), - 0); - } - - /** - * This test simulates {@link WindowMagnificationManager#setConnection} is called by thread A - * and then the former connection is called by thread B. In this situation we should keep the - * new connection. - */ - @Test - public void setSecondConnectionAndFormerConnectionBinderDead_hasWrapperAndNotCallUnlinkToDeath() - throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - MockWindowMagnificationConnection secondConnection = - new MockWindowMagnificationConnection(); - - mWindowMagnificationManager.setConnection(secondConnection.getConnection()); - mMockConnection.getDeathRecipient().binderDied(); - - assertNotNull(mWindowMagnificationManager.mConnectionWrapper); - verify(mMockConnection.asBinder()).unlinkToDeath(mMockConnection.getDeathRecipient(), 0); - verify(secondConnection.asBinder(), never()).unlinkToDeath( - secondConnection.getDeathRecipient(), 0); - } - - @Test - public void setNullConnection_hasConnection_wrapperIsNull() throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - - mWindowMagnificationManager.setConnection(null); - - assertNull(mWindowMagnificationManager.mConnectionWrapper); - verify(mMockConnection.getConnection()).setConnectionCallback(null); - } - - @Test - public void enableWithAnimation_hasConnection_enableWindowMagnification() - throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2f, 200f, 300f); - - verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(2f), - eq(200f), eq(300f), eq(0f), eq(0f), notNull()); - } - - @Test - public void enableWithCallback_hasConnection_enableWindowMagnification() - throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2f, 200f, 300f, - mAnimationCallback, SERVICE_ID); - - verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(2f), - eq(200f), eq(300f), eq(0f), eq(0f), - any(IRemoteMagnificationAnimationCallback.class)); - verify(mAnimationCallback).onResult(true); - } - - @Test - public void disable_hasConnectionAndEnabled_disableWindowMagnification() - throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN); - - mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false); - - verify(mMockConnection.getConnection()).disableWindowMagnification(eq(TEST_DISPLAY), - notNull()); - } - - @Test - public void disableWithCallback_hasConnectionAndEnabled_disableWindowMagnification() - throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN); - - mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false, - mAnimationCallback); - - verify(mMockConnection.getConnection()).disableWindowMagnification(eq(TEST_DISPLAY), - any(IRemoteMagnificationAnimationCallback.class)); - verify(mAnimationCallback).onResult(true); - } - - @Test - public void isWindowMagnifierEnabled_hasConnectionAndEnabled_returnExpectedValue() { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); - - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2f, NaN, NaN); - - assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); - } - - @Test - public void getPersistedScale() { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - - assertEquals(mWindowMagnificationManager.getPersistedScale(TEST_DISPLAY), 2.5f); - } - - @Test - public void persistScale_setValue_expectedValueInProvider() { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2.0f, NaN, NaN); - mWindowMagnificationManager.setScale(TEST_DISPLAY, 2.5f); - - mWindowMagnificationManager.persistScale(TEST_DISPLAY); - - assertEquals(Settings.Secure.getFloatForUser(mResolver, - Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 0f, - CURRENT_USER_ID), 2.5f); - } - - @Test - public void persistScale_setValueWhenScaleIsOne_nothingChanged() { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - final float persistedScale = mWindowMagnificationManager.getPersistedScale(TEST_DISPLAY); - - mWindowMagnificationManager.setScale(TEST_DISPLAY, 1.0f); - mWindowMagnificationManager.persistScale(TEST_DISPLAY); - - assertEquals(Settings.Secure.getFloatForUser(mResolver, - Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 0f, - CURRENT_USER_ID), persistedScale); - } - - @Test - public void scaleSetterGetter_enabledOnTestDisplay_expectedValue() { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2.0f, NaN, NaN); - - mWindowMagnificationManager.setScale(TEST_DISPLAY, 2.5f); - - assertEquals(mWindowMagnificationManager.getScale(TEST_DISPLAY), 2.5f); - } - - @Test - public void scaleSetterGetter_scaleIsOutOfRang_getNormalizeValue() { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2.5f, NaN, NaN); - - mWindowMagnificationManager.setScale(TEST_DISPLAY, 10.0f); - - assertEquals(mWindowMagnificationManager.getScale(TEST_DISPLAY), - MagnificationScaleProvider.MAX_SCALE); - } - - @FlakyTest(bugId = 297879435) - @Test - public void logTrackingTypingFocus_processScroll_logDuration() { - WindowMagnificationManager spyWindowMagnificationManager = spy(mWindowMagnificationManager); - spyWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); - spyWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, /* shown */ true); - - spyWindowMagnificationManager.processScroll(TEST_DISPLAY, 10f, 10f); - - verify(spyWindowMagnificationManager).logTrackingTypingFocus(anyLong()); - } - - @Test - public void onRectangleOnScreenRequested_trackingDisabledByOnDrag_withoutMovingMagnifier() - throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); - mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); - final Region outRegion = new Region(); - mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); - final Rect requestedRect = outRegion.getBounds(); - requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); - mMockConnection.getConnectionCallback().onMove(TEST_DISPLAY); - - mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY, - requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); - - verify(mMockConnection.getConnection(), never()) - .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any()); - } - - - @Test - public void onRectangleOnScreenRequested_trackingDisabledByScroll_withoutMovingMagnifier() - throws RemoteException { - final float distanceX = 10f; - final float distanceY = 10f; - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); - mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); - final Region outRegion = new Region(); - mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); - final Rect requestedRect = outRegion.getBounds(); - requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); - mWindowMagnificationManager.processScroll(TEST_DISPLAY, distanceX, distanceY); - - mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY, - requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); - - verify(mMockConnection.getConnection(), never()) - .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any()); - } - - @Test - public void onRectangleOnScreenRequested_requestRectangleInBound_withoutMovingMagnifier() - throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); - mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); - final Region outRegion = new Region(); - mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); - final Rect requestedRect = outRegion.getBounds(); - requestedRect.inset(-10, -10); - - mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY, - requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); - - verify(mMockConnection.getConnection(), never()) - .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any()); - } - @Test - public void onRectangleOnScreenRequested_imeVisibilityDefaultInvisible_withoutMovingMagnifier() - throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); - final Region outRegion = new Region(); - mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); - final Rect requestedRect = outRegion.getBounds(); - requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); - - mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY, - requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); - - verify(mMockConnection.getConnection(), never()) - .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any()); - } - - @Test - public void onRectangleOnScreenRequested_trackingEnabledByDefault_movingMagnifier() - throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); - mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); - final Region outRegion = new Region(); - mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); - final Rect requestedRect = outRegion.getBounds(); - requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); - - mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY, - requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); - - verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY), - eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()), - any(IRemoteMagnificationAnimationCallback.class)); - } - - @Test - public void onRectangleOnScreenRequested_imeInvisible_withoutMovingMagnifier() - throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); - mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); - final Region outRegion = new Region(); - mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); - final Rect requestedRect = outRegion.getBounds(); - requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); - mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, false); - - mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY, - requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); - - verify(mMockConnection.getConnection(), never()) - .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any()); - } - - @Test - public void onRectangleOnScreenRequested_trackingEnabledByDragAndReset_movingMagnifier() - throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); - mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); - mMockConnection.getConnectionCallback().onMove(TEST_DISPLAY); - mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); - final Region outRegion = new Region(); - mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); - final Rect requestedRect = outRegion.getBounds(); - requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); - - mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY, - requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); - - verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY), - eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()), - any(IRemoteMagnificationAnimationCallback.class)); - } - - @Test - public void onRectangleOnScreenRequested_followTypingIsDisabled_withoutMovingMagnifier() { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); - mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); - final Region beforeRegion = new Region(); - mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion); - final Rect requestedRect = beforeRegion.getBounds(); - requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); - mWindowMagnificationManager.setMagnificationFollowTypingEnabled(false); - - mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY, - requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); - - final Region afterRegion = new Region(); - mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, afterRegion); - assertEquals(afterRegion, beforeRegion); - } - - @Test - public void onRectangleOnScreenRequested_trackingDisabled_withoutMovingMagnifier() { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); - mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); - mWindowMagnificationManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false); - final Region beforeRegion = new Region(); - mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion); - final Rect requestedRect = beforeRegion.getBounds(); - requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); - - mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY, - requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); - - final Region afterRegion = new Region(); - mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, afterRegion); - assertEquals(afterRegion, beforeRegion); - } - - @Test - public void onRectangleOnScreenRequested_trackingDisabledAndEnabledMagnifier_movingMagnifier() - throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); - mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); - mWindowMagnificationManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false); - final Region beforeRegion = new Region(); - mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion); - final Rect requestedRect = beforeRegion.getBounds(); - requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); - mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false); - // Enabling a window magnifier again will turn on the tracking typing focus functionality. - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, NaN, NaN, NaN); - - mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY, - requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); - - verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY), - eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()), - any(IRemoteMagnificationAnimationCallback.class)); - } - - @Test - public void moveWindowMagnifier_enabled_invokeConnectionMethod() throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2f, NaN, NaN); - - mWindowMagnificationManager.moveWindowMagnification(TEST_DISPLAY, 200, 300); - verify(mMockConnection.getConnection()).moveWindowMagnifier(TEST_DISPLAY, 200, 300); - } - - @Test - public void showMagnificationButton_hasConnection_invokeConnectionMethod() - throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - - mWindowMagnificationManager.showMagnificationButton(TEST_DISPLAY, - Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN); - verify(mMockConnection.getConnection()).showMagnificationButton(TEST_DISPLAY, - Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN); - - mWindowMagnificationManager.removeMagnificationButton(TEST_DISPLAY); - verify(mMockConnection.getConnection()).removeMagnificationButton(TEST_DISPLAY); - } - - @Test - public void removeMagnificationSettingsPanel_hasConnection_invokeConnectionMethod() - throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - - mWindowMagnificationManager.removeMagnificationSettingsPanel(TEST_DISPLAY); - verify(mMockConnection.getConnection()).removeMagnificationSettingsPanel(TEST_DISPLAY); - } - - @Test - public void onUserMagnificationScaleChanged_hasConnection_invokeConnectionMethod() - throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - - final float testScale = 3f; - mWindowMagnificationManager.onUserMagnificationScaleChanged( - CURRENT_USER_ID, TEST_DISPLAY, testScale); - verify(mMockConnection.getConnection()).onUserMagnificationScaleChanged( - eq(CURRENT_USER_ID), eq(TEST_DISPLAY), eq(testScale)); - } - - @Test - public void pointersInWindow_magnifierEnabled_returnCorrectValue() throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN); - mMockConnection.getConnectionCallback().onWindowMagnifierBoundsChanged(TEST_DISPLAY, - new Rect(0, 0, 500, 500)); - PointF[] pointersLocation = new PointF[2]; - pointersLocation[0] = new PointF(600, 700); - pointersLocation[1] = new PointF(300, 400); - MotionEvent event = generatePointersDownEvent(pointersLocation); - - assertEquals(mWindowMagnificationManager.pointersInWindow(TEST_DISPLAY, event), 1); - } - - @Test - public void onPerformScaleAction_magnifierEnabled_notifyAction() throws RemoteException { - final float newScale = 4.0f; - final boolean updatePersistence = true; - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN); - - mMockConnection.getConnectionCallback().onPerformScaleAction( - TEST_DISPLAY, newScale, updatePersistence); - - verify(mMockCallback).onPerformScaleAction( - eq(TEST_DISPLAY), eq(newScale), eq(updatePersistence)); - } - - @Test - public void onAccessibilityActionPerformed_magnifierEnabled_notifyAction() - throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN); - - mMockConnection.getConnectionCallback().onAccessibilityActionPerformed(TEST_DISPLAY); - - verify(mMockCallback).onAccessibilityActionPerformed(eq(TEST_DISPLAY)); - } - - @Test - public void binderDied_windowMagnifierIsEnabled_resetState() throws RemoteException { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN); - - mMockConnection.getDeathRecipient().binderDied(); - - assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); - } - - @Test - public void - requestConnectionToNull_disableAllMagnifiersAndRequestWindowMagnificationConnection() - throws RemoteException { - assertTrue(mWindowMagnificationManager.requestConnection(true)); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN); - - assertTrue(mWindowMagnificationManager.requestConnection(false)); - - verify(mMockConnection.getConnection()).disableWindowMagnification(TEST_DISPLAY, null); - verify(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(false); - } - - @Test - public void requestConnection_requestWindowMagnificationConnection() throws RemoteException { - assertTrue(mWindowMagnificationManager.requestConnection(true)); - verify(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(true); - } - - @Test - public void isConnected_requestConnection_expectedValue() throws RemoteException { - mWindowMagnificationManager.requestConnection(true); - assertTrue(mWindowMagnificationManager.isConnected()); - - mWindowMagnificationManager.requestConnection(false); - assertFalse(mWindowMagnificationManager.isConnected()); - } - - @Test - public void requestConnection_registerAndUnregisterBroadcastReceiver() { - assertTrue(mWindowMagnificationManager.requestConnection(true)); - verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class)); - - assertTrue(mWindowMagnificationManager.requestConnection(false)); - verify(mContext).unregisterReceiver(any(BroadcastReceiver.class)); - } - - @Test - public void requestConnectionToNull_expectedGetterResults() { - mWindowMagnificationManager.requestConnection(true); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, 1, 1); - - mWindowMagnificationManager.requestConnection(false); - - assertEquals(1f, mWindowMagnificationManager.getScale(TEST_DISPLAY), 0); - assertTrue(Float.isNaN(mWindowMagnificationManager.getCenterX(TEST_DISPLAY))); - assertTrue(Float.isNaN(mWindowMagnificationManager.getCenterY(TEST_DISPLAY))); - final Region bounds = new Region(); - mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, bounds); - assertTrue(bounds.isEmpty()); - } - - @Test - public void enableWindowMagnification_connecting_invokeConnectionMethodAfterConnected() - throws RemoteException { - stubSetConnection(true); - mWindowMagnificationManager.requestConnection(true); - - assertTrue(mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, 1, 1)); - - // Invoke enableWindowMagnification if the connection is connected. - verify(mMockConnection.getConnection()).enableWindowMagnification( - eq(TEST_DISPLAY), eq(3f), - eq(1f), eq(1f), eq(0f), eq(0f), notNull()); - } - - @Test - public void resetAllMagnification_enabledBySameId_windowMagnifiersDisabled() { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, - 100f, 200f, null, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY_2, 3f, - 100f, 200f, null, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID); - assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); - assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY_2)); - - mWindowMagnificationManager.resetAllIfNeeded(SERVICE_ID); - - assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); - assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY_2)); - } - - @Test - public void resetAllMagnification_enabledByDifferentId_windowMagnifierDisabled() { - final int serviceId2 = SERVICE_ID + 1; - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, - 100f, 200f, null, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY_2, 3f, - 100f, 200f, null, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER, serviceId2); - assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); - assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY_2)); - - mWindowMagnificationManager.resetAllIfNeeded(SERVICE_ID); - - assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); - assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY_2)); - } - - @Test - public void onScreenOff_windowMagnifierIsEnabled_removeButtonAndDisableWindowMagnification() - throws RemoteException { - mWindowMagnificationManager.requestConnection(true); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2.5f, NaN, NaN); - - mWindowMagnificationManager.mScreenStateReceiver.onReceive(mContext, - new Intent(Intent.ACTION_SCREEN_OFF)); - - verify(mMockConnection.getConnection()).removeMagnificationButton(TEST_DISPLAY); - verify(mMockConnection.getConnection()).disableWindowMagnification(TEST_DISPLAY, null); - assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); - } - - @Test - public void centerGetter_enabledOnTestDisplay_expectedValues() { - mWindowMagnificationManager.requestConnection(true); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, 100f, 200f); - - assertEquals(mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 100f); - assertEquals(mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 200f); - } - - @Test - public void centerGetter_enabledOnTestDisplayWindowAtCenter_expectedValues() - throws RemoteException { - mWindowMagnificationManager.requestConnection(true); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, - 100f, 200f, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER); - - assertEquals(mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 100f); - assertEquals(mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 200f); - - verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(3f), - eq(100f), eq(200f), eq(0f), eq(0f), notNull()); - } - - @Test - public void centerGetter_enabledOnTestDisplayWindowAtLeftTop_expectedValues() - throws RemoteException { - mWindowMagnificationManager.requestConnection(true); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, - 100f, 200f, WindowMagnificationManager.WINDOW_POSITION_AT_TOP_LEFT); - - assertEquals(mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 100f); - assertEquals(mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 200f); - - verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(3f), - eq(100f), eq(200f), eq(-1f), eq(-1f), notNull()); - } - - @Test - public void magnifierGetters_disabled_expectedValues() { - mWindowMagnificationManager.requestConnection(true); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, - 100f, 200f, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER); - - mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false); - - assertEquals(1f, mWindowMagnificationManager.getScale(TEST_DISPLAY), 0); - assertTrue(Float.isNaN(mWindowMagnificationManager.getCenterX(TEST_DISPLAY))); - assertTrue(Float.isNaN(mWindowMagnificationManager.getCenterY(TEST_DISPLAY))); - final Region bounds = new Region(); - mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, bounds); - assertTrue(bounds.isEmpty()); - } - - @Test - public void onDisplayRemoved_enabledOnTestDisplay_disabled() { - mWindowMagnificationManager.requestConnection(true); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, 100f, 200f); - - mWindowMagnificationManager.onDisplayRemoved(TEST_DISPLAY); - - assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); - } - - @Test - public void onWindowMagnificationActivationState_magnifierEnabled_notifyActivatedState() { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN); - - verify(mMockCallback).onWindowMagnificationActivationState(TEST_DISPLAY, true); - } - - @Test - public void onWindowMagnificationActivationState_magnifierDisabled_notifyDeactivatedState() { - mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN); - mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false); - - verify(mMockCallback).onWindowMagnificationActivationState(TEST_DISPLAY, false); - - Mockito.reset(mMockCallback); - mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false); - - verify(mMockCallback, never()).onWindowMagnificationActivationState(eq(TEST_DISPLAY), - anyBoolean()); - } - - private MotionEvent generatePointersDownEvent(PointF[] pointersLocation) { - final int len = pointersLocation.length; - - final MotionEvent.PointerProperties[] pp = new MotionEvent.PointerProperties[len]; - for (int i = 0; i < len; i++) { - MotionEvent.PointerProperties pointerProperty = new MotionEvent.PointerProperties(); - pointerProperty.id = i; - pointerProperty.toolType = MotionEvent.TOOL_TYPE_FINGER; - pp[i] = pointerProperty; - } - - final MotionEvent.PointerCoords[] pc = new MotionEvent.PointerCoords[len]; - for (int i = 0; i < len; i++) { - MotionEvent.PointerCoords pointerCoord = new MotionEvent.PointerCoords(); - pointerCoord.x = pointersLocation[i].x; - pointerCoord.y = pointersLocation[i].y; - pc[i] = pointerCoord; - } - - return MotionEvent.obtain( - /* downTime */ SystemClock.uptimeMillis(), - /* eventTime */ SystemClock.uptimeMillis(), - /* action */ MotionEvent.ACTION_POINTER_DOWN, - /* pointerCount */ pc.length, - /* pointerProperties */ pp, - /* pointerCoords */ pc, - /* metaState */ 0, - /* buttonState */ 0, - /* xPrecision */ 1.0f, - /* yPrecision */ 1.0f, - /* deviceId */ 0, - /* edgeFlags */ 0, - /* source */ InputDevice.SOURCE_TOUCHSCREEN, - /* flags */ 0); - } - - -} -- cgit v1.2.3-59-g8ed1b From 1ff7172a8f129610459608d04739643034707840 Mon Sep 17 00:00:00 2001 From: Candice Lo Date: Tue, 14 Nov 2023 06:04:51 +0000 Subject: refactor(magnification): Renaming WindowMagnificationConnectionImpl class as MagnificationConnectionImpl The connection handles stuffs more than magnification window mode. Therefore, we would like to rename the class to improve the readability of our codebase and avoid confusion. Bug: 310109308 Test: manually. Renaming the class atest MagnificationTest atest MagnificationSettingsControllerTest atest WindowMagnificationSettingsTest atest WindowMagnificationControllerTest atest MagnificationconnectionManagerTest atest MagnificationControllerTest Flag: NA Change-Id: I1360adabf6c2d80c69d2390b6b842c01391d6139 --- .../systemui/accessibility/Magnification.java | 36 ++--- .../accessibility/MagnificationConnectionImpl.java | 171 +++++++++++++++++++++ .../WindowMagnificationConnectionImpl.java | 171 --------------------- 3 files changed, 189 insertions(+), 189 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java delete mode 100644 packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java index b704f3c89330..89c567188681 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java @@ -71,7 +71,7 @@ public class Magnification implements CoreStartable, CommandQueue.Callbacks { private final DisplayTracker mDisplayTracker; private final AccessibilityLogger mA11yLogger; - private WindowMagnificationConnectionImpl mWindowMagnificationConnectionImpl; + private MagnificationConnectionImpl mMagnificationConnectionImpl; private SysUiState mSysUiState; @VisibleForTesting @@ -321,37 +321,37 @@ public class Magnification implements CoreStartable, CommandQueue.Callbacks { final WindowMagnifierCallback mWindowMagnifierCallback = new WindowMagnifierCallback() { @Override public void onWindowMagnifierBoundsChanged(int displayId, Rect frame) { - if (mWindowMagnificationConnectionImpl != null) { - mWindowMagnificationConnectionImpl.onWindowMagnifierBoundsChanged(displayId, frame); + if (mMagnificationConnectionImpl != null) { + mMagnificationConnectionImpl.onWindowMagnifierBoundsChanged(displayId, frame); } } @Override public void onSourceBoundsChanged(int displayId, Rect sourceBounds) { - if (mWindowMagnificationConnectionImpl != null) { - mWindowMagnificationConnectionImpl.onSourceBoundsChanged(displayId, sourceBounds); + if (mMagnificationConnectionImpl != null) { + mMagnificationConnectionImpl.onSourceBoundsChanged(displayId, sourceBounds); } } @Override public void onPerformScaleAction(int displayId, float scale, boolean updatePersistence) { - if (mWindowMagnificationConnectionImpl != null) { - mWindowMagnificationConnectionImpl.onPerformScaleAction( + if (mMagnificationConnectionImpl != null) { + mMagnificationConnectionImpl.onPerformScaleAction( displayId, scale, updatePersistence); } } @Override public void onAccessibilityActionPerformed(int displayId) { - if (mWindowMagnificationConnectionImpl != null) { - mWindowMagnificationConnectionImpl.onAccessibilityActionPerformed(displayId); + if (mMagnificationConnectionImpl != null) { + mMagnificationConnectionImpl.onAccessibilityActionPerformed(displayId); } } @Override public void onMove(int displayId) { - if (mWindowMagnificationConnectionImpl != null) { - mWindowMagnificationConnectionImpl.onMove(displayId); + if (mMagnificationConnectionImpl != null) { + mMagnificationConnectionImpl.onMove(displayId); } } @@ -394,8 +394,8 @@ public class Magnification implements CoreStartable, CommandQueue.Callbacks { @Override public void onMagnifierScale(int displayId, float scale, boolean updatePersistence) { - if (mWindowMagnificationConnectionImpl != null) { - mWindowMagnificationConnectionImpl.onPerformScaleAction( + if (mMagnificationConnectionImpl != null) { + mMagnificationConnectionImpl.onPerformScaleAction( displayId, scale, updatePersistence); } mA11yLogger.logThrottled( @@ -454,8 +454,8 @@ public class Magnification implements CoreStartable, CommandQueue.Callbacks { if (magnificationSettingsController != null) { magnificationSettingsController.closeMagnificationSettings(); } - if (mWindowMagnificationConnectionImpl != null) { - mWindowMagnificationConnectionImpl.onChangeMagnificationMode(displayId, newMode); + if (mMagnificationConnectionImpl != null) { + mMagnificationConnectionImpl.onChangeMagnificationMode(displayId, newMode); } } } @@ -500,12 +500,12 @@ public class Magnification implements CoreStartable, CommandQueue.Callbacks { } private void setWindowMagnificationConnection() { - if (mWindowMagnificationConnectionImpl == null) { - mWindowMagnificationConnectionImpl = new WindowMagnificationConnectionImpl(this, + if (mMagnificationConnectionImpl == null) { + mMagnificationConnectionImpl = new MagnificationConnectionImpl(this, mHandler); } mAccessibilityManager.setWindowMagnificationConnection( - mWindowMagnificationConnectionImpl); + mMagnificationConnectionImpl); } private void clearWindowMagnificationConnection() { diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java new file mode 100644 index 000000000000..ebedf83178b4 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2020 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.systemui.accessibility; + +import android.annotation.NonNull; +import android.graphics.Rect; +import android.os.Handler; +import android.os.RemoteException; +import android.util.Log; +import android.view.accessibility.IRemoteMagnificationAnimationCallback; +import android.view.accessibility.IWindowMagnificationConnection; +import android.view.accessibility.IWindowMagnificationConnectionCallback; + +import com.android.systemui.dagger.qualifiers.Main; + +/** + * Implementation of window magnification connection. + * + * @see IWindowMagnificationConnection + */ +class MagnificationConnectionImpl extends IWindowMagnificationConnection.Stub { + + private static final String TAG = "WindowMagnificationConnectionImpl"; + + private IWindowMagnificationConnectionCallback mConnectionCallback; + private final Magnification mMagnification; + private final Handler mHandler; + + MagnificationConnectionImpl(@NonNull Magnification magnification, + @Main Handler mainHandler) { + mMagnification = magnification; + mHandler = mainHandler; + } + + @Override + public void enableWindowMagnification(int displayId, float scale, float centerX, float centerY, + float magnificationFrameOffsetRatioX, float magnificationFrameOffsetRatioY, + IRemoteMagnificationAnimationCallback callback) { + mHandler.post( + () -> mMagnification.enableWindowMagnification(displayId, scale, centerX, + centerY, magnificationFrameOffsetRatioX, + magnificationFrameOffsetRatioY, callback)); + } + + @Override + public void setScale(int displayId, float scale) { + mHandler.post(() -> mMagnification.setScale(displayId, scale)); + } + + @Override + public void disableWindowMagnification(int displayId, + IRemoteMagnificationAnimationCallback callback) { + mHandler.post(() -> mMagnification.disableWindowMagnification(displayId, + callback)); + } + + @Override + public void moveWindowMagnifier(int displayId, float offsetX, float offsetY) { + mHandler.post( + () -> mMagnification.moveWindowMagnifier(displayId, offsetX, offsetY)); + } + + @Override + public void moveWindowMagnifierToPosition(int displayId, float positionX, float positionY, + IRemoteMagnificationAnimationCallback callback) { + mHandler.post(() -> mMagnification.moveWindowMagnifierToPositionInternal( + displayId, positionX, positionY, callback)); + } + + @Override + public void showMagnificationButton(int displayId, int magnificationMode) { + mHandler.post( + () -> mMagnification.showMagnificationButton(displayId, magnificationMode)); + } + + @Override + public void removeMagnificationButton(int displayId) { + mHandler.post( + () -> mMagnification.removeMagnificationButton(displayId)); + } + + @Override + public void removeMagnificationSettingsPanel(int display) { + mHandler.post(() -> mMagnification.hideMagnificationSettingsPanel(display)); + } + + @Override + public void onUserMagnificationScaleChanged(int userId, int displayId, float scale) { + mHandler.post(() -> mMagnification.setUserMagnificationScale( + userId, displayId, scale)); + } + + @Override + public void setConnectionCallback(IWindowMagnificationConnectionCallback callback) { + mConnectionCallback = callback; + } + + void onWindowMagnifierBoundsChanged(int displayId, Rect frame) { + if (mConnectionCallback != null) { + try { + mConnectionCallback.onWindowMagnifierBoundsChanged(displayId, frame); + } catch (RemoteException e) { + Log.e(TAG, "Failed to inform bounds changed", e); + } + } + } + + void onSourceBoundsChanged(int displayId, Rect sourceBounds) { + if (mConnectionCallback != null) { + try { + mConnectionCallback.onSourceBoundsChanged(displayId, sourceBounds); + } catch (RemoteException e) { + Log.e(TAG, "Failed to inform source bounds changed", e); + } + } + } + + void onPerformScaleAction(int displayId, float scale, boolean updatePersistence) { + if (mConnectionCallback != null) { + try { + mConnectionCallback.onPerformScaleAction(displayId, scale, updatePersistence); + } catch (RemoteException e) { + Log.e(TAG, "Failed to inform performing scale action", e); + } + } + } + + void onAccessibilityActionPerformed(int displayId) { + if (mConnectionCallback != null) { + try { + mConnectionCallback.onAccessibilityActionPerformed(displayId); + } catch (RemoteException e) { + Log.e(TAG, "Failed to inform an accessibility action is already performed", e); + } + } + } + + void onChangeMagnificationMode(int displayId, int mode) { + if (mConnectionCallback != null) { + try { + mConnectionCallback.onChangeMagnificationMode(displayId, mode); + } catch (RemoteException e) { + Log.e(TAG, "Failed to inform changing magnification mode", e); + } + } + } + + void onMove(int displayId) { + if (mConnectionCallback != null) { + try { + mConnectionCallback.onMove(displayId); + } catch (RemoteException e) { + Log.e(TAG, "Failed to inform taking control by a user", e); + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java deleted file mode 100644 index 5666851f560f..000000000000 --- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2020 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.systemui.accessibility; - -import android.annotation.NonNull; -import android.graphics.Rect; -import android.os.Handler; -import android.os.RemoteException; -import android.util.Log; -import android.view.accessibility.IRemoteMagnificationAnimationCallback; -import android.view.accessibility.IWindowMagnificationConnection; -import android.view.accessibility.IWindowMagnificationConnectionCallback; - -import com.android.systemui.dagger.qualifiers.Main; - -/** - * Implementation of window magnification connection. - * - * @see IWindowMagnificationConnection - */ -class WindowMagnificationConnectionImpl extends IWindowMagnificationConnection.Stub { - - private static final String TAG = "WindowMagnificationConnectionImpl"; - - private IWindowMagnificationConnectionCallback mConnectionCallback; - private final Magnification mMagnification; - private final Handler mHandler; - - WindowMagnificationConnectionImpl(@NonNull Magnification magnification, - @Main Handler mainHandler) { - mMagnification = magnification; - mHandler = mainHandler; - } - - @Override - public void enableWindowMagnification(int displayId, float scale, float centerX, float centerY, - float magnificationFrameOffsetRatioX, float magnificationFrameOffsetRatioY, - IRemoteMagnificationAnimationCallback callback) { - mHandler.post( - () -> mMagnification.enableWindowMagnification(displayId, scale, centerX, - centerY, magnificationFrameOffsetRatioX, - magnificationFrameOffsetRatioY, callback)); - } - - @Override - public void setScale(int displayId, float scale) { - mHandler.post(() -> mMagnification.setScale(displayId, scale)); - } - - @Override - public void disableWindowMagnification(int displayId, - IRemoteMagnificationAnimationCallback callback) { - mHandler.post(() -> mMagnification.disableWindowMagnification(displayId, - callback)); - } - - @Override - public void moveWindowMagnifier(int displayId, float offsetX, float offsetY) { - mHandler.post( - () -> mMagnification.moveWindowMagnifier(displayId, offsetX, offsetY)); - } - - @Override - public void moveWindowMagnifierToPosition(int displayId, float positionX, float positionY, - IRemoteMagnificationAnimationCallback callback) { - mHandler.post(() -> mMagnification.moveWindowMagnifierToPositionInternal( - displayId, positionX, positionY, callback)); - } - - @Override - public void showMagnificationButton(int displayId, int magnificationMode) { - mHandler.post( - () -> mMagnification.showMagnificationButton(displayId, magnificationMode)); - } - - @Override - public void removeMagnificationButton(int displayId) { - mHandler.post( - () -> mMagnification.removeMagnificationButton(displayId)); - } - - @Override - public void removeMagnificationSettingsPanel(int display) { - mHandler.post(() -> mMagnification.hideMagnificationSettingsPanel(display)); - } - - @Override - public void onUserMagnificationScaleChanged(int userId, int displayId, float scale) { - mHandler.post(() -> mMagnification.setUserMagnificationScale( - userId, displayId, scale)); - } - - @Override - public void setConnectionCallback(IWindowMagnificationConnectionCallback callback) { - mConnectionCallback = callback; - } - - void onWindowMagnifierBoundsChanged(int displayId, Rect frame) { - if (mConnectionCallback != null) { - try { - mConnectionCallback.onWindowMagnifierBoundsChanged(displayId, frame); - } catch (RemoteException e) { - Log.e(TAG, "Failed to inform bounds changed", e); - } - } - } - - void onSourceBoundsChanged(int displayId, Rect sourceBounds) { - if (mConnectionCallback != null) { - try { - mConnectionCallback.onSourceBoundsChanged(displayId, sourceBounds); - } catch (RemoteException e) { - Log.e(TAG, "Failed to inform source bounds changed", e); - } - } - } - - void onPerformScaleAction(int displayId, float scale, boolean updatePersistence) { - if (mConnectionCallback != null) { - try { - mConnectionCallback.onPerformScaleAction(displayId, scale, updatePersistence); - } catch (RemoteException e) { - Log.e(TAG, "Failed to inform performing scale action", e); - } - } - } - - void onAccessibilityActionPerformed(int displayId) { - if (mConnectionCallback != null) { - try { - mConnectionCallback.onAccessibilityActionPerformed(displayId); - } catch (RemoteException e) { - Log.e(TAG, "Failed to inform an accessibility action is already performed", e); - } - } - } - - void onChangeMagnificationMode(int displayId, int mode) { - if (mConnectionCallback != null) { - try { - mConnectionCallback.onChangeMagnificationMode(displayId, mode); - } catch (RemoteException e) { - Log.e(TAG, "Failed to inform changing magnification mode", e); - } - } - } - - void onMove(int displayId) { - if (mConnectionCallback != null) { - try { - mConnectionCallback.onMove(displayId); - } catch (RemoteException e) { - Log.e(TAG, "Failed to inform taking control by a user", e); - } - } - } -} -- cgit v1.2.3-59-g8ed1b From 3323fd314a7a9044c14ad4b3f54dee2ef2da5819 Mon Sep 17 00:00:00 2001 From: Candice Lo Date: Tue, 14 Nov 2023 08:21:49 +0000 Subject: refactor(magnification): Rename methods setScale based on its targets We would like to rename the methods setScale() as setScaleForWindowMagnification() to provide more precise method names. Bug: 310109308 Test: manually. Renaming methods atest MagnificationTest atest MagnificationConnectionManagerTest atest MagnificationControllerTest atest WindowMagnificationControllerTest atest MagnificationConnectionWrapperTest Flag: NA Change-Id: I0fca90e2f3e99685dc90ea5df03414fb72c6c4a0 --- .../view/accessibility/IWindowMagnificationConnection.aidl | 2 +- .../src/com/android/systemui/accessibility/Magnification.java | 2 +- .../systemui/accessibility/MagnificationConnectionImpl.java | 4 ++-- .../accessibility/IWindowMagnificationConnectionTest.java | 4 ++-- .../magnification/MagnificationConnectionManager.java | 9 ++++++--- .../magnification/MagnificationConnectionWrapper.java | 6 +++--- .../accessibility/magnification/PanningScalingHandler.java | 1 + .../magnification/MagnificationConnectionWrapperTest.java | 6 +++--- 8 files changed, 19 insertions(+), 15 deletions(-) diff --git a/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl b/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl index a11c6d0ce956..a404bd6f8c97 100644 --- a/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl +++ b/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl @@ -54,7 +54,7 @@ oneway interface IWindowMagnificationConnection { * @param displayId the logical display id. * @param scale magnification scale. */ - void setScale(int displayId, float scale); + void setScaleForWindowMagnification(int displayId, float scale); /** * Disables window magnification on specified display with animation. diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java index 89c567188681..1edb551eb944 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java @@ -220,7 +220,7 @@ public class Magnification implements CoreStartable, CommandQueue.Callbacks { } @MainThread - void setScale(int displayId, float scale) { + void setScaleForWindowMagnification(int displayId, float scale) { final WindowMagnificationController windowMagnificationController = mMagnificationControllerSupplier.get(displayId); if (windowMagnificationController != null) { diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java index ebedf83178b4..5f0d496dd5d1 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java @@ -57,8 +57,8 @@ class MagnificationConnectionImpl extends IWindowMagnificationConnection.Stub { } @Override - public void setScale(int displayId, float scale) { - mHandler.post(() -> mMagnification.setScale(displayId, scale)); + public void setScaleForWindowMagnification(int displayId, float scale) { + mHandler.post(() -> mMagnification.setScaleForWindowMagnification(displayId, scale)); } @Override diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java index d8799e16ebdb..43952824f9a7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java @@ -133,8 +133,8 @@ public class IWindowMagnificationConnectionTest extends SysuiTestCase { } @Test - public void setScale() throws RemoteException { - mIWindowMagnificationConnection.setScale(TEST_DISPLAY, 3.0f); + public void setScaleForWindowMagnification() throws RemoteException { + mIWindowMagnificationConnection.setScaleForWindowMagnification(TEST_DISPLAY, 3.0f); waitForIdleSync(); verify(mWindowMagnificationController).setScale(3.0f); diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java index 975b3d5eb91a..5a3c070819bd 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java @@ -1130,7 +1130,8 @@ public class MagnificationConnectionManager implements } final float normScale = MagnificationScaleProvider.constrainScale(scale); if (Float.compare(mScale, normScale) != 0 - && mMagnificationConnectionManager.setScaleInternal(mDisplayId, scale)) { + && mMagnificationConnectionManager + .setScaleForWindowMagnificationInternal(mDisplayId, scale)) { mScale = normScale; } } @@ -1286,8 +1287,10 @@ public class MagnificationConnectionManager implements animationCallback); } - private boolean setScaleInternal(int displayId, float scale) { - return mConnectionWrapper != null && mConnectionWrapper.setScale(displayId, scale); + @GuardedBy("mLock") + private boolean setScaleForWindowMagnificationInternal(int displayId, float scale) { + return mConnectionWrapper != null + && mConnectionWrapper.setScaleForWindowMagnification(displayId, scale); } @GuardedBy("mLock") diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java index f0c44d64f5ec..20538f167656 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java @@ -82,16 +82,16 @@ class MagnificationConnectionWrapper { return true; } - boolean setScale(int displayId, float scale) { + boolean setScaleForWindowMagnification(int displayId, float scale) { if (mTrace.isA11yTracingEnabledForTypes(FLAGS_WINDOW_MAGNIFICATION_CONNECTION)) { mTrace.logTrace(TAG + ".setScale", FLAGS_WINDOW_MAGNIFICATION_CONNECTION, "displayId=" + displayId + ";scale=" + scale); } try { - mConnection.setScale(displayId, scale); + mConnection.setScaleForWindowMagnification(displayId, scale); } catch (RemoteException e) { if (DBG) { - Slog.e(TAG, "Error calling setScale()", e); + Slog.e(TAG, "Error calling setScaleForWindowMagnification()", e); } return false; } diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java index 94556282d0d3..6b48d2bacf9d 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java @@ -45,6 +45,7 @@ class PanningScalingHandler extends private static final String TAG = "PanningScalingHandler"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + // TODO(b/312372035): Revisit the scope of usage of the interface interface MagnificationDelegate { boolean processScroll(int displayId, float distanceX, float distanceY); void setScale(int displayId, float scale); diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java index a83cca1d44db..8f85f11b7c49 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java @@ -73,9 +73,9 @@ public class MagnificationConnectionWrapperTest { } @Test - public void setScale() throws RemoteException { - mConnectionWrapper.setScale(TEST_DISPLAY, 3.0f); - verify(mConnection).setScale(TEST_DISPLAY, 3.0f); + public void setScaleForWindowMagnification() throws RemoteException { + mConnectionWrapper.setScaleForWindowMagnification(TEST_DISPLAY, 3.0f); + verify(mConnection).setScaleForWindowMagnification(TEST_DISPLAY, 3.0f); } @Test -- cgit v1.2.3-59-g8ed1b