Merge "Logs magnification feature behavior. (1/2)" into sc-dev

This commit is contained in:
Jacky Kao
2021-03-17 07:19:14 +00:00
committed by Android (Google) Code Review
7 changed files with 194 additions and 10 deletions

View File

@@ -16,6 +16,9 @@
package com.android.internal.accessibility.util;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
@@ -28,6 +31,10 @@ import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT
import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__TRIPLE_TAP;
import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__UNKNOWN_TYPE;
import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__VOLUME_KEY;
import static com.android.internal.util.FrameworkStatsLog.MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_ALL;
import static com.android.internal.util.FrameworkStatsLog.MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_FULL_SCREEN;
import static com.android.internal.util.FrameworkStatsLog.MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_UNKNOWN_MODE;
import static com.android.internal.util.FrameworkStatsLog.MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_WINDOW;
import android.content.ComponentName;
import android.view.accessibility.AccessibilityManager;
@@ -113,6 +120,19 @@ public final class AccessibilityStatsLogUtils {
UNKNOWN_STATUS);
}
/**
* Logs the magnification activated mode and its duration of the usage.
* Calls this when the magnification is disabled.
*
* @param mode The activated magnification mode.
* @param duration The duration in milliseconds during the magnification is activated.
*/
public static void logMagnificationUsageState(int mode, long duration) {
FrameworkStatsLog.write(FrameworkStatsLog.MAGNIFICATION_USAGE_REPORTED,
convertToLoggingMagnificationMode(mode),
duration);
}
private static int convertToLoggingShortcutType(@ShortcutType int shortcutType) {
switch (shortcutType) {
case ACCESSIBILITY_BUTTON:
@@ -127,4 +147,18 @@ public final class AccessibilityStatsLogUtils {
return enabled ? ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__ENABLED
: ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__DISABLED;
}
private static int convertToLoggingMagnificationMode(int mode) {
switch (mode) {
case ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN:
return MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_FULL_SCREEN;
case ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW:
return MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_WINDOW;
case ACCESSIBILITY_MAGNIFICATION_MODE_ALL:
return MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_ALL;
default:
return MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_UNKNOWN_MODE;
}
}
}

View File

@@ -118,6 +118,7 @@ public class FullScreenMagnificationController {
private static final int INVALID_ID = -1;
private int mIdOfLastServiceToMagnify = INVALID_ID;
private boolean mMagnificationActivated = false;
DisplayMagnification(int displayId) {
mDisplayId = displayId;
@@ -322,6 +323,13 @@ public class FullScreenMagnificationController {
mSpecAnimationBridge, spec, animationCallback);
mControllerCtx.getHandler().sendMessage(m);
}
final boolean lastMagnificationActivated = mMagnificationActivated;
mMagnificationActivated = spec.scale > 1.0f;
if (mMagnificationActivated != lastMagnificationActivated) {
mMagnificationRequestObserver.onFullScreenMagnificationActivationState(
mMagnificationActivated);
}
}
/**
@@ -1506,5 +1514,14 @@ public class FullScreenMagnificationController {
* @param serviceId the ID of the service requesting the change
*/
void onRequestMagnificationSpec(int displayId, int serviceId);
/**
* Called when the state of the magnification activation is changed.
* It is for the logging data of the magnification activation state.
*
* @param activated {@code true} if the magnification is activated, otherwise {@code false}.
*/
@GuardedBy("mLock")
void onFullScreenMagnificationActivationState(boolean activated);
}
}

View File

