Merge "Logs accessibility shortcut behavior." into rvc-dev

This commit is contained in:
Jason Hsu
2020-05-10 03:06:30 +00:00
committed by Android (Google) Code Review
5 changed files with 176 additions and 4 deletions

View File

@@ -73,8 +73,11 @@ public class AccessibilityShortcutController {
new ComponentName("com.android.server.accessibility", "ColorInversion");
public static final ComponentName DALTONIZER_COMPONENT_NAME =
new ComponentName("com.android.server.accessibility", "Daltonizer");
// TODO(b/147990389): Use MAGNIFICATION_COMPONENT_NAME to replace.
public static final String MAGNIFICATION_CONTROLLER_NAME =
"com.android.server.accessibility.MagnificationController";
public static final ComponentName MAGNIFICATION_COMPONENT_NAME =
new ComponentName("com.android.server.accessibility", "Magnification");
private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)

View File

@@ -19,10 +19,14 @@ package com.android.internal.accessibility.dialog;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getTargets;
import static com.android.internal.accessibility.util.AccessibilityStatsLogUtils.logAccessibilityButtonLongPressStatus;
import android.annotation.Nullable;
import android.app.Activity;
import android.content.ComponentName;
import android.os.Bundle;
import android.provider.Settings;
import android.text.TextUtils;
@@ -87,6 +91,12 @@ public class AccessibilityButtonChooserActivity extends Activity {
gridview.setAdapter(new ButtonTargetAdapter(mTargets));
gridview.setOnItemClickListener((parent, view, position, id) -> {
final String key = Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT;
String name = mTargets.get(position).getId();
if (name.equals(MAGNIFICATION_CONTROLLER_NAME)) {
name = MAGNIFICATION_COMPONENT_NAME.flattenToString();
}
final ComponentName componentName = ComponentName.unflattenFromString(name);
logAccessibilityButtonLongPressStatus(componentName);
Settings.Secure.putString(getContentResolver(), key, mTargets.get(position).getId());
finish();
});

View File

@@ -0,0 +1,130 @@
/*
* 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.internal.accessibility.util;
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__DISABLED;
import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__ENABLED;
import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__UNKNOWN;
import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON;
import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON_LONG_PRESS;
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 android.content.ComponentName;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.ShortcutType;
import com.android.internal.util.FrameworkStatsLog;
/** Methods for logging accessibility states. */
public final class AccessibilityStatsLogUtils {
private static final int UNKNOWN_STATUS =
ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__UNKNOWN;
private AccessibilityStatsLogUtils() {}
/**
* Logs accessibility feature name that is assigned to the shortcut also its shortcut type.
* Calls this when clicking the shortcut {@link AccessibilityManager#ACCESSIBILITY_BUTTON} or
* {@link AccessibilityManager#ACCESSIBILITY_SHORTCUT_KEY}
*
* @param componentName component name of the accessibility feature
* @param shortcutType accessibility shortcut type {@link ShortcutType}
*/
public static void logAccessibilityShortcutActivated(ComponentName componentName,
@ShortcutType int shortcutType) {
logAccessibilityShortcutActivated(componentName, shortcutType, UNKNOWN_STATUS);
}
/**
* Logs accessibility feature name that is assigned to the shortcut also its shortcut type and
* enabled status. Calls this when clicking the shortcut
* {@link AccessibilityManager#ACCESSIBILITY_BUTTON}
* or {@link AccessibilityManager#ACCESSIBILITY_SHORTCUT_KEY}
*
* @param componentName component name of the accessibility feature
* @param shortcutType accessibility shortcut type
* @param serviceEnabled {@code true} if the service is enabled
*/
public static void logAccessibilityShortcutActivated(ComponentName componentName,
@ShortcutType int shortcutType, boolean serviceEnabled) {
logAccessibilityShortcutActivated(componentName, shortcutType,
convertToLoggingServiceStatus(serviceEnabled));
}
/**
* Logs accessibility feature name that is assigned to the shortcut also its shortcut type and
* status code. Calls this when clicking the shortcut
* {@link AccessibilityManager#ACCESSIBILITY_BUTTON}
* or {@link AccessibilityManager#ACCESSIBILITY_SHORTCUT_KEY}
*
* @param componentName component name of the accessibility feature
* @param shortcutType accessibility shortcut type {@link ShortcutType}
* @param serviceStatus The service status code. 0 denotes unknown_status, 1 denotes enabled, 2
* denotes disabled.
*/
private static void logAccessibilityShortcutActivated(ComponentName componentName,
@ShortcutType int shortcutType, int serviceStatus) {
FrameworkStatsLog.write(FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED,
componentName.flattenToString(), convertToLoggingShortcutType(shortcutType),
serviceStatus);
}
/**
* Logs magnification that is assigned to the triple tap shortcut. Calls this when triggering
* the magnification triple tap shortcut.
*/
public static void logMagnificationTripleTap(boolean enabled) {
FrameworkStatsLog.write(FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED,
MAGNIFICATION_COMPONENT_NAME.flattenToString(),
ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__TRIPLE_TAP,
convertToLoggingServiceStatus(enabled));
}
/**
* Logs accessibility feature name that is assigned to the long pressed accessibility button
* shortcut. Calls this when clicking the long pressed accessibility button shortcut.
*
* @param componentName The component name of the accessibility feature.
*/
public static void logAccessibilityButtonLongPressStatus(ComponentName componentName) {
FrameworkStatsLog.write(FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED,
componentName.flattenToString(),
ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON_LONG_PRESS,
UNKNOWN_STATUS);
}
private static int convertToLoggingShortcutType(@ShortcutType int shortcutType) {
switch (shortcutType) {
case ACCESSIBILITY_BUTTON:
return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON;
case ACCESSIBILITY_SHORTCUT_KEY:
return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__VOLUME_KEY;
}
return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__UNKNOWN_TYPE;
}
private static int convertToLoggingServiceStatus(boolean enabled) {
return enabled ? ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__ENABLED
: ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__DISABLED;
}
}

View File

@@ -20,8 +20,10 @@ import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTT
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
import static android.view.accessibility.AccessibilityManager.ShortcutType;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
import static com.android.internal.accessibility.util.AccessibilityStatsLogUtils.logAccessibilityShortcutActivated;
import static com.android.internal.util.FunctionalUtils.ignoreRemoteException;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import static com.android.server.accessibility.AccessibilityUserState.doesShortcutTargetsStringContain;
@@ -2422,6 +2424,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
// In case user assigned magnification to the given shortcut.
if (targetName.equals(MAGNIFICATION_CONTROLLER_NAME)) {
final boolean enabled = !getMagnificationController().isMagnifying(displayId);
logAccessibilityShortcutActivated(MAGNIFICATION_COMPONENT_NAME, shortcutType, enabled);
sendAccessibilityButtonToInputFilter(displayId);
return;
}
@@ -2431,11 +2435,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
return;
}
// In case user assigned an accessibility framework feature to the given shortcut.
if (performAccessibilityFrameworkFeature(targetComponentName)) {
if (performAccessibilityFrameworkFeature(targetComponentName, shortcutType)) {
return;
}
// In case user assigned an accessibility shortcut target to the given shortcut.
if (performAccessibilityShortcutTargetActivity(displayId, targetComponentName)) {
logAccessibilityShortcutActivated(targetComponentName, shortcutType);
return;
}
// in case user assigned an accessibility service to the given shortcut.
@@ -2445,7 +2450,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
}
private boolean performAccessibilityFrameworkFeature(ComponentName assignedTarget) {
private boolean performAccessibilityFrameworkFeature(ComponentName assignedTarget,
@ShortcutType int shortcutType) {
final Map<ComponentName, ToggleableFrameworkFeatureInfo> frameworkFeatureMap =
AccessibilityShortcutController.getFrameworkShortcutFeaturesMap();
if (!frameworkFeatureMap.containsKey(assignedTarget)) {
@@ -2457,8 +2463,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
featureInfo.getSettingKey(), mCurrentUserId);
// Assuming that the default state will be to have the feature off
if (!TextUtils.equals(featureInfo.getSettingOnValue(), setting.read())) {
logAccessibilityShortcutActivated(assignedTarget, shortcutType, /* serviceEnabled= */
true);
setting.write(featureInfo.getSettingOnValue());
} else {
logAccessibilityShortcutActivated(assignedTarget, shortcutType, /* serviceEnabled= */
false);
setting.write(featureInfo.getSettingOffValue());
}
return true;
@@ -2520,8 +2530,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
if ((targetSdk <= Build.VERSION_CODES.Q && shortcutType == ACCESSIBILITY_SHORTCUT_KEY)
|| (targetSdk > Build.VERSION_CODES.Q && !requestA11yButton)) {
if (serviceConnection == null) {
logAccessibilityShortcutActivated(assignedTarget,
shortcutType, /* serviceEnabled= */ true);
enableAccessibilityServiceLocked(assignedTarget, mCurrentUserId);
} else {
logAccessibilityShortcutActivated(assignedTarget,
shortcutType, /* serviceEnabled= */ false);
disableAccessibilityServiceLocked(assignedTarget, mCurrentUserId);
}
return true;
@@ -2541,6 +2556,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
+ assignedTarget);
return false;
}
// ServiceConnection means service enabled.
logAccessibilityShortcutActivated(assignedTarget, shortcutType, /* serviceEnabled= */
true);
serviceConnection.notifyAccessibilityButtonClickedLocked(displayId);
return true;
}

