Merge "Add some functionality to Settings ShadowLockPatternUtils"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a829847..77d12d7 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4983,6 +4983,9 @@
     <!-- Summary text for keyboards when no layout has been selected. [CHAR LIMIT=35] -->
     <string name="default_keyboard_layout">Default</string>
 
+    <!-- Title for the 'Speech' preference category. [CHAR LIMIT=45] -->
+    <string name="speech_category_title">Speech</string>
+
     <!-- On Languages & input settings screen, setting summary.  Setting for mouse pointer speed. [CHAR LIMIT=35] -->
     <string name="pointer_speed">Pointer speed</string>
 
diff --git a/res/xml/language_and_input.xml b/res/xml/language_and_input.xml
index f2b6d8a..c99d591 100644
--- a/res/xml/language_and_input.xml
+++ b/res/xml/language_and_input.xml
@@ -38,8 +38,6 @@
                 android:name="classname"
                 android:value="com.android.settings.applications.appinfo.AppLocaleDetails" />
         </Preference>
-
-
     </PreferenceCategory>
 
     <PreferenceCategory
@@ -50,6 +48,7 @@
             android:title="@string/virtual_keyboard_category"
             android:fragment="com.android.settings.inputmethod.AvailableVirtualKeyboardFragment"
             settings:keywords="@string/keywords_virtual_keyboard"/>
+
         <Preference
             android:key="physical_keyboard_pref"
             android:title="@string/physical_keyboard_title"
@@ -58,6 +57,21 @@
     </PreferenceCategory>
 
     <PreferenceCategory
+        android:key="speech_category"
+        android:title="@string/speech_category_title">
+        <com.android.settings.widget.GearPreference
+            android:key="voice_input_settings"
+            android:title="@string/voice_input_settings_title"
+            android:fragment="com.android.settings.language.DefaultVoiceInputPicker" />
+
+        <Preference
+            android:key="tts_settings_summary"
+            android:title="@string/tts_settings_title"
+            android:fragment="com.android.settings.tts.TextToSpeechSettings"
+            settings:searchable="false"/>
+    </PreferenceCategory>
+
+    <PreferenceCategory
         android:key="input_assistance_category"
         android:title="@string/input_assistance">
         <!-- Spell checker preference title, summary and fragment will be set programmatically. -->
@@ -79,20 +93,12 @@
     </PreferenceCategory>
 
     <PreferenceCategory
-        android:key="pointer_and_tts_category"
+        android:key="pointer_category"
         android:layout="@layout/preference_category_no_label">
-
         <com.android.settings.PointerSpeedPreference
             android:key="pointer_speed"
             android:title="@string/pointer_speed"
             android:dialogTitle="@string/pointer_speed" />
-
-        <Preference
-            android:key="tts_settings_summary"
-            android:title="@string/tts_settings_title"
-            android:fragment="com.android.settings.tts.TextToSpeechSettings"
-            settings:searchable="false"/>
-
     </PreferenceCategory>
 
     <SwitchPreference
diff --git a/res/xml/manage_assist.xml b/res/xml/manage_assist.xml
index 59ba2f5..c8dbe42 100644
--- a/res/xml/manage_assist.xml
+++ b/res/xml/manage_assist.xml
@@ -49,11 +49,6 @@
         android:title="@string/assist_flash_title"
         android:summary="@string/assist_flash_summary" />
 
-    <com.android.settings.widget.GearPreference
-        android:key="voice_input_settings"
-        android:title="@string/voice_input_settings_title"
-        android:fragment="com.android.settings.applications.assist.DefaultVoiceInputPicker" />
-
     <com.android.settingslib.widget.FooterPreference
         android:key="manage_assist_footer"
         android:title="@string/assist_footer"
diff --git a/src/com/android/settings/applications/assist/ManageAssist.java b/src/com/android/settings/applications/assist/ManageAssist.java
index c96f43f..ad6c71e 100644
--- a/src/com/android/settings/applications/assist/ManageAssist.java
+++ b/src/com/android/settings/applications/assist/ManageAssist.java
@@ -73,7 +73,6 @@
         controllers.add(new AssistContextPreferenceController(context, lifecycle));
         controllers.add(new AssistScreenshotPreferenceController(context, lifecycle));
         controllers.add(new AssistFlashScreenPreferenceController(context, lifecycle));
