Snap for 7464903 from b8c610b188 to sc-release
Change-Id: I8f4cdce3aefe00c6eaa4f96f78f7df917fdec7d9
This commit is contained in:
152
res/layout-sw600dp/request_manage_credentials.xml
Normal file
152
res/layout-sw600dp/request_manage_credentials.xml
Normal file
@@ -0,0 +1,152 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2021 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.
|
||||
-->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="20dp"
|
||||
android:paddingStart="30dp"
|
||||
android:paddingEnd="30dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="2">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
style="@style/RequestManageCredentialsHeaderLandscape">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="none">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/credential_management_app_icon"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:contentDescription="@null" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/credential_management_app_title"
|
||||
style="@style/RequestManageCredentialsTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/credential_management_app_description"
|
||||
style="@style/RequestManageCredentialsDescription"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/request_manage_credentials_description" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="true">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/apps_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/extended_fab"
|
||||
style="@style/RequestManageCredentialsFab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/request_manage_credentials_more"
|
||||
android:theme="@style/Theme.CollapsingToolbar.Settings"
|
||||
app:backgroundTint="?android:attr/colorAccent"
|
||||
app:elevation="3dp"
|
||||
app:icon="@drawable/ic_arrow_downward"
|
||||
app:iconTint="?android:attr/textColorPrimary"
|
||||
app:layout_anchor="@id/apps_list"
|
||||
app:layout_anchorGravity="bottom|center" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Space
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/button_panel"
|
||||
style="@style/RequestManageCredentialsButtonPanel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center|bottom">
|
||||
|
||||
<Button
|
||||
android:id="@+id/dont_allow_button"
|
||||
style="@style/RequestManageCredentialsDontAllowButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/request_manage_credentials_dont_allow" />
|
||||
|
||||
<Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/allow_button"
|
||||
style="@style/RequestManageCredentialsAllowButton"
|
||||
android:theme="@style/RoundedCornerButtonTheme"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/request_manage_credentials_allow" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -20,7 +20,6 @@
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="60dp"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
|
||||
|
||||
<TextView
|
||||
@@ -29,11 +28,13 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:accessibilityLiveRegion="polite"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.TextView" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="12dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 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.
|
||||
-->
|
||||
|
||||
<!-- Layout used by BatterySaverScheduleSeekBarController for the seekbar widget. -->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="6dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:layout_marginStart="18dp"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
|
||||
android:textColor="?android:attr/textColorPrimary" />
|
||||
|
||||
<com.android.settings.widget.DefaultIndicatorSeekBar
|
||||
android:id="@*android:id/seekbar"
|
||||
style="@android:style/Widget.Material.SeekBar.Discrete"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="18dp"
|
||||
android:layout_marginEnd="9dp" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -25,28 +25,13 @@
|
||||
android:clickable="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/icon_frame"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="56dp"
|
||||
android:gravity="start|center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="4dp">
|
||||
<com.android.internal.widget.PreferenceImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"/>
|
||||
</LinearLayout>
|
||||
<include layout="@layout/settingslib_icon_frame"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp">
|
||||
android:paddingTop="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -57,7 +42,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@*android:style/TextAppearance.Material.Subhead"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal"/>
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
android:gravity="center_vertical"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="56dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
@@ -30,12 +30,11 @@
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@android:style/TextAppearance.Material.Subhead"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
android:textColor="?android:attr/textColorPrimary" />
|
||||
|
||||
<SeekBar
|
||||
@@ -43,21 +42,19 @@
|
||||
android:layout_below="@android:id/title"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginTop="-20dp"
|
||||
android:layout_marginBottom="-28dp"
|
||||
android:layout_height="48dp"
|
||||
android:paddingStart="0dp"
|
||||
android:paddingEnd="0dp"
|
||||
style="@android:style/Widget.Material.SeekBar.Discrete" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@*android:id/seekbar"
|
||||
android:paddingBottom="8dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/text1"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|top"
|
||||
@@ -66,7 +63,6 @@
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/text2"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|top"
|
||||
|
||||
@@ -25,28 +25,13 @@
|
||||
android:clickable="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/icon_frame"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="44dp"
|
||||
android:gravity="start|center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="4dp">
|
||||
<com.android.internal.widget.PreferenceImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"/>
|
||||
</LinearLayout>
|
||||
<include layout="@layout/settingslib_icon_frame"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp">
|
||||
android:paddingTop="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -56,9 +41,8 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:paddingStart="12dp"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.PreferenceTitle.SettingsLib"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal"/>
|
||||
<!-- Preference should place its actual preference widget here. -->
|
||||
@@ -79,7 +63,8 @@
|
||||
<SeekBar
|
||||
android:id="@*android:id/seekbar"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingStart="0dp"
|
||||
android:paddingEnd="0dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"/>
|
||||
|
||||
@@ -87,7 +72,6 @@
|
||||
android:id="@+id/suppression_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="12dp"
|
||||
android:layout_gravity="center_vertical|start"
|
||||
android:textAlignment="viewStart"
|
||||
android:singleLine="true"
|
||||
|
||||
@@ -15,49 +15,55 @@
|
||||
-->
|
||||
|
||||
<!-- Layout used by SeekBarPreference for the seekbar widget style. -->
|
||||
<RelativeLayout
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginBottom="6dp"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:minHeight="?android:attr/listPreferredItemHeightSmall"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:clickable="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal"
|
||||
android:paddingStart="56dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
|
||||
android:textColor="?android:attr/textColorPrimary" />
|
||||
<include layout="@layout/settingslib_icon_frame"/>
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignStart="@android:id/title"
|
||||
android:layout_below="@android:id/title"
|
||||
android:maxLines="4"
|
||||
android:paddingStart="56dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
|
||||
android:textColor="?android:attr/textColorSecondary" />
|
||||
|
||||
<com.android.settings.widget.DefaultIndicatorSeekBar
|
||||
android:id="@*android:id/seekbar"
|
||||
style="@android:style/Widget.Material.SeekBar.Discrete"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_below="@android:id/summary"
|
||||
android:paddingStart="56dp"
|
||||
android:paddingEnd="12dp" />
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="16dp">
|
||||
|
||||
</RelativeLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal"/>
|
||||
<!-- Preference should place its actual preference widget here. -->
|
||||
<LinearLayout
|
||||
android:id="@android:id/widget_frame"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="end|center_vertical"
|
||||
android:paddingStart="12dp"
|
||||
android:orientation="vertical"/>
|
||||
</LinearLayout>
|
||||
|
||||
<SeekBar
|
||||
android:id="@*android:id/seekbar"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:paddingStart="0dp"
|
||||
android:paddingEnd="0dp"
|
||||
android:layout_height="48dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
0
res/raw/lottie_adaptive_battery.json
Normal file
0
res/raw/lottie_adaptive_battery.json
Normal file
File diff suppressed because one or more lines are too long
0
res/raw/lottie_flip_camera_for_selfie.json
Normal file
0
res/raw/lottie_flip_camera_for_selfie.json
Normal file
0
res/raw/lottie_lift_to_check_phone.json
Normal file
0
res/raw/lottie_lift_to_check_phone.json
Normal file
0
res/raw/lottie_one_hand_mode.json
Normal file
0
res/raw/lottie_one_hand_mode.json
Normal file
0
res/raw/lottie_prevent_ringing.json
Normal file
0
res/raw/lottie_prevent_ringing.json
Normal file
0
res/raw/lottie_quick_open_camera.json
Normal file
0
res/raw/lottie_quick_open_camera.json
Normal file
0
res/raw/lottie_swipe_fingerprint.json
Normal file
0
res/raw/lottie_swipe_fingerprint.json
Normal file
0
res/raw/lottie_tap_to_check_phone.json
Normal file
0
res/raw/lottie_tap_to_check_phone.json
Normal file
@@ -46,6 +46,7 @@
|
||||
|
||||
<style name="SettingsSeekBarPreference" parent="@style/Preference.Material">
|
||||
<item name="android:layout">@layout/preference_widget_seekbar_settings</item>
|
||||
<item name="iconSpaceReserved">@bool/settingslib_config_icon_space_reserved</item>
|
||||
</style>
|
||||
|
||||
<style name="SyncSwitchPreference" parent="@style/SettingsSwitchPreference.SettingsLib">
|
||||
|
||||
@@ -28,6 +28,14 @@
|
||||
settings:searchable="false"
|
||||
settings:controller="com.android.settings.gestures.SystemNavigationPreferenceController"/>
|
||||
|
||||
<Preference
|
||||
android:fragment="com.android.settings.gestures.OneHandedSettings"
|
||||
android:key="gesture_system_navigation_one_handed_accessibility"
|
||||
android:persistent="false"
|
||||
android:title="@string/one_handed_title"
|
||||
settings:searchable="false"
|
||||
settings:controller="com.android.settings.gestures.OneHandedEnablePreferenceController"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="toggle_power_button_ends_call_preference"
|
||||
android:persistent="false"
|
||||
@@ -39,4 +47,4 @@
|
||||
android:persistent="false"
|
||||
android:title="@string/accelerometer_title"
|
||||
settings:controller="com.android.settings.accessibility.LockScreenRotationPreferenceController"/>
|
||||
</PreferenceScreen>
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
<com.android.settingslib.widget.IllustrationPreference
|
||||
android:key="bubbles_illustration"
|
||||
settings:searchable="false"
|
||||
app:lottie_rawRes="@raw/lottie_bubbles"/>
|
||||
|
||||
<com.android.settingslib.widget.MainSwitchPreference
|
||||
|
||||
@@ -17,21 +17,20 @@
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/double_tap_power_for_camera_title">
|
||||
|
||||
<com.android.settings.widget.VideoPreference
|
||||
<com.android.settingslib.widget.IllustrationPreference
|
||||
android:key="gesture_double_tap_power_video"
|
||||
app:animation="@raw/gesture_double_tap"
|
||||
app:preview="@drawable/gesture_double_tap"
|
||||
app:controller="com.android.settings.widget.VideoPreferenceController" />
|
||||
settings:searchable="false"
|
||||
app:lottie_rawRes="@raw/lottie_quick_open_camera"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="gesture_double_tap_power"
|
||||
android:title="@string/double_tap_power_for_camera_title"
|
||||
android:summary="@string/double_tap_power_for_camera_summary"
|
||||
app:keywords="@string/keywords_gesture"
|
||||
app:controller="com.android.settings.gestures.DoubleTapPowerPreferenceController"
|
||||
app:allowDividerAbove="true" />
|
||||
app:controller="com.android.settings.gestures.DoubleTapPowerPreferenceController"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -17,21 +17,20 @@
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/double_twist_for_camera_mode_title">
|
||||
|
||||
<com.android.settings.widget.VideoPreference
|
||||
<com.android.settingslib.widget.IllustrationPreference
|
||||
android:key="gesture_double_twist_video"
|
||||
app:animation="@raw/gesture_twist"
|
||||
app:preview="@drawable/gesture_twist"
|
||||
app:controller="com.android.settings.widget.VideoPreferenceController" />
|
||||
settings:searchable="false"
|
||||
app:lottie_rawRes="@raw/lottie_flip_camera_for_selfie"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="gesture_double_twist"
|
||||
android:title="@string/double_twist_for_camera_mode_title"
|
||||
android:summary="@string/double_twist_for_camera_mode_summary"
|
||||
app:keywords="@string/keywords_gesture"
|
||||
app:controller="com.android.settings.gestures.DoubleTwistPreferenceController"
|
||||
app:allowDividerAbove="true" />
|
||||
app:controller="com.android.settings.gestures.DoubleTwistPreferenceController" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -18,16 +18,14 @@
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:persistent="false"
|
||||
android:title="@string/one_handed_title">
|
||||
|
||||
<com.android.settingslib.widget.LayoutPreference
|
||||
<com.android.settingslib.widget.IllustrationPreference
|
||||
android:key="one_handed_header"
|
||||
android:layout="@layout/one_handed_header"
|
||||
android:persistent="false"
|
||||
android:selectable="false"
|
||||
settings:allowDividerBelow="false"
|
||||
settings:searchable="false"/>
|
||||
settings:searchable="false"
|
||||
app:lottie_rawRes="@raw/lottie_one_hand_mode"/>
|
||||
|
||||
<com.android.settingslib.widget.MainSwitchPreference
|
||||
android:key="gesture_one_handed_mode_enabled_main_switch"
|
||||
|
||||
@@ -17,21 +17,21 @@
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/ambient_display_pickup_title">
|
||||
|
||||
<com.android.settings.widget.VideoPreference
|
||||
<com.android.settingslib.widget.IllustrationPreference
|
||||
android:key="gesture_pick_up_video"
|
||||
app:animation="@raw/gesture_ambient_lift"
|
||||
app:preview="@drawable/gesture_ambient_lift"
|
||||
app:controller="com.android.settings.widget.VideoPreferenceController" />
|
||||
settings:searchable="false"
|
||||
app:lottie_rawRes="@raw/lottie_lift_to_check_phone"/>
|
||||
|
||||
|
||||
<SwitchPreference
|
||||
android:key="gesture_pick_up"
|
||||
android:title="@string/ambient_display_pickup_title"
|
||||
android:summary="@string/ambient_display_pickup_summary"
|
||||
app:keywords="@string/keywords_gesture"
|
||||
app:controller="com.android.settings.gestures.PickupGesturePreferenceController"
|
||||
app:allowDividerAbove="true" />
|
||||
app:controller="com.android.settings.gestures.PickupGesturePreferenceController" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/gesture_prevent_ringing_screen_title">
|
||||
|
||||
<com.android.settings.widget.VideoPreference
|
||||
<com.android.settingslib.widget.IllustrationPreference
|
||||
android:key="gesture_prevent_ringing_video"
|
||||
app:animation="@raw/gesture_prevent_ringing"
|
||||
app:preview="@drawable/gesture_prevent_ringing"
|
||||
app:controller="com.android.settings.widget.VideoPreferenceController" />
|
||||
settings:searchable="false"
|
||||
app:lottie_rawRes="@raw/lottie_prevent_ringing"/>
|
||||
|
||||
<com.android.settingslib.widget.MainSwitchPreference
|
||||
android:key="gesture_prevent_ringing_switch" />
|
||||
|
||||
@@ -43,19 +43,19 @@
|
||||
android:summary="@string/summary_placeholder"
|
||||
settings:keywords="@string/keywords_lockscreen" />
|
||||
|
||||
<Preference
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
android:key="fingerprint_settings"
|
||||
android:title="@string/security_settings_fingerprint_preference_title"
|
||||
android:summary="@string/summary_placeholder"
|
||||
settings:keywords="@string/keywords_fingerprint_settings" />
|
||||
|
||||
<Preference
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
android:key="face_settings"
|
||||
android:title="@string/security_settings_face_preference_title"
|
||||
android:summary="@string/summary_placeholder"
|
||||
settings:keywords="@string/keywords_face_settings" />
|
||||
|
||||
<Preference
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
android:key="biometric_settings"
|
||||
android:title="@string/security_settings_biometric_preference_title"
|
||||
android:summary="@string/summary_placeholder"
|
||||
|
||||
@@ -16,22 +16,21 @@
|
||||
-->
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:key="gesture_swipe_down_fingerprint_screen"
|
||||
android:title="@string/fingerprint_gesture_screen_title">
|
||||
|
||||
<com.android.settings.widget.VideoPreference
|
||||
<com.android.settingslib.widget.IllustrationPreference
|
||||
android:key="gesture_swipe_down_fingerprint_video"
|
||||
app:animation="@raw/gesture_fingerprint_swipe"
|
||||
app:preview="@drawable/gesture_fingerprint_swipe"
|
||||
app:controller="com.android.settings.widget.VideoPreferenceController" />
|
||||
settings:searchable="false"
|
||||
app:lottie_rawRes="@raw/lottie_swipe_fingerprint"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="gesture_swipe_down_fingerprint"
|
||||
android:title="@string/fingerprint_swipe_for_notifications_title"
|
||||
android:summary="@string/fingerprint_swipe_for_notifications_summary"
|
||||
app:keywords="@string/keywords_gesture"
|
||||
app:controller="com.android.settings.gestures.SwipeToNotificationPreferenceController"
|
||||
app:allowDividerAbove="true" />
|
||||
app:controller="com.android.settings.gestures.SwipeToNotificationPreferenceController" />
|
||||
|
||||
</PreferenceScreen>
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -17,21 +17,20 @@
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/ambient_display_tap_screen_title">
|
||||
|
||||
<com.android.settings.widget.VideoPreference
|
||||
<com.android.settingslib.widget.IllustrationPreference
|
||||
android:key="gesture_tap_screen_video"
|
||||
app:animation="@raw/gesture_ambient_tap_screen"
|
||||
app:preview="@drawable/gesture_ambient_tap_screen"
|
||||
app:controller="com.android.settings.widget.VideoPreferenceController" />
|
||||
settings:searchable="false"
|
||||
app:lottie_rawRes="@raw/lottie_tap_to_check_phone"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="gesture_tap"
|
||||
android:title="@string/ambient_display_tap_screen_title"
|
||||
android:summary="@string/ambient_display_tap_screen_summary"
|
||||
app:keywords="@string/keywords_gesture"
|
||||
app:controller="com.android.settings.gestures.TapScreenGesturePreferenceController"
|
||||
app:allowDividerAbove="true" />
|
||||
app:controller="com.android.settings.gestures.TapScreenGesturePreferenceController" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -309,11 +309,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
return controllers;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isParalleledControllers() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void addToCallbackList(Callback callback) {
|
||||
if (callback != null) {
|
||||
mCallbacks.add(callback);
|
||||
|
||||
@@ -258,21 +258,6 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
}
|
||||
|
||||
private void setupForMultiBiometricEnroll() {
|
||||
final FingerprintManager fingerprintManager = getSystemService(FingerprintManager.class);
|
||||
final FaceManager faceManager = getSystemService(FaceManager.class);
|
||||
final List<FingerprintSensorPropertiesInternal> fpProperties =
|
||||
fingerprintManager.getSensorPropertiesInternal();
|
||||
final List<FaceSensorPropertiesInternal> faceProperties =
|
||||
faceManager.getSensorPropertiesInternal();
|
||||
|
||||
// This would need to be updated for devices with multiple sensors of the same modality
|
||||
mIsFaceEnrollable = !faceProperties.isEmpty() &&
|
||||
faceManager.getEnrolledFaces(mUserId).size()
|
||||
< faceProperties.get(0).maxEnrollmentsPerUser;
|
||||
mIsFingerprintEnrollable = !fpProperties.isEmpty() &&
|
||||
fingerprintManager.getEnrolledFingerprints(mUserId).size()
|
||||
< fpProperties.get(0).maxEnrollmentsPerUser;
|
||||
|
||||
if (!mConfirmingCredentials) {
|
||||
mConfirmingCredentials = true;
|
||||
if (!userHasPassword(mUserId)) {
|
||||
@@ -284,7 +269,33 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
}
|
||||
|
||||
private void startMultiBiometricEnroll(Intent data) {
|
||||
final boolean isSetupWizard = WizardManagerHelper.isAnySetupWizard(getIntent());
|
||||
final FingerprintManager fingerprintManager = getSystemService(FingerprintManager.class);
|
||||
final FaceManager faceManager = getSystemService(FaceManager.class);
|
||||
final List<FingerprintSensorPropertiesInternal> fpProperties =
|
||||
fingerprintManager.getSensorPropertiesInternal();
|
||||
final List<FaceSensorPropertiesInternal> faceProperties =
|
||||
faceManager.getSensorPropertiesInternal();
|
||||
|
||||
mGkPwHandle = BiometricUtils.getGatekeeperPasswordHandle(data);
|
||||
|
||||
if (isSetupWizard) {
|
||||
// This would need to be updated for devices with multiple sensors of the same modality
|
||||
mIsFaceEnrollable = !faceProperties.isEmpty()
|
||||
&& faceManager.getEnrolledFaces(mUserId).size() == 0;
|
||||
mIsFingerprintEnrollable = !fpProperties.isEmpty()
|
||||
&& fingerprintManager.getEnrolledFingerprints(mUserId).size() == 0;
|
||||
} else {
|
||||
// This would need to be updated for devices with multiple sensors of the same modality
|
||||
mIsFaceEnrollable = !faceProperties.isEmpty()
|
||||
&& faceManager.getEnrolledFaces(mUserId).size()
|
||||
< faceProperties.get(0).maxEnrollmentsPerUser;
|
||||
mIsFingerprintEnrollable = !fpProperties.isEmpty()
|
||||
&& fingerprintManager.getEnrolledFingerprints(mUserId).size()
|
||||
< fpProperties.get(0).maxEnrollmentsPerUser;
|
||||
|
||||
}
|
||||
|
||||
mMultiBiometricEnrollHelper = new MultiBiometricEnrollHelper(this, mUserId,
|
||||
mIsFaceEnrollable, mIsFingerprintEnrollable, mGkPwHandle);
|
||||
mMultiBiometricEnrollHelper.startNextStep();
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.biometrics;
|
||||
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.ParentalControlsUtilsInternal;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
|
||||
/**
|
||||
* Utilities for things at the cross-section of biometrics and parental controls. For example,
|
||||
* determining if parental consent is required, determining which strings should be shown, etc.
|
||||
*/
|
||||
public class ParentalControlsUtils {
|
||||
|
||||
private static final String TAG = "ParentalControlsUtils";
|
||||
|
||||
/**
|
||||
* Public version that enables test paths, see
|
||||
* {@link android.hardware.biometrics.ParentalControlsUtilsInternal#isTestModeEnabled(Context)}
|
||||
* @return non-null EnforcedAdmin if parental consent is required
|
||||
*/
|
||||
public static RestrictedLockUtils.EnforcedAdmin parentConsentRequired(@NonNull Context context,
|
||||
@BiometricAuthenticator.Modality int modality) {
|
||||
|
||||
final UserHandle userHandle = new UserHandle(UserHandle.myUserId());
|
||||
if (ParentalControlsUtilsInternal.isTestModeEnabled(context)) {
|
||||
Log.d(TAG, "Requiring consent for test flow");
|
||||
return new RestrictedLockUtils.EnforcedAdmin(null /* ComponentName */, userHandle);
|
||||
}
|
||||
|
||||
final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
|
||||
return parentConsentRequiredInternal(dpm, modality, userHandle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal testable version.
|
||||
* @return non-null EnforcedAdmin if parental consent is required
|
||||
*/
|
||||
@Nullable
|
||||
@VisibleForTesting
|
||||
static RestrictedLockUtils.EnforcedAdmin parentConsentRequiredInternal(
|
||||
@NonNull DevicePolicyManager dpm, @BiometricAuthenticator.Modality int modality,
|
||||
@NonNull UserHandle userHandle) {
|
||||
if (ParentalControlsUtilsInternal.parentConsentRequired(dpm, modality,
|
||||
userHandle)) {
|
||||
final ComponentName cn =
|
||||
ParentalControlsUtilsInternal.getSupervisionComponentName(dpm, userHandle);
|
||||
return new RestrictedLockUtils.EnforcedAdmin(cn, userHandle);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,15 +16,22 @@
|
||||
package com.android.settings.biometrics.combination;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Settings;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.biometrics.BiometricStatusPreferenceController;
|
||||
import com.android.settings.biometrics.ParentalControlsUtils;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
|
||||
/**
|
||||
* Preference controller for biometrics settings page controlling the ability to unlock the phone
|
||||
@@ -38,6 +45,8 @@ public class CombinedBiometricStatusPreferenceController extends
|
||||
FingerprintManager mFingerprintManager;
|
||||
@Nullable
|
||||
FaceManager mFaceManager;
|
||||
@VisibleForTesting
|
||||
RestrictedPreference mPreference;
|
||||
|
||||
public CombinedBiometricStatusPreferenceController(Context context) {
|
||||
this(context, KEY_BIOMETRIC_SETTINGS);
|
||||
@@ -49,6 +58,12 @@ public class CombinedBiometricStatusPreferenceController extends
|
||||
mFaceManager = Utils.getFaceManagerOrNull(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = screen.findPreference(KEY_BIOMETRIC_SETTINGS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isDeviceSupported() {
|
||||
return Utils.hasFingerprintHardware(mContext) && Utils.hasFaceHardware(mContext);
|
||||
@@ -59,6 +74,24 @@ public class CombinedBiometricStatusPreferenceController extends
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
// This controller currently is shown if fingerprint&face exist on the device. If this
|
||||
// changes in the future, the modalities passed into the below will need to be updated.
|
||||
final RestrictedLockUtils.EnforcedAdmin admin = ParentalControlsUtils
|
||||
.parentConsentRequired(mContext,
|
||||
BiometricAuthenticator.TYPE_FACE | BiometricAuthenticator.TYPE_FINGERPRINT);
|
||||
updateStateInternal(admin);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void updateStateInternal(@Nullable RestrictedLockUtils.EnforcedAdmin enforcedAdmin) {
|
||||
if (enforcedAdmin != null && mPreference != null) {
|
||||
mPreference.setDisabledByAdmin(enforcedAdmin);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSummaryTextEnrolled() {
|
||||
// Note that this is currently never called (see the super class)
|
||||
|
||||
@@ -17,18 +17,29 @@
|
||||
package com.android.settings.biometrics.face;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.face.FaceManager;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Settings;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.biometrics.BiometricStatusPreferenceController;
|
||||
import com.android.settings.biometrics.ParentalControlsUtils;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
|
||||
public class FaceStatusPreferenceController extends BiometricStatusPreferenceController {
|
||||
|
||||
public static final String KEY_FACE_SETTINGS = "face_settings";
|
||||
|
||||
protected final FaceManager mFaceManager;
|
||||
@VisibleForTesting
|
||||
RestrictedPreference mPreference;
|
||||
|
||||
public FaceStatusPreferenceController(Context context) {
|
||||
this(context, KEY_FACE_SETTINGS);
|
||||
@@ -39,6 +50,12 @@ public class FaceStatusPreferenceController extends BiometricStatusPreferenceCon
|
||||
mFaceManager = Utils.getFaceManagerOrNull(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = screen.findPreference(KEY_FACE_SETTINGS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isDeviceSupported() {
|
||||
return !Utils.isMultipleBiometricsSupported(mContext) && Utils.hasFaceHardware(mContext);
|
||||
@@ -49,6 +66,21 @@ public class FaceStatusPreferenceController extends BiometricStatusPreferenceCon
|
||||
return mFaceManager.hasEnrolledTemplates(getUserId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
final RestrictedLockUtils.EnforcedAdmin admin = ParentalControlsUtils
|
||||
.parentConsentRequired(mContext, BiometricAuthenticator.TYPE_FACE);
|
||||
updateStateInternal(admin);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void updateStateInternal(@Nullable RestrictedLockUtils.EnforcedAdmin enforcedAdmin) {
|
||||
if (enforcedAdmin != null && mPreference != null) {
|
||||
mPreference.setDisabledByAdmin(enforcedAdmin);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSummaryTextEnrolled() {
|
||||
return mContext.getResources()
|
||||
|
||||
@@ -17,17 +17,28 @@
|
||||
package com.android.settings.biometrics.fingerprint;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.biometrics.BiometricStatusPreferenceController;
|
||||
import com.android.settings.biometrics.ParentalControlsUtils;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
|
||||
public class FingerprintStatusPreferenceController extends BiometricStatusPreferenceController {
|
||||
|
||||
private static final String KEY_FINGERPRINT_SETTINGS = "fingerprint_settings";
|
||||
|
||||
protected final FingerprintManager mFingerprintManager;
|
||||
@VisibleForTesting
|
||||
RestrictedPreference mPreference;
|
||||
|
||||
public FingerprintStatusPreferenceController(Context context) {
|
||||
this(context, KEY_FINGERPRINT_SETTINGS);
|
||||
@@ -38,6 +49,12 @@ public class FingerprintStatusPreferenceController extends BiometricStatusPrefer
|
||||
mFingerprintManager = Utils.getFingerprintManagerOrNull(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = screen.findPreference(KEY_FINGERPRINT_SETTINGS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isDeviceSupported() {
|
||||
return !Utils.isMultipleBiometricsSupported(mContext)
|
||||
@@ -49,6 +66,21 @@ public class FingerprintStatusPreferenceController extends BiometricStatusPrefer
|
||||
return mFingerprintManager.hasEnrolledFingerprints(getUserId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
final RestrictedLockUtils.EnforcedAdmin admin = ParentalControlsUtils
|
||||
.parentConsentRequired(mContext, BiometricAuthenticator.TYPE_FINGERPRINT);
|
||||
updateStateInternal(admin);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void updateStateInternal(@Nullable RestrictedLockUtils.EnforcedAdmin enforcedAdmin) {
|
||||
if (enforcedAdmin != null && mPreference != null) {
|
||||
mPreference.setDisabledByAdmin(enforcedAdmin);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSummaryTextEnrolled() {
|
||||
final int numEnrolled = mFingerprintManager.getEnrolledFingerprints(getUserId()).size();
|
||||
|
||||
@@ -49,11 +49,6 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isParalleledControllers() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHelpResource() {
|
||||
return R.string.help_url_connected_devices;
|
||||
|
||||
@@ -22,7 +22,6 @@ import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.CallSuper;
|
||||
@@ -36,7 +35,6 @@ import androidx.preference.SwitchPreference;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.core.PreferenceControllerListHelper;
|
||||
import com.android.settings.core.SettingsBaseActivity;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
@@ -360,11 +358,6 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
|
||||
* Update state of each preference managed by PreferenceController.
|
||||
*/
|
||||
protected void updatePreferenceStates() {
|
||||
if (isParalleledControllers() && FeatureFlagUtils.isEnabled(getContext(),
|
||||
FeatureFlags.CONTROLLER_ENHANCEMENT)) {
|
||||
updatePreferenceStatesInParallel();
|
||||
return;
|
||||
}
|
||||
final PreferenceScreen screen = getPreferenceScreen();
|
||||
Collection<List<AbstractPreferenceController>> controllerLists =
|
||||
mPreferenceControllers.values();
|
||||
@@ -396,6 +389,8 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
|
||||
* Use parallel method to update state of each preference managed by PreferenceController.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
// To use this parallel approach will cause the side effect of the UI flicker. Such as
|
||||
// the thumb sliding of the toggle button.
|
||||
void updatePreferenceStatesInParallel() {
|
||||
final PreferenceScreen screen = getPreferenceScreen();
|
||||
final Collection<List<AbstractPreferenceController>> controllerLists =
|
||||
|
||||
@@ -402,11 +402,6 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
return mPreferenceControllers;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isParalleledControllers() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void registerReceivers() {
|
||||
LocalBroadcastManager.getInstance(getContext())
|
||||
.registerReceiver(mEnableAdbReceiver, new IntentFilter(
|
||||
|
||||
@@ -90,6 +90,7 @@ public class AdaptiveSleepPreferenceController {
|
||||
if (enforcedAdmin != null) {
|
||||
mPreference.setDisabledByAdmin(enforcedAdmin);
|
||||
} else {
|
||||
mPreference.setChecked(isChecked());
|
||||
mPreference.setEnabled(hasSufficientPermission(mPackageManager) && !isCameraLocked()
|
||||
&& !isPowerSaveMode());
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
mAdaptiveSleepBatterySaverPreferenceController.updateVisibility();
|
||||
mAdaptiveSleepController.updatePreference();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -55,7 +55,8 @@ public class BatterySaverScheduleSeekBarController implements
|
||||
public BatterySaverScheduleSeekBarController(Context context) {
|
||||
mContext = context;
|
||||
mSeekBarPreference = new SeekBarPreference(context);
|
||||
mSeekBarPreference.setLayoutResource(R.layout.battery_saver_schedule_percentage_seekbar);
|
||||
mSeekBarPreference.setLayoutResource(R.layout.preference_widget_seekbar_settings);
|
||||
mSeekBarPreference.setIconSpaceReserved(false);
|
||||
mSeekBarPreference.setOnPreferenceChangeListener(this);
|
||||
mSeekBarPreference.setContinuousUpdates(true);
|
||||
mSeekBarPreference.setMax(MAX_SEEKBAR_VALUE);
|
||||
|
||||
@@ -42,7 +42,10 @@ public abstract class GesturePreferenceController extends TogglePreferenceContro
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
if (isAvailable()) {
|
||||
mVideoPreference = screen.findPreference(getVideoPrefKey());
|
||||
final Preference pref = screen.findPreference(getVideoPrefKey());
|
||||
if (pref instanceof VideoPreference) {
|
||||
mVideoPreference = screen.findPreference(getVideoPrefKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ import androidx.preference.PreferenceScreen;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.widget.VideoPreference;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
@@ -52,8 +51,6 @@ public class PreventRingingGesturePreferenceController extends AbstractPreferenc
|
||||
private final String KEY = "gesture_prevent_ringing_category";
|
||||
private final Context mContext;
|
||||
|
||||
private VideoPreference mVideoPreference;
|
||||
|
||||
@VisibleForTesting
|
||||
PreferenceCategory mPreferenceCategory;
|
||||
@VisibleForTesting
|
||||
@@ -85,8 +82,6 @@ public class PreventRingingGesturePreferenceController extends AbstractPreferenc
|
||||
if (mPreferenceCategory != null) {
|
||||
mSettingObserver = new SettingObserver(mPreferenceCategory);
|
||||
}
|
||||
|
||||
mVideoPreference = screen.findPreference(getVideoPrefKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -142,10 +137,6 @@ public class PreventRingingGesturePreferenceController extends AbstractPreferenc
|
||||
mSettingObserver.register(mContext.getContentResolver());
|
||||
mSettingObserver.onChange(false, null);
|
||||
}
|
||||
|
||||
if (mVideoPreference != null) {
|
||||
mVideoPreference.onViewVisible();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -153,10 +144,6 @@ public class PreventRingingGesturePreferenceController extends AbstractPreferenc
|
||||
if (mSettingObserver != null) {
|
||||
mSettingObserver.unregister(mContext.getContentResolver());
|
||||
}
|
||||
|
||||
if (mVideoPreference != null) {
|
||||
mVideoPreference.onViewInvisible();
|
||||
}
|
||||
}
|
||||
|
||||
private int keyToSetting(String key) {
|
||||
|
||||
@@ -95,11 +95,6 @@ public class NetworkDashboardFragment extends DashboardFragment implements
|
||||
this /* fragment */, this /* mobilePlanHost */);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isParalleledControllers() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
|
||||
Lifecycle lifecycle, MetricsFeatureProvider metricsFeatureProvider, Fragment fragment,
|
||||
MobilePlanPreferenceHost mobilePlanHost) {
|
||||
|
||||
@@ -54,6 +54,7 @@ import java.util.stream.Stream;
|
||||
|
||||
public class SubscriptionUtil {
|
||||
private static final String TAG = "SubscriptionUtil";
|
||||
private static final String PROFILE_GENERIC_DISPLAY_NAME = "CARD";
|
||||
private static List<SubscriptionInfo> sAvailableResultsForTesting;
|
||||
private static List<SubscriptionInfo> sActiveResultsForTesting;
|
||||
|
||||
@@ -257,7 +258,10 @@ public class SubscriptionUtil {
|
||||
.map(i -> {
|
||||
DisplayInfo info = new DisplayInfo();
|
||||
info.subscriptionInfo = i;
|
||||
info.originalName = i.getDisplayName().toString().trim();
|
||||
String displayName = i.getDisplayName().toString();
|
||||
info.originalName = TextUtils.equals(displayName, PROFILE_GENERIC_DISPLAY_NAME)
|
||||
? context.getResources().getString(R.string.sim_card)
|
||||
: displayName.trim();
|
||||
return info;
|
||||
});
|
||||
|
||||
|
||||
@@ -96,11 +96,6 @@ public class ConfigureNotificationSettings extends DashboardFragment implements
|
||||
mNotificationAssistantPreferenceController.setBackend(new NotificationBackend());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isParalleledControllers() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
|
||||
Application app, Fragment host) {
|
||||
final List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
|
||||
@@ -84,12 +84,13 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve
|
||||
}
|
||||
|
||||
if (TextUtils.equals(intent.getAction(), WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
|
||||
showProgressBar();
|
||||
updateProgressBar();
|
||||
updatePanelTitle();
|
||||
return;
|
||||
}
|
||||
|
||||
if (TextUtils.equals(intent.getAction(), WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
|
||||
updateProgressBar();
|
||||
updatePanelTitle();
|
||||
}
|
||||
}
|
||||
@@ -110,13 +111,40 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve
|
||||
private int mDefaultDataSubid = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
|
||||
// Wi-Fi scanning progress bar
|
||||
protected HandlerInjector mHandlerInjector;
|
||||
protected boolean mIsProgressBarVisible;
|
||||
protected final Runnable mHideProgressBarRunnable = () -> {
|
||||
protected boolean mIsScanningSubTitleShownOnce;
|
||||
protected Runnable mHideProgressBarRunnable = () -> {
|
||||
setProgressBarVisible(false);
|
||||
};
|
||||
protected Runnable mHideScanningSubTitleRunnable = () -> {
|
||||
mIsScanningSubTitleShownOnce = true;
|
||||
updatePanelTitle();
|
||||
};
|
||||
|
||||
/**
|
||||
* Wrapper for testing compatibility.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static class HandlerInjector {
|
||||
protected final Handler mHandler;
|
||||
|
||||
HandlerInjector(Context context) {
|
||||
mHandler = context.getMainThreadHandler();
|
||||
}
|
||||
|
||||
public void postDelay(Runnable runnable) {
|
||||
mHandler.postDelayed(runnable, 2000 /* delay millis */);
|
||||
}
|
||||
|
||||
public void removeCallbacks(Runnable runnable) {
|
||||
mHandler.removeCallbacks(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
private InternetConnectivityPanel(Context context) {
|
||||
mContext = context.getApplicationContext();
|
||||
mHandlerInjector = new HandlerInjector(context);
|
||||
mIsProviderModelEnabled = Utils.isProviderModelEnabled(mContext);
|
||||
mInternetUpdater = new InternetUpdater(context, null /* Lifecycle */, this);
|
||||
|
||||
@@ -150,7 +178,7 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve
|
||||
mTelephonyManager.registerTelephonyCallback(
|
||||
new HandlerExecutor(new Handler(Looper.getMainLooper())), mTelephonyCallback);
|
||||
mContext.registerReceiver(mWifiStateReceiver, mWifiStateFilter);
|
||||
showProgressBar();
|
||||
updateProgressBar();
|
||||
updatePanelTitle();
|
||||
}
|
||||
|
||||
@@ -165,7 +193,8 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve
|
||||
mConnectivityListener.stop();
|
||||
mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback);
|
||||
mContext.unregisterReceiver(mWifiStateReceiver);
|
||||
mContext.getMainThreadHandler().removeCallbacks(mHideProgressBarRunnable);
|
||||
mHandlerInjector.removeCallbacks(mHideProgressBarRunnable);
|
||||
mHandlerInjector.removeCallbacks(mHideScanningSubTitleRunnable);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -246,6 +275,7 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve
|
||||
*/
|
||||
@Override
|
||||
public void onAirplaneModeChanged(boolean isAirplaneModeOn) {
|
||||
log("onAirplaneModeChanged: isAirplaneModeOn:" + isAirplaneModeOn);
|
||||
updatePanelTitle();
|
||||
}
|
||||
|
||||
@@ -254,6 +284,7 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve
|
||||
*/
|
||||
@Override
|
||||
public void onWifiEnabledChanged(boolean enabled) {
|
||||
log("onWifiEnabledChanged: enabled:" + enabled);
|
||||
updatePanelTitle();
|
||||
}
|
||||
|
||||
@@ -305,13 +336,6 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve
|
||||
return;
|
||||
}
|
||||
|
||||
if (mIsProgressBarVisible) {
|
||||
// When the Wi-Fi scan result callback is received
|
||||
// Sub-Title: Searching for networks...
|
||||
mSubtitle = SUBTITLE_TEXT_SEARCHING_FOR_NETWORKS;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mInternetUpdater.isAirplaneModeOn()) {
|
||||
return;
|
||||
}
|
||||
@@ -319,11 +343,18 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve
|
||||
final List<ScanResult> wifiList = mWifiManager.getScanResults();
|
||||
if (wifiList != null && wifiList.size() != 0) {
|
||||
// When the Wi-Fi scan result is not empty
|
||||
// Sub-Title: Select the network you want to use for data
|
||||
// Sub-Title: Tap a network to connect
|
||||
mSubtitle = SUBTITLE_TEXT_TAP_A_NETWORK_TO_CONNECT;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mIsScanningSubTitleShownOnce && mIsProgressBarVisible) {
|
||||
// When the Wi-Fi scan result callback is received
|
||||
// Sub-Title: Searching for networks...
|
||||
mSubtitle = SUBTITLE_TEXT_SEARCHING_FOR_NETWORKS;
|
||||
return;
|
||||
}
|
||||
|
||||
// Sub-Title:
|
||||
// show non_carrier_network_unavailable
|
||||
// - while Wi-Fi on + no Wi-Fi item
|
||||
@@ -353,7 +384,7 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve
|
||||
mSubtitle = SUBTITLE_TEXT_NON_CARRIER_NETWORK_UNAVAILABLE;
|
||||
}
|
||||
|
||||
protected void showProgressBar() {
|
||||
protected void updateProgressBar() {
|
||||
if (mWifiManager == null || !mInternetUpdater.isWifiEnabled()) {
|
||||
setProgressBarVisible(false);
|
||||
return;
|
||||
@@ -362,8 +393,9 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve
|
||||
setProgressBarVisible(true);
|
||||
List<ScanResult> wifiScanResults = mWifiManager.getScanResults();
|
||||
if (wifiScanResults != null && wifiScanResults.size() > 0) {
|
||||
mContext.getMainThreadHandler().postDelayed(mHideProgressBarRunnable,
|
||||
2000 /* delay millis */);
|
||||
mHandlerInjector.postDelay(mHideProgressBarRunnable);
|
||||
} else if (!mIsScanningSubTitleShownOnce) {
|
||||
mHandlerInjector.postDelay(mHideScanningSubTitleRunnable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,15 +82,15 @@ public class SettingsMainSwitchPreference extends TwoStatePreference implements
|
||||
holder.setDividerAllowedAbove(false);
|
||||
holder.setDividerAllowedBelow(false);
|
||||
|
||||
mMainSwitchBar = (SettingsMainSwitchBar) holder.findViewById(R.id.main_switch_bar);
|
||||
mMainSwitchBar.show();
|
||||
if (mRestrictedHelper != null) {
|
||||
mEnforcedAdmin = mRestrictedHelper.checkRestrictionEnforced();
|
||||
}
|
||||
updateStatus(isChecked());
|
||||
registerListenerToSwitchBar();
|
||||
|
||||
if (!mIsVisible) {
|
||||
mMainSwitchBar = (SettingsMainSwitchBar) holder.findViewById(R.id.main_switch_bar);
|
||||
if (mIsVisible) {
|
||||
mMainSwitchBar.show();
|
||||
updateStatus(isChecked());
|
||||
registerListenerToSwitchBar();
|
||||
} else {
|
||||
mMainSwitchBar.hide();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.biometrics.combination;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.os.UserManager;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
|
||||
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;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class CombinedBiometricStatusPreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private LockPatternUtils mLockPatternUtils;
|
||||
@Mock
|
||||
private FingerprintManager mFingerprintManager;
|
||||
@Mock
|
||||
private FaceManager mFaceManager;
|
||||
@Mock
|
||||
private UserManager mUm;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
private Context mContext;
|
||||
private CombinedBiometricStatusPreferenceController mController;
|
||||
private Preference mPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)).thenReturn(true);
|
||||
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
|
||||
ShadowApplication.getInstance().setSystemService(Context.FINGERPRINT_SERVICE,
|
||||
mFingerprintManager);
|
||||
ShadowApplication.getInstance().setSystemService(Context.FACE_SERVICE, mFaceManager);
|
||||
ShadowApplication.getInstance().setSystemService(Context.USER_SERVICE, mUm);
|
||||
mPreference = new Preference(mContext);
|
||||
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
when(mFeatureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
|
||||
.thenReturn(mLockPatternUtils);
|
||||
when(mUm.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[] {1234});
|
||||
mController = new CombinedBiometricStatusPreferenceController(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_parentalConsentRequired_preferenceDisabled() {
|
||||
when(mFaceManager.isHardwareDetected()).thenReturn(true);
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
|
||||
|
||||
RestrictedPreference restrictedPreference = mock(RestrictedPreference.class);
|
||||
RestrictedLockUtils.EnforcedAdmin admin = mock(RestrictedLockUtils.EnforcedAdmin.class);
|
||||
|
||||
mController.mPreference = restrictedPreference;
|
||||
mController.updateStateInternal(admin);
|
||||
verify(restrictedPreference).setDisabledByAdmin(eq(admin));
|
||||
}
|
||||
}
|
||||
@@ -22,8 +22,10 @@ import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
@@ -37,6 +39,8 @@ import androidx.preference.Preference;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -129,4 +133,16 @@ public class FaceStatusPreferenceControllerTest {
|
||||
.getString(R.string.security_settings_face_preference_summary));
|
||||
assertThat(mPreference.isVisible()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_parentalConsentRequired_preferenceDisabled() {
|
||||
when(mFaceManager.isHardwareDetected()).thenReturn(true);
|
||||
|
||||
RestrictedPreference restrictedPreference = mock(RestrictedPreference.class);
|
||||
RestrictedLockUtils.EnforcedAdmin admin = mock(RestrictedLockUtils.EnforcedAdmin.class);
|
||||
|
||||
mController.mPreference = restrictedPreference;
|
||||
mController.updateStateInternal(admin);
|
||||
verify(restrictedPreference).setDisabledByAdmin(eq(admin));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,10 @@ import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
@@ -37,6 +39,8 @@ import androidx.preference.Preference;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -130,4 +134,16 @@ public class FingerprintStatusPreferenceControllerTest {
|
||||
R.plurals.security_settings_fingerprint_preference_summary, 1, 1));
|
||||
assertThat(mPreference.isVisible()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_parentalConsentRequired_preferenceDisabled() {
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
|
||||
|
||||
RestrictedPreference restrictedPreference = mock(RestrictedPreference.class);
|
||||
RestrictedLockUtils.EnforcedAdmin admin = mock(RestrictedLockUtils.EnforcedAdmin.class);
|
||||
|
||||
mController.mPreference = restrictedPreference;
|
||||
mController.updateStateInternal(admin);
|
||||
verify(restrictedPreference).setDisabledByAdmin(eq(admin));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ProviderInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.FeatureFlagUtils;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
@@ -46,7 +45,6 @@ import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.slices.BlockingSlicePrefController;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
@@ -335,37 +333,6 @@ public class DashboardFragmentTest {
|
||||
assertThat(pref).isInstanceOf(PrimarySwitchPreference.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isFeatureFlagAndIsParalleled_runParalleledUpdatePreferenceStates() {
|
||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTROLLER_ENHANCEMENT, true);
|
||||
final TestFragment testFragment = spy(new TestFragment(RuntimeEnvironment.application));
|
||||
|
||||
testFragment.updatePreferenceStates();
|
||||
|
||||
verify(testFragment).updatePreferenceStatesInParallel();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notFeatureFlagAndIsParalleled_notRunParalleledUpdatePreferenceStates() {
|
||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTROLLER_ENHANCEMENT, false);
|
||||
final TestFragment testFragment = spy(new TestFragment(RuntimeEnvironment.application));
|
||||
|
||||
testFragment.updatePreferenceStates();
|
||||
|
||||
verify(testFragment, never()).updatePreferenceStatesInParallel();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isFeatureFlagAndNotParalleled_notRunParalleledUpdatePreferenceStates() {
|
||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTROLLER_ENHANCEMENT, true);
|
||||
final TestFragment testFragment = spy(new TestFragment(RuntimeEnvironment.application));
|
||||
testFragment.setUsingControllerEnhancement(false);
|
||||
|
||||
testFragment.updatePreferenceStates();
|
||||
|
||||
verify(testFragment, never()).updatePreferenceStatesInParallel();
|
||||
}
|
||||
|
||||
public static class TestPreferenceController extends AbstractPreferenceController
|
||||
implements PreferenceControllerMixin {
|
||||
|
||||
|
||||
@@ -145,9 +145,6 @@ public class EnterprisePrivacyFeatureProviderImplTest {
|
||||
|
||||
SpannableStringBuilder disclosure = new SpannableStringBuilder();
|
||||
disclosure.append(mResources.getString(R.string.do_disclosure_generic));
|
||||
disclosure.append(mResources.getString(R.string.do_disclosure_learn_more_separator));
|
||||
disclosure.append(mResources.getString(R.string.learn_more),
|
||||
new EnterprisePrivacyFeatureProviderImpl.EnterprisePrivacySpan(mContext), 0);
|
||||
when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(mOwner);
|
||||
when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
|
||||
assertThat(mProvider.getDeviceOwnerDisclosure()).isEqualTo(disclosure);
|
||||
@@ -155,9 +152,6 @@ public class EnterprisePrivacyFeatureProviderImplTest {
|
||||
disclosure = new SpannableStringBuilder();
|
||||
disclosure.append(mResources.getString(R.string.do_disclosure_with_name,
|
||||
OWNER_ORGANIZATION));
|
||||
disclosure.append(mResources.getString(R.string.do_disclosure_learn_more_separator));
|
||||
disclosure.append(mResources.getString(R.string.learn_more),
|
||||
new EnterprisePrivacyFeatureProviderImpl.EnterprisePrivacySpan(mContext), 0);
|
||||
when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(OWNER_ORGANIZATION);
|
||||
assertThat(mProvider.getDeviceOwnerDisclosure()).isEqualTo(disclosure);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,10 @@ import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -39,6 +43,7 @@ public class SettingsMainSwitchPreferenceTest {
|
||||
@Mock
|
||||
private EnforcedAdmin mEnforcedAdmin;
|
||||
private SettingsMainSwitchPreference mPreference;
|
||||
private PreferenceViewHolder mHolder;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -48,6 +53,9 @@ public class SettingsMainSwitchPreferenceTest {
|
||||
mPreference = new SettingsMainSwitchPreference(context);
|
||||
ReflectionHelpers.setField(mPreference, "mEnforcedAdmin", mEnforcedAdmin);
|
||||
ReflectionHelpers.setField(mPreference, "mMainSwitchBar", switchBar);
|
||||
final View rootView = View.inflate(context, R.layout.preference_widget_main_switch,
|
||||
null /* parent */);
|
||||
mHolder = PreferenceViewHolder.createInstanceForTests(rootView);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -60,4 +68,22 @@ public class SettingsMainSwitchPreferenceTest {
|
||||
|
||||
assertThat(restrictedIcon.getVisibility() == View.VISIBLE).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void show_preferenceShouldDisplay() {
|
||||
mPreference.show();
|
||||
|
||||
mPreference.onBindViewHolder(mHolder);
|
||||
|
||||
assertThat(mPreference.isShowing()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hide_preferenceShouldNotDisplay() {
|
||||
mPreference.hide();
|
||||
|
||||
mPreference.onBindViewHolder(mHolder);
|
||||
|
||||
assertThat(mPreference.isShowing()).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.biometrics;
|
||||
|
||||
import static junit.framework.TestCase.assertNotNull;
|
||||
import static junit.framework.TestCase.assertNull;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
|
||||
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
|
||||
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_IRIS;
|
||||
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ParentalControlsUtilsTest {
|
||||
|
||||
@Mock
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private DevicePolicyManager mDpm;
|
||||
private ComponentName mSupervisionComponentName = new ComponentName("pkg", "cls");
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mContext.getContentResolver()).thenReturn(mock(ContentResolver.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper that sets the appropriate mocks and testing behavior before returning the actual
|
||||
* EnforcedAdmin from ParentalControlsUtils.
|
||||
*/
|
||||
@Nullable
|
||||
private RestrictedLockUtils.EnforcedAdmin getEnforcedAdminForCombination(
|
||||
@Nullable ComponentName supervisionComponentName,
|
||||
@BiometricAuthenticator.Modality int modality, int keyguardDisabledFlags) {
|
||||
when(mDpm.getProfileOwnerOrDeviceOwnerSupervisionComponent(any(UserHandle.class)))
|
||||
.thenReturn(supervisionComponentName);
|
||||
when(mDpm.getKeyguardDisabledFeatures(eq(supervisionComponentName)))
|
||||
.thenReturn(keyguardDisabledFlags);
|
||||
|
||||
return ParentalControlsUtils.parentConsentRequiredInternal(mDpm, modality,
|
||||
new UserHandle(UserHandle.myUserId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnforcedAdmin_whenDpmDisablesBiometricsAndSupervisionComponentExists() {
|
||||
int[][] tests = {
|
||||
{TYPE_FINGERPRINT, DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT},
|
||||
{TYPE_FACE, DevicePolicyManager.KEYGUARD_DISABLE_FACE},
|
||||
{TYPE_IRIS, DevicePolicyManager.KEYGUARD_DISABLE_IRIS},
|
||||
};
|
||||
|
||||
for (int i = 0; i < tests.length; i++) {
|
||||
RestrictedLockUtils.EnforcedAdmin admin = getEnforcedAdminForCombination(
|
||||
mSupervisionComponentName, tests[i][0] /* modality */,
|
||||
tests[i][1] /* keyguardDisableFlags */);
|
||||
assertNotNull(admin);
|
||||
assertEquals(mSupervisionComponentName, admin.component);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoEnforcedAdmin_whenNoSupervisionComponent() {
|
||||
// Even if DPM flag exists, returns null EnforcedAdmin when no supervision component exists
|
||||
RestrictedLockUtils.EnforcedAdmin admin = getEnforcedAdminForCombination(
|
||||
null /* supervisionComponentName */, TYPE_FINGERPRINT,
|
||||
DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
|
||||
assertNull(admin);
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,6 @@ package com.android.settings.panel;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -95,11 +93,31 @@ public class InternetConnectivityPanelTest {
|
||||
private FragmentActivity mPanelActivity;
|
||||
|
||||
private Context mContext;
|
||||
private FakeHandlerInjector mFakeHandlerInjector;
|
||||
private InternetConnectivityPanel mPanel;
|
||||
|
||||
private class FakeHandlerInjector extends InternetConnectivityPanel.HandlerInjector {
|
||||
|
||||
private Runnable mRunnable;
|
||||
|
||||
FakeHandlerInjector(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postDelay(Runnable runnable) {
|
||||
mRunnable = runnable;
|
||||
}
|
||||
|
||||
public Runnable getRunnable() {
|
||||
return mRunnable;
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
mFakeHandlerInjector = new FakeHandlerInjector(mContext);
|
||||
when(mContext.getApplicationContext()).thenReturn(mContext);
|
||||
when(mContext.getMainThreadHandler()).thenReturn(mMainThreadHandler);
|
||||
when(mContext.getSystemService(WifiManager.class)).thenReturn(mWifiManager);
|
||||
@@ -109,6 +127,7 @@ public class InternetConnectivityPanelTest {
|
||||
mPanel.mIsProviderModelEnabled = true;
|
||||
mPanel.mInternetUpdater = mInternetUpdater;
|
||||
mPanel.mProviderModelSliceHelper = mProviderModelSliceHelper;
|
||||
mPanel.mHandlerInjector = mFakeHandlerInjector;
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -295,36 +314,41 @@ public class InternetConnectivityPanelTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showProgressBar_wifiDisabled_hideProgress() {
|
||||
public void updateProgressBar_wifiDisabled_hideProgress() {
|
||||
mPanel.mIsProgressBarVisible = true;
|
||||
doReturn(false).when(mInternetUpdater).isWifiEnabled();
|
||||
clearInvocations(mPanelContentCallback);
|
||||
|
||||
mPanel.showProgressBar();
|
||||
mPanel.updateProgressBar();
|
||||
|
||||
assertThat(mPanel.isProgressBarVisible()).isFalse();
|
||||
verify(mPanelContentCallback).onProgressBarVisibleChanged();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showProgressBar_noWifiScanResults_showProgressForever() {
|
||||
public void updateProgressBar_noWifiScanResults_showProgressForever() {
|
||||
mPanel.mIsScanningSubTitleShownOnce = false;
|
||||
mPanel.mIsProgressBarVisible = false;
|
||||
doReturn(true).when(mInternetUpdater).isWifiEnabled();
|
||||
List<ScanResult> noWifiScanResults = new ArrayList<>();
|
||||
doReturn(noWifiScanResults).when(mWifiManager).getScanResults();
|
||||
clearInvocations(mPanelContentCallback);
|
||||
|
||||
mPanel.showProgressBar();
|
||||
mPanel.updateProgressBar();
|
||||
|
||||
assertThat(mPanel.isProgressBarVisible()).isTrue();
|
||||
assertThat(mPanel.mIsProgressBarVisible).isTrue();
|
||||
verify(mPanelContentCallback).onProgressBarVisibleChanged();
|
||||
verify(mPanelContentCallback).onHeaderChanged();
|
||||
verify(mMainThreadHandler, never())
|
||||
.postDelayed(any() /* mHideProgressBarRunnable */, anyLong());
|
||||
|
||||
assertThat(mFakeHandlerInjector.getRunnable())
|
||||
.isEqualTo(mPanel.mHideScanningSubTitleRunnable);
|
||||
mFakeHandlerInjector.getRunnable().run();
|
||||
assertThat(mPanel.mIsScanningSubTitleShownOnce).isTrue();
|
||||
assertThat(mPanel.mIsProgressBarVisible).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showProgressBar_hasWifiScanResults_showProgressDelayedHide() {
|
||||
public void updateProgressBar_hasWifiScanResults_showProgressDelayedHide() {
|
||||
mPanel.mIsProgressBarVisible = false;
|
||||
doReturn(true).when(mInternetUpdater).isWifiEnabled();
|
||||
List<ScanResult> hasWifiScanResults = mock(ArrayList.class);
|
||||
@@ -332,11 +356,15 @@ public class InternetConnectivityPanelTest {
|
||||
doReturn(hasWifiScanResults).when(mWifiManager).getScanResults();
|
||||
clearInvocations(mPanelContentCallback);
|
||||
|
||||
mPanel.showProgressBar();
|
||||
mPanel.updateProgressBar();
|
||||
|
||||
assertThat(mPanel.isProgressBarVisible()).isTrue();
|
||||
verify(mPanelContentCallback).onProgressBarVisibleChanged();
|
||||
verify(mMainThreadHandler).postDelayed(any() /* mHideProgressBarRunnable */, anyLong());
|
||||
|
||||
assertThat(mFakeHandlerInjector.getRunnable())
|
||||
.isEqualTo(mPanel.mHideProgressBarRunnable);
|
||||
mFakeHandlerInjector.getRunnable().run();
|
||||
assertThat(mPanel.mIsProgressBarVisible).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user