• 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 
25 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
26 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
27 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
28 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS;
29 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
30 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__DISABLED;
31 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__ENABLED;
32 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__UNKNOWN;
33 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON;
34 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON_LONG_PRESS;
35 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_FLOATING_MENU;
36 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_GESTURE;
37 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__QUICK_SETTINGS;
38 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__TRIPLE_TAP;
39 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__TWO_FINGER_TRIPLE_TAP;
40 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__UNKNOWN_TYPE;
41 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__VOLUME_KEY;
42 import static com.android.internal.util.FrameworkStatsLog.MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_ALL;
43 import static com.android.internal.util.FrameworkStatsLog.MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_FULL_SCREEN;
44 import static com.android.internal.util.FrameworkStatsLog.MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_UNKNOWN_MODE;
45 import static com.android.internal.util.FrameworkStatsLog.MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_WINDOW;
46 import static com.android.internal.util.FrameworkStatsLog.NON_A11Y_TOOL_SERVICE_WARNING_REPORTED__STATUS__WARNING_CLICKED;
47 import static com.android.internal.util.FrameworkStatsLog.NON_A11Y_TOOL_SERVICE_WARNING_REPORTED__STATUS__WARNING_SERVICE_DISABLED;
48 import static com.android.internal.util.FrameworkStatsLog.NON_A11Y_TOOL_SERVICE_WARNING_REPORTED__STATUS__WARNING_SHOWN;
49 
50 import android.content.ComponentName;
51 import android.content.Context;
52 import android.provider.Settings;
53 
54 import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
55 import com.android.internal.util.FrameworkStatsLog;
56 
57 /** Methods for logging accessibility states. */
58 public final class AccessibilityStatsLogUtils {
59     /** The status represents an accessibility privacy warning has been shown. */
60     public static int ACCESSIBILITY_PRIVACY_WARNING_STATUS_SHOWN =
61             NON_A11Y_TOOL_SERVICE_WARNING_REPORTED__STATUS__WARNING_SHOWN;
62     /** The status represents an accessibility privacy warning has been clicked to review. */
63     public static int ACCESSIBILITY_PRIVACY_WARNING_STATUS_CLICKED =
64             NON_A11Y_TOOL_SERVICE_WARNING_REPORTED__STATUS__WARNING_CLICKED;
65     /** The status represents an accessibility privacy warning service has been disabled. */
66     public static int ACCESSIBILITY_PRIVACY_WARNING_STATUS_SERVICE_DISABLED =
67             NON_A11Y_TOOL_SERVICE_WARNING_REPORTED__STATUS__WARNING_SERVICE_DISABLED;
68 
69     private static final int UNKNOWN_STATUS =
70             ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__UNKNOWN;
71 
AccessibilityStatsLogUtils()72     private AccessibilityStatsLogUtils() {}
73 
74     /**
75      * Logs accessibility feature name that is assigned to the given {@code shortcutType}.
76      * Calls this when clicking the shortcut {@link ShortcutConstants.UserShortcutType#SOFTWARE} or
77      * {@link ShortcutConstants.UserShortcutType#HARDWARE}.
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      */
logAccessibilityShortcutActivated(Context context, ComponentName componentName, @UserShortcutType int shortcutType)83     public static void logAccessibilityShortcutActivated(Context context,
84             ComponentName componentName, @UserShortcutType int shortcutType) {
85         logAccessibilityShortcutActivatedInternal(componentName,
86                 convertToLoggingShortcutType(context, shortcutType), UNKNOWN_STATUS);
87     }
88 
89     /**
90      * Logs accessibility feature name that is assigned to the given {@code shortcutType} and the
91      * {@code serviceEnabled} status.
92      * Calls this when clicking the shortcut {@link ShortcutConstants.UserShortcutType#SOFTWARE}
93      * or {@link ShortcutConstants.UserShortcutType#HARDWARE}.
94      *
95      * @param context context used to retrieve the {@link Settings} provider
96      * @param componentName  component name of the accessibility feature
97      * @param shortcutType   accessibility shortcut type
98      * @param serviceEnabled {@code true} if the service is enabled
99      */
logAccessibilityShortcutActivated( Context context, ComponentName componentName, @UserShortcutType int shortcutType, boolean serviceEnabled)100     public static void logAccessibilityShortcutActivated(
101             Context context, ComponentName componentName,
102             @UserShortcutType int shortcutType, boolean serviceEnabled) {
103         logAccessibilityShortcutActivatedInternal(componentName,
104                 convertToLoggingShortcutType(context, shortcutType),
105                 convertToLoggingServiceStatus(serviceEnabled));
106     }
107 
108     /**
109      * Logs accessibility feature name that is assigned to the given {@code loggingShortcutType} and
110      * {@code loggingServiceStatus} code.
111      *
112      * @param componentName        component name of the accessibility feature
113      * @param loggingShortcutType  accessibility shortcut type for logging. 0 denotes
114      *                             unknown_type, 1 denotes accessibility button, 2 denotes volume
115      *                             key, 3 denotes triple tap on the screen, 4 denotes long press on
116      *                             accessibility button, 5 denotes accessibility floating menu.
117      * @param loggingServiceStatus The service status code for logging. 0 denotes unknown_status, 1
118      *                             denotes enabled, 2 denotes disabled.
119      */
logAccessibilityShortcutActivatedInternal(ComponentName componentName, int loggingShortcutType, int loggingServiceStatus)120     private static void logAccessibilityShortcutActivatedInternal(ComponentName componentName,
121             int loggingShortcutType, int loggingServiceStatus) {
122         FrameworkStatsLog.write(FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED,
123                 componentName.flattenToString(), loggingShortcutType, loggingServiceStatus);
124     }
125 
126     /**
127      * Logs magnification that is assigned to the triple tap shortcut. Calls this when triggering
128      * the magnification triple tap shortcut.
129      */
logMagnificationTripleTap(boolean enabled)130     public static void logMagnificationTripleTap(boolean enabled) {
131         FrameworkStatsLog.write(FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED,
132                 MAGNIFICATION_COMPONENT_NAME.flattenToString(),
133                 ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__TRIPLE_TAP,
134                 convertToLoggingServiceStatus(enabled));
135     }
136 
137     /**
138      * Logs magnification that is assigned to the two finger triple tap shortcut. Calls this when
139      * triggering the magnification two finger triple tap shortcut.
140      */
logMagnificationTwoFingerTripleTap(boolean enabled)141     public static void logMagnificationTwoFingerTripleTap(boolean enabled) {
142         FrameworkStatsLog.write(FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED,
143                 MAGNIFICATION_COMPONENT_NAME.flattenToString(),
144                 // jean update
145                 ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__TWO_FINGER_TRIPLE_TAP,
146                 convertToLoggingServiceStatus(enabled));
147     }
148 
149     /**
150      * Logs accessibility feature name that is assigned to the long pressed accessibility button
151      * shortcut. Calls this when clicking the long pressed accessibility button shortcut.
152      *
153      * @param componentName The component name of the accessibility feature.
154      */
logAccessibilityButtonLongPressStatus(ComponentName componentName)155     public static void logAccessibilityButtonLongPressStatus(ComponentName componentName) {
156         FrameworkStatsLog.write(FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED,
157                 componentName.flattenToString(),
158                 ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON_LONG_PRESS,
159                 UNKNOWN_STATUS);
160     }
161 
162     /**
163      * Logs the magnification activated mode and its duration of the usage.
164      * Calls this when the magnification is disabled.
165      *
166      * @param mode The activated magnification mode.
167      * @param duration The duration in milliseconds during the magnification is activated.
168      * @param scale The last magnification scale for the activation
169      */
logMagnificationUsageState(int mode, long duration, float scale)170     public static void logMagnificationUsageState(int mode, long duration, float scale) {
171         FrameworkStatsLog.write(FrameworkStatsLog.MAGNIFICATION_USAGE_REPORTED,
172                 convertToLoggingMagnificationMode(mode),
173                 duration,
174                 convertToLoggingMagnificationScale(scale));
175     }
176 
177     /**
178      * Logs the activated mode of the magnification when the IME window is shown on the screen.
179      * Calls this when the magnification is enabled and the IME window is shown on the screen.
180      *
181      * @param mode The activated magnification mode.
182      */
logMagnificationModeWithImeOn(int mode)183     public static void logMagnificationModeWithImeOn(int mode) {
184         FrameworkStatsLog.write(FrameworkStatsLog.MAGNIFICATION_MODE_WITH_IME_ON_REPORTED,
185                 convertToLoggingMagnificationMode(mode));
186     }
187 
188     /**
189      * Logs the duration for the window magnifier's following typing focus session.
190      *
191      * @param duration The duration of a triple-tap-and-hold activation session.
192      */
logMagnificationFollowTypingFocusSession(long duration)193     public static void logMagnificationFollowTypingFocusSession(long duration) {
194         FrameworkStatsLog.write(
195                 FrameworkStatsLog.MAGNIFICATION_FOLLOW_TYPING_FOCUS_ACTIVATED_SESSION_REPORTED,
196                 duration);
197     }
198 
199     /**
200      * Logs the duration for the magnification session which is activated by the triple tap and
201      * hold gesture.
202      *
203      * @param duration The duration of a triple-tap-and-hold activation session.
204      */
logMagnificationTripleTapAndHoldSession(long duration)205     public static void logMagnificationTripleTapAndHoldSession(long duration) {
206         FrameworkStatsLog.write(
207                 FrameworkStatsLog.MAGNIFICATION_TRIPLE_TAP_AND_HOLD_ACTIVATED_SESSION_REPORTED,
208                 duration);
209     }
210 
211     /**
212      * Logs the warning status of the non-a11yTool service. Calls this when the warning status is
213      * changed.
214      *
215      * @param packageName    The package name of the non-a11yTool service
216      * @param status         The warning status of the non-a11yTool service, it should be one of
217      *                       {@code ACCESSIBILITY_PRIVACY_WARNING_STATUS_SHOWN},{@code
218      *                       ACCESSIBILITY_PRIVACY_WARNING_STATUS_CLICKED} and {@code
219      *                       ACCESSIBILITY_PRIVACY_WARNING_STATUS_SERVICE_DISABLED}
220      * @param durationMillis The duration in milliseconds between current and previous status
221      */
logNonA11yToolServiceWarningReported(String packageName, int status, long durationMillis)222     public static void logNonA11yToolServiceWarningReported(String packageName, int status,
223             long durationMillis) {
224         FrameworkStatsLog.write(FrameworkStatsLog.NON_A11Y_TOOL_SERVICE_WARNING_REPORT,
225                 packageName, status, durationMillis);
226     }
227 
isAccessibilityFloatingMenuEnabled(Context context)228     private static boolean isAccessibilityFloatingMenuEnabled(Context context) {
229         return Settings.Secure.getInt(context.getContentResolver(),
230                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE, /* def= */ -1)
231                 == ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
232     }
233 
isAccessibilityGestureEnabled(Context context)234     private static boolean isAccessibilityGestureEnabled(Context context) {
235         return Settings.Secure.getInt(context.getContentResolver(),
236                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE, /* def= */ -1)
237                 == ACCESSIBILITY_BUTTON_MODE_GESTURE;
238     }
239 
convertToLoggingShortcutType(Context context, @UserShortcutType int shortcutType)240     private static int convertToLoggingShortcutType(Context context,
241             @UserShortcutType int shortcutType) {
242         switch (shortcutType) {
243             case SOFTWARE:
244                 if (isAccessibilityFloatingMenuEnabled(context)) {
245                     return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_FLOATING_MENU;
246                 } else if (isAccessibilityGestureEnabled(context)) {
247                     return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_GESTURE;
248                 } else {
249                     return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON;
250                 }
251             case GESTURE:
252                 return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_GESTURE;
253             case HARDWARE:
254                 return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__VOLUME_KEY;
255             case QUICK_SETTINGS:
256                 return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__QUICK_SETTINGS;
257         }
258         return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__UNKNOWN_TYPE;
259     }
260 
convertToLoggingServiceStatus(boolean enabled)261     private static int convertToLoggingServiceStatus(boolean enabled) {
262         return enabled ? ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__ENABLED
263                 : ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__DISABLED;
264     }
265 
convertToLoggingMagnificationMode(int mode)266     private static int convertToLoggingMagnificationMode(int mode) {
267         switch (mode) {
268             case ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN:
269                 return MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_FULL_SCREEN;
270             case ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW:
271                 return MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_WINDOW;
272             case ACCESSIBILITY_MAGNIFICATION_MODE_ALL:
273                 return MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_ALL;
274 
275             default:
276                 return MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_UNKNOWN_MODE;
277         }
278     }
279 
convertToLoggingMagnificationScale(float scale)280     private static int convertToLoggingMagnificationScale(float scale) {
281         // per b/269366674, we make every 10% a bucket for both privacy and readability concern.
282         // For example
283         // 1. both 2.30f(230%) and 2.36f(236%) would return 230 as bucket id.
284         // 2. bucket id 370 means scale range in [370%, 379%]
285         return ((int) (scale * 10)) * 10;
286     }
287 }
288