Merge "Replace deprecated APIs in audio switcher." into pi-dev
diff --git a/res/drawable/empty_search_results.xml b/res/drawable/empty_search_results.xml
deleted file mode 100644
index 9162107..0000000
--- a/res/drawable/empty_search_results.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.
- -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="96dp"
- android:height="96dp"
- android:viewportWidth="24"
- android:viewportHeight="24"
- android:tint="?android:attr/colorControlNormal">
-
- <path
- android:fillColor="#000000"
- android:pathData="M15.5,14h-0.79l-0.28-0.27c1.2-1.4,1.82-3.31,1.48-5.34c-0.47-2.78-2.79-5-5.59-5.34c-4.23-0.52-7.79,3.04-7.27,7.27
-c0.34,2.8,2.56,5.12,5.34,5.59c2.03,0.34,3.94-0.28,5.34-1.48L14,14.71v0.79l5.2,5.19c0.41,0.41,1.07,0.41,1.48,0l0.01-0.01
-c0.41-0.41,0.41-1.07,0-1.48L15.5,14z M9.5,14C7.01,14,5,11.99,5,9.5S7.01,5,9.5,5S14,7.01,14,9.5S11.99,14,9.5,14z" />
-</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_find_device_disabled.xml b/res/drawable/ic_find_device_disabled.xml
index 273fe64..39d4fda 100644
--- a/res/drawable/ic_find_device_disabled.xml
+++ b/res/drawable/ic_find_device_disabled.xml
@@ -20,8 +20,6 @@
android:viewportHeight="24">
<path
- android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
- <path
- android:fillColor="#F09300"
- android:pathData="M14,10.5v9.06C12.87,21,12,22,12,22S5,14.25,5,9A7,7,0,0,1,18.93,8H14.29A2.5,2.5,0,1,0,14,10.5ZM16,22h2V20H16Zm0-4h2V10H16Z" />
+ android:fillColor="#FF000000"
+ android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13C19,5.13 15.87,2 12,2zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9zM11,13h2v2h-2V13zM13,6h-2v5h2V6z"/>
</vector>
diff --git a/res/drawable/ic_find_device_enabled.xml b/res/drawable/ic_find_device_enabled.xml
index c9cc86e..16f0245 100644
--- a/res/drawable/ic_find_device_enabled.xml
+++ b/res/drawable/ic_find_device_enabled.xml
@@ -20,10 +20,6 @@
android:viewportHeight="24">
<path
- android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
- <path
- android:fillColor="#4285F4"
- android:pathData="M12,2 C8.13400675,2 5,5.13400675 5,9 C5,14.25 12,22 12,22 C12,22 19,14.25 19,9
-C19,5.13400675 15.8659932,2 12,2 L12,2 Z M8.2,9.66 L9.61,8.24 L11,9.66
-L15.24,5.42 L16.65,6.83 L11,12.49 L8.2,9.66 Z" />
+ android:fillColor="#FF000000"
+ android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13C19,5.13 15.87,2 12,2zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9zM14.5,9c0,1.38 -1.12,2.5 -2.5,2.5S9.5,10.38 9.5,9s1.12,-2.5 2.5,-2.5S14.5,7.62 14.5,9z"/>
</vector>
diff --git a/res/drawable/ic_ota_update_available.xml b/res/drawable/ic_ota_update_available.xml
index be81ea8..2b0d82d 100644
--- a/res/drawable/ic_ota_update_available.xml
+++ b/res/drawable/ic_ota_update_available.xml
@@ -20,8 +20,6 @@
android:viewportHeight="24">
<path
- android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
- <path
- android:fillColor="#F09300"
- android:pathData="M17,1H7A2,2,0,0,0,5,3V21a2,2,0,0,0,2,2H17a2,2,0,0,0,2-2V3A2,2,0,0,0,17,1Zm0,18H7V5H17Zm-1-6H13V8H11v5H8l4,4Z" />
+ android:fillColor="#FF000000"
+ android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7l0,-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7zM16,12.5l-4,4l-4,-4l1.41,-1.41L11,12.67V8.5V8h2v0.5v4.17l1.59,-1.59L16,12.5z"/>
</vector>
diff --git a/res/drawable/ic_ota_update_current.xml b/res/drawable/ic_ota_update_current.xml
index e569774..e9b987a 100644
--- a/res/drawable/ic_ota_update_current.xml
+++ b/res/drawable/ic_ota_update_current.xml
@@ -20,8 +20,6 @@
android:viewportHeight="24">
<path
- android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
- <path
- android:fillColor="#4285F4"
- android:pathData="M17,1H7A2,2,0,0,0,5,3V21a2,2,0,0,0,2,2H17a2,2,0,0,0,2-2V3A2,2,0,0,0,17,1ZM9.11,14.06h0l1.41,1.41,5.66-5.66-1.42-1.4-4.24,4.24L9.11,11.24,7.7,12.66ZM17,19H7V5H17Z" />
+ android:fillColor="#FF000000"
+ android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7l0,-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7zM11.14,16l-3.84,-3.84l1.41,-1.42l2.43,2.42l4.16,-4.16l1.42,1.41L11.14,16z"/>
</vector>
diff --git a/res/drawable/ic_ota_update_stale.xml b/res/drawable/ic_ota_update_stale.xml
index 57bd6d5..266920b 100644
--- a/res/drawable/ic_ota_update_stale.xml
+++ b/res/drawable/ic_ota_update_stale.xml
@@ -20,8 +20,6 @@
android:viewportHeight="24">
<path
- android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
- <path
- android:fillColor="#F09300"
- android:pathData="M17,1a2,2,0,0,1,2,2V21a2,2,0,0,1-2,2H7a2,2,0,0,1-2-2V3A2,2,0,0,1,7,1Zm0,18V5H7V19ZM11,6.5h2v7H11Zm0,9h2v2H11Z" />
+ android:fillColor="#FF000000"
+ android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7l0,-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7zM11,15h2v2h-2V15zM13,8h-2v5h2V8z"/>
</vector>
diff --git a/res/drawable/ic_package_verifier_disabled.xml b/res/drawable/ic_package_verifier_disabled.xml
index fa148d1..9dfcb9d 100644
--- a/res/drawable/ic_package_verifier_disabled.xml
+++ b/res/drawable/ic_package_verifier_disabled.xml
@@ -14,20 +14,12 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="22dp"
- android:height="22dp"
- android:viewportWidth="22"
- android:viewportHeight="22">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
<path
- android:fillColor="#F5A623"
- android:fillType="evenOdd"
- android:pathData="M20.5515334,2.919 C15.9049774,0.613 11,0 11,0 C11,0 6.09502262,0.613
-1.44846657,2.919 C1.15485168,4.149 1,5.432 1,6.752 C1,8.109 1.16490699,9.429
-1.47561589,10.693 C2.13624937,13.382 3.45852187,15.813 5.26143791,17.807
-C6.84313725,19.559 8.79788839,20.973 11,21.926 C13.2021116,20.973
-15.1568627,19.559 16.7395676,17.807 C18.5414781,15.813 19.8637506,13.382
-20.5253896,10.693 C20.835093,9.429 21,8.109 21,6.752 C21,5.432 20.8461538,4.149
-20.5515334,2.919 M12,15.5 L10,15.5 L10,13.5 L12,13.5 L12,15.5 L12,15.5 Z M12,12
-L10,12 L10,6 L12,6 L12,12 L12,12 Z" />
+ android:fillColor="#FF000000"
+ android:pathData="M12,4.24l6,3v4.1c0,3.9 -2.55,7.5 -6,8.59c-3.45,-1.09 -6,-4.7 -6,-8.59v-4.1L12,4.24M12,2L4,6v5.33c0,4.93 3.41,9.55 8,10.67c4.59,-1.12 8,-5.73 8,-10.67V6L12,2L12,2zM11,15h2v2h-2V15zM13,8h-2v5h2V8z"/>
</vector>
diff --git a/res/drawable/ic_package_verifier_enabled.xml b/res/drawable/ic_package_verifier_enabled.xml
index b954258..670ede4 100644
--- a/res/drawable/ic_package_verifier_enabled.xml
+++ b/res/drawable/ic_package_verifier_enabled.xml
@@ -14,22 +14,12 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="22dp"
- android:height="22dp"
- android:viewportWidth="22"
- android:viewportHeight="22">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
<path
- android:fillColor="#4285F4"
- android:fillType="evenOdd"
- android:pathData="M20.5515334,2.92885159 C20.8461538,4.16300283 21,5.45033294 21,6.77478792
-C21,8.13636778 20.835093,9.46082277 20.5253896,10.7290888 C19.8637506,13.4271641
-18.5414781,15.8663687 16.7395676,17.8670984 C15.1568627,19.6250114
-13.2021116,21.0437836 11,22 C8.79788839,21.0437836 6.84313725,19.6250114
-5.26143791,17.8670984 C3.45852187,15.8663687 2.13624937,13.4271641
-1.47561589,10.7290888 C1.16490699,9.46082277 1,8.13636778 1,6.77478792
-C1,5.45033294 1.15485168,4.16300283 1.44846657,2.92885159
-C6.09502262,0.615068868 11,0 11,0 C11,0 15.9049774,0.615068868
-20.5515334,2.92885159 Z M15.6984615,6 L9.61538462,12.2961783 L7,10
-L5.69846154,11.3471338 L9.61538462,15 L17,7.3566879 L15.6984615,6 Z" />
+ android:fillColor="#FF000000"
+ android:pathData="M11.14,16l-3.84,-3.84l1.41,-1.42l2.43,2.42l4.16,-4.16l1.42,1.41L11.14,16zM12,4.24l6,3v4.1c0,3.9 -2.55,7.5 -6,8.59c-3.45,-1.09 -6,-4.7 -6,-8.59v-4.1L12,4.24M12,2L4,6v5.33c0,4.93 3.41,9.55 8,10.67c4.59,-1.12 8,-5.73 8,-10.67V6L12,2L12,2z"/>
</vector>
diff --git a/res/drawable/ic_package_verifier_removed.xml b/res/drawable/ic_package_verifier_removed.xml
index e225ee5..66ad8ed 100644
--- a/res/drawable/ic_package_verifier_removed.xml
+++ b/res/drawable/ic_package_verifier_removed.xml
@@ -14,30 +14,11 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="22dp"
- android:height="22dp"
- android:viewportWidth="22"
- android:viewportHeight="22">
-
- <group
- android:translateX="-1"
- android:translateY="-1">
- <path
- android:fillType="evenOdd"
- android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
- <path
- android:fillColor="#D84336"
- android:fillType="evenOdd"
- android:pathData="M21.5515334,3.92885159 C21.8461538,5.16300283 22,6.45033294 22,7.77478792
-C22,9.13636778 21.835093,10.4608228 21.5253896,11.7290888 C20.8637506,14.4271641
-19.5414781,16.8663687 17.7395676,18.8670984 C16.1568627,20.6250114
-14.2021116,22.0437836 12,23 C9.79788839,22.0437836 7.84313725,20.6250114
-6.26143791,18.8670984 C4.45852187,16.8663687 3.13624937,14.4271641
-2.47561589,11.7290888 C2.16490699,10.4608228 2,9.13636778 2,7.77478792
-C2,6.45033294 2.15485168,5.16300283 2.44846657,3.92885159 C7.09502262,1.61506887
-12,1 12,1 C12,1 16.9049774,1.61506887 21.5515334,3.92885159 Z M14.6469246,7
-L11.9600359,9.71972847 L9.272253,7 L8.00878156,8.28072408 L10.6956703,11.0004526
-L8,13.720181 L9.26347144,15 L11.9600359,12.2802715 L14.7347402,15 L16,13.720181
-L13.2252957,11.0004526 L15.9121844,8.28072408 L14.6469246,7 Z" />
- </group>
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M15.5,9.91L14.09,8.5L12,10.59L9.91,8.5L8.5,9.91L10.59,12L8.5,14.09l1.41,1.41L12,13.42l2.09,2.08l1.41,-1.41L13.42,12L15.5,9.91zM12,4.24l6,3v4.1c0,3.9 -2.55,7.5 -6,8.59c-3.45,-1.09 -6,-4.7 -6,-8.59v-4.1L12,4.24M12,2L4,6v5.33c0,4.93 3.41,9.55 8,10.67c4.59,-1.12 8,-5.73 8,-10.67V6L12,2L12,2z"/>
</vector>
diff --git a/res/layout-sw320dp/settings_entity_header.xml b/res/layout-sw320dp/settings_entity_header.xml
index 79e12a9..9a46adf 100644
--- a/res/layout-sw320dp/settings_entity_header.xml
+++ b/res/layout-sw320dp/settings_entity_header.xml
@@ -62,35 +62,22 @@
<TextView
android:id="@+id/install_type"
+ style="@style/TextAppearance.EntityHeaderSummary"
android:visibility="gone"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="start"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
- android:textColor="?android:attr/textColorSecondary" />
+ android:layout_height="wrap_content"/>
<TextView
android:id="@+id/entity_header_summary"
+ style="@style/TextAppearance.EntityHeaderSummary"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="start"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
- android:textColor="?android:attr/textColorSecondary" />
+ android:layout_height="wrap_content" />
<TextView
android:id="@+id/entity_header_second_summary"
+ style="@style/TextAppearance.EntityHeaderSummary"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="start"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
- android:textColor="?android:attr/textColorSecondary" />
+ android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
diff --git a/res/layout/choose_lock_password.xml b/res/layout/choose_lock_password.xml
index f1b631e..2c94524 100644
--- a/res/layout/choose_lock_password.xml
+++ b/res/layout/choose_lock_password.xml
@@ -20,6 +20,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@drawable/ic_lock"
+ android:importantForAutofill="noExcludeDescendants"
settings:suwFooter="@layout/choose_lock_password_footer"
settings:suwHeaderText="@string/lockpassword_choose_your_screen_lock_header">
diff --git a/res/layout/preference_volume_slider.xml b/res/layout/preference_volume_slider.xml
index 7e146b8..89ecec0 100644
--- a/res/layout/preference_volume_slider.xml
+++ b/res/layout/preference_volume_slider.xml
@@ -72,9 +72,10 @@
android:orientation="vertical"/>
</LinearLayout>
- <FrameLayout
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:orientation="vertical"
android:layout_marginTop="6dp">
<SeekBar
@@ -93,10 +94,11 @@
android:textAlignment="viewStart"
android:singleLine="true"
android:ellipsize="end"
+ android:visibility="gone"
android:textAppearance="@android:style/TextAppearance.Material.Body1"
android:textColor="?android:attr/textColorSecondary"/>
- </FrameLayout>
+ </LinearLayout>
</LinearLayout>
</LinearLayout>
diff --git a/res/layout/settings_entity_header.xml b/res/layout/settings_entity_header.xml
index b534c5e..6698f3f 100644
--- a/res/layout/settings_entity_header.xml
+++ b/res/layout/settings_entity_header.xml
@@ -55,36 +55,22 @@
<TextView
android:id="@+id/install_type"
+ style="@style/TextAppearance.EntityHeaderSummary"
android:visibility="gone"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="start"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
- android:textColor="?android:attr/textColorSecondary" />
+ android:layout_height="wrap_content" />
<TextView
android:id="@+id/entity_header_summary"
+ style="@style/TextAppearance.EntityHeaderSummary"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="start"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
- android:textColor="?android:attr/textColorSecondary" />
+ android:layout_height="wrap_content" />
<TextView
android:id="@+id/entity_header_second_summary"
+ style="@style/TextAppearance.EntityHeaderSummary"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="start"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
- android:textColor="?android:attr/textColorSecondary" />
+ android:layout_height="wrap_content" />
</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 062648a..7ba4715 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -9265,6 +9265,9 @@
<!-- [CHAR_LIMIT=NONE] Developer Settings: Title of the setting which turns on emulation of a display cutout. -->
<string name="display_cutout_emulation">Simulate a display with a cutout</string>
+ <!-- [CHAR_LIMIT=NONE] Developer Settings: Search keywords for the setting which turns on emulation of a display cutout. -->
+ <string name="display_cutout_emulation_keywords">display cutout, notch</string>
+
<!-- [CHAR_LIMIT=NONE] Developer Settings: Label for the option that turns off display cutout emulation. -->
<string name="display_cutout_emulation_none">None</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 23ec207..6ca4715 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -423,6 +423,15 @@
<item name="android:textSize">16sp</item>
</style>
+ <style name="TextAppearance.EntityHeaderSummary"
+ parent="@android:style/TextAppearance.Material.Body1">
+ <item name="android:textAlignment">viewStart</item>
+ <item name="android:textColor">?android:attr/textColorSecondary</item>
+ <item name="android:gravity">start</item>
+ <item name="android:singleLine">true</item>
+ <item name="android:ellipsize">marquee</item>
+ </style>
+
<style name="ActionPrimaryButton" parent="android:Widget.DeviceDefault.Button.Colored"/>
<style name="ActionSecondaryButton" parent="android:Widget.DeviceDefault.Button"/>
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 77d4a7d..c491980 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -382,7 +382,8 @@
<ListPreference
android:key="display_cutout_emulation"
- android:title="@string/display_cutout_emulation" />
+ android:title="@string/display_cutout_emulation"
+ settings:keywords="@string/display_cutout_emulation_keywords" />
</PreferenceCategory>
diff --git a/res/xml/sound_settings.xml b/res/xml/sound_settings.xml
index 7ba1c76..704d553 100644
--- a/res/xml/sound_settings.xml
+++ b/res/xml/sound_settings.xml
@@ -141,11 +141,6 @@
android:key="screen_locking_sounds"
android:title="@string/screen_locking_sounds_title" />
- <!-- Charging sounds -->
- <SwitchPreference
- android:key="charging_sounds"
- android:title="@string/charging_sounds_title" />
-
<!-- Docking sounds -->
<SwitchPreference
android:key="docking_sounds"
diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
index 3ed76d8..82a5b9b 100644
--- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
@@ -259,8 +259,10 @@
return;
}
tile.icon = Icon.createWithResource(iconInfo.first, iconInfo.second);
- ThreadUtils.postOnMainThread(() ->
- preference.setIcon(tile.icon.loadDrawable(preference.getContext()))
+ ThreadUtils.postOnMainThread(() -> {
+ preference.setIcon(tile.icon.loadDrawable(preference.getContext()));
+ tile.icon = null;
+ }
);
});
}
diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetector.java
index 017cd3f..5a640e5 100644
--- a/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetector.java
+++ b/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetector.java
@@ -25,6 +25,7 @@
import com.android.settings.fuelgauge.batterytip.AppInfo;
import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
+import com.android.settings.fuelgauge.batterytip.tips.AppInfoPredicate;
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
@@ -44,17 +45,13 @@
BatteryDatabaseManager mBatteryDatabaseManager;
private Context mContext;
- private Predicate<AppInfo> mAppInfoPredicate = new Predicate<AppInfo>() {
- @Override
- public boolean test(AppInfo appInfo) {
- return Utils.getApplicationLabel(mContext, appInfo.packageName) == null;
- }
- };
+ private AppInfoPredicate mAppInfoPredicate;
public RestrictAppDetector(Context context, BatteryTipPolicy policy) {
mContext = context;
mPolicy = policy;
mBatteryDatabaseManager = BatteryDatabaseManager.getInstance(context);
+ mAppInfoPredicate = new AppInfoPredicate(context);
}
@Override
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/AppInfoPredicate.java b/src/com/android/settings/fuelgauge/batterytip/tips/AppInfoPredicate.java
new file mode 100644
index 0000000..df78caa
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/AppInfoPredicate.java
@@ -0,0 +1,46 @@
+/*
+ * 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.fuelgauge.batterytip.tips;
+
+import android.app.AppOpsManager;
+import android.content.Context;
+
+import com.android.settings.Utils;
+import com.android.settings.fuelgauge.batterytip.AppInfo;
+
+import java.util.function.Predicate;
+
+/**
+ * {@link Predicate} for {@link AppInfo} to check whether it has label or restricted.
+ */
+public class AppInfoPredicate implements Predicate<AppInfo> {
+ private Context mContext;
+ private AppOpsManager mAppOpsManager;
+
+ public AppInfoPredicate(Context context) {
+ mContext = context;
+ mAppOpsManager = context.getSystemService(AppOpsManager.class);
+ }
+
+ @Override
+ public boolean test(AppInfo appInfo) {
+ // Return true if app doesn't have label or already been restricted
+ return Utils.getApplicationLabel(mContext, appInfo.packageName) == null
+ || mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
+ appInfo.uid, appInfo.packageName) == AppOpsManager.MODE_IGNORED;
+ }
+}
diff --git a/src/com/android/settings/gestures/SwipeUpPreferenceController.java b/src/com/android/settings/gestures/SwipeUpPreferenceController.java
index a20cd97..c3abd46 100644
--- a/src/com/android/settings/gestures/SwipeUpPreferenceController.java
+++ b/src/com/android/settings/gestures/SwipeUpPreferenceController.java
@@ -16,8 +16,11 @@
package com.android.settings.gestures;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.UserHandle;
import android.os.UserManager;
@@ -33,6 +36,7 @@
private final int ON = 1;
private final int OFF = 0;
+ private static final String ACTION_QUICKSTEP = "android.intent.action.QUICKSTEP_SERVICE";
private static final String PREF_KEY_VIDEO = "gesture_swipe_up_video";
private final UserManager mUserManager;
@@ -42,6 +46,14 @@
}
static boolean isGestureAvailable(Context context) {
+ final ComponentName recentsComponentName = ComponentName.unflattenFromString(
+ context.getString(com.android.internal.R.string.config_recentsComponentName));
+ final Intent quickStepIntent = new Intent(ACTION_QUICKSTEP)
+ .setPackage(recentsComponentName.getPackageName());
+ if (context.getPackageManager().resolveService(quickStepIntent,
+ PackageManager.MATCH_SYSTEM_ONLY) == null) {
+ return false;
+ }
return true;
}
diff --git a/src/com/android/settings/network/ApnEditor.java b/src/com/android/settings/network/ApnEditor.java
index 61f1243..d0ecb71 100644
--- a/src/com/android/settings/network/ApnEditor.java
+++ b/src/com/android/settings/network/ApnEditor.java
@@ -1195,12 +1195,19 @@
}
}
- private ApnData getApnDataFromUri(Uri uri) {
- ApnData apnData;
- try (Cursor cursor = getActivity().managedQuery(
- uri, sProjection, null /* selection */, null /* sortOrder */)) {
- cursor.moveToFirst();
- apnData = new ApnData(uri, cursor);
+ @VisibleForTesting
+ ApnData getApnDataFromUri(Uri uri) {
+ ApnData apnData = null;
+ try (Cursor cursor = getContentResolver().query(
+ uri,
+ sProjection,
+ null /* selection */,
+ null /* selectionArgs */,
+ null /* sortOrder */)) {
+ if (cursor != null) {
+ cursor.moveToFirst();
+ apnData = new ApnData(uri, cursor);
+ }
}
if (apnData == null) {
diff --git a/src/com/android/settings/network/NetworkDashboardFragment.java b/src/com/android/settings/network/NetworkDashboardFragment.java
index ecae214..89bf5f4 100644
--- a/src/com/android/settings/network/NetworkDashboardFragment.java
+++ b/src/com/android/settings/network/NetworkDashboardFragment.java
@@ -25,6 +25,7 @@
import android.content.Context;
import android.provider.SearchIndexableResource;
import android.support.annotation.VisibleForTesting;
+import android.text.BidiFormatter;
import android.util.Log;
import com.android.internal.logging.nano.MetricsProto;
@@ -172,7 +173,8 @@
@Override
public void setListening(boolean listening) {
if (listening) {
- String summary = mContext.getString(R.string.wifi_settings_title);
+ String summary = BidiFormatter.getInstance()
+ .unicodeWrap(mContext.getString(R.string.wifi_settings_title));
if (mMobileNetworkPreferenceController.isAvailable()) {
final String mobileSettingSummary = mContext.getString(
R.string.network_dashboard_summary_mobile);
diff --git a/src/com/android/settings/notification/RingVolumePreferenceController.java b/src/com/android/settings/notification/RingVolumePreferenceController.java
index ea071fa..e74b110 100644
--- a/src/com/android/settings/notification/RingVolumePreferenceController.java
+++ b/src/com/android/settings/notification/RingVolumePreferenceController.java
@@ -17,6 +17,8 @@
package com.android.settings.notification;
import android.app.NotificationManager;
+import android.arch.lifecycle.LifecycleObserver;
+import android.arch.lifecycle.OnLifecycleEvent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -31,6 +33,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.Utils;
+import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.Objects;
@@ -58,6 +61,7 @@
updateRingerMode();
}
+ @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
@Override
public void onResume() {
super.onResume();
@@ -66,6 +70,7 @@
updatePreferenceIcon();
}
+ @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
@Override
public void onPause() {
super.onPause();
@@ -118,11 +123,10 @@
private void updatePreferenceIcon() {
if (mPreference != null) {
- mPreference.showIcon(mSuppressor != null
- ? com.android.internal.R.drawable.ic_audio_ring_notif_mute
- : mRingerMode == AudioManager.RINGER_MODE_VIBRATE || wasRingerModeVibrate()
- ? com.android.internal.R.drawable.ic_audio_ring_notif_vibrate
- : com.android.internal.R.drawable.ic_audio_ring_notif);
+ mPreference.showIcon(
+ mRingerMode == AudioManager.RINGER_MODE_VIBRATE || wasRingerModeVibrate()
+ ? com.android.internal.R.drawable.ic_audio_ring_notif_vibrate
+ : com.android.internal.R.drawable.ic_audio_ring_notif);
}
}
diff --git a/src/com/android/settings/notification/SoundSettings.java b/src/com/android/settings/notification/SoundSettings.java
index 4c9ee38..6535812 100644
--- a/src/com/android/settings/notification/SoundSettings.java
+++ b/src/com/android/settings/notification/SoundSettings.java
@@ -146,10 +146,16 @@
@Override
public void onAttach(Context context) {
super.onAttach(context);
- use(AlarmVolumePreferenceController.class).setCallback(mVolumeCallback);
- use(MediaVolumePreferenceController.class).setCallback(mVolumeCallback);
- use(RingVolumePreferenceController.class).setCallback(mVolumeCallback);
- use(NotificationVolumePreferenceController.class).setCallback(mVolumeCallback);
+ ArrayList<VolumeSeekBarPreferenceController> volumeControllers = new ArrayList<>();
+ volumeControllers.add(use(AlarmVolumePreferenceController.class));
+ volumeControllers.add(use(MediaVolumePreferenceController.class));
+ volumeControllers.add(use(RingVolumePreferenceController.class));
+ volumeControllers.add(use(NotificationVolumePreferenceController.class));
+
+ for (VolumeSeekBarPreferenceController controller : volumeControllers) {
+ controller.setCallback(mVolumeCallback);
+ getLifecycle().addObserver(controller);
+ }
}
// === Volumes ===
@@ -205,8 +211,6 @@
new DialPadTonePreferenceController(context, fragment, lifecycle);
final ScreenLockSoundPreferenceController screenLockSoundPreferenceController =
new ScreenLockSoundPreferenceController(context, fragment, lifecycle);
- final ChargingSoundPreferenceController chargingSoundPreferenceController =
- new ChargingSoundPreferenceController(context, fragment, lifecycle);
final DockingSoundPreferenceController dockingSoundPreferenceController =
new DockingSoundPreferenceController(context, fragment, lifecycle);
final TouchSoundPreferenceController touchSoundPreferenceController =
@@ -222,7 +226,6 @@
controllers.add(dialPadTonePreferenceController);
controllers.add(screenLockSoundPreferenceController);
- controllers.add(chargingSoundPreferenceController);
controllers.add(dockingSoundPreferenceController);
controllers.add(touchSoundPreferenceController);
controllers.add(vibrateOnTouchPreferenceController);
@@ -233,7 +236,6 @@
"other_sounds_and_vibrations_category").setChildren(
Arrays.asList(dialPadTonePreferenceController,
screenLockSoundPreferenceController,
- chargingSoundPreferenceController,
dockingSoundPreferenceController,
touchSoundPreferenceController,
vibrateOnTouchPreferenceController,
diff --git a/src/com/android/settings/notification/VolumeSeekBarPreference.java b/src/com/android/settings/notification/VolumeSeekBarPreference.java
index 8a48e95..d7b5e52 100644
--- a/src/com/android/settings/notification/VolumeSeekBarPreference.java
+++ b/src/com/android/settings/notification/VolumeSeekBarPreference.java
@@ -196,8 +196,7 @@
if (mSuppressionTextView != null && mSeekBar != null) {
mSuppressionTextView.setText(mSuppressionText);
final boolean showSuppression = !TextUtils.isEmpty(mSuppressionText);
- mSuppressionTextView.setVisibility(showSuppression ? View.VISIBLE : View.INVISIBLE);
- mSeekBar.setVisibility(showSuppression ? View.INVISIBLE : View.VISIBLE);
+ mSuppressionTextView.setVisibility(showSuppression ? View.VISIBLE : View.GONE);
}
}
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index 1a73ea7..4b4b9c2 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -18,19 +18,26 @@
import android.app.PendingIntent;
import android.app.slice.SliceManager;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.net.wifi.WifiManager;
+import android.provider.SettingsSlicesContract;
import android.support.annotation.VisibleForTesting;
import android.support.v4.graphics.drawable.IconCompat;
+import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import com.android.settings.R;
import com.android.settingslib.utils.ThreadUtils;
import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
@@ -144,6 +151,85 @@
return SliceBuilderUtils.buildSlice(getContext(), cachedSliceData);
}
+ /**
+ * Get a list of all valid Uris based on the keys indexed in the Slices database.
+ * <p>
+ * This will return a list of {@link Uri uris} depending on {@param uri}, following:
+ * 1. Authority & Full Path -> Only {@param uri}. It is only a prefix for itself.
+ * 2. Authority & No path -> A list of authority/action/$KEY$, where
+ * {@code $KEY$} is a list of all Slice-enabled keys for the authority.
+ * 3. Authority & action path -> A list of authority/action/$KEY$, where
+ * {@code $KEY$} is a list of all Slice-enabled keys for the authority.
+ * 4. Empty authority & path -> A list of Uris with all keys for both supported authorities.
+ * 5. Else -> Empty list.
+ * <p>
+ * Note that the authority will stay consistent with {@param uri}, and the list of valid Slice
+ * keys depends on if the authority is {@link SettingsSlicesContract#AUTHORITY} or
+ * {@link #SLICE_AUTHORITY}.
+ *
+ * @param uri The uri to look for descendants under.
+ * @returns all valid Settings uris for which {@param uri} is a prefix.
+ */
+ @Override
+ public Collection<Uri> onGetSliceDescendants(Uri uri) {
+ final List<Uri> descendants = new ArrayList<>();
+ final Pair<Boolean, String> pathData = SliceBuilderUtils.getPathData(uri);
+
+ if (pathData != null) {
+ // Uri has a full path and will not have any descendants.
+ descendants.add(uri);
+ return descendants;
+ }
+
+ final String authority = uri.getAuthority();
+ final String pathPrefix = uri.getPath();
+ final boolean isPathEmpty = pathPrefix.isEmpty();
+
+ // No path nor authority. Return all possible Uris.
+ if (isPathEmpty && TextUtils.isEmpty(authority)) {
+ final List<String> platformKeys = mSlicesDatabaseAccessor.getSliceKeys(
+ true /* isPlatformSlice */);
+ final List<String> oemKeys = mSlicesDatabaseAccessor.getSliceKeys(
+ false /* isPlatformSlice */);
+ final List<Uri> allUris = buildUrisFromKeys(platformKeys,
+ SettingsSlicesContract.AUTHORITY);
+ allUris.addAll(buildUrisFromKeys(oemKeys, SettingsSliceProvider.SLICE_AUTHORITY));
+
+ return allUris;
+ }
+
+ // Path is anything but empty, "action", or "intent". Return empty list.
+ if (!isPathEmpty
+ && !TextUtils.equals(pathPrefix, "/" + SettingsSlicesContract.PATH_SETTING_ACTION)
+ && !TextUtils.equals(pathPrefix,
+ "/" + SettingsSlicesContract.PATH_SETTING_INTENT)) {
+ // Invalid path prefix, there are no valid Uri descendants.
+ return descendants;
+ }
+
+ // Can assume authority belongs to the provider. Return all Uris for the authority.
+ final boolean isPlatformUri = TextUtils.equals(authority, SettingsSlicesContract.AUTHORITY);
+ final List<String> keys = mSlicesDatabaseAccessor.getSliceKeys(isPlatformUri);
+ return buildUrisFromKeys(keys, authority);
+ }
+
+ private List<Uri> buildUrisFromKeys(List<String> keys, String authority) {
+ final List<Uri> descendants = new ArrayList<>();
+
+ final Uri.Builder builder = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(authority)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION);
+
+ final String newUriPathPrefix = SettingsSlicesContract.PATH_SETTING_ACTION + "/";
+ for (String key : keys) {
+ builder.path(newUriPathPrefix + key);
+ descendants.add(builder.build());
+ }
+
+ return descendants;
+ }
+
@VisibleForTesting
void loadSlice(Uri uri) {
long startBuildTime = System.currentTimeMillis();
diff --git a/src/com/android/settings/slices/SliceBroadcastReceiver.java b/src/com/android/settings/slices/SliceBroadcastReceiver.java
index 80b7519..d2a6d10 100644
--- a/src/com/android/settings/slices/SliceBroadcastReceiver.java
+++ b/src/com/android/settings/slices/SliceBroadcastReceiver.java
@@ -54,16 +54,16 @@
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
final String key = intent.getStringExtra(EXTRA_SLICE_KEY);
- final boolean isPlatformDefined = intent.getBooleanExtra(EXTRA_SLICE_PLATFORM_DEFINED,
+ final boolean isPlatformSlice = intent.getBooleanExtra(EXTRA_SLICE_PLATFORM_DEFINED,
false /* default */);
switch (action) {
case ACTION_TOGGLE_CHANGED:
- handleToggleAction(context, key, isPlatformDefined);
+ handleToggleAction(context, key, isPlatformSlice);
break;
case ACTION_SLIDER_CHANGED:
int newPosition = intent.getIntExtra(Slice.EXTRA_RANGE_VALUE, -1);
- handleSliderAction(context, key, newPosition);
+ handleSliderAction(context, key, newPosition, isPlatformSlice);
break;
case ACTION_WIFI_CHANGED:
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
@@ -95,6 +95,7 @@
if (!controller.isAvailable()) {
Log.w(TAG, "Can't update " + key + " since the setting is unavailable");
updateUri(context, key, isPlatformSlice);
+ return;
}
// TODO post context.getContentResolver().notifyChanged(uri, null) in the Toggle controller
@@ -107,7 +108,8 @@
updateUri(context, key, isPlatformSlice);
}
- private void handleSliderAction(Context context, String key, int newPosition) {
+ private void handleSliderAction(Context context, String key, int newPosition,
+ boolean isPlatformSlice) {
if (TextUtils.isEmpty(key)) {
throw new IllegalArgumentException(
"No key passed to Intent for slider controller. Use extra: " + EXTRA_SLICE_KEY);
@@ -123,6 +125,12 @@
throw new IllegalArgumentException("Slider action passed for a non-slider key: " + key);
}
+ if (!controller.isAvailable()) {
+ Log.w(TAG, "Can't update " + key + " since the setting is unavailable");
+ updateUri(context, key, isPlatformSlice);
+ return;
+ }
+
final SliderPreferenceController sliderController = (SliderPreferenceController) controller;
final int maxSteps = sliderController.getMaxSteps();
if (newPosition < 0 || newPosition > maxSteps) {
diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java
index a2479a2..e6ba4a8 100644
--- a/src/com/android/settings/slices/SliceBuilderUtils.java
+++ b/src/com/android/settings/slices/SliceBuilderUtils.java
@@ -130,7 +130,7 @@
// Example: "/action/wifi" -> [{}, "action", "wifi"]
// "/action/longer/path" -> [{}, "action", "longer/path"]
if (split.length != 3) {
- throw new IllegalArgumentException("Uri (" + uri + ") has incomplete path: " + path);
+ return null;
}
final boolean isInline = TextUtils.equals(SettingsSlicesContract.PATH_SETTING_ACTION,
diff --git a/src/com/android/settings/slices/SlicesDatabaseAccessor.java b/src/com/android/settings/slices/SlicesDatabaseAccessor.java
index 82b3506..0509f9c 100644
--- a/src/com/android/settings/slices/SlicesDatabaseAccessor.java
+++ b/src/com/android/settings/slices/SlicesDatabaseAccessor.java
@@ -29,6 +29,9 @@
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.slices.SlicesDatabaseHelper.IndexColumns;
+import java.util.ArrayList;
+import java.util.List;
+
import androidx.slice.Slice;
/**
@@ -51,10 +54,12 @@
// Cursor value for boolean true
private final int TRUE = 1;
- Context mContext;
+ private final Context mContext;
+ private final SlicesDatabaseHelper mHelper;
public SlicesDatabaseAccessor(Context context) {
mContext = context;
+ mHelper = SlicesDatabaseHelper.getInstance(mContext);
}
/**
@@ -79,16 +84,44 @@
return buildSliceData(cursor, null /* uri */, false /* isInlineOnly */);
}
+ /**
+ * @return a list of keys in the Slices database matching on {@param isPlatformSlice}.
+ */
+ public List<String> getSliceKeys(boolean isPlatformSlice) {
+ final String whereClause;
+
+ if (isPlatformSlice) {
+ whereClause = IndexColumns.PLATFORM_SLICE + " = 1";
+ } else {
+ whereClause = IndexColumns.PLATFORM_SLICE + " = 0";
+ }
+
+ final SQLiteDatabase database = mHelper.getReadableDatabase();
+ final String[] columns = new String[]{IndexColumns.KEY};
+ final List<String> keys = new ArrayList<>();
+
+ try (final Cursor resultCursor = database.query(TABLE_SLICES_INDEX, columns, whereClause,
+ null /* selection */, null /* groupBy */, null /* having */, null /* orderBy */)) {
+ if (!resultCursor.moveToFirst()) {
+ return keys;
+ }
+
+ do {
+ keys.add(resultCursor.getString(0 /* key index */));
+ } while (resultCursor.moveToNext());
+ }
+
+ return keys;
+ }
+
private Cursor getIndexedSliceData(String path) {
verifyIndexing();
final String whereClause = buildKeyMatchWhereClause();
- final SlicesDatabaseHelper helper = SlicesDatabaseHelper.getInstance(mContext);
- final SQLiteDatabase database = helper.getReadableDatabase();
+ final SQLiteDatabase database = mHelper.getReadableDatabase();
final String[] selection = new String[]{path};
-
- Cursor resultCursor = database.query(TABLE_SLICES_INDEX, SELECT_COLUMNS_ALL, whereClause,
- selection, null /* groupBy */, null /* having */, null /* orderBy */);
+ final Cursor resultCursor = database.query(TABLE_SLICES_INDEX, SELECT_COLUMNS_ALL,
+ whereClause, selection, null /* groupBy */, null /* having */, null /* orderBy */);
int numResults = resultCursor.getCount();
diff --git a/src/com/android/settings/widget/ValidatedEditTextPreference.java b/src/com/android/settings/widget/ValidatedEditTextPreference.java
index a5bab1c..707da00 100644
--- a/src/com/android/settings/widget/ValidatedEditTextPreference.java
+++ b/src/com/android/settings/widget/ValidatedEditTextPreference.java
@@ -74,7 +74,7 @@
editText.removeTextChangedListener(mTextWatcher);
if (mIsPassword) {
editText.setInputType(
- InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+ InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
editText.setMaxLines(1);
}
editText.addTextChangedListener(mTextWatcher);
diff --git a/src/com/android/settings/wifi/WifiNoInternetDialog.java b/src/com/android/settings/wifi/WifiNoInternetDialog.java
index 6b7b2db..b175665 100644
--- a/src/com/android/settings/wifi/WifiNoInternetDialog.java
+++ b/src/com/android/settings/wifi/WifiNoInternetDialog.java
@@ -25,6 +25,7 @@
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
+import android.net.wifi.WifiInfo;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
@@ -107,14 +108,15 @@
mCM.registerNetworkCallback(request, mNetworkCallback);
final NetworkInfo ni = mCM.getNetworkInfo(mNetwork);
- if (ni == null || !ni.isConnectedOrConnecting()) {
+ final NetworkCapabilities nc = mCM.getNetworkCapabilities(mNetwork);
+ if (ni == null || !ni.isConnectedOrConnecting() || nc == null) {
Log.d(TAG, "Network " + mNetwork + " is not connected: " + ni);
finish();
return;
}
- mNetworkName = ni.getExtraInfo();
+ mNetworkName = nc.getSSID();
if (mNetworkName != null) {
- mNetworkName = mNetworkName.replaceAll("^\"|\"$", ""); // Remove double quotes
+ mNetworkName = WifiInfo.removeDoubleQuotes(mNetworkName);
}
createDialog();
diff --git a/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceController.java
index b38558c..5ba0583 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceController.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceController.java
@@ -55,6 +55,7 @@
mPassword = generateRandomPassword();
}
((ValidatedEditTextPreference) mPreference).setValidator(this);
+ ((ValidatedEditTextPreference) mPreference).setIsPassword(true);
((ValidatedEditTextPreference) mPreference).setIsSummaryPassword(true);
updatePasswordDisplay((EditTextPreference) mPreference);
}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
index 4a09b40..a0e5ed8 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
@@ -297,7 +297,7 @@
"content://com.android.settings/tile_icon");
mImpl.bindIcon(preference, tile);
- assertThat(tile.icon).isNotNull();
+ assertThat(preference.getIcon()).isNotNull();
}
@Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetectorTest.java
index 23f08c0..76e2928 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetectorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetectorTest.java
@@ -26,6 +26,7 @@
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.spy;
+import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -53,8 +54,10 @@
@RunWith(SettingsRobolectricTestRunner.class)
public class RestrictAppDetectorTest {
+ private static final int RESTRICTED_UID = 222;
private static final String PACKAGE_NAME = "com.android.app";
private static final String UNINSTALLED_PACKAGE_NAME = "com.android.uninstalled";
+ private static final String RESTRICTED_PACKAGE_NAME = "com.android.restricted";
private Context mContext;
private BatteryTipPolicy mPolicy;
private RestrictAppDetector mRestrictAppDetector;
@@ -66,6 +69,8 @@
private PackageManager mPackageManager;
@Mock
private ApplicationInfo mApplicationInfo;
+ @Mock
+ private AppOpsManager mAppOpsManager;
@Before
public void setUp() throws PackageManager.NameNotFoundException {
@@ -79,8 +84,10 @@
mContext = spy(RuntimeEnvironment.application);
mPolicy = spy(new BatteryTipPolicy(mContext));
- mRestrictAppDetector = new RestrictAppDetector(mContext, mPolicy);
- mRestrictAppDetector.mBatteryDatabaseManager = mBatteryDatabaseManager;
+
+ doReturn(mAppOpsManager).when(mContext).getSystemService(AppOpsManager.class);
+ doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager).checkOpNoThrow(
+ AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, RESTRICTED_UID, RESTRICTED_PACKAGE_NAME);
doReturn(mPackageManager).when(mContext).getPackageManager();
doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(eq(PACKAGE_NAME),
@@ -88,6 +95,10 @@
doReturn(PACKAGE_NAME).when(mApplicationInfo).loadLabel(any());
doThrow(new PackageManager.NameNotFoundException()).when(
mPackageManager).getApplicationInfo(eq(UNINSTALLED_PACKAGE_NAME), anyInt());
+
+ mRestrictAppDetector = new RestrictAppDetector(mContext, mPolicy);
+ mRestrictAppDetector.mBatteryDatabaseManager = mBatteryDatabaseManager;
+
}
@After
@@ -128,6 +139,23 @@
}
@Test
+ public void testDetect_hasRestrictedAnomaly_removeIt() throws
+ PackageManager.NameNotFoundException {
+ mAppInfoList.add(new AppInfo.Builder()
+ .setUid(RESTRICTED_UID)
+ .setPackageName(RESTRICTED_PACKAGE_NAME)
+ .build());
+ doReturn(mAppInfoList).when(mBatteryDatabaseManager)
+ .queryAllAnomalies(anyLong(), eq(AnomalyDatabaseHelper.State.NEW));
+ doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(
+ eq(RESTRICTED_PACKAGE_NAME), anyInt());
+
+ final RestrictAppTip restrictAppTip = (RestrictAppTip) mRestrictAppDetector.detect();
+ assertThat(restrictAppTip.getState()).isEqualTo(BatteryTip.StateType.NEW);
+ assertThat(restrictAppTip.getRestrictAppList()).containsExactly(mAppInfo);
+ }
+
+ @Test
public void testDetect_noAnomaly_tipInvisible() {
doReturn(new ArrayList<AppInfo>()).when(mBatteryDatabaseManager)
.queryAllAnomalies(anyLong(), anyInt());
diff --git a/tests/robotests/src/com/android/settings/gestures/SwipeUpPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/SwipeUpPreferenceControllerTest.java
index f9a6e9c..360609b 100644
--- a/tests/robotests/src/com/android/settings/gestures/SwipeUpPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/SwipeUpPreferenceControllerTest.java
@@ -17,12 +17,14 @@
package com.android.settings.gestures;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.UserManager;
@@ -38,7 +40,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
+import org.robolectric.Shadows;
+import org.robolectric.shadows.ShadowPackageManager;
import java.util.ArrayList;
import java.util.List;
@@ -47,16 +50,36 @@
public class SwipeUpPreferenceControllerTest {
private Context mContext;
+ private ShadowPackageManager mPackageManager;
private SwipeUpPreferenceController mController;
+
+ private static final String ACTION_QUICKSTEP = "android.intent.action.QUICKSTEP_SERVICE";
private static final String KEY_SWIPE_UP = "gesture_swipe_up";
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
+ mPackageManager = Shadows.shadowOf(mContext.getPackageManager());
mController = new SwipeUpPreferenceController(mContext, KEY_SWIPE_UP);
}
@Test
+ public void testIsGestureAvailable_matchingServiceExists_shouldReturnTrue() {
+ final ComponentName recentsComponentName = ComponentName.unflattenFromString(
+ mContext.getString(com.android.internal.R.string.config_recentsComponentName));
+ final Intent quickStepIntent = new Intent(ACTION_QUICKSTEP)
+ .setPackage(recentsComponentName.getPackageName());
+ mPackageManager.addResolveInfoForIntent(quickStepIntent, new ResolveInfo());
+
+ assertThat(SwipeUpPreferenceController.isGestureAvailable(mContext)).isTrue();
+ }
+
+ @Test
+ public void testIsGestureAvailable_noMatchingServiceExists_shouldReturnFalse() {
+ assertThat(SwipeUpPreferenceController.isGestureAvailable(mContext)).isFalse();
+ }
+
+ @Test
public void testIsChecked_configIsSet_shouldReturnTrue() {
// Set the setting to be enabled.
mController.setChecked(true);
diff --git a/tests/robotests/src/com/android/settings/network/ApnEditorTest.java b/tests/robotests/src/com/android/settings/network/ApnEditorTest.java
index f3315e5..1b34fd3 100644
--- a/tests/robotests/src/com/android/settings/network/ApnEditorTest.java
+++ b/tests/robotests/src/com/android/settings/network/ApnEditorTest.java
@@ -21,6 +21,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -116,6 +117,24 @@
}
@Test
+ public void testApnEditor_doesNotUseManagedQuery() {
+ mApnEditorUT.getApnDataFromUri(Mockito.mock(Uri.class));
+
+ verify(mActivity, never()).managedQuery(
+ any(Uri.class),
+ any(String[].class),
+ any(String.class),
+ any(String.class));
+
+ verify(mActivity, never()).managedQuery(
+ any(Uri.class),
+ any(String[].class),
+ any(String.class),
+ any(String[].class),
+ any(String.class));
+ }
+
+ @Test
public void testSetStringValue_valueChanged_shouldSetValue() {
// GIVEN an APN value which is different than the APN value in database
final String apnKey = "apn";
diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
index d54d16f..b5399ea 100644
--- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
@@ -17,6 +17,8 @@
package com.android.settings.slices;
+import static android.content.ContentResolver.SCHEME_CONTENT;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
@@ -41,6 +43,7 @@
import androidx.slice.Slice;
+import java.util.Collection;
import java.util.HashMap;
/**
@@ -114,7 +117,190 @@
assertThat(cachedData).isNull();
}
+ @Test
+ public void getDescendantUris_fullActionUri_returnsSelf() {
+ final Uri uri = SliceBuilderUtils.getUri(
+ SettingsSlicesContract.PATH_SETTING_ACTION + "/key", true);
+
+ final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
+
+ assertThat(descendants).containsExactly(uri);
+ }
+
+ @Test
+ public void getDescendantUris_fullIntentUri_returnsSelf() {
+ final Uri uri = SliceBuilderUtils.getUri(
+ SettingsSlicesContract.PATH_SETTING_ACTION + "/key", true);
+
+ final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
+
+ assertThat(descendants).containsExactly(uri);
+ }
+
+ @Test
+ public void getDescendantUris_wrongPath_returnsEmpty() {
+ final Uri uri = SliceBuilderUtils.getUri("invalid_path", true);
+
+ final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
+
+ assertThat(descendants).isEmpty();
+ }
+
+ @Test
+ public void getDescendantUris_invalidPath_returnsEmpty() {
+ final String key = "platform_key";
+ insertSpecialCase(key, true /* isPlatformSlice */);
+ final Uri uri = new Uri.Builder()
+ .scheme(SCHEME_CONTENT)
+ .authority(SettingsSlicesContract.AUTHORITY)
+ .appendPath("invalid")
+ .build();
+
+ final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
+
+ assertThat(descendants).isEmpty();
+ }
+
+ @Test
+ public void getDescendantUris_platformSlice_doesNotReturnOEMSlice() {
+ insertSpecialCase("oem_key", false /* isPlatformSlice */);
+ final Uri uri = new Uri.Builder()
+ .scheme(SCHEME_CONTENT)
+ .authority(SettingsSlicesContract.AUTHORITY)
+ .build();
+
+ final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
+
+ assertThat(descendants).isEmpty();
+ }
+
+ @Test
+ public void getDescendantUris_oemSlice_doesNotReturnPlatformSlice() {
+ insertSpecialCase("platform_key", true /* isPlatformSlice */);
+ final Uri uri = new Uri.Builder()
+ .scheme(SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .build();
+
+ final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
+
+ assertThat(descendants).isEmpty();
+ }
+
+ @Test
+ public void getDescendantUris_oemSlice_returnsOEMUriDescendant() {
+ final String key = "oem_key";
+ insertSpecialCase(key, false /* isPlatformSlice */);
+ final Uri uri = new Uri.Builder()
+ .scheme(SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .build();
+ final Uri expectedUri = new Uri.Builder()
+ .scheme(SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath(key)
+ .build();
+
+ final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
+
+ assertThat(descendants).containsExactly(expectedUri);
+ }
+
+ @Test
+ public void getDescendantUris_oemSliceNoPath_returnsOEMUriDescendant() {
+ final String key = "oem_key";
+ insertSpecialCase(key, false /* isPlatformSlice */);
+ final Uri uri = new Uri.Builder()
+ .scheme(SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .build();
+ final Uri expectedUri = new Uri.Builder()
+ .scheme(SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath(key)
+ .build();
+
+ final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
+
+ assertThat(descendants).containsExactly(expectedUri);
+ }
+
+ @Test
+ public void getDescendantUris_platformSlice_returnsPlatformUriDescendant() {
+ final String key = "platform_key";
+ insertSpecialCase(key, true /* isPlatformSlice */);
+ final Uri uri = new Uri.Builder()
+ .scheme(SCHEME_CONTENT)
+ .authority(SettingsSlicesContract.AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .build();
+ final Uri expectedUri = new Uri.Builder()
+ .scheme(SCHEME_CONTENT)
+ .authority(SettingsSlicesContract.AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath(key)
+ .build();
+
+ final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
+
+ assertThat(descendants).containsExactly(expectedUri);
+ }
+
+ @Test
+ public void getDescendantUris_platformSliceNoPath_returnsPlatformUriDescendant() {
+ final String key = "platform_key";
+ insertSpecialCase(key, true /* isPlatformSlice */);
+ final Uri uri = new Uri.Builder()
+ .scheme(SCHEME_CONTENT)
+ .authority(SettingsSlicesContract.AUTHORITY)
+ .build();
+ final Uri expectedUri = new Uri.Builder()
+ .scheme(SCHEME_CONTENT)
+ .authority(SettingsSlicesContract.AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath(key)
+ .build();
+
+ final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
+
+ assertThat(descendants).containsExactly(expectedUri);
+ }
+
+ @Test
+ public void getDescendantUris_noAuthorityNorPath_returnsAllUris() {
+ final String platformKey = "platform_key";
+ final String oemKey = "oemKey";
+ insertSpecialCase(platformKey, true /* isPlatformSlice */);
+ insertSpecialCase(oemKey, false /* isPlatformSlice */);
+ final Uri uri = new Uri.Builder()
+ .scheme(SCHEME_CONTENT)
+ .build();
+ final Uri expectedPlatformUri = new Uri.Builder()
+ .scheme(SCHEME_CONTENT)
+ .authority(SettingsSlicesContract.AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath(platformKey)
+ .build();
+ final Uri expectedOemUri = new Uri.Builder()
+ .scheme(SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath(oemKey)
+ .build();
+
+ final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
+
+ assertThat(descendants).containsExactly(expectedPlatformUri, expectedOemUri);
+ }
+
private void insertSpecialCase(String key) {
+ insertSpecialCase(key, true);
+ }
+
+ private void insertSpecialCase(String key, boolean isPlatformSlice) {
ContentValues values = new ContentValues();
values.put(SlicesDatabaseHelper.IndexColumns.KEY, key);
values.put(SlicesDatabaseHelper.IndexColumns.TITLE, TITLE);
@@ -123,6 +309,8 @@
values.put(SlicesDatabaseHelper.IndexColumns.ICON_RESOURCE, 1234);
values.put(SlicesDatabaseHelper.IndexColumns.FRAGMENT, "test");
values.put(SlicesDatabaseHelper.IndexColumns.CONTROLLER, "test");
+ values.put(SlicesDatabaseHelper.IndexColumns.PLATFORM_SLICE, isPlatformSlice);
+ values.put(SlicesDatabaseHelper.IndexColumns.SLICE_TYPE, SliceData.SliceType.INTENT);
mDb.replaceOrThrow(SlicesDatabaseHelper.Tables.TABLE_SLICES_INDEX, null, values);
}
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
index 0cdb2f4..0b6e4b5 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
@@ -18,17 +18,28 @@
package com.android.settings.slices;
import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.app.slice.Slice;
+import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
+import android.database.ContentObserver;
import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.provider.Settings;
+import android.provider.SettingsSlicesContract;
import android.util.Pair;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.core.BasePreferenceController;
import com.android.settings.search.FakeIndexProvider;
import com.android.settings.search.SearchFeatureProvider;
import com.android.settings.search.SearchFeatureProviderImpl;
@@ -36,6 +47,7 @@
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.FakeSliderController;
import com.android.settings.testutils.FakeToggleController;
+import com.android.settings.testutils.FakeUnavailablePreferenceController;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.After;
@@ -65,7 +77,7 @@
@Before
public void setUp() {
- mContext = RuntimeEnvironment.application;
+ mContext = spy(RuntimeEnvironment.application);
mDb = SlicesDatabaseHelper.getInstance(mContext).getWritableDatabase();
mReceiver = new SliceBroadcastReceiver();
SlicesDatabaseHelper helper = SlicesDatabaseHelper.getInstance(mContext);
@@ -192,6 +204,77 @@
mReceiver.onReceive(mContext, intent);
}
+ @Test
+ public void toggleUpdate_unavailableUriNotified() {
+ // Monitor the ContentResolver
+ final ContentResolver resolver = spy(mContext.getContentResolver());
+ doReturn(resolver).when(mContext).getContentResolver();
+
+ // Disable Setting
+ Settings.Global.putInt(mContext.getContentResolver(),
+ FakeToggleController.AVAILABILITY_KEY,
+ BasePreferenceController.DISABLED_UNSUPPORTED);
+
+ // Insert Fake Toggle into Database
+ final String key = "key";
+ mSearchFeatureProvider.getSearchIndexableResources().getProviderValues().clear();
+ insertSpecialCase(FakeToggleController.class, key);
+
+ // Turn on toggle setting
+ final FakeToggleController fakeToggleController = new FakeToggleController(mContext, key);
+ fakeToggleController.setChecked(true);
+
+ // Build Action
+ final Intent intent = new Intent(SettingsSliceProvider.ACTION_TOGGLE_CHANGED);
+ intent.putExtra(SettingsSliceProvider.EXTRA_SLICE_KEY, key);
+
+ // Trigger Slice change
+ mReceiver.onReceive(mContext, intent);
+
+ // Check the value is the same and the Uri has been notified.
+ assertThat(fakeToggleController.isChecked()).isTrue();
+ final Uri expectedUri = SliceBuilderUtils.getUri(
+ SettingsSlicesContract.PATH_SETTING_ACTION + "/" + key, false);
+ verify(resolver).notifyChange(eq(expectedUri), eq(null));
+ }
+
+ @Test
+ public void sliderUpdate_unavailableUriNotified() {
+ // Monitor the ContentResolver
+ final ContentResolver resolver = spy(mContext.getContentResolver());
+ doReturn(resolver).when(mContext).getContentResolver();
+
+ // Disable Setting
+ Settings.Global.putInt(mContext.getContentResolver(),
+ FakeSliderController.AVAILABILITY_KEY,
+ BasePreferenceController.DISABLED_UNSUPPORTED);
+
+ // Insert Fake Slider into Database
+ final String key = "key";
+ final int position = FakeSliderController.MAX_STEPS - 1;
+ final int oldPosition = FakeSliderController.MAX_STEPS;
+ mSearchFeatureProvider.getSearchIndexableResources().getProviderValues().clear();
+ insertSpecialCase(FakeSliderController.class, key);
+
+ // Set slider setting
+ final FakeSliderController fakeSliderController = new FakeSliderController(mContext, key);
+ fakeSliderController.setSliderPosition(oldPosition);
+
+ // Build action
+ final Intent intent = new Intent(SettingsSliceProvider.ACTION_SLIDER_CHANGED);
+ intent.putExtra(Slice.EXTRA_RANGE_VALUE, position);
+ intent.putExtra(SettingsSliceProvider.EXTRA_SLICE_KEY, key);
+
+ // Trigger Slice change
+ mReceiver.onReceive(mContext, intent);
+
+ // Check position is the same and the Uri has been notified.
+ assertThat(fakeSliderController.getSliderPosition()).isEqualTo(oldPosition);
+ final Uri expectedUri = SliceBuilderUtils.getUri(
+ SettingsSlicesContract.PATH_SETTING_ACTION + "/" + key, false);
+ verify(resolver).notifyChange(eq(expectedUri), eq(null));
+ }
+
private void insertSpecialCase(String key) {
insertSpecialCase(fakeControllerName, key);
}
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
index 59eb7ce..8b99c4a 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
@@ -24,7 +24,6 @@
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
-import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -40,6 +39,7 @@
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.FakeSliderController;
import com.android.settings.testutils.FakeToggleController;
+import com.android.settings.testutils.FakeUnavailablePreferenceController;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.SliceTester;
@@ -295,14 +295,16 @@
assertThat(pathPair.second).isEqualTo(KEY);
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void getPathData_noKey_returnsNull() {
final Uri uri = new Uri.Builder()
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
.build();
- SliceBuilderUtils.getPathData(uri);
+ final Pair<Boolean, String> pathPair = SliceBuilderUtils.getPathData(uri);
+
+ assertThat(pathPair).isNull();
}
@Test
@@ -324,7 +326,7 @@
public void testUnsupportedSlice_validTitleSummary() {
final SliceData data = getDummyData(FakeUnavailablePreferenceController.class,
SliceData.SliceType.SWITCH);
- Settings.System.putInt(mContext.getContentResolver(),
+ Settings.Global.putInt(mContext.getContentResolver(),
FakeUnavailablePreferenceController.AVAILABILITY_KEY,
BasePreferenceController.DISABLED_UNSUPPORTED);
@@ -337,7 +339,7 @@
public void testDisabledForUserSlice_validTitleSummary() {
final SliceData data = getDummyData(FakeUnavailablePreferenceController.class,
SliceData.SliceType.SWITCH);
- Settings.System.putInt(mContext.getContentResolver(),
+ Settings.Global.putInt(mContext.getContentResolver(),
FakeUnavailablePreferenceController.AVAILABILITY_KEY,
BasePreferenceController.DISABLED_FOR_USER);
@@ -350,7 +352,7 @@
public void testDisabledDependentSettingSlice_validTitleSummary() {
final SliceData data = getDummyData(FakeUnavailablePreferenceController.class,
SliceData.SliceType.INTENT);
- Settings.System.putInt(mContext.getContentResolver(),
+ Settings.Global.putInt(mContext.getContentResolver(),
FakeUnavailablePreferenceController.AVAILABILITY_KEY,
BasePreferenceController.DISABLED_DEPENDENT_SETTING);
@@ -372,7 +374,7 @@
public void testUnavailableUnknownSlice_validTitleSummary() {
final SliceData data = getDummyData(FakeUnavailablePreferenceController.class,
SliceData.SliceType.SWITCH);
- Settings.System.putInt(mContext.getContentResolver(),
+ Settings.Global.putInt(mContext.getContentResolver(),
FakeUnavailablePreferenceController.AVAILABILITY_KEY,
BasePreferenceController.UNAVAILABLE_UNKNOWN);
diff --git a/tests/robotests/src/com/android/settings/slices/SlicesDatabaseAccessorTest.java b/tests/robotests/src/com/android/settings/slices/SlicesDatabaseAccessorTest.java
index 77c9891..45ec064 100644
--- a/tests/robotests/src/com/android/settings/slices/SlicesDatabaseAccessorTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SlicesDatabaseAccessorTest.java
@@ -18,6 +18,7 @@
package com.android.settings.slices;
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Mockito.spy;
import android.content.ContentValues;
@@ -35,15 +36,17 @@
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
+import java.util.List;
+
@RunWith(SettingsRobolectricTestRunner.class)
public class SlicesDatabaseAccessorTest {
- private final String fakeTitle = "title";
- private final String fakeSummary = "summary";
- private final String fakeScreenTitle = "screen_title";
- private final int fakeIcon = 1234;
- private final String fakeFragmentClassName = FakeIndexProvider.class.getName();
- private final String fakeControllerName = FakePreferenceController.class.getName();
+ private final String FAKE_TITLE = "title";
+ private final String FAKE_SUMMARY = "summary";
+ private final String FAKE_SCREEN_TITLE = "screen_title";
+ private final int FAKE_ICON = 1234;
+ private final String FAKE_FRAGMENT_NAME = FakeIndexProvider.class.getName();
+ private final String FAKE_CONTROLLER_NAME = FakePreferenceController.class.getName();
private Context mContext;
private SQLiteDatabase mDb;
@@ -70,13 +73,13 @@
SliceData data = mAccessor.getSliceDataFromKey(key);
assertThat(data.getKey()).isEqualTo(key);
- assertThat(data.getTitle()).isEqualTo(fakeTitle);
- assertThat(data.getSummary()).isEqualTo(fakeSummary);
- assertThat(data.getScreenTitle()).isEqualTo(fakeScreenTitle);
- assertThat(data.getIconResource()).isEqualTo(fakeIcon);
- assertThat(data.getFragmentClassName()).isEqualTo(fakeFragmentClassName);
+ assertThat(data.getTitle()).isEqualTo(FAKE_TITLE);
+ assertThat(data.getSummary()).isEqualTo(FAKE_SUMMARY);
+ assertThat(data.getScreenTitle()).isEqualTo(FAKE_SCREEN_TITLE);
+ assertThat(data.getIconResource()).isEqualTo(FAKE_ICON);
+ assertThat(data.getFragmentClassName()).isEqualTo(FAKE_FRAGMENT_NAME);
assertThat(data.getUri()).isNull();
- assertThat(data.getPreferenceController()).isEqualTo(fakeControllerName);
+ assertThat(data.getPreferenceController()).isEqualTo(FAKE_CONTROLLER_NAME);
}
@Test(expected = IllegalStateException.class)
@@ -96,13 +99,13 @@
SliceData data = mAccessor.getSliceDataFromUri(uri);
assertThat(data.getKey()).isEqualTo(key);
- assertThat(data.getTitle()).isEqualTo(fakeTitle);
- assertThat(data.getSummary()).isEqualTo(fakeSummary);
- assertThat(data.getScreenTitle()).isEqualTo(fakeScreenTitle);
- assertThat(data.getIconResource()).isEqualTo(fakeIcon);
- assertThat(data.getFragmentClassName()).isEqualTo(fakeFragmentClassName);
+ assertThat(data.getTitle()).isEqualTo(FAKE_TITLE);
+ assertThat(data.getSummary()).isEqualTo(FAKE_SUMMARY);
+ assertThat(data.getScreenTitle()).isEqualTo(FAKE_SCREEN_TITLE);
+ assertThat(data.getIconResource()).isEqualTo(FAKE_ICON);
+ assertThat(data.getFragmentClassName()).isEqualTo(FAKE_FRAGMENT_NAME);
assertThat(data.getUri()).isEqualTo(uri);
- assertThat(data.getPreferenceController()).isEqualTo(fakeControllerName);
+ assertThat(data.getPreferenceController()).isEqualTo(FAKE_CONTROLLER_NAME);
}
@Test(expected = IllegalStateException.class)
@@ -111,15 +114,62 @@
mAccessor.getSliceDataFromUri(uri);
}
+ @Test
+ public void getDescendantUris_platformSlice_doesNotReturnOEMSlice() {
+ final String key = "oem_key";
+ final boolean isPlatformSlice = false;
+ insertSpecialCase(key, isPlatformSlice);
+ final List<String> keys = mAccessor.getSliceKeys(!isPlatformSlice);
+
+ assertThat(keys).isEmpty();
+ }
+
+ @Test
+ public void getDescendantUris_oemSlice_doesNotReturnPlatformSlice() {
+ final String key = "platform_key";
+ final boolean isPlatformSlice = true;
+ insertSpecialCase(key, isPlatformSlice);
+ final List<String> keys = mAccessor.getSliceKeys(!isPlatformSlice);
+
+ assertThat(keys).isEmpty();
+ }
+
+ @Test
+ public void getDescendantUris_oemSlice_returnsOEMUriDescendant() {
+ final String key = "oem_key";
+ final boolean isPlatformSlice = false;
+ insertSpecialCase(key, isPlatformSlice);
+ final List<String> keys = mAccessor.getSliceKeys(isPlatformSlice);
+
+ assertThat(keys).containsExactly(key);
+ }
+
+ @Test
+ public void getDescendantUris_platformSlice_returnsPlatformUriDescendant() {
+ final String key = "platform_key";
+ final boolean isPlatformSlice = true;
+ insertSpecialCase(key, isPlatformSlice);
+ final List<String> keys = mAccessor.getSliceKeys(isPlatformSlice);
+
+ assertThat(keys).containsExactly(key);
+ }
+
private void insertSpecialCase(String key) {
+ insertSpecialCase(key, true);
+ }
+
+ private void insertSpecialCase(String key, boolean isPlatformSlice) {
ContentValues values = new ContentValues();
values.put(SlicesDatabaseHelper.IndexColumns.KEY, key);
- values.put(SlicesDatabaseHelper.IndexColumns.TITLE, fakeTitle);
- values.put(SlicesDatabaseHelper.IndexColumns.SUMMARY, fakeSummary);
- values.put(SlicesDatabaseHelper.IndexColumns.SCREENTITLE, fakeScreenTitle);
- values.put(SlicesDatabaseHelper.IndexColumns.ICON_RESOURCE, fakeIcon);
- values.put(SlicesDatabaseHelper.IndexColumns.FRAGMENT, fakeFragmentClassName);
- values.put(SlicesDatabaseHelper.IndexColumns.CONTROLLER, fakeControllerName);
+ values.put(SlicesDatabaseHelper.IndexColumns.TITLE, FAKE_TITLE);
+ values.put(SlicesDatabaseHelper.IndexColumns.SUMMARY, FAKE_SUMMARY);
+ values.put(SlicesDatabaseHelper.IndexColumns.SCREENTITLE, FAKE_SCREEN_TITLE);
+ values.put(SlicesDatabaseHelper.IndexColumns.ICON_RESOURCE, FAKE_ICON);
+ values.put(SlicesDatabaseHelper.IndexColumns.FRAGMENT, FAKE_FRAGMENT_NAME);
+ values.put(SlicesDatabaseHelper.IndexColumns.CONTROLLER, FAKE_CONTROLLER_NAME);
+ values.put(SlicesDatabaseHelper.IndexColumns.PLATFORM_SLICE, isPlatformSlice);
+ values.put(SlicesDatabaseHelper.IndexColumns.SLICE_TYPE, SliceData.SliceType.INTENT);
+
mDb.replaceOrThrow(SlicesDatabaseHelper.Tables.TABLE_SLICES_INDEX, null, values);
}
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeSliderController.java b/tests/robotests/src/com/android/settings/testutils/FakeSliderController.java
index f4f91ed..530bdee 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeSliderController.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeSliderController.java
@@ -19,13 +19,14 @@
import android.content.Context;
import android.provider.Settings;
-import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.SliderPreferenceController;
public class FakeSliderController extends SliderPreferenceController {
private final String settingKey = "fake_slider_key";
+ public static final String AVAILABILITY_KEY = "fake_slider_availability_key";
+
public static final int MAX_STEPS = 9;
public FakeSliderController(Context context, String key) {
@@ -49,6 +50,7 @@
@Override
public int getAvailabilityStatus() {
- return BasePreferenceController.AVAILABLE;
+ return Settings.Global.getInt(mContext.getContentResolver(),
+ AVAILABILITY_KEY, AVAILABLE);
}
}
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeToggleController.java b/tests/robotests/src/com/android/settings/testutils/FakeToggleController.java
index c984c6c..d0ce76f 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeToggleController.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeToggleController.java
@@ -26,6 +26,8 @@
private String settingKey = "toggle_key";
+ public static final String AVAILABILITY_KEY = "fake_toggle_availability_key";
+
private final int ON = 1;
private final int OFF = 0;
@@ -47,6 +49,7 @@
@Override
public int getAvailabilityStatus() {
- return AVAILABLE;
+ return Settings.Global.getInt(mContext.getContentResolver(),
+ AVAILABILITY_KEY, AVAILABLE);
}
}
diff --git a/tests/robotests/src/com/android/settings/slices/FakeUnavailablePreferenceController.java b/tests/robotests/src/com/android/settings/testutils/FakeUnavailablePreferenceController.java
similarity index 82%
rename from tests/robotests/src/com/android/settings/slices/FakeUnavailablePreferenceController.java
rename to tests/robotests/src/com/android/settings/testutils/FakeUnavailablePreferenceController.java
index a7e5d75..1ceaad8 100644
--- a/tests/robotests/src/com/android/settings/slices/FakeUnavailablePreferenceController.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeUnavailablePreferenceController.java
@@ -1,4 +1,4 @@
-package com.android.settings.slices;
+package com.android.settings.testutils;
import android.content.Context;
import android.provider.Settings;
@@ -15,7 +15,7 @@
@Override
public int getAvailabilityStatus() {
- return Settings.System.getInt(mContext.getContentResolver(),
+ return Settings.Global.getInt(mContext.getContentResolver(),
AVAILABILITY_KEY, 0);
}
}
diff --git a/tests/robotests/src/com/android/settings/widget/ValidatedEditTextPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/ValidatedEditTextPreferenceTest.java
index 5ba9f8a..865422c 100644
--- a/tests/robotests/src/com/android/settings/widget/ValidatedEditTextPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/widget/ValidatedEditTextPreferenceTest.java
@@ -116,7 +116,7 @@
mPreference.onBindDialogView(mView);
assertThat(editText.getInputType()
- & (InputType.TYPE_TEXT_VARIATION_PASSWORD | InputType.TYPE_CLASS_TEXT))
+ & (InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD | InputType.TYPE_CLASS_TEXT))
.isNotEqualTo(0);
}
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java
index 60faa2e..7e757ad 100644
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java
@@ -145,4 +145,21 @@
assertThat(mController.getSecuritySettingForPassword())
.isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
}
+
+ @Test
+ public void updateDisplay_shouldSetInputType() {
+ // Set controller password to anything and verify is set.
+ mController.displayPreference(mScreen);
+ mController.onPreferenceChange(mPreference, "1");
+ assertThat(mController.getPassword()).isEqualTo("1");
+
+ // Create a new config using different password
+ final WifiConfiguration config = new WifiConfiguration();
+ config.preSharedKey = "test_1234";
+ when(mWifiManager.getWifiApConfiguration()).thenReturn(config);
+
+ // Call updateDisplay and verify it's changed.
+ mController.updateDisplay();
+ assertThat(mPreference.isPassword()).isTrue();
+ }
}