Merge "String update." into qt-r1-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index f4ff282..fc3888b 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -102,8 +102,6 @@
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
- <protected-broadcast android:name="com.android.settings.DELETE_SIM_PROFILE_RESULT"/>
-
<application android:label="@string/settings_label"
android:icon="@drawable/ic_launcher_settings"
android:theme="@style/Theme.Settings"
diff --git a/res/drawable/ic_notifications_alert.xml b/res/drawable/ic_notifications_alert.xml
new file mode 100644
index 0000000..5a25459
--- /dev/null
+++ b/res/drawable/ic_notifications_alert.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2019 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">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M18 17v-6c0-3.07-1.63-5.64-4.5-6.32V4c0-0.83-0.67-1.5-1.5-1.5s-1.5 0.67 -1.5 1.5v0.68C7.64 5.36 6 7.92 6 11v6H4v2h16v-2h-2zm-2 0H8v-6c0-2.48 1.51-4.5 4-4.5s4 2.02 4 4.5v6zm-6 3h4c0 1.1-0.9 2-2 2s-2-0.9-2-2zm12-9h-2c0-2.74-1.23-5.19-3.16-6.84l1.41-1.41C20.54 4.77 22 7.71 22 11zM5.75 2.75l1.41 1.41C5.23 5.81 4 8.26 4 11H2c0-3.29 1.46-6.23 3.75-8.25z" />
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_settings_adaptive_sleep.xml b/res/drawable/ic_settings_adaptive_sleep.xml
new file mode 100644
index 0000000..765ed94
--- /dev/null
+++ b/res/drawable/ic_settings_adaptive_sleep.xml
@@ -0,0 +1,31 @@
+<!--
+ Copyright (C) 2019 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.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M10.67,21H7v-1h3.13c-0.27-0.63-0.46-1.3-0.56-2H7V6h10v3.5c0.69,0,1.36,0.1,2,0.28V3 c0-1.1-0.9-1.99-2-1.99L7,1C5.9,1,5,1.9,5,3v18c0,1.1,0.9,2,2,2h5.52C11.79,22.45,11.16,21.77,10.67,21z M7,3h10v1H7V3z" />
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M17,12.5c2.48,0,4.5,2.02,4.5,4.5s-2.02,4.5-4.5,4.5s-4.5-2.02-4.5-4.5S14.52,12.5,17,12.5 M17,11 c-3.31,0-6,2.69-6,6s2.69,6,6,6c3.31,0,6-2.69,6-6S20.31,11,17,11L17,11z" />
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M17,14v3l-2.12,2.12C15.42,19.66,16.17,20,17,20c1.66,0,3-1.34,3-3S18.66,14,17,14z" />
+</vector>
\ No newline at end of file
diff --git a/res/layout-land/confirm_lock_pattern.xml b/res/layout-land/confirm_lock_pattern.xml
index 20a7bfc..6ca9be4 100644
--- a/res/layout-land/confirm_lock_pattern.xml
+++ b/res/layout-land/confirm_lock_pattern.xml
@@ -87,11 +87,9 @@
<com.android.internal.widget.LockPatternView
android:id="@+id/lockPattern"
- android:layout_width="288dp"
- android:layout_height="288dp"
- android:layout_marginStart="-42dp"
- android:layout_marginEnd="-42dp"
- android:layout_gravity="center_vertical"/>
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"/>
<TextView
style="@style/TextAppearance.ErrorText"
diff --git a/res/layout/dialog_mobile_network_color_picker_item.xml b/res/layout/dialog_mobile_network_color_picker_item.xml
new file mode 100644
index 0000000..b6f4092
--- /dev/null
+++ b/res/layout/dialog_mobile_network_color_picker_item.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:background="?android:attr/selectableItemBackground" >
+
+ <ImageView
+ android:id="@+id/color_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="@dimen/sim_label_padding"
+ android:layout_gravity="center_vertical" />
+
+ <TextView
+ android:id="@+id/color_label"
+ android:gravity="center_vertical"
+ android:layout_height="wrap_content"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:paddingTop="@dimen/sim_label_padding"
+ android:paddingBottom="@dimen/sim_label_padding"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
+ android:textColor="?android:attr/textColorPrimary"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/dialog_mobile_network_rename.xml b/res/layout/dialog_mobile_network_rename.xml
index d67f0dc..921ab86 100644
--- a/res/layout/dialog_mobile_network_rename.xml
+++ b/res/layout/dialog_mobile_network_rename.xml
@@ -21,44 +21,89 @@
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:padding="@dimen/sim_content_padding">
+ android:layout_height="wrap_content">
- <EditText
- android:id="@+id/edittext"
+ <LinearLayout
+ android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:inputType="text"
- android:maxLength="50"
- android:singleLine="true">
- <requestFocus/>
- </EditText>
+ android:paddingEnd="@dimen/sim_content_padding"
+ android:paddingStart="@dimen/sim_content_padding">
- <TextView
- style="@style/device_info_dialog_label"
- android:id="@+id/operator_name_label"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/status_operator"/>
- <TextView
- style="@style/device_info_dialog_value"
- android:id="@+id/operator_name_value"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/device_info_not_available"/>
+ <TextView
+ android:id="@+id/name_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/sim_label_padding"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
+ android:textColor="?android:attr/textColorPrimary"
+ android:text="@string/mobile_network_sim_name_label"/>
- <TextView
- style="@style/device_info_dialog_label"
- android:id="@+id/number_label"
+ <EditText
+ android:id="@+id/name_edittext"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="text"
+ android:paddingTop="@dimen/sim_label_padding"
+ android:maxLength="50"
+ android:singleLine="true"/>
+
+ <TextView
+ android:id="@+id/color_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/sim_label_padding"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
+ android:textColor="?android:attr/textColorPrimary"
+ android:text="@string/mobile_network_sim_color_label"/>
+
+ </LinearLayout>
+
+ <Spinner
+ android:id="@+id/color_spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/status_number_sim_status"/>
- <TextView
- style="@style/device_info_dialog_value"
- android:id="@+id/number_value"
+ android:layout_marginStart="@dimen/sim_color_spinner_padding"
+ android:layout_marginEnd="@dimen/sim_color_spinner_padding"/>
+
+ <LinearLayout
+ android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/device_info_not_available"/>
+ android:paddingEnd="@dimen/sim_content_padding"
+ android:paddingStart="@dimen/sim_content_padding">
+
+ <TextView
+ android:id="@+id/operator_name_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/sim_label_padding"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
+ android:textColor="?android:attr/textColorPrimary"
+ android:text="@string/status_operator"/>
+
+ <TextView
+ android:id="@+id/operator_name_value"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/device_info_not_available"/>
+
+ <TextView
+ android:id="@+id/number_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/sim_label_padding"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
+ android:textColor="?android:attr/textColorPrimary"
+ android:text="@string/status_number_sim_status"/>
+
+ <TextView
+ android:id="@+id/number_value"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/device_info_not_available"/>
+
+ </LinearLayout>
</LinearLayout>
</ScrollView>
diff --git a/res/layout/notif_importance_preference.xml b/res/layout/notif_importance_preference.xml
index 2fc2740..29c337a 100644
--- a/res/layout/notif_importance_preference.xml
+++ b/res/layout/notif_importance_preference.xml
@@ -24,7 +24,7 @@
android:padding="@dimen/notification_importance_toggle_marginTop"
android:orientation="vertical">
- <RelativeLayout
+ <com.android.settings.notification.NotificationButtonRelativeLayout
android:id="@+id/alert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -33,7 +33,7 @@
android:focusable="true">
<ImageView
android:id="@+id/alert_icon"
- android:src="@drawable/ic_notifications"
+ android:src="@drawable/ic_notifications_alert"
android:background="@android:color/transparent"
android:layout_gravity="center"
android:layout_width="wrap_content"
@@ -65,7 +65,7 @@
android:layout_below="@id/alert_icon"
android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"
android:visibility="gone" />
- </RelativeLayout>
+ </com.android.settings.notification.NotificationButtonRelativeLayout>
<RelativeLayout
android:id="@+id/silence"
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 09ab682..fbf1a24 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -166,6 +166,7 @@
<dimen name="sim_dialog_margin_bottom">16dip</dimen>
<!-- SIM Dialog padding -->
<dimen name="sim_dialog_padding">8dip</dimen>
+ <dimen name="sim_color_spinner_padding">12dip</dimen>
<dimen name="sim_label_padding">16dip</dimen>
<dimen name="sim_content_padding">24dip</dimen>
<!-- Sim Card Name length -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9862387..3390831 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2833,7 +2833,7 @@
<!-- Setting option summary when adaptive sleep is off [CHAR LIMIT=NONE] -->
<string name="adaptive_sleep_summary_off">Off</string>
<!-- Description about the feature adaptive sleep [CHAR LIMIT=NONE]-->
- <string name="adaptive_sleep_description">Prevents your screen from turning off if you’re looking at it.</string>
+ <string name="adaptive_sleep_description">Keep screen on when viewing it</string>
<!-- Description feature's privacy sensitive details to make sure users understand what feature users, what it saves/sends etc [CHAR LIMIT=NONE]-->
<string name="adaptive_sleep_privacy">Screen attention uses the front camera to see if someone is looking at the screen. It works on device, and images are never stored or sent to Google.</string>
@@ -7337,7 +7337,7 @@
<string name="keywords_assist_gesture_launch">gesture</string>
<string name="keywords_face_unlock">face, unlock, auth, sign in</string>
<string name="keywords_imei_info">imei, meid, min, prl version, imei sv</string>
- <string name="keywords_sim_status">network, mobile network state, service state, signal strength, mobile network type, roaming, iccid</string>
+ <string name="keywords_sim_status">network, mobile network state, service state, signal strength, mobile network type, roaming, iccid, eid</string>
<string name="keywords_model_and_hardware">serial number, hardware version</string>
<string name="keywords_android_version">android security patch level, baseband version, kernel version</string>
<!-- Search keywords for dark mode settings [CHAR LIMIT=NONE] -->
@@ -7903,6 +7903,9 @@
<!-- Configure Notifications: setting summary [CHAR LIMIT=200] -->
<string name="asst_capabilities_actions_replies_summary">Automatically show suggested actions & replies</string>
+ <!-- Configure Notifications: setting title, whether the snooze menu is shown on notifications [CHAR LIMIT=80] -->
+ <string name="snooze_options_title">Allow notification snoozing</string>
+
<!-- Configure Notifications: setting title [CHAR LIMIT=80] -->
<string name="hide_silent_icons_title">Hide icons from gentle notifications</string>
@@ -7973,6 +7976,15 @@
<!-- Configure Notifications: Title for the option controlling notifications on the lockscreen. [CHAR LIMIT=30] -->
<string name="lock_screen_notifications_title">Lock screen</string>
+ <!-- Configure lock screen: Title for the option of unlocking directly to home. [CHAR LIMIT=30] -->
+ <string name="lockscreen_bypass_title">Skip lock screen</string>
+
+ <!-- Configure lock screen: Summary for the option of unlocking directly to home. [CHAR LIMIT=60] -->
+ <string name="lockscreen_bypass_summary">After face unlock, go directly to last used screen</string>
+
+ <!-- Configure lock screen: Search keywords for the option of unlocking directly to home. [CHAR LIMIT=60] -->
+ <string name="keywords_lockscreen_bypass">Lock screen, Lockscreen, Skip, Bypass</string>
+
<!-- Configure Notifications: Title for the option controlling notifications for work profile. [CHAR LIMIT=30] -->
<string name="locked_work_profile_notification_title">When work profile is locked</string>
@@ -8103,7 +8115,7 @@
<string name="notification_silence_title">Silent</string>
<!-- [CHAR LIMIT=100] Notification Importance title -->
- <string name="notification_alert_title">Prioritized</string>
+ <string name="notification_alert_title">Alerting</string>
<!-- [CHAR LIMIT=40] Notification importance title. This setting controls how notifications in older apps may alert the user (eg, sound, visual, vibrate). -->
<string name="allow_interruption">Allow interruptions</string>
@@ -9984,12 +9996,6 @@
<!-- [CHAR_LIMIT=NONE] Developer Settings: Title of the settings category for theme overlays. -->
<string name="theme_customization_category">Theming</string>
- <!-- [CHAR_LIMIT=NONE] Developer Settings: Title of the setting which enables overlays to customize accent color. -->
- <string name="theme_customization_accent_color_title">Accent color</string>
- <!-- [CHAR_LIMIT=NONE] Developer Settings: Title of the setting which enables overlays to customize headline and body fonts. -->
- <string name="theme_customization_font_title">Headline / Body font</string>
- <!-- [CHAR_LIMIT=NONE] Developer Settings: Title of the setting which enables overlays to customize the adaptive icon shape (e.g. launcher and quick settings icons). -->
- <string name="theme_customization_icon_shape_title">Icon shape</string>
<!-- [CHAR_LIMIT=NONE] Developer Settings: Label for the option that turns off customizations for a given category.-->
<string name="theme_customization_device_default">Device default</string>
@@ -10202,7 +10208,7 @@
<!-- Message for the alert dialog which says that the current default home app does not support gesture navigation. [CHAR LIMIT=NONE] -->
<string name="gesture_not_supported_dialog_message">Not supported by your default home app, <xliff:g id="default_home_app" example="Pixel Launcher">%s</xliff:g></string>
- <!-- Positive button for the alert dialog when gesture nav not supported by launcher [CHAR LIMIT=40] -->
+ <!-- Positive button for the alert dialog when gesture nav not supported by launcher [CHAR LIMIT=60] -->
<string name="gesture_not_supported_positive_button">Switch default home app</string>
<!-- Content description for the Information icon [CHAR LIMIT=30] -->
@@ -10955,10 +10961,14 @@
subscription in various places in the Settings app. The default name is typically just the
carrier name, but especially in multi-SIM configurations users may want to use a different
name. [CHAR LIMIT=40] -->
- <string name="mobile_network_sim_name">SIM name</string>
- <!-- Label on the confirmation button of a dialog that lets a user set the display name of a
- mobile network subscription [CHAR LIMIT=20] -->
- <string name="mobile_network_sim_name_rename">Rename</string>
+ <string name="mobile_network_sim_name">SIM name & color</string>
+ <!-- Label for an item listing the name of the SIM that the user has specified. [CHAR LIMIT=40] -->
+ <string name="mobile_network_sim_name_label">Name</string>
+ <!-- Label for an item listing the color of the SIM that the user has specified. [CHAR LIMIT=40] -->
+ <string name="mobile_network_sim_color_label">Color (used by compatible apps)</string>
+ <!-- Label on the confirmation button of a dialog that lets a user set the display name and
+ color of a mobile network subscription [CHAR LIMIT=20] -->
+ <string name="mobile_network_sim_name_rename">Save</string>
<!-- Label for the on position of a switch on the mobile network details page which allows
disabling/enabling a SIM. The SIM is enabled in this state. [CHAR LIMIT=40] -->
<string name="mobile_network_use_sim_on">Use SIM</string>
@@ -11218,11 +11228,11 @@
<string name="forget_passpoint_dialog_message">You may lose access to any remaining time or data. Check with your provider before removing.</string>
<!-- Keywords for Content Capture feature [CHAR_LIMIT=none] -->
- <string name="keywords_content_capture">content capture, app content, app data</string>
+ <string name="keywords_content_capture">content capture, app content</string>
<!-- Title of the 'Content Capture' feature toggle in the Settings -> Privacy screen [CHAR LIMIT=none]-->
- <string name="content_capture">Personalize using app data</string>
+ <string name="content_capture">App content</string>
<!-- Description of the 'Content Capture' feature toggle in the Settings -> Privacy screen [CHAR LIMIT=NONE]-->
- <string name="content_capture_summary">Allow apps to send content to the Android system. Tap to learn more.</string>
+ <string name="content_capture_summary">Allow apps to send content to the Android system</string>
<!-- Title for the button to initiate a heap dump for the system server. [CHAR LIMIT=NONE] -->
<string name="capture_system_heap_dump_title">Capture system heap dump</string>
diff --git a/res/xml/configure_notification_settings.xml b/res/xml/configure_notification_settings.xml
index 224a910..63f6751 100644
--- a/res/xml/configure_notification_settings.xml
+++ b/res/xml/configure_notification_settings.xml
@@ -80,6 +80,11 @@
settings:initialExpandedChildrenCount="0">
<SwitchPreference
+ android:key="show_snooze_options"
+ android:title="@string/snooze_options_title"
+ settings:controller="com.android.settings.notification.SnoozeNotificationPreferenceController" />
+
+ <SwitchPreference
android:key="asst_capabilities_actions_replies"
android:title="@string/asst_capabilities_actions_replies_title"
android:summary="@string/asst_capabilities_actions_replies_summary"
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index a8a6075..63840bbc 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -248,6 +248,11 @@
android:summary="@string/wifi_verbose_logging_summary" />
<SwitchPreference
+ android:key="wifi_scan_throttling"
+ android:title="@string/wifi_scan_throttling"
+ android:summary="@string/wifi_scan_throttling_summary" />
+
+ <SwitchPreference
android:key="mobile_data_always_on"
android:title="@string/mobile_data_always_on"
android:summary="@string/mobile_data_always_on_summary" />
@@ -576,7 +581,7 @@
<com.android.settings.development.autofill.AutofillPreferenceCategory
android:key="debug_autofill_category"
android:title="@string/debug_autofill_category"
- android:order="1100">
+ android:order="1100"> <!-- Incremented by 100 from last order (i.e. 1000) -->
<ListPreference
android:key="autofill_logging_level"
@@ -597,20 +602,4 @@
android:title="@string/autofill_reset_developer_options" />
</com.android.settings.development.autofill.AutofillPreferenceCategory>
-
- <PreferenceCategory
- android:key="theme_customization_category"
- android:title="@string/theme_customization_category"
- android:order="1200"> <!-- Incremented by 100 from last order (i.e. 1100) -->
-
- <ListPreference
- android:key="android.theme.customization.accent_color"
- android:title="@string/theme_customization_accent_color_title"/>
- <ListPreference
- android:key="android.theme.customization.font"
- android:title="@string/theme_customization_font_title"/>
- <ListPreference
- android:key="android.theme.customization.adaptive_icon_shape"
- android:title="@string/theme_customization_icon_shape_title"/>
- </PreferenceCategory>
</PreferenceScreen>
diff --git a/res/xml/privacy_dashboard_settings.xml b/res/xml/privacy_dashboard_settings.xml
index aa789b9..7057ec5 100644
--- a/res/xml/privacy_dashboard_settings.xml
+++ b/res/xml/privacy_dashboard_settings.xml
@@ -62,6 +62,14 @@
android:summary="@string/summary_placeholder"
settings:searchable="false"/>
+ <!-- Bypass lock screen -->
+ <SwitchPreference
+ android:key="privacy_lockscreen_bypass"
+ android:title="@string/lockscreen_bypass_title"
+ android:summary="@string/lockscreen_bypass_summary"
+ settings:keywords="@string/keywords_lockscreen_bypass"
+ settings:controller="com.android.settings.security.LockscreenBypassPreferenceController" />
+
<!-- Privacy Service -->
<PreferenceCategory
android:key="privacy_services"
diff --git a/res/xml/security_lockscreen_settings.xml b/res/xml/security_lockscreen_settings.xml
index 611d33f..69e8a3b 100644
--- a/res/xml/security_lockscreen_settings.xml
+++ b/res/xml/security_lockscreen_settings.xml
@@ -30,6 +30,13 @@
android:summary="@string/summary_placeholder"
settings:keywords="@string/keywords_lock_screen_notif"/>
+ <SwitchPreference
+ android:key="security_lockscreen_bypass"
+ android:title="@string/lockscreen_bypass_title"
+ android:summary="@string/lockscreen_bypass_summary"
+ settings:searchable="false"
+ settings:controller="com.android.settings.security.LockscreenBypassPreferenceController" />
+
<com.android.settingslib.RestrictedSwitchPreference
android:key="security_lockscreen_add_users_when_locked"
android:title="@string/user_add_on_lockscreen_menu"
diff --git a/src/com/android/settings/FallbackHome.java b/src/com/android/settings/FallbackHome.java
index 59347ad..e3944a6 100644
--- a/src/com/android/settings/FallbackHome.java
+++ b/src/com/android/settings/FallbackHome.java
@@ -25,6 +25,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ResolveInfo;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -65,7 +66,7 @@
@Override
public void onColorsChanged(WallpaperColors colors, int which) {
if (colors != null) {
- View decorView = getWindow().getDecorView();
+ final View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
updateVisibilityFlagsFromColors(colors, decorView.getSystemUiVisibility()));
mWallManager.removeOnColorsChangedListener(this);
@@ -81,7 +82,7 @@
// we don't flash the wallpaper before SUW
mProvisioned = Settings.Global.getInt(getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 0) != 0;
- int flags;
+ final int flags;
if (!mProvisioned) {
setTheme(R.style.FallbackHome_SetupWizard);
flags = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
@@ -91,18 +92,11 @@
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
}
- // Set the system ui flags to light status bar if the wallpaper supports dark text to match
- // current system ui color tints. Use a listener to wait for colors if not ready yet.
mWallManager = getSystemService(WallpaperManager.class);
if (mWallManager == null) {
Log.w(TAG, "Wallpaper manager isn't ready, can't listen to color changes!");
} else {
- WallpaperColors colors = mWallManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
- if (colors == null) {
- mWallManager.addOnColorsChangedListener(mColorsChangedListener, null /* handler */);
- } else {
- flags = updateVisibilityFlagsFromColors(colors, flags);
- }
+ loadWallpaperColors(flags);
}
getWindow().getDecorView().setSystemUiVisibility(flags);
@@ -139,6 +133,33 @@
}
};
+ private void loadWallpaperColors(int flags) {
+ final AsyncTask loadWallpaperColorsTask = new AsyncTask<Object, Void, Integer>() {
+ @Override
+ protected Integer doInBackground(Object... params) {
+ final WallpaperColors colors =
+ mWallManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
+
+ // Use a listener to wait for colors if not ready yet.
+ if (colors == null) {
+ mWallManager.addOnColorsChangedListener(mColorsChangedListener,
+ null /* handler */);
+ return null;
+ }
+ return updateVisibilityFlagsFromColors(colors, flags);
+ }
+
+ @Override
+ protected void onPostExecute(Integer flagsToUpdate) {
+ if (flagsToUpdate == null) {
+ return;
+ }
+ getWindow().getDecorView().setSystemUiVisibility(flagsToUpdate);
+ }
+ };
+ loadWallpaperColorsTask.execute();
+ }
+
private void maybeFinish() {
if (getSystemService(UserManager.class).isUserUnlocked()) {
final Intent homeIntent = new Intent(Intent.ACTION_MAIN)
@@ -162,6 +183,8 @@
}
}
+ // Set the system ui flags to light status bar if the wallpaper supports dark text to match
+ // current system ui color tints.
private int updateVisibilityFlagsFromColors(WallpaperColors colors, int flags) {
if ((colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0) {
return flags | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 9dcc222..d6d8957 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -432,6 +432,7 @@
controllers.add(new CameraLaserSensorPreferenceController(context));
controllers.add(new WifiDisplayCertificationPreferenceController(context));
controllers.add(new WifiVerboseLoggingPreferenceController(context));
+ controllers.add(new WifiScanThrottlingPreferenceController(context));
controllers.add(new MobileDataAlwaysOnPreferenceController(context));
controllers.add(new TetheringHardwareAccelPreferenceController(context));
controllers.add(new BluetoothDeviceNoNamePreferenceController(context));
@@ -495,12 +496,6 @@
controllers.add(new DefaultLaunchPreferenceController(context, "inactive_apps"));
controllers.add(new AutofillLoggingLevelPreferenceController(context, lifecycle));
controllers.add(new AutofillResetOptionsPreferenceController(context));
- controllers.add(new OverlayCategoryPreferenceController(context,
- "android.theme.customization.accent_color"));
- controllers.add(new OverlayCategoryPreferenceController(context,
- "android.theme.customization.font"));
- controllers.add(new OverlayCategoryPreferenceController(context,
- "android.theme.customization.adaptive_icon_shape"));
controllers.add(new TrustAgentsExtendUnlockPreferenceController(context));
controllers.add(new TrustLostLocksScreenPreferenceController(context));
return controllers;
diff --git a/src/com/android/settings/development/WifiScanThrottlingPreferenceController.java b/src/com/android/settings/development/WifiScanThrottlingPreferenceController.java
new file mode 100644
index 0000000..a069827
--- /dev/null
+++ b/src/com/android/settings/development/WifiScanThrottlingPreferenceController.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2019 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.development;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.SwitchPreference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.development.DeveloperOptionsPreferenceController;
+
+public class WifiScanThrottlingPreferenceController extends DeveloperOptionsPreferenceController
+ implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
+ private static final String WIFI_SCAN_THROTTLING_KEY = "wifi_scan_throttling";
+ @VisibleForTesting
+ static final int SETTING_THROTTLING_ENABLE_VALUE_ON = 1; // default is throttling enabled.
+ @VisibleForTesting
+ static final int SETTING_THROTTLING_ENABLE_VALUE_OFF = 0;
+
+ public WifiScanThrottlingPreferenceController(Context context) {
+ super(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return WIFI_SCAN_THROTTLING_KEY;
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean isEnabled = (Boolean) newValue;
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.WIFI_SCAN_THROTTLE_ENABLED,
+ isEnabled
+ ? SETTING_THROTTLING_ENABLE_VALUE_ON
+ : SETTING_THROTTLING_ENABLE_VALUE_OFF);
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ final int scanThrottleEnabled = Settings.Global.getInt(
+ mContext.getContentResolver(), Settings.Global.WIFI_SCAN_THROTTLE_ENABLED,
+ SETTING_THROTTLING_ENABLE_VALUE_ON);
+ ((SwitchPreference) mPreference).setChecked(
+ scanThrottleEnabled == SETTING_THROTTLING_ENABLE_VALUE_ON);
+ }
+
+ @Override
+ protected void onDeveloperOptionsSwitchDisabled() {
+ super.onDeveloperOptionsSwitchDisabled();
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.WIFI_SCAN_THROTTLE_ENABLED, SETTING_THROTTLING_ENABLE_VALUE_ON);
+ ((SwitchPreference) mPreference).setChecked(true);
+ }
+}
diff --git a/src/com/android/settings/display/AdaptiveSleepPreferenceController.java b/src/com/android/settings/display/AdaptiveSleepPreferenceController.java
index 6b91792..e83410d 100644
--- a/src/com/android/settings/display/AdaptiveSleepPreferenceController.java
+++ b/src/com/android/settings/display/AdaptiveSleepPreferenceController.java
@@ -25,9 +25,9 @@
public class AdaptiveSleepPreferenceController extends TogglePreferenceController {
-
- private final String SYSTEM_KEY = ADAPTIVE_SLEEP;
- private final int DEFAULT_VALUE = 0;
+ public static final String PREF_NAME = "adaptive_sleep";
+ private static final String SYSTEM_KEY = ADAPTIVE_SLEEP;
+ private static final int DEFAULT_VALUE = 0;
final boolean hasSufficientPermissions;
@@ -35,9 +35,7 @@
super(context, key);
final PackageManager packageManager = mContext.getPackageManager();
- final String attentionPackage = packageManager.getAttentionServicePackageName();
- hasSufficientPermissions = attentionPackage != null && packageManager.checkPermission(
- Manifest.permission.CAMERA, attentionPackage) == PackageManager.PERMISSION_GRANTED;
+ hasSufficientPermissions = hasSufficientPermission(packageManager);
}
@Override
@@ -46,7 +44,6 @@
SYSTEM_KEY, DEFAULT_VALUE) != DEFAULT_VALUE;
}
-
@Override
public boolean setChecked(boolean isChecked) {
Settings.System.putInt(mContext.getContentResolver(), SYSTEM_KEY,
@@ -57,10 +54,7 @@
@Override
@AvailabilityStatus
public int getAvailabilityStatus() {
- return mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_adaptive_sleep_available)
- ? AVAILABLE_UNSEARCHABLE
- : UNSUPPORTED_ON_DEVICE;
+ return isControllerAvailable(mContext);
}
@Override
@@ -69,4 +63,17 @@
? R.string.adaptive_sleep_summary_on
: R.string.adaptive_sleep_summary_off);
}
+
+ public static int isControllerAvailable(Context context) {
+ return context.getResources().getBoolean(
+ com.android.internal.R.bool.config_adaptive_sleep_available)
+ ? AVAILABLE_UNSEARCHABLE
+ : UNSUPPORTED_ON_DEVICE;
+ }
+
+ private static boolean hasSufficientPermission(PackageManager packageManager) {
+ final String attentionPackage = packageManager.getAttentionServicePackageName();
+ return attentionPackage != null && packageManager.checkPermission(
+ Manifest.permission.CAMERA, attentionPackage) == PackageManager.PERMISSION_GRANTED;
+ }
}
diff --git a/src/com/android/settings/display/AdaptiveSleepSettings.java b/src/com/android/settings/display/AdaptiveSleepSettings.java
index 4c17a67..d0f2c9a 100644
--- a/src/com/android/settings/display/AdaptiveSleepSettings.java
+++ b/src/com/android/settings/display/AdaptiveSleepSettings.java
@@ -16,10 +16,15 @@
package com.android.settings.display;
+import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.PREF;
+import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.PREF_KEY_INTERACTED;
+
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.content.SharedPreferences;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
+import android.util.Log;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
@@ -40,8 +45,15 @@
super.onCreate(icicle);
final FooterPreference footerPreference =
mFooterPreferenceMixin.createFooterPreference();
+ final Context context = getContext();
+
footerPreference.setIcon(R.drawable.ic_privacy_shield_24dp);
footerPreference.setTitle(R.string.adaptive_sleep_privacy);
+
+ context.getSharedPreferences(PREF, Context.MODE_PRIVATE)
+ .edit()
+ .putBoolean(PREF_KEY_INTERACTED, true)
+ .apply();
}
@Override
diff --git a/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java b/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java
index 86fee03..aaae076 100644
--- a/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java
+++ b/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java
@@ -64,12 +64,21 @@
.setCardName(contextualNotificationChannelSliceUri)
.setCardCategory(ContextualCard.Category.POSSIBLE)
.build();
+ final String contextualAdaptiveSleepSliceUri =
+ CustomSliceRegistry.CONTEXTUAL_ADAPTIVE_SLEEP_URI.toString();
+ final ContextualCard contextualAdaptiveSleepCard =
+ ContextualCard.newBuilder()
+ .setSliceUri(contextualAdaptiveSleepSliceUri)
+ .setCardName(contextualAdaptiveSleepSliceUri)
+ .setCardCategory(ContextualCard.Category.DEFAULT)
+ .build();
final ContextualCardList cards = ContextualCardList.newBuilder()
.addCard(wifiCard)
.addCard(connectedDeviceCard)
.addCard(lowStorageCard)
.addCard(batteryFixCard)
.addCard(notificationChannelCard)
+ .addCard(contextualAdaptiveSleepCard)
.build();
return cards;
diff --git a/src/com/android/settings/homepage/contextualcards/slices/ContextualAdaptiveSleepSlice.java b/src/com/android/settings/homepage/contextualcards/slices/ContextualAdaptiveSleepSlice.java
new file mode 100644
index 0000000..2c091fa
--- /dev/null
+++ b/src/com/android/settings/homepage/contextualcards/slices/ContextualAdaptiveSleepSlice.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2019 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.homepage.contextualcards.slices;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.display.AdaptiveSleepPreferenceController.PREF_NAME;
+import static com.android.settings.display.AdaptiveSleepPreferenceController.isControllerAvailable;
+import static com.android.settings.slices.CustomSliceRegistry.CONTEXTUAL_ADAPTIVE_SLEEP_URI;
+
+import android.app.PendingIntent;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+
+import androidx.core.graphics.drawable.IconCompat;
+import androidx.slice.Slice;
+import androidx.slice.builders.ListBuilder;
+import androidx.slice.builders.SliceAction;
+
+import com.android.settings.R;
+import com.android.settings.SubSettings;
+import com.android.settings.display.AdaptiveSleepSettings;
+import com.android.settings.slices.CustomSliceable;
+import com.android.settings.slices.SliceBuilderUtils;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import java.util.concurrent.TimeUnit;
+
+public class ContextualAdaptiveSleepSlice implements CustomSliceable {
+ private static final String TAG = "ContextualAdaptiveSleepSlice";
+ private static final long DEFAULT_SETUP_TIME = 0;
+ private Context mContext;
+
+ @VisibleForTesting
+ static final long DEFERRED_TIME_DAYS = TimeUnit.DAYS.toMillis(14);
+ @VisibleForTesting
+ static final String PREF_KEY_SETUP_TIME = "adaptive_sleep_setup_time";
+
+ public static final String PREF_KEY_INTERACTED = "adaptive_sleep_interacted";
+ public static final String PREF = "adaptive_sleep_slice";
+
+ public ContextualAdaptiveSleepSlice(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public Slice getSlice() {
+ final long setupTime = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE).getLong(
+ PREF_KEY_SETUP_TIME, DEFAULT_SETUP_TIME);
+ if (setupTime == DEFAULT_SETUP_TIME) {
+ // Set the first setup time.
+ mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE)
+ .edit()
+ .putLong(PREF_KEY_SETUP_TIME, System.currentTimeMillis())
+ .apply();
+ return null;
+ }
+
+ // Display the contextual card only if all the following 3 conditions hold:
+ // 1. The Screen Attention is enabled in Settings.
+ // 2. The device is not recently set up.
+ // 3. Current user hasn't opened Screen Attention's settings page before.
+ if (isSettingsAvailable() && !isUserInteracted() && !isRecentlySetup()) {
+ final IconCompat icon = IconCompat.createWithResource(mContext,
+ R.drawable.ic_settings_adaptive_sleep);
+ final CharSequence title = mContext.getText(R.string.adaptive_sleep_title);
+ final CharSequence subtitle = mContext.getText(R.string.adaptive_sleep_description);
+
+ final SliceAction pAction = SliceAction.createDeeplink(getPrimaryAction(),
+ icon,
+ ListBuilder.ICON_IMAGE,
+ title);
+ final ListBuilder listBuilder = new ListBuilder(mContext,
+ CONTEXTUAL_ADAPTIVE_SLEEP_URI,
+ ListBuilder.INFINITY)
+ .addRow(new ListBuilder.RowBuilder()
+ .setTitleItem(icon, ListBuilder.ICON_IMAGE)
+ .setTitle(title)
+ .setSubtitle(subtitle)
+ .setPrimaryAction(pAction));
+ return listBuilder.build();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public Uri getUri() {
+ return CONTEXTUAL_ADAPTIVE_SLEEP_URI;
+ }
+
+ @Override
+ public Intent getIntent() {
+ final CharSequence screenTitle = mContext.getText(R.string.adaptive_sleep_title);
+ final Uri contentUri = new Uri.Builder().appendPath(PREF_NAME).build();
+ return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
+ AdaptiveSleepSettings.class.getName(), PREF_NAME, screenTitle.toString(),
+ SettingsEnums.SLICE).setClassName(mContext.getPackageName(),
+ SubSettings.class.getName()).setData(contentUri);
+ }
+
+ private PendingIntent getPrimaryAction() {
+ final Intent intent = getIntent();
+ return PendingIntent.getActivity(mContext, 0 /* requestCode */, intent, 0 /* flags */);
+ }
+
+ /**
+ * @return {@code true} if the current user has opened the Screen Attention settings page
+ * before, otherwise {@code false}.
+ */
+ private boolean isUserInteracted() {
+ return mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE).getBoolean(
+ PREF_KEY_INTERACTED, false);
+ }
+
+ /**
+ * The device is recently set up means its first settings-open time is within 2 weeks ago.
+ *
+ * @return {@code true} if the device is recently set up, otherwise {@code false}.
+ */
+ private boolean isRecentlySetup() {
+ final long endTime = System.currentTimeMillis() - DEFERRED_TIME_DAYS;
+ final long firstSetupTime = mContext.getSharedPreferences(PREF,
+ Context.MODE_PRIVATE).getLong(PREF_KEY_SETUP_TIME, DEFAULT_SETUP_TIME);
+ return firstSetupTime > endTime;
+ }
+
+ /**
+ * Check whether the screen attention settings is enabled. Contextual card will only appear
+ * when the screen attention settings is available.
+ *
+ * @return {@code true} if screen attention settings is enabled, otherwise {@code false}
+ */
+ @VisibleForTesting
+ boolean isSettingsAvailable() {
+ return isControllerAvailable(mContext) == AVAILABLE;
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/network/MobileNetworkListFragment.java b/src/com/android/settings/network/MobileNetworkListFragment.java
index c90827e..4690a28 100644
--- a/src/com/android/settings/network/MobileNetworkListFragment.java
+++ b/src/com/android/settings/network/MobileNetworkListFragment.java
@@ -18,6 +18,7 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.os.UserManager;
import android.provider.SearchIndexableResource;
import com.android.settings.R;
@@ -66,5 +67,10 @@
result.add(sir);
return result;
}
+
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return context.getSystemService(UserManager.class).isAdminUser();
+ }
};
}
diff --git a/src/com/android/settings/network/telephony/DeleteSimProfileConfirmationDialog.java b/src/com/android/settings/network/telephony/DeleteSimProfileConfirmationDialog.java
deleted file mode 100644
index 13bfa92..0000000
--- a/src/com/android/settings/network/telephony/DeleteSimProfileConfirmationDialog.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2019 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.network.telephony;
-
-import android.app.Dialog;
-import android.app.settings.SettingsEnums;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.telephony.SubscriptionInfo;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.appcompat.app.AlertDialog;
-
-import com.android.settings.R;
-import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
-
-public class DeleteSimProfileConfirmationDialog extends InstrumentedDialogFragment implements
- DialogInterface.OnClickListener {
- public static final String TAG = "confirm_delete_sim";
- public static final String KEY_SUBSCRIPTION_INFO = "subscription_info";
- private SubscriptionInfo mInfo;
-
- public static DeleteSimProfileConfirmationDialog newInstance(SubscriptionInfo info) {
- final DeleteSimProfileConfirmationDialog dialog =
- new DeleteSimProfileConfirmationDialog();
- final Bundle args = new Bundle();
- args.putParcelable(KEY_SUBSCRIPTION_INFO, info);
- dialog.setArguments(args);
- return dialog;
- }
-
- @NonNull
- @Override
- public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
- mInfo = getArguments().getParcelable(KEY_SUBSCRIPTION_INFO);
- Context context = getContext();
- final String message = context.getString(R.string.mobile_network_erase_sim_dialog_body,
- mInfo.getCarrierName(), mInfo.getCarrierName());
- return new AlertDialog.Builder(context)
- .setTitle(R.string.mobile_network_erase_sim_dialog_title)
- .setMessage(message)
- .setNegativeButton(R.string.cancel, null)
- .setPositiveButton(R.string.mobile_network_erase_sim_dialog_ok, this)
- .create();
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if (which == DialogInterface.BUTTON_POSITIVE) {
- beginDeletionWithProgress();
- }
- }
-
- @VisibleForTesting
- void beginDeletionWithProgress() {
- final DeleteSimProfileProgressDialog progress =
- DeleteSimProfileProgressDialog.newInstance(mInfo.getSubscriptionId());
- progress.setTargetFragment(getTargetFragment(), 0);
- progress.show(getFragmentManager(), DeleteSimProfileProgressDialog.TAG);
- }
-
- @Override
- public int getMetricsCategory() {
- return SettingsEnums.DIALOG_DELETE_SIM_CONFIRMATION;
- }
-}
diff --git a/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceController.java b/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceController.java
index 22ff2b6..daabf8b 100644
--- a/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceController.java
+++ b/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceController.java
@@ -17,7 +17,9 @@
package com.android.settings.network.telephony;
import android.content.Context;
+import android.content.Intent;
import android.telephony.SubscriptionInfo;
+import android.telephony.euicc.EuiccManager;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
@@ -31,12 +33,13 @@
private SubscriptionInfo mSubscriptionInfo;
private Fragment mParentFragment;
+ private int mRequestCode;
public DeleteSimProfilePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
- public void init(int subscriptionId, Fragment parentFragment) {
+ public void init(int subscriptionId, Fragment parentFragment, int requestCode) {
mParentFragment = parentFragment;
for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions(
@@ -46,6 +49,7 @@
break;
}
}
+ mRequestCode = requestCode;
}
@Override
@@ -53,11 +57,10 @@
super.displayPreference(screen);
final Preference pref = screen.findPreference(getPreferenceKey());
pref.setOnPreferenceClickListener(p -> {
- final DeleteSimProfileConfirmationDialog dialogFragment =
- DeleteSimProfileConfirmationDialog.newInstance(mSubscriptionInfo);
- dialogFragment.setTargetFragment(mParentFragment, 0);
- dialogFragment.show(mParentFragment.getFragmentManager(),
- DeleteSimProfileConfirmationDialog.TAG);
+ final Intent intent = new Intent(EuiccManager.ACTION_DELETE_SUBSCRIPTION_PRIVILEGED);
+ intent.putExtra(EuiccManager.EXTRA_SUBSCRIPTION_ID,
+ mSubscriptionInfo.getSubscriptionId());
+ mParentFragment.startActivityForResult(intent, mRequestCode);
return true;
});
}
diff --git a/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialog.java b/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialog.java
deleted file mode 100644
index c176f3c..0000000
--- a/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialog.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2019 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.network.telephony;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.app.PendingIntent;
-import android.app.ProgressDialog;
-import android.app.settings.SettingsEnums;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Bundle;
-import android.telephony.euicc.EuiccManager;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import com.android.settings.R;
-import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
-
-public class DeleteSimProfileProgressDialog extends InstrumentedDialogFragment {
- public static final String TAG = "delete_sim_progress";
-
- // Note that this must be listed in AndroidManfiest.xml in a <protected-broadcast> tag
- @VisibleForTesting
- static final String PENDING_INTENT =
- "com.android.settings.DELETE_SIM_PROFILE_RESULT";
- private static final int PENDING_INTENT_REQUEST_CODE = 1;
- private static final String KEY_SUBSCRIPTION_ID = "subscription_id";
- @VisibleForTesting
- static final String KEY_DELETE_STARTED = "delete_started";
-
- private boolean mDeleteStarted;
- private BroadcastReceiver mReceiver;
-
- public static DeleteSimProfileProgressDialog newInstance(int subscriptionId) {
- final DeleteSimProfileProgressDialog dialog = new DeleteSimProfileProgressDialog();
- final Bundle args = new Bundle();
- args.putInt(KEY_SUBSCRIPTION_ID, subscriptionId);
- dialog.setArguments(args);
- return dialog;
- }
-
- @Override
- public void onSaveInstanceState(@NonNull Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putBoolean(KEY_DELETE_STARTED, mDeleteStarted);
- }
-
- @NonNull
- @Override
- public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
- if (savedInstanceState != null) {
- mDeleteStarted = savedInstanceState.getBoolean(KEY_DELETE_STARTED, false);
- }
- final Context context = getContext();
- final ProgressDialog progressDialog = new ProgressDialog(context);
- progressDialog.setMessage(
- context.getString(R.string.mobile_network_erase_sim_dialog_progress));
-
- mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- dismiss();
- final Activity activity = getActivity();
- if (activity != null && !activity.isFinishing()) {
- activity.finish();
- }
- }
- };
- context.registerReceiver(mReceiver, new IntentFilter(PENDING_INTENT));
-
- if (!mDeleteStarted) {
- final PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
- PENDING_INTENT_REQUEST_CODE, new Intent(PENDING_INTENT),
- PendingIntent.FLAG_ONE_SHOT);
-
- final EuiccManager euiccManager = context.getSystemService(EuiccManager.class);
- final int subId = getArguments().getInt(KEY_SUBSCRIPTION_ID);
- euiccManager.deleteSubscription(subId, pendingIntent);
- mDeleteStarted = true;
- }
-
- return progressDialog;
- }
-
- @Override
- public void onDismiss(@NonNull DialogInterface dialog) {
- if (mReceiver != null) {
- final Context context = getContext();
- if (context != null) {
- context.unregisterReceiver(mReceiver);
- }
- mReceiver = null;
- }
- }
-
- @Override
- public int getMetricsCategory() {
- return SettingsEnums.DIALOG_DELETE_SIM_PROGRESS;
- }
-}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index e18971d..838aa12 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -61,6 +61,7 @@
private static final String LOG_TAG = "NetworkSettings";
public static final int REQUEST_CODE_EXIT_ECM = 17;
+ public static final int REQUEST_CODE_DELETE_SUBSCRIPTION = 18;
@VisibleForTesting
static final String KEY_CLICKED_PREF = "key_clicked_pref";
@@ -138,7 +139,8 @@
use(BillingCyclePreferenceController.class).init(mSubId);
use(MmsMessagePreferenceController.class).init(mSubId);
use(DisabledSubscriptionController.class).init(getLifecycle(), mSubId);
- use(DeleteSimProfilePreferenceController.class).init(mSubId, this);
+ use(DeleteSimProfilePreferenceController.class).init(mSubId, this,
+ REQUEST_CODE_DELETE_SUBSCRIPTION);
}
use(MobileDataPreferenceController.class).init(getFragmentManager(), mSubId);
use(RoamingPreferenceController.class).init(getFragmentManager(), mSubId);
@@ -226,6 +228,13 @@
}
break;
+ case REQUEST_CODE_DELETE_SUBSCRIPTION:
+ final Activity activity = getActivity();
+ if (activity != null && !activity.isFinishing()) {
+ activity.finish();
+ }
+ break;
+
default:
break;
}
@@ -268,5 +277,11 @@
result.add(sir);
return result;
}
+
+ /** suppress full page if user is not admin */
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return context.getSystemService(UserManager.class).isAdminUser();
+ }
};
}
diff --git a/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragment.java b/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragment.java
index f7e7de5..a28fc91 100644
--- a/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragment.java
+++ b/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragment.java
@@ -19,6 +19,10 @@
import android.app.Dialog;
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Paint;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
import android.os.Bundle;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
@@ -30,7 +34,12 @@
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.Spinner;
import android.widget.TextView;
import com.android.settings.R;
@@ -42,9 +51,12 @@
import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
-/** A dialog allowing the display name of a mobile network subscription to be changed */
+/**
+ * A dialog allowing the display name of a mobile network subscription to be changed
+ */
public class RenameMobileNetworkDialogFragment extends InstrumentedDialogFragment {
- public static final String TAG ="RenameMobileNetwork";
+
+ public static final String TAG = "RenameMobileNetwork";
private static final String KEY_SUBSCRIPTION_ID = "subscription_id";
@@ -52,6 +64,8 @@
private SubscriptionManager mSubscriptionManager;
private int mSubId;
private EditText mNameView;
+ private Spinner mColorSpinner;
+ private Color[] mColors;
public static RenameMobileNetworkDialogFragment newInstance(int subscriptionId) {
final Bundle args = new Bundle(1);
@@ -76,6 +90,11 @@
return mNameView;
}
+ @VisibleForTesting
+ protected Spinner getColorSpinnerView() {
+ return mColorSpinner;
+ }
+
@Override
public void onAttach(Context context) {
super.onAttach(context);
@@ -87,6 +106,8 @@
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+ mColors = getColors();
+
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
final LayoutInflater layoutInflater = builder.getContext().getSystemService(
LayoutInflater.class);
@@ -95,13 +116,11 @@
builder.setTitle(R.string.mobile_network_sim_name)
.setView(view)
.setPositiveButton(R.string.mobile_network_sim_name_rename, (dialog, which) -> {
- SubscriptionInfo currentInfo = mSubscriptionManager.getActiveSubscriptionInfo(
+ mSubscriptionManager.setDisplayName(mNameView.getText().toString(), mSubId,
+ SubscriptionManager.NAME_SOURCE_USER_INPUT);
+ mSubscriptionManager.setIconTint(
+ mColors[mColorSpinner.getSelectedItemPosition()].getColor(),
mSubId);
- String newName = mNameView.getText().toString();
- if (currentInfo != null && !currentInfo.getDisplayName().equals(newName)) {
- mSubscriptionManager.setDisplayName(newName, mSubId,
- SubscriptionManager.NAME_SOURCE_USER_INPUT);
- }
})
.setNegativeButton(android.R.string.cancel, null);
return builder.create();
@@ -109,7 +128,7 @@
@VisibleForTesting
protected void populateView(View view) {
- mNameView = view.findViewById(R.id.edittext);
+ mNameView = view.findViewById(R.id.name_edittext);
final SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(mSubId);
if (info == null) {
Log.w(TAG, "got null SubscriptionInfo for mSubId:" + mSubId);
@@ -121,6 +140,17 @@
mNameView.setSelection(displayName.length());
}
+ mColorSpinner = view.findViewById(R.id.color_spinner);
+ final ColorAdapter adapter = new ColorAdapter(getContext(),
+ R.layout.dialog_mobile_network_color_picker_item, mColors);
+ mColorSpinner.setAdapter(adapter);
+ for (int i = 0; i < mColors.length; i++) {
+ if (mColors[i].getColor() == info.getIconTint()) {
+ mColorSpinner.setSelection(i);
+ break;
+ }
+ }
+
final TextView operatorName = view.findViewById(R.id.operator_name_value);
final ServiceState serviceState = mTelephonyManager.getServiceStateForSubscriber(mSubId);
operatorName.setText(serviceState.getOperatorAlphaLong());
@@ -138,4 +168,80 @@
public int getMetricsCategory() {
return SettingsEnums.MOBILE_NETWORK_RENAME_DIALOG;
}
+
+ private class ColorAdapter extends ArrayAdapter<Color> {
+
+ private Context mContext;
+ private int mItemResId;
+
+ public ColorAdapter(Context context, int resource, Color[] colors) {
+ super(context, resource, colors);
+ mContext = context;
+ mItemResId = resource;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final LayoutInflater inflater = (LayoutInflater)
+ mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ if (convertView == null) {
+ convertView = inflater.inflate(mItemResId, null);
+ }
+ ((ImageView) convertView.findViewById(R.id.color_icon))
+ .setImageDrawable(getItem(position).getDrawable());
+ ((TextView) convertView.findViewById(R.id.color_label))
+ .setText(getItem(position).getLabel());
+
+ return convertView;
+ }
+
+ @Override
+ public View getDropDownView(int position, View convertView, ViewGroup parent) {
+ return getView(position, convertView, parent);
+ }
+ }
+
+ private Color[] getColors() {
+ final Resources res = getContext().getResources();
+ final int[] colorInts = res.getIntArray(com.android.internal.R.array.sim_colors);
+ final String[] colorStrings = res.getStringArray(R.array.color_picker);
+ final int iconSize = res.getDimensionPixelSize(R.dimen.color_swatch_size);
+ final int strokeWidth = res.getDimensionPixelSize(R.dimen.color_swatch_stroke_width);
+ final Color[] colors = new Color[colorInts.length];
+ for (int i = 0; i < colors.length; i++) {
+ colors[i] = new Color(colorStrings[i], colorInts[i], iconSize, strokeWidth);
+ }
+ return colors;
+ }
+
+ private static class Color {
+
+ private String mLabel;
+ private int mColor;
+ private ShapeDrawable mDrawable;
+
+ private Color(String label, int color, int iconSize, int strokeWidth) {
+ mLabel = label;
+ mColor = color;
+ mDrawable = new ShapeDrawable(new OvalShape());
+ mDrawable.setIntrinsicHeight(iconSize);
+ mDrawable.setIntrinsicWidth(iconSize);
+ mDrawable.getPaint().setStrokeWidth(strokeWidth);
+ mDrawable.getPaint().setStyle(Paint.Style.FILL_AND_STROKE);
+ mDrawable.getPaint().setColor(color);
+ }
+
+ private String getLabel() {
+ return mLabel;
+ }
+
+ private int getColor() {
+ return mColor;
+ }
+
+ private ShapeDrawable getDrawable() {
+ return mDrawable;
+ }
+ }
}
diff --git a/src/com/android/settings/notification/AudioHelper.java b/src/com/android/settings/notification/AudioHelper.java
index d178113..01945fd 100644
--- a/src/com/android/settings/notification/AudioHelper.java
+++ b/src/com/android/settings/notification/AudioHelper.java
@@ -22,6 +22,7 @@
import android.media.AudioSystem;
import android.os.UserHandle;
import android.os.UserManager;
+import android.util.Log;
import com.android.settings.Utils;
@@ -30,6 +31,7 @@
*/
public class AudioHelper {
+ private static final String TAG = "AudioHelper";
private Context mContext;
private AudioManager mAudioManager;
@@ -76,6 +78,15 @@
}
public int getMinVolume(int stream) {
- return mAudioManager.getStreamMinVolume(stream);
+ int minVolume;
+ try {
+ minVolume = mAudioManager.getStreamMinVolume(stream);
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "Invalid stream type " + stream);
+ // Fallback to STREAM_VOICE_CALL because CallVolumePreferenceController.java default
+ // return STREAM_VOICE_CALL in getAudioStream
+ minVolume = mAudioManager.getStreamMinVolume(AudioManager.STREAM_VOICE_CALL);
+ }
+ return minVolume;
}
}
diff --git a/src/com/android/settings/notification/ImportancePreference.java b/src/com/android/settings/notification/ImportancePreference.java
index 0d39c8f..3e81d0c 100644
--- a/src/com/android/settings/notification/ImportancePreference.java
+++ b/src/com/android/settings/notification/ImportancePreference.java
@@ -117,11 +117,13 @@
case IMPORTANCE_LOW:
mAlertButton.setBackground(unselectedBackground);
mSilenceButton.setBackground(selectedBackground);
+ mSilenceButton.setSelected(true);
break;
case IMPORTANCE_HIGH:
default:
mSilenceButton.setBackground(unselectedBackground);
mAlertButton.setBackground(selectedBackground);
+ mAlertButton.setSelected(true);
break;
}
setImportanceSummary((ViewGroup) holder.itemView, mImportance, false);
diff --git a/src/com/android/settings/notification/NotificationButtonRelativeLayout.java b/src/com/android/settings/notification/NotificationButtonRelativeLayout.java
new file mode 100644
index 0000000..358cbf3
--- /dev/null
+++ b/src/com/android/settings/notification/NotificationButtonRelativeLayout.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2019 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.notification;
+
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.Button;
+import android.widget.RelativeLayout;
+
+public class NotificationButtonRelativeLayout extends RelativeLayout {
+
+ public NotificationButtonRelativeLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public CharSequence getAccessibilityClassName() {
+ return Button.class.getName();
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java
index fdd71e5..2a728c5 100644
--- a/src/com/android/settings/notification/NotificationSettingsBase.java
+++ b/src/com/android/settings/notification/NotificationSettingsBase.java
@@ -281,7 +281,7 @@
}
private Drawable getAlertingIcon() {
- Drawable icon = getContext().getDrawable(R.drawable.ic_notifications);
+ Drawable icon = getContext().getDrawable(R.drawable.ic_notifications_alert);
icon.setTintList(Utils.getColorAccent(getContext()));
return icon;
}
diff --git a/src/com/android/settings/notification/SnoozeNotificationPreferenceController.java b/src/com/android/settings/notification/SnoozeNotificationPreferenceController.java
new file mode 100644
index 0000000..03170e4
--- /dev/null
+++ b/src/com/android/settings/notification/SnoozeNotificationPreferenceController.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2019 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.notification;
+
+import static android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import com.android.settings.core.TogglePreferenceController;
+
+import androidx.annotation.VisibleForTesting;
+
+public class SnoozeNotificationPreferenceController extends TogglePreferenceController {
+
+ private static final String TAG = "SnoozeNotifPrefContr";
+ @VisibleForTesting
+ static final int ON = 1;
+ @VisibleForTesting
+ static final int OFF = 0;
+
+ public SnoozeNotificationPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public boolean isChecked() {
+ return Settings.Secure.getInt(mContext.getContentResolver(),
+ SHOW_NOTIFICATION_SNOOZE, OFF) == ON;
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ return Settings.Secure.putInt(mContext.getContentResolver(),
+ SHOW_NOTIFICATION_SNOOZE, isChecked ? ON : OFF);
+ }
+}
diff --git a/src/com/android/settings/privacy/EnableContentCaptureWithServiceSettingsPreferenceController.java b/src/com/android/settings/privacy/EnableContentCaptureWithServiceSettingsPreferenceController.java
index 809bfbd..77aab34 100644
--- a/src/com/android/settings/privacy/EnableContentCaptureWithServiceSettingsPreferenceController.java
+++ b/src/com/android/settings/privacy/EnableContentCaptureWithServiceSettingsPreferenceController.java
@@ -96,18 +96,23 @@
for (UserInfo info: userInfos) {
userHandles.add(info.getUserHandle());
}
-
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- UserAdapter adapter = UserAdapter.createUserAdapter(userManager, context, userHandles);
- builder.setTitle(com.android.settingslib.R.string.choose_profile)
- .setAdapter(adapter, (DialogInterface dialog, int which) -> {
- final UserHandle user = userHandles.get(which);
- // Show menu on top level items.
- final Intent intent = pref.getIntent();
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
- context.startActivityAsUser(intent, user);
- })
- .show();
+ if (userHandles.size() == 1) {
+ final Intent intent = pref.getIntent().addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ context.startActivityAsUser(intent, userHandles.get(0));
+ } else {
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ UserAdapter adapter = UserAdapter.createUserAdapter(userManager, context,
+ userHandles);
+ builder.setTitle(com.android.settingslib.R.string.choose_profile)
+ .setAdapter(adapter, (DialogInterface dialog, int which) -> {
+ final UserHandle user = userHandles.get(which);
+ // Show menu on top level items.
+ final Intent intent = pref.getIntent()
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ context.startActivityAsUser(intent, user);
+ })
+ .show();
+ }
}
}
diff --git a/src/com/android/settings/security/LockscreenBypassPreferenceController.java b/src/com/android/settings/security/LockscreenBypassPreferenceController.java
new file mode 100644
index 0000000..e347a73
--- /dev/null
+++ b/src/com/android/settings/security/LockscreenBypassPreferenceController.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 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;
+
+import android.content.Context;
+import android.hardware.face.FaceManager;
+import android.provider.Settings;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.core.TogglePreferenceController;
+
+public class LockscreenBypassPreferenceController extends TogglePreferenceController {
+
+ @VisibleForTesting
+ protected FaceManager mFaceManager;
+
+ public LockscreenBypassPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ mFaceManager = context.getSystemService(FaceManager.class);
+ }
+
+ @Override
+ public boolean isChecked() {
+ boolean defaultValue = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_faceAuthDismissesKeyguard);
+ return Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, defaultValue ? 1 : 0) != 0;
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, isChecked ? 1 : 0);
+ return true;
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
+ return mFaceManager.hasEnrolledTemplates() ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
+ } else {
+ return UNSUPPORTED_ON_DEVICE;
+ }
+ }
+}
diff --git a/src/com/android/settings/slices/CustomSliceRegistry.java b/src/com/android/settings/slices/CustomSliceRegistry.java
index dc3324b..ebfd7b3 100644
--- a/src/com/android/settings/slices/CustomSliceRegistry.java
+++ b/src/com/android/settings/slices/CustomSliceRegistry.java
@@ -26,6 +26,7 @@
import androidx.annotation.VisibleForTesting;
+import com.android.settings.display.AdaptiveSleepPreferenceController;
import com.android.settings.flashlight.FlashlightSlice;
import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
import com.android.settings.homepage.contextualcards.deviceinfo.DataUsageSlice;
@@ -34,6 +35,7 @@
import com.android.settings.homepage.contextualcards.deviceinfo.StorageSlice;
import com.android.settings.homepage.contextualcards.slices.BatteryFixSlice;
import com.android.settings.homepage.contextualcards.slices.BluetoothDevicesSlice;
+import com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice;
import com.android.settings.homepage.contextualcards.slices.ContextualNotificationChannelSlice;
import com.android.settings.homepage.contextualcards.slices.LowStorageSlice;
import com.android.settings.homepage.contextualcards.slices.NotificationChannelSlice;
@@ -65,6 +67,16 @@
.build();
/**
+ * Uri for Contextual Adaptive Sleep Slice
+ */
+ public static final Uri CONTEXTUAL_ADAPTIVE_SLEEP_URI = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_INTENT)
+ .appendPath(AdaptiveSleepPreferenceController.PREF_NAME)
+ .build();
+
+ /**
* Uri for Battery Fix Slice.
*/
public static final Uri BATTERY_FIX_SLICE_URI = new Uri.Builder()
@@ -328,6 +340,7 @@
sUriToSlice.put(BATTERY_FIX_SLICE_URI, BatteryFixSlice.class);
sUriToSlice.put(BLUETOOTH_DEVICES_SLICE_URI, BluetoothDevicesSlice.class);
+ sUriToSlice.put(CONTEXTUAL_ADAPTIVE_SLEEP_URI, ContextualAdaptiveSleepSlice.class);
sUriToSlice.put(CONTEXTUAL_NOTIFICATION_CHANNEL_SLICE_URI,
ContextualNotificationChannelSlice.class);
sUriToSlice.put(CONTEXTUAL_WIFI_SLICE_URI, ContextualWifiSlice.class);
@@ -337,12 +350,12 @@
sUriToSlice.put(FLASHLIGHT_SLICE_URI, FlashlightSlice.class);
sUriToSlice.put(LOCATION_SLICE_URI, LocationSlice.class);
sUriToSlice.put(LOW_STORAGE_SLICE_URI, LowStorageSlice.class);
+ sUriToSlice.put(MEDIA_OUTPUT_INDICATOR_SLICE_URI, MediaOutputIndicatorSlice.class);
+ sUriToSlice.put(MEDIA_OUTPUT_SLICE_URI, MediaOutputSlice.class);
sUriToSlice.put(MOBILE_DATA_SLICE_URI, MobileDataSlice.class);
sUriToSlice.put(NOTIFICATION_CHANNEL_SLICE_URI, NotificationChannelSlice.class);
sUriToSlice.put(STORAGE_SLICE_URI, StorageSlice.class);
sUriToSlice.put(WIFI_SLICE_URI, WifiSlice.class);
- sUriToSlice.put(MEDIA_OUTPUT_SLICE_URI, MediaOutputSlice.class);
- sUriToSlice.put(MEDIA_OUTPUT_INDICATOR_SLICE_URI, MediaOutputIndicatorSlice.class);
}
public static Class<? extends CustomSliceable> getSliceClassByUri(Uri uri) {
diff --git a/src/com/android/settings/slices/SlicePreferenceController.java b/src/com/android/settings/slices/SlicePreferenceController.java
index 89294c7..2432c99 100644
--- a/src/com/android/settings/slices/SlicePreferenceController.java
+++ b/src/com/android/settings/slices/SlicePreferenceController.java
@@ -40,7 +40,8 @@
LifecycleObserver, OnStart, OnStop, Observer<Slice> {
@VisibleForTesting
LiveData<Slice> mLiveData;
- private SlicePreference mSlicePreference;
+ @VisibleForTesting
+ SlicePreference mSlicePreference;
private Uri mUri;
public SlicePreferenceController(Context context, String preferenceKey) {
@@ -82,8 +83,6 @@
@Override
public void onChanged(Slice slice) {
- if (slice != null) {
- mSlicePreference.onSliceUpdated(slice);
- }
+ mSlicePreference.onSliceUpdated(slice);
}
}
diff --git a/tests/robotests/src/com/android/settings/development/WifiScanThrottlingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/WifiScanThrottlingPreferenceControllerTest.java
new file mode 100644
index 0000000..605bd0d
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/WifiScanThrottlingPreferenceControllerTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2019 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.development;
+
+import static com.android.settings.development.WifiScanThrottlingPreferenceController.SETTING_THROTTLING_ENABLE_VALUE_OFF;
+import static com.android.settings.development.WifiScanThrottlingPreferenceController.SETTING_THROTTLING_ENABLE_VALUE_ON;
+
+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 android.provider.Settings;
+
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
+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;
+
+@RunWith(RobolectricTestRunner.class)
+public class WifiScanThrottlingPreferenceControllerTest {
+
+ @Mock
+ private SwitchPreference mPreference;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+
+ private Context mContext;
+ private WifiScanThrottlingPreferenceController mController;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ mController = new WifiScanThrottlingPreferenceController(mContext);
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
+ .thenReturn(mPreference);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void onPreferenceChanged_turnOnScanThrottling() {
+ mController.onPreferenceChange(mPreference, true /* new value */);
+
+ final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.WIFI_SCAN_THROTTLE_ENABLED, 1 /* default */);
+
+ assertThat(mode).isEqualTo(SETTING_THROTTLING_ENABLE_VALUE_ON);
+ }
+
+ @Test
+ public void onPreferenceChanged_turnOffScanThrottling() {
+ mController.onPreferenceChange(mPreference, false /* new value */);
+
+ final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.WIFI_SCAN_THROTTLE_ENABLED, 1 /* default */);
+
+ assertThat(mode).isEqualTo(SETTING_THROTTLING_ENABLE_VALUE_OFF);
+ }
+
+ @Test
+ public void updateState_preferenceShouldBeChecked() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.WIFI_SCAN_THROTTLE_ENABLED,
+ SETTING_THROTTLING_ENABLE_VALUE_ON);
+ mController.updateState(mPreference);
+
+ verify(mPreference).setChecked(true);
+ }
+
+ @Test
+ public void updateState_preferenceShouldNotBeChecked() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.WIFI_SCAN_THROTTLE_ENABLED,
+ SETTING_THROTTLING_ENABLE_VALUE_OFF);
+ mController.updateState(mPreference);
+
+ verify(mPreference).setChecked(false);
+ }
+
+ @Test
+ public void onDeveloperOptionsDisabled_shouldDisablePreference() {
+ mController.onDeveloperOptionsDisabled();
+ final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.WIFI_SCAN_THROTTLE_ENABLED, 1 /* default */);
+
+ assertThat(mode).isEqualTo(SETTING_THROTTLING_ENABLE_VALUE_ON);
+ verify(mPreference).setEnabled(false);
+ verify(mPreference).setChecked(true);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/ContextualAdaptiveSleepSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/ContextualAdaptiveSleepSliceTest.java
new file mode 100644
index 0000000..54fb2c3
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/ContextualAdaptiveSleepSliceTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2019 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.homepage.contextualcards.slices;
+
+import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.DEFERRED_TIME_DAYS;
+import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.PREF;
+import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.PREF_KEY_SETUP_TIME;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+
+import androidx.slice.Slice;
+import androidx.slice.SliceProvider;
+import androidx.slice.widget.SliceLiveData;
+
+import com.android.settings.slices.CustomSliceRegistry;
+
+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;
+
+@RunWith(RobolectricTestRunner.class)
+public class ContextualAdaptiveSleepSliceTest {
+
+ private static final String pkgName = "adaptive_sleep";
+ private Context mContext;
+ private ContextualAdaptiveSleepSlice mContextualAdaptiveSleepSlice;
+ @Mock
+ private PackageManager mPackageManager;
+ @Mock
+ private SharedPreferences mSharedPreferences;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
+ mContext = spy(RuntimeEnvironment.application);
+ mContextualAdaptiveSleepSlice = spy(new ContextualAdaptiveSleepSlice(mContext));
+
+ doReturn(mPackageManager).when(mContext).getPackageManager();
+ doReturn(mSharedPreferences).when(mContext).getSharedPreferences(eq(PREF), anyInt());
+ doReturn(true).when(mContextualAdaptiveSleepSlice).isSettingsAvailable();
+ doReturn(pkgName).when(mPackageManager).getAttentionServicePackageName();
+ doReturn(-DEFERRED_TIME_DAYS).when(mSharedPreferences).getLong(eq(PREF_KEY_SETUP_TIME),
+ anyLong());
+ }
+
+ @Test
+ public void getUri_shouldReturnContextualAdaptiveSleepSliceUri() {
+ final Uri uri = mContextualAdaptiveSleepSlice.getUri();
+
+ assertThat(uri).isEqualTo(CustomSliceRegistry.CONTEXTUAL_ADAPTIVE_SLEEP_URI);
+ }
+
+ @Test
+ public void getSlice_ShowIfFeatureIsAvailable() {
+ final Slice slice = mContextualAdaptiveSleepSlice.getSlice();
+
+ assertThat(slice).isNotNull();
+ }
+
+ @Test
+ public void getSlice_DoNotShowIfFeatureIsUnavailable() {
+ doReturn(false).when(mContextualAdaptiveSleepSlice).isSettingsAvailable();
+
+ final Slice slice = mContextualAdaptiveSleepSlice.getSlice();
+
+ assertThat(slice).isNull();
+ }
+
+ @Test
+ public void getSlice_ShowIfNotRecentlySetup() {
+ final Slice slice = mContextualAdaptiveSleepSlice.getSlice();
+
+ assertThat(slice).isNotNull();
+ }
+
+ @Test
+ public void getSlice_DoNotShowIfRecentlySetup() {
+ doReturn(System.currentTimeMillis()).when(mSharedPreferences).getLong(
+ eq(PREF_KEY_SETUP_TIME), anyLong());
+
+ final Slice slice = mContextualAdaptiveSleepSlice.getSlice();
+
+ assertThat(slice).isNull();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkListFragmentTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkListFragmentTest.java
new file mode 100644
index 0000000..a65ff24
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/MobileNetworkListFragmentTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2019 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.network;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.UserManager;
+
+import com.android.settings.search.BaseSearchIndexProvider;
+
+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.util.ReflectionHelpers;
+
+
+@RunWith(RobolectricTestRunner.class)
+public class MobileNetworkListFragmentTest {
+ @Mock
+ private Context mContext;
+ @Mock
+ private UserManager mUserManager;
+
+ private MobileNetworkListFragment mFragment;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mFragment = new MobileNetworkListFragment();
+ }
+
+ @Test
+ public void isPageSearchEnabled_adminUser_shouldReturnTrue() {
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+ when(mUserManager.isAdminUser()).thenReturn(true);
+ final BaseSearchIndexProvider provider =
+ (BaseSearchIndexProvider) mFragment.SEARCH_INDEX_DATA_PROVIDER;
+
+ final Object obj = ReflectionHelpers.callInstanceMethod(provider, "isPageSearchEnabled",
+ ReflectionHelpers.ClassParameter.from(Context.class, mContext));
+ final boolean isEnabled = (Boolean) obj;
+
+ assertThat(isEnabled).isTrue();
+ }
+
+ @Test
+ public void isPageSearchEnabled_nonAdminUser_shouldReturnFalse() {
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+ when(mUserManager.isAdminUser()).thenReturn(false);
+ final BaseSearchIndexProvider provider =
+ (BaseSearchIndexProvider) mFragment.SEARCH_INDEX_DATA_PROVIDER;
+
+ final Object obj = ReflectionHelpers.callInstanceMethod(provider, "isPageSearchEnabled",
+ ReflectionHelpers.ClassParameter.from(Context.class, mContext));
+ final boolean isEnabled = (Boolean) obj;
+
+ assertThat(isEnabled).isFalse();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfileConfirmationDialogTest.java b/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfileConfirmationDialogTest.java
deleted file mode 100644
index 9b6f551..0000000
--- a/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfileConfirmationDialogTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2019 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.network.telephony;
-
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.telephony.SubscriptionInfo;
-
-import androidx.appcompat.app.AlertDialog;
-import androidx.fragment.app.FragmentActivity;
-
-import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadows.androidx.fragment.FragmentController;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = ShadowAlertDialogCompat.class)
-public class DeleteSimProfileConfirmationDialogTest {
- @Mock
- private SubscriptionInfo mSubscriptionInfo;
-
- private DeleteSimProfileConfirmationDialog mDialogFragment;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mDialogFragment = spy(DeleteSimProfileConfirmationDialog.newInstance(mSubscriptionInfo));
- doNothing().when(mDialogFragment).beginDeletionWithProgress();
- }
-
- @Test
- public void showDialog_dialogCancelled_deleteNotCalled() {
- FragmentController.setupFragment(mDialogFragment, FragmentActivity.class,
- 0 /* containerViewId */,
- null /* bundle */);
- final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
- dialog.getButton(DialogInterface.BUTTON_NEGATIVE).performClick();
- verify(mDialogFragment, never()).beginDeletionWithProgress();
- }
-
- @Test
- public void showDialog_dialogOk_deleteWasCalled() {
- FragmentController.setupFragment(mDialogFragment, FragmentActivity.class,
- 0 /* containerViewId */,
- null /* bundle */);
- final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
- dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
- verify(mDialogFragment).beginDeletionWithProgress();
- }
-}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceControllerTest.java
index 21fd19b..ca8fcf8 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceControllerTest.java
@@ -18,11 +18,15 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.eq;
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.Intent;
import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
import android.telephony.euicc.EuiccManager;
import androidx.fragment.app.Fragment;
@@ -35,6 +39,7 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
@@ -46,12 +51,12 @@
@RunWith(RobolectricTestRunner.class)
public class DeleteSimProfilePreferenceControllerTest {
private static final String PREF_KEY = "delete_profile_key";
+ private static final int REQUEST_CODE = 4321;
private static final int SUB_ID = 1234;
private static final int OTHER_ID = 5678;
@Mock
private Fragment mFragment;
-
@Mock
private SubscriptionInfo mSubscriptionInfo;
@Mock
@@ -85,27 +90,42 @@
@Test
public void getAvailabilityStatus_noSubs_notAvailable() {
SubscriptionUtil.setAvailableSubscriptionsForTesting(new ArrayList<>());
- mController.init(SUB_ID, mFragment);
+ mController.init(SUB_ID, mFragment, REQUEST_CODE);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void getAvailabilityStatus_physicalSim_notAvailable() {
when(mSubscriptionInfo.isEmbedded()).thenReturn(false);
- mController.init(SUB_ID, mFragment);
+ mController.init(SUB_ID, mFragment, REQUEST_CODE);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void getAvailabilityStatus_unknownSim_notAvailable() {
when(mSubscriptionInfo.getSubscriptionId()).thenReturn(OTHER_ID);
- mController.init(SUB_ID, mFragment);
+ mController.init(SUB_ID, mFragment, REQUEST_CODE);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void getAvailabilityStatus_knownEsim_isAvailable() {
- mController.init(SUB_ID, mFragment);
+ mController.init(SUB_ID, mFragment, REQUEST_CODE);
assertThat(mController.isAvailable()).isTrue();
}
+
+ @Test
+ public void onPreferenceClick_startsIntent() {
+ mController.init(SUB_ID, mFragment, REQUEST_CODE);
+ mController.displayPreference(mScreen);
+ mPreference.performClick();
+
+ final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mFragment).startActivityForResult(intentCaptor.capture(), eq(REQUEST_CODE));
+ final Intent intent = intentCaptor.getValue();
+ assertThat(intent.getAction()).isEqualTo(
+ EuiccManager.ACTION_DELETE_SUBSCRIPTION_PRIVILEGED);
+ assertThat(intent.getIntExtra(EuiccManager.EXTRA_SUBSCRIPTION_ID,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID)).isEqualTo(SUB_ID);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialogTest.java b/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialogTest.java
deleted file mode 100644
index aebcc46..0000000
--- a/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialogTest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2019 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.network.telephony;
-
-import static com.android.settings.network.telephony.DeleteSimProfileProgressDialog.KEY_DELETE_STARTED;
-import static com.android.settings.network.telephony.DeleteSimProfileProgressDialog.PENDING_INTENT;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.notNull;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Dialog;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Bundle;
-import android.telephony.euicc.EuiccManager;
-
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentActivity;
-
-import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = ShadowAlertDialogCompat.class)
-public class DeleteSimProfileProgressDialogTest {
- private static final int SUB_ID = 111;
-
- @Mock
- private FragmentActivity mActivity;
- @Mock
- private Fragment mTargetFragment;
- @Mock
- private EuiccManager mEuiccManager;
-
- private Context mContext;
- private DeleteSimProfileProgressDialog mDialogFragment;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mContext = spy(RuntimeEnvironment.application);
-
- when(mContext.getSystemService(EuiccManager.class)).thenReturn(mEuiccManager);
- mDialogFragment = spy(DeleteSimProfileProgressDialog.newInstance(SUB_ID));
- when(mDialogFragment.getContext()).thenReturn(mContext);
- when(mDialogFragment.getTargetFragment()).thenReturn(mTargetFragment);
- when(mDialogFragment.getActivity()).thenReturn(mActivity);
- }
-
- @Test
- public void onCreateDialog_firstShowing_deleteStartedAndRecordedInOutState() {
- mDialogFragment.onCreateDialog(null);
- verify(mEuiccManager).deleteSubscription(eq(SUB_ID), notNull());
-
- final Bundle outState = new Bundle();
- mDialogFragment.onSaveInstanceState(outState);
- assertThat(outState.containsKey(KEY_DELETE_STARTED)).isTrue();
- assertThat(outState.getBoolean(KEY_DELETE_STARTED)).isTrue();
- }
-
- @Test
- public void showDialog_secondShowing_deleteNotStarted() {
- final Bundle inState = new Bundle();
- inState.putBoolean(KEY_DELETE_STARTED, true);
- mDialogFragment.onCreateDialog(inState);
-
- verify(mEuiccManager, never()).deleteSubscription(anyInt(), any());
-
- final Bundle outState = new Bundle();
- mDialogFragment.onSaveInstanceState(outState);
- assertThat(outState.containsKey(KEY_DELETE_STARTED)).isTrue();
- assertThat(outState.getBoolean(KEY_DELETE_STARTED)).isTrue();
- }
-
- @Test
- public void showDialog_pendingIntentReceiverFired_activityFinished() {
- mDialogFragment.onCreateDialog(null);
-
- final ArgumentCaptor<PendingIntent> intentCaptor = ArgumentCaptor.forClass(
- PendingIntent.class);
- verify(mEuiccManager).deleteSubscription(eq(SUB_ID), intentCaptor.capture());
- assertThat(intentCaptor.getValue()).isNotNull();
-
- final ArgumentCaptor<BroadcastReceiver> receiverCaptor = ArgumentCaptor.forClass(
- BroadcastReceiver.class);
- verify(mContext).registerReceiver(receiverCaptor.capture(), any(IntentFilter.class));
-
- doNothing().when(mDialogFragment).dismiss();
- receiverCaptor.getValue().onReceive(mContext, new Intent(PENDING_INTENT));
- verify(mDialogFragment).dismiss();
- verify(mActivity).finish();
- }
-
- @Test
- public void onDismiss_receiverUnregistered() {
- Dialog dialog = mDialogFragment.onCreateDialog(null);
- final ArgumentCaptor<BroadcastReceiver> receiverCaptor = ArgumentCaptor.forClass(
- BroadcastReceiver.class);
- verify(mContext).registerReceiver(receiverCaptor.capture(), any(IntentFilter.class));
-
- mDialogFragment.onDismiss(dialog);
- verify(mContext).unregisterReceiver(eq(receiverCaptor.getValue()));
- }
-}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java
index 011bca5..4afe0fc 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java
@@ -16,17 +16,21 @@
package com.android.settings.network.telephony;
+import static com.android.settings.network.telephony.MobileNetworkSettings.REQUEST_CODE_DELETE_SUBSCRIPTION;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
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.app.usage.NetworkStatsManager;
import android.content.Context;
import android.net.NetworkPolicyManager;
import android.os.Bundle;
+import android.os.UserManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
@@ -35,6 +39,7 @@
import com.android.settings.core.FeatureFlags;
import com.android.settings.datausage.DataUsageSummaryPreferenceController;
import com.android.settings.development.featureflags.FeatureFlagPersistent;
+import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -47,6 +52,7 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
import java.util.List;
@@ -80,6 +86,7 @@
args.putInt(Settings.EXTRA_SUB_ID, subscriptionId);
mFragment.setArguments(args);
when(mFragment.getActivity()).thenReturn(mActivity);
+ when(mActivity.isFinishing()).thenReturn(false);
when(mActivity.getSystemService(NetworkPolicyManager.class)).thenReturn(
mNetworkPolicyManager);
}
@@ -118,4 +125,47 @@
.count())
.isEqualTo(1);
}
+
+ @Test
+ public void onActivityResult_noActivity_noCrash() {
+ when(mFragment.getActivity()).thenReturn(null);
+ // this should not crash
+ mFragment.onActivityResult(REQUEST_CODE_DELETE_SUBSCRIPTION, 0, null);
+ }
+
+ @Test
+ public void onActivityResult_deleteSubscription_activityFinishes() {
+ mFragment.onActivityResult(REQUEST_CODE_DELETE_SUBSCRIPTION, 0, null);
+ verify(mActivity).finish();
+ }
+
+ @Test
+ public void isPageSearchEnabled_adminUser_shouldReturnTrue() {
+ final UserManager userManager = mock(UserManager.class);
+ when(mContext.getSystemService(UserManager.class)).thenReturn(userManager);
+ when(userManager.isAdminUser()).thenReturn(true);
+ final BaseSearchIndexProvider provider =
+ (BaseSearchIndexProvider) mFragment.SEARCH_INDEX_DATA_PROVIDER;
+
+ final Object obj = ReflectionHelpers.callInstanceMethod(provider, "isPageSearchEnabled",
+ ReflectionHelpers.ClassParameter.from(Context.class, mContext));
+ final boolean isEnabled = (Boolean) obj;
+
+ assertThat(isEnabled).isTrue();
+ }
+
+ @Test
+ public void isPageSearchEnabled_nonAdminUser_shouldReturnFalse() {
+ final UserManager userManager = mock(UserManager.class);
+ when(mContext.getSystemService(UserManager.class)).thenReturn(userManager);
+ when(userManager.isAdminUser()).thenReturn(false);
+ final BaseSearchIndexProvider provider =
+ (BaseSearchIndexProvider) mFragment.SEARCH_INDEX_DATA_PROVIDER;
+
+ final Object obj = ReflectionHelpers.callInstanceMethod(provider, "isPageSearchEnabled",
+ ReflectionHelpers.ClassParameter.from(Context.class, mContext));
+ final boolean isEnabled = (Boolean) obj;
+
+ assertThat(isEnabled).isFalse();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragmentTest.java b/tests/robotests/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragmentTest.java
index 5b008be..53b4f00 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragmentTest.java
@@ -30,6 +30,7 @@
import static org.mockito.Mockito.when;
import android.content.DialogInterface;
+import android.graphics.Color;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
@@ -38,6 +39,7 @@
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
+import android.widget.Spinner;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity;
@@ -58,6 +60,7 @@
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowAlertDialogCompat.class)
public class RenameMobileNetworkDialogFragmentTest {
+
@Mock
private TelephonyManager mTelephonyMgr;
@Mock
@@ -95,7 +98,7 @@
}
@Test
- public void dialog_cancelButtonClicked_setDisplayNameNotCalled() {
+ public void dialog_cancelButtonClicked_setDisplayNameAndIconTintNotCalled() {
when(mSubscriptionMgr.getActiveSubscriptionInfo(mSubscriptionId)).thenReturn(
mSubscriptionInfo);
final AlertDialog dialog = startDialog();
@@ -106,10 +109,11 @@
negativeButton.performClick();
verify(mSubscriptionMgr, never()).setDisplayName(anyString(), anyInt(), anyInt());
+ verify(mSubscriptionMgr, never()).setIconTint(anyInt(), anyInt());
}
@Test
- public void dialog_renameButtonClicked_setDisplayNameCalled() {
+ public void dialog_saveButtonClicked_setDisplayNameAndIconTint() {
when(mSubscriptionMgr.getActiveSubscriptionInfo(mSubscriptionId)).thenReturn(
mSubscriptionInfo);
@@ -117,6 +121,9 @@
final EditText nameView = mFragment.getNameView();
nameView.setText("test2");
+ final Spinner colorSpinnerView = mFragment.getColorSpinnerView();
+ colorSpinnerView.setSelection(0);
+
final Button positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
positiveButton.performClick();
@@ -124,6 +131,8 @@
verify(mSubscriptionMgr).setDisplayName(captor.capture(), eq(mSubscriptionId),
eq(SubscriptionManager.NAME_SOURCE_USER_INPUT));
assertThat(captor.getValue()).isEqualTo("test2");
+ verify(mSubscriptionMgr)
+ .setIconTint(eq(Color.parseColor("#ff00796b" /* teal */)), eq(mSubscriptionId));
}
@Test
@@ -140,7 +149,9 @@
assertThat(view.findViewById(R.id.number_label).getVisibility()).isEqualTo(View.GONE);
}
- /** Helper method to start the dialog */
+ /**
+ * Helper method to start the dialog
+ */
private AlertDialog startDialog() {
mFragment.show(mActivity.getSupportFragmentManager(), null);
return ShadowAlertDialogCompat.getLatestAlertDialog();
diff --git a/tests/robotests/src/com/android/settings/notification/AudioHelperTest.java b/tests/robotests/src/com/android/settings/notification/AudioHelperTest.java
new file mode 100644
index 0000000..79d0198
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/AudioHelperTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 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.notification;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class AudioHelperTest {
+
+ private static final int START = -10;
+ private static final int END = 10;
+ private static final int DEFAULT = -100;
+
+ private Context mContext;
+ private AudioHelper mAudioHelper;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ mAudioHelper = new AudioHelper(mContext);
+ }
+
+ @Test
+ public void getMaxVolume_anyStreamType_getValue() {
+ int volume = DEFAULT;
+
+ for (int i = START; i < END; i++) {
+ volume = mAudioHelper.getMaxVolume(i);
+ assertThat(volume).isNotEqualTo(DEFAULT);
+ }
+ }
+
+ @Test
+ public void getMinVolume_anyStreamType_getValue() {
+ int volume = DEFAULT;
+
+ for (int i = START; i < END; i++) {
+ volume = mAudioHelper.getMinVolume(i);
+ assertThat(volume).isNotEqualTo(DEFAULT);
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/SnoozeNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/SnoozeNotificationPreferenceControllerTest.java
new file mode 100644
index 0000000..6779ff1
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/SnoozeNotificationPreferenceControllerTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2019 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.notification;
+
+import static android.provider.Settings.Secure.NOTIFICATION_BADGING;
+import static android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE;
+
+import static com.android.settings.notification.BadgingNotificationPreferenceController.OFF;
+import static com.android.settings.notification.BadgingNotificationPreferenceController.ON;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.TwoStatePreference;
+
+@RunWith(RobolectricTestRunner.class)
+public class SnoozeNotificationPreferenceControllerTest {
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mContext;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private PreferenceScreen mScreen;
+
+ private SnoozeNotificationPreferenceController mController;
+ private Preference mPreference;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mController = new SnoozeNotificationPreferenceController(mContext,
+ "key");
+ mPreference = new Preference(RuntimeEnvironment.application);
+ mPreference.setKey(mController.getPreferenceKey());
+ when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
+ }
+
+ @Test
+ public void display_configIsTrue_shouldDisplay() {
+ mController.displayPreference(mScreen);
+ assertThat(mPreference.isVisible()).isTrue();
+ }
+
+ @Test
+ public void isChecked_settingIsOff_shouldReturnFalse() {
+ Settings.Secure.putInt(mContext.getContentResolver(), SHOW_NOTIFICATION_SNOOZE, OFF);
+
+ assertThat(mController.isChecked()).isFalse();
+ }
+
+ @Test
+ public void isChecked_settingIsOn_shouldReturnTrue() {
+ Settings.Secure.putInt(mContext.getContentResolver(), SHOW_NOTIFICATION_SNOOZE, ON);
+
+ assertThat(mController.isChecked()).isTrue();
+ }
+
+ @Test
+ public void setChecked_setFalse_disablesSetting() {
+ Settings.Secure.putInt(mContext.getContentResolver(), SHOW_NOTIFICATION_SNOOZE, ON);
+
+ mController.setChecked(false);
+ int updatedValue = Settings.Secure.getInt(mContext.getContentResolver(),
+ SHOW_NOTIFICATION_SNOOZE, -1);
+
+ assertThat(updatedValue).isEqualTo(OFF);
+ }
+
+ @Test
+ public void setChecked_setTrue_enablesSetting() {
+ Settings.Secure.putInt(mContext.getContentResolver(), SHOW_NOTIFICATION_SNOOZE, OFF);
+
+ mController.setChecked(true);
+ int updatedValue = Settings.Secure.getInt(mContext.getContentResolver(),
+ SHOW_NOTIFICATION_SNOOZE, -1);
+
+ assertThat(updatedValue).isEqualTo(ON);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/security/LockscreenBypassPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/LockscreenBypassPreferenceControllerTest.java
new file mode 100644
index 0000000..1b8817b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/security/LockscreenBypassPreferenceControllerTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.hardware.face.FaceManager;
+import android.provider.Settings;
+
+import androidx.preference.SwitchPreference;
+
+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.util.ReflectionHelpers;
+
+@RunWith(RobolectricTestRunner.class)
+public class LockscreenBypassPreferenceControllerTest {
+
+ @Mock
+ private FaceManager mFaceManager;
+ private SwitchPreference mPreference;
+
+ private Context mContext;
+ private LockscreenBypassPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ mPreference = new SwitchPreference(mContext);
+
+ mController = new LockscreenBypassPreferenceController(mContext, "TestKey");
+ ReflectionHelpers.setField(mController, "mFaceManager", mFaceManager);
+ }
+
+ @Test
+ public void isAvailable_whenHardwareDetected() {
+ assertThat(mController.isAvailable()).isFalse();
+ when(mFaceManager.isHardwareDetected()).thenReturn(true);
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void onPreferenceChange_settingIsUpdated() {
+ boolean defaultValue = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_faceAuthDismissesKeyguard);
+ boolean state = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, defaultValue ? 1 : 0) != 0;
+
+ assertThat(mController.onPreferenceChange(mPreference, !state)).isTrue();
+ boolean newState = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, 0) != 0;
+ assertThat(newState).isEqualTo(!state);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/slices/SlicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/slices/SlicePreferenceControllerTest.java
index 364fb60..65eaddd 100644
--- a/tests/robotests/src/com/android/settings/slices/SlicePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SlicePreferenceControllerTest.java
@@ -41,6 +41,8 @@
@Mock
private LiveData<Slice> mLiveData;
+ @Mock
+ private SlicePreference mSlicePreference;
private Context mContext;
private SlicePreferenceController mController;
private Uri mUri;
@@ -53,6 +55,7 @@
mContext = spy(RuntimeEnvironment.application);
mController = new SlicePreferenceController(mContext, KEY);
mController.mLiveData = mLiveData;
+ mController.mSlicePreference = mSlicePreference;
mUri = Uri.EMPTY;
}
@@ -78,4 +81,11 @@
mController.onStop();
verify(mLiveData).removeObserver(mController);
}
+
+ @Test
+ public void onChanged_nullSlice_updateSlice() {
+ mController.onChanged(null);
+
+ verify(mController.mSlicePreference).onSliceUpdated(null);
+ }
}
\ No newline at end of file