Merge "Add SpaLib for Settings"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index c05d310..e14cba7 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -909,6 +909,46 @@
android:value="true"/>
</activity>
+ <activity
+ android:name=".Settings$LanguageSettingsActivity"
+ android:label="@string/languages_settings"
+ android:exported="true"
+ android:icon="@drawable/ic_settings_languages">
+ <intent-filter>
+ <action android:name="android.settings.LANGUAGE_SETTINGS"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.VOICE_LAUNCH"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+ android:value="com.android.settings.language.LanguageSettings"/>
+ <meta-data android:name="com.android.settings.HIGHLIGHT_MENU_KEY"
+ android:value="@string/menu_key_system"/>
+ <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+ android:value="true"/>
+ </activity>
+
+ <activity
+ android:name=".Settings$KeyboardSettingsActivity"
+ android:label="@string/keyboard_settings"
+ android:exported="true"
+ android:icon="@drawable/ic_settings_language">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.VOICE_LAUNCH"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+ android:value="com.android.settings.inputmethod.KeyboardSettings"/>
+ <meta-data android:name="com.android.settings.HIGHLIGHT_MENU_KEY"
+ android:value="@string/menu_key_system"/>
+ <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+ android:value="true"/>
+ </activity>
+
<activity android:name="Settings$AvailableVirtualKeyboardActivity"
android:exported="true"
android:label="@string/available_virtual_keyboard_category">
diff --git a/res/drawable/ic_settings_keyboards.xml b/res/drawable/ic_settings_keyboards.xml
new file mode 100644
index 0000000..7eb5a13
--- /dev/null
+++ b/res/drawable/ic_settings_keyboards.xml
@@ -0,0 +1,25 @@
+<!--
+ 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.
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?android:attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M4,19Q3.175,19 2.588,18.413Q2,17.825 2,17V7Q2,6.175 2.588,5.588Q3.175,5 4,5H20Q20.825,5 21.413,5.588Q22,6.175 22,7V17Q22,17.825 21.413,18.413Q20.825,19 20,19ZM4,17H20Q20,17 20,17Q20,17 20,17V7Q20,7 20,7Q20,7 20,7H4Q4,7 4,7Q4,7 4,7V17Q4,17 4,17Q4,17 4,17ZM8,16H16V14H8ZM5,13H7V11H5ZM8,13H10V11H8ZM11,13H13V11H11ZM14,13H16V11H14ZM17,13H19V11H17ZM5,10H7V8H5ZM8,10H10V8H8ZM11,10H13V8H11ZM14,10H16V8H14ZM17,10H19V8H17ZM4,17Q4,17 4,17Q4,17 4,17V7Q4,7 4,7Q4,7 4,7Q4,7 4,7Q4,7 4,7V17Q4,17 4,17Q4,17 4,17Z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_settings_languages.xml b/res/drawable/ic_settings_languages.xml
new file mode 100644
index 0000000..bee0df6
--- /dev/null
+++ b/res/drawable/ic_settings_languages.xml
@@ -0,0 +1,25 @@
+<!--
+ 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.
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?android:attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M11.9,22 L16.45,10H18.55L23.1,22H21L19.95,18.95H15.1L14,22ZM15.7,17.2H19.3L17.55,12.25H17.45ZM4,19 L2.6,17.6 7.65,12.55Q6.7,11.5 5.988,10.375Q5.275,9.25 4.75,8H6.85Q7.3,8.9 7.813,9.625Q8.325,10.35 9.05,11.15Q10.15,9.95 10.875,8.688Q11.6,7.425 12.1,6H1V4H8V2H10V4H17V6H14.1Q13.575,7.775 12.675,9.45Q11.775,11.125 10.45,12.6L12.85,15.05L12.1,17.1L9,14Z"/>
+</vector>
\ No newline at end of file
diff --git a/res/layout/fingerprint_enroll_introduction.xml b/res/layout/fingerprint_enroll_introduction.xml
index a01f3a9..0c10e52 100644
--- a/res/layout/fingerprint_enroll_introduction.xml
+++ b/res/layout/fingerprint_enroll_introduction.xml
@@ -199,6 +199,8 @@
android:layout_width="16dp"
android:layout_height="wrap_content"/>
<TextView
+ android:id="@+id/footer_learn_more"
+ android:linksClickable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/BiometricEnrollIntroMessage"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 04121af..dde0b67 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -743,7 +743,11 @@
<!-- Introduction detail message shown in face education [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_education_message"></string>
<!-- Introduction detail message shown in face education for accessibility [CHAR LIMIT=NONE] -->
- <string name="security_settings_face_enroll_education_message_accessibility"></string>
+ <string name="security_settings_face_enroll_education_message_accessibility" product="default"></string>
+ <!-- Introduction detail message shown in face education for accessibility [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_education_message_accessibility" product="tablet"></string>
+ <!-- Introduction detail message shown in face education for accessibility [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_education_message_accessibility" product="device"></string>
<!-- Button that takes the user to the enrollment activity [CHAR LIMIT=20] -->
<string name="security_settings_face_enroll_education_start">Start</string>
<!-- Confirmation dialog message shown when users with system accessibility features enabled try to start the non-accessibility version of enrollment [CHAR LIMIT=150] -->
@@ -755,7 +759,11 @@
<!-- Button shown which shows accessibility toggles for face enrollment when clicked. [CHAR LIMIT=32] -->
<string name="security_settings_face_enroll_introduction_accessibility">Use accessibility setup</string>
<!-- Additional details shown when the accessibility toggle is expanded. [CHAR LIMIT=NONE]-->
- <string name="security_settings_face_enroll_introduction_accessibility_expanded"></string>
+ <string name="security_settings_face_enroll_introduction_accessibility_expanded" product="default"></string>
+ <!-- Additional details shown when the accessibility toggle is expanded. [CHAR LIMIT=NONE]-->
+ <string name="security_settings_face_enroll_introduction_accessibility_expanded" product="tablet"></string>
+ <!-- Additional details shown when the accessibility toggle is expanded. [CHAR LIMIT=NONE]-->
+ <string name="security_settings_face_enroll_introduction_accessibility_expanded" product="device"></string>
<!-- Message shown for a toggle which when enabled, allows the user to enroll using a simpler flow for accessibility [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_accessibility_diversity"></string>
<!-- Message shown for a toggle which when enabled, allows the user to enroll using a simpler flow for accessibility [CHAR LIMIT=NONE] -->
@@ -775,7 +783,11 @@
<!-- Introduction title shown in face enrollment to introduce the face unlock feature, when face unlock is disabled by device admin [CHAR LIMIT=60] -->
<string name="security_settings_face_enroll_introduction_title_unlock_disabled">Use your face to authenticate</string>
<!-- Introduction detail message shown in face enrollment dialog [CHAR LIMIT=NONE]-->
- <string name="security_settings_face_enroll_introduction_message">Use your face to unlock your phone, authorize purchases, or sign in to apps.</string>
+ <string name="security_settings_face_enroll_introduction_message" product="default">Use your face to unlock your phone, authorize purchases, or sign in to apps.</string>
+ <!-- Introduction detail message shown in face enrollment dialog [CHAR LIMIT=NONE]-->
+ <string name="security_settings_face_enroll_introduction_message" product="tablet">Use your face to unlock your tablet, authorize purchases, or sign in to apps.</string>
+ <!-- Introduction detail message shown in face enrollment dialog [CHAR LIMIT=NONE]-->
+ <string name="security_settings_face_enroll_introduction_message" product="device">Use your face to unlock your device, authorize purchases, or sign in to apps.</string>
<!-- Introduction detail message shown in face enrollment dialog when asking for parental consent [CHAR LIMIT=NONE]-->
<string name="security_settings_face_enroll_introduction_consent_message_0" product="default">Allow your child to use their face to unlock their phone</string>
<!-- Introduction detail message shown in face enrollment dialog when asking for parental consent [CHAR LIMIT=NONE]-->
@@ -799,32 +811,72 @@
<!-- Message on the face enrollment introduction page that provides information about glasses when asking for parental consent. [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_info_consent_glasses"></string>
<!-- Message on the face enrollment introduction page that provides information about what could cause the phone to unlock. [CHAR LIMIT=NONE] -->
- <string name="security_settings_face_enroll_introduction_info_looking"></string>
+ <string name="security_settings_face_enroll_introduction_info_looking" product="default"></string>
+ <!-- Message on the face enrollment introduction page that provides information about what could cause the phone to unlock. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_info_looking" product="tablet"></string>
+ <!-- Message on the face enrollment introduction page that provides information about what could cause the phone to unlock. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_info_looking" product="device"></string>
<!-- Message on the face enrollment introduction page that provides information about what could cause the phone to unlock when asking for parental consent. [CHAR LIMIT=NONE] -->
- <string name="security_settings_face_enroll_introduction_info_consent_looking"></string>
+ <string name="security_settings_face_enroll_introduction_info_consent_looking" product="default"></string>
+ <!-- Message on the face enrollment introduction page that provides information about what could cause the phone to unlock when asking for parental consent. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_info_consent_looking" product="tablet"></string>
+ <!-- Message on the face enrollment introduction page that provides information about what could cause the phone to unlock when asking for parental consent. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_info_consent_looking" product="device"></string>
<!-- Message on the face enrollment introduction page that provides information about the relative security of face for unlocking the phone. [CHAR LIMIT=NONE] -->
- <string name="security_settings_face_enroll_introduction_info_consent_less_secure"></string>
+ <string name="security_settings_face_enroll_introduction_info_consent_less_secure" product="default"></string>
+ <!-- Message on the face enrollment introduction page that provides information about the relative security of face for unlocking the phone. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_info_consent_less_secure" product="tablet"></string>
+ <!-- Message on the face enrollment introduction page that provides information about the relative security of face for unlocking the phone. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_info_consent_less_secure" product="device"></string>
<!-- Message on the face enrollment introduction page that provides information about the relative security of face for unlocking the phone for parental consent. [CHAR LIMIT=NONE] -->
- <string name="security_settings_face_enroll_introduction_info_less_secure"></string>
+ <string name="security_settings_face_enroll_introduction_info_less_secure" product="default"></string>
+ <!-- Message on the face enrollment introduction page that provides information about the relative security of face for unlocking the phone for parental consent. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_info_less_secure" product="tablet"></string>
+ <!-- Message on the face enrollment introduction page that provides information about the relative security of face for unlocking the phone for parental consent. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_info_less_secure" product="device"></string>
<!-- Message on the face enrollment introduction page that provides information about how to require eyes to be open for Face Unlock. [CHAR LIMIT=NONE] -->
- <string name="security_settings_face_enroll_introduction_info_gaze"></string>
+ <string name="security_settings_face_enroll_introduction_info_gaze" product="default"></string>
+ <!-- Message on the face enrollment introduction page that provides information about how to require eyes to be open for Face Unlock. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_info_gaze" product="tablet"></string>
+ <!-- Message on the face enrollment introduction page that provides information about how to require eyes to be open for Face Unlock. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_info_gaze" product="device"></string>
<!-- Message on the face enrollment introduction page that provides information about how to require eyes to be open for Face Unlock when asking for parental consent. [CHAR LIMIT=NONE] -->
- <string name="security_settings_face_enroll_introduction_info_consent_gaze"></string>
+ <string name="security_settings_face_enroll_introduction_info_consent_gaze" product="default"></string>
+ <!-- Message on the face enrollment introduction page that provides information about how to require eyes to be open for Face Unlock when asking for parental consent. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_info_consent_gaze" product="tablet"></string>
+ <!-- Message on the face enrollment introduction page that provides information about how to require eyes to be open for Face Unlock when asking for parental consent. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_info_consent_gaze" product="device"></string>
<!-- Title of a section on the face enrollment introduction page that explains how face unlock works. [CHAR LIMIT=40] -->
<string name="security_settings_face_enroll_introduction_how_title"></string>
<!-- Message on the face enrollment introduction page that explains how face unlock works. [CHAR LIMIT=NONE] -->
- <string name="security_settings_face_enroll_introduction_how_message"></string>
+ <string name="security_settings_face_enroll_introduction_how_message" product="default"></string>
+ <!-- Message on the face enrollment introduction page that explains how face unlock works. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_how_message" product="tablet"></string>
+ <!-- Message on the face enrollment introduction page that explains how face unlock works. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_how_message" product="device"></string>
<!-- Message on the face enrollment introduction page that explains how Face Unlock works when asking for parental consent. [CHAR LIMIT=NONE] -->
- <string name="security_settings_face_enroll_introduction_how_consent_message"></string>
+ <string name="security_settings_face_enroll_introduction_how_consent_message" product="default"></string>
+ <!-- Message on the face enrollment introduction page that explains how Face Unlock works when asking for parental consent. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_how_consent_message" product="tablet"></string>
+ <!-- Message on the face enrollment introduction page that explains how Face Unlock works when asking for parental consent. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_how_consent_message" product="device"></string>
<!-- Title of a section on the face enrollment introduction page that explains privacy controls for face unlock. [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_control_title"></string>
<!-- Title of a section on the face enrollment introduction page that explains privacy controls for face unlock when asking for parental consent. [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_control_consent_title"></string>
<!-- Message on the face enrollment introduction page that explains privacy controls for face unlock [CHAR LIMIT=NONE] -->
- <string name="security_settings_face_enroll_introduction_control_message"></string>
+ <string name="security_settings_face_enroll_introduction_control_message" product="default"></string>
+ <!-- Message on the face enrollment introduction page that explains privacy controls for face unlock [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_control_message" product="tablet"></string>
+ <!-- Message on the face enrollment introduction page that explains privacy controls for face unlock [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_control_message" product="device"></string>
<!-- Message on the face enrollment introduction page that explains privacy controls for face unlock when asking for parental consent. [CHAR LIMIT=NONE] -->
- <string name="security_settings_face_enroll_introduction_control_consent_message"></string>
+ <string name="security_settings_face_enroll_introduction_control_consent_message" product="default"></string>
+ <!-- Message on the face enrollment introduction page that explains privacy controls for face unlock when asking for parental consent. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_control_consent_message" product="tablet"></string>
+ <!-- Message on the face enrollment introduction page that explains privacy controls for face unlock when asking for parental consent. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_enroll_introduction_control_consent_message" product="device"></string>
<!-- Title shown in face enrollment dialog [CHAR LIMIT=40] -->
<string name="security_settings_face_enroll_repeat_title">Center your face in the circle</string>
<!-- Button text to skip enrollment of face [CHAR LIMIT=40] -->
@@ -918,7 +970,11 @@
<!-- Introduction detail message shown in fingerprint enrollment dialog (default) [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_enroll_introduction_v2_message" product="default">Use your fingerprint to unlock your phone or verify it\u2019s you, like when you sign in to apps or approve a purchase.</string>
<!-- Introduction detail message shown in fingerprint enrollment dialog when asking for parental consent [CHAR LIMIT=NONE]-->
- <string name="security_settings_fingerprint_enroll_introduction_consent_message">Allow your child to use their fingerprint to unlock their phone or verify it\u2019s them. This happens when they sign in to apps, approve a purchase, and more.</string>
+ <string name="security_settings_fingerprint_enroll_introduction_consent_message" product="default">Allow your child to use their fingerprint to unlock their phone or verify it\u2019s them. This happens when they sign in to apps, approve a purchase, and more.</string>
+ <!-- Introduction detail message shown in fingerprint enrollment dialog when asking for parental consent [CHAR LIMIT=NONE]-->
+ <string name="security_settings_fingerprint_enroll_introduction_consent_message" product="tablet">Allow your child to use their fingerprint to unlock their tablet or verify it\u2019s them. This happens when they sign in to apps, approve a purchase, and more.</string>
+ <!-- Introduction detail message shown in fingerprint enrollment dialog when asking for parental consent [CHAR LIMIT=NONE]-->
+ <string name="security_settings_fingerprint_enroll_introduction_consent_message" product="device">Allow your child to use their fingerprint to unlock their device or verify it\u2019s them. This happens when they sign in to apps, approve a purchase, and more.</string>
<!-- Introduction title shown in the bottom of fingerprint enrollment dialog [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_enroll_introduction_footer_title_1">You\u2019re in control</string>
<!-- Introduction title shown in the bottom of fingerprint enrollment dialog [CHAR LIMIT=NONE]-->
@@ -939,6 +995,16 @@
<string name="setup_fingerprint_enroll_skip_after_adding_lock_text">Fingerprint setup only takes a minute or two. If you skip this, you can add your fingerprint later in settings.</string>
<!-- Title of dialog shown when the user tries to skip setting up a screen lock, warning them of potential consequences of not doing so [CHAR LIMIT=30]-->
+ <!-- Introduction detail message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE]-->
+ <string name="security_settings_fingerprint_v2_enroll_introduction_message_setup">When you see this icon, use your fingerprint for authentication, like when you sign in to apps or approve a purchase</string>
+ <!-- Introduction subtitle message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE]-->
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_title_1">Keep in mind</string>
+ <!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE]-->
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_1" product="default">Using your fingerprint to unlock your phone may be less secure than a strong pattern or PIN</string>
+ <!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE]-->
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_1" product="tablet">Using your fingerprint to unlock your tablet may be less secure than a strong pattern or PIN</string>
+ <!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE]-->
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_1" product="device">Using your fingerprint to unlock your device may be less secure than a strong pattern or PIN</string>
<!-- Introduction subtitle message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_title_2">How it works</string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE]-->
@@ -946,13 +1012,29 @@
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard when asking for parental consent. [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_2">Fingerprint Unlock creates a unique model of your child\u2019s fingerprint to verify it\u2019s them. To create this fingerprint model during setup, they will take images of their fingerprint from different positions.</string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE]-->
- <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_3">When you use Pixel Imprint, images are used to update your fingerprint model. Images used to create your fingerprint model are never stored, but the fingerprint model is stored securely on your phone and never leaves the phone. All processing occurs securely on your phone.</string>
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_3" product="default">When you use Pixel Imprint, images are used to update your fingerprint model. Images used to create your fingerprint model are never stored, but the fingerprint model is stored securely on your phone and never leaves the phone. All processing occurs securely on your phone.</string>
+ <!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE]-->
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_3" product="tablet">When you use Pixel Imprint, images are used to update your fingerprint model. Images used to create your fingerprint model are never stored, but the fingerprint model is stored securely on your tablet and never leaves the tablet. All processing occurs securely on your tablet.</string>
+ <!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE]-->
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_3" product="device">When you use Pixel Imprint, images are used to update your fingerprint model. Images used to create your fingerprint model are never stored, but the fingerprint model is stored securely on your device and never leaves the device. All processing occurs securely on your device.</string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard when asking for parental consent. [CHAR LIMIT=NONE]-->
- <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_3">When they use Pixel Imprint, images are used to update their fingerprint model. Images used to create your child\u2019s fingerprint model are never stored, but the fingerprint model is stored securely on the phone and never leaves the phone. All processing occurs securely on the phone.</string>
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_3" product="default">When they use Pixel Imprint, images are used to update their fingerprint model. Images used to create your child\u2019s fingerprint model are never stored, but the fingerprint model is stored securely on the phone and never leaves the phone. All processing occurs securely on the phone.</string>
+ <!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard when asking for parental consent. [CHAR LIMIT=NONE]-->
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_3" product="tablet">When they use Pixel Imprint, images are used to update their fingerprint model. Images used to create your child\u2019s fingerprint model are never stored, but the fingerprint model is stored securely on the tablet and never leaves the tablet. All processing occurs securely on the tablet.</string>
+ <!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard when asking for parental consent. [CHAR LIMIT=NONE]-->
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_3" product="device">When they use Pixel Imprint, images are used to update their fingerprint model. Images used to create your child\u2019s fingerprint model are never stored, but the fingerprint model is stored securely on the device and never leaves the device. All processing occurs securely on the device.</string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE] -->
- <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_4">You can delete your fingerprint images and model, or turn off Fingerprint Unlock at any time in Settings. Fingerprint images and models are stored on the phone until you delete them.</string>
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_4" product="default">You can delete your fingerprint images and model, or turn off Fingerprint Unlock at any time in Settings. Fingerprint images and models are stored on the phone until you delete them.</string>
+ <!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_4" product="tablet">You can delete your fingerprint images and model, or turn off Fingerprint Unlock at any time in Settings. Fingerprint images and models are stored on the tablet until you delete them.</string>
+ <!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_4" product="device">You can delete your fingerprint images and model, or turn off Fingerprint Unlock at any time in Settings. Fingerprint images and models are stored on the device until you delete them.</string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard when asking for parental consent. [CHAR LIMIT=NONE] -->
- <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_4">You and your child can delete their fingerprint images and model, or turn off Fingerprint Unlock at any time in Settings. Fingerprint images and models are stored on the phone until they\u2019re deleted.</string>
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_4" product="default">You and your child can delete their fingerprint images and model, or turn off Fingerprint Unlock at any time in Settings. Fingerprint images and models are stored on the phone until they\u2019re deleted.</string>
+ <!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard when asking for parental consent. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_4" product="tablet">You and your child can delete their fingerprint images and model, or turn off Fingerprint Unlock at any time in Settings. Fingerprint images and models are stored on the tablet until they\u2019re deleted.</string>
+ <!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard when asking for parental consent. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_4" product="device">You and your child can delete their fingerprint images and model, or turn off Fingerprint Unlock at any time in Settings. Fingerprint images and models are stored on the device until they\u2019re deleted.</string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_5" product="default">Your phone can be unlocked when you don\u2019t intend to, like if someone holds it up to your finger.</string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE] -->
@@ -960,7 +1042,11 @@
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_5" product="device">Your device can be unlocked when you don\u2019t intend to, like if someone holds it up to your finger.</string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard when asking for parental consent. [CHAR LIMIT=NONE] -->
- <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_5">Your child\u2019s phone can be unlocked when they don\u2019t intend to, like if someone holds it up to their finger.</string>
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_5" product="default">Your child\u2019s phone can be unlocked when they don\u2019t intend to, like if someone holds it up to their finger.</string>
+ <!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard when asking for parental consent. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_5" product="tablet">Your child\u2019s tablet can be unlocked when they don\u2019t intend to, like if someone holds it up to their finger.</string>
+ <!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard when asking for parental consent. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_5" product="device">Your child\u2019s device can be unlocked when they don\u2019t intend to, like if someone holds it up to their finger.</string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_6">For best results, use a screen protector that\u2019s Made for Google certified. With other screen protectors, your fingerprint may not work.</string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard when asking for parental consent. [CHAR LIMIT=NONE] -->
@@ -4902,6 +4988,10 @@
<!-- Title of setting on main settings screen. This item will take the user to the screen to tweak settings realted to locale and text -->
<string name="language_settings">Languages & input</string>
+ <!-- Title of setting on main settings screen. This item will take the user to the screen to tweak settings related to languages -->
+ <string name="languages_settings">Languages</string>
+ <!-- Title of setting on main settings screen. This item will take the user to the screen to tweak settings related to keyboards -->
+ <string name="keyboard_settings">Keyboard</string>
<!-- Text displayed when user has restriction DISALLOW_CONFIG_LOCALE [CHAR LIMIT=NONE]-->
<string name="language_empty_list_user_restricted">You don\u2019t have permission to change the device language.</string>
<!-- Title of Languages & input settings screen -->
@@ -4910,6 +5000,8 @@
<string name="input_assistance">Tools</string>
<!-- On Languages & input settings screen, heading. Inside the "Languages & input settings" screen, this is the header for settings that relate to keyboard (enable/disable each keyboard, settings for each keyboard). -->
<string name="keyboard_settings_category">Keyboard & input methods</string>
+ <!-- On Languages settings screen, setting option name. title of the setting to take the user to a screen to select the locale. -->
+ <string name="system_language">System Languages</string>
<!-- On Text & language settings screen, setting option name. title of the setting to take the user to a screen to select the locale. -->
<string name="phone_language">Languages</string>
<!-- On Text & language settings screen, setting option name. summary of the setting to take the user to a screen to select the locale. -->
@@ -5077,6 +5169,10 @@
<string name="input_methods_and_subtype_enabler_title">Choose active input methods</string>
<!-- Summary for on-screen keyboard settings -->
<string name="onscreen_keyboard_settings_summary">Onscreen keyboard settings</string>
+ <!-- Summary for default keyboard settings -->
+ <string name="keyboard_settings_summary">On-screen keyboard, Speech, Tools</string>
+ <!-- Summary for keyboard settings attaching physical_keyboard -->
+ <string name="keyboard_settings_with_physical_keyboard_summary">On-screen keyboard, Physical keyboard, Speech, Tools</string>
<!-- Title for built-in keyboard settings -->
<string name="builtin_keyboard_settings_title">Physical keyboard</string>
<!-- Summary for built-in keyboard settings -->
@@ -7974,8 +8070,10 @@
<!-- Title for setting tile leading to setting UI which allows user set default app to
handle actions such as open web page, making phone calls, default SMS apps [CHAR LIMIT=40]-->
<string name="app_default_dashboard_title">Default apps</string>
- <!-- Summary text for system preference tile, showing important setting items under system setting [CHAR LIMIT=NONE]-->
+ <!-- Summary text for system preference title, showing important setting items under system setting [CHAR LIMIT=NONE]-->
<string name="system_dashboard_summary">Languages, gestures, time, backup</string>
+ <!-- Summary text for language preference title, showing important setting items under language setting [CHAR LIMIT=NONE]-->
+ <string name="languages_setting_summary">System languages, app languages</string>
<!-- Search strings -->
<!-- Text to describe the search results fragment title [CHAR LIMIT=16] -->
diff --git a/res/xml/keyboard_settings.xml b/res/xml/keyboard_settings.xml
new file mode 100644
index 0000000..bff1160
--- /dev/null
+++ b/res/xml/keyboard_settings.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ 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.
+ -->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:title="@string/keyboard_settings">
+ <PreferenceCategory
+ android:key="keyboards_category"
+ android:title="@string/keyboard_and_input_methods_category">
+ <Preference
+ android:key="virtual_keyboard_pref"
+ 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"
+ android:summary="@string/summary_placeholder"
+ android:fragment="com.android.settings.inputmethod.PhysicalKeyboardFragment"/>
+ </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. -->
+ <!-- Note: Mark this as persistent="false" to remove unnecessarily saved shared preference.
+ See: InputMethodAndSubtypeUtil.removeUnnecessaryNonPersistentPreference. -->
+ <Preference
+ android:key="spellcheckers_settings"
+ android:title="@string/spellcheckers_settings_title"
+ android:persistent="false"
+ android:fragment="com.android.settings.inputmethod.SpellCheckersSettings" />
+
+ <!-- User dictionary preference title and fragment will be set programmatically. -->
+ <Preference
+ android:key="key_user_dictionary_settings"
+ android:title="@string/user_dict_settings_title"
+ android:summary="@string/user_dict_settings_summary"
+ android:fragment="com.android.settings.inputmethod.UserDictionaryList"
+ settings:controller="com.android.settings.language.UserDictionaryPreferenceController" />
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ 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" />
+ </PreferenceCategory>
+
+ <SwitchPreference
+ android:key="vibrate_input_devices"
+ android:title="@string/vibrate_input_devices"
+ android:summary="@string/vibrate_input_devices_summary"
+ settings:controller="com.android.settings.inputmethod.GameControllerPreferenceController" />
+
+ <com.android.settings.widget.WorkOnlyCategory
+ android:key="language_and_input_for_work_category"
+ android:title="@string/language_and_input_for_work_category_title"
+ settings:searchable="false">
+
+ <Preference
+ android:key="spellcheckers_settings_for_work_pref"
+ android:title="@string/spellcheckers_settings_for_work_title"
+ android:fragment="com.android.settings.inputmethod.SpellCheckersSettings"
+ settings:forWork="true"
+ settings:controller="com.android.settings.core.WorkPreferenceController" />
+
+ <Preference
+ android:key="user_dictionary_settings_for_work_pref"
+ android:title="@string/user_dict_settings_for_work_title"
+ android:fragment="com.android.settings.inputmethod.UserDictionaryList"
+ settings:forWork="true"
+ settings:controller="com.android.settings.inputmethod.SpellCheckerForWorkPreferenceController" />
+ </com.android.settings.widget.WorkOnlyCategory>
+</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/language_and_input.xml b/res/xml/language_and_input.xml
index 64b5003..03614bc 100644
--- a/res/xml/language_and_input.xml
+++ b/res/xml/language_and_input.xml
@@ -25,7 +25,8 @@
<Preference
android:key="phone_language"
android:title="@string/phone_language"
- android:fragment="com.android.settings.localepicker.LocaleListEditor" />
+ android:fragment="com.android.settings.localepicker.LocaleListEditor"
+ settings:controller="com.android.settings.language.PhoneLanguagePreferenceController" />
<Preference
android:key="apps_language"
diff --git a/res/xml/language_settings.xml b/res/xml/language_settings.xml
new file mode 100644
index 0000000..69fa4d2
--- /dev/null
+++ b/res/xml/language_settings.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ 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.
+ -->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:title="@string/languages_settings">
+ <PreferenceCategory
+ android:key="languages_category"
+ android:title="@string/locale_picker_category_title">
+ <Preference
+ android:key="phone_language"
+ android:title="@string/system_language"
+ android:fragment="com.android.settings.localepicker.LocaleListEditor"
+ settings:controller="com.android.settings.language.PhoneLanguagePreferenceController" />
+ <Preference
+ android:key="apps_language"
+ android:title="@string/app_locales_picker_menu_title"
+ android:summary="@string/app_locale_picker_summary"
+ android:fragment="com.android.settings.applications.manageapplications.ManageApplications"
+ settings:controller="com.android.settings.applications.appinfo.ManageAppLocalePreferenceController">
+ <extra
+ android:name="classname"
+ android:value="com.android.settings.applications.appinfo.AppLocaleDetails" />
+ </Preference>
+ </PreferenceCategory>
+</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/languages.xml b/res/xml/languages.xml
index 0f45540..ed65df0 100644
--- a/res/xml/languages.xml
+++ b/res/xml/languages.xml
@@ -39,4 +39,4 @@
android:selectable="false"
settings:controller="com.android.settings.localepicker.LocaleHelperPreferenceController"/>
-</PreferenceScreen>
+</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/system_dashboard_fragment.xml b/res/xml/system_dashboard_fragment.xml
index 9228ddd..3b24203 100644
--- a/res/xml/system_dashboard_fragment.xml
+++ b/res/xml/system_dashboard_fragment.xml
@@ -25,7 +25,25 @@
android:title="@string/language_settings"
android:icon="@drawable/ic_settings_language"
android:order="-260"
- android:fragment="com.android.settings.language.LanguageAndInputSettings"/>
+ android:fragment="com.android.settings.language.LanguageAndInputSettings"
+ settings:controller="com.android.settings.language.LanguageAndInputPreferenceController"/>
+
+ <Preference
+ android:key="language_settings"
+ android:title="@string/languages_settings"
+ android:summary="@string/languages_setting_summary"
+ android:icon="@drawable/ic_settings_languages"
+ android:order="-260"
+ android:fragment="com.android.settings.language.LanguageSettings"
+ settings:controller="com.android.settings.language.LanguagePreferenceController"/>
+
+ <Preference
+ android:key="Keyboard_settings"
+ android:title="@string/keyboard_settings"
+ android:icon="@drawable/ic_settings_keyboards"
+ android:order="-255"
+ android:fragment="com.android.settings.inputmethod.KeyboardSettings"
+ settings:controller="com.android.settings.inputmethod.KeyboardPreferenceController"/>
<Preference
android:key="gesture_settings"
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index f1c1191..7ed95bc 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -111,6 +111,8 @@
public static class SpellCheckersSettingsActivity extends SettingsActivity { /* empty */ }
public static class LocalePickerActivity extends SettingsActivity { /* empty */ }
public static class LanguageAndInputSettingsActivity extends SettingsActivity { /* empty */ }
+ public static class LanguageSettingsActivity extends SettingsActivity { /* empty */ }
+ public static class KeyboardSettingsActivity extends SettingsActivity { /* empty */ }
public static class UserDictionarySettingsActivity extends SettingsActivity { /* empty */ }
public static class DarkThemeSettingsActivity extends SettingsActivity { /* empty */ }
public static class DisplaySettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/accounts/AccountDetailDashboardFragment.java b/src/com/android/settings/accounts/AccountDetailDashboardFragment.java
index 1485500..0668c62 100644
--- a/src/com/android/settings/accounts/AccountDetailDashboardFragment.java
+++ b/src/com/android/settings/accounts/AccountDetailDashboardFragment.java
@@ -64,8 +64,7 @@
@Override
public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- getPreferenceManager().setPreferenceComparisonCallback(null);
+ // Initialize the parameters since displayTile() will be called in super.onCreate().
Bundle args = getArguments();
final Activity activity = getActivity();
mUserHandle = Utils.getSecureTargetUser(activity.getActivityToken(),
@@ -82,6 +81,9 @@
mAccountType = args.getString(KEY_ACCOUNT_TYPE);
}
}
+
+ super.onCreate(icicle);
+ getPreferenceManager().setPreferenceComparisonCallback(null);
mAccountSynController.init(mAccount, mUserHandle);
mRemoveAccountController.init(mAccount, mUserHandle);
}
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
index a8be8f7..2598296 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
@@ -26,6 +26,8 @@
import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.os.Bundle;
+import android.text.Html;
+import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
@@ -120,7 +122,9 @@
infoMessageLooking.setText(getInfoMessageLooking());
inControlTitle.setText(getInControlTitle());
howMessage.setText(getHowMessage());
- inControlMessage.setText(getInControlMessage());
+ inControlMessage.setText(Html.fromHtml(getString(getInControlMessage()),
+ Html.FROM_HTML_MODE_LEGACY));
+ inControlMessage.setMovementMethod(LinkMovementMethod.getInstance());
lessSecure.setText(getLessSecureMessage());
// Set up and show the "less secure" info section if necessary.
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
index bad1bbd..8656948 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
@@ -16,6 +16,8 @@
package com.android.settings.biometrics.fingerprint;
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_USER_CANCELED;
+
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.annotation.IntDef;
@@ -51,6 +53,7 @@
import android.widget.ProgressBar;
import android.widget.TextView;
+import androidx.annotation.IdRes;
import androidx.appcompat.app.AlertDialog;
import com.android.internal.annotations.VisibleForTesting;
@@ -80,6 +83,7 @@
private static final String TAG = "FingerprintEnrollEnrolling";
static final String TAG_SIDECAR = "sidecar";
static final String KEY_STATE_CANCELED = "is_canceled";
+ static final String KEY_STATE_PREVIOUS_ROTATION = "previous_rotation";
private static final int PROGRESS_BAR_MAX = 10000;
@@ -134,6 +138,7 @@
private boolean mRestoring;
private Vibrator mVibrator;
private boolean mIsSetupWizard;
+ private boolean mIsOrientationChanged;
private boolean mIsCanceled;
private AccessibilityManager mAccessibilityManager;
private boolean mIsAccessibilityEnabled;
@@ -156,6 +161,23 @@
}
@Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ if (hasFocus) {
+ return;
+ }
+
+ // By UX design, we should ensure seamless enrollment CUJ even though user rotate device.
+ // Do NOT cancel enrollment progress after rotating, adding mIsOrientationChanged
+ // to judge if the focus changed was triggered by rotation, current WMS has triple callbacks
+ // (true > false > true), we need to reset mIsOrientationChanged when !hasFocus callback.
+ if (!mIsOrientationChanged) {
+ onCancelEnrollment(FINGERPRINT_ERROR_USER_CANCELED);
+ } else {
+ mIsOrientationChanged = false;
+ }
+ }
+
+ @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -295,11 +317,15 @@
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(KEY_STATE_CANCELED, mIsCanceled);
+ outState.putInt(KEY_STATE_PREVIOUS_ROTATION, mPreviousRotation);
}
private void restoreSavedState(Bundle savedInstanceState) {
mRestoring = true;
mIsCanceled = savedInstanceState.getBoolean(KEY_STATE_CANCELED, false);
+ mPreviousRotation = savedInstanceState.getInt(KEY_STATE_PREVIOUS_ROTATION,
+ getDisplay().getRotation());
+ mIsOrientationChanged = mPreviousRotation != getDisplay().getRotation();
}
@Override
@@ -337,6 +363,19 @@
}
}
+ @VisibleForTesting
+ void onCancelEnrollment(@IdRes int errorMsgId) {
+ FingerprintErrorDialog.showErrorDialog(this, errorMsgId);
+ mIsCanceled = true;
+ mIsOrientationChanged = false;
+ cancelEnrollment();
+ stopIconAnimation();
+ stopListenOrientationEvent();
+ if (!mCanAssumeUdfps) {
+ mErrorText.removeCallbacks(mTouchAgainRunnable);
+ }
+ }
+
@Override
protected void onStop() {
if (!isChangingConfigurations()) {
@@ -556,14 +595,7 @@
@Override
public void onEnrollmentError(int errMsgId, CharSequence errString) {
- FingerprintErrorDialog.showErrorDialog(this, errMsgId);
- mIsCanceled = true;
- cancelEnrollment();
- stopIconAnimation();
- stopListenOrientationEvent();
- if (!mCanAssumeUdfps) {
- mErrorText.removeCallbacks(mTouchAgainRunnable);
- }
+ onCancelEnrollment(errMsgId);
}
@Override
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
index 71d0c8e..838c472 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
@@ -26,6 +26,8 @@
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.os.Bundle;
+import android.text.Html;
+import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
@@ -104,6 +106,11 @@
footerMessage5.setText(getFooterMessage5());
footerMessage6.setText(getFooterMessage6());
+ final TextView footerLink = findViewById(R.id.footer_learn_more);
+ footerLink.setMovementMethod(LinkMovementMethod.getInstance());
+ footerLink.setText(Html.fromHtml(getString(getFooterLearnMore()),
+ Html.FROM_HTML_MODE_LEGACY));
+
if (mCanAssumeUdfps) {
footerMessage6.setVisibility(View.VISIBLE);
iconShield.setVisibility(View.VISIBLE);
@@ -187,6 +194,11 @@
return R.string.security_settings_fingerprint_v2_enroll_introduction_footer_message_6;
}
+ @StringRes
+ protected int getFooterLearnMore() {
+ return R.string.security_settings_fingerprint_v2_enroll_introduction_message_learn_more;
+ }
+
@Override
protected boolean isDisabledByAdmin() {
return RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 5e17e0b..c6f64d6 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -115,11 +115,13 @@
import com.android.settings.gestures.SystemNavigationGestureSettings;
import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
import com.android.settings.inputmethod.KeyboardLayoutPickerFragment;
+import com.android.settings.inputmethod.KeyboardSettings;
import com.android.settings.inputmethod.PhysicalKeyboardFragment;
import com.android.settings.inputmethod.SpellCheckersSettings;
import com.android.settings.inputmethod.UserDictionaryList;
import com.android.settings.inputmethod.UserDictionarySettings;
import com.android.settings.language.LanguageAndInputSettings;
+import com.android.settings.language.LanguageSettings;
import com.android.settings.localepicker.LocaleListEditor;
import com.android.settings.location.LocationServices;
import com.android.settings.location.LocationSettings;
@@ -205,6 +207,8 @@
LocaleListEditor.class.getName(),
AvailableVirtualKeyboardFragment.class.getName(),
LanguageAndInputSettings.class.getName(),
+ LanguageSettings.class.getName(),
+ KeyboardSettings.class.getName(),
SpellCheckersSettings.class.getName(),
UserDictionaryList.class.getName(),
UserDictionarySettings.class.getName(),
@@ -383,6 +387,8 @@
Settings.LocationSettingsActivity.class.getName(),
// Home page > System
Settings.LanguageAndInputSettingsActivity.class.getName(),
+ Settings.LanguageSettingsActivity.class.getName(),
+ Settings.KeyboardSettingsActivity.class.getName(),
Settings.DateTimeSettingsActivity.class.getName(),
Settings.EnterprisePrivacySettingsActivity.class.getName(),
Settings.MyDeviceInfoActivity.class.getName(),
diff --git a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
index c2b5198..a2b1454 100644
--- a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
+++ b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
@@ -101,6 +101,7 @@
SystemDashboardFragment.class.getName(), CategoryKey.CATEGORY_SYSTEM);
PARENT_TO_CATEGORY_KEY_MAP.put(LanguageAndInputSettings.class.getName(),
CategoryKey.CATEGORY_SYSTEM_LANGUAGE);
+ // TODO(b/242680328) Tie new category key to LanguageSettings and KeyboardSettings page
PARENT_TO_CATEGORY_KEY_MAP.put(DevelopmentSettingsDashboardFragment.class.getName(),
CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
PARENT_TO_CATEGORY_KEY_MAP.put(ConfigureNotificationSettings.class.getName(),
diff --git a/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceController.java b/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceController.java
index c9cc2b7..04dfc79 100644
--- a/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceController.java
+++ b/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceController.java
@@ -40,9 +40,8 @@
private static final String TAG = "AbstractBtDlgCtr";
- private static final int SOURCE_CODEC_TYPE_OPUS = 6; // TODO(b/240635097): remove in U
-
- protected static final int[] CODEC_TYPES = {SOURCE_CODEC_TYPE_OPUS,
+ protected static final int[] CODEC_TYPES = {
+ BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS,
BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3,
BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD,
diff --git a/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java b/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java
index 87d5ff0..2f0d27c 100644
--- a/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java
+++ b/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java
@@ -40,8 +40,6 @@
private static final String KEY = "bluetooth_audio_codec_settings";
private static final String TAG = "BtCodecCtr";
- private static final int SOURCE_CODEC_TYPE_OPUS = 6; // TODO remove in U
-
private final Callback mCallback;
public BluetoothCodecDialogPreferenceController(Context context, Lifecycle lifecycle,
@@ -125,7 +123,7 @@
codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
break;
case 7:
- codecTypeValue = SOURCE_CODEC_TYPE_OPUS; // TODO update in U
+ codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS;
codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
break;
default:
@@ -190,7 +188,7 @@
case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC:
index = 5;
break;
- case SOURCE_CODEC_TYPE_OPUS: // TODO update in U
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS:
index = 7;
break;
default:
diff --git a/src/com/android/settings/inputmethod/KeyboardPreferenceController.java b/src/com/android/settings/inputmethod/KeyboardPreferenceController.java
new file mode 100644
index 0000000..75351b1
--- /dev/null
+++ b/src/com/android/settings/inputmethod/KeyboardPreferenceController.java
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ * 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.settings.inputmethod;
+
+import android.content.Context;
+import android.hardware.input.InputManager;
+import android.util.FeatureFlagUtils;
+
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.inputmethod.PhysicalKeyboardFragment.HardKeyboardDeviceInfo;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnPause;
+import com.android.settingslib.core.lifecycle.events.OnResume;
+
+import java.util.List;
+
+public class KeyboardPreferenceController extends BasePreferenceController
+ implements PreferenceControllerMixin, LifecycleObserver, OnResume, OnPause,
+ InputManager.InputDeviceListener {
+
+ private final InputManager mIm;
+
+ private Preference mPreference;
+
+ public KeyboardPreferenceController(Context context, String key) {
+ super(context, key);
+ mIm = context.getSystemService(InputManager.class);
+ }
+
+ @Override
+ public void onInputDeviceAdded(int deviceId) {
+ updateSummary();
+ }
+
+ @Override
+ public void onInputDeviceRemoved(int deviceId) {
+ updateSummary();
+ }
+
+ @Override
+ public void onInputDeviceChanged(int deviceId) {
+ updateSummary();
+ }
+
+ @Override
+ public void onPause() {
+ mIm.unregisterInputDeviceListener(this);
+ }
+
+ @Override
+ public void onResume() {
+ mIm.registerInputDeviceListener(this, null);
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ mPreference = preference;
+ updateSummary();
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ boolean isFeatureOn = FeatureFlagUtils
+ .isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
+ return isFeatureOn ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+ }
+
+ private void updateSummary() {
+ final List<HardKeyboardDeviceInfo> keyboards =
+ PhysicalKeyboardFragment.getHardKeyboards(mContext);
+ if (keyboards.isEmpty()) {
+ mPreference.setSummary(R.string.keyboard_settings_summary);
+ } else {
+ mPreference.setSummary(R.string.keyboard_settings_with_physical_keyboard_summary);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/inputmethod/KeyboardSettings.java b/src/com/android/settings/inputmethod/KeyboardSettings.java
new file mode 100644
index 0000000..2d6ac88
--- /dev/null
+++ b/src/com/android/settings/inputmethod/KeyboardSettings.java
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ * 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.settings.inputmethod;
+
+import static android.app.admin.DevicePolicyResources.Strings.Settings.PERSONAL_DICTIONARY_FOR_WORK;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.SPELL_CHECKER_FOR_WORK;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_KEYBOARDS_AND_TOOLS;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.FeatureFlagUtils;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.language.DefaultVoiceInputPreferenceController;
+import com.android.settings.language.PointerSpeedController;
+import com.android.settings.language.TtsPreferenceController;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.widget.PreferenceCategoryController;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.search.SearchIndexable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@SearchIndexable
+public class KeyboardSettings extends DashboardFragment {
+
+ private static final String TAG = "KeyboardSettings";
+
+ 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_CATEGORY = "pointer_category";
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.SETTINGS_KEYBOARDS_CATEGORY;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ replaceEnterpriseStringTitle("language_and_input_for_work_category",
+ WORK_PROFILE_KEYBOARDS_AND_TOOLS,
+ R.string.language_and_input_for_work_category_title);
+ replaceEnterpriseStringTitle("spellcheckers_settings_for_work_pref",
+ SPELL_CHECKER_FOR_WORK,
+ R.string.spellcheckers_settings_for_work_title);
+ replaceEnterpriseStringTitle("user_dictionary_settings_for_work_pref",
+ PERSONAL_DICTIONARY_FOR_WORK,
+ R.string.user_dict_settings_for_work_title);
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.keyboard_settings;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, getSettingsLifecycle());
+ }
+
+ private static List<AbstractPreferenceController> buildPreferenceControllers(
+ @NonNull Context context, @Nullable Lifecycle lifecycle) {
+ final List<AbstractPreferenceController> controllers = new ArrayList<>();
+ // Input
+ final VirtualKeyboardPreferenceController virtualKeyboardPreferenceController =
+ new VirtualKeyboardPreferenceController(context);
+ final PhysicalKeyboardPreferenceController physicalKeyboardPreferenceController =
+ new PhysicalKeyboardPreferenceController(context, lifecycle);
+ controllers.add(virtualKeyboardPreferenceController);
+ controllers.add(physicalKeyboardPreferenceController);
+ controllers.add(new PreferenceCategoryController(context,
+ KEY_KEYBOARDS_CATEGORY).setChildren(
+ Arrays.asList(virtualKeyboardPreferenceController,
+ physicalKeyboardPreferenceController)));
+
+ // 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_CATEGORY).setChildren(Arrays.asList(pointerController)));
+
+ // Input Assistance
+ controllers.add(new SpellCheckerPreferenceController(context));
+
+ return controllers;
+ }
+
+ public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider(R.xml.keyboard_settings) {
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return FeatureFlagUtils
+ .isEnabled(context, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/com/android/settings/language/LanguageAndInputPreferenceController.java b/src/com/android/settings/language/LanguageAndInputPreferenceController.java
index 04bf622..691d907 100644
--- a/src/com/android/settings/language/LanguageAndInputPreferenceController.java
+++ b/src/com/android/settings/language/LanguageAndInputPreferenceController.java
@@ -21,6 +21,7 @@
import android.content.pm.PackageManager;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.FeatureFlagUtils;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
@@ -41,7 +42,9 @@
@Override
public int getAvailabilityStatus() {
- return AVAILABLE;
+ boolean isFeatureOn = FeatureFlagUtils
+ .isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
+ return isFeatureOn ? CONDITIONALLY_UNAVAILABLE : AVAILABLE;
}
@Override
diff --git a/src/com/android/settings/language/LanguageAndInputSettings.java b/src/com/android/settings/language/LanguageAndInputSettings.java
index 2d80da5..f40473c 100644
--- a/src/com/android/settings/language/LanguageAndInputSettings.java
+++ b/src/com/android/settings/language/LanguageAndInputSettings.java
@@ -24,6 +24,7 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle;
+import android.util.FeatureFlagUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -104,8 +105,6 @@
private static List<AbstractPreferenceController> buildPreferenceControllers(
@NonNull Context context, @Nullable Lifecycle lifecycle) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
- // Language
- controllers.add(new PhoneLanguagePreferenceController(context));
// Input
final VirtualKeyboardPreferenceController virtualKeyboardPreferenceController =
@@ -154,11 +153,16 @@
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.language_and_input) {
-
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null);
}
+
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return !FeatureFlagUtils
+ .isEnabled(context, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
+ }
};
}
diff --git a/src/com/android/settings/language/LanguagePreferenceController.java b/src/com/android/settings/language/LanguagePreferenceController.java
new file mode 100644
index 0000000..08033cd
--- /dev/null
+++ b/src/com/android/settings/language/LanguagePreferenceController.java
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ * 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.settings.language;
+
+import android.content.Context;
+import android.util.FeatureFlagUtils;
+
+import com.android.settings.core.BasePreferenceController;
+
+public class LanguagePreferenceController extends BasePreferenceController {
+
+ public LanguagePreferenceController(Context context, String key) {
+ super(context, key);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ boolean isFeatureOn = FeatureFlagUtils
+ .isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
+ return isFeatureOn ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/language/LanguageSettings.java b/src/com/android/settings/language/LanguageSettings.java
new file mode 100644
index 0000000..f814e36
--- /dev/null
+++ b/src/com/android/settings/language/LanguageSettings.java
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ * 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.settings.language;
+
+import android.app.Activity;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.util.FeatureFlagUtils;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.search.SearchIndexable;
+
+@SearchIndexable
+public class LanguageSettings extends DashboardFragment {
+
+ private static final String TAG = "LanguageSettings";
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.SETTINGS_LANGUAGES_CATEGORY;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ // Hack to update action bar title. It's necessary to refresh title because this page user
+ // can change locale from here and fragment won't relaunch. Once language changes, title
+ // must display in the new language.
+ final Activity activity = getActivity();
+ if (activity == null) {
+ return;
+ }
+ activity.setTitle(R.string.languages_settings);
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.language_settings;
+ }
+
+ public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider(R.xml.language_settings) {
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return FeatureFlagUtils
+ .isEnabled(context, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/com/android/settings/language/PhoneLanguagePreferenceController.java b/src/com/android/settings/language/PhoneLanguagePreferenceController.java
index 4f67a8f..0d5aa37 100644
--- a/src/com/android/settings/language/PhoneLanguagePreferenceController.java
+++ b/src/com/android/settings/language/PhoneLanguagePreferenceController.java
@@ -16,33 +16,32 @@
package com.android.settings.language;
-import android.app.settings.SettingsEnums;
import android.content.Context;
import androidx.preference.Preference;
import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.SubSettingLauncher;
-import com.android.settings.localepicker.LocaleListEditor;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.AbstractPreferenceController;
import java.util.List;
-public class PhoneLanguagePreferenceController extends AbstractPreferenceController
+public class PhoneLanguagePreferenceController extends BasePreferenceController
implements PreferenceControllerMixin {
- private static final String KEY_PHONE_LANGUAGE = "phone_language";
-
- public PhoneLanguagePreferenceController(Context context) {
- super(context);
+ public PhoneLanguagePreferenceController(Context context, String key) {
+ super(context, key);
}
@Override
- public boolean isAvailable() {
- return mContext.getResources().getBoolean(R.bool.config_show_phone_language)
- && mContext.getAssets().getLocales().length > 1;
+ public int getAvailabilityStatus() {
+ if (mContext.getResources().getBoolean(R.bool.config_show_phone_language)
+ && mContext.getAssets().getLocales().length > 1) {
+ return AVAILABLE;
+ } else {
+ return CONDITIONALLY_UNAVAILABLE;
+ }
}
@Override
@@ -61,23 +60,4 @@
// make search page look like there are duplicate result, creating confusion.
keys.add(getPreferenceKey());
}
-
- @Override
- public String getPreferenceKey() {
- return KEY_PHONE_LANGUAGE;
- }
-
- @Override
- public boolean handlePreferenceTreeClick(Preference preference) {
- if (!KEY_PHONE_LANGUAGE.equals(preference.getKey())) {
- return false;
- }
- new SubSettingLauncher(mContext)
- .setDestination(LocaleListEditor.class.getName())
- .setSourceMetricsCategory(SettingsEnums.SETTINGS_LANGUAGE_CATEGORY)
- .setTitleRes(R.string.language_picker_title)
- .launch();
- return true;
- }
-
}
diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java
index 3af10fd..6ed4169 100644
--- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java
+++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java
@@ -16,6 +16,8 @@
package com.android.settings.biometrics.fingerprint;
+import static com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling.KEY_STATE_PREVIOUS_ROTATION;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.any;
@@ -28,14 +30,18 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.content.Context;
import android.hardware.biometrics.ComponentInfoInternal;
import android.hardware.biometrics.SensorProperties;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintManager.EnrollmentCallback;
import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
+import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Vibrator;
+import android.view.Display;
+import android.view.Surface;
import android.widget.TextView;
import com.android.settings.R;
@@ -49,6 +55,7 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
import org.robolectric.android.controller.ActivityController;
import java.util.ArrayList;
@@ -61,7 +68,10 @@
@Mock private Vibrator mVibrator;
+ @Mock private Display mMockDisplay;
+
private FingerprintEnrollEnrolling mActivity;
+ private Context mContext;
@Before
public void setUp() {
@@ -100,6 +110,26 @@
verify(mVibrator, never()).vibrate(anyInt(), anyString(), any(), anyString(), any());
}
+ @Test
+ public void fingerprintUdfpsOverlayEnrollment_gainFocus_shouldNotCancel() {
+ initializeActivityFor(FingerprintSensorProperties.TYPE_UDFPS_OPTICAL);
+
+ mActivity.onEnrollmentProgressChange(1, 1);
+ mActivity.onWindowFocusChanged(true);
+
+ verify(mActivity, never()).onCancelEnrollment(anyInt());
+ }
+
+ @Test
+ public void fingerprintUdfpsOverlayEnrollment_loseFocus_shouldCancel() {
+ initializeActivityFor(FingerprintSensorProperties.TYPE_UDFPS_OPTICAL);
+
+ mActivity.onEnrollmentProgressChange(1, 1);
+ mActivity.onWindowFocusChanged(false);
+
+ verify(mActivity, never()).onCancelEnrollment(anyInt());
+ }
+
private void initializeActivityFor(int sensorType) {
final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
final FingerprintSensorPropertiesInternal prop =
@@ -111,15 +141,21 @@
sensorType,
true /* resetLockoutRequiresHardwareAuthToken */);
final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
+ final Bundle savedInstanceState = new Bundle();
+ savedInstanceState.putInt(KEY_STATE_PREVIOUS_ROTATION, Surface.ROTATION_90);
props.add(prop);
- when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(props);
-
+ mContext = spy(RuntimeEnvironment.application);
mActivity = spy(FingerprintEnrollEnrolling.class);
+
+ when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(props);
+ when(mContext.getDisplay()).thenReturn(mMockDisplay);
+ when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_0);
+
doReturn(true).when(mActivity).shouldShowLottie();
doReturn(mFingerprintManager).when(mActivity).getSystemService(FingerprintManager.class);
doReturn(mVibrator).when(mActivity).getSystemService(Vibrator.class);
- ActivityController.of(mActivity).create();
+ ActivityController.of(mActivity).create(savedInstanceState);
}
private EnrollmentCallback verifyAndCaptureEnrollmentCallback() {
diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java
index 8da44cc..de2b363 100644
--- a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java
@@ -52,8 +52,6 @@
@RunWith(RobolectricTestRunner.class)
public class BluetoothCodecDialogPreferenceControllerTest {
- private static final int SOURCE_CODEC_TYPE_OPUS = 6; // TODO(b/240635097): remove in U
-
private static final String DEVICE_ADDRESS = "00:11:22:33:44:55";
@Mock
@@ -123,7 +121,7 @@
.setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC)
.build();
mCodecConfigOPUS = new BluetoothCodecConfig.Builder()
- .setCodecType(SOURCE_CODEC_TYPE_OPUS)
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS)
.build();
when(mBluetoothAdapter.getActiveDevices(eq(BluetoothProfile.A2DP)))
.thenReturn(Arrays.asList(mActiveDevice));
@@ -143,8 +141,8 @@
mController.onBluetoothServiceConnected(mBluetoothA2dp);
mController.writeConfigurationValues(0);
- // TODO(b/240635097): update in U
- verify(mBluetoothA2dpConfigStore).setCodecType(SOURCE_CODEC_TYPE_OPUS);
+ verify(mBluetoothA2dpConfigStore).setCodecType(
+ BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS);
}
@Test
@@ -176,8 +174,8 @@
verify(mBluetoothA2dpConfigStore).setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC);
mController.writeConfigurationValues(7);
- // TODO(b/240635097): update in U
- verify(mBluetoothA2dpConfigStore).setCodecType(SOURCE_CODEC_TYPE_OPUS);
+ verify(mBluetoothA2dpConfigStore).setCodecType(
+ BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS);
}
@Test
@@ -211,8 +209,8 @@
@Test
public void getCurrentIndexByConfig_verifyOpusIndex() {
assertThat(mController.getCurrentIndexByConfig(mCodecConfigOPUS)).isEqualTo(
- mController.convertCfgToBtnIndex(SOURCE_CODEC_TYPE_OPUS));
- // TODO(b/240635097): update in U
+ mController.convertCfgToBtnIndex(
+ BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS));
}
@@ -239,7 +237,7 @@
mController.onHDAudioEnabled(/* enabled= */ true);
verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecType(
- eq(SOURCE_CODEC_TYPE_OPUS)); // TODO(b/240635097): update in U
+ eq(BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/language/PhoneLanguagePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/language/PhoneLanguagePreferenceControllerTest.java
index b67cc5d..aa4c32e 100644
--- a/tests/robotests/src/com/android/settings/language/PhoneLanguagePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/language/PhoneLanguagePreferenceControllerTest.java
@@ -27,6 +27,7 @@
import androidx.preference.Preference;
+import com.android.settings.core.BasePreferenceController;
import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
@@ -59,7 +60,7 @@
mContext = spy(RuntimeEnvironment.application);
when(mContext.getAssets()).thenReturn(mAssets);
mFeatureFactory = FakeFeatureFactory.setupForTest();
- mController = new PhoneLanguagePreferenceController(mContext);
+ mController = new PhoneLanguagePreferenceController(mContext, "key");
}
@Test
@@ -77,6 +78,22 @@
}
@Test
+ public void testGetAvailabilityStatus_hasMultipleLocales_returnAvailable() {
+ when(mAssets.getLocales()).thenReturn(new String[] {"en", "de"});
+
+ assertThat(mController.getAvailabilityStatus())
+ .isEqualTo(BasePreferenceController.AVAILABLE);
+ }
+
+ @Test
+ public void testGetAvailabilityStatus_hasSingleLocales_returnConditionallyUnavailable() {
+ when(mAssets.getLocales()).thenReturn(new String[] {"en"});
+
+ assertThat(mController.getAvailabilityStatus())
+ .isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
+ }
+
+ @Test
@Config(qualifiers = "mcc999")
public void testIsAvailable_ifDisabled_shouldReturnFalse() {
assertThat(mController.isAvailable()).isFalse();