View File

@@ -24,6 +24,7 @@ import static android.view.MotionEvent.ACTION_POINTER_DOWN;
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;
import static com.android.internal.accessibility.util.AccessibilityStatsLogUtils.logMagnificationTripleTap;
import static com.android.server.accessibility.gestures.GestureUtils.distance;
import static java.lang.Math.abs;
@@ -759,10 +760,17 @@ class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler
// Shortcut acts as the 2 initial taps
if (mShortcutTriggered) return tapCount() + 2 >= numTaps;
return mDetectTripleTap
final boolean multitapTriggered = mDetectTripleTap
&& tapCount() >= numTaps
&& isMultiTap(mPreLastDown, mLastDown)
&& isMultiTap(mPreLastUp, mLastUp);
// Only log the triple tap event, use numTaps to filter.
if (multitapTriggered && numTaps > 2) {
final boolean enabled = mMagnificationController.isMagnifying(mDisplayId);
logMagnificationTripleTap(enabled);
}
return multitapTriggered;
}
private boolean isMultiTap(MotionEvent first, MotionEvent second) {
@@ -885,7 +893,6 @@ class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler
}
private void onTripleTap(MotionEvent up) {
if (DEBUG_DETECTING) {
Slog.i(LOG_TAG, "onTripleTap(); delayed: "
+ MotionEventInfo.toString(mDelayedEventQueue));
@@ -908,6 +915,10 @@ class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler
mViewportDraggingState.mZoomedInBeforeDrag =
mMagnificationController.isMagnifying(mDisplayId);
// Triple tap and hold also belongs to triple tap event.
final boolean enabled = !mViewportDraggingState.mZoomedInBeforeDrag;
logMagnificationTripleTap(enabled);
zoomOn(down.getX(), down.getY());
transitionTo(mViewportDraggingState);