Merge "Import translations. DO NOT MERGE" into rvc-dev
diff --git a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
index be66d0c..891d535 100644
--- a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
+++ b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
@@ -73,8 +73,11 @@
             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)
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityButtonChooserActivity.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityButtonChooserActivity.java
index 7c4df52..7eb09e5 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityButtonChooserActivity.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityButtonChooserActivity.java
@@ -19,10 +19,14 @@
 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 @@
         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();
         });
diff --git a/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java b/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
new file mode 100644
index 0000000..c2e1426
--- /dev/null
+++ b/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
@@ -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;
+    }
+}
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 783e084..bc859c1 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -142,7 +142,7 @@
     <string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"ୱାଇ-ଫାଇ"</string>
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"ୱାଇଫାଇ କଲିଂ"</string>
     <string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
-    <string name="wifi_calling_off_summary" msgid="5626710010766902560">"ଅଫ୍"</string>
+    <string name="wifi_calling_off_summary" msgid="5626710010766902560">"ବନ୍ଦ"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"ୱାଇ-ଫାଇ ମାଧ୍ୟମରେ କଲ୍ କରନ୍ତୁ"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"ମୋବାଇଲ ନେଟ୍‌ୱର୍କ ମାଧ୍ୟମରେ କଲ୍ କରନ୍ତୁ"</string>
     <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"କେବଳ ୱାଇ-ଫାଇ"</string>
@@ -1119,7 +1119,7 @@
     <string name="dialog_alert_title" msgid="651856561974090712">"ଧ୍ୟାନଦିଅନ୍ତୁ"</string>
     <string name="loading" msgid="3138021523725055037">"ଲୋଡ୍ କରାଯାଉଛି…"</string>
     <string name="capital_on" msgid="2770685323900821829">"ଚାଲୁ"</string>
-    <string name="capital_off" msgid="7443704171014626777">"ଅଫ୍"</string>
+    <string name="capital_off" msgid="7443704171014626777">"ବନ୍ଦ"</string>
     <string name="checked" msgid="9179896827054513119">"ଯାଞ୍ଚ ହୋଇଛି"</string>
     <string name="not_checked" msgid="7972320087569023342">"ଯାଞ୍ଚ ହୋଇନାହିଁ"</string>
     <string name="whichApplication" msgid="5432266899591255759">"ବ୍ୟବହାର କରି କାର୍ଯ୍ୟ ସମ୍ପୂର୍ଣ୍ଣ କରନ୍ତୁ"</string>
@@ -1231,7 +1231,7 @@
     <string name="volume_icon_description_notification" msgid="579091344110747279">"ବିଜ୍ଞପ୍ତି ଭଲ୍ୟୁମ୍‍"</string>
     <string name="ringtone_default" msgid="9118299121288174597">"ଡିଫଲ୍ଟ ରିଙ୍ଗଟୋନ୍‌"</string>
     <string name="ringtone_default_with_actual" msgid="2709686194556159773">"ଡିଫଲ୍ଟ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
-    <string name="ringtone_silent" msgid="397111123930141876">"କିଛିନୁହେଁ"</string>
+    <string name="ringtone_silent" msgid="397111123930141876">"କିଛି ନାହିଁ"</string>
     <string name="ringtone_picker_title" msgid="667342618626068253">"ରିଙ୍ଗଟୋନ୍‌"</string>
     <string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"ଆଲାରାମ୍ ଶବ୍ଦ"</string>
     <string name="ringtone_picker_title_notification" msgid="6387191794719608122">"ବିଜ୍ଞପ୍ତି ଶବ୍ଦ"</string>
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
index b501a2e..ca7a5db 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
@@ -49,12 +49,12 @@
         manager!!.clearCache()
         originalQsMediaPlayer = Settings.System.getInt(context.getContentResolver(),
                 "qs_media_player", 1)
-        Settings.System.putInt(context.getContentResolver(), "qs_media_player", 0)
+        Settings.Global.putInt(context.getContentResolver(), "qs_media_player", 0)
     }
 
     @After
     public fun teardown() {
-        Settings.System.putInt(context.getContentResolver(), "qs_media_player",
+        Settings.Global.putInt(context.getContentResolver(), "qs_media_player",
                 originalQsMediaPlayer)
     }
 
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 02ab60b..6d848d1 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -20,8 +20,10 @@
 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 @@
         }
         // 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 @@
             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 @@
         }
     }
 
-    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 @@
                 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 @@
             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 @@
                         + assignedTarget);
                 return false;
             }
+            // ServiceConnection means service enabled.
+            logAccessibilityShortcutActivated(assignedTarget, shortcutType, /* serviceEnabled= */
+                    true);
             serviceConnection.notifyAccessibilityButtonClickedLocked(displayId);
             return true;
         }
diff --git a/services/accessibility/java/com/android/server/accessibility/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/FullScreenMagnificationGestureHandler.java
index 9e4fd80..afe6238 100644
--- a/services/accessibility/java/com/android/server/accessibility/FullScreenMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/FullScreenMagnificationGestureHandler.java
@@ -24,6 +24,7 @@
 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 @@
             // 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 @@
         }
 
         private void onTripleTap(MotionEvent up) {
-
             if (DEBUG_DETECTING) {
                 Slog.i(LOG_TAG, "onTripleTap(); delayed: "
                         + MotionEventInfo.toString(mDelayedEventQueue));
@@ -908,6 +915,10 @@
             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);