-        controllers.add(new DefaultVoiceInputPreferenceController(context, lifecycle));
         return controllers;
     }
 
diff --git a/src/com/android/settings/applications/assist/DefaultVoiceInputPicker.java b/src/com/android/settings/language/DefaultVoiceInputPicker.java
similarity index 85%
rename from src/com/android/settings/applications/assist/DefaultVoiceInputPicker.java
rename to src/com/android/settings/language/DefaultVoiceInputPicker.java
index d4ea4a9..8a73fdf 100644
--- a/src/com/android/settings/applications/assist/DefaultVoiceInputPicker.java
+++ b/src/com/android/settings/language/DefaultVoiceInputPicker.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.applications.assist;
+package com.android.settings.language;
 
 import android.app.settings.SettingsEnums;
 import android.content.ComponentName;
@@ -31,6 +31,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+/** Controls the Voice Input setting. */
 public class DefaultVoiceInputPicker extends DefaultAppPickerFragment {
 
     private VoiceInputHelper mHelper;
@@ -76,7 +77,7 @@
     @Override
     protected boolean setDefaultKey(String value) {
         for (VoiceInputHelper.RecognizerInfo info : mHelper.mAvailableRecognizerInfos) {
-            if (TextUtils.equals(value, info.key)) {
+            if (TextUtils.equals(value, info.mKey)) {
                 Settings.Secure.putString(getContext().getContentResolver(),
                         Settings.Secure.VOICE_RECOGNITION_SERVICE, value);
                 return true;
@@ -85,35 +86,38 @@
         return true;
     }
 
+    /** Gets the current recognition service component. */
     public static ComponentName getCurrentService(VoiceInputHelper helper) {
         return helper.mCurrentRecognizer;
     }
 
+    /** Stores the info of the Voice Input provider. */
     public static class VoiceInputDefaultAppInfo extends DefaultAppInfo {
 
         public VoiceInputHelper.BaseInfo mInfo;
 
         public VoiceInputDefaultAppInfo(Context context, PackageManager pm, int userId,
                 VoiceInputHelper.BaseInfo info, boolean enabled) {
-            super(context, pm, userId, info.componentName, null /* summary */, enabled);
+            super(context, pm, userId, info.mComponentName, null /* summary */, enabled);
             mInfo = info;
         }
 
         @Override
         public String getKey() {
-            return mInfo.key;
+            return mInfo.mKey;
         }
 
         @Override
         public CharSequence loadLabel() {
-            return mInfo.label;
+            return mInfo.mLabel;
         }
 
+        /** Gets the setting intent. */
         public Intent getSettingIntent() {
-            if (mInfo.settings == null) {
+            if (mInfo.mSettings == null) {
                 return null;
             }
-            return new Intent(Intent.ACTION_MAIN).setComponent(mInfo.settings);
+            return new Intent(Intent.ACTION_MAIN).setComponent(mInfo.mSettings);
         }
     }
 }
diff --git a/src/com/android/settings/applications/assist/DefaultVoiceInputPreferenceController.java b/src/com/android/settings/language/DefaultVoiceInputPreferenceController.java
similarity index 94%
rename from src/com/android/settings/applications/assist/DefaultVoiceInputPreferenceController.java
rename to src/com/android/settings/language/DefaultVoiceInputPreferenceController.java
index 59f5731..74c156c 100644
--- a/src/com/android/settings/applications/assist/DefaultVoiceInputPreferenceController.java
+++ b/src/com/android/settings/language/DefaultVoiceInputPreferenceController.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,13 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.settings.applications.assist;
+package com.android.settings.language;
 
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.net.Uri;
 import android.text.TextUtils;
 
 import androidx.preference.Preference;
@@ -33,8 +32,7 @@
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
 
-import java.util.List;
-
+/** Controller of the Voice Input preference. */
 public class DefaultVoiceInputPreferenceController extends DefaultAppPreferenceController
         implements LifecycleObserver, OnResume, OnPause {
 
@@ -95,7 +93,7 @@
         }
 
         for (VoiceInputHelper.RecognizerInfo info : mHelper.mAvailableRecognizerInfos) {
-            if (TextUtils.equals(defaultKey, info.key)) {
+            if (TextUtils.equals(defaultKey, info.mKey)) {
                 return new DefaultVoiceInputPicker.VoiceInputDefaultAppInfo(mContext,
                         mPackageManager, mUserId, info, true /* enabled */);
             }
diff --git a/src/com/android/settings/language/LanguageAndInputSettings.java b/src/com/android/settings/language/LanguageAndInputSettings.java
index 58c082b..23e37ba 100644
--- a/src/com/android/settings/language/LanguageAndInputSettings.java
+++ b/src/com/android/settings/language/LanguageAndInputSettings.java
@@ -47,8 +47,9 @@
     private static final String TAG = "LangAndInputSettings";
 
     private static final String KEY_KEYBOARDS_CATEGORY = "keyboards_category";
+    private static final String KEY_SPEECH_CATEGORY = "speech_category";
     private static final String KEY_TEXT_TO_SPEECH = "tts_settings_summary";
-    private static final String KEY_POINTER_AND_TTS_CATEGORY = "pointer_and_tts_category";
+    private static final String KEY_POINTER_CATEGORY = "pointer_category";
 
     @Override
     public int getMetricsCategory() {
@@ -109,15 +110,22 @@
                 Arrays.asList(virtualKeyboardPreferenceController,
                         physicalKeyboardPreferenceController)));
 
-        // Pointer and Tts
+        // Speech
+        final DefaultVoiceInputPreferenceController defaultVoiceInputPreferenceController =
+                new DefaultVoiceInputPreferenceController(context, lifecycle);
         final TtsPreferenceController ttsPreferenceController =
                 new TtsPreferenceController(context, KEY_TEXT_TO_SPEECH);
+        controllers.add(defaultVoiceInputPreferenceController);
         controllers.add(ttsPreferenceController);
+        controllers.add(new PreferenceCategoryController(context,
+                KEY_SPEECH_CATEGORY).setChildren(
+                Arrays.asList(defaultVoiceInputPreferenceController, ttsPreferenceController)));
+
+        // Pointer
         final PointerSpeedController pointerController = new PointerSpeedController(context);
         controllers.add(pointerController);
         controllers.add(new PreferenceCategoryController(context,
-                KEY_POINTER_AND_TTS_CATEGORY).setChildren(
-                Arrays.asList(pointerController, ttsPreferenceController)));
+                KEY_POINTER_CATEGORY).setChildren(Arrays.asList(pointerController)));
 
         // Input Assistance
         controllers.add(new SpellCheckerPreferenceController(context));
diff --git a/src/com/android/settings/applications/assist/VoiceInputHelper.java b/src/com/android/settings/language/VoiceInputHelper.java
similarity index 77%
rename from src/com/android/settings/applications/assist/VoiceInputHelper.java
rename to src/com/android/settings/language/VoiceInputHelper.java
index 285f4f7..7915ba4 100644
--- a/src/com/android/settings/applications/assist/VoiceInputHelper.java
+++ b/src/com/android/settings/language/VoiceInputHelper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.applications.assist;
+package com.android.settings.language;
 
 import android.content.ComponentName;
 import android.content.Context;
@@ -39,40 +39,46 @@
 import java.util.Collections;
 import java.util.List;
 
+/** Helper class of the Voice Input setting. */
 public final class VoiceInputHelper {
     static final String TAG = "VoiceInputHelper";
     final Context mContext;
 
     final List<ResolveInfo> mAvailableRecognition;
 
-    // TODO: Remove this superclass as we only have 1 class now (RecognizerInfo).
-    static public class BaseInfo implements Comparable {
-        public final ServiceInfo service;
-        public final ComponentName componentName;
-        public final String key;
-        public final ComponentName settings;
-        public final CharSequence label;
-        public final String labelStr;
-        public final CharSequence appLabel;
+    /**
+     * Base info of the Voice Input provider.
+     *
+     * TODO: Remove this superclass as we only have 1 class now (RecognizerInfo).
+     */
+    public static class BaseInfo implements Comparable<BaseInfo> {
+        public final ServiceInfo mService;
+        public final ComponentName mComponentName;
+        public final String mKey;
+        public final ComponentName mSettings;
+        public final CharSequence mLabel;
+        public final String mLabelStr;
+        public final CharSequence mAppLabel;
 
-        public BaseInfo(PackageManager pm, ServiceInfo _service, String _settings) {
-            service = _service;
-            componentName = new ComponentName(_service.packageName, _service.name);
-            key = componentName.flattenToShortString();
-            settings = _settings != null
-                    ? new ComponentName(_service.packageName, _settings) : null;
-            label = _service.loadLabel(pm);
-            labelStr = label.toString();
-            appLabel = _service.applicationInfo.loadLabel(pm);
+        public BaseInfo(PackageManager pm, ServiceInfo service, String settings) {
+            mService = service;
+            mComponentName = new ComponentName(service.packageName, service.name);
+            mKey = mComponentName.flattenToShortString();
+            mSettings = settings != null
+                    ? new ComponentName(service.packageName, settings) : null;
+            mLabel = service.loadLabel(pm);
+            mLabelStr = mLabel.toString();
+            mAppLabel = service.applicationInfo.loadLabel(pm);
         }
 
         @Override
-        public int compareTo(Object another) {
-            return labelStr.compareTo(((BaseInfo) another).labelStr);
+        public int compareTo(BaseInfo another) {
+            return mLabelStr.compareTo(another.mLabelStr);
         }
     }
 
-    static public class RecognizerInfo extends BaseInfo {
+    /** Info of the speech recognizer (i.e. recognition service). */
+    public static class RecognizerInfo extends BaseInfo {
         public final boolean mSelectableAsDefault;
 
         public RecognizerInfo(PackageManager pm,
@@ -96,6 +102,7 @@
                 PackageManager.GET_META_DATA);
     }
 
+    /** Draws the UI of the Voice Input picker page. */
     public void buildUi() {
         // Get the currently selected recognizer from the secure setting.
         String currentSetting = Settings.Secure.getString(
@@ -120,8 +127,8 @@
             try (XmlResourceParser parser = si.loadXmlMetaData(mContext.getPackageManager(),
                     RecognitionService.SERVICE_META_DATA)) {
                 if (parser == null) {
-                    throw new XmlPullParserException("No " + RecognitionService.SERVICE_META_DATA +
-                            " meta-data for " + si.packageName);
+                    throw new XmlPullParserException("No " + RecognitionService.SERVICE_META_DATA
+                            + " meta-data for " + si.packageName);
                 }
 
                 Resources res = mContext.getPackageManager().getResourcesForApplication(
@@ -132,6 +139,7 @@
                 int type;
                 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                         && type != XmlPullParser.START_TAG) {
+                    // Intentionally do nothing.
                 }
 
                 String nodeName = parser.getName();
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
index 1886d34..b6401cf 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.applications.appinfo;
 
+import static com.android.settings.applications.appinfo.AppInfoDashboardFragment.ACCESS_RESTRICTED_SETTINGS;
 import static com.android.settings.applications.appinfo.AppInfoDashboardFragment.ARG_PACKAGE_NAME;
 import static com.android.settings.applications.appinfo.AppInfoDashboardFragment.UNINSTALL_ALL_USERS_MENU;
 import static com.android.settings.applications.appinfo.AppInfoDashboardFragment.UNINSTALL_UPDATES;
@@ -55,7 +56,6 @@
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
@@ -145,7 +145,6 @@
     }
 
     @Test
-    @Ignore
     public void onPrepareOptionsMenu_setUpdateMenuVisible_byDefaultForSystemApps_shouldBeTrue() {
         Menu menu = onPrepareOptionsMenuTestsSetup();
         mFragment.onPrepareOptionsMenu(menu);
@@ -155,7 +154,6 @@
 
     @Test
     @Config(qualifiers = "mcc999")
-    @Ignore
     public void onPrepareOptionsMenu_setUpdateMenuVisible_ifDisabledByDevice_shouldBeFalse() {
         Menu menu = onPrepareOptionsMenuTestsSetup();
         mFragment.onPrepareOptionsMenu(menu);
@@ -168,8 +166,10 @@
         Menu menu = mock(Menu.class);
         final MenuItem uninstallUpdatesMenuItem = mock(MenuItem.class);
         final MenuItem uninstallForAllMenuItem = mock(MenuItem.class);
+        final MenuItem accessRestrictedMenuItem = mock(MenuItem.class);
         when(menu.findItem(UNINSTALL_UPDATES)).thenReturn(uninstallUpdatesMenuItem);
         when(menu.findItem(UNINSTALL_ALL_USERS_MENU)).thenReturn(uninstallForAllMenuItem);
+        when(menu.findItem(ACCESS_RESTRICTED_SETTINGS)).thenReturn(accessRestrictedMenuItem);
 
         // Setup work to prevent NPE
         final ApplicationInfo info = new ApplicationInfo();