• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 import static com.android.internal.util.FrameworkStatsLog.NON_A11Y_TOOL_SERVICE_WARNING_REPORTED__STATUS__WARNING_CLICKED;
43 import static com.android.internal.util.FrameworkStatsLog.NON_A11Y_TOOL_SERVICE_WARNING_REPORTED__STATUS__WARNING_SERVICE_DISABLED;
44 import static com.android.internal.util.FrameworkStatsLog.NON_A11Y_TOOL_SERVICE_WARNING_REPORTED__STATUS__WARNING_SHOWN;
45 
46 import android.content.ComponentName;
47 import android.content.Context;
48 import android.provider.Settings;
49 import android.view.accessibility.AccessibilityManager;
50 import android.view.accessibility.AccessibilityManager.ShortcutType;
51 
52 import com.android.internal.util.FrameworkStatsLog;
53 
54 /** Methods for logging accessibility states. */
55 public final class AccessibilityStatsLogUtils {
56     /** The status represents an accessibility privacy warning has been shown. */
57     public static int ACCESSIBILITY_PRIVACY_WARNING_STATUS_SHOWN =
58             NON_A11Y_TOOL_SERVICE_WARNING_REPORTED__STATUS__WARNING_SHOWN;
59     /** The status represents an accessibility privacy warning has been clicked to review. */
60     public static int ACCESSIBILITY_PRIVACY_WARNING_STATUS_CLICKED =
61             NON_A11Y_TOOL_SERVICE_WARNING_REPORTED__STATUS__WARNING_CLICKED;
62     /** The status represents an accessibility privacy warning service has been disabled. */
63     public static int ACCESSIBILITY_PRIVACY_WARNING_STATUS_SERVICE_DISABLED =
64             NON_A11Y_TOOL_SERVICE_WARNING_REPORTED__STATUS__WARNING_SERVICE_DISABLED;
65 
66     private static final int UNKNOWN_STATUS =
67             ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__UNKNOWN;
68 
AccessibilityStatsLogUtils()69     private AccessibilityStatsLogUtils() {}
70 
71     /**
72      * Logs accessibility feature name that is assigned to the given {@code shortcutType}.
73      * Calls this when clicking the shortcut {@link AccessibilityManager#ACCESSIBILITY_BUTTON} or
74      * {@link AccessibilityManager#ACCESSIBILITY_SHORTCUT_KEY}.
75      *
76      * @param context context used to retrieve the {@link Settings} provider
77      * @param componentName component name of the accessibility feature
78      * @param shortcutType  accessibility shortcut type
79      */
logAccessibilityShortcutActivated(Context context, ComponentName componentName, @ShortcutType int shortcutType)80     public static void logAccessibilityShortcutActivated(Context context,
81             ComponentName componentName, @ShortcutType int shortcutType) {
82         logAccessibilityShortcutActivatedInternal(componentName,
83                 convertToLoggingShortcutType(context, shortcutType), UNKNOWN_STATUS);
84     }
85 
86     /**
87      * Logs accessibility feature name that is assigned to the given {@code shortcutType} and the
88      * {@code serviceEnabled} status.
89      * Calls this when clicking the shortcut {@link AccessibilityManager#ACCESSIBILITY_BUTTON}
90      * or {@link AccessibilityManager#ACCESSIBILITY_SHORTCUT_KEY}.
91      *
92      * @param context context used to retrieve the {@link Settings} provider
93      * @param componentName  component name of the accessibility feature
94      * @param shortcutType   accessibility shortcut type
95      * @param serviceEnabled {@code true} if the service is enabled
96      */
logAccessibilityShortcutActivated(Context context, ComponentName componentName, @ShortcutType int shortcutType, boolean serviceEnabled)97     public static void logAccessibilityShortcutActivated(Context context,
98             ComponentName componentName, @ShortcutType int shortcutType, boolean serviceEnabled) {
99         logAccessibilityShortcutActivatedInternal(componentName,
100                 convertToLoggingShortcutType(context, shortcutType),
101                 convertToLoggingServiceStatus(serviceEnabled));
102     }
103 
104     /**
105      * Logs accessibility feature name that is assigned to the given {@code loggingShortcutType} and
106      * {@code loggingServiceStatus} code.
107      *
108      * @param componentName        component name of the accessibility feature
109      * @param loggingShortcutType  accessibility shortcut type for logging. 0 denotes
110      *                             unknown_type, 1 denotes accessibility button, 2 denotes volume
111      *                             key, 3 denotes triple tap on the screen, 4 denotes long press on
112      *                             accessibility button, 5 denotes accessibility floating menu.
113      * @param loggingServiceStatus The service status code for logging. 0 denotes unknown_status, 1
114      *                             denotes enabled, 2 denotes disabled.
115      */
logAccessibilityShortcutActivatedInternal(ComponentName componentName, int loggingShortcutType, int loggingServiceStatus)116     private static void logAccessibilityShortcutActivatedInternal(ComponentName componentName,
117             int loggingShortcutType, int loggingServiceStatus) {
118         FrameworkStatsLog.write(FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED,
119                 componentName.flattenToString(), loggingShortcutType, loggingServiceStatus);
120     }
121 
122     /**
123      * Logs magnification that is assigned to the triple tap shortcut. Calls this when triggering
124      * the magnification triple tap shortcut.
125      */
logMagnificationTripleTap(boolean enabled)126     public static void logMagnificationTripleTap(boolean enabled) {
127         FrameworkStatsLog.write(FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED,
128                 MAGNIFICATION_COMPONENT_NAME.flattenToString(),
129                 ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__TRIPLE_TAP,
130                 convertToLoggingServiceStatus(enabled));
131     }
132 
133     /**
134      * Logs accessibility feature name that is assigned to the long pressed accessibility button
135      * shortcut. Calls this when clicking the long pressed accessibility button shortcut.
136      *
137      * @param componentName The component name of the accessibility feature.
138      */
logAccessibilityButtonLongPressStatus(ComponentName componentName)139     public static void logAccessibilityButtonLongPressStatus(ComponentName componentName) {
140         FrameworkStatsLog.write(FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED,
141                 componentName.flattenToString(),
142                 ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON_LONG_PRESS,
143                 UNKNOWN_STATUS);
144     }
145 
146     /**
147      * Logs the magnification activated mode and its duration of the usage.
148      * Calls this when the magnification is disabled.
149      *
150      * @param mode The activated magnification mode.
151      * @param duration The duration in milliseconds during the magnification is activated.
152      */
logMagnificationUsageState(int mode, long duration)153     public static void logMagnificationUsageState(int mode, long duration) {
154         FrameworkStatsLog.write(FrameworkStatsLog.MAGNIFICATION_USAGE_REPORTED,
155                 convertToLoggingMagnificationMode(mode),
156                 duration);
157     }
158 
159     /**
160      * Logs the activated mode of the magnification when the IME window is shown on the screen.
161      * Calls this when the magnification is enabled and the IME window is shown on the screen.
162      *
163      * @param mode The activated magnification mode.
164      */
logMagnificationModeWithImeOn(int mode)165     public static void logMagnificationModeWithImeOn(int mode) {
166         FrameworkStatsLog.write(FrameworkStatsLog.MAGNIFICATION_MODE_WITH_IME_ON_REPORTED,
167                 convertToLoggingMagnificationMode(mode));
168     }
169 
170     /**
171      * Logs the duration for the window magnifier's following typing focus session.
172      *
173      * @param duration The duration of a triple-tap-and-hold activation session.
174      */
logMagnificationFollowTypingFocusSession(long duration)175     public static void logMagnificationFollowTypingFocusSession(long duration) {
176         FrameworkStatsLog.write(
177                 FrameworkStatsLog.MAGNIFICATION_FOLLOW_TYPING_FOCUS_ACTIVATED_SESSION_REPORTED,
178                 duration);
179     }
180 
181     /**
182      * Logs the duration for the magnification session which is activated by the triple tap and
183      * hold gesture.
184      *
185      * @param duration The duration of a triple-tap-and-hold activation session.
186      */
logMagnificationTripleTapAndHoldSession(long duration)187     public static void logMagnificationTripleTapAndHoldSession(long duration) {
188         FrameworkStatsLog.write(
189                 FrameworkStatsLog.MAGNIFICATION_TRIPLE_TAP_AND_HOLD_ACTIVATED_SESSION_REPORTED,
190                 duration);
191     }
192 
193     /**
194      * Logs the warning status of the non-a11yTool service. Calls this when the warning status is
195      * changed.
196      *
197      * @param packageName    The package name of the non-a11yTool service
198      * @param status         The warning status of the non-a11yTool service, it should be one of
199      *                       {@code ACCESSIBILITY_PRIVACY_WARNING_STATUS_SHOWN},{@code
200      *                       ACCESSIBILITY_PRIVACY_WARNING_STATUS_CLICKED} and {@code
201      *                       ACCESSIBILITY_PRIVACY_WARNING_STATUS_SERVICE_DISABLED}
202      * @param durationMillis The duration in milliseconds between current and previous status
203      */
logNonA11yToolServiceWarningReported(String packageName, int status, long durationMillis)204     public static void logNonA11yToolServiceWarningReported(String packageName, int status,
205             long durationMillis) {
206         FrameworkStatsLog.write(FrameworkStatsLog.NON_A11Y_TOOL_SERVICE_WARNING_REPORT,
207                 packageName, status, durationMillis);
208     }
209 
isAccessibilityFloatingMenuEnabled(Context context)210     private static boolean isAccessibilityFloatingMenuEnabled(Context context) {
211         return Settings.Secure.getInt(context.getContentResolver(),
212                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE, /* def= */ -1)
213                 == ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
214     }
215 
isAccessibilityGestureEnabled(Context context)216     private static boolean isAccessibilityGestureEnabled(Context context) {
217         return Settings.Secure.getInt(context.getContentResolver(),
218                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE, /* def= */ -1)
219                 == ACCESSIBILITY_BUTTON_MODE_GESTURE;
220     }
221 
convertToLoggingShortcutType(Context context, @ShortcutType int shortcutType)222     private static int convertToLoggingShortcutType(Context context,
223             @ShortcutType int shortcutType) {
224         switch (shortcutType) {
225             case ACCESSIBILITY_BUTTON:
226                 if (isAccessibilityFloatingMenuEnabled(context)) {
227                     return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_FLOATING_MENU;
228                 } else if (isAccessibilityGestureEnabled(context)) {
229                     return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_GESTURE;
230                 } else {
231                     return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON;
232                 }
233             case ACCESSIBILITY_SHORTCUT_KEY:
234                 return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__VOLUME_KEY;
235         }
236         return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__UNKNOWN_TYPE;
237     }
238 
convertToLoggingServiceStatus(boolean enabled)239     private static int convertToLoggingServiceStatus(boolean enabled) {
240         return enabled ? ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__ENABLED
241                 : ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__DISABLED;
242     }
243 
convertToLoggingMagnificationMode(int mode)244     private static int convertToLoggingMagnificationMode(int mode) {
245         switch (mode) {
246             case ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN:
247                 return MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_FULL_SCREEN;
248             case ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW:
249                 return MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_WINDOW;
250             case ACCESSIBILITY_MAGNIFICATION_MODE_ALL:
251                 return MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_ALL;
252 
253             default:
254                 return MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_UNKNOWN_MODE;
255         }
256     }
257 }
258