Merge "Fix the Easter egg invocation gesture nonfunctional."
diff --git a/protos/contextual_card_list.proto b/protos/contextual_card_list.proto
index 69c3741..54e5654 100644
--- a/protos/contextual_card_list.proto
+++ b/protos/contextual_card_list.proto
@@ -19,6 +19,7 @@
POSSIBLE = 2;
IMPORTANT = 3;
DEFERRED_SETUP = 5;
+ STICKY = 6;
}
/** Slice uri of the contextual card */
diff --git a/res/drawable/ic_add_blue_24dp.xml b/res/drawable/ic_add_blue_24dp.xml
new file mode 100644
index 0000000..a9a2f60
--- /dev/null
+++ b/res/drawable/ic_add_blue_24dp.xml
@@ -0,0 +1,26 @@
+<!--
+ Copyright (C) 2020 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="#4285F4"
+ android:pathData="M20,13h-7v7h-2v-7H4v-2h7V4h2v7h7V13z"/>
+</vector>
+
diff --git a/res/drawable/ic_analytics_grey.xml b/res/drawable/ic_analytics_grey.xml
new file mode 100644
index 0000000..f0bbdb9
--- /dev/null
+++ b/res/drawable/ic_analytics_grey.xml
@@ -0,0 +1,21 @@
+<!--
+ ~ Copyright (C) 2020 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 android:autoMirrored="true" android:height="24dp"
+ android:viewportHeight="24" android:viewportWidth="24"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="#757575" android:pathData="M19,3L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM9,17L7,17v-5h2v5zM13,17h-2v-3h2v3zM13,12h-2v-2h2v2zM17,17h-2L15,7h2v10z"/>
+</vector>
diff --git a/res/drawable/ic_check_box_anim.xml b/res/drawable/ic_check_box_anim.xml
new file mode 100644
index 0000000..f6aed8f
--- /dev/null
+++ b/res/drawable/ic_check_box_anim.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright (C) 2020 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
+ -->
+
+<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/checked"
+ android:state_checked="true"
+ android:drawable="@drawable/ic_check_box_blue_24dp" />
+ <item
+ android:id="@+id/unchecked"
+ android:drawable="@drawable/ic_check_box_outline_24dp" />
+</animated-selector>
diff --git a/res/drawable/ic_check_box_blue_24dp.xml b/res/drawable/ic_check_box_blue_24dp.xml
new file mode 100644
index 0000000..43cae69
--- /dev/null
+++ b/res/drawable/ic_check_box_blue_24dp.xml
@@ -0,0 +1,26 @@
+<!--
+ Copyright (C) 2020 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:pathData="M19,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.11,0 2,-0.9 2,-2L21,5c0,-1.1 -0.89,-2 -2,-2zM10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z"
+ android:fillColor="#4285F4"/>
+</vector>
+
diff --git a/res/drawable/ic_check_box_outline_24dp.xml b/res/drawable/ic_check_box_outline_24dp.xml
new file mode 100644
index 0000000..f6f453a
--- /dev/null
+++ b/res/drawable/ic_check_box_outline_24dp.xml
@@ -0,0 +1,26 @@
+<!--
+ Copyright (C) 2020 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:pathData="M19,5v14H5V5h14m0,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2z"
+ android:fillColor="#757575"/>
+</vector>
+
diff --git a/res/drawable/ic_speaker_group_black_24dp.xml b/res/drawable/ic_speaker_group_black_24dp.xml
new file mode 100644
index 0000000..ae0d562
--- /dev/null
+++ b/res/drawable/ic_speaker_group_black_24dp.xml
@@ -0,0 +1,31 @@
+<!--
+ Copyright (C) 2020 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:pathData="M18.2,1L9.8,1C8.81,1 8,1.81 8,2.8v14.4c0,0.99 0.81,1.79 1.8,1.79l8.4,0.01c0.99,0 1.8,-0.81 1.8,-1.8L20,2.8c0,-0.99 -0.81,-1.8 -1.8,-1.8zM14,3c1.1,0 2,0.89 2,2s-0.9,2 -2,2 -2,-0.89 -2,-2 0.9,-2 2,-2zM14,16.5c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4 4,1.79 4,4 -1.79,4 -4,4z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M14,12.5m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M6,5H4v16c0,1.1 0.89,2 2,2h10v-2H6V5z"
+ android:fillColor="#000000"/>
+</vector>
diff --git a/res/drawable/ic_storage_grey.xml b/res/drawable/ic_storage_grey.xml
new file mode 100644
index 0000000..420aba8
--- /dev/null
+++ b/res/drawable/ic_storage_grey.xml
@@ -0,0 +1,21 @@
+<!--
+ ~ Copyright (C) 2020 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 android:autoMirrored="true" android:height="24dp"
+ android:viewportHeight="24" android:viewportWidth="24"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="#757575" android:pathData="M2,20h20v-4L2,16v4zM4,17h2v2L4,19v-2zM2,4v4h20L22,4L2,4zM6,7L4,7L4,5h2v2zM2,14h20v-4L2,10v4zM4,11h2v2L4,13v-2z"/>
+</vector>
diff --git a/res/layout/accessibility_autoclick_custom_seekbar.xml b/res/layout/accessibility_autoclick_custom_seekbar.xml
index 0a60cff..283530b 100644
--- a/res/layout/accessibility_autoclick_custom_seekbar.xml
+++ b/res/layout/accessibility_autoclick_custom_seekbar.xml
@@ -31,12 +31,12 @@
android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.TextView" />
<LinearLayout
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<ImageView
- android:id="@+id/smaller"
+ android:id="@+id/shorter"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
@@ -49,12 +49,13 @@
<SeekBar
android:id="@+id/autoclick_delay"
- android:layout_width="260dp"
+ android:layout_width="0dp"
android:layout_height="48dp"
+ android:layout_weight="1"
android:contentDescription="@string/accessibility_autoclick_seekbar_desc" />
<ImageView
- android:id="@+id/larger"
+ android:id="@+id/longer"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
diff --git a/res/layout/interact_across_profiles_consent_dialog.xml b/res/layout/interact_across_profiles_consent_dialog.xml
new file mode 100644
index 0000000..6052508
--- /dev/null
+++ b/res/layout/interact_across_profiles_consent_dialog.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2020 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.
+ -->
+
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/interact_across_profiles_dialog_layout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="24dp"
+ android:paddingEnd="24dp"
+ android:orientation="horizontal">
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <LinearLayout
+ android:id="@+id/interact_across_profiles_dialog"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:gravity="start"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/interact_across_profiles_consent_dialog_title"
+ android:text="@string/interact_across_profiles_consent_dialog_title"
+ style="@style/CrossProfileConsentDialogTitle"/>
+
+ <TextView
+ android:id="@+id/interact_across_profiles_consent_dialog_summary"
+ android:text="@string/interact_across_profiles_consent_dialog_summary"
+ style="@style/CrossProfileConsentDialogDescription"/>
+
+ <LinearLayout
+ android:id="@+id/app_data_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingBottom="16pt"
+ android:gravity="start"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/app_data_icon"
+ android:src="@drawable/ic_analytics_grey"
+ style="@style/CrossProfileConsentDialogIcon"/>
+
+ <LinearLayout
+ android:id="@+id/app_data_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingStart="16dp"
+ android:gravity="start"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/app_data_title"
+ android:text="@string/interact_across_profiles_consent_dialog_app_data_title"
+ style="@style/CrossProfileConsentDialogSubTitle"/>
+
+ <TextView
+ android:id="@+id/app_data_summary"
+ android:text="@string/interact_across_profiles_consent_dialog_app_data_summary"
+ style="@style/CrossProfileConsentDialogSubDescription"/>
+ </LinearLayout>
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/permissions_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="start"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/permissions_icon"
+ android:src="@drawable/ic_storage_grey"
+ style="@style/CrossProfileConsentDialogIcon"/>
+
+ <LinearLayout
+ android:id="@+id/permissions_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="start"
+ android:paddingStart="16dp"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/permissions_title"
+ android:text="@string/interact_across_profiles_consent_dialog_permissions_title"
+ style="@style/CrossProfileConsentDialogSubTitle"/>
+
+ <TextView
+ android:id="@+id/permissions_summary"
+ android:text="@string/interact_across_profiles_consent_dialog_permissions_summary"
+ style="@style/CrossProfileConsentDialogSubDescription"/>
+ </LinearLayout>
+ </LinearLayout>
+ </LinearLayout>
+ </ScrollView>
+</RelativeLayout>
diff --git a/res/layout/notification_history.xml b/res/layout/notification_history.xml
index a97afb6..b3308c5 100644
--- a/res/layout/notification_history.xml
+++ b/res/layout/notification_history.xml
@@ -19,8 +19,7 @@
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:id="@+id/scroll"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@*android:color/material_grey_50">
+ android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
@@ -100,17 +99,13 @@
android:layout_height="wrap_content"
android:clipChildren="true"
android:elevation="3dp"
- android:background="@drawable/rounded_bg"
- settings:layout_constraintHeight_max="200dp"
- settings:layout_constrainedHeight="true">
+ android:background="@drawable/rounded_bg">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/notification_list"
android:layout_width="match_parent"
- android:layout_height="0dp"
+ android:layout_height="wrap_content"
android:clipChildren="true"
- settings:layout_constraintHeight_max="300dp"
- settings:layout_constrainedHeight="true"
settings:fastScrollEnabled="true"
settings:fastScrollHorizontalThumbDrawable="@drawable/thumb_drawable"
settings:fastScrollHorizontalTrackDrawable="@drawable/line_drawable"
@@ -144,10 +139,8 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/notification_list"
android:layout_width="match_parent"
- android:layout_height="0dp"
+ android:layout_height="wrap_content"
android:clipChildren="true"
- settings:layout_constraintHeight_max="300dp"
- settings:layout_constrainedHeight="true"
settings:fastScrollEnabled="true"
settings:fastScrollHorizontalThumbDrawable="@drawable/thumb_drawable"
settings:fastScrollHorizontalTrackDrawable="@drawable/line_drawable"
diff --git a/res/layout/palette_listview_item.xml b/res/layout/palette_listview_item.xml
index e8cc940..3342ef1 100644
--- a/res/layout/palette_listview_item.xml
+++ b/res/layout/palette_listview_item.xml
@@ -22,10 +22,12 @@
<TextView
android:id="@+id/item_textview"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="10dp"
- android:textSize="20dp"
+ android:layout_height="42dp"
+ android:fontFamily="roboto-bold"
+ android:gravity="center_vertical"
android:maxLength="20"
- android:singleLine="true"/>
+ android:paddingLeft="@dimen/accessibility_layout_margin_start_end"
+ android:singleLine="true"
+ android:textSize="14dp" />
</FrameLayout>
diff --git a/res/layout/zen_mode_settings_button.xml b/res/layout/zen_mode_settings_button.xml
index 14fe644..49aa287 100644
--- a/res/layout/zen_mode_settings_button.xml
+++ b/res/layout/zen_mode_settings_button.xml
@@ -23,13 +23,6 @@
android:paddingVertical="@dimen/zen_mode_button_padding_vertical">
<TextView
- android:text="@string/zen_mode_settings_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/screen_margin_sides"
- android:textAppearance="@android:style/TextAppearance.DeviceDefault.Large"/>
-
- <TextView
android:text="@string/zen_mode_settings_summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/res/values/config.xml b/res/values/config.xml
index 42bc0d6..2373b25 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -206,6 +206,9 @@
com.android.settings.intelligence
</string>
+ <!-- Whether the confirmation for sim deletion is defaulted to be on or off-->
+ <bool name="config_sim_deletion_confirmation_default_on">false</bool>
+
<!-- Package Installer package name -->
<string name="config_package_installer_package_name" translatable="false">
com.android.packageinstaller
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index f79874c..024569b 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -82,6 +82,7 @@
<dimen name="notification_importance_button_padding">14dp</dimen>
<dimen name="notification_history_header_drawable_start">26dp</dimen>
+ <dimen name="conversation_icon_size">48dp</dimen>
<dimen name="zen_mode_button_padding_vertical">16dp</dimen>
<dimen name="zen_schedule_rule_checkbox_padding">7dp</dimen>
@@ -266,7 +267,7 @@
<dimen name="message_metadata_top_padding">4dp</dimen>
<!-- Accessibility Settings -->
- <dimen name="accessibility_layout_margin_start_end">24dp</dimen>
+ <dimen name="accessibility_layout_margin_start_end">16dp</dimen>
<dimen name="accessibility_button_preference_padding_top_bottom">18dp</dimen>
<!-- Accessibility, Screen magnification. These values are meant to be relative values and the actual layout value will be set programmatically. -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c32d557..ac77cc5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3750,7 +3750,29 @@
<!-- Tethering controls, footer note displayed when tethering is disabled because Data Saver mode is on [CHAR LIMIT=none]-->
<string name="tether_settings_disabled_on_data_saver">"Can\u2019t tether or use portable hotspots while Data Saver is on"</string>
+ <!-- Tethering setting summary when only Wi-Fi hotspot is on [CHAR LIMIT=NONE]-->
+ <string name="tether_settings_summary_hotspot_only">Hotspot only</string>
+ <!-- Tethering setting summary when only USB tethering is on [CHAR LIMIT=NONE]-->
+ <string name="tether_settings_summary_usb_tethering_only">USB only</string>
+ <!-- Tethering setting summary when only Bluetooth tethering is on [CHAR LIMIT=NONE]-->
+ <string name="tether_settings_summary_bluetooth_tethering_only">Bluetooth only</string>
+ <!-- Tethering setting summary when Wi-Fi hotspot and USB tethering are on [CHAR LIMIT=NONE]-->
+ <string name="tether_settings_summary_hotspot_and_usb">Hotspot, USB</string>
+ <!-- Tethering setting summary when Wi-Fi hotspot and Bluetooth tethering are on [CHAR LIMIT=NONE]-->
+ <string name="tether_settings_summary_hotspot_and_bluetooth">Hotspot, Bluetooth</string>
+ <!-- Tethering setting summary when USB and Bluetooth tethering are on [CHAR LIMIT=NONE]-->
+ <string name="tether_settings_summary_usb_and_bluetooth">USB, Bluetooth</string>
+ <!-- Tethering setting summary when Wi-Fi hotspot and USB and Bluetooth tethering are on [CHAR LIMIT=NONE]-->
+ <string name="tether_settings_summary_hotspot_and_usb_and_bluetooth">Hotspot, USB, Bluetooth</string>
+ <!-- Tethering setting summary when hotspot and tethering are off [CHAR LIMIT=NONE]-->
+ <string name="tether_settings_summary_off">Not sharing internet with other devices</string>
+
+ <!-- Tethering interface options [CHAR LIMIT=NONE]-->
+ <string name="tethering_interface_options">Tethering</string>
+
<!-- Disable Wifi Hotspot option-->
+ <!-- Don't use Wi-Fi hotspot title [CHAR LIMIT=NONE]-->
+ <string name="disable_wifi_hotspot_title">Don\u2019t use Wi\u2011Fi hotspot</string>
<!-- Don't use Wi-Fi hotspot summary when USB tethering is chosen [CHAR LIMIT=NONE]-->
<string name="disable_wifi_hotspot_when_usb_on">Only share internet via USB</string>
<!-- Don't use Wi-Fi hotspot summary when Bluetooth tethering is chosen [CHAR LIMIT=NONE]-->
@@ -4830,7 +4852,7 @@
<!-- Short summary for nav bar Magnification. Tells the user that this feature allows the user to magnify the screen using a button in the nav bar -->
<string name="accessibility_screen_magnification_navbar_short_summary">Tap a button to zoom</string>
<!-- Summary for the accessibility preference screen to enable screen magnification gestures. [CHAR LIMIT=none] -->
- <string name="accessibility_screen_magnification_summary">Quickly zoom in on the screen to see content more clearly.\n\n<b>To zoom in:</b>\n\t1. Use shortcut to start magnification\n\t2. Tap the screen\n\t3. Drag 2 fingers to move around screen\n\t4. Pinch with 2 fingers to adjust zoom\n\t5. Use shortcut to stop magnification</string>
+ <string name="accessibility_screen_magnification_summary"><![CDATA[Quickly zoom in on the screen to see content more clearly.<br/><br/><b>To zoom in:</b><br/>\t1. Use shortcut to start magnification<br/>\t2. Tap the screen<br/>\t3. Drag 2 fingers to move around screen<br/>\t4. Pinch with 2 fingers to adjust zoom<br/>\t5. Use shortcut to stop magnification<br/><br/><b>To zoom in temporarily:</b><br/>\t1. Use shortcut to start magnification<br/>\t2. Touch & hold anywhere on the screen<br/>\t3. Drag finger to move around screen<br/>\t4. Lift finger to stop magnification]]></string>
<!-- Summary for the accessibility preference screen to enable screen magnification via the nav bar. [CHAR LIMIT=none] -->
<string name="accessibility_screen_magnification_navbar_summary">When magnification is turned on, you can zoom in on your screen.\n\n<b>To zoom</b>, start magnification, then tap anywhere on the screen.\n<ul><li>Drag 2 or more fingers to scroll</li>\n<li>Pinch 2 or more fingers to adjust zoom</li></ul>\n\n<b>To zoom temporarily</b>, start magnification, then touch & hold anywhere on the screen.\n<ul><li>Drag to move around the screen</li>\n<li>Lift finger to zoom out</li></ul>\n\nYou can’t zoom in on the keyboard or navigation bar.</string>
<!-- Title for the Accessibility tutorial dialog in Accessibility service with button. [CHAR LIMIT=50] -->
@@ -4940,12 +4962,12 @@
<!-- Used in the accessibility service settings to control turning display color inversion on/off entirely. [CHAR LIMIT=NONE] -->
<string name="accessibility_display_inversion_switch_title">Use color inversion</string>
<!-- Subtitle for the accessibility preference to configure display color inversion. [CHAR LIMIT=NONE] -->
- <string name="accessibility_display_inversion_preference_subtitle">Color inversion turns light screens dark. This helps people who are sensitive to bright light see the screen more easily.\n\nNote: Dark colors will turn light. Colors will change in media and images. You can also use Dark theme (Settings > Display).</string>
+ <string name="accessibility_display_inversion_preference_subtitle"><![CDATA[Color inversion turns light screens dark. This helps people who are sensitive to bright light see the screen more easily.<br/><br/>Note: Dark colors will turn light. Colors will change in media and images. You can also use Dark theme (Settings > Display).]]></string>
<!-- Title for accessibility preference for configuring feature that performs click action soon after mouse/trackpad pointer stops moving. [CHAR LIMIT=NONE] -->
<string name="accessibility_autoclick_preference_title">Auto click (dwell timing)</string>
<!-- Footer text to explain what autoclick does -->
<string name="accessibility_autoclick_description">If you are using a mouse, you can set the cursor to take action automatically when it stops moving for a certain amount of time.</string>
- <!-- Option heading to leave the auto click requirement for accessibility users at its default level. [CHAR LIMIT=35] -->
+ <!-- Option heading to leave the auto click requirement for accessibility users at its default level. [CHAR LIMIT=50] -->
<string name="accessibility_autoclick_default_title">Don\u2019t use auto click (default)</string>
<!-- Option heading to leave the auto click requirement for accessibility users at its short level. [CHAR LIMIT=35] -->
<string name="accessibility_autoclick_short_title">Short</string>
@@ -4966,7 +4988,7 @@
<!-- Description for the button that longer auto click time. [CHAR_LIMIT=NONE] -->
<string name="accessibility_autoclick_longer_desc">Longer</string>
<!-- Description for the seekbar that adjust auto click time. [CHAR_LIMIT=NONE] -->
- <string name="accessibility_autoclick_seekbar_desc">auto click time</string>
+ <string name="accessibility_autoclick_seekbar_desc">Auto click time</string>
<!-- Title for accessibility preference screen for configuring vibrations. -->
<string name="accessibility_vibration_settings_title">Vibration & haptic strength</string>
<!-- Title for accessibility preference for configuring notification vibrations. -->
@@ -8456,33 +8478,55 @@
<!-- Special access > Title for managing the settings where users opt-in to connect a work app
to its personal equivalent, allowing cross-profile communication. [CHAR LIMIT=50] -->
- <string name="interact_across_profiles_title" translatable="false">Connected work and personal apps</string>
+ <string name="interact_across_profiles_title" translatable="false">Connected personal and work apps</string>
- <!-- Special access > Connected work and personal apps > Text to display when the list is empty. [CHAR LIMIT=NONE] -->
+ <!-- Special access > Connected personal and work apps > Text to display when the list is empty. [CHAR LIMIT=NONE] -->
<string name="interact_across_profiles_empty_text" translatable="false">No connected apps</string>
- <!-- Special access > Connected work and personal apps > Additional keywords to search for. [CHAR LIMIT=NONE] -->
+ <!-- Special access > Connected personal and work apps > Additional keywords to search for. [CHAR LIMIT=NONE] -->
<string name="interact_across_profiles_keywords" translatable="false">cross profile connected app apps work and personal</string>
<!-- Apps > App Details > Advanced section string title. [CHAR LIMIT=NONE] -->
- <string name="interact_across_profiles_app_detail_title" translatable="false">Connected work and personal apps</string>
+ <string name="interact_across_profiles_app_detail_title" translatable="false">Connected personal and work apps</string>
- <!-- Apps > App Details > Connected work and personal apps > Switch title. [CHAR LIMIT=NONE] -->
- <string name="interact_across_profiles_app_detail_switch" translatable="false">Connect these apps</string>
+ <!-- Apps > App Details > Connected personal and work apps > Switch title. [CHAR LIMIT=NONE] -->
+ <string name="interact_across_profiles_switch_enabled" translatable="false">Connected</string>
- <!-- Apps > App Details > Connected work and personal apps > Description. [CHAR LIMIT=NONE] -->
+ <!-- Apps > App Details > Connected personal and work apps > Switch title. [CHAR LIMIT=NONE] -->
+ <string name="interact_across_profiles_switch_disabled" translatable="false">Connect these apps</string>
+
+ <!-- Apps > App Details > Connected personal and work apps > Description. [CHAR LIMIT=NONE] -->
<string name="interact_across_profiles_summary_1" translatable="false">Connected apps share permissions and can access each other\u2019s data.</string>
- <!-- Apps > App Details > Connected work and personal apps > Description. [CHAR LIMIT=NONE] -->
+ <!-- Apps > App Details > Connected personal and work apps > Description. [CHAR LIMIT=NONE] -->
<string name="interact_across_profiles_summary_2" translatable="false">Only connect apps that you trust with your personal data.Your data may be exposed to your IT admin.</string>
- <!-- TODO(b/148594054): Replace calendar with actual app name -->
- <!-- Apps > App Details > Connected work and personal apps > Consent dialog title. [CHAR LIMIT=NONE] -->
- <string name="interact_across_profiles_consent_dialog_title" translatable="false">Trust work Calendar with your personal data?</string>
+ <!-- Apps > App Details > Connected personal and work apps > Consent dialog title. [CHAR LIMIT=NONE] -->
+ <string name="interact_across_profiles_consent_dialog_title" translatable="false">Trust work %1$s with your personal data?</string>
- <!-- TODO(b/148594054): Replace calendar with actual app name -->
- <!-- Apps > App Details > Connected work and personal apps > Consent dialog description. [CHAR LIMIT=NONE] -->
- <string name="interact_across_profiles_consent_dialog_summary" translatable="false">Calendar may expose your personal data to your IT admin</string>
+ <!-- Apps > App Details > Connected personal and work apps > Consent dialog description. [CHAR LIMIT=NONE] -->
+ <string name="interact_across_profiles_consent_dialog_summary" translatable="false">%1$s may expose your personal data to your IT admin.</string>
+
+ <!-- Apps > App Details > Connected personal and work apps > Consent dialog App data title. [CHAR LIMIT=NONE] -->
+ <string name="interact_across_profiles_consent_dialog_app_data_title" translatable="false">App data</string>
+
+ <!-- Apps > App Details > Connected personal and work apps > Consent dialog App data description. [CHAR LIMIT=NONE] -->
+ <string name="interact_across_profiles_consent_dialog_app_data_summary" translatable="false">It can access data in your personal %1$s app.</string>
+
+ <!-- Apps > App Details > Connected personal and work apps > Consent dialog Permissions title. [CHAR LIMIT=NONE] -->
+ <string name="interact_across_profiles_consent_dialog_permissions_title" translatable="false">Permissions</string>
+
+ <!-- Apps > App Details > Connected personal and work apps > Consent dialog Permissions description. [CHAR LIMIT=NONE] -->
+ <string name="interact_across_profiles_consent_dialog_permissions_summary" translatable="false">It can use your personal %1$s app\u2019s permissions, like access to location, storage, or contacts.</string>
+
+ <!-- Summary of preference to manage connected personal and work apps, informing the user that currently no apps are connected -->
+ <string name="interact_across_profiles_number_of_connected_apps_none" translatable="false">No apps connected</string>
+
+ <!-- Summary of preference to manage connected personal and work apps, informing the user how many apps are connected -->
+ <plurals name="interact_across_profiles_number_of_connected_apps" translatable="false">
+ <item quantity="one"><xliff:g id="count">%d</xliff:g> app connected</item>
+ <item quantity="other"><xliff:g id="count">%d</xliff:g> apps connected</item>
+ </plurals>
<!-- Sound & notification > Advanced section: Title for managing Do Not Disturb access option. [CHAR LIMIT=40] -->
<string name="manage_zen_access_title">Do Not Disturb access</string>
@@ -8974,6 +9018,11 @@
<!-- [CHAR LIMIT=60] Unlock setting for screen pinning -->
<string name="screen_pinning_unlock_none">Lock device when unpinning</string>
+ <!-- [CHAR LIMIT=60] turn eSim deletion confirmation on/off -->
+ <string name="confirm_sim_deletion_title">Confirm SIM deletion</string>
+ <!-- [CHAR LIMIT=NONE] eSim deletion confirmation description -->
+ <string name="confirm_sim_deletion_description">Verify it\u0027s you before erasing a downloaded SIM</string>
+
<!-- Opening string on the dialog that prompts the user to confirm that they really want to delete their existing work profile. The administration app icon and name appear after the final colon. [CHAR LIMIT=NONE] -->
<string name="opening_paragraph_delete_profile_unknown_company">This work profile is managed by:</string>
<!-- Summary for work profile accounts group. [CHAR LIMIT=25] -->
@@ -11025,6 +11074,18 @@
<!-- Summary for media output settings when the media stream is being captured by something else. -->
<string name="media_output_summary_unavailable">Unavailable</string>
+ <!-- Title for the media output group dialog with media related devices [CHAR LIMIT=50] -->
+ <string name="media_output_group_panel_title">Add outputs</string>
+
+ <!-- Title for the media output slice with group devices [CHAR LIMIT=50] -->
+ <string name="media_output_group">Group</string>
+
+ <!-- Summary for media output group with only one device which is active [CHAR LIMIT=NONE] -->
+ <string name="media_output_group_panel_single_device_summary">1 device selected</string>
+
+ <!-- Summary for media output group with the active device count [CHAR LIMIT=NONE] -->
+ <string name="media_output_group_panel_multiple_devices_summary"><xliff:g id="count" example="2">%1$d</xliff:g> devices selected</string>
+
<!-- Title for HFP(hands free profile) output switch button in settings. -->
<string name="take_call_on_title">Take call on</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 9816e07..c42fab2 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -643,4 +643,49 @@
<item name="android:clipChildren">true</item>
</style>
+ <style name="CrossProfileConsentDialogTitle">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:gravity">center</item>
+ <item name="android:textSize">20sp</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <item name="android:fontFamily">google-sans-medium</item>
+ <item name="android:paddingTop">36dp</item>
+ <item name="android:paddingBottom">16dp</item>
+ </style>
+
+ <style name="CrossProfileConsentDialogDescription">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:layout_marginBottom">36dp</item>
+ <item name="android:textSize">16sp</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <item name="android:fontFamily">sans-serif</item>
+ <item name="android:gravity">start</item>
+ </style>
+
+ <style name="CrossProfileConsentDialogIcon">
+ <item name="android:layout_width">24dp</item>
+ <item name="android:layout_height">24dp</item>
+ <item name="android:antialias">true</item>
+ <item name="android:gravity">start</item>
+ </style>
+
+ <style name="CrossProfileConsentDialogSubTitle">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:textSize">16sp</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <item name="android:fontFamily">sans-serif</item>
+ <item name="android:gravity">start</item>
+ </style>
+
+ <style name="CrossProfileConsentDialogSubDescription">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:textSize">14sp</item>
+ <item name="android:textColor">?android:attr/textColorSecondary</item>
+ <item name="android:fontFamily">sans-serif</item>
+ <item name="android:gravity">start</item>
+ </style>
</resources>
diff --git a/res/xml/accessibility_autoclick_settings.xml b/res/xml/accessibility_autoclick_settings.xml
index ad588f6..f126113 100644
--- a/res/xml/accessibility_autoclick_settings.xml
+++ b/res/xml/accessibility_autoclick_settings.xml
@@ -47,6 +47,7 @@
android:key="autoclick_custom_seekbar"
android:layout="@layout/accessibility_autoclick_custom_seekbar"
android:selectable="false"
+ android:visibility="gone"
settings:allowDividerBelow="true"
settings:controller="com.android.settings.accessibility.ToggleAutoclickCustomSeekbarController" />
diff --git a/res/xml/accessibility_color_inversion_settings.xml b/res/xml/accessibility_color_inversion_settings.xml
index 9681001..ba0d6fd 100644
--- a/res/xml/accessibility_color_inversion_settings.xml
+++ b/res/xml/accessibility_color_inversion_settings.xml
@@ -31,17 +31,4 @@
settings:allowDividerBelow="true"
settings:searchable="false" />
- <PreferenceCategory
- android:key="color_inversion_footer_category">
-
- <com.android.settingslib.widget.FooterPreference
- android:key="color_inversion_footer"
- android:persistent="false"
- android:selectable="false"
- settings:allowDividerAbove="false"
- android:title="@string/accessibility_display_inversion_preference_subtitle"
- settings:searchable="false" />
-
- </PreferenceCategory>
-
</PreferenceScreen>
diff --git a/res/xml/accessibility_daltonizer_settings.xml b/res/xml/accessibility_daltonizer_settings.xml
index b2ab5ef..c98736b 100644
--- a/res/xml/accessibility_daltonizer_settings.xml
+++ b/res/xml/accessibility_daltonizer_settings.xml
@@ -52,16 +52,4 @@
</PreferenceCategory>
- <PreferenceCategory
- android:key="daltonizer_footer_category">
-
- <com.android.settingslib.widget.FooterPreference
- android:key="daltonizer_footer"
- android:persistent="false"
- android:selectable="false"
- settings:allowDividerAbove="false"
- android:title="@string/accessibility_display_daltonizer_preference_subtitle"
- settings:searchable="false" />
-
- </PreferenceCategory>
</PreferenceScreen>
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index 914cc7a..7ff68aa 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -17,15 +17,10 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:key="accessibility_settings_screen"
android:persistent="false"
android:title="@string/accessibility_settings">
- <Preference
- android:fragment="com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment"
- android:key="accessibility_shortcut_preference"
- android:persistent="false"
- android:title="@string/accessibility_global_gesture_preference_title" />
-
<PreferenceCategory
android:key="user_installed_services_category"
android:persistent="false"
@@ -197,7 +192,8 @@
<PreferenceCategory
android:key="experimental_category"
android:persistent="false"
- android:title="@string/experimental_category_title">
+ android:title="@string/experimental_category_title"
+ settings:initialExpandedChildrenCount="1">
<SwitchPreference
android:key="toggle_high_text_contrast_preference"
@@ -220,5 +216,14 @@
android:persistent="false"
android:title="@string/accessibility_display_inversion_preference_title"
settings:controller="com.android.settings.accessibility.ColorInversionPreferenceController"/>
+
+ <SwitchPreference
+ android:key="accessibility_shortcut_preference"
+ android:persistent="false"
+ android:title="@string/accessibility_shortcut_service_on_lock_screen_title"
+ android:summary="@string/accessibility_shortcut_description"
+ settings:controller="com.android.settings.accessibility.AccessibilityShortcutPreferenceController"/>
+
</PreferenceCategory>
+
</PreferenceScreen>
diff --git a/res/xml/accessibility_shortcut_settings.xml b/res/xml/accessibility_shortcut_settings.xml
deleted file mode 100644
index 7708551..0000000
--- a/res/xml/accessibility_shortcut_settings.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:settings="http://schemas.android.com/apk/res-auto"
- android:title="@string/accessibility_global_gesture_preference_title">
-
- <SwitchPreference
- android:key="accessibility_shortcut_on_lock_screen"
- android:title="@string/accessibility_shortcut_service_on_lock_screen_title" />
-
- <com.android.settingslib.widget.FooterPreference
- android:key="accessibility_shortcut_footer"
- android:selectable="false"
- android:title="@string/accessibility_shortcut_description"
- settings:searchable="false" />
-
-</PreferenceScreen>
diff --git a/res/xml/accounts_dashboard_settings.xml b/res/xml/accounts_dashboard_settings.xml
index c42e1c7..d2affc7 100644
--- a/res/xml/accounts_dashboard_settings.xml
+++ b/res/xml/accounts_dashboard_settings.xml
@@ -17,7 +17,9 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
- android:title="@string/account_dashboard_title">
+ android:key="user_and_account_settings_screen"
+ android:title="@string/account_dashboard_title"
+ settings:keywords="@string/keywords_accounts">
<PreferenceCategory
android:key="dashboard_tile_placeholder"
diff --git a/res/xml/all_tether_prefs.xml b/res/xml/all_tether_prefs.xml
index d16adc5..f552522 100644
--- a/res/xml/all_tether_prefs.xml
+++ b/res/xml/all_tether_prefs.xml
@@ -55,7 +55,7 @@
<PreferenceCategory
android:key="tethering_options_group"
- android:title="Tethering"
+ android:title="@string/tethering_interface_options"
settings:searchable="false">
<SwitchPreference
android:key="enable_usb_tethering"
@@ -73,7 +73,7 @@
<SwitchPreference
android:key="disable_wifi_tethering"
- android:title="Don't use Wi-Fi hotspot"
+ android:title="@string/disable_wifi_hotspot_title"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.network.WifiTetherDisablePreferenceController"
settings:keywords="@string/keywords_hotspot_tethering" />
diff --git a/res/xml/app_and_notification.xml b/res/xml/app_and_notification.xml
index aa1a6ee..f75bd86 100644
--- a/res/xml/app_and_notification.xml
+++ b/res/xml/app_and_notification.xml
@@ -18,6 +18,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:key="apps_and_notification_screen"
android:title="@string/app_and_notification_dashboard_title"
settings:initialExpandedChildrenCount="4">
<!-- the initial count should include the dynamic tiles -->
diff --git a/res/xml/connected_devices.xml b/res/xml/connected_devices.xml
index 444b35c..a1736b2 100644
--- a/res/xml/connected_devices.xml
+++ b/res/xml/connected_devices.xml
@@ -17,6 +17,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:key="connected_devices_screen"
android:title="@string/connected_devices_dashboard_title">
<com.android.settings.slices.SlicePreference
diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml
index 4bf0c82..35b7b4d 100644
--- a/res/xml/display_settings.xml
+++ b/res/xml/display_settings.xml
@@ -17,7 +17,9 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:key="display_settings_screen"
android:title="@string/display_settings"
+ settings:keywords="@string/keywords_display"
settings:initialExpandedChildrenCount="5">
<com.android.settingslib.RestrictedPreference
diff --git a/res/xml/interact_across_profiles_permissions_details.xml b/res/xml/interact_across_profiles_permissions_details.xml
index e9a4803..8b1e043 100644
--- a/res/xml/interact_across_profiles_permissions_details.xml
+++ b/res/xml/interact_across_profiles_permissions_details.xml
@@ -24,15 +24,13 @@
android:selectable="false"/>
<SwitchPreference
- android:key="interact_across_profiles_settings_switch"
- android:title="@string/interact_across_profiles_app_detail_switch"/>
+ android:key="interact_across_profiles_settings_switch" />
<Preference
android:summary="@string/interact_across_profiles_summary_1"
- android:selectable="false"/>
+ android:selectable="false" />
<Preference
android:summary="@string/interact_across_profiles_summary_2"
- android:selectable="false"/>
-
+ android:selectable="false" />
</PreferenceScreen>
diff --git a/res/xml/location_settings.xml b/res/xml/location_settings.xml
index 6662c2f..fb03f4c 100644
--- a/res/xml/location_settings.xml
+++ b/res/xml/location_settings.xml
@@ -17,7 +17,9 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
- android:title="@string/location_settings_title">
+ android:key="location_settings"
+ android:title="@string/location_settings_title"
+ settings:keywords="@string/keywords_location">
<PreferenceCategory
android:key="recent_location_requests"
diff --git a/res/xml/my_device_info.xml b/res/xml/my_device_info.xml
index dbf1623..5e5fab3 100644
--- a/res/xml/my_device_info.xml
+++ b/res/xml/my_device_info.xml
@@ -18,6 +18,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:key="my_device_info_pref_screen"
android:title="@string/about_settings">
<com.android.settingslib.widget.LayoutPreference
diff --git a/res/xml/network_and_internet.xml b/res/xml/network_and_internet.xml
index 7653746..eaa7808 100644
--- a/res/xml/network_and_internet.xml
+++ b/res/xml/network_and_internet.xml
@@ -17,6 +17,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:key="network_and_internet_screen"
android:title="@string/network_dashboard_title"
settings:initialExpandedChildrenCount="5">
@@ -79,6 +80,18 @@
settings:userRestriction="no_config_tethering"
settings:useAdminDisabledSummary="true" />
+ <com.android.settings.widget.MasterSwitchPreference
+ android:fragment="com.android.settings.AllInOneTetherSettings"
+ android:key="all_tether_settings"
+ android:title="@string/tether_settings_title_all"
+ android:icon="@drawable/ic_wifi_tethering"
+ android:order="6"
+ android:summary="@string/summary_placeholder"
+ settings:controller="com.android.settings.network.AllInOneTetherPreferenceController"
+ settings:keywords="@string/keywords_hotspot_tethering"
+ settings:userRestriction="no_config_tethering"
+ settings:useAdminDisabledSummary="true" />
+
<com.android.settings.datausage.DataSaverPreference
android:key="restrict_background_parent_entry"
android:title="@string/data_saver_title"
diff --git a/res/xml/power_usage_summary.xml b/res/xml/power_usage_summary.xml
index 869bb94..005ce17 100644
--- a/res/xml/power_usage_summary.xml
+++ b/res/xml/power_usage_summary.xml
@@ -17,7 +17,9 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
- android:title="@string/power_usage_summary_title">
+ android:key="power_usage_summary_screen"
+ android:title="@string/power_usage_summary_title"
+ settings:keywords="@string/keywords_battery">
<com.android.settingslib.widget.LayoutPreference
android:key="battery_header"
diff --git a/res/xml/privacy_dashboard_settings.xml b/res/xml/privacy_dashboard_settings.xml
index abedc53..623460c 100644
--- a/res/xml/privacy_dashboard_settings.xml
+++ b/res/xml/privacy_dashboard_settings.xml
@@ -18,6 +18,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:key="privacy_dashboard_page"
android:title="@string/privacy_dashboard_title"
settings:initialExpandedChildrenCount="4">
diff --git a/res/xml/security_dashboard_settings.xml b/res/xml/security_dashboard_settings.xml
index cf56d67..7610b32 100644
--- a/res/xml/security_dashboard_settings.xml
+++ b/res/xml/security_dashboard_settings.xml
@@ -18,6 +18,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:key="security_dashboard_page"
android:title="@string/security_settings_title"
settings:initialExpandedChildrenCount="9">
@@ -146,4 +147,11 @@
android:summary="@string/summary_placeholder"
android:fragment="com.android.settings.security.ScreenPinningSettings" />
-</PreferenceScreen>
+ <SwitchPreference
+ android:order="90"
+ android:key="confirm_sim_deletion"
+ android:title="@string/confirm_sim_deletion_title"
+ android:summary="@string/confirm_sim_deletion_description"
+ settings:controller="com.android.settings.security.ConfirmSimDeletionPreferenceController"/>
+
+</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/sound_settings.xml b/res/xml/sound_settings.xml
index c525ccd..2c42111 100644
--- a/res/xml/sound_settings.xml
+++ b/res/xml/sound_settings.xml
@@ -18,16 +18,18 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/sound_settings"
+ android:key="sound_settings"
settings:keywords="@string/keywords_sounds"
settings:initialExpandedChildrenCount="9">
- <!-- Remote volume -->
- <com.android.settings.notification.RemoteVolumeSeekBarPreference
- android:key="remote_volume"
- android:icon="@drawable/ic_volume_remote"
- android:title="@string/remote_media_volume_option_title"
+ <!-- Remote volume group -->
+ <PreferenceCategory
+ android:key="remote_media_group"
+ android:title=""
android:order="-185"
- settings:controller="com.android.settings.notification.RemoteVolumePreferenceController"/>
+ settings:allowDividerBelow="true"
+ settings:controller="com.android.settings.notification.RemoteVolumeGroupController">
+ </PreferenceCategory>
<!-- Media volume -->
<com.android.settings.notification.VolumeSeekBarPreference
diff --git a/res/xml/special_access.xml b/res/xml/special_access.xml
index 132d50e..b0498f8 100644
--- a/res/xml/special_access.xml
+++ b/res/xml/special_access.xml
@@ -40,6 +40,13 @@
</Preference>
<Preference
+ android:key="interact_across_profiles"
+ android:title="@string/interact_across_profiles_title"
+ android:fragment="com.android.settings.applications.specialaccess.interactacrossprofiles.InteractAcrossProfilesSettings"
+ settings:keywords="@string/interact_across_profiles_keywords"
+ settings:controller="com.android.settings.applications.specialaccess.interactacrossprofiles.InteractAcrossProfilesController" />
+
+ <Preference
android:key="device_administrators"
android:title="@string/manage_device_admin"
android:fragment="com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminSettings"
@@ -147,13 +154,6 @@
</Preference>
<Preference
- android:key="interact_across_profiles"
- android:title="@string/interact_across_profiles_title"
- android:fragment="com.android.settings.applications.specialaccess.interactacrossprofiles.InteractAcrossProfilesSettings"
- settings:keywords="@string/interact_across_profiles_keywords"
- settings:controller="com.android.settings.applications.specialaccess.interactacrossprofiles.InteractAcrossProfilesController"/>
-
- <Preference
android:key="special_access_more"
android:title="@string/special_access_more"
settings:controller="com.android.settings.applications.specialaccess.MoreSpecialAccessPreferenceController" />
diff --git a/res/xml/system_dashboard_fragment.xml b/res/xml/system_dashboard_fragment.xml
index 5d0fbcd..88b8d2f 100644
--- a/res/xml/system_dashboard_fragment.xml
+++ b/res/xml/system_dashboard_fragment.xml
@@ -17,6 +17,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:key="system_dashboard_screen"
android:title="@string/header_category_system"
settings:initialExpandedChildrenCount="4">
@@ -75,4 +76,4 @@
android:targetClass="@string/additional_system_update_menu"/>
</Preference>
-</PreferenceScreen>
+</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/top_level_settings.xml b/res/xml/top_level_settings.xml
index 8f8d3d1..367f426 100644
--- a/res/xml/top_level_settings.xml
+++ b/res/xml/top_level_settings.xml
@@ -53,7 +53,6 @@
android:icon="@drawable/ic_homepage_battery"
android:fragment="com.android.settings.fuelgauge.PowerUsageSummary"
android:order="-90"
- settings:keywords="@string/keywords_battery"
settings:controller="com.android.settings.fuelgauge.TopLevelBatteryPreferenceController"/>
<Preference
@@ -80,7 +79,6 @@
android:icon="@drawable/ic_homepage_storage"
android:order="-60"
android:fragment="com.android.settings.deviceinfo.StorageSettings"
- settings:keywords="@string/keywords_display"
settings:controller="com.android.settings.deviceinfo.TopLevelStoragePreferenceController"/>
<Preference
@@ -98,7 +96,6 @@
android:icon="@drawable/ic_homepage_location"
android:order="-50"
android:fragment="com.android.settings.location.LocationSettings"
- settings:keywords="@string/keywords_location"
settings:controller="com.android.settings.location.TopLevelLocationPreferenceController"/>
<Preference
@@ -117,7 +114,6 @@
android:icon="@drawable/ic_homepage_accounts"
android:order="-30"
android:fragment="com.android.settings.accounts.AccountDashboardFragment"
- settings:keywords="@string/keywords_accounts"
settings:controller="com.android.settings.accounts.TopLevelAccountEntryPreferenceController"/>
<Preference
diff --git a/res/xml/zen_mode_event_rule_settings.xml b/res/xml/zen_mode_event_rule_settings.xml
index 841fc06..46b95e1 100644
--- a/res/xml/zen_mode_event_rule_settings.xml
+++ b/res/xml/zen_mode_event_rule_settings.xml
@@ -24,6 +24,7 @@
<com.android.settingslib.widget.LayoutPreference
android:key="pref_app_header"
android:layout="@layout/settings_entity_header"
+ android:selectable="false"
settings:allowDividerBelow="true" />
<com.android.settingslib.widget.ActionButtonsPreference
diff --git a/res/xml/zen_mode_schedule_rule_settings.xml b/res/xml/zen_mode_schedule_rule_settings.xml
index 8484854..cab8731 100644
--- a/res/xml/zen_mode_schedule_rule_settings.xml
+++ b/res/xml/zen_mode_schedule_rule_settings.xml
@@ -24,6 +24,7 @@
<com.android.settingslib.widget.LayoutPreference
android:key="pref_app_header"
android:layout="@layout/settings_entity_header"
+ android:selectable="false"
settings:allowDividerBelow="true"/>
<com.android.settingslib.widget.ActionButtonsPreference
diff --git a/res/xml/zen_mode_settings.xml b/res/xml/zen_mode_settings.xml
index a55c6be..ce2d132 100644
--- a/res/xml/zen_mode_settings.xml
+++ b/res/xml/zen_mode_settings.xml
@@ -18,7 +18,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
- android:title=" ">
+ android:title="@string/zen_mode_settings_title">
<!-- Turn on DND button -->
<com.android.settingslib.widget.LayoutPreference
diff --git a/src/com/android/settings/AllInOneTetherSettings.java b/src/com/android/settings/AllInOneTetherSettings.java
index 4576fb7..a15ad1f 100644
--- a/src/com/android/settings/AllInOneTetherSettings.java
+++ b/src/com/android/settings/AllInOneTetherSettings.java
@@ -201,8 +201,6 @@
// Set initial state based on SharedPreferences value.
onSharedPreferenceChanged(mSharedPreferences, KEY_ENABLE_WIFI_TETHERING);
-
- // TODO(b/147325229): Hide advanced settings like security and ap band.
}
@Override
@@ -321,12 +319,6 @@
}
@Override
- public void onExpandButtonClick() {
- super.onExpandButtonClick();
- // TODO(b/147325229): Display hidden advanced settings like security and ap band.
- }
-
- @Override
public int getHelpResource() {
return R.string.help_url_tether;
}
diff --git a/src/com/android/settings/TestingSettingsBroadcastReceiver.java b/src/com/android/settings/TestingSettingsBroadcastReceiver.java
index 0e1296b..aa28a18 100644
--- a/src/com/android/settings/TestingSettingsBroadcastReceiver.java
+++ b/src/com/android/settings/TestingSettingsBroadcastReceiver.java
@@ -1,9 +1,10 @@
package com.android.settings;
+import static com.android.internal.telephony.TelephonyIntents.SECRET_CODE_ACTION;
+
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.telephony.TelephonyManager;
import com.android.settings.Settings.TestingSettingsActivity;
@@ -15,7 +16,7 @@
@Override
public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(TelephonyManager.ACTION_SECRET_CODE)) {
+ if (intent.getAction().equals(SECRET_CODE_ACTION)) {
Intent i = new Intent(Intent.ACTION_MAIN);
i.setClass(context, TestingSettingsActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index 9793e85..94e73fa 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -74,6 +74,8 @@
// Index of the first preference in a preference category.
private static final int FIRST_PREFERENCE_IN_CATEGORY_INDEX = -1;
+ private static final String EMPTY_STRING = "";
+
// Preference categories
private static final String CATEGORY_SCREEN_READER = "screen_reader_category";
private static final String CATEGORY_AUDIO_AND_CAPTIONS = "audio_and_captions_category";
@@ -255,17 +257,22 @@
public static CharSequence getServiceSummary(Context context, AccessibilityServiceInfo info,
boolean serviceEnabled) {
+ final CharSequence serviceSummary = info.loadSummary(context.getPackageManager());
+ final int fragmentType = AccessibilityUtil.getAccessibilityServiceFragmentType(info);
+
+ if (fragmentType == AccessibilityServiceFragmentType.INVISIBLE) {
+ return TextUtils.isEmpty(serviceSummary) ? EMPTY_STRING : serviceSummary;
+ }
+
final String serviceState = serviceEnabled
? context.getString(R.string.accessibility_summary_state_enabled)
: context.getString(R.string.accessibility_summary_state_disabled);
- final CharSequence serviceSummary = info.loadSummary(context.getPackageManager());
final String stateSummaryCombo = context.getString(
R.string.preference_summary_default_combination,
serviceState, serviceSummary);
- return (TextUtils.isEmpty(serviceSummary))
- ? serviceState
- : stateSummaryCombo;
+ return (TextUtils.isEmpty(serviceSummary)) ? serviceState : stateSummaryCombo;
+
}
@VisibleForTesting
@@ -397,7 +404,8 @@
preference.setEnabled(true);
}
- switch (AccessibilityUtil.getAccessibilityServiceFragmentType(info)) {
+ final int fragmentType = AccessibilityUtil.getAccessibilityServiceFragmentType(info);
+ switch (fragmentType) {
case AccessibilityServiceFragmentType.LEGACY:
preference.setFragment(
LegacyAccessibilityServicePreferenceFragment.class.getName());
@@ -508,6 +516,8 @@
experimentalCategory.removePreference(mDisplayDaltonizerPreferenceScreen);
mDisplayDaltonizerPreferenceScreen.setOrder(
mDisplayMagnificationPreferenceScreen.getOrder() + 1);
+ mDisplayDaltonizerPreferenceScreen.setSummary(AccessibilityUtil.getSummary(
+ getContext(), Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED));
mToggleInversionPreference.setOrder(
mDisplayDaltonizerPreferenceScreen.getOrder() + 1);
mToggleLargePointerIconPreference.setOrder(
diff --git a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceController.java b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceController.java
new file mode 100644
index 0000000..ce3d294
--- /dev/null
+++ b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceController.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 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.accessibility;
+
+import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
+import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+import com.android.settings.core.TogglePreferenceController;
+
+/**
+ * Settings page for accessibility shortcut
+ */
+public class AccessibilityShortcutPreferenceController extends TogglePreferenceController {
+
+ public AccessibilityShortcutPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ @Override
+ public boolean isChecked() {
+ final ContentResolver cr = mContext.getContentResolver();
+ // The shortcut is enabled by default on the lock screen as long as the user has
+ // enabled the shortcut with the warning dialog
+ final int dialogShown = Settings.Secure.getInt(
+ cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, OFF);
+ final boolean enabledFromLockScreen = Settings.Secure.getInt(
+ cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, dialogShown) == ON;
+ return enabledFromLockScreen;
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ return Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, isChecked ? ON : OFF,
+ UserHandle.USER_CURRENT);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+}
diff --git a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
deleted file mode 100644
index ca3c2e8..0000000
--- a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2017 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.accessibility;
-
-import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
-import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
-
-import android.accessibilityservice.AccessibilityServiceInfo;
-import android.annotation.Nullable;
-import android.app.settings.SettingsEnums;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.view.View;
-import android.view.accessibility.AccessibilityManager;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.SwitchPreference;
-
-import com.android.internal.accessibility.AccessibilityShortcutController;
-import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.accessibility.AccessibilityUtils;
-import com.android.settingslib.search.Indexable;
-import com.android.settingslib.search.SearchIndexable;
-
-/**
- * Settings page for accessibility shortcut
- */
-@SearchIndexable
-public class AccessibilityShortcutPreferenceFragment extends ToggleFeaturePreferenceFragment
- implements Indexable {
-
- public static final String ON_LOCK_SCREEN_KEY = "accessibility_shortcut_on_lock_screen";
-
- private SwitchPreference mOnLockScreenSwitchPreference;
- private final ContentObserver mContentObserver = new ContentObserver(new Handler()) {
- @Override
- public void onChange(boolean selfChange) {
- updatePreferences();
- }
- };
-
- @Override
- public int getMetricsCategory() {
- return SettingsEnums.ACCESSIBILITY_TOGGLE_GLOBAL_GESTURE;
- }
-
- @Override
- public int getHelpResource() {
- return R.string.help_url_accessibility_shortcut;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mOnLockScreenSwitchPreference = (SwitchPreference) findPreference(ON_LOCK_SCREEN_KEY);
- mOnLockScreenSwitchPreference.setOnPreferenceChangeListener((Preference p, Object o) -> {
- Settings.Secure.putInt(getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN,
- ((Boolean) o) ? ON : OFF);
- return true;
- });
- }
-
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- final PreferenceScreen preferenceScreen = getPreferenceScreen();
- preferenceScreen.findPreference(KEY_GENERAL_CATEGORY).setVisible(false);
-
- preferenceScreen.setOrderingAsAdded(false);
- mToggleServiceDividerSwitchPreference.setVisible(false);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- updatePreferences();
- getContentResolver().registerContentObserver(
- Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN),
- false, mContentObserver);
- }
-
- @Override
- public void onPause() {
- getContentResolver().unregisterContentObserver(mContentObserver);
- super.onPause();
- }
-
- @Override
- protected int getPreferenceScreenResId() {
- return R.xml.accessibility_shortcut_settings;
- }
-
- @Override
- protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
- Settings.Secure.putInt(getContentResolver(), preferenceKey, enabled ? ON : OFF);
- updatePreferences();
- }
-
- private void updatePreferences() {
- ContentResolver cr = getContentResolver();
- // The shortcut is enabled by default on the lock screen as long as the user has
- // enabled the shortcut with the warning dialog
- final int dialogShown = Settings.Secure.getInt(
- cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, OFF);
- final boolean enabledFromLockScreen = Settings.Secure.getInt(
- cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, dialogShown) == ON;
- mOnLockScreenSwitchPreference.setChecked(enabledFromLockScreen);
- }
-
- /**
- * Get the user-visible name of the service currently selected for the shortcut.
- *
- * @param context The current context
- * @return The name of the service or a string saying that none is selected.
- */
- public static CharSequence getServiceName(Context context) {
- if (!shortcutFeatureAvailable(context)) {
- return context.getString(R.string.accessibility_no_service_selected);
- }
- AccessibilityServiceInfo shortcutServiceInfo = getServiceInfo(context);
- if (shortcutServiceInfo != null) {
- return shortcutServiceInfo.getResolveInfo().loadLabel(context.getPackageManager());
- }
- return AccessibilityShortcutController.getFrameworkShortcutFeaturesMap()
- .get(getShortcutComponent(context)).getLabel(context);
- }
-
- private static AccessibilityServiceInfo getServiceInfo(Context context) {
- return AccessibilityManager.getInstance(context)
- .getInstalledServiceInfoWithComponentName(getShortcutComponent(context));
- }
-
- private static boolean shortcutFeatureAvailable(Context context) {
- ComponentName shortcutFeature = getShortcutComponent(context);
- if (shortcutFeature == null) return false;
-
- if (AccessibilityShortcutController.getFrameworkShortcutFeaturesMap()
- .containsKey(shortcutFeature)) {
- return true;
- }
- return getServiceInfo(context) != null;
- }
-
- private static @Nullable ComponentName getShortcutComponent(Context context) {
- String componentNameString = AccessibilityUtils.getShortcutTargetServiceComponentNameString(
- context, UserHandle.myUserId());
- if (componentNameString == null) return null;
- return ComponentName.unflattenFromString(componentNameString);
- }
-
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider() {
- // This fragment is for details of the shortcut. Only the shortcut itself needs
- // to be indexed.
- protected boolean isPageSearchEnabled(Context context) {
- return false;
- }
- };
-}
diff --git a/src/com/android/settings/accessibility/AccessibilitySlicePreferenceController.java b/src/com/android/settings/accessibility/AccessibilitySlicePreferenceController.java
index e53afeb..ca3befa 100644
--- a/src/com/android/settings/accessibility/AccessibilitySlicePreferenceController.java
+++ b/src/com/android/settings/accessibility/AccessibilitySlicePreferenceController.java
@@ -16,6 +16,9 @@
package com.android.settings.accessibility;
+import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
+import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
+
import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -39,8 +42,7 @@
private final ComponentName mComponentName;
- private final int ON = 1;
- private final int OFF = 0;
+ private static final String EMPTY_STRING = "";
public AccessibilitySlicePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
@@ -55,8 +57,9 @@
@Override
public CharSequence getSummary() {
final AccessibilityServiceInfo serviceInfo = getAccessibilityServiceInfo();
- return serviceInfo == null
- ? "" : AccessibilitySettings.getServiceSummary(mContext, serviceInfo, isChecked());
+
+ return serviceInfo == null ? EMPTY_STRING : AccessibilitySettings.getServiceSummary(
+ mContext, serviceInfo, isChecked());
}
@Override
diff --git a/src/com/android/settings/accessibility/CaptionAppearanceFragment.java b/src/com/android/settings/accessibility/CaptionAppearanceFragment.java
index 0fd3d06..d31465e 100644
--- a/src/com/android/settings/accessibility/CaptionAppearanceFragment.java
+++ b/src/com/android/settings/accessibility/CaptionAppearanceFragment.java
@@ -122,10 +122,6 @@
refreshPreviewText();
}
- private void refreshPreferenceViewEnabled(boolean enabled) {
- mPreviewText.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
- }
-
private void refreshPreviewText() {
final Context context = getActivity();
if (context == null) {
@@ -217,8 +213,6 @@
mPreferenceList.add(mFontSize);
mPreferenceList.add(mPreset);
- refreshPreferenceViewEnabled(mCaptioningManager.isEnabled());
-
mCustom = (PreferenceCategory) findPreference(PREF_CUSTOM);
mShowingCustom = true;
diff --git a/src/com/android/settings/accessibility/DaltonizerPreferenceController.java b/src/com/android/settings/accessibility/DaltonizerPreferenceController.java
index 2922b76..c859d8c 100644
--- a/src/com/android/settings/accessibility/DaltonizerPreferenceController.java
+++ b/src/com/android/settings/accessibility/DaltonizerPreferenceController.java
@@ -19,15 +19,10 @@
import android.content.Context;
import android.provider.Settings;
-import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
-import com.google.common.primitives.Ints;
-
/** Controller that shows and updates the color correction summary. */
public class DaltonizerPreferenceController extends BasePreferenceController {
-
- private static final String DALTONIZER_TYPE = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER;
private static final String DALTONIZER_ENABLED =
Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED;
@@ -42,21 +37,6 @@
@Override
public CharSequence getSummary() {
- final String[] daltonizerSummaries = mContext.getResources().getStringArray(
- R.array.daltonizer_mode_summaries);
- final int[] daltonizerValues = mContext.getResources().getIntArray(
- R.array.daltonizer_type_values);
- final int timeoutValue =
- DaltonizerRadioButtonPreferenceController.getSecureAccessibilityDaltonizerValue(
- mContext.getContentResolver(), DALTONIZER_TYPE);
- final int idx = Ints.indexOf(daltonizerValues, timeoutValue);
- final String serviceSummary = daltonizerSummaries[idx == -1 ? 0 : idx];
-
- final CharSequence serviceState = AccessibilityUtil.getSummary(mContext,
- DALTONIZER_ENABLED);
-
- return mContext.getString(
- R.string.preference_summary_default_combination,
- serviceState, serviceSummary);
+ return AccessibilityUtil.getSummary(mContext, DALTONIZER_ENABLED);
}
}
diff --git a/src/com/android/settings/accessibility/DaltonizerRadioButtonPreferenceController.java b/src/com/android/settings/accessibility/DaltonizerRadioButtonPreferenceController.java
index dd5eb10..f6f554e 100644
--- a/src/com/android/settings/accessibility/DaltonizerRadioButtonPreferenceController.java
+++ b/src/com/android/settings/accessibility/DaltonizerRadioButtonPreferenceController.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.content.res.Resources;
import android.provider.Settings;
+import android.view.View;
import android.view.accessibility.AccessibilityManager;
import androidx.lifecycle.LifecycleObserver;
@@ -122,6 +123,7 @@
mPreference = (RadioButtonPreference)
screen.findPreference(getPreferenceKey());
mPreference.setOnClickListener(this);
+ mPreference.setAppendixVisibility(View.GONE);
updateState(mPreference);
}
diff --git a/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java b/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java
index 31a8c19..f73ca01 100644
--- a/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java
+++ b/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java
@@ -92,8 +92,8 @@
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
extras.putInt(AccessibilitySettings.EXTRA_TITLE_RES,
R.string.accessibility_screen_magnification_gestures_title);
- extras.putInt(AccessibilitySettings.EXTRA_SUMMARY_RES,
- R.string.accessibility_screen_magnification_summary);
+ extras.putCharSequence(AccessibilitySettings.EXTRA_HTML_DESCRIPTION,
+ context.getText(R.string.accessibility_screen_magnification_summary));
extras.putInt(AccessibilitySettings.EXTRA_VIDEO_RAW_RESOURCE_ID,
R.raw.accessibility_screen_magnification);
}
diff --git a/src/com/android/settings/accessibility/MagnificationNavbarPreferenceController.java b/src/com/android/settings/accessibility/MagnificationNavbarPreferenceController.java
index 1b8d854d..952f820 100644
--- a/src/com/android/settings/accessibility/MagnificationNavbarPreferenceController.java
+++ b/src/com/android/settings/accessibility/MagnificationNavbarPreferenceController.java
@@ -55,8 +55,8 @@
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED);
extras.putInt(AccessibilitySettings.EXTRA_TITLE_RES,
R.string.accessibility_screen_magnification_navbar_title);
- extras.putInt(AccessibilitySettings.EXTRA_SUMMARY_RES,
- R.string.accessibility_screen_magnification_navbar_summary);
+ extras.putCharSequence(AccessibilitySettings.EXTRA_HTML_DESCRIPTION,
+ mContext.getText(R.string.accessibility_screen_magnification_navbar_summary));
extras.putBoolean(AccessibilitySettings.EXTRA_CHECKED, isChecked());
extras.putBoolean(AccessibilitySettings.EXTRA_LAUNCHED_FROM_SUW, mIsFromSUW);
}
diff --git a/src/com/android/settings/accessibility/MagnificationPreferenceController.java b/src/com/android/settings/accessibility/MagnificationPreferenceController.java
index 8b214a2..7ac7bef 100644
--- a/src/com/android/settings/accessibility/MagnificationPreferenceController.java
+++ b/src/com/android/settings/accessibility/MagnificationPreferenceController.java
@@ -18,7 +18,6 @@
import android.content.Context;
import android.os.Bundle;
-import android.provider.Settings;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
@@ -41,22 +40,8 @@
@Override
public CharSequence getSummary() {
- final boolean tripleTapEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1;
- final boolean buttonEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, 0) == 1;
-
- int summaryResId = 0;
- if (!tripleTapEnabled && !buttonEnabled) {
- summaryResId = R.string.accessibility_feature_state_off;
- } else if (!tripleTapEnabled && buttonEnabled) {
- summaryResId = R.string.accessibility_screen_magnification_navbar_title;
- } else if (tripleTapEnabled && !buttonEnabled) {
- summaryResId = R.string.accessibility_screen_magnification_gestures_title;
- } else {
- summaryResId = R.string.accessibility_screen_magnification_state_navbar_gesture;
- }
- return mContext.getResources().getText(summaryResId);
+ return mContext.getResources().getText(
+ R.string.accessibility_screen_magnification_navbar_title);
}
@Override
diff --git a/src/com/android/settings/accessibility/PaletteListPreference.java b/src/com/android/settings/accessibility/PaletteListPreference.java
index de35112..c5c4205 100644
--- a/src/com/android/settings/accessibility/PaletteListPreference.java
+++ b/src/com/android/settings/accessibility/PaletteListPreference.java
@@ -26,7 +26,7 @@
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
-import com.android.settingslib.widget.R;
+import com.android.settings.R;
/** Preference that easier preview by matching name to color. */
public class PaletteListPreference extends Preference {
diff --git a/src/com/android/settings/accessibility/PaletteListView.java b/src/com/android/settings/accessibility/PaletteListView.java
index 0030817..ef010e2 100644
--- a/src/com/android/settings/accessibility/PaletteListView.java
+++ b/src/com/android/settings/accessibility/PaletteListView.java
@@ -35,7 +35,7 @@
import androidx.annotation.VisibleForTesting;
-import com.android.settingslib.widget.R;
+import com.android.settings.R;
import com.google.common.collect.Iterables;
@@ -55,13 +55,13 @@
* display also the view background shows the color beside the text variable end point.
*/
public class PaletteListView extends ListView {
- private static final float VIEW_PITCH = 0.05f;
private final Context mContext;
private final DisplayAdapter mDisplayAdapter;
private final LayoutInflater mLayoutInflater;
private final String mDefaultGradientColorCodeString;
private final int mDefaultGradientColor;
private float mTextBound;
+ private static final float LANDSCAPE_MAX_WIDTH_PERCENTAGE = 100f;
public PaletteListView(Context context) {
this(context, null);
@@ -206,8 +206,17 @@
final float textWidth = textView.getPaint().measureText(textView.getText().toString());
// Computes rate of text width compare to screen width, and measures the round the double
// to two decimal places manually.
- final float textBound = Math.round(textWidth / getScreenWidth(windowManager) * 100) / 100f;
- mTextBound = textBound + VIEW_PITCH;
+ final float textBound = Math.round(
+ textWidth / getScreenWidth(windowManager) * LANDSCAPE_MAX_WIDTH_PERCENTAGE)
+ / LANDSCAPE_MAX_WIDTH_PERCENTAGE;
+
+ // Left padding and right padding with color preview.
+ final float paddingPixel = getResources().getDimension(
+ R.dimen.accessibility_layout_margin_start_end);
+ final float paddingWidth =
+ Math.round(paddingPixel / getScreenWidth(windowManager)
+ * LANDSCAPE_MAX_WIDTH_PERCENTAGE) / LANDSCAPE_MAX_WIDTH_PERCENTAGE;
+ mTextBound = textBound + paddingWidth + paddingWidth;
}
private static class ViewHolder {
diff --git a/src/com/android/settings/accessibility/ShortcutPreference.java b/src/com/android/settings/accessibility/ShortcutPreference.java
index 2a62439..00b63b6 100644
--- a/src/com/android/settings/accessibility/ShortcutPreference.java
+++ b/src/com/android/settings/accessibility/ShortcutPreference.java
@@ -165,6 +165,9 @@
setWidgetLayoutResource(R.layout.preference_widget_settings);
setIconSpaceReserved(false);
mAutoEnabledSettings = true;
+
+ // Disable whole component to let each child component can be addressed.
+ setSelectable(false);
}
private void callOnSettingsClicked() {
diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
index a75c536..17ca939 100644
--- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
@@ -330,9 +330,6 @@
.appendPath(String.valueOf(animatedImageRes))
.build();
- // Settings html description.
- mHtmlDescription = arguments.getCharSequence(AccessibilitySettings.EXTRA_HTML_DESCRIPTION);
-
// Get Accessibility service name.
mPackageName = getAccessibilityServiceInfo().getResolveInfo().loadLabel(
getPackageManager());
diff --git a/src/com/android/settings/accessibility/ToggleAutoclickCustomSeekbarController.java b/src/com/android/settings/accessibility/ToggleAutoclickCustomSeekbarController.java
index 301d8dc..b98a503 100644
--- a/src/com/android/settings/accessibility/ToggleAutoclickCustomSeekbarController.java
+++ b/src/com/android/settings/accessibility/ToggleAutoclickCustomSeekbarController.java
@@ -138,12 +138,12 @@
mDelayLabel = preference.findViewById(R.id.current_label);
mDelayLabel.setText(delayTimeToString(delayMillis));
- mShorter = preference.findViewById(R.id.smaller);
+ mShorter = preference.findViewById(R.id.shorter);
mShorter.setOnClickListener(v -> {
minusDelayByImageView();
});
- mLonger = preference.findViewById(R.id.larger);
+ mLonger = preference.findViewById(R.id.longer);
mLonger.setOnClickListener(v -> {
plusDelayByImageView();
});
diff --git a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java
index ffde1e3..ec5784e 100644
--- a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java
@@ -29,8 +29,6 @@
import android.view.View;
import android.view.ViewGroup;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import com.android.settings.R;
@@ -45,7 +43,6 @@
public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePreferenceFragment {
private static final String ENABLED = Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED;
- private static final String CATEGORY_FOOTER_KEY = "color_inversion_footer_category";
private static final int DIALOG_ID_EDIT_SHORTCUT = 1;
private final Handler mHandler = new Handler();
private SettingsContentObserver mSettingsContentObserver;
@@ -91,7 +88,8 @@
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mComponentName = COLOR_INVERSION_COMPONENT_NAME;
- mPackageName = getString(R.string.accessibility_display_inversion_preference_title);
+ mPackageName = getText(R.string.accessibility_display_inversion_preference_title);
+ mHtmlDescription = getText(R.string.accessibility_display_inversion_preference_subtitle);
final List<String> enableServiceFeatureKeys = new ArrayList<>(/* initialCapacity= */ 1);
enableServiceFeatureKeys.add(ENABLED);
mSettingsContentObserver = new SettingsContentObserver(mHandler, enableServiceFeatureKeys) {
@@ -104,17 +102,6 @@
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- final PreferenceScreen preferenceScreen = getPreferenceScreen();
- preferenceScreen.setOrderingAsAdded(false);
- final PreferenceCategory footerCategory = preferenceScreen.findPreference(
- CATEGORY_FOOTER_KEY);
- footerCategory.setOrder(Integer.MAX_VALUE);
- }
-
- @Override
public void onResume() {
super.onResume();
updateSwitchBarToggleSwitch();
diff --git a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
index f2b84e5..9b8b117 100644
--- a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
@@ -32,7 +32,6 @@
import android.view.ViewGroup;
import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
@@ -50,8 +49,8 @@
implements DaltonizerRadioButtonPreferenceController.OnChangeListener {
private static final String ENABLED = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED;
- private static final String CATEGORY_FOOTER_KEY = "daltonizer_footer_category";
- private static final String CATEGORY_MODE_KEY = "daltonizer_mode_category";
+ private static final String KEY_PREVIEW = "daltonizer_preview";
+ private static final String KEY_CATEGORY_MODE = "daltonizer_mode_category";
private static final List<AbstractPreferenceController> sControllers = new ArrayList<>();
private final Handler mHandler = new Handler();
private SettingsContentObserver mSettingsContentObserver;
@@ -82,7 +81,8 @@
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mComponentName = DALTONIZER_COMPONENT_NAME;
- mPackageName = getString(R.string.accessibility_display_daltonizer_preference_title);
+ mPackageName = getText(R.string.accessibility_display_daltonizer_preference_title);
+ mHtmlDescription = getText(R.string.accessibility_display_daltonizer_preference_subtitle);
final List<String> enableServiceFeatureKeys = new ArrayList<>(/* initialCapacity= */ 1);
enableServiceFeatureKeys.add(ENABLED);
mSettingsContentObserver = new SettingsContentObserver(mHandler, enableServiceFeatureKeys) {
@@ -97,16 +97,32 @@
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
+ updatePreferenceOrder();
+ }
+
+ /** Customizes the order by preference key. */
+ private List<String> getPreferenceOrderList() {
+ List<String> lists = new ArrayList<>();
+ lists.add(KEY_PREVIEW);
+ lists.add(KEY_USE_SERVICE_PREFERENCE);
+ lists.add(KEY_CATEGORY_MODE);
+ lists.add(KEY_GENERAL_CATEGORY);
+ lists.add(KEY_INTRODUCTION_CATEGORY);
+ return lists;
+ }
+
+ private void updatePreferenceOrder() {
+ List<String> lists = getPreferenceOrderList();
final PreferenceScreen preferenceScreen = getPreferenceScreen();
preferenceScreen.setOrderingAsAdded(false);
- final PreferenceCategory modeCategory = preferenceScreen.findPreference(
- CATEGORY_MODE_KEY);
- modeCategory.setOrder(Integer.MAX_VALUE - 1);
-
- final PreferenceCategory footerCategory = preferenceScreen.findPreference(
- CATEGORY_FOOTER_KEY);
- footerCategory.setOrder(Integer.MAX_VALUE);
+ final int size = lists.size();
+ for (int i = 0; i < size; i++) {
+ final Preference preference = preferenceScreen.findPreference(lists.get(i));
+ if (preference != null) {
+ preference.setOrder(i);
+ }
+ }
}
@Override
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
index 5571591..19a0f2b 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -27,6 +27,8 @@
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.text.Html;
import android.text.TextUtils;
import android.view.LayoutInflater;
@@ -47,6 +49,7 @@
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
import com.android.settings.widget.SwitchBar;
+import com.android.settingslib.accessibility.AccessibilityUtils;
import com.android.settingslib.widget.FooterPreference;
import java.lang.annotation.Retention;
@@ -79,7 +82,9 @@
protected CharSequence mHtmlDescription;
private static final String ANCHOR_TAG = "a";
private static final String DRAWABLE_FOLDER = "drawable";
- protected static final String KEY_GENERAL_CATEGORY = "categories";
+ protected static final String KEY_USE_SERVICE_PREFERENCE = "use_service";
+ protected static final String KEY_GENERAL_CATEGORY = "general_categories";
+ protected static final String KEY_INTRODUCTION_CATEGORY = "introduction_categories";
private static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference";
private static final String EXTRA_SHORTCUT_TYPE = "shortcut_type";
private TouchExplorationStateChangeListener mTouchExplorationStateChangeListener;
@@ -110,6 +115,7 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ setupDefaultShortcutIfNecessary(getPrefContext());
final int resId = getPreferenceScreenResId();
if (resId <= 0) {
PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(
@@ -136,6 +142,9 @@
final SwitchBar switchBar = activity.getSwitchBar();
switchBar.hide();
+ // Need to be called as early as possible. Protected variables will be assigned here.
+ onProcessArguments(getArguments());
+
PreferenceScreen preferenceScreen = getPreferenceScreen();
if (mImageUri != null) {
final AnimatedImagePreference animatedImagePreference = new AnimatedImagePreference(
@@ -146,9 +155,14 @@
}
mToggleServiceDividerSwitchPreference = new DividerSwitchPreference(getPrefContext());
+ mToggleServiceDividerSwitchPreference.setKey(KEY_USE_SERVICE_PREFERENCE);
+ if (getArguments().containsKey(AccessibilitySettings.EXTRA_CHECKED)) {
+ final boolean enabled = getArguments().getBoolean(AccessibilitySettings.EXTRA_CHECKED);
+ mToggleServiceDividerSwitchPreference.setChecked(enabled);
+ }
+
preferenceScreen.addPreference(mToggleServiceDividerSwitchPreference);
- onProcessArguments(getArguments());
updateToggleServiceTitle(mToggleServiceDividerSwitchPreference);
final PreferenceCategory groupCategory = new PreferenceCategory(getPrefContext());
@@ -177,6 +191,7 @@
getPrefContext());
final CharSequence title = getString(R.string.accessibility_introduction_title,
mPackageName);
+ introductionCategory.setKey(KEY_INTRODUCTION_CATEGORY);
introductionCategory.setTitle(title);
preferenceScreen.addPreference(introductionCategory);
@@ -335,12 +350,6 @@
// Key.
mPreferenceKey = arguments.getString(AccessibilitySettings.EXTRA_PREFERENCE_KEY);
- // Enabled.
- if (arguments.containsKey(AccessibilitySettings.EXTRA_CHECKED)) {
- final boolean enabled = arguments.getBoolean(AccessibilitySettings.EXTRA_CHECKED);
- mToggleServiceDividerSwitchPreference.setChecked(enabled);
- }
-
// Title.
if (arguments.containsKey(AccessibilitySettings.EXTRA_RESOLVE_INFO)) {
ResolveInfo info = arguments.getParcelable(AccessibilitySettings.EXTRA_RESOLVE_INFO);
@@ -358,6 +367,12 @@
AccessibilitySettings.EXTRA_SUMMARY);
createFooterPreference(summary);
}
+
+ // Settings html description.
+ if (arguments.containsKey(AccessibilitySettings.EXTRA_HTML_DESCRIPTION)) {
+ mHtmlDescription = arguments.getCharSequence(
+ AccessibilitySettings.EXTRA_HTML_DESCRIPTION);
+ }
}
private Drawable getDrawableFromUri(Uri imageUri) {
@@ -631,4 +646,32 @@
preferenceScreen.addPreference(new FooterPreference.Builder(getActivity()).setTitle(
title).build());
}
+
+ /**
+ * Setups a configurable default if the setting has never been set.
+ */
+ private static void setupDefaultShortcutIfNecessary(Context context) {
+ final String targetKey = Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
+ String targetString = Settings.Secure.getString(context.getContentResolver(), targetKey);
+ if (!TextUtils.isEmpty(targetString)) {
+ // The shortcut setting has been set
+ return;
+ }
+
+ // AccessibilityManager#getAccessibilityShortcutTargets may not return correct shortcut
+ // targets during boot. Needs to read settings directly here.
+ targetString = AccessibilityUtils.getShortcutTargetServiceComponentNameString(context,
+ UserHandle.myUserId());
+ if (TextUtils.isEmpty(targetString)) {
+ // No configurable default accessibility service
+ return;
+ }
+
+ // Only fallback to default accessibility service when setting is never updated.
+ final ComponentName shortcutName = ComponentName.unflattenFromString(targetString);
+ if (shortcutName != null) {
+ Settings.Secure.putString(context.getContentResolver(), targetKey,
+ shortcutName.flattenToString());
+ }
+ }
}
diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
index 7ca2abf..e31feaa 100644
--- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
@@ -83,8 +83,6 @@
private static final char COMPONENT_NAME_SEPARATOR = ':';
private static final TextUtils.SimpleStringSplitter sStringColonSplitter =
new TextUtils.SimpleStringSplitter(COMPONENT_NAME_SEPARATOR);
-
- protected Preference mConfigWarningPreference;
protected VideoPreference mVideoPreference;
protected class VideoPreference extends Preference {
@@ -192,12 +190,6 @@
initShortcutPreference();
super.onViewCreated(view, savedInstanceState);
-
- mConfigWarningPreference = new Preference(getPrefContext());
- mConfigWarningPreference.setSelectable(false);
- mConfigWarningPreference.setPersistent(false);
- mConfigWarningPreference.setVisible(false);
- preferenceScreen.addPreference(mConfigWarningPreference);
}
@Override
@@ -219,7 +211,6 @@
videoView.start();
}
- updateConfigurationWarningIfNeeded();
updateShortcutPreferenceData();
updateShortcutPreference();
}
@@ -428,7 +419,6 @@
: DialogEnums.ACCESSIBILITY_BUTTON_TUTORIAL);
}
MagnificationPreferenceFragment.setChecked(getContentResolver(), preferenceKey, enabled);
- updateConfigurationWarningIfNeeded();
}
@Override
@@ -496,16 +486,6 @@
mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext()));
}
- private void updateConfigurationWarningIfNeeded() {
- final CharSequence warningMessage =
- MagnificationPreferenceFragment.getConfigurationWarningStringForSecureSettingsKey(
- mPreferenceKey, getPrefContext());
- if (warningMessage != null) {
- mConfigWarningPreference.setSummary(warningMessage);
- }
- mConfigWarningPreference.setVisible(warningMessage != null);
- }
-
@VisibleForTesting
static void optInAllMagnificationValuesToSettings(Context context, int shortcutTypes) {
if ((shortcutTypes & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) {
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index eb6515e..54af16f 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -43,6 +43,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageItemInfo;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
@@ -143,7 +144,7 @@
implements View.OnClickListener, OnItemSelectedListener, SearchView.OnQueryTextListener {
static final String TAG = "ManageApplications";
- static final boolean DEBUG = false;
+ static final boolean DEBUG = Build.IS_DEBUGGABLE;
// Intent extras.
public static final String EXTRA_CLASSNAME = "classname";
@@ -178,8 +179,6 @@
public static final int STORAGE_TYPE_LEGACY = 2; // Show apps even if they can be categorized.
public static final int STORAGE_TYPE_PHOTOS_VIDEOS = 3;
- private static final int NO_USER_SPECIFIED = -1;
-
/**
* Intents with action {@code android.settings.MANAGE_APP_OVERLAY_PERMISSION}
* and data URI scheme {@code package} don't go to the app-specific screen for managing the
@@ -461,19 +460,8 @@
pinnedHeader.addView(mSpinnerHeader, 0);
final AppFilterRegistry appFilterRegistry = AppFilterRegistry.getInstance();
- mFilterAdapter.enableFilter(appFilterRegistry.getDefaultFilterType(mListType));
-
- AppFilter compositeFilter = getCompositeFilter(mListType, mStorageType, mVolumeUuid);
- if (mIsWorkOnly) {
- compositeFilter = new CompoundFilter(compositeFilter, ApplicationsState.FILTER_WORK);
- }
- if (mIsPersonalOnly) {
- compositeFilter = new CompoundFilter(compositeFilter,
- ApplicationsState.FILTER_PERSONAL);
- }
- if (compositeFilter != null) {
- mApplications.setCompositeFilter(compositeFilter);
- }
+ final int filterType = appFilterRegistry.getDefaultFilterType(mListType);
+ mFilterAdapter.enableFilter(filterType);
if (mListType == LIST_TYPE_MAIN) {
if (UserManager.get(getActivity()).getUserProfiles().size() > 1 && !mIsWorkOnly
@@ -491,6 +479,8 @@
if (mListType == LIST_TYPE_HIGH_POWER) {
mFilterAdapter.enableFilter(FILTER_APPS_POWER_WHITELIST_ALL);
}
+
+ setCompositeFilter();
}
@VisibleForTesting
@@ -511,11 +501,8 @@
return new CompoundFilter(ApplicationsState.FILTER_MOVIES, filter);
} else if (listType == LIST_TYPE_PHOTOGRAPHY) {
return new CompoundFilter(ApplicationsState.FILTER_PHOTOS, filter);
- } else {
- final AppFilterRegistry appFilterRegistry = AppFilterRegistry.getInstance();
- return appFilterRegistry.get(
- appFilterRegistry.getDefaultFilterType(listType)).getFilter();
}
+ return null;
}
@Override
@@ -615,6 +602,21 @@
}
}
+ private void setCompositeFilter() {
+ AppFilter compositeFilter = getCompositeFilter(mListType, mStorageType, mVolumeUuid);
+ if (compositeFilter == null) {
+ compositeFilter = mFilter.getFilter();
+ }
+ if (mIsWorkOnly) {
+ compositeFilter = new CompoundFilter(compositeFilter, ApplicationsState.FILTER_WORK);
+ }
+ if (mIsPersonalOnly) {
+ compositeFilter = new CompoundFilter(compositeFilter,
+ ApplicationsState.FILTER_PERSONAL);
+ }
+ mApplications.setCompositeFilter(compositeFilter);
+ }
+
// utility method used to start sub activity
private void startApplicationDetailsActivity() {
switch (mListType) {
@@ -823,6 +825,7 @@
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
mFilter = mFilterAdapter.getFilter(position);
+ setCompositeFilter();
mApplications.setFilter(mFilter);
if (DEBUG) {
@@ -1227,14 +1230,10 @@
comparatorObj = ApplicationsState.ALPHA_COMPARATOR;
}
- filterObj = new CompoundFilter(filterObj, ApplicationsState.FILTER_NOT_HIDE);
- AppFilter finalFilterObj = filterObj;
+ final AppFilter finalFilterObj = new CompoundFilter(filterObj,
+ ApplicationsState.FILTER_NOT_HIDE);
ThreadUtils.postOnBackgroundThread(() -> {
- final ArrayList<AppEntry> entries = mSession.rebuild(finalFilterObj,
- comparatorObj, false);
- if (entries != null) {
- ThreadUtils.postOnMainThread(() -> onRebuildComplete(entries));
- }
+ mSession.rebuild(finalFilterObj, comparatorObj, false);
});
}
@@ -1284,7 +1283,7 @@
@Override
public void onRebuildComplete(ArrayList<AppEntry> entries) {
if (DEBUG) {
- Log.d(TAG, "onRebuildComplete");
+ Log.d(TAG, "onRebuildComplete size=" + entries.size());
}
final int filterType = mAppFilter.getFilterType();
if (filterType == FILTER_APPS_POWER_WHITELIST ||
diff --git a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesController.java b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesController.java
index 0f7c057..bc8542e 100644
--- a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesController.java
+++ b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesController.java
@@ -17,10 +17,13 @@
package com.android.settings.applications.specialaccess.interactacrossprofiles;
import android.content.Context;
+import android.content.pm.CrossProfileApps;
+import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
+import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import java.util.List;
@@ -33,12 +36,16 @@
private final Context mContext;
private final UserManager mUserManager;
+ private final PackageManager mPackageManager;
+ private final CrossProfileApps mCrossProfileApps;
public InteractAcrossProfilesController(Context context, String preferenceKey) {
super(context, preferenceKey);
mContext = context;
mUserManager = mContext.getSystemService(UserManager.class);
+ mCrossProfileApps = mContext.getSystemService(CrossProfileApps.class);
+ mPackageManager = mContext.getPackageManager();
}
@Override
@@ -51,4 +58,17 @@
}
return DISABLED_FOR_USER;
}
+
+ @Override
+ public CharSequence getSummary() {
+ final int connectedApps = InteractAcrossProfilesSettings.getNumberOfEnabledApps(
+ mContext, mPackageManager, mUserManager, mCrossProfileApps);
+ return connectedApps == 0
+ ? mContext.getResources().getString(
+ R.string.interact_across_profiles_number_of_connected_apps_none)
+ : mContext.getResources().getQuantityString(
+ R.plurals.interact_across_profiles_number_of_connected_apps,
+ connectedApps,
+ connectedApps);
+ }
}
diff --git a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java
index ad40d70..ff61626 100644
--- a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java
+++ b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java
@@ -22,13 +22,15 @@
import android.content.DialogInterface;
import android.content.PermissionChecker;
import android.content.pm.CrossProfileApps;
+import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
-import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.IconDrawableFactory;
+import android.view.View;
import android.widget.ImageView;
+import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
@@ -51,6 +53,7 @@
private UserManager mUserManager;
private SwitchPreference mSwitchPref;
private LayoutPreference mHeader;
+ private PackageManager mPackageManager;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -59,6 +62,7 @@
mContext = getContext();
mCrossProfileApps = mContext.getSystemService(CrossProfileApps.class);
mUserManager = mContext.getSystemService(UserManager.class);
+ mPackageManager = mContext.getPackageManager();
addPreferencesFromResource(R.xml.interact_across_profiles_permissions_details);
mSwitchPref = findPreference(INTERACT_ACROSS_PROFILES_SETTINGS_SWITCH);
@@ -72,10 +76,17 @@
}
final UserHandle workProfile = getWorkProfile();
final UserHandle personalProfile = mUserManager.getProfileParent(workProfile);
- addAppIcons(personalProfile, workProfile);
+ addAppTitleAndIcons(personalProfile, workProfile);
}
- private void addAppIcons(UserHandle personalProfile, UserHandle workProfile) {
+ private void addAppTitleAndIcons(UserHandle personalProfile, UserHandle workProfile) {
+ final TextView title = mHeader.findViewById(R.id.entity_header_title);
+ if (title != null) {
+ final String appLabel = mPackageInfo.applicationInfo.loadLabel(
+ mPackageManager).toString();
+ title.setText(appLabel);
+ }
+
final ImageView personalIconView = mHeader.findViewById(R.id.entity_header_icon_personal);
if (personalIconView != null) {
personalIconView.setImageDrawable(IconDrawableFactory.newInstance(mContext)
@@ -114,35 +125,57 @@
return true;
}
if (!isInteractAcrossProfilesEnabled()) {
- // TODO(b/148594054): Create a proper dialogue.
- new AlertDialog.Builder(getActivity())
- .setTitle(R.string.interact_across_profiles_consent_dialog_title)
- .setMessage(R.string.interact_across_profiles_consent_dialog_summary)
- .setPositiveButton(R.string.allow, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- enableInteractAcrossProfiles(true);
- refreshUi();
- }
- })
- .setNegativeButton(R.string.deny, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- refreshUi();
- }
- })
- .create().show();
- } else {
- enableInteractAcrossProfiles(false);
- refreshUi();
+ showConsentDialog();
}
return true;
}
+ private void showConsentDialog() {
+ final String appLabel = mPackageInfo.applicationInfo.loadLabel(mPackageManager).toString();
+
+ final View dialogView = getLayoutInflater().inflate(
+ R.layout.interact_across_profiles_consent_dialog, null);
+
+ final TextView dialogTitle = dialogView.findViewById(
+ R.id.interact_across_profiles_consent_dialog_title);
+ dialogTitle.setText(
+ getString(R.string.interact_across_profiles_consent_dialog_title, appLabel));
+
+ final TextView dialogSummary = dialogView.findViewById(
+ R.id.interact_across_profiles_consent_dialog_summary);
+ dialogSummary.setText(
+ getString(R.string.interact_across_profiles_consent_dialog_summary, appLabel));
+
+ final TextView appDataSummary = dialogView.findViewById(R.id.app_data_summary);
+ appDataSummary.setText(getString(
+ R.string.interact_across_profiles_consent_dialog_app_data_summary, appLabel));
+
+ final TextView permissionsSummary = dialogView.findViewById(R.id.permissions_summary);
+ permissionsSummary.setText(getString(
+ R.string.interact_across_profiles_consent_dialog_permissions_summary, appLabel));
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setView(dialogView)
+ .setPositiveButton(R.string.allow, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ enableInteractAcrossProfiles(true);
+ refreshUi();
+ }
+ })
+ .setNegativeButton(R.string.deny, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ refreshUi();
+ }
+ })
+ .create().show();
+ }
+
private boolean isInteractAcrossProfilesEnabled() {
return isInteractAcrossProfilesEnabled(
mContext, mPackageName, mPackageInfo.applicationInfo.uid);
}
- private static boolean isInteractAcrossProfilesEnabled(Context context, String packageName, int uid) {
+ static boolean isInteractAcrossProfilesEnabled(Context context, String packageName, int uid) {
return PermissionChecker.PERMISSION_GRANTED
== PermissionChecker.checkPermissionForPreflight(
context,
@@ -178,13 +211,21 @@
return false;
}
- mSwitchPref.setChecked(isInteractAcrossProfilesEnabled());
final ImageView horizontalArrowIcon = mHeader.findViewById(R.id.entity_header_swap_horiz);
- if (horizontalArrowIcon != null) {
- final Drawable icon = mSwitchPref.isChecked()
- ? mContext.getDrawable(R.drawable.ic_swap_horiz_blue)
- : mContext.getDrawable(R.drawable.ic_swap_horiz_grey);
- horizontalArrowIcon.setImageDrawable(icon);
+ if (isInteractAcrossProfilesEnabled()) {
+ mSwitchPref.setChecked(true);
+ mSwitchPref.setTitle(R.string.interact_across_profiles_switch_enabled);
+ if (horizontalArrowIcon != null) {
+ horizontalArrowIcon.setImageDrawable(
+ mContext.getDrawable(R.drawable.ic_swap_horiz_blue));
+ }
+ } else {
+ mSwitchPref.setChecked(false);
+ mSwitchPref.setTitle(R.string.interact_across_profiles_switch_disabled);
+ if (horizontalArrowIcon != null) {
+ horizontalArrowIcon.setImageDrawable(
+ mContext.getDrawable(R.drawable.ic_swap_horiz_grey));
+ }
}
return true;
}
diff --git a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesSettings.java b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesSettings.java
index 2fd1e9f..d686978 100644
--- a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesSettings.java
+++ b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesSettings.java
@@ -73,7 +73,7 @@
screen.removeAll();
final ArrayList<Pair<ApplicationInfo, UserHandle>> crossProfileApps =
- collectConfigurableApps();
+ collectConfigurableApps(mPackageManager, mUserManager, mCrossProfileApps);
final Context prefContext = getPrefContext();
for (final Pair<ApplicationInfo, UserHandle> appData : crossProfileApps) {
@@ -124,21 +124,37 @@
* @return the list of applications for the personal profile in the calling user's profile group
* that can configure interact across profiles.
*/
- ArrayList<Pair<ApplicationInfo, UserHandle>> collectConfigurableApps() {
- final UserHandle personalProfile = getPersonalProfileForCallingUser();
+ static ArrayList<Pair<ApplicationInfo, UserHandle>> collectConfigurableApps(
+ PackageManager packageManager, UserManager userManager,
+ CrossProfileApps crossProfileApps) {
+ final UserHandle personalProfile = getPersonalProfileForCallingUser(userManager);
if (personalProfile == null) {
return new ArrayList<>();
}
- final ArrayList<Pair<ApplicationInfo, UserHandle>> crossProfileApps = new ArrayList<>();
- final List<PackageInfo> installedPackages = mPackageManager.getInstalledPackagesAsUser(
+ final ArrayList<Pair<ApplicationInfo, UserHandle>> apps = new ArrayList<>();
+ final List<PackageInfo> installedPackages = packageManager.getInstalledPackagesAsUser(
GET_ACTIVITIES, personalProfile.getIdentifier());
for (PackageInfo packageInfo : installedPackages) {
- if (mCrossProfileApps.canConfigureInteractAcrossProfiles(packageInfo.packageName)) {
- crossProfileApps.add(new Pair<>(packageInfo.applicationInfo, personalProfile));
+ if (crossProfileApps.canConfigureInteractAcrossProfiles(packageInfo.packageName)) {
+ apps.add(new Pair<>(packageInfo.applicationInfo, personalProfile));
}
}
- return crossProfileApps;
+ return apps;
+ }
+
+ /**
+ * @return the number of applications that can interact across profiles.
+ */
+ static int getNumberOfEnabledApps(
+ Context context, PackageManager packageManager, UserManager userManager,
+ CrossProfileApps crossProfileApps) {
+ final ArrayList<Pair<ApplicationInfo, UserHandle>> apps =
+ collectConfigurableApps(packageManager, userManager, crossProfileApps);
+ apps.removeIf(
+ app -> !InteractAcrossProfilesDetails.isInteractAcrossProfilesEnabled(
+ context, app.first.packageName, app.first.uid));
+ return apps.size();
}
/**
@@ -146,12 +162,12 @@
* Returns null if user is not in a profile group.
*/
@Nullable
- private UserHandle getPersonalProfileForCallingUser() {
+ private static UserHandle getPersonalProfileForCallingUser(UserManager userManager) {
final int callingUser = UserHandle.myUserId();
- if (mUserManager.getProfiles(callingUser).isEmpty()) {
+ if (userManager.getProfiles(callingUser).isEmpty()) {
return null;
}
- final UserInfo parentProfile = mUserManager.getProfileParent(callingUser);
+ final UserInfo parentProfile = userManager.getProfileParent(callingUser);
return parentProfile == null
? UserHandle.of(callingUser) : parentProfile.getUserHandle();
}
diff --git a/src/com/android/settings/core/FeatureFlags.java b/src/com/android/settings/core/FeatureFlags.java
index d2ad30d..331e572 100644
--- a/src/com/android/settings/core/FeatureFlags.java
+++ b/src/com/android/settings/core/FeatureFlags.java
@@ -29,4 +29,5 @@
public static final String CONTROLLER_ENHANCEMENT = "settings_controller_loading_enhancement";
public static final String CONDITIONAL_CARDS = "settings_conditionals";
public static final String TETHER_ALL_IN_ONE = "settings_tether_all_in_one";
+ public static final String CONTEXTUAL_HOME2 = "settings_contextual_home2";
}
diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
index 3a744a9..a2233fc 100644
--- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
@@ -258,7 +258,7 @@
preference.setSummary(summary);
} else if (tile.getMetaData() != null
&& tile.getMetaData().containsKey(META_DATA_PREFERENCE_SUMMARY_URI)) {
- // Set a placeholder summary before starting to fetch real summary, this is necessary
+ // Set a placeholder summary before starting to fetch real summary, this is necessary
// to avoid preference height change.
preference.setSummary(R.string.summary_placeholder);
diff --git a/src/com/android/settings/development/graphicsdriver/GraphicsDriverFooterPreferenceController.java b/src/com/android/settings/development/graphicsdriver/GraphicsDriverFooterPreferenceController.java
index e368aab..4862cfe 100644
--- a/src/com/android/settings/development/graphicsdriver/GraphicsDriverFooterPreferenceController.java
+++ b/src/com/android/settings/development/graphicsdriver/GraphicsDriverFooterPreferenceController.java
@@ -26,6 +26,7 @@
import android.provider.Settings;
import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.core.BasePreferenceController;
@@ -80,6 +81,12 @@
}
@Override
+ public void updateState(Preference preference) {
+ final FooterPreference footerPref = (FooterPreference) preference;
+ footerPref.setVisible(isAvailable());
+ }
+
+ @Override
public void onGraphicsDriverContentChanged() {
updateState(mPreference);
}
diff --git a/src/com/android/settings/deviceinfo/StorageSettings.java b/src/com/android/settings/deviceinfo/StorageSettings.java
index aedaa4c..38626ca 100644
--- a/src/com/android/settings/deviceinfo/StorageSettings.java
+++ b/src/com/android/settings/deviceinfo/StorageSettings.java
@@ -550,6 +550,13 @@
final List<SearchIndexableRaw> result = new ArrayList<>();
SearchIndexableRaw data = new SearchIndexableRaw(context);
+ data.title = context.getString(R.string.storage_settings);
+ data.key = "storage_settings";
+ data.screenTitle = context.getString(R.string.storage_settings);
+ data.keywords = context.getString(R.string.keywords_storage_settings);
+ result.add(data);
+
+ data = new SearchIndexableRaw(context);
data.title = context.getString(R.string.internal_storage);
data.key = "storage_settings_internal_storage";
data.screenTitle = context.getString(R.string.storage_settings);
diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
index 1986965..d7e07d9 100644
--- a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
+++ b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
@@ -27,6 +27,7 @@
import android.os.IBinder;
import android.os.PersistableBundle;
import android.os.RemoteException;
+import android.telephony.AccessNetworkConstants;
import android.telephony.Annotation;
import android.telephony.CarrierConfigManager;
import android.telephony.CellBroadcastIntents;
@@ -42,6 +43,9 @@
import android.telephony.TelephonyManager;
import android.telephony.UiccCardInfo;
import android.telephony.euicc.EuiccManager;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.ImsMmTelManager;
+import android.telephony.ims.ImsReasonInfo;
import android.text.TextUtils;
import android.util.Log;
@@ -107,11 +111,27 @@
new OnSubscriptionsChangedListener() {
@Override
public void onSubscriptionsChanged() {
- mSubscriptionInfo = mSubscriptionManager.getActiveSubscriptionInfo(
- mSubscriptionInfo.getSubscriptionId());
- mTelephonyManager = mTelephonyManager.createForSubscriptionId(
- mSubscriptionInfo.getSubscriptionId());
- updateNetworkProvider();
+ final int prevSubId = (mSubscriptionInfo != null)
+ ? mSubscriptionInfo.getSubscriptionId()
+ : SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+ mSubscriptionInfo = getPhoneSubscriptionInfo(mSlotIndex);
+
+ final int nextSubId = (mSubscriptionInfo != null)
+ ? mSubscriptionInfo.getSubscriptionId()
+ : SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+ if (prevSubId != nextSubId) {
+ if (SubscriptionManager.isValidSubscriptionId(prevSubId)) {
+ unregisterImsRegistrationCallback(prevSubId);
+ }
+ if (SubscriptionManager.isValidSubscriptionId(nextSubId)) {
+ mTelephonyManager =
+ mTelephonyManager.createForSubscriptionId(nextSubId);
+ registerImsRegistrationCallback(nextSubId);
+ }
+ }
+ updateSubscriptionStatus();
}
};
@@ -201,13 +221,17 @@
}
mPhoneStateListener = getPhoneStateListener();
+ updateLatestAreaInfo();
+ updateSubscriptionStatus();
+ }
+
+ private void updateSubscriptionStatus() {
updateNetworkProvider();
final ServiceState serviceState = mTelephonyManager.getServiceState();
final SignalStrength signalStrength = mTelephonyManager.getSignalStrength();
updatePhoneNumber();
- updateLatestAreaInfo();
updateServiceState(serviceState);
updateSignalStrength(signalStrength);
updateNetworkType();
@@ -241,6 +265,7 @@
| PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
| PhoneStateListener.LISTEN_SERVICE_STATE);
mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
+ registerImsRegistrationCallback(mSubscriptionInfo.getSubscriptionId());
if (mShowLatestAreaInfo) {
updateAreaInfoText();
@@ -255,6 +280,7 @@
return;
}
+ unregisterImsRegistrationCallback(mSubscriptionInfo.getSubscriptionId());
mSubscriptionManager.removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
@@ -525,21 +551,68 @@
}
}
- private void updateImsRegistrationState() {
+ private boolean isImsRegistrationStateShowUp() {
final int subscriptionId = mSubscriptionInfo.getSubscriptionId();
final PersistableBundle carrierConfig =
mCarrierConfigManager.getConfigForSubId(subscriptionId);
- final boolean showImsRegState = carrierConfig == null ? false :
+ return carrierConfig == null ? false :
carrierConfig.getBoolean(
CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL);
- if (showImsRegState) {
- final boolean isImsRegistered = mTelephonyManager.isImsRegistered(subscriptionId);
- mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString(isImsRegistered ?
- R.string.ims_reg_status_registered : R.string.ims_reg_status_not_registered));
- } else {
- mDialog.removeSettingFromScreen(IMS_REGISTRATION_STATE_LABEL_ID);
- mDialog.removeSettingFromScreen(IMS_REGISTRATION_STATE_VALUE_ID);
+ }
+
+ private void updateImsRegistrationState() {
+ if (isImsRegistrationStateShowUp()) {
+ return;
}
+ mDialog.removeSettingFromScreen(IMS_REGISTRATION_STATE_LABEL_ID);
+ mDialog.removeSettingFromScreen(IMS_REGISTRATION_STATE_VALUE_ID);
+ }
+
+ private ImsMmTelManager.RegistrationCallback mImsRegStateCallback =
+ new ImsMmTelManager.RegistrationCallback() {
+ @Override
+ public void onRegistered(@AccessNetworkConstants.TransportType int imsTransportType) {
+ mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString(
+ R.string.ims_reg_status_registered));
+ }
+ @Override
+ public void onRegistering(@AccessNetworkConstants.TransportType int imsTransportType) {
+ mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString(
+ R.string.ims_reg_status_not_registered));
+ }
+ @Override
+ public void onUnregistered(@Nullable ImsReasonInfo info) {
+ mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString(
+ R.string.ims_reg_status_not_registered));
+ }
+ @Override
+ public void onTechnologyChangeFailed(
+ @AccessNetworkConstants.TransportType int imsTransportType,
+ @Nullable ImsReasonInfo info) {
+ mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString(
+ R.string.ims_reg_status_not_registered));
+ }
+ };
+
+ private void registerImsRegistrationCallback(int subId) {
+ if (!isImsRegistrationStateShowUp()) {
+ return;
+ }
+ try {
+ final ImsMmTelManager imsMmTelMgr = ImsMmTelManager.createForSubscriptionId(subId);
+ imsMmTelMgr.registerImsRegistrationCallback(mDialog.getContext().getMainExecutor(),
+ mImsRegStateCallback);
+ } catch (ImsException exception) {
+ Log.w(TAG, "fail to register IMS status for subId=" + subId, exception);
+ }
+ }
+
+ private void unregisterImsRegistrationCallback(int subId) {
+ if (!isImsRegistrationStateShowUp()) {
+ return;
+ }
+ final ImsMmTelManager imsMmTelMgr = ImsMmTelManager.createForSubscriptionId(subId);
+ imsMmTelMgr.unregisterImsRegistrationCallback(mImsRegStateCallback);
}
private SubscriptionInfo getPhoneSubscriptionInfo(int slotId) {
diff --git a/src/com/android/settings/homepage/TopLevelSettings.java b/src/com/android/settings/homepage/TopLevelSettings.java
index e27e288..8a7f4bd 100644
--- a/src/com/android/settings/homepage/TopLevelSettings.java
+++ b/src/com/android/settings/homepage/TopLevelSettings.java
@@ -100,5 +100,12 @@
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.top_level_settings);
+ new BaseSearchIndexProvider(R.xml.top_level_settings) {
+
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ // Never searchable, all entries in this page are already indexed elsewhere.
+ return false;
+ }
+ };
}
diff --git a/src/com/android/settings/homepage/contextualcards/CardDatabaseHelper.java b/src/com/android/settings/homepage/contextualcards/CardDatabaseHelper.java
index 39c48c1..8c471b0 100644
--- a/src/com/android/settings/homepage/contextualcards/CardDatabaseHelper.java
+++ b/src/com/android/settings/homepage/contextualcards/CardDatabaseHelper.java
@@ -31,7 +31,7 @@
public class CardDatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "CardDatabaseHelper";
private static final String DATABASE_NAME = "homepage_cards.db";
- private static final int DATABASE_VERSION = 5;
+ private static final int DATABASE_VERSION = 6;
public static final String CARD_TABLE = "cards";
@@ -62,11 +62,6 @@
String CATEGORY = "category";
/**
- * Keep the card last display's locale.
- */
- String LOCALIZED_TO_LOCALE = "localized_to_locale";
-
- /**
* Package name for all card candidates.
*/
String PACKAGE_NAME = "package_name";
@@ -77,51 +72,6 @@
String APP_VERSION = "app_version";
/**
- * Title resource name of the package.
- */
- String TITLE_RES_NAME = "title_res_name";
-
- /**
- * Title of the package to be shown.
- */
- String TITLE_TEXT = "title_text";
-
- /**
- * Summary resource name of the package.
- */
- String SUMMARY_RES_NAME = "summary_res_name";
-
- /**
- * Summary of the package to be shown.
- */
- String SUMMARY_TEXT = "summary_text";
-
- /**
- * Icon resource name of the package.
- */
- String ICON_RES_NAME = "icon_res_name";
-
- /**
- * Icon resource id of the package.
- */
- String ICON_RES_ID = "icon_res_id";
-
- /**
- * Key value mapping to Intent in Settings. Do action when user presses card.
- */
- String CARD_ACTION = "card_action";
-
- /**
- * Expire time of the card. The unit of the value is mini-second.
- */
- String EXPIRE_TIME_MS = "expire_time_ms";
-
- /**
- * Decide the card display full-length width or half-width in screen.
- */
- String SUPPORT_HALF_WIDTH = "support_half_width";
-
- /**
* Decide the card is dismissed or not.
*/
String CARD_DISMISSED = "card_dismissed";
@@ -140,30 +90,10 @@
" TEXT, " +
CardColumns.CATEGORY +
" INTEGER DEFAULT 0, " +
- CardColumns.LOCALIZED_TO_LOCALE +
- " TEXT, " +
CardColumns.PACKAGE_NAME +
" TEXT NOT NULL, " +
CardColumns.APP_VERSION +
" INTEGER NOT NULL, " +
- CardColumns.TITLE_RES_NAME +
- " TEXT, " +
- CardColumns.TITLE_TEXT +
- " TEXT, " +
- CardColumns.SUMMARY_RES_NAME +
- " TEXT, " +
- CardColumns.SUMMARY_TEXT +
- " TEXT, " +
- CardColumns.ICON_RES_NAME +
- " TEXT, " +
- CardColumns.ICON_RES_ID +
- " INTEGER DEFAULT 0, " +
- CardColumns.CARD_ACTION +
- " INTEGER, " +
- CardColumns.EXPIRE_TIME_MS +
- " INTEGER, " +
- CardColumns.SUPPORT_HALF_WIDTH +
- " INTEGER DEFAULT 0, " +
CardColumns.CARD_DISMISSED +
" INTEGER DEFAULT 0 " +
");";
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCard.java b/src/com/android/settings/homepage/contextualcards/ContextualCard.java
index ccfb22d..262cd2f 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCard.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCard.java
@@ -56,17 +56,10 @@
private final double mRankingScore;
private final String mSliceUri;
private final int mCategory;
- private final String mLocalizedToLocale;
private final String mPackageName;
private final long mAppVersion;
- private final String mTitleResName;
private final String mTitleText;
- private final String mSummaryResName;
private final String mSummaryText;
- private final String mIconResName;
- private final int mIconResId;
- private final int mCardAction;
- private final long mExpireTimeMS;
private final boolean mIsLargeCard;
private final Drawable mIconDrawable;
@LayoutRes
@@ -98,10 +91,6 @@
return mCategory;
}
- public String getLocalizedToLocale() {
- return mLocalizedToLocale;
- }
-
public String getPackageName() {
return mPackageName;
}
@@ -110,38 +99,14 @@
return mAppVersion;
}
- public String getTitleResName() {
- return mTitleResName;
- }
-
public String getTitleText() {
return mTitleText;
}
- public String getSummaryResName() {
- return mSummaryResName;
- }
-
public String getSummaryText() {
return mSummaryText;
}
- public String getIconResName() {
- return mIconResName;
- }
-
- public int getIconResId() {
- return mIconResId;
- }
-
- public int getCardAction() {
- return mCardAction;
- }
-
- public long getExpireTimeMS() {
- return mExpireTimeMS;
- }
-
public Drawable getIconDrawable() {
return mIconDrawable;
}
@@ -150,10 +115,6 @@
return mIsLargeCard;
}
- boolean isCustomCard() {
- return TextUtils.isEmpty(mSliceUri);
- }
-
public int getViewType() {
return mViewType;
}
@@ -177,17 +138,10 @@
mRankingScore = builder.mRankingScore;
mSliceUri = builder.mSliceUri;
mCategory = builder.mCategory;
- mLocalizedToLocale = builder.mLocalizedToLocale;
mPackageName = builder.mPackageName;
mAppVersion = builder.mAppVersion;
- mTitleResName = builder.mTitleResName;
mTitleText = builder.mTitleText;
- mSummaryResName = builder.mSummaryResName;
mSummaryText = builder.mSummaryText;
- mIconResName = builder.mIconResName;
- mIconResId = builder.mIconResId;
- mCardAction = builder.mCardAction;
- mExpireTimeMS = builder.mExpireTimeMS;
mIconDrawable = builder.mIconDrawable;
mIsLargeCard = builder.mIsLargeCard;
mViewType = builder.mViewType;
@@ -207,31 +161,14 @@
mBuilder.setSliceUri(Uri.parse(mSliceUri));
mCategory = c.getInt(c.getColumnIndex(CardDatabaseHelper.CardColumns.CATEGORY));
mBuilder.setCategory(mCategory);
- mLocalizedToLocale = c.getString(
- c.getColumnIndex(CardDatabaseHelper.CardColumns.LOCALIZED_TO_LOCALE));
- mBuilder.setLocalizedToLocale(mLocalizedToLocale);
mPackageName = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.PACKAGE_NAME));
mBuilder.setPackageName(mPackageName);
mAppVersion = c.getLong(c.getColumnIndex(CardDatabaseHelper.CardColumns.APP_VERSION));
mBuilder.setAppVersion(mAppVersion);
- mTitleResName = c.getString(
- c.getColumnIndex(CardDatabaseHelper.CardColumns.TITLE_RES_NAME));
- mBuilder.setTitleResName(mTitleResName);
- mTitleText = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.TITLE_TEXT));
+ mTitleText = "";
mBuilder.setTitleText(mTitleText);
- mSummaryResName = c.getString(
- c.getColumnIndex(CardDatabaseHelper.CardColumns.SUMMARY_RES_NAME));
- mBuilder.setSummaryResName(mSummaryResName);
- mSummaryText = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.SUMMARY_TEXT));
- mBuilder.setSummaryText(mSummaryText);
- mIconResName = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.ICON_RES_NAME));
- mBuilder.setIconResName(mIconResName);
- mIconResId = c.getInt(c.getColumnIndex(CardDatabaseHelper.CardColumns.ICON_RES_ID));
- mBuilder.setIconResId(mIconResId);
- mCardAction = c.getInt(c.getColumnIndex(CardDatabaseHelper.CardColumns.CARD_ACTION));
- mBuilder.setCardAction(mCardAction);
- mExpireTimeMS = c.getLong(c.getColumnIndex(CardDatabaseHelper.CardColumns.EXPIRE_TIME_MS));
- mBuilder.setExpireTimeMS(mExpireTimeMS);
+ mSummaryText = "";
+ mBuilder.setTitleText(mSummaryText);
mIsLargeCard = false;
mBuilder.setIsLargeCard(mIsLargeCard);
mIconDrawable = null;
@@ -278,17 +215,10 @@
private double mRankingScore;
private String mSliceUri;
private int mCategory;
- private String mLocalizedToLocale;
private String mPackageName;
private long mAppVersion;
- private String mTitleResName;
private String mTitleText;
- private String mSummaryResName;
private String mSummaryText;
- private String mIconResName;
- private int mIconResId;
- private int mCardAction;
- private long mExpireTimeMS;
private Drawable mIconDrawable;
private boolean mIsLargeCard;
@LayoutRes
@@ -321,11 +251,6 @@
return this;
}
- public Builder setLocalizedToLocale(String localizedToLocale) {
- mLocalizedToLocale = localizedToLocale;
- return this;
- }
-
public Builder setPackageName(String packageName) {
mPackageName = packageName;
return this;
@@ -336,46 +261,16 @@
return this;
}
- public Builder setTitleResName(String titleResName) {
- mTitleResName = titleResName;
- return this;
- }
-
public Builder setTitleText(String titleText) {
mTitleText = titleText;
return this;
}
- public Builder setSummaryResName(String summaryResName) {
- mSummaryResName = summaryResName;
- return this;
- }
-
public Builder setSummaryText(String summaryText) {
mSummaryText = summaryText;
return this;
}
- public Builder setIconResName(String iconResName) {
- mIconResName = iconResName;
- return this;
- }
-
- public Builder setIconResId(int iconResId) {
- mIconResId = iconResId;
- return this;
- }
-
- public Builder setCardAction(int cardAction) {
- mCardAction = cardAction;
- return this;
- }
-
- public Builder setExpireTimeMS(long expireTimeMS) {
- mExpireTimeMS = expireTimeMS;
- return this;
- }
-
public Builder setIconDrawable(Drawable iconDrawable) {
mIconDrawable = iconDrawable;
return this;
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java b/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java
index 17a226d..1c83a10 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java
@@ -16,6 +16,7 @@
package com.android.settings.homepage.contextualcards;
+import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.STICKY_VALUE;
import static com.android.settings.slices.CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI;
import static com.android.settings.slices.CustomSliceRegistry.CONTEXTUAL_NOTIFICATION_CHANNEL_SLICE_URI;
import static com.android.settings.slices.CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI;
@@ -112,9 +113,7 @@
if (cursor.getCount() > 0) {
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
final ContextualCard card = new ContextualCard(cursor);
- if (card.isCustomCard()) {
- //TODO(b/114688391): Load and generate custom card,then add into list
- } else if (isLargeCard(card)) {
+ if (isLargeCard(card)) {
result.add(card.mutate().setIsLargeCard(true).build());
} else {
result.add(card);
@@ -129,18 +128,34 @@
@VisibleForTesting
List<ContextualCard> getDisplayableCards(List<ContextualCard> candidates) {
final List<ContextualCard> eligibleCards = filterEligibleCards(candidates);
+ final List<ContextualCard> stickyCards = new ArrayList<>();
final List<ContextualCard> visibleCards = new ArrayList<>();
final List<ContextualCard> hiddenCards = new ArrayList<>();
- final int size = eligibleCards.size();
- final int cardCount = getCardCount();
- for (int i = 0; i < size; i++) {
- if (i < cardCount) {
- visibleCards.add(eligibleCards.get(i));
- } else {
- hiddenCards.add(eligibleCards.get(i));
+ final int maxCardCount = getCardCount();
+ eligibleCards.forEach(card -> {
+ if (card.getCategory() != STICKY_VALUE) {
+ return;
}
- }
+ if (stickyCards.size() < maxCardCount) {
+ stickyCards.add(card);
+ } else {
+ hiddenCards.add(card);
+ }
+ });
+
+ final int nonStickyCardCount = maxCardCount - stickyCards.size();
+ eligibleCards.forEach(card -> {
+ if (card.getCategory() == STICKY_VALUE) {
+ return;
+ }
+ if (visibleCards.size() < nonStickyCardCount) {
+ visibleCards.add(card);
+ } else {
+ hiddenCards.add(card);
+ }
+ });
+ visibleCards.addAll(stickyCards);
if (!CardContentProvider.DELETE_CARD_URI.equals(mNotifyUri)) {
final MetricsFeatureProvider metricsFeatureProvider =
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java b/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
index 9e9069f..9beb624 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
@@ -17,6 +17,7 @@
package com.android.settings.homepage.contextualcards;
import static com.android.settings.homepage.contextualcards.ContextualCardLoader.CARD_CONTENT_LOADER_ID;
+import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.STICKY_VALUE;
import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE;
import static com.android.settings.slices.CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI;
import static com.android.settings.slices.CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI;
@@ -346,16 +347,23 @@
return result;
}
- // TODO(b/143055685):use category to determine whether they are sticky.
private List<ContextualCard> getCardsWithStickyViewType(List<ContextualCard> cards) {
final List<ContextualCard> result = new ArrayList<>(cards);
int replaceCount = 0;
for (int index = 0; index < result.size(); index++) {
+ final ContextualCard card = cards.get(index);
+ if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2)) {
+ if (card.getCategory() == STICKY_VALUE) {
+ result.set(index, card.mutate().setViewType(
+ SliceContextualCardRenderer.VIEW_TYPE_STICKY).build());
+ }
+ continue;
+ }
+
if (replaceCount > STICKY_CARDS.size() - 1) {
break;
}
- final ContextualCard card = cards.get(index);
if (card.getCardType() != ContextualCard.CardType.SLICE) {
continue;
}
diff --git a/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java b/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java
index 8558ee7..0fcde26 100644
--- a/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java
+++ b/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java
@@ -88,9 +88,6 @@
if (card.getRankingScore() < 0) {
return false;
}
- if (card.isCustomCard()) {
- return true;
- }
final Uri uri = card.getSliceUri();
if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
diff --git a/src/com/android/settings/network/AllInOneTetherPreferenceController.java b/src/com/android/settings/network/AllInOneTetherPreferenceController.java
new file mode 100644
index 0000000..85cfb8b
--- /dev/null
+++ b/src/com/android/settings/network/AllInOneTetherPreferenceController.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2020 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 android.os.UserManager.DISALLOW_CONFIG_TETHERING;
+
+import static com.android.settings.network.TetherEnabler.BLUETOOTH_TETHER_KEY;
+import static com.android.settings.network.TetherEnabler.KEY_ENABLE_WIFI_TETHERING;
+import static com.android.settings.network.TetherEnabler.USB_TETHER_KEY;
+import static com.android.settingslib.RestrictedLockUtilsInternal.checkIfRestrictionEnforced;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothPan;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.UserHandle;
+import android.util.FeatureFlagUtils;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.Lifecycle.Event;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.TetherSettings;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.FeatureFlags;
+import com.android.settings.widget.MasterSwitchController;
+import com.android.settings.widget.MasterSwitchPreference;
+import com.android.settingslib.TetherUtil;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * This controller helps to manage the switch state and visibility of "Hotspot & tethering" switch
+ * preference. It updates the preference summary text based on tethering state.
+ */
+public class AllInOneTetherPreferenceController extends BasePreferenceController implements
+ LifecycleObserver, TetherEnabler.OnTetherStateUpdateListener {
+ private static final String TAG = "AllInOneTetherPreferenceController";
+
+ private static final byte HOTSPOT_ONLY = 1;
+ private static final byte USB_ONLY = 1 << 1;
+ private static final byte BLUETOOTH_ONLY = 1 << 2;
+ private static final byte HOTSPOT_AND_USB = HOTSPOT_ONLY | USB_ONLY;
+ private static final byte HOTSPOT_AND_BLUETOOTH = HOTSPOT_ONLY | BLUETOOTH_ONLY;
+ private static final byte USB_AND_BLUETOOTH = USB_ONLY | BLUETOOTH_ONLY;
+ private static final byte HOTSPOT_AND_USB_AND_BLUETOOTH =
+ HOTSPOT_ONLY | USB_ONLY | BLUETOOTH_ONLY;
+
+ private final boolean mAdminDisallowedTetherConfig;
+ private final AtomicReference<BluetoothPan> mBluetoothPan;
+ private final BluetoothAdapter mBluetoothAdapter;
+ private final SharedPreferences mTetherEnablerSharedPreferences;
+ @VisibleForTesting
+ final BluetoothProfile.ServiceListener mBtProfileServiceListener =
+ new BluetoothProfile.ServiceListener() {
+ @Override
+ public void onServiceConnected(int profile, BluetoothProfile proxy) {
+ mBluetoothPan.set((BluetoothPan) proxy);
+ }
+
+ @Override
+ public void onServiceDisconnected(int profile) {
+ mBluetoothPan.set(null);
+ }
+ };
+
+ private MasterSwitchPreference mPreference;
+ private TetherEnabler mTetherEnabler;
+
+ @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+ AllInOneTetherPreferenceController() {
+ super(null /*context*/, "test");
+ mAdminDisallowedTetherConfig = false;
+ mBluetoothPan = new AtomicReference<>();
+ mBluetoothAdapter = null;
+ mTetherEnablerSharedPreferences = null;
+ }
+
+ public AllInOneTetherPreferenceController(Context context, String key) {
+ super(context, key);
+ mBluetoothPan = new AtomicReference<>();
+ mAdminDisallowedTetherConfig = checkIfRestrictionEnforced(
+ context, DISALLOW_CONFIG_TETHERING, UserHandle.myUserId()) != null;
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ mTetherEnablerSharedPreferences =
+ context.getSharedPreferences(TetherEnabler.SHARED_PREF, Context.MODE_PRIVATE);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = screen.findPreference(mPreferenceKey);
+ if (mPreference != null && !mAdminDisallowedTetherConfig) {
+ // Grey out if provisioning is not available.
+ mPreference.setEnabled(!TetherSettings.isProvisioningNeededButUnavailable(mContext));
+ }
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ if (!TetherUtil.isTetherAvailable(mContext)
+ || !FeatureFlagUtils.isEnabled(mContext, FeatureFlags.TETHER_ALL_IN_ONE)) {
+ return CONDITIONALLY_UNAVAILABLE;
+ } else {
+ return AVAILABLE;
+ }
+ }
+
+ @Override
+ public CharSequence getSummary() {
+ if (mPreference != null && mPreference.isChecked()) {
+ int chosenType = 0;
+ chosenType |= mTetherEnablerSharedPreferences
+ .getBoolean(KEY_ENABLE_WIFI_TETHERING, true) ? HOTSPOT_ONLY : 0;
+ chosenType |= mTetherEnablerSharedPreferences.getBoolean(USB_TETHER_KEY, false)
+ ? USB_ONLY : 0;
+ chosenType |= mTetherEnablerSharedPreferences.getBoolean(BLUETOOTH_TETHER_KEY, false)
+ ? BLUETOOTH_ONLY : 0;
+ switch (chosenType) {
+ case HOTSPOT_ONLY:
+ return mContext.getString(R.string.tether_settings_summary_hotspot_only);
+ case USB_ONLY:
+ return mContext.getString(R.string.tether_settings_summary_usb_tethering_only);
+ case BLUETOOTH_ONLY:
+ return mContext.getString(
+ R.string.tether_settings_summary_bluetooth_tethering_only);
+ case HOTSPOT_AND_USB:
+ return mContext.getString(R.string.tether_settings_summary_hotspot_and_usb);
+ case HOTSPOT_AND_BLUETOOTH:
+ return mContext.getString(
+ R.string.tether_settings_summary_hotspot_and_bluetooth);
+ case USB_AND_BLUETOOTH:
+ return mContext.getString(R.string.tether_settings_summary_usb_and_bluetooth);
+ case HOTSPOT_AND_USB_AND_BLUETOOTH:
+ return mContext.getString(
+ R.string.tether_settings_summary_hotspot_and_usb_and_bluetooth);
+ default:
+ Log.e(TAG, "None of the tether interfaces is chosen");
+ return mContext.getString(R.string.summary_placeholder);
+ }
+ }
+
+ return mContext.getString(R.string.tether_settings_summary_off);
+ }
+
+ @OnLifecycleEvent(Event.ON_CREATE)
+ public void onCreate() {
+ if (mBluetoothAdapter != null
+ && mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
+ mBluetoothAdapter.getProfileProxy(mContext, mBtProfileServiceListener,
+ BluetoothProfile.PAN);
+ }
+ }
+
+ @OnLifecycleEvent(Event.ON_RESUME)
+ public void onResume() {
+ if (mTetherEnabler != null) {
+ mTetherEnabler.setListener(this);
+ }
+ }
+
+ @OnLifecycleEvent(Event.ON_PAUSE)
+ public void onPause() {
+ if (mTetherEnabler != null) {
+ mTetherEnabler.setListener(null);
+ }
+ }
+
+ @OnLifecycleEvent(Event.ON_DESTROY)
+ public void onDestroy() {
+ final BluetoothProfile profile = mBluetoothPan.getAndSet(null);
+ if (profile != null && mBluetoothAdapter != null) {
+ mBluetoothAdapter.closeProfileProxy(BluetoothProfile.PAN, profile);
+ }
+ }
+
+ void initEnabler(Lifecycle lifecycle) {
+ if (mPreference != null) {
+ mTetherEnabler = new TetherEnabler(
+ mContext, new MasterSwitchController(mPreference), mBluetoothPan);
+ if (lifecycle != null) {
+ lifecycle.addObserver(mTetherEnabler);
+ }
+ } else {
+ Log.e(TAG, "TetherEnabler is not initialized");
+ }
+ }
+
+ @Override
+ public void onTetherStateUpdated(boolean isTethering) {
+ updateState(mPreference);
+ }
+}
diff --git a/src/com/android/settings/network/NetworkDashboardFragment.java b/src/com/android/settings/network/NetworkDashboardFragment.java
index 71d7066..ad3df33 100644
--- a/src/com/android/settings/network/NetworkDashboardFragment.java
+++ b/src/com/android/settings/network/NetworkDashboardFragment.java
@@ -20,6 +20,7 @@
import android.app.Dialog;
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AlertDialog;
@@ -65,6 +66,13 @@
use(MultiNetworkHeaderController.class).init(getSettingsLifecycle());
use(AirplaneModePreferenceController.class).setFragment(this);
+ getSettingsLifecycle().addObserver(use(AllInOneTetherPreferenceController.class));
+ }
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ super.onCreatePreferences(savedInstanceState, rootKey);
+ use(AllInOneTetherPreferenceController.class).initEnabler(getSettingsLifecycle());
}
@Override
diff --git a/src/com/android/settings/network/TetherEnabler.java b/src/com/android/settings/network/TetherEnabler.java
index ffb0ef2..e17dcd1 100644
--- a/src/com/android/settings/network/TetherEnabler.java
+++ b/src/com/android/settings/network/TetherEnabler.java
@@ -61,6 +61,20 @@
DataSaverBackend.Listener, LifecycleObserver,
SharedPreferences.OnSharedPreferenceChangeListener {
+ private OnTetherStateUpdateListener mListener;
+
+ /**
+ * Interface definition for a callback to be invoked when the tethering has been updated.
+ */
+ public interface OnTetherStateUpdateListener {
+ /**
+ * Called when the tethering state has changed.
+ *
+ * @param isTethering The new tethering state.
+ */
+ void onTetherStateUpdated(boolean isTethering);
+ }
+
private static final String TAG = "TetherEnabler";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -135,6 +149,10 @@
mContext.unregisterReceiver(mTetherChangeReceiver);
}
+ public void setListener(@Nullable OnTetherStateUpdateListener listener) {
+ mListener = listener;
+ }
+
@VisibleForTesting
void updateState(@Nullable String[] tethered) {
boolean isTethering = tethered == null ? isTethering() : isTethering(tethered);
@@ -143,6 +161,9 @@
}
setSwitchCheckedInternal(isTethering);
mSwitchWidgetController.setEnabled(!mDataSaverEnabled);
+ if (mListener != null) {
+ mListener.onTetherStateUpdated(isTethering);
+ }
}
private void setSwitchCheckedInternal(boolean checked) {
diff --git a/src/com/android/settings/network/TetherPreferenceController.java b/src/com/android/settings/network/TetherPreferenceController.java
index 8fc05aa..d18d897 100644
--- a/src/com/android/settings/network/TetherPreferenceController.java
+++ b/src/com/android/settings/network/TetherPreferenceController.java
@@ -39,7 +39,6 @@
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
-import com.android.settings.AllInOneTetherSettings;
import com.android.settings.R;
import com.android.settings.TetherSettings;
import com.android.settings.core.FeatureFlags;
@@ -112,16 +111,13 @@
// Grey out if provisioning is not available.
mPreference.setEnabled(!TetherSettings.isProvisioningNeededButUnavailable(mContext));
-
- if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.TETHER_ALL_IN_ONE)) {
- mPreference.setFragment(AllInOneTetherSettings.class.getName());
- }
}
}
@Override
public boolean isAvailable() {
- return TetherUtil.isTetherAvailable(mContext);
+ return TetherUtil.isTetherAvailable(mContext)
+ && !FeatureFlagUtils.isEnabled(mContext, FeatureFlags.TETHER_ALL_IN_ONE);
}
@Override
diff --git a/src/com/android/settings/network/ims/ImsQueryController.java b/src/com/android/settings/network/ims/ImsQueryController.java
index f48fc6a..fec862b 100644
--- a/src/com/android/settings/network/ims/ImsQueryController.java
+++ b/src/com/android/settings/network/ims/ImsQueryController.java
@@ -47,13 +47,15 @@
mTransportType = transportType;
}
+ abstract boolean isEnabledByUser(int subId);
+
@VisibleForTesting
- ImsQuery isTtyOnVolteEnabled(int subId) {
- return new ImsQueryTtyOnVolteStat(subId);
+ boolean isTtyOnVolteEnabled(int subId) {
+ return (new ImsQueryTtyOnVolteStat(subId)).query();
}
@VisibleForTesting
- ImsQuery isProvisionedOnDevice(int subId) {
- return new ImsQueryProvisioningStat(subId, mCapability, mTech);
+ boolean isProvisionedOnDevice(int subId) {
+ return (new ImsQueryProvisioningStat(subId, mCapability, mTech)).query();
}
}
diff --git a/src/com/android/settings/network/ims/VolteQueryImsState.java b/src/com/android/settings/network/ims/VolteQueryImsState.java
index 608768a..23f8bab 100644
--- a/src/com/android/settings/network/ims/VolteQueryImsState.java
+++ b/src/com/android/settings/network/ims/VolteQueryImsState.java
@@ -55,8 +55,8 @@
* Implementation of ImsQueryController#isEnabledByUser(int subId)
*/
@VisibleForTesting
- ImsQuery isEnabledByUser(int subId) {
- return new ImsQueryEnhanced4gLteModeUserSetting(subId);
+ boolean isEnabledByUser(int subId) {
+ return (new ImsQueryEnhanced4gLteModeUserSetting(subId)).query();
}
@VisibleForTesting
@@ -77,7 +77,7 @@
}
return imsManager.isVolteEnabledByPlatform()
- && isProvisionedOnDevice(mSubId).query();
+ && isProvisionedOnDevice(mSubId);
}
/**
@@ -101,7 +101,7 @@
}
return ((!isTtyEnabled(mContext))
- || (isTtyOnVolteEnabled(mSubId).query()));
+ || (isTtyOnVolteEnabled(mSubId)));
}
@VisibleForTesting
@@ -119,6 +119,6 @@
if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
return false;
}
- return isEnabledByUser(mSubId).query();
+ return isEnabledByUser(mSubId);
}
}
diff --git a/src/com/android/settings/network/ims/VtQueryImsState.java b/src/com/android/settings/network/ims/VtQueryImsState.java
index a9003b1..60bd729 100644
--- a/src/com/android/settings/network/ims/VtQueryImsState.java
+++ b/src/com/android/settings/network/ims/VtQueryImsState.java
@@ -55,8 +55,8 @@
* Implementation of ImsQueryController#isEnabledByUser(int subId)
*/
@VisibleForTesting
- ImsQuery isEnabledByUser(int subId) {
- return new ImsQueryVtUserSetting(subId);
+ boolean isEnabledByUser(int subId) {
+ return (new ImsQueryVtUserSetting(subId)).query();
}
@VisibleForTesting
@@ -77,7 +77,7 @@
}
return imsManager.isVtEnabledByPlatform()
- && isProvisionedOnDevice(mSubId).query()
+ && isProvisionedOnDevice(mSubId)
&& MobileNetworkUtils.isImsServiceStateReady(imsManager);
}
@@ -91,7 +91,7 @@
return false;
}
return ((!isTtyEnabled(mContext))
- || (isTtyOnVolteEnabled(mSubId).query()));
+ || (isTtyOnVolteEnabled(mSubId)));
}
@VisibleForTesting
@@ -109,6 +109,6 @@
if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
return false;
}
- return isEnabledByUser(mSubId).query();
+ return isEnabledByUser(mSubId);
}
}
diff --git a/src/com/android/settings/network/ims/WifiCallingQueryImsState.java b/src/com/android/settings/network/ims/WifiCallingQueryImsState.java
index ab0bc8c..1667b7f 100644
--- a/src/com/android/settings/network/ims/WifiCallingQueryImsState.java
+++ b/src/com/android/settings/network/ims/WifiCallingQueryImsState.java
@@ -55,8 +55,8 @@
* Implementation of ImsQueryController#isEnabledByUser(int subId)
*/
@VisibleForTesting
- ImsQuery isEnabledByUser(int subId) {
- return new ImsQueryWfcUserSetting(subId);
+ boolean isEnabledByUser(int subId) {
+ return (new ImsQueryWfcUserSetting(subId)).query();
}
@VisibleForTesting
@@ -77,7 +77,7 @@
}
return imsManager.isWfcEnabledByPlatform()
- && isProvisionedOnDevice(mSubId).query();
+ && isProvisionedOnDevice(mSubId);
}
/**
@@ -101,7 +101,7 @@
}
return ((!isTtyEnabled(mContext))
- || (isTtyOnVolteEnabled(mSubId).query()));
+ || (isTtyOnVolteEnabled(mSubId)));
}
@VisibleForTesting
@@ -119,6 +119,6 @@
if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
return false;
}
- return isEnabledByUser(mSubId).query();
+ return isEnabledByUser(mSubId);
}
}
diff --git a/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceController.java b/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceController.java
index daabf8b..b6a78a1 100644
--- a/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceController.java
+++ b/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceController.java
@@ -18,15 +18,18 @@
import android.content.Context;
import android.content.Intent;
+import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.euicc.EuiccManager;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
+import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.network.SubscriptionUtil;
+import com.android.settings.security.ConfirmSimDeletionPreferenceController;
+import com.android.settings.wifi.dpp.WifiDppUtils;
/** This controls a preference allowing the user to delete the profile for an eSIM. */
public class DeleteSimProfilePreferenceController extends BasePreferenceController {
@@ -34,16 +37,19 @@
private SubscriptionInfo mSubscriptionInfo;
private Fragment mParentFragment;
private int mRequestCode;
+ private boolean mConfirmationDefaultOn;
public DeleteSimProfilePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
+ mConfirmationDefaultOn =
+ context.getResources()
+ .getBoolean(R.bool.config_sim_deletion_confirmation_default_on);
}
public void init(int subscriptionId, Fragment parentFragment, int requestCode) {
mParentFragment = parentFragment;
- for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions(
- mContext)) {
+ for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions(mContext)) {
if (info.getSubscriptionId() == subscriptionId && info.isEmbedded()) {
mSubscriptionInfo = info;
break;
@@ -53,16 +59,27 @@
}
@Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
- final Preference pref = screen.findPreference(getPreferenceKey());
- pref.setOnPreferenceClickListener(p -> {
- final Intent intent = new Intent(EuiccManager.ACTION_DELETE_SUBSCRIPTION_PRIVILEGED);
- intent.putExtra(EuiccManager.EXTRA_SUBSCRIPTION_ID,
- mSubscriptionInfo.getSubscriptionId());
- mParentFragment.startActivityForResult(intent, mRequestCode);
- return true;
- });
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ boolean confirmDeletion =
+ Settings.Global.getInt(
+ mContext.getContentResolver(),
+ ConfirmSimDeletionPreferenceController.KEY_CONFIRM_SIM_DELETION,
+ mConfirmationDefaultOn ? 1 : 0)
+ == 1;
+ if (confirmDeletion) {
+ WifiDppUtils.showLockScreen(mContext, () -> deleteSim());
+ } else {
+ deleteSim();
+ }
+
+ return true;
+ }
+
+ private void deleteSim() {
+ final Intent intent = new Intent(EuiccManager.ACTION_DELETE_SUBSCRIPTION_PRIVILEGED);
+ intent.putExtra(EuiccManager.EXTRA_SUBSCRIPTION_ID, mSubscriptionInfo.getSubscriptionId());
+ mParentFragment.startActivityForResult(intent, mRequestCode);
+ // result handled in MobileNetworkSettings
}
@Override
@@ -73,5 +90,4 @@
return CONDITIONALLY_UNAVAILABLE;
}
}
-
}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index 199564d..e5ba96a 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -274,9 +274,11 @@
break;
case REQUEST_CODE_DELETE_SUBSCRIPTION:
- final Activity activity = getActivity();
- if (activity != null && !activity.isFinishing()) {
- activity.finish();
+ if (resultCode != Activity.RESULT_CANCELED) {
+ final Activity activity = getActivity();
+ if (activity != null && !activity.isFinishing()) {
+ activity.finish();
+ }
}
break;
diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java
index c8fb7e3..d6f8986 100644
--- a/src/com/android/settings/notification/NotificationBackend.java
+++ b/src/com/android/settings/notification/NotificationBackend.java
@@ -37,6 +37,8 @@
import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -51,6 +53,7 @@
import com.android.settingslib.R;
import com.android.settingslib.Utils;
+import com.android.settingslib.notification.ConversationIconFactory;
import com.android.settingslib.utils.StringUtil;
import java.util.ArrayList;
@@ -509,10 +512,15 @@
return null;
}
- public Drawable getConversationDrawable(Context context, ShortcutInfo info) {
- LauncherApps la = context.getSystemService(LauncherApps.class);
- return la.getShortcutBadgedIconDrawable(info,
- context.getResources().getDisplayMetrics().densityDpi);
+ public Drawable getConversationDrawable(Context context, ShortcutInfo info, String pkg,
+ int uid) {
+ ConversationIconFactory iconFactory = new ConversationIconFactory(context,
+ context.getSystemService(LauncherApps.class),
+ context.getPackageManager(), IconDrawableFactory.newInstance(context),
+ context.getResources().getDimensionPixelSize(
+ R.dimen.conversation_icon_size));
+ return new BitmapDrawable(context.getResources(),
+ iconFactory.getConversationBitmap(info, pkg, uid));
}
public void requestPinShortcut(Context context, ShortcutInfo shortcutInfo) {
diff --git a/src/com/android/settings/notification/RemoteVolumePreferenceController.java b/src/com/android/settings/notification/RemoteVolumePreferenceController.java
deleted file mode 100644
index bb41975..0000000
--- a/src/com/android/settings/notification/RemoteVolumePreferenceController.java
+++ /dev/null
@@ -1,300 +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.notification;
-
-import android.content.Context;
-import android.media.session.MediaController;
-import android.media.session.MediaSession;
-import android.media.session.MediaSessionManager;
-import android.net.Uri;
-import android.os.Looper;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.VisibleForTesting;
-import androidx.lifecycle.OnLifecycleEvent;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settings.slices.SliceBackgroundWorker;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.volume.MediaSessions;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Objects;
-
-public class RemoteVolumePreferenceController extends VolumeSeekBarPreferenceController {
-
- private static final String KEY_REMOTE_VOLUME = "remote_volume";
- private static final String TAG = "RemoteVolumePrefCtr";
- @VisibleForTesting
- static final int REMOTE_VOLUME = 100;
-
- private MediaSessions mMediaSessions;
- @VisibleForTesting
- MediaSession.Token mActiveToken;
- @VisibleForTesting
- MediaController mMediaController;
-
- @VisibleForTesting
- MediaSessions.Callbacks mCallbacks = new MediaSessions.Callbacks() {
- @Override
- public void onRemoteUpdate(MediaSession.Token token, String name,
- MediaController.PlaybackInfo pi) {
- if (mActiveToken == null) {
- updateToken(token);
- }
- if (Objects.equals(mActiveToken, token)) {
- updatePreference(mPreference, mActiveToken, pi);
- }
- }
-
- @Override
- public void onRemoteRemoved(MediaSession.Token t) {
- if (Objects.equals(mActiveToken, t)) {
- updateToken(null);
- if (mPreference != null) {
- mPreference.setVisible(false);
- }
- }
- }
-
- @Override
- public void onRemoteVolumeChanged(MediaSession.Token token, int flags) {
- if (Objects.equals(mActiveToken, token)) {
- if (mPreference == null) {
- Log.e(TAG,"Preference is null");
- return;
- }
- if (mMediaController == null) {
- Log.e(TAG,"MediaController is null");
- return;
- }
- final MediaController.PlaybackInfo pi = mMediaController.getPlaybackInfo();
- if (pi == null) {
- Log.e(TAG,"PlaybackInfo is null");
- return;
- }
- mPreference.setProgress(pi.getCurrentVolume());
- }
- }
- };
-
- public RemoteVolumePreferenceController(Context context) {
- super(context, KEY_REMOTE_VOLUME);
- mMediaSessions = new MediaSessions(context, Looper.getMainLooper(), mCallbacks);
- updateToken(getActiveRemoteToken(mContext));
- }
-
- @Override
- public int getAvailabilityStatus() {
- // Always return true to make it indexed in database
- return AVAILABLE_UNSEARCHABLE;
- }
-
- /**
- * Return {@link android.media.session.MediaSession.Token} for active remote token, or
- * {@code null} if there is no active remote token.
- */
- public static MediaSession.Token getActiveRemoteToken(Context context) {
- final MediaSessionManager sessionManager = context.getSystemService(
- MediaSessionManager.class);
- final List<MediaController> controllers = sessionManager.getActiveSessions(null);
- for (MediaController mediaController : controllers) {
- final MediaController.PlaybackInfo pi = mediaController.getPlaybackInfo();
- if (isRemote(pi)) {
- return mediaController.getSessionToken();
- }
- }
-
- // No active remote media at this point
- return null;
- }
-
- @Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
- mPreference.setVisible(mActiveToken != null);
- if (mMediaController != null) {
- updatePreference(mPreference, mActiveToken, mMediaController.getPlaybackInfo());
- }
- }
-
- @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
- public void onResume() {
- super.onResume();
- mMediaSessions.init();
- }
-
- @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
- public void onPause() {
- super.onPause();
- mMediaSessions.destroy();
- }
-
- @Override
- public int getSliderPosition() {
- if (mPreference != null) {
- return mPreference.getProgress();
- }
- if (mMediaController == null) {
- return 0;
- }
- final MediaController.PlaybackInfo playbackInfo = mMediaController.getPlaybackInfo();
- return playbackInfo != null ? playbackInfo.getCurrentVolume() : 0;
- }
-
- @Override
- public boolean setSliderPosition(int position) {
- if (mPreference != null) {
- mPreference.setProgress(position);
- }
- if (mMediaController == null) {
- return false;
- }
- mMediaController.setVolumeTo(position, 0);
- return true;
- }
-
- @Override
- public int getMax() {
- if (mPreference != null) {
- return mPreference.getMax();
- }
- if (mMediaController == null) {
- return 0;
- }
- final MediaController.PlaybackInfo playbackInfo = mMediaController.getPlaybackInfo();
- return playbackInfo != null ? playbackInfo.getMaxVolume() : 0;
- }
-
- @Override
- public int getMin() {
- if (mPreference != null) {
- return mPreference.getMin();
- }
- return 0;
- }
-
- @Override
- public boolean isSliceable() {
- return TextUtils.equals(getPreferenceKey(), KEY_REMOTE_VOLUME);
- }
-
- @Override
- public boolean isPublicSlice() {
- return true;
- }
-
- @Override
- public boolean useDynamicSliceSummary() {
- return true;
- }
-
- @Override
- public String getPreferenceKey() {
- return KEY_REMOTE_VOLUME;
- }
-
- @Override
- public int getAudioStream() {
- // This can be anything because remote volume controller doesn't rely on it.
- return REMOTE_VOLUME;
- }
-
- @Override
- public int getMuteIcon() {
- return R.drawable.ic_volume_remote_mute;
- }
-
- public static boolean isRemote(MediaController.PlaybackInfo pi) {
- return pi != null
- && pi.getPlaybackType() == MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE;
- }
-
- @Override
- public Class<? extends SliceBackgroundWorker> getBackgroundWorkerClass() {
- return RemoteVolumeSliceWorker.class;
- }
-
- private void updatePreference(VolumeSeekBarPreference seekBarPreference,
- MediaSession.Token token, MediaController.PlaybackInfo playbackInfo) {
- if (seekBarPreference == null || token == null || playbackInfo == null) {
- return;
- }
-
- seekBarPreference.setMax(playbackInfo.getMaxVolume());
- seekBarPreference.setVisible(true);
- setSliderPosition(playbackInfo.getCurrentVolume());
- }
-
- private void updateToken(MediaSession.Token token) {
- mActiveToken = token;
- if (token != null) {
- mMediaController = new MediaController(mContext, mActiveToken);
- } else {
- mMediaController = null;
- }
- }
-
- /**
- * Listener for background change to remote volume, which listens callback
- * from {@code MediaSessions}
- */
- public static class RemoteVolumeSliceWorker extends SliceBackgroundWorker<Void> implements
- MediaSessions.Callbacks {
-
- private MediaSessions mMediaSessions;
-
- public RemoteVolumeSliceWorker(Context context, Uri uri) {
- super(context, uri);
- mMediaSessions = new MediaSessions(context, Looper.getMainLooper(), this);
- }
-
- @Override
- protected void onSlicePinned() {
- mMediaSessions.init();
- }
-
- @Override
- protected void onSliceUnpinned() {
- mMediaSessions.destroy();
- }
-
- @Override
- public void close() throws IOException {
- mMediaSessions = null;
- }
-
- @Override
- public void onRemoteUpdate(MediaSession.Token token, String name,
- MediaController.PlaybackInfo pi) {
- notifySliceChange();
- }
-
- @Override
- public void onRemoteRemoved(MediaSession.Token t) {
- notifySliceChange();
- }
-
- @Override
- public void onRemoteVolumeChanged(MediaSession.Token token, int flags) {
- notifySliceChange();
- }
- }
-}
diff --git a/src/com/android/settings/notification/SoundSettings.java b/src/com/android/settings/notification/SoundSettings.java
index 7d14691..ad11f55 100644
--- a/src/com/android/settings/notification/SoundSettings.java
+++ b/src/com/android/settings/notification/SoundSettings.java
@@ -179,7 +179,6 @@
volumeControllers.add(use(RingVolumePreferenceController.class));
volumeControllers.add(use(NotificationVolumePreferenceController.class));
volumeControllers.add(use(CallVolumePreferenceController.class));
- volumeControllers.add(use(RemoteVolumePreferenceController.class));
use(HandsFreeProfileOutputPreferenceController.class).setCallback(listPreference ->
onPreferenceDataChanged(listPreference));
@@ -190,6 +189,7 @@
controller.setCallback(mVolumeCallback);
getSettingsLifecycle().addObserver(controller);
}
+ getSettingsLifecycle().addObserver(use(RemoteVolumeGroupController.class));
}
// === Volumes ===
diff --git a/src/com/android/settings/notification/app/ConversationListPreferenceController.java b/src/com/android/settings/notification/app/ConversationListPreferenceController.java
index fa1b050..dba7086 100644
--- a/src/com/android/settings/notification/app/ConversationListPreferenceController.java
+++ b/src/com/android/settings/notification/app/ConversationListPreferenceController.java
@@ -127,7 +127,7 @@
conversation.getParentChannelLabel(), conversation.getGroupLabel())
: conversation.getParentChannelLabel());
if (si != null) {
- pref.setIcon(mBackend.getConversationDrawable(mContext, si));
+ pref.setIcon(mBackend.getConversationDrawable(mContext, si, mAppRow.pkg, mAppRow.uid));
}
pref.setKey(conversation.getNotificationChannel().getId());
diff --git a/src/com/android/settings/notification/app/NotificationSettings.java b/src/com/android/settings/notification/app/NotificationSettings.java
index 983ad2b..e30b35c 100644
--- a/src/com/android/settings/notification/app/NotificationSettings.java
+++ b/src/com/android/settings/notification/app/NotificationSettings.java
@@ -33,6 +33,7 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.UserHandle;
@@ -203,7 +204,8 @@
mConversationInfo = mBackend.getConversationInfo(
mContext, mPkg, mUid, mChannel.getConversationId());
if (mConversationInfo != null) {
- mConversationDrawable = mBackend.getConversationDrawable(mContext, mConversationInfo);
+ mConversationDrawable = mBackend.getConversationDrawable(
+ mContext, mConversationInfo, mAppRow.pkg, mAppRow.uid);
}
}
diff --git a/src/com/android/settings/notification/history/NotificationHistoryActivity.java b/src/com/android/settings/notification/history/NotificationHistoryActivity.java
index a02d3aa..9b78ae9 100644
--- a/src/com/android/settings/notification/history/NotificationHistoryActivity.java
+++ b/src/com/android/settings/notification/history/NotificationHistoryActivity.java
@@ -129,6 +129,7 @@
mPm = getPackageManager();
+ mTodayView.removeAllViews();
mHistoryLoader = new HistoryLoader(this, new NotificationBackend(), mPm);
mHistoryLoader.load(mOnHistoryLoaderListener);
@@ -245,16 +246,18 @@
LinearLayoutManager lm = new LinearLayoutManager(NotificationHistoryActivity.this);
rv.setLayoutManager(lm);
rv.setAdapter(new NotificationSbnAdapter(NotificationHistoryActivity.this, mPm));
- ((NotificationSbnAdapter) rv.getAdapter()).onRebuildComplete(
- Arrays.asList(snoozed));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(
rv.getContext(), lm.getOrientation());
rv.addItemDecoration(dividerItemDecoration);
+ rv.setNestedScrollingEnabled(false);
+
+ ((NotificationSbnAdapter) rv.getAdapter()).onRebuildComplete(
+ Arrays.asList(snoozed));
}
try {
StatusBarNotification[] dismissed = mNm.getHistoricalNotifications(
- NotificationHistoryActivity.this.getPackageName(), 10, false);
+ NotificationHistoryActivity.this.getPackageName(), 6, false);
RecyclerView rv = mDismissView.findViewById(R.id.notification_list);
LinearLayoutManager lm = new LinearLayoutManager(NotificationHistoryActivity.this);
rv.setLayoutManager(lm);
@@ -262,6 +265,8 @@
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(
rv.getContext(), lm.getOrientation());
rv.addItemDecoration(dividerItemDecoration);
+ rv.setNestedScrollingEnabled(false);
+
((NotificationSbnAdapter) rv.getAdapter()).onRebuildComplete(
Arrays.asList(dismissed));
mDismissView.setVisibility(View.VISIBLE);
diff --git a/src/com/android/settings/notification/history/NotificationHistoryAdapter.java b/src/com/android/settings/notification/history/NotificationHistoryAdapter.java
index 87804d5..4448dee 100644
--- a/src/com/android/settings/notification/history/NotificationHistoryAdapter.java
+++ b/src/com/android/settings/notification/history/NotificationHistoryAdapter.java
@@ -63,7 +63,8 @@
holder.setTitle(hn.getTitle());
holder.setSummary(hn.getText());
holder.setPostedTime(hn.getPostedTimeMs());
- holder.addOnClick(hn.getPackage(), hn.getUserId(), hn.getChannelId());
+ holder.addOnClick(hn.getPackage(), hn.getUserId(), hn.getChannelId(),
+ hn.getConversationId());
}
@Override
diff --git a/src/com/android/settings/notification/history/NotificationHistoryViewHolder.java b/src/com/android/settings/notification/history/NotificationHistoryViewHolder.java
index e7caa6a..d1f47af 100644
--- a/src/com/android/settings/notification/history/NotificationHistoryViewHolder.java
+++ b/src/com/android/settings/notification/history/NotificationHistoryViewHolder.java
@@ -18,6 +18,7 @@
import static android.provider.Settings.EXTRA_APP_PACKAGE;
import static android.provider.Settings.EXTRA_CHANNEL_ID;
+import static android.provider.Settings.EXTRA_CONVERSATION_ID;
import android.content.Intent;
import android.os.UserHandle;
@@ -61,11 +62,12 @@
mTime.setTime(postedTime);
}
- void addOnClick(String pkg, int userId, String channelId) {
+ void addOnClick(String pkg, int userId, String channelId, String conversationId) {
itemView.setOnClickListener(v -> {
Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
.putExtra(EXTRA_APP_PACKAGE, pkg)
- .putExtra(EXTRA_CHANNEL_ID, channelId);
+ .putExtra(EXTRA_CHANNEL_ID, channelId)
+ .putExtra(EXTRA_CONVERSATION_ID, conversationId);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
itemView.getContext().startActivityAsUser(intent, UserHandle.of(userId));
});
diff --git a/src/com/android/settings/notification/history/NotificationSbnAdapter.java b/src/com/android/settings/notification/history/NotificationSbnAdapter.java
index 77740d7..a35b5d4 100644
--- a/src/com/android/settings/notification/history/NotificationSbnAdapter.java
+++ b/src/com/android/settings/notification/history/NotificationSbnAdapter.java
@@ -94,6 +94,13 @@
}
public void onRebuildComplete(List<StatusBarNotification> notifications) {
+ // summaries are low content; don't bother showing them
+ for (int i = notifications.size() - 1; i >= 0; i--) {
+ StatusBarNotification sbn = notifications.get(i);
+ if (sbn.isGroup() && sbn.getNotification().isGroupSummary()) {
+ notifications.remove(i);
+ }
+ }
mValues = notifications;
notifyDataSetChanged();
}
diff --git a/src/com/android/settings/notification/zen/ZenAutomaticRuleHeaderPreferenceController.java b/src/com/android/settings/notification/zen/ZenAutomaticRuleHeaderPreferenceController.java
index 4f6717b..8139555 100644
--- a/src/com/android/settings/notification/zen/ZenAutomaticRuleHeaderPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenAutomaticRuleHeaderPreferenceController.java
@@ -25,7 +25,6 @@
import android.graphics.drawable.Drawable;
import android.service.notification.ZenModeConfig;
import android.util.Slog;
-import android.view.View;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
@@ -61,31 +60,21 @@
return mRule != null;
}
+ @Override
public void updateState(Preference preference) {
- if (mRule == null) {
+ if (mRule == null || mFragment == null) {
return;
}
- if (mFragment != null) {
- LayoutPreference pref = (LayoutPreference) preference;
-
- if (mController == null) {
- mController = EntityHeaderController
- .newInstance(mFragment.getActivity(), mFragment,
- pref.findViewById(R.id.entity_header));
- }
-
- pref = mController.setIcon(getIcon())
- .setLabel(mRule.getName())
- .setPackageName(mRule.getOwner().getPackageName())
- .setUid(mContext.getUserId())
- .setHasAppInfoLink(false)
- .setButtonActions(EntityHeaderController.ActionType.ACTION_EDIT_PREFERENCE,
- EntityHeaderController.ActionType.ACTION_NONE)
- .done(mFragment.getActivity(), mContext);
-
- pref.findViewById(R.id.entity_header).setVisibility(View.VISIBLE);
+ if (mController == null) {
+ final LayoutPreference pref = (LayoutPreference) preference;
+ mController = EntityHeaderController.newInstance(mFragment.getActivity(), mFragment,
+ pref.findViewById(R.id.entity_header));
}
+
+ mController.setIcon(getIcon())
+ .setLabel(mRule.getName())
+ .done(mFragment.getActivity(), false /* rebindActions */);
}
private Drawable getIcon() {
diff --git a/src/com/android/settings/panel/PanelContent.java b/src/com/android/settings/panel/PanelContent.java
index 5670469..60b9ed7 100644
--- a/src/com/android/settings/panel/PanelContent.java
+++ b/src/com/android/settings/panel/PanelContent.java
@@ -55,7 +55,6 @@
*/
List<Uri> getSlices();
-
/**
* @return an {@link Intent} to the full content in Settings that is summarized by the Panel.
*
@@ -64,4 +63,15 @@
* </p>
*/
Intent getSeeMoreIntent();
+
+ /**
+ * @return an {@link Intent} to the go to the target activity.
+ *
+ * <p>
+ * A common usage is to go back to previous panel.
+ * </p>
+ */
+ default Intent getHeaderIconIntent() {
+ return null;
+ }
}
diff --git a/src/com/android/settings/panel/PanelFragment.java b/src/com/android/settings/panel/PanelFragment.java
index 8fda894..0f46758 100644
--- a/src/com/android/settings/panel/PanelFragment.java
+++ b/src/com/android/settings/panel/PanelFragment.java
@@ -201,6 +201,9 @@
mTitleIcon.setImageIcon(icon.toIcon(getContext()));
mHeaderTitle.setText(mPanel.getTitle());
mHeaderSubtitle.setText(mPanel.getSubTitle());
+ if (mPanel.getHeaderIconIntent() != null) {
+ mTitleIcon.setOnClickListener(getHeaderIconListener());
+ }
}
mSeeMoreButton.setOnClickListener(getSeeMoreListener());
mDoneButton.setOnClickListener(getCloseListener());
@@ -381,4 +384,12 @@
getActivity().finish();
};
}
+
+ @VisibleForTesting
+ View.OnClickListener getHeaderIconListener() {
+ return (v) -> {
+ final FragmentActivity activity = getActivity();
+ activity.startActivity(mPanel.getHeaderIconIntent());
+ };
+ }
}
diff --git a/src/com/android/settings/password/BiometricFragment.java b/src/com/android/settings/password/BiometricFragment.java
index fe0740b..bc0e5c7 100644
--- a/src/com/android/settings/password/BiometricFragment.java
+++ b/src/com/android/settings/password/BiometricFragment.java
@@ -130,8 +130,12 @@
.setDeviceCredentialAllowed(true)
.setSubtitle(mBundle.getString(BiometricPrompt.KEY_SUBTITLE))
.setDescription(mBundle.getString(BiometricPrompt.KEY_DESCRIPTION))
- .setConfirmationRequired(
- mBundle.getBoolean(BiometricPrompt.KEY_REQUIRE_CONFIRMATION, true))
+ .setTextForDeviceCredential(
+ mBundle.getCharSequence(BiometricPrompt.KEY_DEVICE_CREDENTIAL_TITLE),
+ mBundle.getCharSequence(BiometricPrompt.KEY_DEVICE_CREDENTIAL_SUBTITLE),
+ mBundle.getCharSequence(BiometricPrompt.KEY_DEVICE_CREDENTIAL_DESCRIPTION))
+ .setConfirmationRequired(mBundle.getBoolean(
+ BiometricPrompt.KEY_REQUIRE_CONFIRMATION, true))
.setDisallowBiometricsIfPolicyExists(mBundle.getBoolean(
BiometricPrompt.EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS, false));
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
index 6f505bd..83368f9 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
@@ -182,14 +182,7 @@
if ((mTitle == null) && isManagedProfile) {
mTitle = getTitleFromOrganizationName(mUserId);
}
- final @LockPatternUtils.CredentialType int credentialType = Utils.getCredentialType(
- mContext, effectiveUserId);
- if (mTitle == null) {
- mTitle = getTitleFromCredentialType(credentialType, isManagedProfile);
- }
- if (mDetails == null) {
- mDetails = getDetailsFromCredentialType(credentialType, isManagedProfile);
- }
+
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this);
final LockPatternUtils lockPatternUtils = new LockPatternUtils(this);
@@ -200,6 +193,17 @@
bpBundle.putBoolean(BiometricPrompt.EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS,
mCheckDevicePolicyManager);
+ final @LockPatternUtils.CredentialType int credentialType = Utils.getCredentialType(
+ mContext, effectiveUserId);
+ if (mTitle == null) {
+ bpBundle.putString(BiometricPrompt.KEY_DEVICE_CREDENTIAL_TITLE,
+ getTitleFromCredentialType(credentialType, isManagedProfile));
+ }
+ if (mDetails == null) {
+ bpBundle.putString(BiometricPrompt.KEY_DEVICE_CREDENTIAL_DESCRIPTION,
+ getDetailsFromCredentialType(credentialType, isManagedProfile));
+ }
+
boolean launchedBiometric = false;
boolean launchedCDC = false;
// If the target is a managed user and user key not unlocked yet, we will force unlock
diff --git a/src/com/android/settings/security/ConfirmSimDeletionPreferenceController.java b/src/com/android/settings/security/ConfirmSimDeletionPreferenceController.java
new file mode 100644
index 0000000..f24d8db
--- /dev/null
+++ b/src/com/android/settings/security/ConfirmSimDeletionPreferenceController.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2020 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.app.KeyguardManager;
+import android.content.Context;
+import android.provider.Settings;
+
+import androidx.preference.Preference;
+import androidx.preference.TwoStatePreference;
+
+import com.android.settings.R;
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.network.telephony.MobileNetworkUtils;
+
+/** Enable/disable user confirmation before deleting an eSim */
+public class ConfirmSimDeletionPreferenceController extends TogglePreferenceController {
+ public static final String KEY_CONFIRM_SIM_DELETION = "confirm_sim_deletion";
+ private boolean mConfirmationDefaultOn;
+
+ public ConfirmSimDeletionPreferenceController(Context context, String key) {
+ super(context, key);
+ mConfirmationDefaultOn =
+ context.getResources()
+ .getBoolean(R.bool.config_sim_deletion_confirmation_default_on);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ // hide if eSim is not supported on the device
+ return MobileNetworkUtils.showEuiccSettings(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ }
+
+ private boolean getGlobalState() {
+ return Settings.Global.getInt(
+ mContext.getContentResolver(),
+ KEY_CONFIRM_SIM_DELETION,
+ mConfirmationDefaultOn ? 1 : 0)
+ == 1;
+ }
+
+ @Override
+ public boolean isChecked() {
+ return getGlobalState();
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ Settings.Global.putInt(
+ mContext.getContentResolver(), KEY_CONFIRM_SIM_DELETION, isChecked ? 1 : 0);
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+
+ final KeyguardManager keyguardManager = mContext.getSystemService(KeyguardManager.class);
+ if (!keyguardManager.isKeyguardSecure()) {
+ preference.setEnabled(false);
+ if (preference instanceof TwoStatePreference) {
+ ((TwoStatePreference) preference).setChecked(false);
+ }
+ preference.setSummary(R.string.disabled_because_no_backup_security);
+ } else {
+ preference.setEnabled(true);
+ if (preference instanceof TwoStatePreference) {
+ ((TwoStatePreference) preference).setChecked(getGlobalState());
+ }
+ preference.setSummary(R.string.confirm_sim_deletion_description);
+ }
+ }
+}
diff --git a/src/com/android/settings/security/SecuritySettings.java b/src/com/android/settings/security/SecuritySettings.java
index da8f003..effbd70 100644
--- a/src/com/android/settings/security/SecuritySettings.java
+++ b/src/com/android/settings/security/SecuritySettings.java
@@ -20,7 +20,6 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
-import android.provider.SearchIndexableResource;
import com.android.settings.R;
import com.android.settings.biometrics.face.FaceProfileStatusPreferenceController;
diff --git a/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java b/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java
index ce036d2..852f286 100644
--- a/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java
+++ b/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java
@@ -20,6 +20,7 @@
import android.os.Bundle;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.EventLog;
import android.util.Log;
import com.android.settings.bluetooth.BluetoothSliceBuilder;
@@ -73,6 +74,11 @@
private static Uri parse(Uri uri) {
final String sliceParameter = uri.getQueryParameter(EXTRA_SLICE);
- return TextUtils.isEmpty(sliceParameter) ? null : Uri.parse(sliceParameter);
+ if (TextUtils.isEmpty(sliceParameter)) {
+ EventLog.writeEvent(0x534e4554, "122836081", -1, "");
+ return null;
+ } else {
+ return Uri.parse(sliceParameter);
+ }
}
}
diff --git a/src/com/android/settings/users/AddUserWhenLockedPreferenceController.java b/src/com/android/settings/users/AddUserWhenLockedPreferenceController.java
index 34892fa..df2f54e 100644
--- a/src/com/android/settings/users/AddUserWhenLockedPreferenceController.java
+++ b/src/com/android/settings/users/AddUserWhenLockedPreferenceController.java
@@ -28,15 +28,12 @@
public class AddUserWhenLockedPreferenceController extends TogglePreferenceController {
private final UserCapabilities mUserCaps;
- private LockPatternUtils mLockPatternUtils;
+ private final LockPatternUtils mLockPatternUtils;
public AddUserWhenLockedPreferenceController(Context context, String key) {
super(context, key);
mUserCaps = UserCapabilities.create(context);
- }
-
- void setLockPatternUtils(LockPatternUtils lockPatternUtils) {
- mLockPatternUtils = lockPatternUtils;
+ mLockPatternUtils = new LockPatternUtils(context);
}
@Override
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 51da9d2..6397af8 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -241,8 +241,6 @@
mAddUserWhenLockedPreferenceController = new AddUserWhenLockedPreferenceController(
activity, KEY_ADD_USER_WHEN_LOCKED);
- mAddUserWhenLockedPreferenceController.setLockPatternUtils(
- new LockPatternUtils(getPrefContext()));
mMultiUserFooterPreferenceController = new MultiUserFooterPreferenceController(activity,
KEY_MULTIUSER_FOOTER);
@@ -1296,7 +1294,6 @@
AddUserWhenLockedPreferenceController controller =
new AddUserWhenLockedPreferenceController(
context, KEY_ADD_USER_WHEN_LOCKED);
- controller.setLockPatternUtils(new LockPatternUtils(context));
controller.updateNonIndexableKeys(niks);
new AutoSyncDataPreferenceController(context, null /* parent */)
.updateNonIndexableKeys(niks);
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index 626e4f3..d9b9e3c 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -667,7 +667,7 @@
config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
if (mAccessPointSecurity == AccessPoint.SECURITY_EAP_SUITE_B) {
config.allowedKeyManagement.set(KeyMgmt.SUITE_B_192);
- config.requirePMF = true;
+ config.requirePmf = true;
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
config.allowedGroupManagementCiphers.set(WifiConfiguration.GroupMgmtCipher
@@ -807,7 +807,7 @@
break;
case AccessPoint.SECURITY_SAE:
config.allowedKeyManagement.set(KeyMgmt.SAE);
- config.requirePMF = true;
+ config.requirePmf = true;
if (mPasswordView.length() != 0) {
String password = mPasswordView.getText().toString();
config.preSharedKey = '"' + password + '"';
@@ -816,7 +816,7 @@
case AccessPoint.SECURITY_OWE:
config.allowedKeyManagement.set(KeyMgmt.OWE);
- config.requirePMF = true;
+ config.requirePmf = true;
break;
default:
diff --git a/src/com/android/settings/wifi/WifiConfigController2.java b/src/com/android/settings/wifi/WifiConfigController2.java
index 26042f5..8352a76 100644
--- a/src/com/android/settings/wifi/WifiConfigController2.java
+++ b/src/com/android/settings/wifi/WifiConfigController2.java
@@ -662,7 +662,7 @@
config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
if (mWifiEntrySecurity == WifiEntry.SECURITY_EAP_SUITE_B) {
config.allowedKeyManagement.set(KeyMgmt.SUITE_B_192);
- config.requirePMF = true;
+ config.requirePmf = true;
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
config.allowedGroupManagementCiphers.set(WifiConfiguration.GroupMgmtCipher
@@ -801,7 +801,7 @@
break;
case WifiEntry.SECURITY_SAE:
config.allowedKeyManagement.set(KeyMgmt.SAE);
- config.requirePMF = true;
+ config.requirePmf = true;
if (mPasswordView.length() != 0) {
String password = mPasswordView.getText().toString();
config.preSharedKey = '"' + password + '"';
@@ -810,7 +810,7 @@
case WifiEntry.SECURITY_OWE:
config.allowedKeyManagement.set(KeyMgmt.OWE);
- config.requirePMF = true;
+ config.requirePmf = true;
break;
default:
diff --git a/src/com/android/settings/wifi/WifiUtils.java b/src/com/android/settings/wifi/WifiUtils.java
index 4faf11f..08ba441 100644
--- a/src/com/android/settings/wifi/WifiUtils.java
+++ b/src/com/android/settings/wifi/WifiUtils.java
@@ -193,7 +193,7 @@
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
if (security == AccessPoint.SECURITY_EAP_SUITE_B) {
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192);
- config.requirePMF = true;
+ config.requirePmf = true;
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
config.allowedGroupManagementCiphers.set(WifiConfiguration.GroupMgmtCipher
@@ -207,7 +207,7 @@
break;
case AccessPoint.SECURITY_SAE:
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE);
- config.requirePMF = true;
+ config.requirePmf = true;
if (!TextUtils.isEmpty(password)) {
config.preSharedKey = '"' + password + '"';
}
@@ -215,7 +215,7 @@
case AccessPoint.SECURITY_OWE:
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE);
- config.requirePMF = true;
+ config.requirePmf = true;
break;
default:
diff --git a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
index cc9c22f..a00bb23 100644
--- a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
+++ b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
@@ -30,6 +30,7 @@
import android.telephony.PhoneStateListener;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.ims.ImsManager;
import android.telephony.ims.ImsMmTelManager;
import android.telephony.ims.ProvisioningManager;
import android.text.TextUtils;
@@ -46,7 +47,6 @@
import androidx.preference.PreferenceScreen;
import com.android.ims.ImsConfig;
-import com.android.ims.ImsManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Phone;
import com.android.settings.R;
@@ -100,7 +100,7 @@
private boolean mUseWfcHomeModeForRoaming = false;
private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
- private ImsManager mImsManager;
+ private com.android.ims.ImsManager mImsManager;
private ImsMmTelManager mImsMmTelManager;
private ProvisioningManager mProvisioningManager;
private TelephonyManager mTelephonyManager;
@@ -222,7 +222,7 @@
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
- if (action.equals(ImsManager.ACTION_IMS_REGISTRATION_ERROR)) {
+ if (action.equals(ImsManager.ACTION_WFC_IMS_REGISTRATION_ERROR)) {
// If this fragment is active then we are immediately
// showing alert on screen. There is no need to add
// notification in this case.
@@ -261,8 +261,8 @@
}
@VisibleForTesting
- ImsManager getImsManager() {
- return ImsManager.getInstance(getActivity(),
+ com.android.ims.ImsManager getImsManager() {
+ return com.android.ims.ImsManager.getInstance(getActivity(),
SubscriptionUtil.getPhoneId(getActivity(), mSubId));
}
@@ -305,7 +305,7 @@
mUpdateAddress.setOnPreferenceClickListener(mUpdateAddressListener);
mIntentFilter = new IntentFilter();
- mIntentFilter.addAction(ImsManager.ACTION_IMS_REGISTRATION_ERROR);
+ mIntentFilter.addAction(ImsManager.ACTION_WFC_IMS_REGISTRATION_ERROR);
}
@Override
diff --git a/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java b/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java
index 3c3aa7d..fdd0bbe 100644
--- a/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java
+++ b/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java
@@ -253,7 +253,7 @@
final WifiConfiguration enhancedOpenNetworkWifiConfiguration =
getBasicWifiConfiguration();
enhancedOpenNetworkWifiConfiguration.allowedKeyManagement.set(KeyMgmt.OWE);
- enhancedOpenNetworkWifiConfiguration.requirePMF = true;
+ enhancedOpenNetworkWifiConfiguration.requirePmf = true;
wifiConfigurations.add(enhancedOpenNetworkWifiConfiguration);
return wifiConfigurations;
}
@@ -282,7 +282,7 @@
}
} else if (mSecurity.startsWith(SECURITY_SAE)) {
wifiConfiguration.allowedKeyManagement.set(KeyMgmt.SAE);
- wifiConfiguration.requirePMF = true;
+ wifiConfiguration.requirePmf = true;
if (mPreSharedKey.length() != 0) {
wifiConfiguration.preSharedKey = addQuotationIfNeeded(mPreSharedKey);
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceControllerTest.java
new file mode 100644
index 0000000..53f6cc0
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceControllerTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2020 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.accessibility;
+
+import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
+import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+import androidx.preference.SwitchPreference;
+
+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 AccessibilityShortcutPreferenceControllerTest {
+
+ private Context mContext;
+ private SwitchPreference mPreference;
+ private AccessibilityShortcutPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ mPreference = new SwitchPreference(mContext);
+ mController = new AccessibilityShortcutPreferenceController(mContext,
+ "accessibility_shortcut_preference");
+ }
+
+ @Test
+ public void isChecked_enabledShortcutOnLockScreen_shouldReturnTrue() {
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, ON, UserHandle.USER_CURRENT);
+
+ mController.updateState(mPreference);
+
+ assertThat(mController.isChecked()).isTrue();
+ assertThat(mPreference.isChecked()).isTrue();
+ }
+
+ @Test
+ public void isChecked_disabledShortcutOnLockScreen_shouldReturnFalse() {
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, OFF,
+ UserHandle.USER_CURRENT);
+
+ mController.updateState(mPreference);
+
+ assertThat(mController.isChecked()).isFalse();
+ assertThat(mPreference.isChecked()).isFalse();
+ }
+
+ @Test
+ public void setChecked_setTrue_shouldEnableShortcutOnLockScreen() {
+ mController.setChecked(true);
+
+ assertThat(Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, OFF,
+ UserHandle.USER_CURRENT)).isEqualTo(ON);
+ }
+
+ @Test
+ public void setChecked_setFalse_shouldDisableShortcutOnLockScreen() {
+ mController.setChecked(false);
+
+ assertThat(Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, ON,
+ UserHandle.USER_CURRENT)).isEqualTo(OFF);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/DaltonizerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/DaltonizerPreferenceControllerTest.java
index 62eb074..1a00cc1 100644
--- a/tests/robotests/src/com/android/settings/accessibility/DaltonizerPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/DaltonizerPreferenceControllerTest.java
@@ -34,7 +34,6 @@
private static final String PREF_KEY = "daltonizer_preference";
private static final int ON = 1;
private static final int OFF = 0;
- private static final String DALTONIZER_VALUE = "11";
private Context mContext;
private DaltonizerPreferenceController mController;
@@ -62,13 +61,4 @@
assertThat(mController.getSummary().toString().contains(
mContext.getText(R.string.accessibility_feature_state_off))).isTrue();
}
-
- @Test
- public void getSummary_selectProtanomaly_shouldReturnProtanomalySummary() {
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, DALTONIZER_VALUE);
-
- assertThat(mController.getSummary().toString().contains(
- mContext.getText(R.string.daltonizer_mode_protanomaly))).isTrue();
- }
}
diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesSettingsTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesSettingsTest.java
index 9a4c56b..db5507a 100644
--- a/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesSettingsTest.java
@@ -20,10 +20,12 @@
import static org.robolectric.Shadows.shadowOf;
+import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.CrossProfileApps;
import android.content.pm.PackageManager;
+import android.content.pm.PermissionInfo;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Pair;
@@ -32,12 +34,10 @@
import com.google.common.collect.ImmutableList;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadows.ShadowProcess;
-import org.robolectric.util.ReflectionHelpers;
import java.util.List;
@@ -47,6 +47,7 @@
private static final int PERSONAL_PROFILE_ID = 0;
private static final int WORK_PROFILE_ID = 10;
private static final int WORK_UID = UserHandle.PER_USER_RANGE * WORK_PROFILE_ID;
+ private static final int PACKAGE_UID = 0;
private static final String PERSONAL_CROSS_PROFILE_PACKAGE = "personalCrossProfilePackage";
private static final String PERSONAL_NON_CROSS_PROFILE_PACKAGE =
@@ -58,21 +59,17 @@
ImmutableList.of(PERSONAL_CROSS_PROFILE_PACKAGE, PERSONAL_NON_CROSS_PROFILE_PACKAGE);
private static final List<String> WORK_PROFILE_INSTALLED_PACKAGES =
ImmutableList.of(WORK_CROSS_PROFILE_PACKAGE, WORK_NON_CROSS_PROFILE_PACKAGE);
+ public static final String INTERACT_ACROSS_PROFILES_PERMISSION =
+ "android.permission.INTERACT_ACROSS_PROFILES";
private final Context mContext = ApplicationProvider.getApplicationContext();
private final PackageManager mPackageManager = mContext.getPackageManager();
private final UserManager mUserManager = mContext.getSystemService(UserManager.class);
private final CrossProfileApps mCrossProfileApps =
mContext.getSystemService(CrossProfileApps.class);
+ private final AppOpsManager mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
private final InteractAcrossProfilesSettings mFragment = new InteractAcrossProfilesSettings();
- @Before
- public void setup() {
- ReflectionHelpers.setField(mFragment, "mPackageManager", mPackageManager);
- ReflectionHelpers.setField(mFragment, "mUserManager", mUserManager);
- ReflectionHelpers.setField(mFragment, "mCrossProfileApps", mCrossProfileApps);
- }
-
@Test
public void collectConfigurableApps_fromPersonal_returnsPersonalPackages() {
shadowOf(mUserManager).addUser(
@@ -87,7 +84,8 @@
shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_CROSS_PROFILE_PACKAGE);
shadowOf(mCrossProfileApps).addCrossProfilePackage(WORK_CROSS_PROFILE_PACKAGE);
- List<Pair<ApplicationInfo, UserHandle>> apps = mFragment.collectConfigurableApps();
+ List<Pair<ApplicationInfo, UserHandle>> apps = mFragment.collectConfigurableApps(
+ mPackageManager, mUserManager, mCrossProfileApps);
assertThat(apps.size()).isEqualTo(1);
assertThat(apps.get(0).first.packageName).isEqualTo(PERSONAL_CROSS_PROFILE_PACKAGE);
@@ -108,7 +106,8 @@
shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_CROSS_PROFILE_PACKAGE);
shadowOf(mCrossProfileApps).addCrossProfilePackage(WORK_CROSS_PROFILE_PACKAGE);
- List<Pair<ApplicationInfo, UserHandle>> apps = mFragment.collectConfigurableApps();
+ List<Pair<ApplicationInfo, UserHandle>> apps = mFragment.collectConfigurableApps(
+ mPackageManager, mUserManager, mCrossProfileApps);
assertThat(apps.size()).isEqualTo(1);
assertThat(apps.get(0).first.packageName).isEqualTo(PERSONAL_CROSS_PROFILE_PACKAGE);
@@ -122,8 +121,40 @@
PERSONAL_PROFILE_ID, PERSONAL_PROFILE_INSTALLED_PACKAGES);
shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_CROSS_PROFILE_PACKAGE);
- List<Pair<ApplicationInfo, UserHandle>> apps = mFragment.collectConfigurableApps();
+ List<Pair<ApplicationInfo, UserHandle>> apps = mFragment.collectConfigurableApps(
+ mPackageManager, mUserManager, mCrossProfileApps);
assertThat(apps).isEmpty();
}
+
+ @Test
+ public void getNumberOfEnabledApps_returnsNumberOfEnabledApps() {
+ shadowOf(mUserManager).addUser(
+ PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
+ shadowOf(mUserManager).addProfile(
+ PERSONAL_PROFILE_ID, WORK_PROFILE_ID,
+ "work-profile"/* profileName */, 0/* profileFlags */);
+ shadowOf(mPackageManager).setInstalledPackagesForUserId(
+ PERSONAL_PROFILE_ID, PERSONAL_PROFILE_INSTALLED_PACKAGES);
+ shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_CROSS_PROFILE_PACKAGE);
+ shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_NON_CROSS_PROFILE_PACKAGE);
+ String appOp = AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION);
+ shadowOf(mAppOpsManager).setMode(
+ appOp, PACKAGE_UID, PERSONAL_CROSS_PROFILE_PACKAGE, AppOpsManager.MODE_ALLOWED);
+ shadowOf(mAppOpsManager).setMode(
+ appOp, PACKAGE_UID, PERSONAL_CROSS_PROFILE_PACKAGE, AppOpsManager.MODE_IGNORED);
+ shadowOf(mPackageManager).addPermissionInfo(createCrossProfilesPermissionInfo());
+
+ int numOfApps = mFragment.getNumberOfEnabledApps(
+ mContext, mPackageManager, mUserManager, mCrossProfileApps);
+
+ assertThat(numOfApps).isEqualTo(1);
+ }
+
+ private PermissionInfo createCrossProfilesPermissionInfo() {
+ PermissionInfo permissionInfo = new PermissionInfo();
+ permissionInfo.name = INTERACT_ACROSS_PROFILES_PERMISSION;
+ permissionInfo.protectionLevel = PermissionInfo.PROTECTION_FLAG_APPOP;
+ return permissionInfo;
+ }
}
diff --git a/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java
index bc495f6..772f9ae 100644
--- a/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java
@@ -38,6 +38,7 @@
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -98,6 +99,7 @@
}
@Test
+ @Ignore
public void updateState_option2Set_shouldUpdateToOption2() {
when(mBluetoothCodecConfig.getSampleRate()).thenReturn(
BluetoothCodecConfig.SAMPLE_RATE_48000);
diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceControllerTest.java
index 802f871..0041920 100644
--- a/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceControllerTest.java
@@ -35,6 +35,7 @@
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -101,6 +102,7 @@
}
@Test
+ @Ignore
public void onIndexUpdated_checkFlow() {
mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC, null, null);
when(mBluetoothA2dp.getCodecStatus(null)).thenReturn(mCodecStatus);
diff --git a/tests/robotests/src/com/android/settings/development/graphicsdriver/GraphicsDriverFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/graphicsdriver/GraphicsDriverFooterPreferenceControllerTest.java
index 1dac131..a2d23b6 100644
--- a/tests/robotests/src/com/android/settings/development/graphicsdriver/GraphicsDriverFooterPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/graphicsdriver/GraphicsDriverFooterPreferenceControllerTest.java
@@ -105,4 +105,20 @@
verify(mGraphicsDriverContentObserver).unregister(mResolver);
}
+
+ @Test
+ public void updateState_available_visible() {
+ when(mController.getAvailabilityStatus()).thenReturn(AVAILABLE_UNSEARCHABLE);
+ mController.updateState(mPreference);
+
+ verify(mPreference).setVisible(true);
+ }
+
+ @Test
+ public void updateState_unavailable_invisible() {
+ when(mController.getAvailabilityStatus()).thenReturn(CONDITIONALLY_UNAVAILABLE);
+ mController.updateState(mPreference);
+
+ verify(mPreference).setVisible(false);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java
index 851dfe0..395c8a4 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java
@@ -43,6 +43,7 @@
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
import android.content.pm.PackageInfo;
@@ -80,6 +81,7 @@
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowPackageManager;
+import org.robolectric.shadows.ShadowTelephonyManager;
import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
@@ -93,7 +95,6 @@
@Mock
private SimStatusDialogFragment mDialog;
- @Mock
private TelephonyManager mTelephonyManager;
@Mock
private SubscriptionInfo mSubscriptionInfo;
@@ -115,7 +116,6 @@
private PersistableBundle mPersistableBundle;
@Mock
private EuiccManager mEuiccManager;
- @Mock
private SubscriptionManager mSubscriptionManager;
private SimStatusDialogController mController;
@@ -131,10 +131,22 @@
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
+ mContext = spy(RuntimeEnvironment.application);
when(mDialog.getContext()).thenReturn(mContext);
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
+
+ mSubscriptionManager = spy(mContext.getSystemService(SubscriptionManager.class));
+
+ mTelephonyManager = spy(mContext.getSystemService(TelephonyManager.class));
+ final ShadowTelephonyManager shadowTelephonyMgr = shadowOf(mTelephonyManager);
+ shadowTelephonyMgr.setTelephonyManagerForSubscriptionId(
+ SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, mTelephonyManager);
+ doReturn(2).when(mTelephonyManager).getCardIdForDefaultEuicc();
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mTelephonyManager).getDataNetworkType();
+
+ doReturn(mEuiccManager).when(mContext).getSystemService(EuiccManager.class);
+
mController = spy(new SimStatusDialogController(mDialog, mLifecycle, 0 /* phone id */));
ShadowDeviceInfoUtils.setPhoneNumber("");
//CellSignalStrength setup
@@ -156,9 +168,9 @@
ReflectionHelpers.setField(mController, "mSubscriptionManager", mSubscriptionManager);
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_SINGLE_SIM);
- when(mTelephonyManager.getUiccCardsInfo()).thenReturn(new ArrayList<UiccCardInfo>());
- when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(
- new HashMap<Integer, Integer>());
+ doReturn(new ArrayList<UiccCardInfo>()).when(mTelephonyManager).getUiccCardsInfo();
+ doReturn(new HashMap<Integer, Integer>()).when(mTelephonyManager)
+ .getLogicalToPhysicalSlotMapping();
when(mEuiccManager.isEnabled()).thenReturn(false);
when(mEuiccManager.getEid()).thenReturn("");
@@ -168,7 +180,6 @@
when(mPersistableBundle.getBoolean(
CarrierConfigManager.KEY_SHOW_SIGNAL_STRENGTH_IN_SIM_STATUS_BOOL))
.thenReturn(true);
- when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
doReturn(mServiceState).when(mTelephonyManager).getServiceState();
doReturn(mSignalStrength).when(mTelephonyManager).getSignalStrength();
@@ -185,7 +196,6 @@
}
@Test
- @Ignore
public void initialize_updateNetworkProviderWithFoobarCarrier_shouldUpdateCarrierWithFoobar() {
final CharSequence carrierName = "foobar";
doReturn(carrierName).when(mSubscriptionInfo).getCarrierName();
@@ -196,7 +206,6 @@
}
@Test
- @Ignore
public void initialize_updatePhoneNumberWith1111111111_shouldUpdatePhoneNumber() {
ShadowDeviceInfoUtils.setPhoneNumber("1111111111");
@@ -209,7 +218,6 @@
}
@Test
- @Ignore
public void initialize_updateLatestAreaInfoWithCdmaPhone_shouldRemoveOperatorInfoSetting() {
when(mTelephonyManager.getPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_CDMA);
@@ -220,7 +228,6 @@
}
@Test
- @Ignore
public void initialize_updateServiceStateWithInService_shouldUpdateTextToBeCInService() {
when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE);
@@ -231,7 +238,6 @@
}
@Test
- @Ignore
public void initialize_updateServiceStateWithPowerOff_shouldUpdateTextAndResetSignalStrength() {
when(mServiceState.getState()).thenReturn(ServiceState.STATE_POWER_OFF);
when(mPersistableBundle.getBoolean(
@@ -245,7 +251,6 @@
}
@Test
- @Ignore
public void initialize_updateVoiceDataOutOfService_shouldUpdateSettingAndResetSignalStrength() {
when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
when(mServiceState.getDataRegistrationState()).thenReturn(
@@ -261,7 +266,6 @@
}
@Test
- @Ignore
public void initialize_updateVoiceOutOfServiceDataInService_shouldUpdateTextToBeInService() {
when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
when(mServiceState.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE);
@@ -275,7 +279,6 @@
}
@Test
- @Ignore
public void initialize_updateSignalStrengthWithLte50Wcdma40_shouldUpdateSignalStrengthTo50() {
final int lteDbm = 50;
final int lteAsu = 50;
@@ -293,7 +296,6 @@
}
@Test
- @Ignore
public void initialize_updateSignalStrengthWithLte50Cdma30_shouldUpdateSignalStrengthTo50() {
final int lteDbm = 50;
final int lteAsu = 50;
@@ -311,7 +313,6 @@
}
@Test
- @Ignore
public void initialize_updateVoiceOutOfServiceDataInService_shouldUpdateSignalStrengthTo50() {
when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
when(mServiceState.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE);
@@ -332,7 +333,6 @@
}
@Test
- @Ignore
public void initialize_updateVoiceNetworkTypeWithEdge_shouldUpdateSettingToEdge() {
when(mTelephonyManager.getVoiceNetworkType()).thenReturn(
TelephonyManager.NETWORK_TYPE_EDGE);
@@ -344,7 +344,6 @@
}
@Test
- @Ignore
public void initialize_updateDataNetworkTypeWithEdge_shouldUpdateSettingToEdge() {
when(mTelephonyManager.getDataNetworkType()).thenReturn(
TelephonyManager.NETWORK_TYPE_EDGE);
@@ -356,7 +355,6 @@
}
@Test
- @Ignore
public void initialize_updateRoamingStatusIsRoaming_shouldSetSettingToRoaming() {
when(mServiceState.getRoaming()).thenReturn(true);
@@ -367,7 +365,6 @@
}
@Test
- @Ignore
public void initialize_updateRoamingStatusNotRoaming_shouldSetSettingToRoamingOff() {
when(mServiceState.getRoaming()).thenReturn(false);
@@ -378,7 +375,6 @@
}
@Test
- @Ignore
public void initialize_doNotShowIccid_shouldRemoveIccidSetting() {
when(mPersistableBundle.getBoolean(
CarrierConfigManager.KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL)).thenReturn(false);
@@ -390,7 +386,6 @@
}
@Test
- @Ignore
public void initialize_doNotShowSignalStrength_shouldRemoveSignalStrengthSetting() {
when(mPersistableBundle.getBoolean(
CarrierConfigManager.KEY_SHOW_SIGNAL_STRENGTH_IN_SIM_STATUS_BOOL))
@@ -403,7 +398,6 @@
}
@Test
- @Ignore
public void initialize_showSignalStrengthAndIccId_shouldShowSignalStrengthAndIccIdSetting() {
// getConfigForSubId is nullable, so make sure the default behavior is correct
when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(null);
@@ -416,7 +410,6 @@
}
@Test
- @Ignore
public void initialize_showIccid_shouldSetIccidToSetting() {
final String iccid = "12351351231241";
when(mPersistableBundle.getBoolean(
@@ -429,7 +422,6 @@
}
@Test
- @Ignore
public void initialize_updateEid_shouldNotSetEid() {
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_DUAL_SIM);
@@ -468,7 +460,6 @@
}
@Test
- @Ignore
public void initialize_updateEid_shouldSetEidFromCard() {
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_DUAL_SIM);
@@ -507,7 +498,6 @@
}
@Test
- @Ignore
public void initialize_updateEid_shouldSetEidFromManager() {
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_DUAL_SIM);
@@ -549,7 +539,6 @@
}
@Test
- @Ignore
public void initialize_updateEid_shouldRemoveEid() {
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_DUAL_SIM);
@@ -589,7 +578,6 @@
}
@Test
- @Ignore
public void initialize_updateEid_shouldNotSetEidInSingleSimMode() {
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_SINGLE_SIM);
@@ -619,7 +607,6 @@
}
@Test
- @Ignore
public void initialize_updateEid_shouldSetEidInSingleSimModeWithEnabledEuicc() {
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_SINGLE_SIM);
@@ -651,7 +638,6 @@
}
@Test
- @Ignore
public void initialize_updateEid_shouldSetEidInSingleSimModeWithDisabledEuicc() {
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_SINGLE_SIM);
@@ -683,7 +669,6 @@
}
@Test
- @Ignore
public void initialize_updateEid_shouldRemoveEidInSingleSimMode() {
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_SINGLE_SIM);
@@ -763,7 +748,6 @@
}
@Test
- @Ignore
public void initialize_nullSignalStrength_noCrash() {
doReturn(null).when(mTelephonyManager).getSignalStrength();
// we should not crash when running the following line
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
index ebb5292..5e49aa0 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
@@ -20,7 +20,6 @@
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.mock;
@@ -120,7 +119,7 @@
mController.handlePreferenceTreeClick(mPreference);
final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mActivity).startActivityForResultAsUser(argumentCaptor.capture(), anyInt(),
+ verify(mActivity).startActivityAsUser(argumentCaptor.capture(),
nullable(UserHandle.class));
final Intent intent = argumentCaptor.getValue();
@@ -138,8 +137,8 @@
mController.handlePreferenceTreeClick(mPreference);
final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mFragment.getActivity()).startActivityForResultAsUser(argumentCaptor.capture(),
- anyInt(), nullable(UserHandle.class));
+ verify(mFragment.getActivity()).startActivityAsUser(argumentCaptor.capture(),
+ nullable(UserHandle.class));
final Intent intent = argumentCaptor.getValue();
assertThat(intent.getAction()).isEqualTo(Intent.ACTION_MAIN);
@@ -165,8 +164,8 @@
mController.handlePreferenceTreeClick(mPreference);
final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mFragment.getActivity()).startActivityForResultAsUser(argumentCaptor.capture(),
- anyInt(), nullable(UserHandle.class));
+ verify(mFragment.getActivity()).startActivityAsUser(argumentCaptor.capture(),
+ nullable(UserHandle.class));
final Intent intent = argumentCaptor.getValue();
assertThat(intent.getAction()).isEqualTo(Intent.ACTION_MAIN);
@@ -184,8 +183,8 @@
mController.handlePreferenceTreeClick(mPreference);
final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mFragment.getActivity()).startActivityForResultAsUser(argumentCaptor.capture(),
- anyInt(), nullable(UserHandle.class));
+ verify(mFragment.getActivity()).startActivityAsUser(argumentCaptor.capture(),
+ nullable(UserHandle.class));
Intent intent = argumentCaptor.getValue();
assertThat(intent.getAction()).isEqualTo(Intent.ACTION_MAIN);
@@ -221,8 +220,8 @@
.isTrue();
final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mFragment.getActivity()).startActivityForResultAsUser(argumentCaptor.capture(),
- anyInt(), nullable(UserHandle.class));
+ verify(mFragment.getActivity()).startActivityAsUser(argumentCaptor.capture(),
+ nullable(UserHandle.class));
Intent intent = argumentCaptor.getValue();
Intent browseIntent = mVolume.buildBrowseIntent();
@@ -238,8 +237,8 @@
mController.handlePreferenceTreeClick(mPreference);
final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mFragment.getActivity()).startActivityForResultAsUser(argumentCaptor.capture(),
- anyInt(), nullable(UserHandle.class));
+ verify(mFragment.getActivity()).startActivityAsUser(argumentCaptor.capture(),
+ nullable(UserHandle.class));
Intent intent = argumentCaptor.getValue();
assertThat(intent.getAction()).isEqualTo(Intent.ACTION_MAIN);
@@ -256,8 +255,8 @@
mController.handlePreferenceTreeClick(mPreference);
final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mFragment.getActivity()).startActivityForResultAsUser(argumentCaptor.capture(),
- anyInt(), nullable(UserHandle.class));
+ verify(mFragment.getActivity()).startActivityAsUser(argumentCaptor.capture(),
+ nullable(UserHandle.class));
Intent intent = argumentCaptor.getValue();
assertThat(intent.getAction()).isEqualTo(Intent.ACTION_MAIN);
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/CardDatabaseHelperTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/CardDatabaseHelperTest.java
index 36e4f04..7c76999 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/CardDatabaseHelperTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/CardDatabaseHelperTest.java
@@ -67,18 +67,8 @@
CardDatabaseHelper.CardColumns.SCORE,
CardDatabaseHelper.CardColumns.SLICE_URI,
CardDatabaseHelper.CardColumns.CATEGORY,
- CardDatabaseHelper.CardColumns.LOCALIZED_TO_LOCALE,
CardDatabaseHelper.CardColumns.PACKAGE_NAME,
CardDatabaseHelper.CardColumns.APP_VERSION,
- CardDatabaseHelper.CardColumns.TITLE_RES_NAME,
- CardDatabaseHelper.CardColumns.TITLE_TEXT,
- CardDatabaseHelper.CardColumns.SUMMARY_RES_NAME,
- CardDatabaseHelper.CardColumns.SUMMARY_TEXT,
- CardDatabaseHelper.CardColumns.ICON_RES_NAME,
- CardDatabaseHelper.CardColumns.ICON_RES_ID,
- CardDatabaseHelper.CardColumns.CARD_ACTION,
- CardDatabaseHelper.CardColumns.EXPIRE_TIME_MS,
- CardDatabaseHelper.CardColumns.SUPPORT_HALF_WIDTH,
CardDatabaseHelper.CardColumns.CARD_DISMISSED,
};
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java
index 00993f6..fceb79d 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java
@@ -17,6 +17,7 @@
package com.android.settings.homepage.contextualcards;
import static com.android.settings.homepage.contextualcards.ContextualCardLoader.DEFAULT_CARD_COUNT;
+import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.STICKY_VALUE;
import static com.google.common.truth.Truth.assertThat;
@@ -82,16 +83,41 @@
@Test
public void getDisplayableCards_fourEligibleCards_shouldShowDefaultCardCount() {
- final List<ContextualCard> fourCards = getContextualCardList();
- doReturn(fourCards).when(mContextualCardLoader).filterEligibleCards(anyList());
+ final List<ContextualCard> cards = getContextualCardList().stream().limit(4)
+ .collect(Collectors.toList());
+ doReturn(cards).when(mContextualCardLoader).filterEligibleCards(anyList());
- final List<ContextualCard> result = mContextualCardLoader
- .getDisplayableCards(fourCards);
+ final List<ContextualCard> result = mContextualCardLoader.getDisplayableCards(cards);
assertThat(result).hasSize(DEFAULT_CARD_COUNT);
}
@Test
+ public void getDisplayableCards_oneStickyCard_shouldShowOneStickyCardAtTheTail() {
+ final List<ContextualCard> cards = getContextualCardList().stream().limit(5)
+ .collect(Collectors.toList());
+ doReturn(cards).when(mContextualCardLoader).filterEligibleCards(anyList());
+
+ final List<ContextualCard> result = mContextualCardLoader.getDisplayableCards(cards);
+
+ assertThat(result).hasSize(DEFAULT_CARD_COUNT);
+ assertThat(result.get(DEFAULT_CARD_COUNT - 1).getCategory()).isEqualTo(STICKY_VALUE);
+ }
+
+ @Test
+ public void getDisplayableCards_threeStickyCards_shouldShowThreeStickyCardAtTheTail() {
+ final List<ContextualCard> cards = getContextualCardList();
+ doReturn(cards).when(mContextualCardLoader).filterEligibleCards(anyList());
+
+ final List<ContextualCard> result = mContextualCardLoader.getDisplayableCards(cards);
+
+ assertThat(result).hasSize(DEFAULT_CARD_COUNT);
+ for (int i = 1; i <= Math.min(3, DEFAULT_CARD_COUNT); i++) {
+ assertThat(result.get(DEFAULT_CARD_COUNT - i).getCategory()).isEqualTo(STICKY_VALUE);
+ }
+ }
+
+ @Test
public void getDisplayableCards_refreshCardUri_shouldLogContextualCard() {
mContextualCardLoader.mNotifyUri = CardContentProvider.REFRESH_CARD_URI;
@@ -128,20 +154,20 @@
private List<ContextualCard> getContextualCardList() {
final List<ContextualCard> cards = new ArrayList<>();
cards.add(new ContextualCard.Builder()
- .setName("test_wifi")
+ .setName("test_low_storage")
.setCardType(ContextualCard.CardType.SLICE)
- .setSliceUri(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI)
+ .setSliceUri(CustomSliceRegistry.LOW_STORAGE_SLICE_URI)
.build());
cards.add(new ContextualCard.Builder()
.setName("test_flashlight")
.setCardType(ContextualCard.CardType.SLICE)
- .setSliceUri(
- Uri.parse("content://com.android.settings.test.slices/action/flashlight"))
+ .setSliceUri(Uri.parse(
+ "content://com.android.settings.test.slices/action/flashlight"))
.build());
cards.add(new ContextualCard.Builder()
- .setName("test_connected")
+ .setName("test_dark_theme")
.setCardType(ContextualCard.CardType.SLICE)
- .setSliceUri(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI)
+ .setSliceUri(CustomSliceRegistry.DARK_THEME_SLICE_URI)
.build());
cards.add(new ContextualCard.Builder()
.setName("test_gesture")
@@ -149,6 +175,24 @@
.setSliceUri(Uri.parse(
"content://com.android.settings.test.slices/action/gesture_pick_up"))
.build());
+ cards.add(new ContextualCard.Builder()
+ .setName("test_wifi")
+ .setCardType(ContextualCard.CardType.SLICE)
+ .setSliceUri(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI)
+ .setCategory(STICKY_VALUE)
+ .build());
+ cards.add(new ContextualCard.Builder()
+ .setName("test_connected")
+ .setCardType(ContextualCard.CardType.SLICE)
+ .setSliceUri(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI)
+ .setCategory(STICKY_VALUE)
+ .build());
+ cards.add(new ContextualCard.Builder()
+ .setName("test_sticky")
+ .setCardType(ContextualCard.CardType.SLICE)
+ .setSliceUri(Uri.parse("content://com.android.settings.test.slices/action/sticky"))
+ .setCategory(STICKY_VALUE)
+ .build());
return cards;
}
}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java
index d179cae..8958d6e 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java
@@ -565,7 +565,27 @@
}
@Test
+ public void getCardsWithViewType_hasOneStickySlice_shouldHaveOneStickyCard() {
+ FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2, true);
+ final List<ContextualCard> cards = new ArrayList<>();
+ cards.add(buildContextualCard(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI.toString()));
+ cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString()));
+ final List<Integer> categories = Arrays.asList(
+ ContextualCardProto.ContextualCard.Category.STICKY_VALUE,
+ ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE
+ );
+ final List<ContextualCard> cardListWithWifi = buildCategoriedCards(cards, categories);
+
+ final List<ContextualCard> result = mManager.getCardsWithViewType(cardListWithWifi);
+
+ assertThat(result).hasSize(cards.size());
+ assertThat(result.get(0).getViewType()).isEqualTo(VIEW_TYPE_STICKY);
+ assertThat(result.get(1).getViewType()).isEqualTo(VIEW_TYPE_FULL_WIDTH);
+ }
+
+ @Test
public void getCardsWithViewType_hasWifiSlice_shouldHaveOneStickyCard() {
+ FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2, false);
final List<ContextualCard> cards = new ArrayList<>();
cards.add(buildContextualCard(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI.toString()));
cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString()));
@@ -584,6 +604,7 @@
@Test
public void getCardsWithViewType_hasBluetoothDeviceSlice_shouldHaveOneStickyCard() {
+ FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2, false);
final List<ContextualCard> cards = new ArrayList<>();
cards.add(buildContextualCard(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI.toString()));
cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString()));
@@ -602,6 +623,7 @@
@Test
public void getCardsWithViewType_hasWifiAndBtDeviceSlice_shouldHaveTwoStickyCards() {
+ FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2, false);
final List<ContextualCard> cards = new ArrayList<>();
cards.add(buildContextualCard(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI.toString()));
cards.add(buildContextualCard(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI.toString()));
@@ -624,6 +646,7 @@
@Test
public void getCardsWithViewType_noWifiOrBtDeviceSlice_shouldNotHaveStickyCard() {
+ FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2, false);
final List<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
@@ -683,8 +706,8 @@
cards.add(new ContextualCard.Builder()
.setName("test_flashlight")
.setCardType(ContextualCard.CardType.SLICE)
- .setSliceUri(
- Uri.parse("content://com.android.settings.test.slices/action/flashlight"))
+ .setSliceUri(Uri.parse(
+ "content://com.android.settings.test.slices/action/flashlight"))
.setViewType(VIEW_TYPE_FULL_WIDTH)
.build());
cards.add(new ContextualCard.Builder()
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java
index 3777920..23ae2f3 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java
@@ -76,18 +76,6 @@
}
@Test
- public void isCardEligibleToDisplay_customCard_returnTrue() {
- final ContextualCard customCard = new ContextualCard.Builder()
- .setName("custom_card")
- .setCardType(ContextualCard.CardType.DEFAULT)
- .setTitleText("custom_title")
- .setSummaryText("custom_summary")
- .build();
-
- assertThat(mEligibleCardChecker.isCardEligibleToDisplay(customCard)).isTrue();
- }
-
- @Test
public void isCardEligibleToDisplay_invalidScheme_returnFalse() {
final Uri sliceUri = Uri.parse("contet://com.android.settings.slices/action/flashlight");
diff --git a/tests/robotests/src/com/android/settings/network/AllInOneTetherPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/AllInOneTetherPreferenceControllerTest.java
new file mode 100644
index 0000000..c74e669
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/AllInOneTetherPreferenceControllerTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2020 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 org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothPan;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+import android.content.SharedPreferences;
+
+import com.android.settings.widget.MasterSwitchPreference;
+
+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;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+@RunWith(RobolectricTestRunner.class)
+public class AllInOneTetherPreferenceControllerTest {
+
+ @Mock
+ private Context mContext;
+ @Mock
+ private BluetoothAdapter mBluetoothAdapter;
+ @Mock
+ private MasterSwitchPreference mPreference;
+ @Mock
+ private SharedPreferences mSharedPreferences;
+
+ private AllInOneTetherPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mController = spy(AllInOneTetherPreferenceController.class);
+ ReflectionHelpers.setField(mController, "mContext", mContext);
+ ReflectionHelpers.setField(mController, "mBluetoothAdapter", mBluetoothAdapter);
+ ReflectionHelpers.setField(mController, "mPreference", mPreference);
+ ReflectionHelpers
+ .setField(mController, "mTetherEnablerSharedPreferences", mSharedPreferences);
+ }
+
+ @Test
+ public void onCreate_shouldInitBluetoothPan() {
+ when(mBluetoothAdapter.getState()).thenReturn(BluetoothAdapter.STATE_ON);
+ mController.onCreate();
+
+ verify(mBluetoothAdapter).getState();
+ verify(mBluetoothAdapter).getProfileProxy(mContext, mController.mBtProfileServiceListener,
+ BluetoothProfile.PAN);
+ }
+
+ @Test
+ public void onCreate_shouldNotInitBluetoothPanWhenBluetoothOff() {
+ when(mBluetoothAdapter.getState()).thenReturn(BluetoothAdapter.STATE_OFF);
+ mController.onCreate();
+
+ verify(mBluetoothAdapter).getState();
+ verifyNoMoreInteractions(mBluetoothAdapter);
+ }
+
+ @Test
+ public void goThroughLifecycle_shouldDestroyBluetoothProfile() {
+ final BluetoothPan pan = mock(BluetoothPan.class);
+ final AtomicReference<BluetoothPan> panRef =
+ ReflectionHelpers.getField(mController, "mBluetoothPan");
+ panRef.set(pan);
+
+ mController.onDestroy();
+
+ verify(mBluetoothAdapter).closeProfileProxy(BluetoothProfile.PAN, pan);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/network/ims/MockImsQueryResult.java b/tests/robotests/src/com/android/settings/network/ims/MockImsQueryResult.java
deleted file mode 100644
index d2a7129..0000000
--- a/tests/robotests/src/com/android/settings/network/ims/MockImsQueryResult.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2020 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.ims;
-
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-@RunWith(RobolectricTestRunner.class)
-public class MockImsQueryResult {
-
- public static class BooleanResult implements ImsQuery {
- private boolean mResult;
-
- public BooleanResult(boolean result) {
- super();
- mResult = result;
- }
-
- public boolean query() {
- return mResult;
- }
- }
-
-}
diff --git a/tests/robotests/src/com/android/settings/network/ims/MockVolteQueryImsState.java b/tests/robotests/src/com/android/settings/network/ims/MockVolteQueryImsState.java
index 42ddd70..84399a2 100644
--- a/tests/robotests/src/com/android/settings/network/ims/MockVolteQueryImsState.java
+++ b/tests/robotests/src/com/android/settings/network/ims/MockVolteQueryImsState.java
@@ -27,9 +27,9 @@
*/
public class MockVolteQueryImsState extends VolteQueryImsState {
- private ImsQuery mIsTtyOnVolteEnabled;
- private ImsQuery mIsProvisionedOnDevice;
- private ImsQuery mIsEnabledByUser;
+ private Boolean mIsTtyOnVolteEnabled;
+ private Boolean mIsProvisionedOnDevice;
+ private Boolean mIsEnabledByUser;
/**
* Constructor
@@ -46,11 +46,11 @@
}
public void setIsTtyOnVolteEnabled(boolean enabled) {
- mIsTtyOnVolteEnabled = new MockImsQueryResult.BooleanResult(enabled);
+ mIsTtyOnVolteEnabled = enabled;
}
@Override
- ImsQuery isTtyOnVolteEnabled(int subId) {
+ boolean isTtyOnVolteEnabled(int subId) {
if (mIsTtyOnVolteEnabled != null) {
return mIsTtyOnVolteEnabled;
}
@@ -58,11 +58,11 @@
}
public void setIsProvisionedOnDevice(boolean isProvisioned) {
- mIsProvisionedOnDevice = new MockImsQueryResult.BooleanResult(isProvisioned);
+ mIsProvisionedOnDevice = isProvisioned;
}
@Override
- ImsQuery isProvisionedOnDevice(int subId) {
+ boolean isProvisionedOnDevice(int subId) {
if (mIsProvisionedOnDevice != null) {
return mIsProvisionedOnDevice;
}
@@ -70,11 +70,11 @@
}
public void setIsEnabledByUser(boolean enabled) {
- mIsEnabledByUser = new MockImsQueryResult.BooleanResult(enabled);
+ mIsEnabledByUser = enabled;
}
@Override
- ImsQuery isEnabledByUser(int subId) {
+ boolean isEnabledByUser(int subId) {
if (mIsEnabledByUser != null) {
return mIsEnabledByUser;
}
diff --git a/tests/robotests/src/com/android/settings/network/ims/MockVtQueryImsState.java b/tests/robotests/src/com/android/settings/network/ims/MockVtQueryImsState.java
index b5971e9..4fd7d0c 100644
--- a/tests/robotests/src/com/android/settings/network/ims/MockVtQueryImsState.java
+++ b/tests/robotests/src/com/android/settings/network/ims/MockVtQueryImsState.java
@@ -26,9 +26,9 @@
*/
public class MockVtQueryImsState extends VtQueryImsState {
- private ImsQuery mIsTtyOnVolteEnabled;
- private ImsQuery mIsProvisionedOnDevice;
- private ImsQuery mIsEnabledByUser;
+ private Boolean mIsTtyOnVolteEnabled;
+ private Boolean mIsProvisionedOnDevice;
+ private Boolean mIsEnabledByUser;
/**
* Constructor
@@ -45,11 +45,11 @@
}
public void setIsTtyOnVolteEnabled(boolean enabled) {
- mIsTtyOnVolteEnabled = new MockImsQueryResult.BooleanResult(enabled);
+ mIsTtyOnVolteEnabled = enabled;
}
@Override
- ImsQuery isTtyOnVolteEnabled(int subId) {
+ boolean isTtyOnVolteEnabled(int subId) {
if (mIsTtyOnVolteEnabled != null) {
return mIsTtyOnVolteEnabled;
}
@@ -57,11 +57,11 @@
}
public void setIsProvisionedOnDevice(boolean isProvisioned) {
- mIsProvisionedOnDevice = new MockImsQueryResult.BooleanResult(isProvisioned);
+ mIsProvisionedOnDevice = isProvisioned;
}
@Override
- ImsQuery isProvisionedOnDevice(int subId) {
+ boolean isProvisionedOnDevice(int subId) {
if (mIsProvisionedOnDevice != null) {
return mIsProvisionedOnDevice;
}
@@ -69,11 +69,11 @@
}
public void setIsEnabledByUser(boolean enabled) {
- mIsEnabledByUser = new MockImsQueryResult.BooleanResult(enabled);
+ mIsEnabledByUser = enabled;
}
@Override
- ImsQuery isEnabledByUser(int subId) {
+ boolean isEnabledByUser(int subId) {
if (mIsEnabledByUser != null) {
return mIsEnabledByUser;
}
diff --git a/tests/robotests/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java b/tests/robotests/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java
index aa30aa0..8123c93 100644
--- a/tests/robotests/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java
+++ b/tests/robotests/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java
@@ -26,9 +26,9 @@
*/
public class MockWifiCallingQueryImsState extends WifiCallingQueryImsState {
- private ImsQuery mIsTtyOnVolteEnabled;
- private ImsQuery mIsProvisionedOnDevice;
- private ImsQuery mIsEnabledByUser;
+ private Boolean mIsTtyOnVolteEnabled;
+ private Boolean mIsProvisionedOnDevice;
+ private Boolean mIsEnabledByUser;
/**
* Constructor
@@ -45,11 +45,11 @@
}
public void setIsTtyOnVolteEnabled(boolean enabled) {
- mIsTtyOnVolteEnabled = new MockImsQueryResult.BooleanResult(enabled);
+ mIsTtyOnVolteEnabled = enabled;
}
@Override
- ImsQuery isTtyOnVolteEnabled(int subId) {
+ boolean isTtyOnVolteEnabled(int subId) {
if (mIsTtyOnVolteEnabled != null) {
return mIsTtyOnVolteEnabled;
}
@@ -57,11 +57,11 @@
}
public void setIsProvisionedOnDevice(boolean isProvisioned) {
- mIsProvisionedOnDevice = new MockImsQueryResult.BooleanResult(isProvisioned);
+ mIsProvisionedOnDevice = isProvisioned;
}
@Override
- ImsQuery isProvisionedOnDevice(int subId) {
+ boolean isProvisionedOnDevice(int subId) {
if (mIsProvisionedOnDevice != null) {
return mIsProvisionedOnDevice;
}
@@ -69,11 +69,11 @@
}
public void setIsEnabledByUser(boolean enabled) {
- mIsEnabledByUser = new MockImsQueryResult.BooleanResult(enabled);
+ mIsEnabledByUser = enabled;
}
@Override
- ImsQuery isEnabledByUser(int subId) {
+ boolean isEnabledByUser(int subId) {
if (mIsEnabledByUser != null) {
return mIsEnabledByUser;
}
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 ca8fcf8..401a92e 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/DeleteSimProfilePreferenceControllerTest.java
@@ -25,6 +25,7 @@
import android.content.Context;
import android.content.Intent;
+import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.euicc.EuiccManager;
@@ -34,6 +35,7 @@
import androidx.preference.PreferenceScreen;
import com.android.settings.network.SubscriptionUtil;
+import com.android.settings.security.ConfirmSimDeletionPreferenceController;
import org.junit.After;
import org.junit.Before;
@@ -118,7 +120,11 @@
public void onPreferenceClick_startsIntent() {
mController.init(SUB_ID, mFragment, REQUEST_CODE);
mController.displayPreference(mScreen);
- mPreference.performClick();
+ // turn off confirmation before click
+ Settings.Global.putInt(mContext.getContentResolver(),
+ ConfirmSimDeletionPreferenceController.KEY_CONFIRM_SIM_DELETION, 0);
+
+ mController.handlePreferenceTreeClick(mPreference);
final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mFragment).startActivityForResult(intentCaptor.capture(), eq(REQUEST_CODE));
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 9bf8370..a4c3672 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java
@@ -26,6 +26,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.Activity;
import android.app.usage.NetworkStatsManager;
import android.content.Context;
import android.net.NetworkPolicyManager;
@@ -111,12 +112,12 @@
public void onActivityResult_noActivity_noCrash() {
when(mFragment.getActivity()).thenReturn(null);
// this should not crash
- mFragment.onActivityResult(REQUEST_CODE_DELETE_SUBSCRIPTION, 0, null);
+ mFragment.onActivityResult(REQUEST_CODE_DELETE_SUBSCRIPTION, Activity.RESULT_OK, null);
}
@Test
public void onActivityResult_deleteSubscription_activityFinishes() {
- mFragment.onActivityResult(REQUEST_CODE_DELETE_SUBSCRIPTION, 0, null);
+ mFragment.onActivityResult(REQUEST_CODE_DELETE_SUBSCRIPTION, Activity.RESULT_OK, null);
verify(mActivity).finish();
}
diff --git a/tests/robotests/src/com/android/settings/notification/RemoteVolumePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/RemoteVolumePreferenceControllerTest.java
deleted file mode 100644
index 44fc04f..0000000
--- a/tests/robotests/src/com/android/settings/notification/RemoteVolumePreferenceControllerTest.java
+++ /dev/null
@@ -1,226 +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.notification;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.media.session.ISessionController;
-import android.media.session.MediaController;
-import android.media.session.MediaSession;
-import android.media.session.MediaSessionManager;
-
-import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
-
-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 java.util.ArrayList;
-import java.util.List;
-
-@RunWith(RobolectricTestRunner.class)
-public class RemoteVolumePreferenceControllerTest {
- private static final int CURRENT_POS = 5;
- private static final int MAX_POS = 10;
-
- @Mock
- private MediaSessionManager mMediaSessionManager;
- @Mock
- private MediaController mMediaController;
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private ISessionController mStub;
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private ISessionController mStub2;
- private MediaSession.Token mToken;
- private MediaSession.Token mToken2;
- private RemoteVolumePreferenceController mController;
- private Context mContext;
- private List<MediaController> mActiveSessions;
- private MediaController.PlaybackInfo mPlaybackInfo;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- mContext = spy(RuntimeEnvironment.application);
- when(mContext.getSystemService(MediaSessionManager.class)).thenReturn(mMediaSessionManager);
- mActiveSessions = new ArrayList<>();
- mActiveSessions.add(mMediaController);
- when(mMediaSessionManager.getActiveSessions(null)).thenReturn(
- mActiveSessions);
- mToken = new MediaSession.Token(mStub);
- mToken2 = new MediaSession.Token(mStub2);
-
- mController = new RemoteVolumePreferenceController(mContext);
- mPlaybackInfo = new MediaController.PlaybackInfo(
- MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE, 0, MAX_POS, CURRENT_POS, null);
- when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo);
- when(mMediaController.getSessionToken()).thenReturn(mToken);
- }
-
- @Test
- public void getActiveRemoteToken_containRemoteMedia_returnToken() {
- when(mMediaController.getPlaybackInfo()).thenReturn(
- new MediaController.PlaybackInfo(MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE,
- 0, 0, 0, null));
- assertThat(mController.getActiveRemoteToken(mContext)).isEqualTo(mToken);
- }
-
- @Test
- public void getActiveRemoteToken_noRemoteMedia_returnNull() {
- when(mMediaController.getPlaybackInfo()).thenReturn(
- new MediaController.PlaybackInfo(MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL,
- 0, 0, 0, null));
- assertThat(mController.getActiveRemoteToken(mContext)).isNull();
- }
-
- @Test
- public void isAvailable_returnAvailableUnsearchable() {
- assertThat(mController.isAvailable()).isTrue();
- assertThat(mController.getAvailabilityStatus()).isEqualTo(
- BasePreferenceController.AVAILABLE_UNSEARCHABLE);
- }
-
- @Test
- public void getMuteIcon_returnMuteIcon() {
- assertThat(mController.getMuteIcon()).isEqualTo(R.drawable.ic_volume_remote_mute);
- }
-
- @Test
- public void getAudioStream_returnRemoteVolume() {
- assertThat(mController.getAudioStream()).isEqualTo(
- RemoteVolumePreferenceController.REMOTE_VOLUME);
- }
-
- @Test
- public void getSliderPosition_controllerNull_returnZero() {
- mController.mMediaController = null;
-
- assertThat(mController.getSliderPosition()).isEqualTo(0);
- }
-
- @Test
- public void getSliderPosition_controllerExists_returnValue() {
- mController.mMediaController = mMediaController;
-
- assertThat(mController.getSliderPosition()).isEqualTo(CURRENT_POS);
- }
-
- @Test
- public void getMinValue_controllerNull_returnZero() {
- mController.mMediaController = null;
-
- assertThat(mController.getMin()).isEqualTo(0);
- }
-
- @Test
- public void getMinValue_controllerExists_returnValue() {
- mController.mMediaController = mMediaController;
-
- assertThat(mController.getMin()).isEqualTo(0);
- }
-
- @Test
- public void getMaxValue_controllerNull_returnZero() {
- mController.mMediaController = null;
-
- assertThat(mController.getMax()).isEqualTo(0);
- }
-
- @Test
- public void getMaxValue_controllerExists_returnValue() {
- mController.mMediaController = mMediaController;
-
- assertThat(mController.getMax()).isEqualTo(MAX_POS);
- }
-
- @Test
- public void setSliderPosition_controllerNull_returnFalse() {
- mController.mMediaController = null;
-
- assertThat(mController.setSliderPosition(CURRENT_POS)).isFalse();
- }
-
- @Test
- public void setSliderPosition_controllerExists_returnTrue() {
- mController.mMediaController = mMediaController;
-
- assertThat(mController.setSliderPosition(CURRENT_POS)).isTrue();
- verify(mMediaController).setVolumeTo(CURRENT_POS, 0 /* flags */);
- }
-
- @Test
- public void onRemoteUpdate_firstToken_updateTokenAndPreference() {
- mController.mPreference = new VolumeSeekBarPreference(mContext);
- mController.mActiveToken = null;
-
- mController.mCallbacks.onRemoteUpdate(mToken, "token", mPlaybackInfo);
-
- assertThat(mController.mActiveToken).isEqualTo(mToken);
- assertThat(mController.mPreference.isVisible()).isTrue();
- assertThat(mController.mPreference.getMax()).isEqualTo(MAX_POS);
- assertThat(mController.mPreference.getProgress()).isEqualTo(CURRENT_POS);
- }
-
- @Test
- public void onRemoteUpdate_differentToken_doNothing() {
- mController.mActiveToken = mToken;
-
- mController.mCallbacks.onRemoteUpdate(mToken2, "token2", mPlaybackInfo);
-
- assertThat(mController.mActiveToken).isEqualTo(mToken);
- }
-
- @Test
- public void onRemoteRemoved_tokenRemoved_setInvisible() {
- mController.mPreference = new VolumeSeekBarPreference(mContext);
- mController.mActiveToken = mToken;
-
- mController.mCallbacks.onRemoteRemoved(mToken);
-
- assertThat(mController.mActiveToken).isNull();
- assertThat(mController.mPreference.isVisible()).isFalse();
- }
-
- @Test
- public void onRemoteVolumeChanged_volumeChanged_updateIt() {
- mController.mPreference = new VolumeSeekBarPreference(mContext);
- mController.mPreference.setMax(MAX_POS);
- mController.mActiveToken = mToken;
- mController.mMediaController = mMediaController;
-
- mController.mCallbacks.onRemoteVolumeChanged(mToken, 0 /* flags */);
-
- assertThat(mController.mPreference.getProgress()).isEqualTo(CURRENT_POS);
- }
-
- @Test
- public void isPublicSlice_returnTrue() {
- assertThat(mController.isPublicSlice()).isTrue();
- }
-}
diff --git a/tests/robotests/src/com/android/settings/notification/SoundSettingsTest.java b/tests/robotests/src/com/android/settings/notification/SoundSettingsTest.java
index 56d0828..b6f06f4 100644
--- a/tests/robotests/src/com/android/settings/notification/SoundSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/notification/SoundSettingsTest.java
@@ -25,13 +25,13 @@
import android.content.Context;
import android.media.AudioManager;
-import android.os.Handler;
import android.os.UserManager;
import android.preference.SeekBarVolumizer;
import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils;
import com.android.settings.testutils.shadow.ShadowAudioHelper;
+import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
import com.android.settings.testutils.shadow.ShadowUserManager;
@@ -48,7 +48,8 @@
public class SoundSettingsTest {
@Test
- @Config(shadows = {ShadowUserManager.class, ShadowAudioHelper.class, ShadowDeviceConfig.class})
+ @Config(shadows = {ShadowUserManager.class, ShadowAudioHelper.class, ShadowDeviceConfig.class,
+ ShadowBluetoothAdapter.class})
public void getNonIndexableKeys_existInXmlLayout() {
final Context context = spy(RuntimeEnvironment.application);
AudioManager audioManager = mock(AudioManager.class);
diff --git a/tests/robotests/src/com/android/settings/users/AddUserWhenLockedPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/users/AddUserWhenLockedPreferenceControllerTest.java
index 9e0f2cc..7bfee10 100644
--- a/tests/robotests/src/com/android/settings/users/AddUserWhenLockedPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/users/AddUserWhenLockedPreferenceControllerTest.java
@@ -42,6 +42,7 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowUserManager.class})
@@ -63,7 +64,7 @@
mLockPatternUtils = mock(LockPatternUtils.class);
mUserManager = ShadowUserManager.getShadow();
mController = new AddUserWhenLockedPreferenceController(mContext, "fake_key");
- mController.setLockPatternUtils(mLockPatternUtils);
+ ReflectionHelpers.setField(mController, "mLockPatternUtils", mLockPatternUtils);
mUserManager.setSupportsMultipleUsers(true);
}
@@ -104,7 +105,7 @@
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
final AddUserWhenLockedPreferenceController controller =
new AddUserWhenLockedPreferenceController(mContext, "fake_key");
- controller.setLockPatternUtils(mLockPatternUtils);
+ ReflectionHelpers.setField(controller, "mLockPatternUtils", mLockPatternUtils);
final RestrictedSwitchPreference preference = mock(RestrictedSwitchPreference.class);
controller.updateState(preference);
@@ -162,7 +163,7 @@
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false);
final AddUserWhenLockedPreferenceController controller =
new AddUserWhenLockedPreferenceController(mContext, "fake_key");
- controller.setLockPatternUtils(mLockPatternUtils);
+ ReflectionHelpers.setField(controller, "mLockPatternUtils", mLockPatternUtils);
final RestrictedSwitchPreference preference = mock(RestrictedSwitchPreference.class);
controller.updateState(preference);
@@ -180,7 +181,7 @@
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
final AddUserWhenLockedPreferenceController controller =
new AddUserWhenLockedPreferenceController(mContext, "fake_key");
- controller.setLockPatternUtils(mLockPatternUtils);
+ ReflectionHelpers.setField(controller, "mLockPatternUtils", mLockPatternUtils);
final RestrictedSwitchPreference preference = mock(RestrictedSwitchPreference.class);
controller.updateState(preference);
diff --git a/tests/unit/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java b/tests/unit/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java
deleted file mode 100644
index 0c27379..0000000
--- a/tests/unit/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2018 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.accessibility;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
-import static androidx.test.espresso.matcher.ViewMatchers.isChecked;
-import static androidx.test.espresso.matcher.ViewMatchers.isNotChecked;
-import static androidx.test.espresso.matcher.ViewMatchers.withParent;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.Matchers.allOf;
-
-import android.app.Instrumentation;
-import android.os.Bundle;
-
-import android.provider.Settings;
-import android.widget.CompoundButton;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.rule.ActivityTestRule;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.settings.R;
-import com.android.settings.Settings.AccessibilitySettingsActivity;
-import com.android.settings.core.InstrumentedPreferenceFragment;
-import com.android.settings.core.SubSettingLauncher;
-
-import org.hamcrest.Matcher;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class AccessibilityShortcutPreferenceFragmentTest {
- @Rule
- public final ActivityTestRule<AccessibilitySettingsActivity> mActivityRule =
- new ActivityTestRule<>(AccessibilitySettingsActivity.class, true);
-
- private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
- private AccessibilityShortcutPreferenceFragment mAccessibilityShortcutPreferenceFragment;
- private AccessibilitySettingsActivity mActivity;
-
- @Before
- public void setUp() {
- mActivity = mActivityRule.getActivity();
- }
-
- @Test
- public void lockScreenPreference_setOnBeforeDialogShown_isOn() {
- setDialogShown(false);
- setOnLockscreen(true);
- startFragment();
- assertLockscreenSwitchIsCheckedIs(true);
- }
-
- @Test
- public void lockScreenPreference_defaultAfterDialogShown_isOn() {
- setDialogShown(true);
- setOnLockscreen(null);
- startFragment();
- assertLockscreenSwitchIsCheckedIs(true);
- }
-
- private void startFragment() {
- mInstrumentation.runOnMainSync(() -> {
- new SubSettingLauncher(mActivity)
- .setDestination(AccessibilityShortcutPreferenceFragment.class.getName())
- .setArguments(new Bundle())
- .setSourceMetricsCategory(
- InstrumentedPreferenceFragment.METRICS_CATEGORY_UNKNOWN)
- .launch();
- });
- }
-
- private void setDialogShown(boolean shown) {
- Settings.Secure.putInt(mActivity.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, shown ? 1 : 0);
- }
-
- private void setOnLockscreen(Boolean onLockscreen) {
- if (onLockscreen == null) {
- Settings.Secure.putString(mActivity.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, null);
- } else {
- Settings.Secure.putInt(mActivity.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, onLockscreen ? 1 : 0);
- }
- }
-
- private void assertLockscreenSwitchIsCheckedIs(boolean isChecked) {
- // Identify the switch by looking for a grandparent that has a descendent with the
- // switch label. To disambiguate, make sure that grandparent doesn't also have a descendant
- // with the title of the main switch
- final String lockScreenSwitchTitle =
- mActivity.getString(R.string.accessibility_shortcut_service_on_lock_screen_title);
- final String mainSwitchTitle =
- mActivity.getString(R.string.accessibility_service_master_switch_title);
- Matcher isCheckedMatcher = (isChecked) ? isChecked() : isNotChecked();
- Matcher hasLockScreenTitleDescendant = hasDescendant(withText(lockScreenSwitchTitle));
- Matcher noMainSwitchTitleDescendant = not(hasDescendant(withText(mainSwitchTitle)));
- onView(allOf(withParent(withParent(allOf(
- hasLockScreenTitleDescendant, noMainSwitchTitleDescendant))),
- instanceOf(CompoundButton.class))).check(matches(isCheckedMatcher));
- }
-}