@@ -16,6 +16,7 @@
package com.android.server.accessibility.magnification;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
@@ -25,11 +26,13 @@ import android.content.Context;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Slog;
import android.util.SparseArray;
import android.view.accessibility.MagnificationAnimationCallback;
import com.android.internal.accessibility.util.AccessibilityStatsLogUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.accessibility.AccessibilityManagerService;
@@ -51,7 +54,8 @@ import com.android.server.accessibility.AccessibilityManagerService;
* </ol>
*/
public class MagnificationController implements WindowMagnificationManager.Callback,
MagnificationGestureHandler.Callback {
MagnificationGestureHandler.Callback,
FullScreenMagnificationController.MagnificationRequestObserver {
private static final boolean DEBUG = false;
private static final String TAG = "MagnificationController";
@@ -66,6 +70,9 @@ public class MagnificationController implements WindowMagnificationManager.Callb
private WindowMagnificationManager mWindowMagnificationMgr;
private int mMagnificationCapabilities = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
private long mWindowModeEnabledTime = 0;
private long mFullScreenModeEnabledTime = 0;
/**
* A callback to inform the magnification transition result.
*/
@@ -187,7 +194,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb
setDisableMagnificationCallbackLocked(displayId, animationEndCallback);
}
void onRequestMagnificationSpec(int displayId, int serviceId) {
@Override
public void onRequestMagnificationSpec(int displayId, int serviceId) {
synchronized (mLock) {
if (serviceId == AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID) {
return;
@@ -200,6 +208,39 @@ public class MagnificationController implements WindowMagnificationManager.Callb
}
}
// TODO : supporting multi-display (b/182227245).
@Override
public void onWindowMagnificationActivationState(boolean activated) {
if (activated) {
mWindowModeEnabledTime = SystemClock.uptimeMillis();
} else {
logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
SystemClock.uptimeMillis() - mWindowModeEnabledTime);
}
}
@Override
public void onFullScreenMagnificationActivationState(boolean activated) {
if (activated) {
mFullScreenModeEnabledTime = SystemClock.uptimeMillis();
} else {
logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN,
SystemClock.uptimeMillis() - mFullScreenModeEnabledTime);
}
}
/**
* Wrapper method of logging the magnification activated mode and its duration of the usage
* when the magnification is disabled.
*
* @param mode The activated magnification mode.
* @param duration The duration in milliseconds during the magnification is activated.
*/
@VisibleForTesting
public void logMagnificationUsageState(int mode, long duration) {
AccessibilityStatsLogUtils.logMagnificationUsageState(mode, duration);
}
/**
* Updates the active user ID of {@link FullScreenMagnificationController} and {@link
* WindowMagnificationManager}.
@@ -260,7 +301,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
synchronized (mLock) {
if (mFullScreenMagnificationController == null) {
mFullScreenMagnificationController = new FullScreenMagnificationController(mContext,
mAms, mLock, this::onRequestMagnificationSpec);
mAms, mLock, this);
mFullScreenMagnificationController.setUserId(mAms.getCurrentUserIdLocked());
}
}
@@ -340,7 +381,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
mTransitionCallBack = transitionCallBack;
mDisplayId = displayId;
mTargetMode = targetMode;
mCurrentMode = mTargetMode ^ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
mCurrentMode = mTargetMode ^ ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
mCurrentScale = scale;
mCurrentCenter.set(currentCenter);
}

View File

@@ -93,6 +93,13 @@ public class WindowMagnificationManager implements
* @param scale the target scale, or {@link Float#NaN} to leave unchanged
*/
void onPerformScaleAction(int displayId, float scale);
/**
* Called when the state of the magnification activation is changed.
*
* @param activated {@code true} if the magnification is activated, otherwise {@code false}.
*/
void onWindowMagnificationActivationState(boolean activated);
}
private final Callback mCallback;
@@ -264,6 +271,7 @@ public class WindowMagnificationManager implements
*/
void enableWindowMagnification(int displayId, float scale, float centerX, float centerY,
@Nullable MagnificationAnimationCallback animationCallback) {
final boolean enabled;
synchronized (mLock) {
if (mConnectionWrapper == null) {
return;
@@ -272,9 +280,13 @@ public class WindowMagnificationManager implements
if (magnifier == null) {
magnifier = createWindowMagnifier(displayId);
}
magnifier.enableWindowMagnificationInternal(scale, centerX, centerY,
enabled = magnifier.enableWindowMagnificationInternal(scale, centerX, centerY,
animationCallback);
}
if (enabled) {
mCallback.onWindowMagnificationActivationState(true);
}
}
/**
@@ -296,16 +308,21 @@ public class WindowMagnificationManager implements
*/
void disableWindowMagnification(int displayId, boolean clear,
MagnificationAnimationCallback animationCallback) {
final boolean disabled;
synchronized (mLock) {
WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
if (magnifier == null || mConnectionWrapper == null) {
return;
}
magnifier.disableWindowMagnificationInternal(animationCallback);
disabled = magnifier.disableWindowMagnificationInternal(animationCallback);
if (clear) {
mWindowMagnifiers.delete(displayId);
}
}
if (disabled) {
mCallback.onWindowMagnificationActivationState(false);
}
}
/**
@@ -560,26 +577,35 @@ public class WindowMagnificationManager implements
}
@GuardedBy("mLock")
void enableWindowMagnificationInternal(float scale, float centerX, float centerY,
boolean enableWindowMagnificationInternal(float scale, float centerX, float centerY,
@Nullable MagnificationAnimationCallback animationCallback) {
if (mEnabled) {
return;
return false;
}
final float normScale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
if (mWindowMagnificationManager.enableWindowMagnificationInternal(mDisplayId, normScale,
centerX, centerY, animationCallback)) {
mScale = normScale;
mEnabled = true;
return true;
}
return false;
}
@GuardedBy("mLock")
void disableWindowMagnificationInternal(
boolean disableWindowMagnificationInternal(
@Nullable MagnificationAnimationCallback animationResultCallback) {
if (mEnabled && mWindowMagnificationManager.disableWindowMagnificationInternal(
if (!mEnabled) {
return false;
}
if (mWindowMagnificationManager.disableWindowMagnificationInternal(
mDisplayId, animationResultCallback)) {
mEnabled = false;
return true;
}
return false;
}
@GuardedBy("mLock")

View File

@@ -1114,6 +1114,30 @@ public class FullScreenMagnificationControllerTest {
argThat(closeTo(newEndSpec)));
}
@Test
public void testSetScale_toMagnifying_shouldNotifyActivatedState() {
setScaleToMagnifying();
verify(mRequestObserver).onFullScreenMagnificationActivationState(eq(true));
}
@Test
public void testReset_afterMagnifying_shouldNotifyDeactivatedState() {
setScaleToMagnifying();
mFullScreenMagnificationController.reset(DISPLAY_0, mAnimationCallback);
verify(mRequestObserver).onFullScreenMagnificationActivationState(eq(false));
}
private void setScaleToMagnifying() {
register(DISPLAY_0);
float scale = 2.0f;
PointF pivotPoint = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
mFullScreenMagnificationController.setScale(DISPLAY_0, scale, pivotPoint.x, pivotPoint.y,
false, SERVICE_ID_1);
}
private void initMockWindowManager() {
for (int i = 0; i < DISPLAY_COUNT; i++) {
when(mMockWindowManager.setMagnificationCallbacks(eq(i), any())).thenReturn(true);

View File

@@ -16,6 +16,9 @@
package com.android.server.accessibility.magnification;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
import static com.android.server.accessibility.AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID;
import static org.junit.Assert.assertEquals;
@@ -24,6 +27,7 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
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.nullable;
import static org.mockito.Mockito.doAnswer;
@@ -282,6 +286,27 @@ public class MagnificationControllerTest {
verify(mWindowMagnificationManager).persistScale(eq(TEST_DISPLAY));
}
@Test
public void onWindowMagnificationActivationState_windowActivated_logWindowDuration() {
mMagnificationController.onWindowMagnificationActivationState(true);
mMagnificationController.onWindowMagnificationActivationState(false);
verify(mMagnificationController).logMagnificationUsageState(
eq(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW), anyLong());
}
@Test
public void
onFullScreenMagnificationActivationState_fullScreenActivated_logFullScreenDuration() {
mMagnificationController.onFullScreenMagnificationActivationState(true);
mMagnificationController.onFullScreenMagnificationActivationState(false);
verify(mMagnificationController).logMagnificationUsageState(
eq(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN), anyLong());
}
@Test
public void onTouchInteractionStart_fullScreenAndCapabilitiesAll_showMagnificationButton()
throws RemoteException {

View File

@@ -392,6 +392,23 @@ public class WindowMagnificationManagerTest {
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(eq(true));
}
@Test
public void onWindowMagnificationActivationState_magnifierDisabled_notifyDeactivatedState() {
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, true);
verify(mMockCallback).onWindowMagnificationActivationState(eq(false));
}
private MotionEvent generatePointersDownEvent(PointF[] pointersLocation) {
final int len = pointersLocation.length;