Snap for 9541950 from c88ad2f866 to udc-release
Change-Id: Ie2ad2cc62d85d9f81208247b41de9fb27d183310
This commit is contained in:
@@ -3636,7 +3636,7 @@
|
||||
android:label="@string/notification_channel_title"
|
||||
android:theme="@style/Theme.Panel"
|
||||
android:excludeFromRecents="true"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
android:configChanges="keyboardHidden|screenSize"
|
||||
android:exported="true">
|
||||
<intent-filter android:priority="1">
|
||||
<action android:name="android.settings.CHANNEL_NOTIFICATION_SETTINGS" />
|
||||
|
||||
@@ -245,6 +245,12 @@
|
||||
<string name="security_settings_fingerprint_enroll_finish_v2_message" product="device">Now you can use your fingerprint to unlock your device or verify it\u2019s you, like when you sign in to apps or approve a purchase</string>
|
||||
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (default) [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_fingerprint_enroll_finish_v2_message" product="default">Now you can use your fingerprint to unlock your phone or verify it\u2019s you, like when you sign in to apps or approve a purchase</string>
|
||||
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (tablet) [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_fingerprint_enroll_finish_v2_add_fingerprint_message" product="tablet">Now you can use your fingerprint to unlock your tablet or verify it\u2019s you, like when you sign in to apps or approve a purchase. \n\nAdd another fingerprint so it\u2019s easier to unlock when you hold your tablet in different ways.</string>
|
||||
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (device) [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_fingerprint_enroll_finish_v2_add_fingerprint_message" product="device">Now you can use your fingerprint to unlock your device or verify it\u2019s you, like when you sign in to apps or approve a purchase.\n\nAdd another fingerprint so it\u2019s easier to unlock when you hold your device in different ways.</string>
|
||||
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (default) [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_fingerprint_enroll_finish_v2_add_fingerprint_message" product="default">Now you can use your fingerprint to unlock your phone or verify it\u2019s you, like when you sign in to apps or approve a purchase.\n\nAdd another fingerprint so it\u2019s easier to unlock when you hold your phone in different ways.</string>
|
||||
<!-- Dialog text shown when the user tries to skip setting up a screen lock, warning that they can't continue to set up fingerprint. (tablet) [CHAR LIMIT=NONE] -->
|
||||
<string name="lock_screen_pin_skip_message" product="tablet">A PIN protects the tablet if it\u2019s lost or stolen</string>
|
||||
<!-- Dialog text shown when the user tries to skip setting up a screen lock, warning that they can't continue to set up fingerprint. (tablet) [CHAR LIMIT=NONE] -->
|
||||
|
||||
24
res/drawable/checkbox_circle_shape.xml
Normal file
24
res/drawable/checkbox_circle_shape.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<!--
|
||||
~ Copyright (C) 2023 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.
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:state_checked="true"
|
||||
android:drawable="@drawable/ic_check_circle_filled_24dp" />
|
||||
<item
|
||||
android:state_checked="false"
|
||||
android:drawable="@drawable/ic_circle_outline_24dp" />
|
||||
</selector>
|
||||
27
res/drawable/ic_check_circle_filled_24dp.xml
Normal file
27
res/drawable/ic_check_circle_filled_24dp.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<!--
|
||||
~ Copyright (C) 2023 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"
|
||||
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?androidprv:attr/colorAccentPrimaryVariant">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10c5.52,0 10,-4.48 10,-10S17.52,2 12,2zM10.59,16.6l-4.24,-4.24l1.41,-1.41l2.83,2.83l5.66,-5.66l1.41,1.41L10.59,16.6z"/>
|
||||
</vector>
|
||||
26
res/drawable/ic_circle_outline_24dp.xml
Normal file
26
res/drawable/ic_circle_outline_24dp.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<!--
|
||||
~ Copyright (C) 2023 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="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
|
||||
</vector>
|
||||
@@ -19,12 +19,13 @@
|
||||
android:width="18dp"
|
||||
android:height="18dp"
|
||||
android:viewportWidth="48"
|
||||
android:viewportHeight="48">
|
||||
android:viewportHeight="48"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M0,0h48v48H0z M 0,0"/>
|
||||
<path
|
||||
android:pathData="M46,11v29c0,4.4 -3.6,8 -8,8H23.4c-2.16,0 -4.2,-0.86 -5.7,-2.38L2,29.66s2.52,-2.46 2.6,-2.5c0.44,-0.38 0.98,-0.58 1.58,-0.58 0.44,0 0.84,0.12 1.2,0.32 0.08,0.02 8.62,4.92 8.62,4.92V8c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v14h2V3c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v19h2V5c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v17h2V11c0,-1.66 1.34,-3 3,-3s3,1.34 3,3z"
|
||||
android:fillColor="#757575"/>
|
||||
android:fillColor="#FFFFFF"/>
|
||||
</group>
|
||||
</vector>
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
android:width="18dp"
|
||||
android:height="18dp"
|
||||
android:viewportWidth="48"
|
||||
android:viewportHeight="48">
|
||||
android:viewportHeight="48"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:pathData="M24,9C14,9 5.46,15.22 2,24c3.46,8.78 12,15 22,15 10.01,0 18.54,-6.22 22,-15 -3.46,-8.78 -11.99,-15 -22,-15zM24,34c-5.52,0 -10,-4.48 -10,-10s4.48,-10 10,-10 10,4.48 10,10 -4.48,10 -10,10zM24,18c-3.31,0 -6,2.69 -6,6s2.69,6 6,6 6,-2.69 6,-6 -2.69,-6 -6,-6z"
|
||||
android:fillColor="#757575"/>
|
||||
android:fillColor="#FFFFFF"/>
|
||||
</vector>
|
||||
|
||||
@@ -67,8 +67,31 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/auto_pin_confirm_enabler"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="14dp"
|
||||
android:text="@string/auto_pin_confirm_user_message"
|
||||
android:textSize="16sp"
|
||||
android:button="@drawable/checkbox_circle_shape"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/auto_pin_confirm_security_message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/auto_pin_confirm_opt_in_security_message"
|
||||
android:textSize="16sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/screen_lock_options"
|
||||
style="@style/SudGlifButton.Tertiary"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/main_content"
|
||||
android:layout_height="@dimen/output_switcher_slice_max_height"
|
||||
android:maxHeight="@dimen/output_switcher_slice_max_height"
|
||||
android:background="@drawable/settings_panel_background"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent">
|
||||
|
||||
@@ -19,4 +19,5 @@
|
||||
<dimen name="biometric_auth_pattern_view_size">248dp</dimen>
|
||||
<dimen name="biometric_auth_pattern_view_max_size">348dp</dimen>
|
||||
|
||||
<dimen name="output_switcher_slice_max_height">300dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -101,6 +101,14 @@
|
||||
-->
|
||||
</string-array>
|
||||
|
||||
<!-- List containing the component names of pre-installed speech services. -->
|
||||
<string-array name="config_preinstalled_speech_services" translatable="false">
|
||||
<!--
|
||||
<item>com.example.package.first/com.example.class.FirstService</item>
|
||||
<item>com.example.package.second/com.example.class.SecondService</item>
|
||||
-->
|
||||
</string-array>
|
||||
|
||||
<!-- List containing the component names of pre-installed interaction control services. -->
|
||||
<string-array name="config_preinstalled_interaction_control_services" translatable="false">
|
||||
<!--
|
||||
@@ -109,8 +117,9 @@
|
||||
-->
|
||||
</string-array>
|
||||
|
||||
<!-- List containing the order of services in screen reader category by componentname.
|
||||
All componentnames in a category need to be specified to guarantee correct behavior.-->
|
||||
<!-- List containing the order of services in screen reader category by {@link ComponentName}.
|
||||
All {@link ComponentName} in a category need to be specified to guarantee correct
|
||||
behavior.-->
|
||||
<string-array name="config_order_screen_reader_services" translatable="false">
|
||||
<!--
|
||||
<item>com.example.package.first/com.example.class.FirstService</item>
|
||||
@@ -119,8 +128,8 @@
|
||||
</string-array>
|
||||
|
||||
<!-- List containing the order of services in captions category by preference key or
|
||||
componentname. All preference keys in a category need to be specified to guarantee correct
|
||||
behavior.-->
|
||||
{@link ComponentName}. All preference keys in a category need to be specified to guarantee
|
||||
correct behavior.-->
|
||||
<string-array name="config_order_captions_services" translatable="false">
|
||||
<!--
|
||||
<item>com.example.package.first/com.example.class.FirstService</item>
|
||||
@@ -131,8 +140,8 @@
|
||||
-->
|
||||
</string-array>
|
||||
|
||||
<!-- List containing the order of services in audio and caption category by preference key
|
||||
or componentname. All preference keys in a category need to be specified to guarantee
|
||||
<!-- List containing the order of services in audio and caption category by preference key or
|
||||
{@link ComponentName}. All preference keys in a category need to be specified to guarantee
|
||||
correct behavior.-->
|
||||
<string-array name="config_order_audio_services" translatable="false">
|
||||
<!--
|
||||
@@ -144,8 +153,8 @@
|
||||
-->
|
||||
</string-array>
|
||||
|
||||
<!-- List containing the order of services in display category by preference key
|
||||
or componentname. All preference keys in a category need to be specified to guarantee
|
||||
<!-- List containing the order of services in display category by preference key or
|
||||
{@link ComponentName}. All preference keys in a category need to be specified to guarantee
|
||||
correct behavior.-->
|
||||
<string-array name="config_order_display_services" translatable="false">
|
||||
<!--
|
||||
@@ -157,8 +166,21 @@
|
||||
-->
|
||||
</string-array>
|
||||
|
||||
<!-- List containing the order of services in interaction control category by preference key
|
||||
or componentname. All preference keys in a category need to be specified to guarantee
|
||||
<!-- List containing the order of services in speech category by preference key or
|
||||
{@link ComponentName}. All preference keys in a category need to be specified to guarantee
|
||||
correct behavior.-->
|
||||
<string-array name="config_order_speech_services" translatable="false">
|
||||
<!--
|
||||
<item>com.example.package.first/com.example.class.FirstService</item>
|
||||
<item>com.example.package.second/com.example.class.SecondService</item>
|
||||
<item>font_size_preference_screen</item>
|
||||
<item>dark_ui_mode_accessibility</item>
|
||||
<item>...</item>
|
||||
-->
|
||||
</string-array>
|
||||
|
||||
<!-- List containing the order of services in interaction control category by preference key or
|
||||
{@link ComponentName}. All preference keys in a category need to be specified to guarantee
|
||||
correct behavior.-->
|
||||
<string-array name="config_order_interaction_control_services" translatable="false">
|
||||
<!--
|
||||
|
||||
@@ -932,18 +932,6 @@
|
||||
<string name="security_settings_udfps_enroll_progress_a11y_message">Enrolling fingerprint <xliff:g id="percentage" example="10">%d</xliff:g> percent</string>
|
||||
<!-- Title shown in fingerprint enrollment dialog once enrollment is completed [CHAR LIMIT=29] -->
|
||||
<string name="security_settings_fingerprint_enroll_finish_title">Fingerprint added</string>
|
||||
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (tablet) [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_fingerprint_enroll_finish_v2_message" product="tablet">Now you can use your fingerprint to unlock your tablet or verify it\u2019s you, like when you sign in to apps or approve a purchase</string>
|
||||
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (device) [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_fingerprint_enroll_finish_v2_message" product="device">Now you can use your fingerprint to unlock your device or verify it\u2019s you, like when you sign in to apps or approve a purchase</string>
|
||||
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (default) [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_fingerprint_enroll_finish_v2_message" product="default">Now you can use your fingerprint to unlock your phone or verify it\u2019s you, like when you sign in to apps or approve a purchase</string>
|
||||
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (tablet) [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_fingerprint_enroll_finish_v2_add_fingerprint_message" product="tablet">Now you can use your fingerprint to unlock your tablet or verify it\u2019s you, like when you sign in to apps or approve a purchase. \n\nAdd another fingerprint so it\u2019s easier to unlock when you hold your tablet in different ways.</string>
|
||||
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (device) [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_fingerprint_enroll_finish_v2_add_fingerprint_message" product="device">Now you can use your fingerprint to unlock your device or verify it\u2019s you, like when you sign in to apps or approve a purchase.\n\nAdd another fingerprint so it\u2019s easier to unlock when you hold your device in different ways.</string>
|
||||
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (default) [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_fingerprint_enroll_finish_v2_add_fingerprint_message" product="default">Now you can use your fingerprint to unlock your phone or verify it\u2019s you, like when you sign in to apps or approve a purchase.\n\nAdd another fingerprint so it\u2019s easier to unlock when you hold your phone in different ways.</string>
|
||||
<!-- Title for require screen on to auth toggle shown in fingerprint enrollment dialog once enrollment is completed. [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_require_screen_on_to_auth_title">Touch to unlock anytime</string>
|
||||
<!-- Description for require screen on to auth toggle shown in fingerprint enrollment dialog once enrollment is completed. [CHAR LIMIT=NONE] -->
|
||||
@@ -1102,6 +1090,15 @@
|
||||
<!-- Title for dialog in screen lock settings, allowing users to choose other types of screen locks. [CHAR LIMIT=40] -->
|
||||
<string name="setup_lock_settings_options_dialog_title">Screen lock options</string>
|
||||
|
||||
<!-- Title of the lock screen auto pin confirm setting. [CHAR LIMIT=NONE] -->
|
||||
<string name="lock_screen_auto_pin_confirm_title">Auto-confirm unlock</string>
|
||||
<!-- Summary of the lock screen auto pin confirm setting. [CHAR LIMIT=NONE] -->
|
||||
<string name="lock_screen_auto_pin_confirm_summary">Unlock automatically if you input a correct PIN of 6 digits or more. This is slightly less secure than tapping Enter to confirm.</string>
|
||||
<!-- Message shown to check auto pin confirmation feature when the user is updating the PIN. [CHAR LIMIT=NONE] -->
|
||||
<string name="auto_pin_confirm_user_message">Auto-confirm correct PIN</string>
|
||||
<!-- Message shown to explain the security concern if a user opts-in to the auto-pin feature. [CHAR LIMIT=NONE] -->
|
||||
<string name="auto_pin_confirm_opt_in_security_message">Confirming your PIN by tapping Enter is more secure than using auto-confirm</string>
|
||||
|
||||
<!-- Main Security lock settings --><skip />
|
||||
<!-- Title for PreferenceScreen to launch picker for security method when there is none [CHAR LIMIT=22] -->
|
||||
<string name="unlock_set_unlock_launch_picker_title">Screen lock</string>
|
||||
@@ -1262,6 +1259,12 @@
|
||||
other {PIN must be at least # digits}
|
||||
}</string>
|
||||
|
||||
<!-- Hint shown in dialog screen when PIN is too short with Additional text indicating minAutoConfirmLen(eg: 6) digits PIN offer additional security -->
|
||||
<string name="lockpassword_pin_too_short_autoConfirm_extra_message">{count, plural,
|
||||
=1 {PIN must contain at least # digit, but a {minAutoConfirmLen}-digit PIN is recommended for added security}
|
||||
other {PIN must be at least # digits, but a {minAutoConfirmLen}-digit PIN is recommended for added security}
|
||||
}</string>
|
||||
|
||||
<!-- Error shown in popup when password is too long -->
|
||||
<string name="lockpassword_password_too_long">{count, plural,
|
||||
=1 {Must be fewer than # character}
|
||||
|
||||
@@ -169,6 +169,11 @@
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="speech_category"
|
||||
android:persistent="false"
|
||||
android:title="@string/speech_category_title"/>
|
||||
|
||||
<PreferenceCategory
|
||||
android:persistent="false"
|
||||
android:title="@string/general_category_title">
|
||||
|
||||
@@ -27,6 +27,12 @@
|
||||
android:key="visiblepattern"
|
||||
android:title="@string/lockpattern_settings_enable_visible_pattern_title" />
|
||||
|
||||
<!-- available in pin -->
|
||||
<SwitchPreference
|
||||
android:key="auto_pin_confirm"
|
||||
android:title="@string/lock_screen_auto_pin_confirm_title"
|
||||
android:summary="@string/lock_screen_auto_pin_confirm_summary" />
|
||||
|
||||
<!-- available in pin/pattern/password -->
|
||||
<com.android.settings.display.TimeoutListPreference
|
||||
android:key="lock_after_timeout"
|
||||
|
||||
@@ -63,6 +63,7 @@ public class AccessibilitySettings extends DashboardFragment {
|
||||
private static final String CATEGORY_SCREEN_READER = "screen_reader_category";
|
||||
private static final String CATEGORY_CAPTIONS = "captions_category";
|
||||
private static final String CATEGORY_AUDIO = "audio_category";
|
||||
private static final String CATEGORY_SPEECH = "speech_category";
|
||||
private static final String CATEGORY_DISPLAY = "display_category";
|
||||
private static final String CATEGORY_DOWNLOADED_SERVICES = "user_installed_services_category";
|
||||
@VisibleForTesting
|
||||
@@ -70,7 +71,7 @@ public class AccessibilitySettings extends DashboardFragment {
|
||||
|
||||
private static final String[] CATEGORIES = new String[]{
|
||||
CATEGORY_SCREEN_READER, CATEGORY_CAPTIONS, CATEGORY_AUDIO, CATEGORY_DISPLAY,
|
||||
CATEGORY_INTERACTION_CONTROL, CATEGORY_DOWNLOADED_SERVICES
|
||||
CATEGORY_SPEECH, CATEGORY_INTERACTION_CONTROL, CATEGORY_DOWNLOADED_SERVICES
|
||||
};
|
||||
|
||||
// Extras passed to sub-fragments.
|
||||
@@ -351,6 +352,8 @@ public class AccessibilitySettings extends DashboardFragment {
|
||||
R.array.config_preinstalled_audio_services);
|
||||
initializePreBundledServicesMapFromArray(CATEGORY_DISPLAY,
|
||||
R.array.config_preinstalled_display_services);
|
||||
initializePreBundledServicesMapFromArray(CATEGORY_SPEECH,
|
||||
R.array.config_preinstalled_speech_services);
|
||||
initializePreBundledServicesMapFromArray(CATEGORY_INTERACTION_CONTROL,
|
||||
R.array.config_preinstalled_interaction_control_services);
|
||||
|
||||
@@ -390,6 +393,8 @@ public class AccessibilitySettings extends DashboardFragment {
|
||||
R.array.config_order_interaction_control_services);
|
||||
updateCategoryOrderFromArray(CATEGORY_DISPLAY,
|
||||
R.array.config_order_display_services);
|
||||
updateCategoryOrderFromArray(CATEGORY_SPEECH,
|
||||
R.array.config_order_speech_services);
|
||||
|
||||
// Need to check each time when updateServicePreferences() called.
|
||||
if (downloadedServicesCategory.getPreferenceCount() == 0) {
|
||||
@@ -398,8 +403,9 @@ public class AccessibilitySettings extends DashboardFragment {
|
||||
getPreferenceScreen().addPreference(downloadedServicesCategory);
|
||||
}
|
||||
|
||||
// Hide screen reader category if it is empty.
|
||||
// Hide category if it is empty.
|
||||
updatePreferenceCategoryVisibility(CATEGORY_SCREEN_READER);
|
||||
updatePreferenceCategoryVisibility(CATEGORY_SPEECH);
|
||||
}
|
||||
|
||||
private List<RestrictedPreference> getInstalledAccessibilityList(Context context) {
|
||||
|
||||
@@ -650,6 +650,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
new SubSettingLauncher(context)
|
||||
.setDestination(destination.getName())
|
||||
.setArguments(args)
|
||||
.setUserHandle(UserHandle.getUserHandleForUid(app.uid))
|
||||
.setSourceMetricsCategory(sourceMetricsCategory)
|
||||
.launch();
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import androidx.preference.PreferenceScreen;
|
||||
import com.android.settings.applications.AppStateBaseBridge;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settings.widget.AppCheckBoxPreference;
|
||||
import com.android.settingslib.applications.AppUtils;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||
@@ -126,9 +127,9 @@ public class BridgedAppsPreferenceController extends BasePreferenceController im
|
||||
final AppEntry entry = apps.get(i);
|
||||
final String prefKey = entry.info.packageName + "|" + entry.info.uid;
|
||||
appsKeySet.add(prefKey);
|
||||
CheckBoxPreference preference = mScreen.findPreference(prefKey);
|
||||
AppCheckBoxPreference preference = mScreen.findPreference(prefKey);
|
||||
if (preference == null) {
|
||||
preference = new CheckBoxPreference(mScreen.getContext());
|
||||
preference = new AppCheckBoxPreference(mScreen.getContext());
|
||||
preference.setIcon(AppUtils.getIcon(mContext, entry));
|
||||
preference.setTitle(entry.label);
|
||||
preference.setKey(prefKey);
|
||||
|
||||
@@ -49,10 +49,11 @@ public class BiometricsViewModelFactory implements ViewModelProvider.Factory {
|
||||
private static final String TAG = "BiometricsViewModelFact";
|
||||
|
||||
public static final CreationExtras.Key<ChallengeGenerator> CHALLENGE_GENERATOR_KEY =
|
||||
new CreationExtras.Key<>() {};
|
||||
new CreationExtras.Key<ChallengeGenerator>() {};
|
||||
public static final CreationExtras.Key<EnrollmentRequest> ENROLLMENT_REQUEST_KEY =
|
||||
new CreationExtras.Key<>() {};
|
||||
public static final CreationExtras.Key<Integer> USER_ID_KEY = new CreationExtras.Key<>() {};
|
||||
new CreationExtras.Key<EnrollmentRequest>() {};
|
||||
public static final CreationExtras.Key<Integer> USER_ID_KEY =
|
||||
new CreationExtras.Key<Integer>() {};
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
|
||||
@@ -71,6 +71,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImeAwareEditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TextView.OnEditorActionListener;
|
||||
@@ -101,7 +102,9 @@ import com.google.android.setupdesign.util.ThemeHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ChooseLockPassword extends SettingsActivity {
|
||||
private static final String TAG = "ChooseLockPassword";
|
||||
@@ -223,6 +226,8 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
private static final String KEY_CURRENT_CREDENTIAL = "current_credential";
|
||||
private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker";
|
||||
|
||||
private static final int MIN_AUTO_PIN_REQUIREMENT_LENGTH = 6;
|
||||
|
||||
private LockscreenCredential mCurrentCredential;
|
||||
private LockscreenCredential mChosenPassword;
|
||||
private boolean mRequestGatekeeperPassword;
|
||||
@@ -255,6 +260,9 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
protected FooterButton mSkipOrClearButton;
|
||||
private FooterButton mNextButton;
|
||||
private TextView mMessage;
|
||||
protected CheckBox mAutoPinConfirmOption;
|
||||
protected TextView mAutoConfirmSecurityMessage;
|
||||
protected boolean mIsAutoPinConfirmOptionSetManually;
|
||||
|
||||
private TextChangedHandler mTextChangedHandler;
|
||||
|
||||
@@ -515,6 +523,16 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
mPasswordEntry.requestFocus();
|
||||
mPasswordEntryInputDisabler = new TextViewInputDisabler(mPasswordEntry);
|
||||
|
||||
// Fetch the AutoPinConfirmOption
|
||||
mAutoPinConfirmOption = view.findViewById(R.id.auto_pin_confirm_enabler);
|
||||
mAutoConfirmSecurityMessage = view.findViewById(R.id.auto_pin_confirm_security_message);
|
||||
mIsAutoPinConfirmOptionSetManually = false;
|
||||
setOnAutoConfirmOptionClickListener();
|
||||
if (mAutoPinConfirmOption != null) {
|
||||
mAutoPinConfirmOption.setVisibility(View.GONE);
|
||||
mAutoPinConfirmOption.setChecked(false);
|
||||
}
|
||||
|
||||
final Activity activity = getActivity();
|
||||
|
||||
int currentType = mPasswordEntry.getInputType();
|
||||
@@ -808,10 +826,22 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
R.string.lockpassword_password_requires_nonnumerical));
|
||||
break;
|
||||
case TOO_SHORT:
|
||||
messages.add(StringUtil.getIcuPluralsString(getContext(), error.requirement,
|
||||
String message = StringUtil.getIcuPluralsString(getContext(),
|
||||
error.requirement,
|
||||
mIsAlphaMode
|
||||
? R.string.lockpassword_password_too_short
|
||||
: R.string.lockpassword_pin_too_short));
|
||||
: R.string.lockpassword_pin_too_short);
|
||||
if (mLockPatternUtils.isAutoPinConfirmFeatureAvailable()
|
||||
&& !mIsAlphaMode
|
||||
&& error.requirement < MIN_AUTO_PIN_REQUIREMENT_LENGTH) {
|
||||
Map<String, Object> arguments = new HashMap<>();
|
||||
arguments.put("count", error.requirement);
|
||||
arguments.put("minAutoConfirmLen", MIN_AUTO_PIN_REQUIREMENT_LENGTH);
|
||||
message = StringUtil.getIcuPluralsString(getContext(),
|
||||
arguments,
|
||||
R.string.lockpassword_pin_too_short_autoConfirm_extra_message);
|
||||
}
|
||||
messages.add(message);
|
||||
break;
|
||||
case TOO_SHORT_WHEN_ALL_NUMERIC:
|
||||
messages.add(
|
||||
@@ -864,6 +894,8 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
String[] messages = convertErrorCodeToMessages();
|
||||
// Update the fulfillment of requirements.
|
||||
mPasswordRequirementAdapter.setRequirements(messages);
|
||||
// set the visibility of pin_auto_confirm option accordingly
|
||||
setAutoPinConfirmOption(passwordCompliant, length);
|
||||
// Enable/Disable the next button accordingly.
|
||||
setNextEnabled(passwordCompliant);
|
||||
} else {
|
||||
@@ -896,6 +928,36 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
return visibleOrGone ? View.VISIBLE : View.GONE;
|
||||
}
|
||||
|
||||
private void setAutoPinConfirmOption(boolean enabled, int length) {
|
||||
if (!mLockPatternUtils.isAutoPinConfirmFeatureAvailable()
|
||||
|| mAutoPinConfirmOption == null) {
|
||||
return;
|
||||
}
|
||||
if (enabled && !mIsAlphaMode && isAutoPinConfirmPossible(length)) {
|
||||
mAutoPinConfirmOption.setVisibility(View.VISIBLE);
|
||||
mAutoConfirmSecurityMessage.setVisibility(View.VISIBLE);
|
||||
if (!mIsAutoPinConfirmOptionSetManually) {
|
||||
mAutoPinConfirmOption.setChecked(length == MIN_AUTO_PIN_REQUIREMENT_LENGTH);
|
||||
}
|
||||
} else {
|
||||
mAutoPinConfirmOption.setVisibility(View.GONE);
|
||||
mAutoConfirmSecurityMessage.setVisibility(View.GONE);
|
||||
mAutoPinConfirmOption.setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAutoPinConfirmPossible(int currentPinLength) {
|
||||
return currentPinLength >= MIN_AUTO_PIN_REQUIREMENT_LENGTH;
|
||||
}
|
||||
|
||||
private void setOnAutoConfirmOptionClickListener() {
|
||||
if (mAutoPinConfirmOption != null) {
|
||||
mAutoPinConfirmOption.setOnClickListener((v) -> {
|
||||
mIsAutoPinConfirmOptionSetManually = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void setHeaderText(String text) {
|
||||
// Only set the text if it is different than the existing one to avoid announcing again.
|
||||
if (!TextUtils.isEmpty(mLayout.getHeaderText())
|
||||
@@ -951,6 +1013,10 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
}
|
||||
mSaveAndFinishWorker.start(mLockPatternUtils, mRequestGatekeeperPassword,
|
||||
mChosenPassword, mCurrentCredential, mUserId);
|
||||
// update the pin_auto_confirm setting accordingly.
|
||||
mLockPatternUtils.setAutoPinConfirm(
|
||||
(mAutoPinConfirmOption != null && mAutoPinConfirmOption.isChecked()),
|
||||
mUserId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -170,6 +170,12 @@ public class SetupChooseLockPassword extends ChooseLockPassword {
|
||||
mOptionsButton.setVisibility(
|
||||
mUiStage == Stage.Introduction ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
// Visibility of auto pin confirm opt-in/out option should always be invisible.
|
||||
if (mAutoPinConfirmOption != null) {
|
||||
mAutoPinConfirmOption.setVisibility(View.GONE);
|
||||
mAutoConfirmSecurityMessage.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.security.screenlock;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.TwoStatePreference;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
/**
|
||||
* Preference controller for the pin_auto_confirm setting.
|
||||
*/
|
||||
public class AutoPinConfirmPreferenceController extends AbstractPreferenceController implements
|
||||
PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
|
||||
|
||||
private static final String PREF_KEY_PIN_AUTO_CONFIRM = "auto_pin_confirm";
|
||||
private static final long MIN_AUTO_PIN_REQUIREMENT_LENGTH = 6L;
|
||||
|
||||
private final int mUserId;
|
||||
private final LockPatternUtils mLockPatternUtils;
|
||||
|
||||
public AutoPinConfirmPreferenceController(Context context, int userId,
|
||||
LockPatternUtils lockPatternUtils) {
|
||||
super(context);
|
||||
mUserId = userId;
|
||||
mLockPatternUtils = lockPatternUtils;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
setPinAutoConfirmSettingState((boolean) newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
((TwoStatePreference) preference).setChecked(getPinAutoConfirmSettingState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mLockPatternUtils.isAutoPinConfirmFeatureAvailable() && isPinLock()
|
||||
&& isPinLengthEligibleForAutoConfirmation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return PREF_KEY_PIN_AUTO_CONFIRM;
|
||||
}
|
||||
|
||||
private boolean isPinLock() {
|
||||
return mLockPatternUtils.getCredentialTypeForUser(mUserId)
|
||||
== LockPatternUtils.CREDENTIAL_TYPE_PIN;
|
||||
}
|
||||
|
||||
private boolean isPinLengthEligibleForAutoConfirmation() {
|
||||
return mLockPatternUtils.getPinLength(mUserId) >= MIN_AUTO_PIN_REQUIREMENT_LENGTH;
|
||||
}
|
||||
|
||||
private boolean getPinAutoConfirmSettingState() {
|
||||
return mLockPatternUtils.isAutoPinConfirmEnabled(mUserId);
|
||||
}
|
||||
|
||||
private void setPinAutoConfirmSettingState(boolean state) {
|
||||
mLockPatternUtils.setAutoPinConfirm(state, mUserId);
|
||||
}
|
||||
}
|
||||
@@ -75,6 +75,8 @@ public class ScreenLockSettings extends DashboardFragment
|
||||
context, MY_USER_ID, lockPatternUtils));
|
||||
controllers.add(new LockAfterTimeoutPreferenceController(
|
||||
context, MY_USER_ID, lockPatternUtils));
|
||||
controllers.add(new AutoPinConfirmPreferenceController(
|
||||
context, MY_USER_ID, lockPatternUtils));
|
||||
controllers.add(new OwnerInfoPreferenceController(context, parent));
|
||||
return controllers;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,9 @@ import com.android.settings.fuelgauge.batteryusage.BatteryChartPreferenceControl
|
||||
import com.android.settings.fuelgauge.batteryusage.BatteryDiffEntry
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spaprivileged.framework.common.asUser
|
||||
import com.android.settingslib.spaprivileged.model.app.installed
|
||||
import com.android.settingslib.spaprivileged.model.app.userHandle
|
||||
import com.android.settingslib.spaprivileged.model.app.userId
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -63,6 +65,7 @@ fun AppBatteryPreference(app: ApplicationInfo) {
|
||||
}
|
||||
|
||||
private class AppBatteryPresenter(private val context: Context, private val app: ApplicationInfo) {
|
||||
private val userContext = context.asUser(app.userHandle)
|
||||
private var batteryDiffEntryState: LoadingState<BatteryDiffEntry?>
|
||||
by mutableStateOf(LoadingState.Loading)
|
||||
|
||||
@@ -84,7 +87,7 @@ private class AppBatteryPresenter(private val context: Context, private val app:
|
||||
|
||||
private suspend fun getBatteryDiffEntry(): BatteryDiffEntry? = withContext(Dispatchers.IO) {
|
||||
BatteryChartPreferenceController.getAppBatteryUsageData(
|
||||
context, app.packageName, app.userId
|
||||
userContext, app.packageName, app.userId
|
||||
).also {
|
||||
Log.d(TAG, "loadBatteryDiffEntries():\n$it")
|
||||
}
|
||||
@@ -141,6 +144,7 @@ private class AppBatteryPresenter(private val context: Context, private val app:
|
||||
.setDestination(AdvancedPowerUsageDetail::class.java.name)
|
||||
.setTitleRes(R.string.battery_details_title)
|
||||
.setArguments(args)
|
||||
.setUserHandle(app.userHandle)
|
||||
.setSourceMetricsCategory(AppInfoSettingsProvider.METRICS_CATEGORY)
|
||||
.launch()
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public final class ScreenOnTimeControllerTest {
|
||||
|
||||
ArgumentCaptor<CharSequence> argumentCaptor = ArgumentCaptor.forClass(CharSequence.class);
|
||||
verify(mScreenOnTimeTextPreference).setText(argumentCaptor.capture());
|
||||
assertThat(argumentCaptor.getValue().toString()).isEqualTo("18 days, 12 hr, 27 min");
|
||||
assertThat(argumentCaptor.getValue().toString()).isEqualTo("18 days 12 hr 27 min");
|
||||
verify(mScreenOnTimeTextPreference).setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,10 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
|
||||
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
|
||||
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
|
||||
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
|
||||
import static android.provider.DeviceConfig.NAMESPACE_AUTO_PIN_CONFIRMATION;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
|
||||
|
||||
import static com.android.internal.widget.LockPatternUtils.FLAG_ENABLE_AUTO_PIN_CONFIRMATION;
|
||||
import static com.android.internal.widget.LockPatternUtils.PASSWORD_TYPE_KEY;
|
||||
import static com.android.settings.password.ChooseLockGeneric.CONFIRM_CREDENTIALS;
|
||||
|
||||
@@ -43,15 +45,21 @@ import android.app.admin.PasswordMetrics;
|
||||
import android.app.admin.PasswordPolicy;
|
||||
import android.content.Intent;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.widget.LockscreenCredential;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.password.ChooseLockPassword.ChooseLockPasswordFragment;
|
||||
import com.android.settings.password.ChooseLockPassword.IntentBuilder;
|
||||
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
|
||||
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
|
||||
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
import com.android.settings.widget.ScrollToParentEditText;
|
||||
|
||||
import com.google.android.setupdesign.GlifLayout;
|
||||
|
||||
@@ -71,9 +79,9 @@ import org.robolectric.shadows.ShadowDrawable;
|
||||
ShadowLockPatternUtils.class,
|
||||
ShadowUtils.class,
|
||||
ShadowDevicePolicyManager.class,
|
||||
ShadowDeviceConfig.class,
|
||||
})
|
||||
public class ChooseLockPasswordTest {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
SettingsShadowResources.overrideResource(
|
||||
@@ -387,7 +395,9 @@ public class ChooseLockPasswordTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processAndValidatePasswordRequirements_defaultPinMinimumLength() {
|
||||
public void processAndValidatePasswordRequirements_autoPinDisabled_defaultPinMinimumLength() {
|
||||
DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
|
||||
/* value= */ "false", /* makeDefault= */ false);
|
||||
PasswordPolicy policy = new PasswordPolicy();
|
||||
policy.quality = PASSWORD_QUALITY_UNSPECIFIED;
|
||||
|
||||
@@ -399,6 +409,22 @@ public class ChooseLockPasswordTest {
|
||||
"PIN must be at least 4 digits");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processAndValidatePasswordRequirements_autoPinEnabled_defaultPinMinimumLength() {
|
||||
DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
|
||||
/* value= */ "true", /* makeDefault= */ false);
|
||||
PasswordPolicy policy = new PasswordPolicy();
|
||||
policy.quality = PASSWORD_QUALITY_UNSPECIFIED;
|
||||
|
||||
assertPasswordValidationResult(
|
||||
/* minMetrics */ policy.getMinMetrics(),
|
||||
/* minComplexity= */ PASSWORD_COMPLEXITY_NONE,
|
||||
/* passwordType= */ PASSWORD_QUALITY_NUMERIC,
|
||||
/* userEnteredPassword= */ LockscreenCredential.createPassword("11"),
|
||||
"PIN must be at least 4 digits"
|
||||
+ ", but a 6-digit PIN is recommended for added security");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processAndValidatePasswordRequirements_maximumLength() {
|
||||
PasswordPolicy policy = new PasswordPolicy();
|
||||
@@ -424,6 +450,123 @@ public class ChooseLockPasswordTest {
|
||||
"PIN must be at least 8 digits");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void autoPinConfirmOption_featureEnabledAndUntouchedByUser_changeStateAsPerRules() {
|
||||
DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
|
||||
/* value= */ "true", /* makeDefault= */ false);
|
||||
ChooseLockPassword passwordActivity = setupActivityWithPinTypeAndDefaultPolicy();
|
||||
|
||||
ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(passwordActivity);
|
||||
ScrollToParentEditText passwordEntry = passwordActivity.findViewById(R.id.password_entry);
|
||||
CheckBox pinAutoConfirmOption = passwordActivity
|
||||
.findViewById(R.id.auto_pin_confirm_enabler);
|
||||
TextView securityMessage =
|
||||
passwordActivity.findViewById(R.id.auto_pin_confirm_security_message);
|
||||
|
||||
passwordEntry.setText("1234");
|
||||
fragment.updateUi();
|
||||
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(securityMessage.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(pinAutoConfirmOption.isChecked()).isFalse();
|
||||
|
||||
passwordEntry.setText("123456");
|
||||
fragment.updateUi();
|
||||
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(securityMessage.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(pinAutoConfirmOption.isChecked()).isTrue();
|
||||
|
||||
passwordEntry.setText("12345678");
|
||||
fragment.updateUi();
|
||||
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(securityMessage.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(pinAutoConfirmOption.isChecked()).isFalse();
|
||||
|
||||
passwordEntry.setText("123456");
|
||||
fragment.updateUi();
|
||||
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(securityMessage.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(pinAutoConfirmOption.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void autoPinConfirmOption_featureEnabledAndModifiedByUser_shouldChangeStateAsPerRules() {
|
||||
DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
|
||||
/* value= */ "true", /* makeDefault= */ false);
|
||||
ChooseLockPassword passwordActivity = setupActivityWithPinTypeAndDefaultPolicy();
|
||||
|
||||
ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(passwordActivity);
|
||||
ScrollToParentEditText passwordEntry = passwordActivity.findViewById(R.id.password_entry);
|
||||
CheckBox pinAutoConfirmOption = passwordActivity
|
||||
.findViewById(R.id.auto_pin_confirm_enabler);
|
||||
TextView securityMessage =
|
||||
passwordActivity.findViewById(R.id.auto_pin_confirm_security_message);
|
||||
|
||||
passwordEntry.setText("123456");
|
||||
fragment.updateUi();
|
||||
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(securityMessage.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(pinAutoConfirmOption.isChecked()).isTrue();
|
||||
|
||||
pinAutoConfirmOption.performClick();
|
||||
assertThat(pinAutoConfirmOption.isChecked()).isFalse();
|
||||
|
||||
passwordEntry.setText("12345678");
|
||||
fragment.updateUi();
|
||||
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(securityMessage.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(pinAutoConfirmOption.isChecked()).isFalse();
|
||||
|
||||
passwordEntry.setText("123456");
|
||||
fragment.updateUi();
|
||||
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(securityMessage.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(pinAutoConfirmOption.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void autoPinConfirmOption_featureDisabled_shouldRemainInvisibleAndUnchecked() {
|
||||
DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
|
||||
/* value= */ "false", /* makeDefault= */ false);
|
||||
ChooseLockPassword passwordActivity = setupActivityWithPinTypeAndDefaultPolicy();
|
||||
|
||||
ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(passwordActivity);
|
||||
ScrollToParentEditText passwordEntry = passwordActivity.findViewById(R.id.password_entry);
|
||||
CheckBox pinAutoConfirmOption = passwordActivity
|
||||
.findViewById(R.id.auto_pin_confirm_enabler);
|
||||
TextView securityMessage =
|
||||
passwordActivity.findViewById(R.id.auto_pin_confirm_security_message);
|
||||
|
||||
passwordEntry.setText("1234");
|
||||
fragment.updateUi();
|
||||
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(securityMessage.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(pinAutoConfirmOption.isChecked()).isFalse();
|
||||
|
||||
passwordEntry.setText("123456");
|
||||
fragment.updateUi();
|
||||
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(securityMessage.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(pinAutoConfirmOption.isChecked()).isFalse();
|
||||
|
||||
passwordEntry.setText("12345678");
|
||||
fragment.updateUi();
|
||||
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(securityMessage.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(pinAutoConfirmOption.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
private ChooseLockPassword setupActivityWithPinTypeAndDefaultPolicy() {
|
||||
PasswordPolicy policy = new PasswordPolicy();
|
||||
policy.quality = PASSWORD_QUALITY_UNSPECIFIED;
|
||||
|
||||
return buildChooseLockPasswordActivity(
|
||||
new IntentBuilder(application)
|
||||
.setUserId(UserHandle.myUserId())
|
||||
.setPasswordType(PASSWORD_QUALITY_NUMERIC)
|
||||
.setPasswordRequirement(PASSWORD_COMPLEXITY_NONE, policy.getMinMetrics())
|
||||
.build());
|
||||
}
|
||||
|
||||
private ChooseLockPassword buildChooseLockPasswordActivity(Intent intent) {
|
||||
return Robolectric.buildActivity(ChooseLockPassword.class, intent).setup().get();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.security.screenlock;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AutoPinConfirmPreferenceControllerTest {
|
||||
private static final Integer TEST_USER_ID = 1;
|
||||
@Mock
|
||||
private LockPatternUtils mLockPatternUtils;
|
||||
private AutoPinConfirmPreferenceController mController;
|
||||
private SwitchPreference mPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
Context context = ApplicationProvider.getApplicationContext();
|
||||
mController =
|
||||
new AutoPinConfirmPreferenceController(context, TEST_USER_ID, mLockPatternUtils);
|
||||
mPreference = new SwitchPreference(context);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_featureEnabledAndLockSetToNone_shouldReturnFalse() {
|
||||
when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
|
||||
when(mLockPatternUtils.isAutoPinConfirmFeatureAvailable()).thenReturn(true);
|
||||
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_featureEnabledAndLockSetToPassword_shouldReturnFalse() {
|
||||
when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
|
||||
when(mLockPatternUtils.isAutoPinConfirmFeatureAvailable()).thenReturn(true);
|
||||
when(mLockPatternUtils.getCredentialTypeForUser(TEST_USER_ID))
|
||||
.thenReturn(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
|
||||
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_featureEnabledAndLockSetToPIN_lengthLessThanSix_shouldReturnFalse() {
|
||||
when(mLockPatternUtils.isAutoPinConfirmFeatureAvailable()).thenReturn(true);
|
||||
when(mLockPatternUtils.getCredentialTypeForUser(TEST_USER_ID))
|
||||
.thenReturn(LockPatternUtils.CREDENTIAL_TYPE_PIN);
|
||||
when(mLockPatternUtils.getPinLength(TEST_USER_ID)).thenReturn(5L);
|
||||
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_featureEnabledAndLockSetToPIN_lengthMoreThanEqSix_shouldReturnTrue() {
|
||||
when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
|
||||
when(mLockPatternUtils.isAutoPinConfirmFeatureAvailable()).thenReturn(true);
|
||||
when(mLockPatternUtils.getCredentialTypeForUser(TEST_USER_ID))
|
||||
.thenReturn(LockPatternUtils.CREDENTIAL_TYPE_PIN);
|
||||
when(mLockPatternUtils.getPinLength(TEST_USER_ID)).thenReturn(6L);
|
||||
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_featureDisabledAndLockSetToPIN_shouldReturnFalse() {
|
||||
when(mLockPatternUtils.isAutoPinConfirmFeatureAvailable()).thenReturn(false);
|
||||
when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
|
||||
when(mLockPatternUtils.getCredentialTypeForUser(TEST_USER_ID))
|
||||
.thenReturn(LockPatternUtils.CREDENTIAL_TYPE_PIN);
|
||||
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_ChangingSettingState_shouldSetPreferenceToAppropriateCheckedState() {
|
||||
when(mLockPatternUtils.isAutoPinConfirmFeatureAvailable()).thenReturn(true);
|
||||
// When auto_pin_confirm setting is disabled, switchPreference is unchecked
|
||||
when(mLockPatternUtils.isAutoPinConfirmEnabled(TEST_USER_ID)).thenReturn(false);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isChecked()).isFalse();
|
||||
|
||||
// When auto_pin_confirm setting is enabled, switchPreference is checked
|
||||
when(mLockPatternUtils.isAutoPinConfirmEnabled(TEST_USER_ID)).thenReturn(true);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_shouldUpdatePinAutoConfirmSetting() {
|
||||
when(mLockPatternUtils.isAutoPinConfirmFeatureAvailable()).thenReturn(true);
|
||||
mController.onPreferenceChange(mPreference, /* newValue= */ true);
|
||||
verify(mLockPatternUtils).setAutoPinConfirm(true, TEST_USER_ID);
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,9 @@ import com.android.settings.R
|
||||
import com.android.settings.fuelgauge.AdvancedPowerUsageDetail
|
||||
import com.android.settings.fuelgauge.batteryusage.BatteryChartPreferenceController
|
||||
import com.android.settings.fuelgauge.batteryusage.BatteryDiffEntry
|
||||
import com.android.settings.testutils.mockAsUser
|
||||
import com.android.settingslib.spaprivileged.framework.common.asUser
|
||||
import com.android.settingslib.spaprivileged.model.app.userHandle
|
||||
import com.android.settingslib.spaprivileged.model.app.userId
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
@@ -69,6 +72,7 @@ class AppBatteryPreferenceTest {
|
||||
.mockStatic(AdvancedPowerUsageDetail::class.java)
|
||||
.strictness(Strictness.LENIENT)
|
||||
.startMocking()
|
||||
context.mockAsUser()
|
||||
whenever(context.resources).thenReturn(resources)
|
||||
whenever(resources.getBoolean(R.bool.config_show_app_info_settings_battery))
|
||||
.thenReturn(true)
|
||||
|
||||
@@ -34,7 +34,6 @@ import android.os.Looper;
|
||||
import android.service.notification.NotificationListenerFilter;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import androidx.preference.CheckBoxPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
@@ -42,6 +41,7 @@ import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settings.widget.AppCheckBoxPreference;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -120,7 +120,7 @@ public class BridgedAppsPreferenceControllerTest {
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
|
||||
|
||||
CheckBoxPreference p = mock(CheckBoxPreference.class);
|
||||
AppCheckBoxPreference p = mock(AppCheckBoxPreference.class);
|
||||
when(p.getKey()).thenReturn("pkg|12300");
|
||||
mScreen.addPreference(p);
|
||||
|
||||
@@ -161,7 +161,7 @@ public class BridgedAppsPreferenceControllerTest {
|
||||
|
||||
mController.onRebuildComplete(entries);
|
||||
|
||||
CheckBoxPreference actual = mScreen.findPreference("pkg|12300");
|
||||
AppCheckBoxPreference actual = mScreen.findPreference("pkg|12300");
|
||||
|
||||
assertThat(actual.isChecked()).isTrue();
|
||||
assertThat(actual.getTitle()).isEqualTo("hi");
|
||||
@@ -178,7 +178,7 @@ public class BridgedAppsPreferenceControllerTest {
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
|
||||
|
||||
CheckBoxPreference pref = new CheckBoxPreference(mContext);
|
||||
AppCheckBoxPreference pref = new AppCheckBoxPreference(mContext);
|
||||
pref.setKey("pkg|567");
|
||||
|
||||
mController.onPreferenceChange(pref, false);
|
||||
@@ -204,7 +204,7 @@ public class BridgedAppsPreferenceControllerTest {
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
|
||||
|
||||
CheckBoxPreference pref = new CheckBoxPreference(mContext);
|
||||
AppCheckBoxPreference pref = new AppCheckBoxPreference(mContext);
|
||||
pref.setKey("pkg|567");
|
||||
|
||||
mController.onPreferenceChange(pref, true);
|
||||
|
||||
Reference in New Issue
Block a user