1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.accessibility.util; 18 19 import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU; 20 import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_GESTURE; 21 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL; 22 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN; 23 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW; 24 import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON; 25 import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY; 26 27 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME; 28 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__DISABLED; 29 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__ENABLED; 30 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__UNKNOWN; 31 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON; 32 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON_LONG_PRESS; 33 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_FLOATING_MENU; 34 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_GESTURE; 35 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__TRIPLE_TAP; 36 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__UNKNOWN_TYPE; 37 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__VOLUME_KEY; 38 import static com.android.internal.util.FrameworkStatsLog.MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_ALL; 39 import static com.android.internal.util.FrameworkStatsLog.MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_FULL_SCREEN; 40 import static com.android.internal.util.FrameworkStatsLog.MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_UNKNOWN_MODE; 41 import static com.android.internal.util.FrameworkStatsLog.MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_WINDOW; 42 43 import android.content.ComponentName; 44 import android.content.Context; 45 import android.provider.Settings; 46 import android.view.accessibility.AccessibilityManager; 47 import android.view.accessibility.AccessibilityManager.ShortcutType; 48 49 import com.android.internal.util.FrameworkStatsLog; 50 51 /** Methods for logging accessibility states. */ 52 public final class AccessibilityStatsLogUtils { 53 private static final int UNKNOWN_STATUS = 54 ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__UNKNOWN; 55 AccessibilityStatsLogUtils()56 private AccessibilityStatsLogUtils() {} 57 58 /** 59 * Logs accessibility feature name that is assigned to the given {@code shortcutType}. 60 * Calls this when clicking the shortcut {@link AccessibilityManager#ACCESSIBILITY_BUTTON} or 61 * {@link AccessibilityManager#ACCESSIBILITY_SHORTCUT_KEY}. 62 * 63 * @param context context used to retrieve the {@link Settings} provider 64 * @param componentName component name of the accessibility feature 65 * @param shortcutType accessibility shortcut type 66 */ logAccessibilityShortcutActivated(Context context, ComponentName componentName, @ShortcutType int shortcutType)67 public static void logAccessibilityShortcutActivated(Context context, 68 ComponentName componentName, @ShortcutType int shortcutType) { 69 logAccessibilityShortcutActivatedInternal(componentName, 70 convertToLoggingShortcutType(context, shortcutType), UNKNOWN_STATUS); 71 } 72 73 /** 74 * Logs accessibility feature name that is assigned to the given {@code shortcutType} and the 75 * {@code serviceEnabled} status. 76 * Calls this when clicking the shortcut {@link AccessibilityManager#ACCESSIBILITY_BUTTON} 77 * or {@link AccessibilityManager#ACCESSIBILITY_SHORTCUT_KEY}. 78 * 79 * @param context context used to retrieve the {@link Settings} provider 80 * @param componentName component name of the accessibility feature 81 * @param shortcutType accessibility shortcut type 82 * @param serviceEnabled {@code true} if the service is enabled 83 */ logAccessibilityShortcutActivated(Context context, ComponentName componentName, @ShortcutType int shortcutType, boolean serviceEnabled)84 public static void logAccessibilityShortcutActivated(Context context, 85 ComponentName componentName, @ShortcutType int shortcutType, boolean serviceEnabled) { 86 logAccessibilityShortcutActivatedInternal(componentName, 87 convertToLoggingShortcutType(context, shortcutType), 88 convertToLoggingServiceStatus(serviceEnabled)); 89 } 90 91 /** 92 * Logs accessibility feature name that is assigned to the given {@code loggingShortcutType} and 93 * {@code loggingServiceStatus} code. 94 * 95 * @param componentName component name of the accessibility feature 96 * @param loggingShortcutType accessibility shortcut type for logging. 0 denotes 97 * unknown_type, 1 denotes accessibility button, 2 denotes volume 98 * key, 3 denotes triple tap on the screen, 4 denotes long press on 99 * accessibility button, 5 denotes accessibility floating menu. 100 * @param loggingServiceStatus The service status code for logging. 0 denotes unknown_status, 1 101 * denotes enabled, 2 denotes disabled. 102 */ logAccessibilityShortcutActivatedInternal(ComponentName componentName, int loggingShortcutType, int loggingServiceStatus)103 private static void logAccessibilityShortcutActivatedInternal(ComponentName componentName, 104 int loggingShortcutType, int loggingServiceStatus) { 105 FrameworkStatsLog.write(FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED, 106 componentName.flattenToString(), loggingShortcutType, loggingServiceStatus); 107 } 108 109 /** 110 * Logs magnification that is assigned to the triple tap shortcut. Calls this when triggering 111 * the magnification triple tap shortcut. 112 */ logMagnificationTripleTap(boolean enabled)113 public static void logMagnificationTripleTap(boolean enabled) { 114 FrameworkStatsLog.write(FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED, 115 MAGNIFICATION_COMPONENT_NAME.flattenToString(), 116 ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__TRIPLE_TAP, 117 convertToLoggingServiceStatus(enabled)); 118 } 119 120 /** 121 * Logs accessibility feature name that is assigned to the long pressed accessibility button 122 * shortcut. Calls this when clicking the long pressed accessibility button shortcut. 123 * 124 * @param componentName The component name of the accessibility feature. 125 */ logAccessibilityButtonLongPressStatus(ComponentName componentName)126 public static void logAccessibilityButtonLongPressStatus(ComponentName componentName) { 127 FrameworkStatsLog.write(FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED, 128 componentName.flattenToString(), 129 ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON_LONG_PRESS, 130 UNKNOWN_STATUS); 131 } 132 133 /** 134 * Logs the magnification activated mode and its duration of the usage. 135 * Calls this when the magnification is disabled. 136 * 137 * @param mode The activated magnification mode. 138 * @param duration The duration in milliseconds during the magnification is activated. 139 */ logMagnificationUsageState(int mode, long duration)140 public static void logMagnificationUsageState(int mode, long duration) { 141 FrameworkStatsLog.write(FrameworkStatsLog.MAGNIFICATION_USAGE_REPORTED, 142 convertToLoggingMagnificationMode(mode), 143 duration); 144 } 145 146 /** 147 * Logs the activated mode of the magnification when the IME window is shown on the screen. 148 * Calls this when the magnification is enabled and the IME window is shown on the screen. 149 * 150 * @param mode The activated magnification mode. 151 */ logMagnificationModeWithImeOn(int mode)152 public static void logMagnificationModeWithImeOn(int mode) { 153 FrameworkStatsLog.write(FrameworkStatsLog.MAGNIFICATION_MODE_WITH_IME_ON_REPORTED, 154 convertToLoggingMagnificationMode(mode)); 155 } 156 isAccessibilityFloatingMenuEnabled(Context context)157 private static boolean isAccessibilityFloatingMenuEnabled(Context context) { 158 return Settings.Secure.getInt(context.getContentResolver(), 159 Settings.Secure.ACCESSIBILITY_BUTTON_MODE, /* def= */ -1) 160 == ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU; 161 } 162 isAccessibilityGestureEnabled(Context context)163 private static boolean isAccessibilityGestureEnabled(Context context) { 164 return Settings.Secure.getInt(context.getContentResolver(), 165 Settings.Secure.ACCESSIBILITY_BUTTON_MODE, /* def= */ -1) 166 == ACCESSIBILITY_BUTTON_MODE_GESTURE; 167 } 168 convertToLoggingShortcutType(Context context, @ShortcutType int shortcutType)169 private static int convertToLoggingShortcutType(Context context, 170 @ShortcutType int shortcutType) { 171 switch (shortcutType) { 172 case ACCESSIBILITY_BUTTON: 173 if (isAccessibilityFloatingMenuEnabled(context)) { 174 return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_FLOATING_MENU; 175 } else if (isAccessibilityGestureEnabled(context)) { 176 return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_GESTURE; 177 } else { 178 return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON; 179 } 180 case ACCESSIBILITY_SHORTCUT_KEY: 181 return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__VOLUME_KEY; 182 } 183 return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__UNKNOWN_TYPE; 184 } 185 convertToLoggingServiceStatus(boolean enabled)186 private static int convertToLoggingServiceStatus(boolean enabled) { 187 return enabled ? ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__ENABLED 188 : ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__DISABLED; 189 } 190 convertToLoggingMagnificationMode(int mode)191 private static int convertToLoggingMagnificationMode(int mode) { 192 switch (mode) { 193 case ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN: 194 return MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_FULL_SCREEN; 195 case ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW: 196 return MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_WINDOW; 197 case ACCESSIBILITY_MAGNIFICATION_MODE_ALL: 198 return MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_ALL; 199 200 default: 201 return MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_UNKNOWN_MODE; 202 } 203 } 204 } 205