Merge "5/n: Add face settings"
diff --git a/Android.mk b/Android.mk
index a573378..6b0d077 100644
--- a/Android.mk
+++ b/Android.mk
@@ -25,13 +25,10 @@
androidx.slice_slice-core \
androidx.slice_slice-view \
androidx.core_core \
- androidx.legacy_legacy-support-v4 \
- androidx.legacy_legacy-support-v13 \
androidx.appcompat_appcompat \
androidx.cardview_cardview \
androidx.preference_preference \
androidx.recyclerview_recyclerview \
- androidx.legacy_legacy-preference-v14 \
com.google.android.material_material \
LOCAL_JAVA_LIBRARIES := \
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b4dcd9c..bb43bbf 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -737,7 +737,6 @@
android:label="@string/zen_mode_settings_title"
android:icon="@drawable/ic_notifications"
android:exported="true"
- android:taskAffinity="com.android.settings"
android:parentActivityName="Settings">
<intent-filter android:priority="1">
<action android:name="android.settings.ZEN_MODE_SETTINGS" />
@@ -908,7 +907,6 @@
android:label="@string/night_display_title"
android:enabled="@*android:bool/config_nightDisplayAvailable"
android:icon="@drawable/ic_settings_night_display"
- android:taskAffinity="com.android.settings"
android:parentActivityName="Settings">
<intent-filter android:priority="32">
<action android:name="android.intent.action.MAIN" />
@@ -1930,7 +1928,7 @@
<activity android:name=".bluetooth.BluetoothPairingDialog"
android:excludeFromRecents="true"
android:windowSoftInputMode="stateVisible|adjustResize"
- android:theme="@*android:style/Theme.DeviceDefault.Settings.Dialog.NoActionBar">
+ android:theme="@style/Theme.AlertDialog">
<intent-filter android:priority="1">
<action android:name="android.bluetooth.device.action.PAIRING_REQUEST" />
<category android:name="android.intent.category.DEFAULT" />
@@ -1958,13 +1956,6 @@
</intent-filter>
</activity>
- <activity android:name=".connecteddevice.usb.UsbModeChooserActivity"
- android:excludeFromRecents="true"
- android:exported="true"
- android:permission="android.permission.MANAGE_USB"
- android:theme="@*android:style/Theme.DeviceDefault.Settings.Dialog.NoActionBar">
- </activity>
-
<activity android:name=".Settings$UsbDetailsActivity"
android:excludeFromRecents="true"
android:permission="android.permission.MANAGE_USB"
@@ -1977,7 +1968,7 @@
android:excludeFromRecents="true"
android:exported="true"
android:permission="android.permission.DUMP"
- android:theme="@*android:style/Theme.DeviceDefault.Settings.Dialog.NoActionBar">
+ android:theme="@style/Theme.AlertDialog">
<intent-filter>
<action android:name="android.settings.SHOW_REMOTE_BUGREPORT_DIALOG" />
<category android:name="android.intent.category.DEFAULT" />
@@ -2673,7 +2664,7 @@
</activity>
<activity android:name=".sim.SimPreferenceDialog"
- android:theme="@*android:style/Theme.DeviceDefault.Settings.Dialog.NoActionBar"
+ android:theme="@style/Theme.AlertDialog"
android:excludeFromRecents="true" />
<activity
@@ -2703,7 +2694,7 @@
</activity>
<activity android:name=".sim.SimDialogActivity"
- android:theme="@*android:style/Theme.DeviceDefault.Settings.Dialog.NoActionBar"
+ android:theme="@style/Theme.AlertDialog"
android:label="@string/sim_settings_title"
android:excludeFromRecents="true">
<intent-filter>
diff --git a/res/drawable/ic_accessibility_illustration_colorblind.xml b/res/drawable/ic_accessibility_illustration_colorblind.xml
new file mode 100644
index 0000000..e2e73aa
--- /dev/null
+++ b/res/drawable/ic_accessibility_illustration_colorblind.xml
@@ -0,0 +1,67 @@
+<!--
+ ~ 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
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="264.0"
+ android:viewportWidth="264.0">
+ <path android:fillColor="#FBBC04"
+ android:pathData="M112.52,208.91c-0.15,-0.9 -0.95,-1.54 -1.87,-1.51c-17.81,0.66 -36.14,-7.45 -51.36,-19.19c-24.31,-18.75 -40.49,-51.17 -34.81,-79.36l-3.53,-1.81c-24.28,31.54 -18.42,76.8 13.11,101.11c23.58,18.19 53.7,19.43 78.15,5.76L112.52,208.91z"/>
+ <path android:fillColor="#FDE293"
+ android:pathData="M44.48,195.92c18.36,14.16 46.39,20.23 66.95,18.26c1.04,-0.1 1.79,-1.05 1.62,-2.09l-0.52,-3.19c-0.15,-0.9 -0.95,-1.54 -1.87,-1.51c-17.81,0.66 -36.14,-7.45 -51.36,-19.19c-24.31,-18.75 -40.49,-51.17 -34.81,-79.36l-3.53,-1.81C9.98,136.93 15.03,173.21 44.48,195.92z"/>
+ <path android:fillColor="#6D4C41"
+ android:pathData="M20.8,107.25l1.15,-7.6c0.18,-1.17 1.42,-1.85 2.5,-1.38l3.31,1.44c1.01,0.44 1.39,1.67 0.81,2.6l-4.08,6.55L20.8,107.25z"/>
+ <path android:fillColor="#6D4C41"
+ android:pathData="M102,74.65l-0.03,2.62c-1.15,0.05 -2.31,0.04 -3.46,-0.02c-0.01,-0.04 0.01,-2.58 0,-2.62c-1.03,-7.56 0.59,-13.08 1.98,-16.21c0.35,-0.79 1.22,-1.2 2.05,-0.98c1.22,0.33 2.44,0.68 3.64,1.04c1.1,0.34 1.58,1.65 0.94,2.61C102.05,68.82 102,74.65 102,74.65z"/>
+ <path android:fillColor="#FEEFC3"
+ android:pathData="M148.04,97.35c-1.11,-13.75 -12.4,-24.77 -26.17,-25.59c-3.6,-0.21 -7.06,0.26 -10.28,1.29c-7.39,2.39 -15.3,2.33 -22.66,-0.15c-3.2,-1.08 -6.65,-1.6 -10.26,-1.43c-13.78,0.63 -25.21,11.5 -26.51,25.24c-0.47,4.97 0.38,9.7 2.22,13.9l-0.01,0l18.44,43.41c0.04,0.1 0.08,0.2 0.12,0.29l0.15,0.36l0.02,0c2.21,4.75 6.99,8.06 12.57,8.1c2.57,0.02 4.99,-0.66 7.07,-1.86c4.26,-2.46 9.62,-2.42 13.85,0.09c2.06,1.23 4.47,1.94 7.04,1.96c5.58,0.04 10.41,-3.21 12.68,-7.93l0.02,0l0.16,-0.36c0.04,-0.1 0.09,-0.19 0.13,-0.29l19.02,-43.16l-0.01,0C147.53,107.05 148.45,102.33 148.04,97.35z"/>
+ <path android:fillColor="#EA4335"
+ android:pathData="M79.99,77.27c2.43,0 4.81,0.39 7.08,1.16c4.34,1.47 8.86,2.21 13.42,2.21c4.38,0 8.71,-0.68 12.89,-2.03c2.18,-0.71 4.47,-1.06 6.79,-1.06c0.45,0 0.9,0.01 1.35,0.04c10.92,0.65 19.83,9.35 20.71,20.25c0.31,3.83 -0.33,7.53 -1.9,10.99l-3.94,8.69l0.13,-0.01l-15.22,34.54l-0.03,0.06l-0.02,0.04l0,0.01l-0.17,0.36c-1.38,2.86 -4.19,4.63 -7.34,4.63l-0.06,0c-1.45,-0.01 -2.87,-0.4 -4.1,-1.14c-3,-1.78 -6.45,-2.73 -9.98,-2.73c-3.44,0 -6.81,0.9 -9.75,2.6c-1.23,0.71 -2.63,1.08 -4.06,1.08l-0.06,0c-3.13,-0.02 -6,-1.88 -7.33,-4.73l-0.15,-0.33l-0.02,-0.05l-0.02,-0.05l-0.02,-0.05l-14.77,-34.77l0.13,0.01l-3.82,-8.71c-1.53,-3.48 -2.12,-7.19 -1.76,-11.02c1.03,-10.88 10.05,-19.47 20.98,-19.97C79.3,77.28 79.64,77.27 79.99,77.27L79.99,77.27M79.99,71.45c-0.44,0 -0.87,0.01 -1.31,0.03c-13.78,0.63 -25.21,11.5 -26.51,25.24c-0.47,4.97 0.38,9.7 2.22,13.9l-0.01,0l18.44,43.41c0.04,0.1 0.08,0.2 0.12,0.29l0.15,0.36l0.02,0c2.21,4.75 6.99,8.06 12.57,8.1c0.03,0 0.06,0 0.1,0c2.54,0 4.92,-0.68 6.97,-1.86c2.1,-1.21 4.47,-1.82 6.84,-1.82c2.43,0 4.86,0.64 7,1.91c2.06,1.23 4.47,1.94 7.04,1.96c0.03,0 0.06,0 0.1,0c5.54,0 10.33,-3.24 12.58,-7.93l0.02,0l0.16,-0.36c0.04,-0.1 0.09,-0.19 0.13,-0.29l19.02,-43.16l-0.01,0c1.9,-4.17 2.81,-8.9 2.41,-13.87c-1.11,-13.75 -12.4,-24.77 -26.17,-25.59c-0.57,-0.03 -1.13,-0.05 -1.69,-0.05c-2.99,0 -5.88,0.47 -8.58,1.35c-3.62,1.17 -7.36,1.75 -11.1,1.75c-3.9,0 -7.8,-0.63 -11.56,-1.9C86.13,71.96 83.12,71.45 79.99,71.45L79.99,71.45z"/>
+ <path android:fillColor="#FBBC04"
+ android:pathData="M87.76,114.52c-1.45,-0.01 -2.63,1.16 -2.64,2.6c-0.01,1.45 1.16,2.63 2.6,2.64c1.45,0.01 5.26,-2.59 5.26,-2.59S89.21,114.53 87.76,114.52z"/>
+ <path android:fillColor="#FBBC04"
+ android:pathData="M93.4,106.75c-1.02,-1.03 -2.68,-1.04 -3.71,-0.02c-1.03,1.02 -1.04,2.68 -0.02,3.71c1.02,1.03 5.55,1.89 5.55,1.89S94.42,107.78 93.4,106.75z"/>
+ <path android:fillColor="#FBBC04"
+ android:pathData="M93.26,128.06c-1.03,1.02 -2.69,1.01 -3.71,-0.02c-1.02,-1.03 -1.01,-2.69 0.02,-3.71c1.03,-1.02 5.57,-1.82 5.57,-1.82S94.29,127.04 93.26,128.06z"/>
+ <path android:fillColor="#EA4335"
+ android:pathData="M148.04,97.35c-1.11,-13.75 -12.4,-24.77 -26.17,-25.59c-3.6,-0.21 -7.06,0.26 -10.28,1.29c-3.69,1.19 -7.52,1.78 -11.34,1.75l-0.56,84.29c2.4,0.02 4.8,0.65 6.91,1.91c2.06,1.23 4.47,1.94 7.04,1.96c5.58,0.04 10.41,-3.21 12.68,-7.93l0.02,0l0.16,-0.36c0.04,-0.1 0.09,-0.19 0.13,-0.29l19.02,-43.16l-0.01,0C147.53,107.05 148.45,102.33 148.04,97.35z"/>
+ <path android:fillColor="#9CCC65"
+ android:pathData="M169.25,173.55c-0.75,-0.24 -1.54,-0.38 -2.37,-0.37c-4.11,0.03 -7.42,3.38 -7.39,7.49C164.05,180.63 167.9,177.65 169.25,173.55z"/>
+ <path android:fillColor="#9CCC65"
+ android:pathData="M149.06,170.38c0.04,5.72 4.71,10.33 10.43,10.29C159.45,174.94 154.78,170.34 149.06,170.38z"/>
+ <path android:fillColor="#F57C00"
+ android:pathData="M128.64,213.24a31.07,31.07 0,1 0,62.14 -0.42a31.07,31.07 0,1 0,-62.14 0.42z"/>
+ <path android:fillColor="#9CCC65"
+ android:pathData="M153.74,20.13c-1.04,0.17 -1.87,0.99 -2.04,2.04c-0.86,5.29 0.73,10.9 4.81,14.97s9.69,5.67 14.97,4.81c1.04,-0.17 1.87,-0.99 2.04,-2.04c0.86,-5.29 -0.73,-10.9 -4.81,-14.97C164.64,20.86 159.03,19.27 153.74,20.13z"/>
+ <path android:fillColor="#3949AB"
+ android:pathData="M158.58,69.64a12.99,12.99 62.72,1 0,4.91 -25.51a12.99,12.99 62.72,1 0,-4.91 25.51z"/>
+ <path android:fillColor="#1A237E"
+ android:pathData="M159.66,51.83l2.66,2.78l3.74,0.91l-2.78,2.66l-0.91,3.75l-2.66,-2.79l-3.74,-0.91l2.78,-2.66z"/>
+ <path android:fillColor="#3949AB"
+ android:pathData="M185.95,62.31a12.99,12.99 114.61,1 0,4.91 -25.51a12.99,12.99 62.72,1 0,-4.91 25.51z"/>
+ <path android:fillColor="#1A237E"
+ android:pathData="M187.03,44.49l2.66,2.79l3.74,0.91l-2.78,2.66l-0.91,3.74l-2.66,-2.78l-3.74,-0.91l2.78,-2.66z"/>
+ <path android:fillColor="#3949AB"
+ android:pathData="M169.42,83.27a12.99,12.99 87.23,1 0,21.51 -14.57a12.99,12.99 123.26,1 0,-21.51 14.57z"/>
+ <path android:fillColor="#1A237E"
+ android:pathData="M182.79,71.45l-0.09,3.85l2,3.29l-3.85,-0.09l-3.29,2l0.09,-3.85l-2,-3.29l3.85,0.09z"/>
+ <path android:fillColor="#8D6E63"
+ android:pathData="M242.38,62.35c0.98,2.75 2.3,9.01 -1.42,17.85l2.91,0.73c0,0 5.93,-9.31 4.14,-20.42c-0.2,-1.27 -1.58,-2 -2.76,-1.49c-0.72,0.31 -1.35,0.61 -1.88,0.87C242.47,60.35 242.04,61.4 242.38,62.35z"/>
+ <path android:fillColor="#9CCC65"
+ android:pathData="M255.94,108.8c2.85,-6.33 2.91,-13.91 -0.73,-20.75c-4.98,-9.36 -15.93,-14.24 -26.21,-11.7c-7.34,1.81 -12.85,6.72 -15.72,12.86c-4.4,9.42 -11.23,17.6 -19.98,23.21c-7.06,4.53 -12.73,11.42 -15.69,20.17c-5.98,17.69 1.9,37.45 18.39,46.22c19.93,10.6 44.32,1.98 53.36,-18.29c3.05,-6.84 3.95,-14.1 2.98,-21.01C250.87,129.11 251.62,118.38 255.94,108.8z"/>
+ <path android:fillColor="#81C995"
+ android:pathData="M252.33,139.52c-1.46,-10.41 -0.71,-21.14 3.61,-30.72c2.85,-6.33 2.91,-13.91 -0.73,-20.75c-0.9,-1.69 -1.99,-3.22 -3.24,-4.6c1.62,5.53 1.11,11.25 -1.12,16.2c-4.32,9.59 -5.07,20.31 -3.61,30.72c0.97,6.91 0.08,14.17 -2.98,21.01c-9.04,20.26 -33.43,28.89 -53.36,18.29c-5.07,-2.7 -9.32,-6.43 -12.61,-10.83c3.26,8.34 9.38,15.56 17.7,19.98c19.93,10.6 44.32,1.98 53.36,-18.29C252.41,153.69 253.31,146.43 252.33,139.52z"/>
+</vector>
diff --git a/res/layout/settings_homepage.xml b/res/layout/settings_homepage.xml
index c36cf8b..fb00c7d 100644
--- a/res/layout/settings_homepage.xml
+++ b/res/layout/settings_homepage.xml
@@ -43,7 +43,7 @@
android:id="@+id/search_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:src="@drawable/ic_search_24dp"
+ android:src="@drawable/ic_search_floating_24dp"
app:backgroundTint="@android:color/white"
app:layout_anchor="@id/bar" />
diff --git a/res/values/aliases.xml b/res/values/aliases.xml
index 060ba1d..1be4350 100644
--- a/res/values/aliases.xml
+++ b/res/values/aliases.xml
@@ -23,5 +23,6 @@
<item name="fingerprint_enroll_enrolling" type="layout">@layout/fingerprint_enroll_enrolling_base</item>
<item name="fingerprint_enroll_finish" type="layout">@layout/fingerprint_enroll_finish_base</item>
<item name="choose_lock_pattern" type="layout">@layout/choose_lock_pattern_common</item>
+ <item name="ic_search_floating_24dp" type="drawable">@drawable/ic_search_24dp</item>
</resources>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 0a058d5..e57cbfa 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1119,4 +1119,18 @@
<item>0</item>
</string-array>
+ <!-- Titles for autofill logging level preference. [CHAR LIMIT=50] -->
+ <string-array name="autofill_logging_level_entries">
+ <item>Off</item>
+ <item>Debug</item>
+ <item>Verbose</item>
+ </string-array>
+
+ <!-- Values for autofill logging level preference. -->
+ <string-array name="autofill_logging_level_values" translatable="false" >
+ <item>0</item> <!-- AutofillManager.NO_LOGGING -->
+ <item>2</item> <!-- AutofillManager.FLAG_ADD_CLIENT_DEBUG -->
+ <item>4</item> <!-- AutofillManager.FLAG_ADD_CLIENT_VERBOSE -->
+ </string-array>
+
</resources>
diff --git a/res/values/bools.xml b/res/values/bools.xml
index b406605..08bb08c 100644
--- a/res/values/bools.xml
+++ b/res/values/bools.xml
@@ -32,6 +32,9 @@
Can be overridden for specific product builds. -->
<bool name="auto_confirm_bluetooth_activation_dialog">false</bool>
+ <!-- Whether the device name is shown in About device or not -->
+ <bool name="config_show_device_name">true</bool>
+
<!-- Whether to show a preference item for the manual in About phone -->
<bool name="config_show_manual">false</bool>
<!-- Whether to show a preference item for regulatory information in About phone -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 5a49147..df98e0e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -841,7 +841,9 @@
<string name="disabled_by_administrator_summary">Disabled by admin</string>
<!-- In the security screen, the header title for security statuses -->
<string name="security_status_title">Security status</string>
- <!-- Summary for Security settings, explaining a few important settings under it [CHAR LIMIT=NONE]-->
+ <!-- Summary for Security settings, explaining a few important settings under it [CHAR LIMIT=NONE] -->
+ <string name="security_dashboard_summary_face">Screen lock, face unlock</string>
+ <!-- Summary for Security settings, explaining a few important settings under it [CHAR LIMIT=NONE] -->
<string name="security_dashboard_summary">Screen lock, fingerprint</string>
<!-- Summary for Security settings when fingerprint is not supported [CHAR LIMIT=NONE]-->
<string name="security_dashboard_summary_no_fingerprint">Screen lock</string>
@@ -4583,6 +4585,8 @@
<!-- Used in the Captions settings screen to control turning on/off the feature entirely -->
<string name="accessibility_caption_master_switch_title">Use captions</string>
+ <!-- Button text for the accessibility dialog continue to the next screen for hearing aid. [CHAR LIMIT=32] -->
+ <string name="accessibility_hearingaid_instruction_continue_button">Continue</string>
<!-- Title for the accessibility preference for hearing aid. [CHAR LIMIT=35] -->
<string name="accessibility_hearingaid_title">Hearing aids</string>
<!-- Summary for the accessibility preference for hearing aid when not connected. [CHAR LIMIT=50] -->
@@ -5100,6 +5104,9 @@
<item quantity="other">Limiting battery usage for %1$d apps</item>
</plurals>
+ <!-- Summary for restricted app to show the restriction time [CHAR LIMIT=NONE] -->
+ <string name="restricted_app_time_summary">Restricted <xliff:g id="time" example="5 days ago">%1$s</xliff:g></string>
+
<!-- Footer message for restrict app details page -->
<string name="restricted_app_detail_footer">These apps have been using battery in the background. Restricted apps may not work properly and notifications may be delayed.</string>
@@ -5954,7 +5961,7 @@
<!-- Activity title for network data usage summary. [CHAR LIMIT=25] -->
<string name="data_usage_summary_title">Data usage</string>
- <!-- Activity title Mobile data & WI-FI summary. [CHAR LIMIT=25] -->
+ <!-- Activity title Mobile data & WI-FI summary. [CHAR LIMIT=40] -->
<string name="data_usage_app_summary_title">Mobile data & Wi\u2011Fi</string>
<!-- Message about carrier data accounting. [CHAR LIMIT=100] -->
<string name="data_usage_accounting">Carrier data accounting may differ from your device.</string>
@@ -9873,6 +9880,24 @@
]]>
</string>
+ <!-- Preference category for autofill debugging development settings. [CHAR LIMIT=25] -->
+ <string name="debug_autofill_category">Autofill</string>
+
+ <!-- UI debug setting: logging level for Android Autofill [CHAR LIMIT=25] -->
+ <string name="autofill_logging_level_title">Logging level</string>
+
+ <!-- Title of developer options to set the maximum number of requests per session [CHAR LIMIT=60]-->
+ <string name="autofill_max_partitions">Max requests per session</string>
+
+ <!-- Title of developer options to set the maximum number of visible datasets in the autofill UX [CHAR LIMIT=60]-->
+ <string name="autofill_max_visible_datasets">Max visible datasets</string>
+
+ <!-- Reset all autofill developer options to their default values.[CHAR_LIMIT=60] -->
+ <string name="autofill_reset_developer_options">Reset to default values</string>
+
+ <!-- Toast message shown when autofill_reset_developer_options has been performed. [CHAR_LIMIT=none] -->
+ <string name="autofill_reset_developer_options_complete">Autofill developer options have been reset</string>
+
<!-- Name of setting for switching device theme [CHAR LIMIT=60] -->
<string name="device_theme">Device theme</string>
<!-- Name of default device theme [CHAR LIMIT=60] -->
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 3bf36ba9..63944d9 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -165,12 +165,28 @@
<item name="android:windowNoTitle">true</item>
</style>
- <style name="Theme.Settings.Home" parent="Theme.AppCompat.Light.NoActionBar">
+ <style name="Theme.Settings.Home" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Color names copied from frameworks/base/core/res/res/values/themes_device_defaults.xml -->
<item name="colorPrimary">@*android:color/primary_device_default_settings_light</item>
<item name="colorPrimaryDark">@*android:color/primary_dark_device_default_settings_light</item>
- <item name="android:colorAccent">@*android:color/accent_device_default_light</item>
+ <item name="colorAccent">@*android:color/accent_device_default_light</item>
+ </style>
+
+ <!--TODO(b/111875856) This theme will be useless, when we add real activity/fragment to handle the full screen for WifiDialog -->
+ <style name="Theme.Settings.WifiDialogFullScreen" parent="Theme.AppCompat.DayNight.NoActionBar">
+ <!-- Color names copied from frameworks/base/core/res/res/values/themes_device_defaults.xml -->
+ <item name="colorPrimary">@*android:color/primary_device_default_settings_light</item>
+ <item name="colorPrimaryDark">@*android:color/primary_dark_device_default_settings_light</item>
+ <item name="colorAccent">@*android:color/accent_device_default_light</item>
+
+ <!-- Add white nav bar with divider that matches material -->
+ <item name="android:navigationBarDividerColor">@color/ripple_material_light</item>
+ <item name="android:navigationBarColor">@android:color/white</item>
+ <item name="android:windowLightNavigationBar">true</item>
<item name="android:windowLightStatusBar">true</item>
+
+ <!-- For AndroidX AlertDialog -->
+ <item name="alertDialogTheme">@style/Theme.AlertDialog</item>
</style>
</resources>
diff --git a/res/values/themes_suw.xml b/res/values/themes_suw.xml
index 11ef373..f09b2b1 100644
--- a/res/values/themes_suw.xml
+++ b/res/values/themes_suw.xml
@@ -18,8 +18,8 @@
<!-- SUW related themes -->
<resources>
<style name="GlifTheme" parent="SuwThemeGlif">
- <!-- For all Alert Dialogs -->
- <item name="android:alertDialogTheme">@style/ThemeOverlay.AlertDialog</item>
+ <!-- For all AndroidX Alert Dialogs -->
+ <item name="alertDialogTheme">@style/ThemeOverlay.AlertDialog</item>
<item name="android:windowBackground">?android:attr/colorBackground</item>
<item name="*android:preferencePanelStyle">@*android:style/PreferencePanel.Dialog</item>
<item name="fingerprint_layout_theme">@style/FingerprintLayoutTheme</item>
@@ -37,8 +37,8 @@
</style>
<style name="GlifTheme.Light" parent="SuwThemeGlif.Light">
- <!-- For all Alert Dialogs -->
- <item name="android:alertDialogTheme">@style/ThemeOverlay.AlertDialog</item>
+ <!-- For all AndroidX Alert Dialogs -->
+ <item name="alertDialogTheme">@style/ThemeOverlay.AlertDialog</item>
<item name="android:windowBackground">?android:attr/colorBackground</item>
<item name="*android:preferencePanelStyle">@*android:style/PreferencePanel.Dialog</item>
<item name="fingerprint_layout_theme">@style/FingerprintLayoutTheme</item>
@@ -56,8 +56,8 @@
</style>
<style name="GlifV2Theme" parent="SuwThemeGlifV2">
- <!-- For all Alert Dialogs -->
- <item name="android:alertDialogTheme">@style/GlifV2ThemeAlertDialog</item>
+ <!-- For all AndroidX Alert Dialogs -->
+ <item name="alertDialogTheme">@style/GlifV2ThemeAlertDialog</item>
<item name="android:windowBackground">?android:attr/colorBackground</item>
<item name="*android:preferencePanelStyle">@*android:style/PreferencePanel.Dialog</item>
<item name="fingerprint_layout_theme">@style/FingerprintLayoutTheme</item>
@@ -75,8 +75,8 @@
</style>
<style name="GlifV2Theme.Light" parent="SuwThemeGlifV2.Light">
- <!-- For all Alert Dialogs -->
- <item name="android:alertDialogTheme">@style/GlifV2ThemeAlertDialog.Light</item>
+ <!-- For all AndroidX Alert Dialogs -->
+ <item name="alertDialogTheme">@style/GlifV2ThemeAlertDialog.Light</item>
<item name="android:windowBackground">?android:attr/colorBackground</item>
<item name="*android:preferencePanelStyle">@*android:style/PreferencePanel.Dialog</item>
<item name="fingerprint_layout_theme">@style/FingerprintLayoutTheme</item>
@@ -94,8 +94,8 @@
</style>
<style name="GlifV3Theme" parent="SuwThemeGlifV3">
- <!-- For all Alert Dialogs -->
- <item name="android:alertDialogTheme">@style/GlifV2ThemeAlertDialog</item>
+ <!-- For all AndroidX Alert Dialogs -->
+ <item name="alertDialogTheme">@style/GlifV2ThemeAlertDialog</item>
<item name="android:windowBackground">?android:attr/colorBackground</item>
<item name="*android:preferencePanelStyle">@*android:style/PreferencePanel.Dialog</item>
<item name="fingerprint_layout_theme">@style/FingerprintLayoutTheme</item>
@@ -113,8 +113,8 @@
</style>
<style name="GlifV3Theme.Light" parent="SuwThemeGlifV3.Light">
- <!-- For all Alert Dialogs -->
- <item name="android:alertDialogTheme">@style/GlifV2ThemeAlertDialog.Light</item>
+ <!-- For all AndroidX Alert Dialogs -->
+ <item name="alertDialogTheme">@style/GlifV2ThemeAlertDialog.Light</item>
<item name="android:windowBackground">?android:attr/colorBackground</item>
<item name="*android:preferencePanelStyle">@*android:style/PreferencePanel.Dialog</item>
<item name="fingerprint_layout_theme">@style/FingerprintLayoutTheme</item>
@@ -145,11 +145,11 @@
<item name="android:windowAnimationStyle">@null</item>
</style>
- <style name="GlifV2ThemeAlertDialog" parent="SuwAlertDialogTheme">
+ <style name="GlifV2ThemeAlertDialog" parent="SuwAlertDialogThemeCompat">
<item name="android:windowSoftInputMode">adjustResize</item>
</style>
- <style name="GlifV2ThemeAlertDialog.Light" parent="SuwAlertDialogTheme.Light">
+ <style name="GlifV2ThemeAlertDialog.Light" parent="SuwAlertDialogThemeCompat.Light">
<item name="android:windowSoftInputMode">adjustResize</item>
</style>
@@ -190,4 +190,16 @@
<item name="preferenceTheme">@style/PreferenceTheme</item>
<item name="switchBarTheme">@style/ThemeOverlay.SwitchBar.Settings</item>
</style>
+
+ <style name="SuwAlertDialogThemeCompat" parent="@style/Theme.AppCompat.Dialog.Alert">
+ <!-- copied from Theme.DeviceDefault.Light.Dialog.Alert -->
+ <item name="colorAccent">@*android:color/accent_device_default_light</item>
+ <item name="dialogCornerRadius">@*android:dimen/config_dialogCornerRadius</item>
+ </style>
+
+ <style name="SuwAlertDialogThemeCompat.Light" parent="@style/Theme.AppCompat.Light.Dialog.Alert">
+ <!-- copied from Theme.DeviceDefault.Light.Dialog.Alert -->
+ <item name="colorAccent">@*android:color/accent_device_default_light</item>
+ <item name="dialogCornerRadius">@*android:dimen/config_dialogCornerRadius</item>
+ </style>
</resources>
\ No newline at end of file
diff --git a/res/xml/accessibility_daltonizer_settings.xml b/res/xml/accessibility_daltonizer_settings.xml
index fc26fd3..9cd3865 100644
--- a/res/xml/accessibility_daltonizer_settings.xml
+++ b/res/xml/accessibility_daltonizer_settings.xml
@@ -24,6 +24,7 @@
android:entryValues="@array/daltonizer_type_values"
android:key="type"
android:summary="%s"
- android:title="@string/daltonizer_type" />
+ android:title="@string/daltonizer_type"
+ android:icon="@drawable/ic_accessibility_illustration_colorblind" />
</PreferenceScreen>
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index 9dda18f..e36f578 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -114,6 +114,11 @@
android:persistent="false"/>
<Preference
+ android:key="hearing_aid_preference"
+ android:summary="@string/accessibility_hearingaid_not_connected_summary"
+ android:title="@string/accessibility_hearingaid_title"/>
+
+ <Preference
android:fragment="com.android.settings.accessibility.CaptionPropertiesFragment"
android:key="captioning_preference_screen"
android:title="@string/accessibility_captioning_title" />
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 3d5f198..b0c7c9c 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -506,4 +506,29 @@
android:title="@string/reset_shortcut_manager_throttling" />
</PreferenceCategory>
+ <com.android.settings.development.autofill.AutofillPreferenceCategory
+ android:key="debug_autofill_category"
+ android:title="@string/debug_autofill_category"
+ android:order="1100">
+
+ <ListPreference
+ android:key="autofill_logging_level"
+ android:title="@string/autofill_logging_level_title"
+ android:entries="@array/autofill_logging_level_entries"
+ android:entryValues="@array/autofill_logging_level_values" />
+
+ <com.android.settings.development.autofill.AutofillMaxPartitionsPreference
+ android:key="autofill_max_partitions"
+ android:title="@string/autofill_max_partitions" />
+
+ <com.android.settings.development.autofill.AutofillVisibleDatasetsPreference
+ android:key="autofill_visible_datasets"
+ android:title="@string/autofill_max_visible_datasets" />
+
+ <Preference
+ android:key="autofill_reset_developer_options"
+ android:title="@string/autofill_reset_developer_options" />
+
+ </com.android.settings.development.autofill.AutofillPreferenceCategory>
+
</PreferenceScreen>
diff --git a/res/xml/my_device_info.xml b/res/xml/my_device_info.xml
index b70b613..22c1844 100644
--- a/res/xml/my_device_info.xml
+++ b/res/xml/my_device_info.xml
@@ -133,6 +133,14 @@
android:summary="@string/summary_placeholder"
android:selectable="false"/>
+ <!-- Device up time -->
+ <Preference
+ android:key="up_time"
+ android:order="37"
+ android:title="@string/status_up_time"
+ android:summary="@string/summary_placeholder"
+ android:selectable="false" />
+
<!-- Safety & regulatory manual -->
<Preference
android:key="safety_info"
diff --git a/res/xml/power_usage_summary.xml b/res/xml/power_usage_summary.xml
index 4ff67b7..b4db4ed 100644
--- a/res/xml/power_usage_summary.xml
+++ b/res/xml/power_usage_summary.xml
@@ -23,12 +23,16 @@
<com.android.settings.applications.LayoutPreference
android:key="battery_header"
+ android:title="@string/summary_placeholder"
android:selectable="false"
- android:layout="@layout/battery_header" />
+ android:layout="@layout/battery_header"
+ settings:controller="com.android.settings.fuelgauge.BatteryHeaderPreferenceController" />
<PreferenceCategory
android:key="battery_tip"
- android:layout="@layout/preference_category_no_label" />
+ android:title="@string/summary_placeholder"
+ android:layout="@layout/preference_category_no_label"
+ settings:controller="com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController" />
<Preference
android:fragment="com.android.settings.fuelgauge.batterysaver.BatterySaverSettings"
@@ -47,7 +51,8 @@
<SwitchPreference
android:key="battery_percentage"
android:title="@string/battery_percentage"
- android:summary="@string/battery_percentage_description" />
+ android:summary="@string/battery_percentage_description"
+ settings:controller="com.android.settings.display.BatteryPercentagePreferenceController" />
<com.android.settings.fuelgauge.PowerGaugePreference
diff --git a/src/com/android/settings/FallbackHome.java b/src/com/android/settings/FallbackHome.java
index 7d5948e..59347ad 100644
--- a/src/com/android/settings/FallbackHome.java
+++ b/src/com/android/settings/FallbackHome.java
@@ -19,6 +19,7 @@
import android.app.Activity;
import android.app.WallpaperColors;
import android.app.WallpaperManager;
+import android.app.WallpaperManager.OnColorsChangedListener;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -44,6 +45,7 @@
private static final int PROGRESS_TIMEOUT = 2000;
private boolean mProvisioned;
+ private WallpaperManager mWallManager;
private final Runnable mProgressTimeoutRunnable = () -> {
View v = getLayoutInflater().inflate(
@@ -59,6 +61,18 @@
getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON);
};
+ private final OnColorsChangedListener mColorsChangedListener = new OnColorsChangedListener() {
+ @Override
+ public void onColorsChanged(WallpaperColors colors, int which) {
+ if (colors != null) {
+ View decorView = getWindow().getDecorView();
+ decorView.setSystemUiVisibility(
+ updateVisibilityFlagsFromColors(colors, decorView.getSystemUiVisibility()));
+ mWallManager.removeOnColorsChangedListener(this);
+ }
+ }
+ };
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -78,13 +92,17 @@
}
// Set the system ui flags to light status bar if the wallpaper supports dark text to match
- // current system ui color tints.
- final WallpaperColors colors = getSystemService(WallpaperManager.class)
- .getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
- if (colors != null
- && (colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0) {
- flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
- | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+ // current system ui color tints. Use a listener to wait for colors if not ready yet.
+ mWallManager = getSystemService(WallpaperManager.class);
+ if (mWallManager == null) {
+ Log.w(TAG, "Wallpaper manager isn't ready, can't listen to color changes!");
+ } else {
+ WallpaperColors colors = mWallManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
+ if (colors == null) {
+ mWallManager.addOnColorsChangedListener(mColorsChangedListener, null /* handler */);
+ } else {
+ flags = updateVisibilityFlagsFromColors(colors, flags);
+ }
}
getWindow().getDecorView().setSystemUiVisibility(flags);
@@ -109,6 +127,9 @@
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
+ if (mWallManager != null) {
+ mWallManager.removeOnColorsChangedListener(mColorsChangedListener);
+ }
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -141,6 +162,15 @@
}
}
+ private int updateVisibilityFlagsFromColors(WallpaperColors colors, int flags) {
+ if ((colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0) {
+ return flags | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
+ | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+ }
+ return flags & ~(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)
+ & ~(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
+ }
+
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index cacd04e..f95a303 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -290,8 +290,10 @@
launchSettingFragment(initialFragmentName, isSubSettings, intent);
}
+ final boolean deviceProvisioned = Utils.isDeviceProvisioned(this);
if (mIsShowingDashboard) {
- findViewById(R.id.search_bar).setVisibility(View.VISIBLE);
+ findViewById(R.id.search_bar).setVisibility(
+ deviceProvisioned ? View.VISIBLE : View.INVISIBLE);
findViewById(R.id.action_bar).setVisibility(View.GONE);
final Toolbar toolbar = findViewById(R.id.search_action_bar);
FeatureFactory.getFactory(this).getSearchFeatureProvider()
@@ -310,7 +312,6 @@
ActionBar actionBar = getActionBar();
if (actionBar != null) {
- boolean deviceProvisioned = Utils.isDeviceProvisioned(this);
actionBar.setDisplayHomeAsUpEnabled(deviceProvisioned);
actionBar.setHomeButtonEnabled(deviceProvisioned);
actionBar.setDisplayShowTitleEnabled(!mIsShowingDashboard);
diff --git a/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java b/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java
new file mode 100644
index 0000000..b946e3e
--- /dev/null
+++ b/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java
@@ -0,0 +1,217 @@
+/*
+ * 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 android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHearingAid;
+import android.bluetooth.BluetoothProfile;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.fragment.app.FragmentManager;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.bluetooth.BluetoothDeviceDetailsFragment;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnPause;
+import com.android.settingslib.core.lifecycle.events.OnResume;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+
+/**
+ * Controller that shows and updates the bluetooth device name
+ */
+public class AccessibilityHearingAidPreferenceController extends BasePreferenceController
+ implements LifecycleObserver, OnResume, OnPause {
+ private static final String TAG = "AccessibilityHearingAidPreferenceController";
+ private Preference mHearingAidPreference;
+
+ private final BroadcastReceiver mHearingAidChangedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) {
+ final int state = intent.getIntExtra(BluetoothHearingAid.EXTRA_STATE,
+ BluetoothHearingAid.STATE_DISCONNECTED);
+ if (state == BluetoothHearingAid.STATE_CONNECTED) {
+ updateState(mHearingAidPreference);
+ } else {
+ mHearingAidPreference
+ .setSummary(R.string.accessibility_hearingaid_not_connected_summary);
+ }
+ } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
+ final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+ BluetoothAdapter.ERROR);
+ if (state != BluetoothAdapter.STATE_ON) {
+ mHearingAidPreference
+ .setSummary(R.string.accessibility_hearingaid_not_connected_summary);
+ }
+ }
+ }
+ };
+
+ private final LocalBluetoothManager mLocalBluetoothManager;
+ //cache value of supporting hearing aid or not
+ private boolean mHearingAidProfileSupported;
+ private FragmentManager mFragmentManager;
+
+ public AccessibilityHearingAidPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ mLocalBluetoothManager = getLocalBluetoothManager();
+ mHearingAidProfileSupported = isHearingAidProfileSupported();
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mHearingAidPreference = screen.findPreference(getPreferenceKey());
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return mHearingAidProfileSupported ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ }
+
+ @Override
+ public void onResume() {
+ if (mHearingAidProfileSupported) {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
+ filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+ mContext.registerReceiver(mHearingAidChangedReceiver, filter);
+ }
+ }
+
+ @Override
+ public void onPause() {
+ if (mHearingAidProfileSupported) {
+ mContext.unregisterReceiver(mHearingAidChangedReceiver);
+ }
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ if (TextUtils.equals(preference.getKey(), getPreferenceKey())){
+ final CachedBluetoothDevice device = getConnectedHearingAidDevice();
+ if (device == null) {
+ launchHearingAidInstructionDialog();
+ } else {
+ launchBluetoothDeviceDetailSetting(device);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public CharSequence getSummary() {
+ final CachedBluetoothDevice device = getConnectedHearingAidDevice();
+ if (device == null) {
+ return mContext.getText(R.string.accessibility_hearingaid_not_connected_summary);
+ }
+ return device.getName();
+ }
+
+ public void setFragmentManager(FragmentManager fragmentManager) {
+ mFragmentManager = fragmentManager;
+ }
+
+ private CachedBluetoothDevice getConnectedHearingAidDevice() {
+ if (!mHearingAidProfileSupported) {
+ return null;
+ }
+ final LocalBluetoothAdapter localAdapter = mLocalBluetoothManager.getBluetoothAdapter();
+ if (!localAdapter.isEnabled()) {
+ return null;
+ }
+ final List<BluetoothDevice> deviceList = mLocalBluetoothManager.getProfileManager()
+ .getHearingAidProfile().getConnectedDevices();
+ final Iterator it = deviceList.iterator();
+ if (it.hasNext()) {
+ BluetoothDevice obj = (BluetoothDevice)it.next();
+ return mLocalBluetoothManager.getCachedDeviceManager().findDevice(obj);
+ }
+ return null;
+ }
+
+ private boolean isHearingAidProfileSupported() {
+ final LocalBluetoothAdapter localAdapter = mLocalBluetoothManager.getBluetoothAdapter();
+ final List<Integer> supportedList = localAdapter.getSupportedProfiles();
+ if (supportedList.contains(BluetoothProfile.HEARING_AID)) {
+ return true;
+ }
+ return false;
+ }
+
+ private LocalBluetoothManager getLocalBluetoothManager() {
+ final FutureTask<LocalBluetoothManager> localBtManagerFutureTask = new FutureTask<>(
+ // Avoid StrictMode ThreadPolicy violation
+ () -> com.android.settings.bluetooth.Utils.getLocalBtManager(mContext));
+ try {
+ localBtManagerFutureTask.run();
+ return localBtManagerFutureTask.get();
+ } catch (InterruptedException | ExecutionException e) {
+ Log.w(TAG, "Error getting LocalBluetoothManager.", e);
+ return null;
+ }
+ }
+
+ @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+ void setPreference(Preference preference) {
+ mHearingAidPreference = preference;
+ }
+
+ @VisibleForTesting
+ void launchBluetoothDeviceDetailSetting(final CachedBluetoothDevice device) {
+ if (device == null) {
+ return;
+ }
+ final Bundle args = new Bundle();
+ args.putString(BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS,
+ device.getDevice().getAddress());
+
+ new SubSettingLauncher(mContext)
+ .setDestination(BluetoothDeviceDetailsFragment.class.getName())
+ .setArguments(args)
+ .setTitleRes(R.string.device_details_title)
+ .setSourceMetricsCategory(MetricsProto.MetricsEvent.ACCESSIBILITY)
+ .launch();
+ }
+
+ @VisibleForTesting
+ void launchHearingAidInstructionDialog() {
+ HearingAidDialogFragment fragment = HearingAidDialogFragment.newInstance();
+ fragment.show(mFragmentManager, HearingAidDialogFragment.class.toString());
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index 22cff3e..d1b1ad4 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -110,6 +110,8 @@
"select_long_press_timeout_preference";
private static final String ACCESSIBILITY_SHORTCUT_PREFERENCE =
"accessibility_shortcut_preference";
+ private static final String HEARING_AID_PREFERENCE =
+ "hearing_aid_preference";
private static final String CAPTIONING_PREFERENCE_SCREEN =
"captioning_preference_screen";
private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN =
@@ -221,9 +223,11 @@
private Preference mAutoclickPreferenceScreen;
private Preference mAccessibilityShortcutPreferenceScreen;
private Preference mDisplayDaltonizerPreferenceScreen;
+ private Preference mHearingAidPreference;
private Preference mVibrationPreferenceScreen;
private SwitchPreference mToggleInversionPreference;
private ColorInversionPreferenceController mInversionPreferenceController;
+ private AccessibilityHearingAidPreferenceController mHearingAidPreferenceController;
private int mLongPressTimeoutDefault;
@@ -276,6 +280,15 @@
}
@Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ mHearingAidPreferenceController = new AccessibilityHearingAidPreferenceController
+ (context, HEARING_AID_PREFERENCE);
+ mHearingAidPreferenceController.setFragmentManager(getFragmentManager());
+ getLifecycle().addObserver(mHearingAidPreferenceController);
+ }
+
+ @Override
public void onResume() {
super.onResume();
updateAllPreferences();
@@ -335,6 +348,8 @@
} else if (mToggleMasterMonoPreference == preference) {
handleToggleMasterMonoPreferenceClick();
return true;
+ } else if (mHearingAidPreferenceController.handlePreferenceTreeClick(preference)) {
+ return true;
}
return super.onPreferenceTreeClick(preference);
}
@@ -452,6 +467,10 @@
}
}
+ // Hearing Aid.
+ mHearingAidPreference = findPreference(HEARING_AID_PREFERENCE);
+ mHearingAidPreferenceController.displayPreference(getPreferenceScreen());
+
// Captioning.
mCaptioningPreferenceScreen = findPreference(CAPTIONING_PREFERENCE_SCREEN);
@@ -686,6 +705,8 @@
updateVibrationSummary(mVibrationPreferenceScreen);
+ mHearingAidPreferenceController.updateState(mHearingAidPreference);
+
updateFeatureSummary(Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED,
mCaptioningPreferenceScreen);
updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
diff --git a/src/com/android/settings/accessibility/HearingAidDialogFragment.java b/src/com/android/settings/accessibility/HearingAidDialogFragment.java
new file mode 100644
index 0000000..0380ed3
--- /dev/null
+++ b/src/com/android/settings/accessibility/HearingAidDialogFragment.java
@@ -0,0 +1,65 @@
+/*
+ * 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 android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.bluetooth.BluetoothPairingDetail;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+public class HearingAidDialogFragment extends InstrumentedDialogFragment {
+ public static HearingAidDialogFragment newInstance() {
+ HearingAidDialogFragment frag = new HearingAidDialogFragment();
+ return frag;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.accessibility_hearingaid_pair_instructions_first_message)
+ .setMessage(R.string.accessibility_hearingaid_pair_instructions_second_message)
+ .setPositiveButton(R.string.accessibility_hearingaid_instruction_continue_button,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ launchBluetoothAddDeviceSetting();
+ }
+ })
+ .setNegativeButton(android.R.string.cancel,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) { }
+ })
+ .create();
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.DIALOG_ACCESSIBILITY_HEARINGAID;
+ }
+
+ private void launchBluetoothAddDeviceSetting() {
+ new SubSettingLauncher(getActivity())
+ .setDestination(BluetoothPairingDetail.class.getName())
+ .setSourceMetricsCategory(MetricsProto.MetricsEvent.ACCESSIBILITY)
+ .launch();
+ }
+}
diff --git a/src/com/android/settings/accounts/AccountPreferenceController.java b/src/com/android/settings/accounts/AccountPreferenceController.java
index 904dea3..46a3e6b 100644
--- a/src/com/android/settings/accounts/AccountPreferenceController.java
+++ b/src/com/android/settings/accounts/AccountPreferenceController.java
@@ -192,12 +192,10 @@
data.screenTitle = screenTitle;
rawData.add(data);
}
- {
- SearchIndexableRaw data = new SearchIndexableRaw(mContext);
- data.title = res.getString(R.string.managed_profile_settings_title);
- data.screenTitle = screenTitle;
- rawData.add(data);
- }
+ SearchIndexableRaw data = new SearchIndexableRaw(mContext);
+ data.title = res.getString(R.string.managed_profile_settings_title);
+ data.screenTitle = screenTitle;
+ rawData.add(data);
}
}
}
@@ -300,6 +298,7 @@
final ProfileData data = mProfiles.get(userInfo.id);
if (data != null) {
data.pendingRemoval = false;
+ data.userInfo = userInfo;
if (userInfo.isEnabled()) {
// recreate the authentication helper to refresh the list of enabled accounts
data.authenticatorHelper =
diff --git a/src/com/android/settings/bluetooth/AlwaysDiscoverable.java b/src/com/android/settings/bluetooth/AlwaysDiscoverable.java
index b89706d..7b94871 100644
--- a/src/com/android/settings/bluetooth/AlwaysDiscoverable.java
+++ b/src/com/android/settings/bluetooth/AlwaysDiscoverable.java
@@ -22,8 +22,6 @@
import android.content.Intent;
import android.content.IntentFilter;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
-
import androidx.annotation.VisibleForTesting;
/** Helper class, intended to be used by an Activity, to keep the local Bluetooth adapter in
@@ -35,15 +33,15 @@
private static final String TAG = "AlwaysDiscoverable";
private Context mContext;
- private LocalBluetoothAdapter mLocalAdapter;
+ private BluetoothAdapter mBluetoothAdapter;
private IntentFilter mIntentFilter;
@VisibleForTesting
boolean mStarted;
- public AlwaysDiscoverable(Context context, LocalBluetoothAdapter localAdapter) {
+ public AlwaysDiscoverable(Context context) {
mContext = context;
- mLocalAdapter = localAdapter;
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
}
@@ -56,8 +54,9 @@
}
mContext.registerReceiver(this, mIntentFilter);
mStarted = true;
- if (mLocalAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
- mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+ if (mBluetoothAdapter.getScanMode()
+ != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
+ mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
}
}
@@ -67,7 +66,7 @@
}
mContext.unregisterReceiver(this);
mStarted = false;
- mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
+ mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
}
@Override
@@ -76,8 +75,9 @@
if (action != BluetoothAdapter.ACTION_SCAN_MODE_CHANGED) {
return;
}
- if (mLocalAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
- mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+ if (mBluetoothAdapter.getScanMode()
+ != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
+ mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
}
}
}
diff --git a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
index 44ef4be..2b9c2cb 100644
--- a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
@@ -60,25 +60,6 @@
}
@Override
- public void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state,
- int bluetoothProfile) {
- if (DBG) {
- Log.d(TAG, "onProfileConnectionStateChanged() device: " +
- cachedDevice.getName() + ", state: " + state + ", bluetoothProfile: "
- + bluetoothProfile);
- }
- if (state == BluetoothProfile.STATE_CONNECTED) {
- if (isFilterMatched(cachedDevice)) {
- addPreference(cachedDevice);
- } else {
- removePreference(cachedDevice);
- }
- } else if (state == BluetoothProfile.STATE_DISCONNECTED) {
- removePreference(cachedDevice);
- }
- }
-
- @Override
public boolean isFilterMatched(CachedBluetoothDevice cachedDevice) {
final int audioMode = mAudioManager.getMode();
final int currentAudioProfile;
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java b/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
index 5b65335..b9154f5 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
@@ -27,8 +27,6 @@
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -46,8 +44,7 @@
@VisibleForTesting
Preference mPreference;
- private LocalBluetoothManager mLocalManager;
- protected LocalBluetoothAdapter mLocalAdapter;
+ protected BluetoothAdapter mBluetoothAdapter;
/**
* Constructor exclusively used for Slice.
@@ -55,19 +52,11 @@
public BluetoothDeviceNamePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
- mLocalManager = Utils.getLocalBtManager(context);
- if (mLocalManager == null) {
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ if (mBluetoothAdapter == null) {
Log.e(TAG, "Bluetooth is not supported on this device");
return;
}
- mLocalAdapter = mLocalManager.getBluetoothAdapter();
- }
-
- @VisibleForTesting
- BluetoothDeviceNamePreferenceController(Context context, LocalBluetoothAdapter localAdapter,
- String preferenceKey) {
- super(context, preferenceKey);
- mLocalAdapter = localAdapter;
}
@Override
@@ -91,7 +80,7 @@
@Override
public int getAvailabilityStatus() {
- return mLocalAdapter != null ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ return mBluetoothAdapter != null ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
@@ -138,7 +127,7 @@
}
protected String getDeviceName() {
- return mLocalAdapter.getName();
+ return mBluetoothAdapter.getName();
}
/**
@@ -152,7 +141,8 @@
final String action = intent.getAction();
if (TextUtils.equals(action, BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED)) {
- if (mPreference != null && mLocalAdapter != null && mLocalAdapter.isEnabled()) {
+ if (mPreference != null && mBluetoothAdapter != null
+ && mBluetoothAdapter.isEnabled()) {
updatePreferenceState(mPreference);
}
} else if (TextUtils.equals(action, BluetoothAdapter.ACTION_STATE_CHANGED)) {
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java b/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java
index 0fb2f87..24fcf6a 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java
@@ -16,12 +16,12 @@
package com.android.settings.bluetooth;
+import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.text.TextUtils;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import androidx.annotation.VisibleForTesting;
@@ -42,13 +42,6 @@
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
}
- @VisibleForTesting
- BluetoothDeviceRenamePreferenceController(Context context, LocalBluetoothAdapter localAdapter,
- String preferenceKey) {
- super(context, localAdapter, preferenceKey);
- mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
- }
-
/**
* Set the {@link Fragment} that used to show {@link LocalDeviceNameDialogFragment}
* in {@code handlePreferenceTreeClick}
@@ -61,7 +54,7 @@
@Override
protected void updatePreferenceState(final Preference preference) {
preference.setSummary(getSummary());
- preference.setVisible(mLocalAdapter != null && mLocalAdapter.isEnabled());
+ preference.setVisible(mBluetoothAdapter != null && mBluetoothAdapter.isEnabled());
}
@Override
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
index 0c0c5ea..dece0cc 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
@@ -162,6 +162,11 @@
@Override
public void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state,
int bluetoothProfile) {
+ if (DBG) {
+ Log.d(TAG, "onProfileConnectionStateChanged() device: " + cachedDevice.getName()
+ + ", state: " + state + ", bluetoothProfile: " + bluetoothProfile);
+ }
+ update(cachedDevice);
}
@Override
diff --git a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
index 3db3005..aec6d2d 100755
--- a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
+++ b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
@@ -28,7 +28,6 @@
import com.android.settings.R;
import com.android.settingslib.bluetooth.BluetoothDiscoverableTimeoutReceiver;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
import androidx.preference.Preference;
@@ -64,7 +63,7 @@
private final Handler mUiHandler;
private final Preference mDiscoveryPreference;
- private final LocalBluetoothAdapter mLocalAdapter;
+ private final BluetoothAdapter mBluetoothAdapter;
private final SharedPreferences mSharedPreferences;
@@ -92,17 +91,16 @@
}
};
- BluetoothDiscoverableEnabler(LocalBluetoothAdapter adapter,
- Preference discoveryPreference) {
+ BluetoothDiscoverableEnabler(Preference discoveryPreference) {
mUiHandler = new Handler();
- mLocalAdapter = adapter;
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mDiscoveryPreference = discoveryPreference;
mSharedPreferences = discoveryPreference.getSharedPreferences();
discoveryPreference.setPersistent(false);
}
public void resume(Context context) {
- if (mLocalAdapter == null) {
+ if (mBluetoothAdapter == null) {
return;
}
@@ -113,11 +111,11 @@
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
mContext.registerReceiver(mReceiver, filter);
mDiscoveryPreference.setOnPreferenceClickListener(this);
- handleModeChanged(mLocalAdapter.getScanMode());
+ handleModeChanged(mBluetoothAdapter.getScanMode());
}
public void pause() {
- if (mLocalAdapter == null) {
+ if (mBluetoothAdapter == null) {
return;
}
@@ -139,7 +137,8 @@
long endTimestamp = System.currentTimeMillis() + timeout * 1000L;
LocalBluetoothPreferences.persistDiscoverableEndTimestamp(mContext, endTimestamp);
- mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, timeout);
+ mBluetoothAdapter
+ .setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, timeout);
updateCountdownSummary();
Log.d(TAG, "setEnabled(): enabled = " + enable + "timeout = " + timeout);
@@ -151,7 +150,7 @@
}
} else {
- mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
+ mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
BluetoothDiscoverableTimeoutReceiver.cancelDiscoverableAlarm(mContext);
}
}
@@ -250,7 +249,7 @@
void setNumberOfPairedDevices(int pairedDevices) {
mNumberOfPairedDevices = pairedDevices;
- handleModeChanged(mLocalAdapter.getScanMode());
+ handleModeChanged(mBluetoothAdapter.getScanMode());
}
void handleModeChanged(int mode) {
@@ -273,7 +272,7 @@
}
private void updateCountdownSummary() {
- int mode = mLocalAdapter.getScanMode();
+ int mode = mBluetoothAdapter.getScanMode();
if (mode != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
return;
}
diff --git a/src/com/android/settings/bluetooth/BluetoothEnabler.java b/src/com/android/settings/bluetooth/BluetoothEnabler.java
index 98a4b9c..9c00a50 100644
--- a/src/com/android/settings/bluetooth/BluetoothEnabler.java
+++ b/src/com/android/settings/bluetooth/BluetoothEnabler.java
@@ -29,8 +29,6 @@
import com.android.settings.widget.SwitchWidgetController;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.WirelessUtils;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import androidx.annotation.VisibleForTesting;
@@ -45,7 +43,7 @@
private final MetricsFeatureProvider mMetricsFeatureProvider;
private Context mContext;
private boolean mValidListener;
- private final LocalBluetoothAdapter mLocalAdapter;
+ private final BluetoothAdapter mBluetoothAdapter;
private final IntentFilter mIntentFilter;
private final RestrictionUtils mRestrictionUtils;
private SwitchWidgetController.OnSwitchChangeListener mCallback;
@@ -65,15 +63,14 @@
};
public BluetoothEnabler(Context context, SwitchWidgetController switchController,
- MetricsFeatureProvider metricsFeatureProvider, LocalBluetoothManager manager,
- int metricsEvent) {
- this(context, switchController, metricsFeatureProvider, manager, metricsEvent,
+ MetricsFeatureProvider metricsFeatureProvider, int metricsEvent) {
+ this(context, switchController, metricsFeatureProvider, metricsEvent,
new RestrictionUtils());
}
public BluetoothEnabler(Context context, SwitchWidgetController switchController,
- MetricsFeatureProvider metricsFeatureProvider, LocalBluetoothManager manager,
- int metricsEvent, RestrictionUtils restrictionUtils) {
+ MetricsFeatureProvider metricsFeatureProvider, int metricsEvent,
+ RestrictionUtils restrictionUtils) {
mContext = context;
mMetricsFeatureProvider = metricsFeatureProvider;
mSwitchController = switchController;
@@ -81,12 +78,10 @@
mValidListener = false;
mMetricsEvent = metricsEvent;
- if (manager == null) {
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ if (mBluetoothAdapter == null) {
// Bluetooth is not supported
- mLocalAdapter = null;
mSwitchController.setEnabled(false);
- } else {
- mLocalAdapter = manager.getBluetoothAdapter();
}
mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
mRestrictionUtils = restrictionUtils;
@@ -107,14 +102,14 @@
final boolean restricted = maybeEnforceRestrictions();
- if (mLocalAdapter == null) {
+ if (mBluetoothAdapter == null) {
mSwitchController.setEnabled(false);
return;
}
// Bluetooth state is not sticky, so set it manually
if (!restricted) {
- handleStateChanged(mLocalAdapter.getBluetoothState());
+ handleStateChanged(mBluetoothAdapter.getState());
}
mSwitchController.startListening();
@@ -123,7 +118,7 @@
}
public void pause() {
- if (mLocalAdapter == null) {
+ if (mBluetoothAdapter == null) {
return;
}
if (mValidListener) {
@@ -188,8 +183,8 @@
mMetricsFeatureProvider.action(mContext, mMetricsEvent, isChecked);
- if (mLocalAdapter != null) {
- boolean status = mLocalAdapter.setBluetoothEnabled(isChecked);
+ if (mBluetoothAdapter != null) {
+ boolean status = setBluetoothEnabled(isChecked);
// If we cannot toggle it ON then reset the UI assets:
// a) The switch should be OFF but it should still be togglable (enabled = True)
// b) The switch bar should have OFF text.
@@ -249,4 +244,8 @@
mCallback.onSwitchToggled(isChecked);
}
}
+
+ private boolean setBluetoothEnabled(boolean isEnabled) {
+ return isEnabled ? mBluetoothAdapter.enable() : mBluetoothAdapter.disable();
+ }
}
diff --git a/src/com/android/settings/bluetooth/BluetoothFeatureProvider.java b/src/com/android/settings/bluetooth/BluetoothFeatureProvider.java
deleted file mode 100644
index a6ae31c..0000000
--- a/src/com/android/settings/bluetooth/BluetoothFeatureProvider.java
+++ /dev/null
@@ -1,32 +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.bluetooth;
-
-/**
- * Feature provider for bluetooth feature
- */
-public interface BluetoothFeatureProvider {
- /**
- * @return whether additional pairing page is enabled
- */
- boolean isPairingPageEnabled();
-
- /**
- * @return whether device details should be shown as a separate page (true) or a dialog (false)
- */
- boolean isDeviceDetailPageEnabled();
-}
diff --git a/src/com/android/settings/bluetooth/BluetoothFeatureProviderImpl.java b/src/com/android/settings/bluetooth/BluetoothFeatureProviderImpl.java
deleted file mode 100644
index c4962d6..0000000
--- a/src/com/android/settings/bluetooth/BluetoothFeatureProviderImpl.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.android.settings.bluetooth;
-
-/**
- * Impl for bluetooth feature provider
- */
-public class BluetoothFeatureProviderImpl implements BluetoothFeatureProvider {
-
- @Override
- public boolean isPairingPageEnabled() {
- return false;
- }
-
- @Override
- public boolean isDeviceDetailPageEnabled() {
- return false;
- }
-}
\ No newline at end of file
diff --git a/src/com/android/settings/bluetooth/BluetoothPairingDetail.java b/src/com/android/settings/bluetooth/BluetoothPairingDetail.java
index af2711c..905327d 100644
--- a/src/com/android/settings/bluetooth/BluetoothPairingDetail.java
+++ b/src/com/android/settings/bluetooth/BluetoothPairingDetail.java
@@ -63,7 +63,7 @@
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mInitialScanStarted = false;
- mAlwaysDiscoverable = new AlwaysDiscoverable(getContext(), mLocalAdapter);
+ mAlwaysDiscoverable = new AlwaysDiscoverable(getContext());
}
@Override
@@ -74,7 +74,7 @@
return;
}
updateBluetooth();
- mAvailableDevicesCategory.setProgress(mLocalAdapter.isDiscovering());
+ mAvailableDevicesCategory.setProgress(mBluetoothAdapter.isDiscovering());
}
@Override
@@ -85,11 +85,11 @@
@VisibleForTesting
void updateBluetooth() {
- if (mLocalAdapter.isEnabled()) {
- updateContent(mLocalAdapter.getBluetoothState());
+ if (mBluetoothAdapter.isEnabled()) {
+ updateContent(mBluetoothAdapter.getState());
} else {
// Turn on bluetooth if it is disabled
- mLocalAdapter.enable();
+ mBluetoothAdapter.enable();
}
}
@@ -148,7 +148,7 @@
switch (bluetoothState) {
case BluetoothAdapter.STATE_ON:
mDevicePreferenceMap.clear();
- mLocalAdapter.setBluetoothEnabled(true);
+ mBluetoothAdapter.enable();
addDeviceCategory(mAvailableDevicesCategory,
R.string.bluetooth_preference_found_media_devices,
diff --git a/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java b/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java
index 7d5ae2b..7a56994 100644
--- a/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java
+++ b/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java
@@ -33,8 +33,6 @@
import com.android.settings.connecteddevice.BluetoothDashboardFragment;
import com.android.settings.slices.SliceBroadcastReceiver;
import com.android.settings.slices.SliceBuilderUtils;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
@@ -119,10 +117,13 @@
*/
public static void handleUriChange(Context context, Intent intent) {
final boolean newBluetoothState = intent.getBooleanExtra(EXTRA_TOGGLE_STATE, false);
- final LocalBluetoothAdapter adapter = LocalBluetoothManager.getInstance(context,
- null /* callback */).getBluetoothAdapter();
+ final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
- adapter.setBluetoothEnabled(newBluetoothState);
+ if (newBluetoothState) {
+ adapter.enable();
+ } else {
+ adapter.disable();
+ }
// Do not notifyChange on Uri. The service takes longer to update the current value than it
// does for the Slice to check the current value again. Let {@link SliceBroadcastRelay}
// handle it.
diff --git a/src/com/android/settings/bluetooth/BluetoothSummaryUpdater.java b/src/com/android/settings/bluetooth/BluetoothSummaryUpdater.java
index 08aee5f..03fffa4 100644
--- a/src/com/android/settings/bluetooth/BluetoothSummaryUpdater.java
+++ b/src/com/android/settings/bluetooth/BluetoothSummaryUpdater.java
@@ -25,7 +25,6 @@
import com.android.settings.widget.SummaryUpdater;
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import java.util.Set;
@@ -39,15 +38,14 @@
public final class BluetoothSummaryUpdater extends SummaryUpdater implements BluetoothCallback {
private static final String TAG = "BluetoothSummaryUpdater";
+ private final BluetoothAdapter mBluetoothAdapter;
private final LocalBluetoothManager mBluetoothManager;
- private final LocalBluetoothAdapter mBluetoothAdapter;
public BluetoothSummaryUpdater(Context context, OnSummaryChangeListener listener,
LocalBluetoothManager bluetoothManager) {
super(context, listener);
mBluetoothManager = bluetoothManager;
- mBluetoothAdapter = mBluetoothManager != null
- ? mBluetoothManager.getBluetoothAdapter() : null;
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
}
@Override
diff --git a/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java b/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java
index c6658e1..d828302 100644
--- a/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java
@@ -26,8 +26,6 @@
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.utils.AnnotationSpan;
import com.android.settings.widget.SwitchWidgetController;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -43,10 +41,6 @@
implements LifecycleObserver, OnStart, OnStop,
SwitchWidgetController.OnSwitchChangeListener, View.OnClickListener {
- @VisibleForTesting
- LocalBluetoothAdapter mBluetoothAdapter;
-
- private LocalBluetoothManager mBluetoothManager;
private BluetoothEnabler mBluetoothEnabler;
private RestrictionUtils mRestrictionUtils;
private SwitchWidgetController mSwitch;
@@ -56,15 +50,12 @@
public BluetoothSwitchPreferenceController(Context context,
SwitchWidgetController switchController,
FooterPreference footerPreference) {
- this(context, Utils.getLocalBtManager(context), new RestrictionUtils(), switchController,
- footerPreference);
+ this(context, new RestrictionUtils(), switchController, footerPreference);
}
@VisibleForTesting
- public BluetoothSwitchPreferenceController(Context context,
- LocalBluetoothManager bluetoothManager, RestrictionUtils restrictionUtils,
+ public BluetoothSwitchPreferenceController(Context context, RestrictionUtils restrictionUtils,
SwitchWidgetController switchController, FooterPreference footerPreference) {
- mBluetoothManager = bluetoothManager;
mRestrictionUtils = restrictionUtils;
mSwitch = switchController;
mContext = context;
@@ -73,12 +64,9 @@
mSwitch.setupView();
updateText(mSwitch.isChecked());
- if (mBluetoothManager != null) {
- mBluetoothAdapter = mBluetoothManager.getBluetoothAdapter();
- }
mBluetoothEnabler = new BluetoothEnabler(context,
switchController,
- FeatureFactory.getFactory(context).getMetricsFeatureProvider(), mBluetoothManager,
+ FeatureFactory.getFactory(context).getMetricsFeatureProvider(),
MetricsEvent.ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE,
mRestrictionUtils);
mBluetoothEnabler.setToggleCallback(this);
diff --git a/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
index 500fb06..259a403 100644
--- a/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
@@ -60,25 +60,6 @@
}
@Override
- public void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state,
- int bluetoothProfile) {
- if (DBG) {
- Log.d(TAG, "onProfileConnectionStateChanged() device: " +
- cachedDevice.getName() + ", state: " + state + ", bluetoothProfile: "
- + bluetoothProfile);
- }
- if (state == BluetoothProfile.STATE_CONNECTED) {
- if (isFilterMatched(cachedDevice)) {
- addPreference(cachedDevice);
- } else {
- removePreference(cachedDevice);
- }
- } else if (state == BluetoothProfile.STATE_DISCONNECTED) {
- removePreference(cachedDevice);
- }
- }
-
- @Override
public boolean isFilterMatched(CachedBluetoothDevice cachedDevice) {
final int audioMode = mAudioManager.getMode();
final int currentAudioProfile;
diff --git a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
index 7c7e271..7c4224e 100644
--- a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
+++ b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
@@ -28,7 +28,6 @@
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.BluetoothDeviceFilter;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import java.util.Collection;
@@ -64,7 +63,7 @@
BluetoothDevice mSelectedDevice;
- LocalBluetoothAdapter mLocalAdapter;
+ BluetoothAdapter mBluetoothAdapter;
LocalBluetoothManager mLocalManager;
@VisibleForTesting
@@ -97,7 +96,7 @@
Log.e(TAG, "Bluetooth is not supported on this device");
return;
}
- mLocalAdapter = mLocalManager.getBluetoothAdapter();
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mShowDevicesWithoutNames = SystemProperties.getBoolean(
BLUETOOTH_SHOW_DEVICES_WITHOUT_NAMES_PROPERTY, false);
@@ -146,7 +145,7 @@
@Override
public boolean onPreferenceTreeClick(Preference preference) {
if (KEY_BT_SCAN.equals(preference.getKey())) {
- mLocalAdapter.startScanning(true);
+ startScanning();
return true;
}
@@ -172,7 +171,7 @@
}
// Prevent updates while the list shows one of the state messages
- if (mLocalAdapter.getBluetoothState() != BluetoothAdapter.STATE_ON) return;
+ if (mBluetoothAdapter.getState() != BluetoothAdapter.STATE_ON) return;
if (mFilter.matches(cachedDevice.getDevice())) {
createDevicePreference(cachedDevice);
@@ -214,7 +213,7 @@
myDevicePreference.setTitle(getString(
R.string.bluetooth_footer_mac_message,
- bidiFormatter.unicodeWrap(mLocalAdapter.getAddress())));
+ bidiFormatter.unicodeWrap(mBluetoothAdapter.getAddress())));
}
@Override
@@ -227,21 +226,21 @@
@VisibleForTesting
void enableScanning() {
- // LocalBluetoothAdapter already handles repeated scan requests
- mLocalAdapter.startScanning(true);
+ // BluetoothAdapter already handles repeated scan requests
+ startScanning();
mScanEnabled = true;
}
@VisibleForTesting
void disableScanning() {
- mLocalAdapter.stopScanning();
+ stopScanning();
mScanEnabled = false;
}
@Override
public void onScanningStateChanged(boolean started) {
if (!started && mScanEnabled) {
- mLocalAdapter.startScanning(true);
+ startScanning();
}
}
@@ -287,4 +286,16 @@
public boolean shouldShowDevicesWithoutNames() {
return mShowDevicesWithoutNames;
}
+
+ void startScanning() {
+ if (!mBluetoothAdapter.isDiscovering()) {
+ mBluetoothAdapter.startDiscovery();
+ }
+ }
+
+ void stopScanning() {
+ if (mBluetoothAdapter.isDiscovering()) {
+ mBluetoothAdapter.cancelDiscovery();
+ }
+ }
}
diff --git a/src/com/android/settings/bluetooth/DevicePickerActivity.java b/src/com/android/settings/bluetooth/DevicePickerActivity.java
index 43ba05d..5228cd8 100644
--- a/src/com/android/settings/bluetooth/DevicePickerActivity.java
+++ b/src/com/android/settings/bluetooth/DevicePickerActivity.java
@@ -16,16 +16,17 @@
package com.android.settings.bluetooth;
-import android.app.Activity;
import android.os.Bundle;
import com.android.settings.R;
+import androidx.fragment.app.FragmentActivity;
+
/**
* Activity for Bluetooth device picker dialog. The device picker logic
* is implemented in the {@link BluetoothPairingDetail} fragment.
*/
-public final class DevicePickerActivity extends Activity {
+public final class DevicePickerActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
diff --git a/src/com/android/settings/bluetooth/DevicePickerFragment.java b/src/com/android/settings/bluetooth/DevicePickerFragment.java
index 5d404d7..097fba7 100644
--- a/src/com/android/settings/bluetooth/DevicePickerFragment.java
+++ b/src/com/android/settings/bluetooth/DevicePickerFragment.java
@@ -94,7 +94,7 @@
mSelectedDevice = null;
if (mScanAllowed) {
enableScanning();
- mAvailableDevicesCategory.setProgress(mLocalAdapter.isDiscovering());
+ mAvailableDevicesCategory.setProgress(mBluetoothAdapter.isDiscovering());
}
}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothPreferences.java b/src/com/android/settings/bluetooth/LocalBluetoothPreferences.java
index 2a65901..faed1c3 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothPreferences.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothPreferences.java
@@ -16,13 +16,13 @@
package com.android.settings.bluetooth;
+import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.text.TextUtils;
import android.util.Log;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
/**
@@ -89,7 +89,7 @@
}
// If the device was discoverING recently
- LocalBluetoothAdapter adapter = manager.getBluetoothAdapter();
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
if (adapter.isDiscovering()) {
return true;
diff --git a/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragment.java b/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragment.java
index 029b974..4cbcce8 100644
--- a/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragment.java
+++ b/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragment.java
@@ -25,13 +25,11 @@
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
/** Provides a dialog for changing the advertised name of the local bluetooth adapter. */
public class LocalDeviceNameDialogFragment extends BluetoothNameDialogFragment {
public static final String TAG = "LocalAdapterName";
- private LocalBluetoothAdapter mLocalAdapter;
+ private BluetoothAdapter mBluetoothAdapter;
public static LocalDeviceNameDialogFragment newInstance() {
return new LocalDeviceNameDialogFragment();
@@ -53,8 +51,7 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- LocalBluetoothManager localManager = Utils.getLocalBtManager(getActivity());
- mLocalAdapter = localManager.getBluetoothAdapter();
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
}
@Override
@@ -84,14 +81,14 @@
@Override
protected String getDeviceName() {
- if (mLocalAdapter != null && mLocalAdapter.isEnabled()) {
- return mLocalAdapter.getName();
+ if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
+ return mBluetoothAdapter.getName();
}
return null;
}
@Override
protected void setDeviceName(String deviceName) {
- mLocalAdapter.setName(deviceName);
+ mBluetoothAdapter.setName(deviceName);
}
}
diff --git a/src/com/android/settings/bluetooth/RequestPermissionActivity.java b/src/com/android/settings/bluetooth/RequestPermissionActivity.java
index 5f6fc39..fff6f12 100644
--- a/src/com/android/settings/bluetooth/RequestPermissionActivity.java
+++ b/src/com/android/settings/bluetooth/RequestPermissionActivity.java
@@ -34,8 +34,6 @@
import com.android.settings.R;
import com.android.settingslib.bluetooth.BluetoothDiscoverableTimeoutReceiver;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
import androidx.appcompat.app.AlertDialog;
@@ -58,7 +56,7 @@
static final int REQUEST_ENABLE_DISCOVERABLE = 2;
static final int REQUEST_DISABLE = 3;
- private LocalBluetoothAdapter mLocalAdapter;
+ private BluetoothAdapter mBluetoothAdapter;
private int mTimeout = BluetoothDiscoverableEnabler.DEFAULT_DISCOVERABLE_TIMEOUT;
@@ -76,13 +74,13 @@
setResult(Activity.RESULT_CANCELED);
- // Note: initializes mLocalAdapter and returns true on error
+ // Note: initializes mBluetoothAdapter and returns true on error
if (parseIntent()) {
finish();
return;
}
- int btState = mLocalAdapter.getState();
+ int btState = mBluetoothAdapter.getState();
if (mRequest == REQUEST_DISABLE) {
switch (btState) {
@@ -204,7 +202,7 @@
switch (mRequest) {
case REQUEST_ENABLE:
case REQUEST_ENABLE_DISCOVERABLE: {
- if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) {
+ if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
proceedAndFinish();
} else {
// If BT is not up yet, show "Turning on Bluetooth..."
@@ -216,7 +214,7 @@
} break;
case REQUEST_DISABLE: {
- if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_OFF) {
+ if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_OFF) {
proceedAndFinish();
} else {
// If BT is not up yet, show "Turning off Bluetooth..."
@@ -252,7 +250,7 @@
if (mRequest == REQUEST_ENABLE || mRequest == REQUEST_DISABLE) {
// BT toggled. Done
returnCode = RESULT_OK;
- } else if (mLocalAdapter.setScanMode(
+ } else if (mBluetoothAdapter.setScanMode(
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, mTimeout)) {
// If already in discoverable mode, this will extend the timeout.
long endTime = System.currentTimeMillis() + (long) mTimeout * 1000;
@@ -284,7 +282,7 @@
}
/**
- * Parse the received Intent and initialize mLocalBluetoothAdapter.
+ * Parse the received Intent and initialize mBluetoothAdapter.
* @return true if an error occurred; false otherwise
*/
private boolean parseIntent() {
@@ -314,13 +312,6 @@
return true;
}
- LocalBluetoothManager manager = Utils.getLocalBtManager(this);
- if (manager == null) {
- Log.e(TAG, "Error: there's a problem starting Bluetooth");
- setResult(RESULT_CANCELED);
- return true;
- }
-
String packageName = getCallingPackage();
if (TextUtils.isEmpty(packageName)) {
packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME);
@@ -340,7 +331,12 @@
}
}
- mLocalAdapter = manager.getBluetoothAdapter();
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ if (mBluetoothAdapter == null) {
+ Log.e(TAG, "Error: there's a problem starting Bluetooth");
+ setResult(RESULT_CANCELED);
+ return true;
+ }
return false;
}
diff --git a/src/com/android/settings/bluetooth/RequestPermissionHelperActivity.java b/src/com/android/settings/bluetooth/RequestPermissionHelperActivity.java
index aaa7b50..99ac928 100644
--- a/src/com/android/settings/bluetooth/RequestPermissionHelperActivity.java
+++ b/src/com/android/settings/bluetooth/RequestPermissionHelperActivity.java
@@ -28,8 +28,6 @@
import com.android.internal.app.AlertActivity;
import com.android.internal.app.AlertController;
import com.android.settings.R;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
/**
* RequestPermissionHelperActivity asks the user whether to toggle Bluetooth.
@@ -49,7 +47,7 @@
public static final String EXTRA_APP_LABEL =
"com.android.settings.bluetooth.extra.APP_LABEL";
- private LocalBluetoothAdapter mLocalAdapter;
+ private BluetoothAdapter mBluetoothAdapter;
private CharSequence mAppLabel;
@@ -63,7 +61,7 @@
setResult(RESULT_CANCELED);
- // Note: initializes mLocalAdapter and returns true on error
+ // Note: initializes mBluetoothAdapter and returns true on error
if (!parseIntent()) {
finish();
return;
@@ -131,20 +129,20 @@
startActivity(intent);
}
} else {
- mLocalAdapter.enable();
+ mBluetoothAdapter.enable();
setResult(Activity.RESULT_OK);
}
} break;
case RequestPermissionActivity.REQUEST_DISABLE: {
- mLocalAdapter.disable();
+ mBluetoothAdapter.disable();
setResult(Activity.RESULT_OK);
} break;
}
}
/**
- * Parse the received Intent and initialize mLocalBluetoothAdapter.
+ * Parse the received Intent and initialize mBluetoothAdapter.
* @return true if an error occurred; false otherwise
*/
private boolean parseIntent() {
@@ -167,16 +165,14 @@
return false;
}
- LocalBluetoothManager manager = Utils.getLocalBtManager(this);
- if (manager == null) {
+ mAppLabel = getIntent().getCharSequenceExtra(EXTRA_APP_LABEL);
+
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ if (mBluetoothAdapter == null) {
Log.e(TAG, "Error: there's a problem starting Bluetooth");
return false;
}
- mAppLabel = getIntent().getCharSequenceExtra(EXTRA_APP_LABEL);
-
- mLocalAdapter = manager.getBluetoothAdapter();
-
return true;
}
}
diff --git a/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
index db11164..059a920 100644
--- a/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
@@ -49,16 +49,6 @@
}
@Override
- public void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state,
- int bluetoothProfile) {
- if (state == BluetoothProfile.STATE_CONNECTED) {
- removePreference(cachedDevice);
- } else if (state == BluetoothProfile.STATE_DISCONNECTED) {
- addPreference(cachedDevice);
- }
- }
-
- @Override
public boolean isFilterMatched(CachedBluetoothDevice cachedDevice) {
final BluetoothDevice device = cachedDevice.getDevice();
if (DBG) {
diff --git a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java
index e5e1a70..feb64b5 100644
--- a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java
+++ b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java
@@ -30,7 +30,6 @@
import com.android.settings.bluetooth.Utils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.dashboard.DashboardFragment;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnPause;
@@ -54,7 +53,7 @@
LocalBluetoothManager mLocalManager;
private FooterPreferenceMixinCompat mFooterPreferenceMixin;
private FooterPreference mPreference;
- private LocalBluetoothAdapter mLocalAdapter;
+ private BluetoothAdapter mBluetoothAdapter;
private AlwaysDiscoverable mAlwaysDiscoverable;
public DiscoverableFooterPreferenceController(Context context) {
@@ -63,8 +62,8 @@
if (mLocalManager == null) {
return;
}
- mLocalAdapter = mLocalManager.getBluetoothAdapter();
- mAlwaysDiscoverable = new AlwaysDiscoverable(context, mLocalAdapter);
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ mAlwaysDiscoverable = new AlwaysDiscoverable(context);
initReceiver();
}
@@ -121,7 +120,7 @@
mContext.registerReceiver(mBluetoothChangedReceiver,
new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
mAlwaysDiscoverable.start();
- updateFooterPreferenceTitle(mLocalAdapter.getState());
+ updateFooterPreferenceTitle(mBluetoothAdapter.getState());
}
@Override
@@ -142,7 +141,7 @@
}
private CharSequence getPreferenceTitle() {
- final String deviceName = mLocalAdapter.getName();
+ final String deviceName = mBluetoothAdapter.getName();
if (TextUtils.isEmpty(deviceName)) {
return null;
}
diff --git a/src/com/android/settings/core/SettingsBaseActivity.java b/src/com/android/settings/core/SettingsBaseActivity.java
index 9672694..23eb860 100644
--- a/src/com/android/settings/core/SettingsBaseActivity.java
+++ b/src/com/android/settings/core/SettingsBaseActivity.java
@@ -38,7 +38,7 @@
import androidx.fragment.app.FragmentActivity;
import com.android.settings.R;
-import com.android.settingslib.drawer.CategoryManager;
+import com.android.settings.dashboard.CategoryManager;
import java.util.ArrayList;
import java.util.List;
@@ -172,10 +172,6 @@
new CategoriesUpdateTask().execute();
}
- public String getSettingPkg() {
- return CategoryManager.SETTING_PKG;
- }
-
public interface CategoryListener {
void onCategoriesChanged();
}
@@ -190,7 +186,7 @@
@Override
protected Void doInBackground(Void... params) {
- mCategoryManager.reloadAllCategories(SettingsBaseActivity.this, getSettingPkg());
+ mCategoryManager.reloadAllCategories(SettingsBaseActivity.this);
return null;
}
diff --git a/src/com/android/settings/dashboard/CategoryManager.java b/src/com/android/settings/dashboard/CategoryManager.java
new file mode 100644
index 0000000..4072072
--- /dev/null
+++ b/src/com/android/settings/dashboard/CategoryManager.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2016 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.dashboard;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
+import android.util.Pair;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.settingslib.applications.InterestingConfigChanges;
+import com.android.settingslib.drawer.CategoryKey;
+import com.android.settingslib.drawer.DashboardCategory;
+import com.android.settingslib.drawer.Tile;
+import com.android.settingslib.drawer.TileUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+public class CategoryManager {
+
+ private static final String TAG = "CategoryManager";
+
+ private static CategoryManager sInstance;
+ private final InterestingConfigChanges mInterestingConfigChanges;
+
+ // Tile cache (key: <packageName, activityName>, value: tile)
+ private final Map<Pair<String, String>, Tile> mTileByComponentCache;
+
+ // Tile cache (key: category key, value: category)
+ private final Map<String, DashboardCategory> mCategoryByKeyMap;
+
+ private List<DashboardCategory> mCategories;
+ private String mExtraAction;
+
+ public static CategoryManager get(Context context) {
+ return get(context, null);
+ }
+
+ public static CategoryManager get(Context context, String action) {
+ if (sInstance == null) {
+ sInstance = new CategoryManager(context, action);
+ }
+ return sInstance;
+ }
+
+ CategoryManager(Context context, String action) {
+ mTileByComponentCache = new ArrayMap<>();
+ mCategoryByKeyMap = new ArrayMap<>();
+ mInterestingConfigChanges = new InterestingConfigChanges();
+ mInterestingConfigChanges.applyNewConfig(context.getResources());
+ mExtraAction = action;
+ }
+
+ public synchronized DashboardCategory getTilesByCategory(Context context, String categoryKey) {
+ tryInitCategories(context);
+
+ return mCategoryByKeyMap.get(categoryKey);
+ }
+
+ public synchronized List<DashboardCategory> getCategories(Context context) {
+ tryInitCategories(context);
+ return mCategories;
+ }
+
+ public synchronized void reloadAllCategories(Context context) {
+ final boolean forceClearCache = mInterestingConfigChanges.applyNewConfig(
+ context.getResources());
+ mCategories = null;
+ tryInitCategories(context, forceClearCache);
+ }
+
+ public synchronized void updateCategoryFromBlacklist(Set<ComponentName> tileBlacklist) {
+ if (mCategories == null) {
+ Log.w(TAG, "Category is null, skipping blacklist update");
+ }
+ for (int i = 0; i < mCategories.size(); i++) {
+ DashboardCategory category = mCategories.get(i);
+ for (int j = 0; j < category.getTilesCount(); j++) {
+ Tile tile = category.getTile(j);
+ if (tileBlacklist.contains(tile.intent.getComponent())) {
+ category.removeTile(j--);
+ }
+ }
+ }
+ }
+
+ private synchronized void tryInitCategories(Context context) {
+ // Keep cached tiles by default. The cache is only invalidated when InterestingConfigChange
+ // happens.
+ tryInitCategories(context, false /* forceClearCache */);
+ }
+
+ private synchronized void tryInitCategories(Context context, boolean forceClearCache) {
+ if (mCategories == null) {
+ if (forceClearCache) {
+ mTileByComponentCache.clear();
+ }
+ mCategoryByKeyMap.clear();
+ mCategories = TileUtils.getCategories(context, mTileByComponentCache, mExtraAction);
+ for (DashboardCategory category : mCategories) {
+ mCategoryByKeyMap.put(category.key, category);
+ }
+ backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
+ sortCategories(context, mCategoryByKeyMap);
+ filterDuplicateTiles(mCategoryByKeyMap);
+ }
+ }
+
+ @VisibleForTesting
+ synchronized void backwardCompatCleanupForCategory(
+ Map<Pair<String, String>, Tile> tileByComponentCache,
+ Map<String, DashboardCategory> categoryByKeyMap) {
+ // A package can use a) CategoryKey, b) old category keys, c) both.
+ // Check if a package uses old category key only.
+ // If yes, map them to new category key.
+
+ // Build a package name -> tile map first.
+ final Map<String, List<Tile>> packageToTileMap = new HashMap<>();
+ for (Entry<Pair<String, String>, Tile> tileEntry : tileByComponentCache.entrySet()) {
+ final String packageName = tileEntry.getKey().first;
+ List<Tile> tiles = packageToTileMap.get(packageName);
+ if (tiles == null) {
+ tiles = new ArrayList<>();
+ packageToTileMap.put(packageName, tiles);
+ }
+ tiles.add(tileEntry.getValue());
+ }
+
+ for (Entry<String, List<Tile>> entry : packageToTileMap.entrySet()) {
+ final List<Tile> tiles = entry.getValue();
+ // Loop map, find if all tiles from same package uses old key only.
+ boolean useNewKey = false;
+ boolean useOldKey = false;
+ for (Tile tile : tiles) {
+ if (CategoryKey.KEY_COMPAT_MAP.containsKey(tile.category)) {
+ useOldKey = true;
+ } else {
+ useNewKey = true;
+ break;
+ }
+ }
+ // Uses only old key, map them to new keys one by one.
+ if (useOldKey && !useNewKey) {
+ for (Tile tile : tiles) {
+ final String newCategoryKey = CategoryKey.KEY_COMPAT_MAP.get(tile.category);
+ tile.category = newCategoryKey;
+ // move tile to new category.
+ DashboardCategory newCategory = categoryByKeyMap.get(newCategoryKey);
+ if (newCategory == null) {
+ newCategory = new DashboardCategory();
+ categoryByKeyMap.put(newCategoryKey, newCategory);
+ }
+ newCategory.addTile(tile);
+ }
+ }
+ }
+ }
+
+ /**
+ * Sort the tiles injected from all apps such that if they have the same priority value,
+ * they wil lbe sorted by package name.
+ * <p/>
+ * A list of tiles are considered sorted when their priority value decreases in a linear
+ * scan.
+ */
+ @VisibleForTesting
+ synchronized void sortCategories(Context context,
+ Map<String, DashboardCategory> categoryByKeyMap) {
+ for (Entry<String, DashboardCategory> categoryEntry : categoryByKeyMap.entrySet()) {
+ categoryEntry.getValue().sortTiles(context.getPackageName());
+ }
+ }
+
+ /**
+ * Filter out duplicate tiles from category. Duplicate tiles are the ones pointing to the
+ * same intent.
+ */
+ @VisibleForTesting
+ synchronized void filterDuplicateTiles(Map<String, DashboardCategory> categoryByKeyMap) {
+ for (Entry<String, DashboardCategory> categoryEntry : categoryByKeyMap.entrySet()) {
+ final DashboardCategory category = categoryEntry.getValue();
+ final int count = category.getTilesCount();
+ final Set<ComponentName> components = new ArraySet<>();
+ for (int i = count - 1; i >= 0; i--) {
+ final Tile tile = category.getTile(i);
+ if (tile.intent == null) {
+ continue;
+ }
+ final ComponentName tileComponent = tile.intent.getComponent();
+ if (components.contains(tileComponent)) {
+ category.removeTile(i);
+ } else {
+ components.add(tileComponent);
+ }
+ }
+ }
+ }
+
+ /**
+ * Sort priority value for tiles within a single {@code DashboardCategory}.
+ *
+ * @see #sortCategories(Context, Map)
+ */
+ private synchronized void sortCategoriesForExternalTiles(Context context,
+ DashboardCategory dashboardCategory) {
+ dashboardCategory.sortTiles(context.getPackageName());
+
+ }
+}
diff --git a/src/com/android/settings/dashboard/DashboardAdapter.java b/src/com/android/settings/dashboard/DashboardAdapter.java
index a76414d..b278f60 100644
--- a/src/com/android/settings/dashboard/DashboardAdapter.java
+++ b/src/com/android/settings/dashboard/DashboardAdapter.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.service.settings.suggestions.Suggestion;
import android.text.TextUtils;
@@ -314,8 +315,9 @@
@VisibleForTesting
void onBindTile(DashboardItemHolder holder, Tile tile) {
- Drawable icon = mCache.getIcon(tile.icon);
- if (!TextUtils.equals(tile.icon.getResPackage(), mContext.getPackageName())
+ Icon tileIcon = tile.getIcon(mContext);
+ Drawable icon = mCache.getIcon(tileIcon);
+ if (!TextUtils.equals(tileIcon.getResPackage(), mContext.getPackageName())
&& !(icon instanceof RoundedHomepageIcon)) {
icon = new RoundedHomepageIcon(mContext, icon);
try {
@@ -324,7 +326,7 @@
TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT, 0 /* default */);
if (colorRes != 0) {
final int bgColor = mContext.getPackageManager()
- .getResourcesForApplication(tile.icon.getResPackage())
+ .getResourcesForApplication(tileIcon.getResPackage())
.getColor(colorRes, null /* theme */);
((RoundedHomepageIcon) icon).setBackgroundColor(bgColor);
}
@@ -332,7 +334,7 @@
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Failed to set background color for " + tile.intent.getPackage());
}
- mCache.updateIcon(tile.icon, icon);
+ mCache.updateIcon(tileIcon, icon);
}
holder.icon.setImageDrawable(icon);
holder.title.setText(tile.title);
diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
index a443355..a3410bd 100644
--- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
@@ -34,13 +34,15 @@
import android.util.Log;
import android.util.Pair;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
-import com.android.settingslib.drawer.CategoryManager;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.ProfileSelectDialog;
import com.android.settingslib.drawer.Tile;
@@ -51,9 +53,6 @@
import java.util.List;
import java.util.Map;
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
-
/**
* Impl for {@code DashboardFeatureProvider}.
*/
@@ -239,8 +238,9 @@
@VisibleForTesting
void bindIcon(Preference preference, Tile tile) {
- if (tile.icon != null) {
- preference.setIcon(tile.icon.loadDrawable(preference.getContext()));
+ final Icon tileIcon = tile.getIcon(mContext);
+ if (tileIcon != null) {
+ preference.setIcon(tileIcon.loadDrawable(preference.getContext()));
} else if (tile.metaData != null
&& tile.metaData.containsKey(META_DATA_PREFERENCE_ICON_URI)) {
ThreadUtils.postOnBackgroundThread(() -> {
diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java
index 2a962c1..fceec3b 100644
--- a/src/com/android/settings/dashboard/DashboardFragment.java
+++ b/src/com/android/settings/dashboard/DashboardFragment.java
@@ -24,6 +24,11 @@
import android.util.ArraySet;
import android.util.Log;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.PreferenceControllerListHelper;
@@ -43,11 +48,6 @@
import java.util.Map;
import java.util.Set;
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceManager;
-import androidx.preference.PreferenceScreen;
-
/**
* Base fragment for dashboard style UI containing a list of static and dynamic setting items.
*/
@@ -256,7 +256,8 @@
@VisibleForTesting
boolean tintTileIcon(Tile tile) {
- if (tile.icon == null) {
+ final Context context = getContext();
+ if (tile.getIcon(context) == null) {
return false;
}
// First check if the tile has set the icon tintable metadata.
@@ -265,7 +266,7 @@
&& metadata.containsKey(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE)) {
return metadata.getBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE);
}
- final String pkgName = getContext().getPackageName();
+ final String pkgName = context.getPackageName();
// If this drawable is coming from outside Settings, tint it to match the color.
return pkgName != null && tile.intent != null
&& !pkgName.equals(tile.intent.getComponent().getPackageName());
@@ -330,7 +331,7 @@
/**
* Refresh preference items backed by DashboardCategory.
*/
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ @VisibleForTesting
void refreshDashboardTiles(final String TAG) {
final PreferenceScreen screen = getPreferenceScreen();
@@ -370,7 +371,7 @@
continue;
}
if (tintTileIcon(tile)) {
- tile.icon.setTint(tintColor);
+ tile.getIcon(context).setTint(tintColor);
}
if (mDashboardTilePrefKeys.contains(key)) {
// Have the key already, will rebind.
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java
index 1564b9f..92744ae 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java
@@ -20,15 +20,14 @@
import android.content.Context;
import android.content.SharedPreferences;
import android.service.settings.suggestions.Suggestion;
-import android.util.Pair;
+
+import androidx.annotation.NonNull;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.suggestions.SuggestionControllerMixinCompat;
import java.util.List;
-import androidx.annotation.NonNull;
-
/** Interface should be implemented if you have added new suggestions */
public interface SuggestionFeatureProvider {
@@ -42,11 +41,6 @@
*/
ComponentName getSuggestionServiceComponent();
- /**
- * Returns true if smart suggestion should be used instead of xml based SuggestionParser.
- */
- boolean isSmartSuggestionEnabled(Context context);
-
/** Return true if the suggestion has already been completed and does not need to be shown */
boolean isSuggestionComplete(Context context, @NonNull ComponentName suggestion);
@@ -65,9 +59,4 @@
*/
void dismissSuggestion(Context context, SuggestionControllerMixinCompat suggestionMixin,
Suggestion suggestion);
-
- /**
- * Returns common tagged data for suggestion logging.
- */
- Pair<Integer, Object>[] getLoggingTaggedData(Context context);
}
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
index e1cf1a3..4dd0a5c 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
@@ -22,10 +22,10 @@
import android.content.SharedPreferences;
import android.service.settings.suggestions.Suggestion;
import android.util.Log;
-import android.util.Pair;
+
+import androidx.annotation.NonNull;
import com.android.internal.logging.nano.MetricsProto;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.Settings.NightDisplaySuggestionActivity;
import com.android.settings.biometrics.fingerprint.FingerprintEnrollSuggestionActivity;
import com.android.settings.biometrics.fingerprint.FingerprintSuggestionActivity;
@@ -42,8 +42,6 @@
import java.util.List;
-import androidx.annotation.NonNull;
-
public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider {
private static final String TAG = "SuggestionFeature";
@@ -68,11 +66,6 @@
}
@Override
- public boolean isSmartSuggestionEnabled(Context context) {
- return false;
- }
-
- @Override
public boolean isSuggestionComplete(Context context, @NonNull ComponentName component) {
final String className = component.getClassName();
if (className.equals(WallpaperSuggestionActivity.class.getName())) {
@@ -126,12 +119,4 @@
suggestion.getId());
mixin.dismissSuggestion(suggestion);
}
-
- @Override
- public Pair<Integer, Object>[] getLoggingTaggedData(Context context) {
- final boolean isSmartSuggestionEnabled = isSmartSuggestionEnabled(context);
- return new Pair[] {Pair.create(
- MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED,
- isSmartSuggestionEnabled ? 1 : 0)};
- }
}
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 82ca54b..5be381a 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -39,6 +39,8 @@
import com.android.settings.SettingsActivity;
import com.android.settings.Utils;
import com.android.settings.dashboard.RestrictedDashboardFragment;
+import com.android.settings.development.autofill.AutofillLoggingLevelPreferenceController;
+import com.android.settings.development.autofill.AutofillResetOptionsPreferenceController;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.widget.SwitchBar;
@@ -466,6 +468,8 @@
controllers.add(new DefaultLaunchPreferenceController(context, "density"));
controllers.add(new DefaultLaunchPreferenceController(context, "background_check"));
controllers.add(new DefaultLaunchPreferenceController(context, "inactive_apps"));
+ controllers.add(new AutofillLoggingLevelPreferenceController(context));
+ controllers.add(new AutofillResetOptionsPreferenceController(context));
return controllers;
}
diff --git a/src/com/android/settings/development/autofill/AbstractGlobalSettingsPreference.java b/src/com/android/settings/development/autofill/AbstractGlobalSettingsPreference.java
new file mode 100644
index 0000000..080c387
--- /dev/null
+++ b/src/com/android/settings/development/autofill/AbstractGlobalSettingsPreference.java
@@ -0,0 +1,112 @@
+/*
+ * 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.development.autofill;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.provider.Settings;
+import android.text.BidiFormatter;
+import android.text.InputType;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.Slog;
+import android.view.Display;
+import android.view.View;
+import android.view.autofill.AutofillManager;
+import android.widget.EditText;
+
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settingslib.CustomEditTextPreferenceCompat;
+
+import java.text.NumberFormat;
+
+/**
+ * Base class for Autofill integer properties that are backed by
+ * {@link android.provider.Settings.Global}.
+ */
+abstract class AbstractGlobalSettingsPreference extends CustomEditTextPreferenceCompat {
+
+ private static final String TAG = "AbstractGlobalSettingsPreference";
+
+ private final String mKey;
+ private final int mDefaultValue;
+
+ private final AutofillDeveloperSettingsObserver mObserver;
+
+ protected AbstractGlobalSettingsPreference(Context context, AttributeSet attrs,
+ String key, int defaultValue) {
+ super(context, attrs);
+
+ mKey = key;
+ mDefaultValue = defaultValue;
+ mObserver = new AutofillDeveloperSettingsObserver(context, () -> updateSummary());
+ }
+
+ @Override
+ public void onAttached() {
+ super.onAttached();
+
+ mObserver.register();
+ updateSummary();
+ }
+
+ @Override
+ public void onDetached() {
+ mObserver.unregister();
+
+ super.onDetached();
+ }
+
+ private String getCurrentValue() {
+ final int value = Settings.Global.getInt(getContext().getContentResolver(),
+ mKey, mDefaultValue);
+
+ return Integer.toString(value);
+ }
+
+ private void updateSummary() {
+ setSummary(getCurrentValue());
+
+ }
+
+ @Override
+ protected void onBindDialogView(View view) {
+ super.onBindDialogView(view);
+
+ EditText editText = view.findViewById(android.R.id.edit);
+ if (editText != null) {
+ editText.setInputType(InputType.TYPE_CLASS_NUMBER);
+ editText.setText(getCurrentValue());
+ Utils.setEditTextCursorPosition(editText);
+ }
+ }
+
+ @Override
+ protected void onDialogClosed(boolean positiveResult) {
+ if (positiveResult) {
+ final String stringValue = getText();
+ int newValue = mDefaultValue;
+ try {
+ newValue = Integer.parseInt(stringValue);
+ } catch (Exception e) {
+ Log.e(TAG, "Error converting '" + stringValue + "' to integer. Using "
+ + mDefaultValue + " instead");
+ }
+ Settings.Global.putInt(getContext().getContentResolver(), mKey, newValue);
+ }
+ }
+}
diff --git a/src/com/android/settings/development/autofill/AutofillDeveloperSettingsObserver.java b/src/com/android/settings/development/autofill/AutofillDeveloperSettingsObserver.java
new file mode 100644
index 0000000..ae8e246
--- /dev/null
+++ b/src/com/android/settings/development/autofill/AutofillDeveloperSettingsObserver.java
@@ -0,0 +1,59 @@
+/*
+ * 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.development.autofill;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+final class AutofillDeveloperSettingsObserver extends ContentObserver {
+
+ private final Runnable mChangeCallback;
+ private final ContentResolver mResolver;
+
+ public AutofillDeveloperSettingsObserver(Context context, Runnable changeCallback) {
+ super(new Handler());
+
+ mResolver = context.getContentResolver();
+ mChangeCallback = changeCallback;
+ }
+
+ public void register() {
+ mResolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.AUTOFILL_LOGGING_LEVEL), false, this,
+ UserHandle.USER_ALL);
+ mResolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE), false, this,
+ UserHandle.USER_ALL);
+ mResolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS), false, this,
+ UserHandle.USER_ALL);
+ }
+
+ public void unregister() {
+ mResolver.unregisterContentObserver(this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri, int userId) {
+ mChangeCallback.run(); // Run Forrest, Run!
+ }
+}
diff --git a/src/com/android/settings/development/autofill/AutofillLoggingLevelPreferenceController.java b/src/com/android/settings/development/autofill/AutofillLoggingLevelPreferenceController.java
new file mode 100644
index 0000000..a22295c
--- /dev/null
+++ b/src/com/android/settings/development/autofill/AutofillLoggingLevelPreferenceController.java
@@ -0,0 +1,100 @@
+/*
+ * 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.development.autofill;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.provider.Settings;
+import android.view.autofill.AutofillManager;
+
+import com.android.settings.R;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.development.DeveloperOptionsPreferenceController;
+
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+
+public final class AutofillLoggingLevelPreferenceController
+ extends DeveloperOptionsPreferenceController
+ implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
+
+ private static final String AUTOFILL_LOGGING_LEVEL_KEY = "autofill_logging_level";
+
+ private final String[] mListValues;
+ private final String[] mListSummaries;
+ private final AutofillDeveloperSettingsObserver mObserver;
+
+ public AutofillLoggingLevelPreferenceController(Context context) {
+ super(context);
+
+ Resources resources = context.getResources();
+ mListValues = resources.getStringArray(R.array.autofill_logging_level_values);
+ mListSummaries = resources.getStringArray(R.array.autofill_logging_level_entries);
+ mObserver = new AutofillDeveloperSettingsObserver(mContext, () -> updateOptions());
+ mObserver.register();
+ // TODO: there should be a hook on AbstractPreferenceController where we could unregister it
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return AUTOFILL_LOGGING_LEVEL_KEY;
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ writeLevel(newValue);
+ updateOptions();
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ updateOptions();
+ }
+
+ @Override
+ protected void onDeveloperOptionsSwitchDisabled() {
+ super.onDeveloperOptionsSwitchDisabled();
+ writeLevel(null);
+ }
+
+ private void updateOptions() {
+ final int level = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.AUTOFILL_LOGGING_LEVEL, AutofillManager.DEFAULT_LOGGING_LEVEL);
+
+ final int index;
+ if (level == AutofillManager.FLAG_ADD_CLIENT_DEBUG) {
+ index = 1;
+ } else if (level == AutofillManager.FLAG_ADD_CLIENT_VERBOSE) {
+ index = 2;
+ } else {
+ index = 0;
+ }
+ final ListPreference listPreference = (ListPreference) mPreference;
+ listPreference.setValue(mListValues[index]);
+ listPreference.setSummary(mListSummaries[index]);
+ }
+
+ private void writeLevel(Object newValue) {
+ int level = AutofillManager.NO_LOGGING;
+ if (newValue instanceof String) {
+ level = Integer.parseInt((String) newValue);
+ }
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.AUTOFILL_LOGGING_LEVEL, level);
+ }
+}
diff --git a/src/com/android/settings/development/autofill/AutofillMaxPartitionsPreference.java b/src/com/android/settings/development/autofill/AutofillMaxPartitionsPreference.java
new file mode 100644
index 0000000..ab0cec9
--- /dev/null
+++ b/src/com/android/settings/development/autofill/AutofillMaxPartitionsPreference.java
@@ -0,0 +1,30 @@
+/*
+ * 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.development.autofill;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.view.autofill.AutofillManager;
+
+import java.text.NumberFormat;
+
+public final class AutofillMaxPartitionsPreference extends AbstractGlobalSettingsPreference {
+
+ public AutofillMaxPartitionsPreference(Context context, AttributeSet attrs) {
+ super(context, attrs, Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE,
+ AutofillManager.DEFAULT_MAX_PARTITIONS_SIZE);
+ }
+}
diff --git a/src/com/android/settings/development/autofill/AutofillPreferenceCategory.java b/src/com/android/settings/development/autofill/AutofillPreferenceCategory.java
new file mode 100644
index 0000000..711100d
--- /dev/null
+++ b/src/com/android/settings/development/autofill/AutofillPreferenceCategory.java
@@ -0,0 +1,87 @@
+/*
+ * 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.development.autofill;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.autofill.AutofillManager;
+
+import androidx.preference.PreferenceCategory;
+
+public final class AutofillPreferenceCategory extends PreferenceCategory {
+
+ private static final String TAG = "AutofillPreferenceCategory";
+ private static final long DELAYED_MESSAGE_TIME_MS = 2000;
+
+ private final ContentResolver mContentResolver;
+ private final ContentObserver mSettingsObserver;
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+ public AutofillPreferenceCategory(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ mSettingsObserver = new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri, int userId) {
+ // We cannot apply the change yet because AutofillManager.isEnabled() state is
+ // updated by a ContentObserver as well and there's no guarantee of which observer
+ // is called first - hence, it's possible that the state didn't change here yet.
+ mHandler.postDelayed(() -> notifyDependencyChange(shouldDisableDependents()),
+ DELAYED_MESSAGE_TIME_MS);
+ }
+ };
+ mContentResolver = context.getContentResolver();
+ }
+
+ @Override
+ public void onAttached() {
+ super.onAttached();
+
+ mContentResolver.registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.AUTOFILL_SERVICE), false,
+ mSettingsObserver);
+ }
+
+ @Override
+ public void onDetached() {
+ mContentResolver.unregisterContentObserver(mSettingsObserver);
+
+ super.onDetached();
+ }
+
+ // PreferenceCategory.isEnabled() always return false, so we rather not change that logic
+ // decide whether the children should be shown using isAutofillEnabled() instead.
+ private boolean isAutofillEnabled() {
+ final AutofillManager afm = getContext().getSystemService(AutofillManager.class);
+ final boolean enabled = afm != null && afm.isEnabled();
+ Log.v(TAG, "isAutofillEnabled(): " + enabled);
+ return enabled;
+ }
+
+ @Override
+ public boolean shouldDisableDependents() {
+ final boolean shouldIt = !isAutofillEnabled();
+ Log.v(TAG, "shouldDisableDependents(): " + shouldIt);
+ return shouldIt;
+ }
+}
diff --git a/src/com/android/settings/development/autofill/AutofillResetOptionsPreferenceController.java b/src/com/android/settings/development/autofill/AutofillResetOptionsPreferenceController.java
new file mode 100644
index 0000000..42f7a48
--- /dev/null
+++ b/src/com/android/settings/development/autofill/AutofillResetOptionsPreferenceController.java
@@ -0,0 +1,64 @@
+/*
+ * 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.development.autofill;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.view.autofill.AutofillManager;
+import android.widget.Toast;
+
+import com.android.settings.R;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.development.DeveloperOptionsPreferenceController;
+
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+
+public final class AutofillResetOptionsPreferenceController
+ extends DeveloperOptionsPreferenceController
+ implements PreferenceControllerMixin {
+
+ private static final String AUTOFILL_RESET_OPTIONS_KEY = "autofill_reset_developer_options";
+
+ public AutofillResetOptionsPreferenceController(Context context) {
+ super(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return AUTOFILL_RESET_OPTIONS_KEY;
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ if (!TextUtils.equals(AUTOFILL_RESET_OPTIONS_KEY, preference.getKey())) {
+ return false;
+ }
+ final ContentResolver contentResolver = mContext.getContentResolver();
+ Settings.Global.putInt(contentResolver, Settings.Global.AUTOFILL_LOGGING_LEVEL,
+ AutofillManager.DEFAULT_LOGGING_LEVEL);
+ Settings.Global.putInt(contentResolver, Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE,
+ AutofillManager.DEFAULT_MAX_PARTITIONS_SIZE);
+ Settings.Global.putInt(contentResolver, Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS, 0);
+ Toast.makeText(mContext, R.string.autofill_reset_developer_options_complete,
+ Toast.LENGTH_SHORT).show();
+ return true;
+ }
+}
diff --git a/src/com/android/settings/development/autofill/AutofillVisibleDatasetsPreference.java b/src/com/android/settings/development/autofill/AutofillVisibleDatasetsPreference.java
new file mode 100644
index 0000000..2f0d15f
--- /dev/null
+++ b/src/com/android/settings/development/autofill/AutofillVisibleDatasetsPreference.java
@@ -0,0 +1,26 @@
+/*
+ * 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.development.autofill;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.util.AttributeSet;
+
+public final class AutofillVisibleDatasetsPreference extends AbstractGlobalSettingsPreference {
+
+ public AutofillVisibleDatasetsPreference(Context context, AttributeSet attrs) {
+ super(context, attrs, Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS, 0);
+ }
+}
diff --git a/src/com/android/settings/deviceinfo/DeviceNamePreferenceController.java b/src/com/android/settings/deviceinfo/DeviceNamePreferenceController.java
index 0d4df99..d8e2e79 100644
--- a/src/com/android/settings/deviceinfo/DeviceNamePreferenceController.java
+++ b/src/com/android/settings/deviceinfo/DeviceNamePreferenceController.java
@@ -16,7 +16,7 @@
package com.android.settings.deviceinfo;
-import android.annotation.Nullable;
+import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
@@ -27,10 +27,9 @@
import com.android.settings.bluetooth.BluetoothLengthDeviceNameFilter;
import com.android.settings.core.BasePreferenceController;
+import com.android.settings.R;
import com.android.settings.widget.ValidatedEditTextPreference;
import com.android.settings.wifi.tether.WifiDeviceNameTextValidator;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnCreate;
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
@@ -49,10 +48,9 @@
private static final String KEY_PENDING_DEVICE_NAME = "key_pending_device_name";
private String mDeviceName;
protected WifiManager mWifiManager;
+ private final BluetoothAdapter mBluetoothAdapter;
private final WifiDeviceNameTextValidator mWifiDeviceNameTextValidator;
private ValidatedEditTextPreference mPreference;
- @Nullable
- private LocalBluetoothManager mBluetoothManager;
private DeviceNamePreferenceHost mHost;
private String mPendingDeviceName;
@@ -61,6 +59,7 @@
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
mWifiDeviceNameTextValidator = new WifiDeviceNameTextValidator();
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
initializeDeviceName();
}
@@ -90,7 +89,9 @@
@Override
public int getAvailabilityStatus() {
- return AVAILABLE;
+ return mContext.getResources().getBoolean(R.bool.config_show_device_name)
+ ? AVAILABLE
+ : UNSUPPORTED_ON_DEVICE;
}
@Override
@@ -115,10 +116,6 @@
return mWifiDeviceNameTextValidator.isTextValid(deviceName);
}
- public void setLocalBluetoothManager(LocalBluetoothManager localBluetoothManager) {
- mBluetoothManager = localBluetoothManager;
- }
-
public void confirmDeviceName() {
if (mPendingDeviceName != null) {
setDeviceName(mPendingDeviceName);
@@ -146,14 +143,8 @@
}
private void setBluetoothDeviceName(String deviceName) {
- // Bluetooth manager doesn't exist for certain devices.
- if (mBluetoothManager == null) {
- return;
- }
-
- final LocalBluetoothAdapter localBluetoothAdapter = mBluetoothManager.getBluetoothAdapter();
- if (localBluetoothAdapter != null) {
- localBluetoothAdapter.setName(getFilteredBluetoothString(deviceName));
+ if (mBluetoothAdapter != null) {
+ mBluetoothAdapter.setName(getFilteredBluetoothString(deviceName));
}
}
diff --git a/src/com/android/settings/deviceinfo/UptimePreferenceController.java b/src/com/android/settings/deviceinfo/UptimePreferenceController.java
new file mode 100644
index 0000000..4f02594
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/UptimePreferenceController.java
@@ -0,0 +1,35 @@
+/*
+ * 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.deviceinfo;
+
+import android.content.Context;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.deviceinfo.AbstractUptimePreferenceController;
+
+/**
+ * Concrete subclass of uptime preference controller
+ */
+public class UptimePreferenceController extends AbstractUptimePreferenceController
+ implements PreferenceControllerMixin {
+ public UptimePreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, lifecycle);
+ }
+
+ // This space intentionally left blank
+}
\ No newline at end of file
diff --git a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
index 976a254..425edd9 100644
--- a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
+++ b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
@@ -16,8 +16,6 @@
package com.android.settings.deviceinfo.aboutphone;
-import static com.android.settings.bluetooth.Utils.getLocalBtManager;
-
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@@ -46,6 +44,7 @@
import com.android.settings.deviceinfo.PhoneNumberPreferenceController;
import com.android.settings.deviceinfo.RegulatoryInfoPreferenceController;
import com.android.settings.deviceinfo.SafetyInfoPreferenceController;
+import com.android.settings.deviceinfo.UptimePreferenceController;
import com.android.settings.deviceinfo.WifiMacAddressPreferenceController;
import com.android.settings.deviceinfo.firmwareversion.FirmwareVersionPreferenceController;
import com.android.settings.deviceinfo.imei.ImeiInfoPreferenceController;
@@ -116,7 +115,6 @@
controllers.add(new BrandedAccountPreferenceController(context));
DeviceNamePreferenceController deviceNamePreferenceController =
new DeviceNamePreferenceController(context);
- deviceNamePreferenceController.setLocalBluetoothManager(getLocalBtManager(context));
deviceNamePreferenceController.setHost(fragment);
if (lifecycle != null) {
lifecycle.addObserver(deviceNamePreferenceController);
@@ -134,6 +132,7 @@
controllers.add(new FccEquipmentIdPreferenceController(context));
controllers.add(
new BuildNumberPreferenceController(context, activity, fragment, lifecycle));
+ controllers.add(new UptimePreferenceController(context, lifecycle));
return controllers;
}
diff --git a/src/com/android/settings/display/BatteryPercentagePreferenceController.java b/src/com/android/settings/display/BatteryPercentagePreferenceController.java
index 0bd4445..50fbc64 100644
--- a/src/com/android/settings/display/BatteryPercentagePreferenceController.java
+++ b/src/com/android/settings/display/BatteryPercentagePreferenceController.java
@@ -21,8 +21,8 @@
import android.provider.Settings;
import com.android.internal.R;
+import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.core.AbstractPreferenceController;
import androidx.preference.Preference;
import androidx.preference.SwitchPreference;
@@ -31,24 +31,18 @@
* A controller to manage the switch for showing battery percentage in the status bar.
*/
-public class BatteryPercentagePreferenceController extends AbstractPreferenceController implements
+public class BatteryPercentagePreferenceController extends BasePreferenceController implements
PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
- private static final String KEY_BATTERY_PERCENTAGE = "battery_percentage";
-
- public BatteryPercentagePreferenceController(Context context) {
- super(context);
+ public BatteryPercentagePreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
}
@Override
- public boolean isAvailable() {
- return mContext.getResources()
- .getBoolean(R.bool.config_battery_percentage_setting_available);
- }
-
- @Override
- public String getPreferenceKey() {
- return KEY_BATTERY_PERCENTAGE;
+ public int getAvailabilityStatus() {
+ return mContext.getResources().getBoolean(
+ R.bool.config_battery_percentage_setting_available) ? AVAILABLE
+ : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
index 71eb554..5b5f50a 100644
--- a/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
@@ -27,6 +27,7 @@
import com.android.settings.R;
import com.android.settings.applications.LayoutPreference;
+import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.Utils;
@@ -42,7 +43,7 @@
/**
* Controller that update the battery header view
*/
-public class BatteryHeaderPreferenceController extends AbstractPreferenceController
+public class BatteryHeaderPreferenceController extends BasePreferenceController
implements PreferenceControllerMixin, LifecycleObserver, OnStart {
@VisibleForTesting
static final String KEY_BATTERY_HEADER = "battery_header";
@@ -56,30 +57,35 @@
@VisibleForTesting
TextView mSummary2;
- private final Activity mActivity;
- private final PreferenceFragmentCompat mHost;
- private final Lifecycle mLifecycle;
+ private Activity mActivity;
+ private PreferenceFragmentCompat mHost;
+ private Lifecycle mLifecycle;
private final PowerManager mPowerManager;
private LayoutPreference mBatteryLayoutPref;
- public BatteryHeaderPreferenceController(Context context, Activity activity,
- PreferenceFragmentCompat host, Lifecycle lifecycle) {
- super(context);
- mActivity = activity;
- mHost = host;
- mLifecycle = lifecycle;
- if (mLifecycle != null) {
- mLifecycle.addObserver(this);
- }
+ public BatteryHeaderPreferenceController(Context context, String key) {
+ super(context, key);
mPowerManager = context.getSystemService(PowerManager.class);
}
+ public void setActivity(Activity activity) {
+ mActivity = activity;
+ }
+
+ public void setFragment(PreferenceFragmentCompat fragment) {
+ mHost = fragment;
+ }
+
+ public void setLifecycle(Lifecycle lifecycle) {
+ mLifecycle = lifecycle;
+ }
+
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
- mBatteryLayoutPref = (LayoutPreference) screen.findPreference(KEY_BATTERY_HEADER);
- mBatteryMeterView = (BatteryMeterView) mBatteryLayoutPref
+ mBatteryLayoutPref = (LayoutPreference) screen.findPreference(getPreferenceKey());
+ mBatteryMeterView = mBatteryLayoutPref
.findViewById(R.id.battery_header_icon);
mBatteryPercentText = mBatteryLayoutPref.findViewById(R.id.battery_percent);
mSummary1 = mBatteryLayoutPref.findViewById(R.id.summary1);
@@ -89,13 +95,8 @@
}
@Override
- public boolean isAvailable() {
- return true;
- }
-
- @Override
- public String getPreferenceKey() {
- return KEY_BATTERY_HEADER;
+ public int getAvailabilityStatus() {
+ return AVAILABLE_UNSEARCHABLE;
}
@Override
diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java
index 9e920c4..3676761 100644
--- a/src/com/android/settings/fuelgauge/BatteryUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryUtils.java
@@ -38,11 +38,14 @@
import com.android.internal.os.BatteryStatsHelper;
import com.android.internal.util.ArrayUtils;
import com.android.settings.R;
+import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
import com.android.settings.fuelgauge.batterytip.AnomalyInfo;
+import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
import com.android.settings.fuelgauge.batterytip.StatsManagerConfig;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
import com.android.settingslib.utils.PowerUtil;
+import com.android.settingslib.utils.ThreadUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -101,8 +104,8 @@
mContext = context;
mPackageManager = context.getPackageManager();
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
- mPowerUsageFeatureProvider = FeatureFactory.getFactory(
- context).getPowerUsageFeatureProvider(context);
+ mPowerUsageFeatureProvider = FeatureFactory.getFactory(context)
+ .getPowerUsageFeatureProvider(context);
}
public long getProcessTimeMs(@StatusType int type, @Nullable BatteryStats.Uid uid,
@@ -400,6 +403,18 @@
}
// Control whether app could run jobs in the background
mAppOpsManager.setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName, mode);
+
+ ThreadUtils.postOnBackgroundThread(() -> {
+ final BatteryDatabaseManager batteryDatabaseManager = BatteryDatabaseManager
+ .getInstance(mContext);
+ if (mode == AppOpsManager.MODE_IGNORED) {
+ batteryDatabaseManager.insertAction(AnomalyDatabaseHelper.ActionType.RESTRICTION,
+ uid, packageName, System.currentTimeMillis());
+ } else if (mode == AppOpsManager.MODE_ALLOWED) {
+ batteryDatabaseManager.deleteAction(AnomalyDatabaseHelper.ActionType.RESTRICTION,
+ uid, packageName);
+ }
+ });
}
public boolean isForceAppStandbyEnabled(int uid, String packageName) {
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 843aeec..2ae5876 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -25,7 +25,6 @@
import android.provider.SearchIndexableResource;
import android.text.BidiFormatter;
import android.text.format.Formatter;
-import android.util.SparseArray;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@@ -40,19 +39,15 @@
import com.android.settings.applications.LayoutPreference;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.SummaryLoader;
-import com.android.settings.display.BatteryPercentagePreferenceController;
import com.android.settings.fuelgauge.batterytip.BatteryTipLoader;
import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.utils.PowerUtil;
import com.android.settingslib.utils.StringUtil;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -198,6 +193,22 @@
};
@Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ final SettingsActivity activity = (SettingsActivity) getActivity();
+
+ mBatteryHeaderPreferenceController = use(BatteryHeaderPreferenceController.class);
+ mBatteryHeaderPreferenceController.setActivity(activity);
+ mBatteryHeaderPreferenceController.setFragment(this);
+ mBatteryHeaderPreferenceController.setLifecycle(getSettingsLifecycle());
+
+ mBatteryTipPreferenceController = use(BatteryTipPreferenceController.class);
+ mBatteryTipPreferenceController.setActivity(activity);
+ mBatteryTipPreferenceController.setFragment(this);
+ mBatteryTipPreferenceController.setBatteryTipListener(this::onBatteryTipHandled);
+ }
+
+ @Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setAnimationAllowed(true);
@@ -232,22 +243,6 @@
}
@Override
- protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
- final Lifecycle lifecycle = getSettingsLifecycle();
- final SettingsActivity activity = (SettingsActivity) getActivity();
- final List<AbstractPreferenceController> controllers = new ArrayList<>();
- mBatteryHeaderPreferenceController = new BatteryHeaderPreferenceController(
- context, activity, this /* host */, lifecycle);
- controllers.add(mBatteryHeaderPreferenceController);
- mBatteryTipPreferenceController = new BatteryTipPreferenceController(context,
- KEY_BATTERY_TIP, (SettingsActivity) getActivity(), this /* fragment */, this /*
- BatteryTipListener */);
- controllers.add(mBatteryTipPreferenceController);
- controllers.add(new BatteryPercentagePreferenceController(context));
- return controllers;
- }
-
- @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (DEBUG) {
menu.add(Menu.NONE, MENU_STATS_TYPE, Menu.NONE, R.string.menu_stats_total)
diff --git a/src/com/android/settings/fuelgauge/RestrictedAppDetails.java b/src/com/android/settings/fuelgauge/RestrictedAppDetails.java
index 4934bce..b64a707 100644
--- a/src/com/android/settings/fuelgauge/RestrictedAppDetails.java
+++ b/src/com/android/settings/fuelgauge/RestrictedAppDetails.java
@@ -22,6 +22,8 @@
import android.os.Bundle;
import android.os.UserHandle;
import android.util.IconDrawableFactory;
+import android.util.Log;
+import android.util.SparseLongArray;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
@@ -29,7 +31,9 @@
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
import com.android.settings.fuelgauge.batterytip.AppInfo;
+import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
import com.android.settings.fuelgauge.batterytip.BatteryTipDialogFragment;
import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
@@ -37,6 +41,7 @@
import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
import com.android.settings.widget.AppCheckBoxPreference;
import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.utils.StringUtil;
import com.android.settingslib.widget.FooterPreferenceMixinCompat;
import java.util.List;
@@ -57,6 +62,7 @@
@VisibleForTesting
static final String EXTRA_APP_INFO_LIST = "app_info_list";
private static final String KEY_PREF_RESTRICTED_APP_LIST = "restrict_app_list";
+ private static final long TIME_NULL = -1;
@VisibleForTesting
List<AppInfo> mAppInfos;
@@ -68,6 +74,8 @@
BatteryUtils mBatteryUtils;
@VisibleForTesting
PackageManager mPackageManager;
+ @VisibleForTesting
+ BatteryDatabaseManager mBatteryDatabaseManager;
private final FooterPreferenceMixinCompat mFooterPreferenceMixin =
new FooterPreferenceMixinCompat(this, getSettingsLifecycle());
@@ -96,6 +104,7 @@
mPackageManager = context.getPackageManager();
mIconDrawableFactory = IconDrawableFactory.newInstance(context);
mBatteryUtils = BatteryUtils.getInstance(context);
+ mBatteryDatabaseManager = BatteryDatabaseManager.getInstance(context);
refreshUi();
}
@@ -135,6 +144,9 @@
void refreshUi() {
mRestrictedAppListGroup.removeAll();
final Context context = getPrefContext();
+ final SparseLongArray timestampArray = mBatteryDatabaseManager
+ .queryActionTime(AnomalyDatabaseHelper.ActionType.RESTRICTION);
+ final long now = System.currentTimeMillis();
for (int i = 0, size = mAppInfos.size(); i < size; i++) {
final CheckBoxPreference checkBoxPreference = new AppCheckBoxPreference(context);
@@ -158,9 +170,16 @@
return false;
});
+
+ final long timestamp = timestampArray.get(appInfo.uid, TIME_NULL);
+ if (timestamp != TIME_NULL) {
+ checkBoxPreference.setSummary(getString(R.string.restricted_app_time_summary,
+ StringUtil.formatRelativeTime(context, now - timestamp, false)));
+ }
+ final CharSequence test = checkBoxPreference.getSummaryOn();
mRestrictedAppListGroup.addPreference(checkBoxPreference);
} catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
+ Log.e(TAG, "Can't find package: " + appInfo.packageName);
}
}
}
diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyDatabaseHelper.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyDatabaseHelper.java
index bc332b6..bd1633f 100644
--- a/src/com/android/settings/fuelgauge/batterytip/AnomalyDatabaseHelper.java
+++ b/src/com/android/settings/fuelgauge/batterytip/AnomalyDatabaseHelper.java
@@ -33,7 +33,7 @@
private static final String TAG = "BatteryDatabaseHelper";
private static final String DATABASE_NAME = "battery_settings.db";
- private static final int DATABASE_VERSION = 4;
+ private static final int DATABASE_VERSION = 5;
@Retention(RetentionPolicy.SOURCE)
@IntDef({State.NEW,
@@ -45,8 +45,15 @@
int AUTO_HANDLED = 2;
}
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({ActionType.RESTRICTION})
+ public @interface ActionType {
+ int RESTRICTION = 0;
+ }
+
public interface Tables {
String TABLE_ANOMALY = "anomaly";
+ String TABLE_ACTION = "action";
}
public interface AnomalyColumns {
@@ -91,6 +98,42 @@
+ AnomalyColumns.ANOMALY_STATE + "," + AnomalyColumns.TIME_STAMP_MS + ")"
+ ")";
+
+ public interface ActionColumns {
+ /**
+ * The package name of an app been performed an action
+ */
+ String PACKAGE_NAME = "package_name";
+ /**
+ * The uid of an app been performed an action
+ */
+ String UID = "uid";
+ /**
+ * The type of user action
+ * @see ActionType
+ */
+ String ACTION_TYPE = "action_type";
+ /**
+ * The time when action been performed
+ */
+ String TIME_STAMP_MS = "time_stamp_ms";
+ }
+
+ private static final String CREATE_ACTION_TABLE =
+ "CREATE TABLE " + Tables.TABLE_ACTION +
+ "(" +
+ ActionColumns.UID +
+ " INTEGER NOT NULL, " +
+ ActionColumns.PACKAGE_NAME +
+ " TEXT, " +
+ ActionColumns.ACTION_TYPE +
+ " INTEGER NOT NULL, " +
+ ActionColumns.TIME_STAMP_MS +
+ " INTEGER NOT NULL, " +
+ " PRIMARY KEY (" + ActionColumns.ACTION_TYPE + "," + ActionColumns.UID + ","
+ + ActionColumns.PACKAGE_NAME + ")"
+ + ")";
+
private static AnomalyDatabaseHelper sSingleton;
public static synchronized AnomalyDatabaseHelper getInstance(Context context) {
@@ -109,11 +152,6 @@
bootstrapDB(db);
}
- private void bootstrapDB(SQLiteDatabase db) {
- db.execSQL(CREATE_ANOMALY_TABLE);
- Log.i(TAG, "Bootstrapped database");
- }
-
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < DATABASE_VERSION) {
@@ -137,7 +175,14 @@
bootstrapDB(db);
}
+ private void bootstrapDB(SQLiteDatabase db) {
+ db.execSQL(CREATE_ANOMALY_TABLE);
+ db.execSQL(CREATE_ACTION_TABLE);
+ Log.i(TAG, "Bootstrapped database");
+ }
+
private void dropTables(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + Tables.TABLE_ANOMALY);
+ db.execSQL("DROP TABLE IF EXISTS " + Tables.TABLE_ACTION);
}
}
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryDatabaseManager.java b/src/com/android/settings/fuelgauge/batterytip/BatteryDatabaseManager.java
index 910b368..513244e 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryDatabaseManager.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryDatabaseManager.java
@@ -17,6 +17,8 @@
package com.android.settings.fuelgauge.batterytip;
import static android.database.sqlite.SQLiteDatabase.CONFLICT_IGNORE;
+import static android.database.sqlite.SQLiteDatabase.CONFLICT_REPLACE;
+
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
.ANOMALY_STATE;
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
@@ -26,6 +28,7 @@
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
.TIME_STAMP_MS;
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns.UID;
+import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.Tables.TABLE_ACTION;
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.Tables.TABLE_ANOMALY;
import android.content.ContentValues;
@@ -34,12 +37,15 @@
import android.database.sqlite.SQLiteDatabase;
import android.text.TextUtils;
import android.util.ArrayMap;
+import android.util.SparseLongArray;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.ActionColumns;
+
import androidx.annotation.VisibleForTesting;
/**
@@ -158,4 +164,65 @@
}
}
}
+
+ /**
+ * Query latest timestamps when an app has been performed action {@code type}
+ *
+ * @param type of action been performed
+ * @return {@link SparseLongArray} where key is uid and value is timestamp
+ */
+ public synchronized SparseLongArray queryActionTime(
+ @AnomalyDatabaseHelper.ActionType int type) {
+ final SparseLongArray timeStamps = new SparseLongArray();
+ try (SQLiteDatabase db = mDatabaseHelper.getReadableDatabase()) {
+ final String[] projection = {ActionColumns.UID, ActionColumns.TIME_STAMP_MS};
+ final String selection = ActionColumns.ACTION_TYPE + " = ? ";
+ final String[] selectionArgs = new String[]{String.valueOf(type)};
+
+ try (Cursor cursor = db.query(TABLE_ACTION, projection, selection, selectionArgs,
+ null /* groupBy */, null /* having */, null /* orderBy */)) {
+ final int uidIndex = cursor.getColumnIndex(ActionColumns.UID);
+ final int timestampIndex = cursor.getColumnIndex(ActionColumns.TIME_STAMP_MS);
+
+ while (cursor.moveToNext()) {
+ final int uid = cursor.getInt(uidIndex);
+ final long timeStamp = cursor.getLong(timestampIndex);
+ timeStamps.append(uid, timeStamp);
+ }
+ }
+ }
+
+ return timeStamps;
+ }
+
+ /**
+ * Insert an action, or update it if already existed
+ */
+ public synchronized boolean insertAction(@AnomalyDatabaseHelper.ActionType int type,
+ int uid, String packageName, long timestampMs) {
+ try (SQLiteDatabase db = mDatabaseHelper.getWritableDatabase()) {
+ final ContentValues values = new ContentValues();
+ values.put(ActionColumns.UID, uid);
+ values.put(ActionColumns.PACKAGE_NAME, packageName);
+ values.put(ActionColumns.ACTION_TYPE, type);
+ values.put(ActionColumns.TIME_STAMP_MS, timestampMs);
+ return db.insertWithOnConflict(TABLE_ACTION, null, values, CONFLICT_REPLACE) != -1;
+ }
+ }
+
+ /**
+ * Remove an action
+ */
+ public synchronized boolean deleteAction(@AnomalyDatabaseHelper.ActionType int type,
+ int uid, String packageName) {
+ try (SQLiteDatabase db = mDatabaseHelper.getWritableDatabase()) {
+ final String where =
+ ActionColumns.ACTION_TYPE + " = ? AND " + ActionColumns.UID + " = ? AND "
+ + ActionColumns.PACKAGE_NAME + " = ? ";
+ final String[] whereArgs = new String[]{String.valueOf(type), String.valueOf(uid),
+ String.valueOf(packageName)};
+
+ return db.delete(TABLE_ACTION, where, whereArgs) != 0;
+ }
+ }
}
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceController.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceController.java
index 0a9a4c7..158ffd4 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceController.java
@@ -59,24 +59,27 @@
InstrumentedPreferenceFragment mFragment;
public BatteryTipPreferenceController(Context context, String preferenceKey) {
- this(context, preferenceKey, null, null, null);
- }
-
- public BatteryTipPreferenceController(Context context, String preferenceKey,
- SettingsActivity settingsActivity, InstrumentedPreferenceFragment fragment,
- BatteryTipListener batteryTipListener) {
super(context, preferenceKey);
- mBatteryTipListener = batteryTipListener;
mBatteryTipMap = new HashMap<>();
- mFragment = fragment;
- mSettingsActivity = settingsActivity;
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
mNeedUpdate = true;
}
+ public void setActivity(SettingsActivity activity) {
+ mSettingsActivity = activity;
+ }
+
+ public void setFragment(InstrumentedPreferenceFragment fragment) {
+ mFragment = fragment;
+ }
+
+ public void setBatteryTipListener(BatteryTipListener lsn) {
+ mBatteryTipListener = lsn;
+ }
+
@Override
public int getAvailabilityStatus() {
- return AVAILABLE;
+ return AVAILABLE_UNSEARCHABLE;
}
@Override
diff --git a/src/com/android/settings/homepage/HomepageFragment.java b/src/com/android/settings/homepage/HomepageFragment.java
index 9ccb8e2..ff89dd5 100644
--- a/src/com/android/settings/homepage/HomepageFragment.java
+++ b/src/com/android/settings/homepage/HomepageFragment.java
@@ -87,6 +87,8 @@
final int screenWidthpx = getResources().getDisplayMetrics().widthPixels;
final View searchbar = activity.findViewById(R.id.search_bar_container);
final View bottombar = activity.findViewById(R.id.bar);
+ final Toolbar searchActionBar = (Toolbar) activity.findViewById(R.id.search_action_bar);
+ searchActionBar.setNavigationIcon(R.drawable.ic_search_floating_24dp);
mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
diff --git a/src/com/android/settings/network/NetworkDashboardFragment.java b/src/com/android/settings/network/NetworkDashboardFragment.java
index 27e1a98..d5ef9aa 100644
--- a/src/com/android/settings/network/NetworkDashboardFragment.java
+++ b/src/com/android/settings/network/NetworkDashboardFragment.java
@@ -24,6 +24,7 @@
import android.icu.text.ListFormatter;
import android.provider.SearchIndexableResource;
import android.text.BidiFormatter;
+import android.text.TextUtils;
import android.util.Log;
import com.android.internal.logging.nano.MetricsProto;
@@ -153,21 +154,25 @@
private final Context mContext;
private final SummaryLoader mSummaryLoader;
+ private final WifiMasterSwitchPreferenceController mWifiPreferenceController;
private final MobileNetworkPreferenceController mMobileNetworkPreferenceController;
private final TetherPreferenceController mTetherPreferenceController;
public SummaryProvider(Context context, SummaryLoader summaryLoader) {
this(context, summaryLoader,
+ new WifiMasterSwitchPreferenceController(context, null),
new MobileNetworkPreferenceController(context),
new TetherPreferenceController(context, null /* lifecycle */));
}
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
SummaryProvider(Context context, SummaryLoader summaryLoader,
+ WifiMasterSwitchPreferenceController wifiPreferenceController,
MobileNetworkPreferenceController mobileNetworkPreferenceController,
TetherPreferenceController tetherPreferenceController) {
mContext = context;
mSummaryLoader = summaryLoader;
+ mWifiPreferenceController = wifiPreferenceController;
mMobileNetworkPreferenceController = mobileNetworkPreferenceController;
mTetherPreferenceController = tetherPreferenceController;
}
@@ -176,20 +181,27 @@
@Override
public void setListening(boolean listening) {
if (listening) {
- final List<String> summaries = new ArrayList<>();
+ final String wifiSummary = BidiFormatter.getInstance()
+ .unicodeWrap(mContext.getString(R.string.wifi_settings_title));
+ final String mobileSummary = mContext.getString(
+ R.string.network_dashboard_summary_mobile);
+ final String dataUsageSummary = mContext.getString(
+ R.string.network_dashboard_summary_data_usage);
+ final String hotspotSummary = mContext.getString(
+ R.string.network_dashboard_summary_hotspot);
- summaries.add(BidiFormatter.getInstance()
- .unicodeWrap(mContext.getString(R.string.wifi_settings_title)));
- if (mMobileNetworkPreferenceController.isAvailable()) {
- summaries.add(mContext.getString(
- R.string.network_dashboard_summary_mobile));
+ final List<String> summaries = new ArrayList<>();
+ if (mWifiPreferenceController.isAvailable() && !TextUtils.isEmpty(wifiSummary)) {
+ summaries.add(wifiSummary);
}
- final String dataUsageSettingSummary = mContext.getString(
- R.string.network_dashboard_summary_data_usage);
- summaries.add(dataUsageSettingSummary);
- if (mTetherPreferenceController.isAvailable()) {
- summaries.add(mContext.getString(
- R.string.network_dashboard_summary_hotspot));
+ if (mMobileNetworkPreferenceController.isAvailable() && !TextUtils.isEmpty(mobileSummary)) {
+ summaries.add(mobileSummary);
+ }
+ if (!TextUtils.isEmpty(dataUsageSummary)) {
+ summaries.add(dataUsageSummary);
+ }
+ if (mTetherPreferenceController.isAvailable() && !TextUtils.isEmpty(hotspotSummary)) {
+ summaries.add(hotspotSummary);
}
mSummaryLoader.setSummary(this, ListFormatter.getInstance().format(summaries));
}
diff --git a/src/com/android/settings/nfc/AndroidBeam.java b/src/com/android/settings/nfc/AndroidBeam.java
index 452bf91..efa6041 100644
--- a/src/com/android/settings/nfc/AndroidBeam.java
+++ b/src/com/android/settings/nfc/AndroidBeam.java
@@ -53,6 +53,8 @@
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
+ if (mNfcAdapter == null)
+ getActivity().finish();
setHasOptionsMenu(true);
}
@@ -90,7 +92,6 @@
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
-
SettingsActivity activity = (SettingsActivity) getActivity();
mOldActivityTitle = activity.getActionBar().getTitle();
diff --git a/src/com/android/settings/nfc/PaymentDefaultDialog.java b/src/com/android/settings/nfc/PaymentDefaultDialog.java
index 949f87d..73b92e7 100644
--- a/src/com/android/settings/nfc/PaymentDefaultDialog.java
+++ b/src/com/android/settings/nfc/PaymentDefaultDialog.java
@@ -42,7 +42,11 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mBackend = new PaymentBackend(this);
+ try {
+ mBackend = new PaymentBackend(this);
+ } catch (NullPointerException e) {
+ finish();
+ }
Intent intent = getIntent();
ComponentName component = intent.getParcelableExtra(
CardEmulation.EXTRA_SERVICE_COMPONENT);
diff --git a/src/com/android/settings/notification/AbstractZenModePreferenceController.java b/src/com/android/settings/notification/AbstractZenModePreferenceController.java
index 5d92279..791e28c 100644
--- a/src/com/android/settings/notification/AbstractZenModePreferenceController.java
+++ b/src/com/android/settings/notification/AbstractZenModePreferenceController.java
@@ -117,7 +117,7 @@
}
protected int getZenDuration() {
- return Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.ZEN_DURATION,
+ return Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ZEN_DURATION,
0);
}
@@ -125,8 +125,8 @@
private final Uri ZEN_MODE_URI = Settings.Global.getUriFor(Settings.Global.ZEN_MODE);
private final Uri ZEN_MODE_CONFIG_ETAG_URI = Settings.Global.getUriFor(
Settings.Global.ZEN_MODE_CONFIG_ETAG);
- private final Uri ZEN_MODE_DURATION_URI = Settings.Global.getUriFor(
- Settings.Global.ZEN_DURATION);
+ private final Uri ZEN_MODE_DURATION_URI = Settings.Secure.getUriFor(
+ Settings.Secure.ZEN_DURATION);
private final Preference mPreference;
diff --git a/src/com/android/settings/notification/ChargingSoundPreferenceController.java b/src/com/android/settings/notification/ChargingSoundPreferenceController.java
index fccde6a..c7cd232 100644
--- a/src/com/android/settings/notification/ChargingSoundPreferenceController.java
+++ b/src/com/android/settings/notification/ChargingSoundPreferenceController.java
@@ -16,10 +16,10 @@
package com.android.settings.notification;
-import static com.android.settings.notification.SettingPref.TYPE_GLOBAL;
+import static com.android.settings.notification.SettingPref.TYPE_SECURE;
import android.content.Context;
-import android.provider.Settings.Global;
+import android.provider.Settings.Secure;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
@@ -33,7 +33,7 @@
Lifecycle lifecycle) {
super(context, parent, lifecycle);
mPreference = new SettingPref(
- TYPE_GLOBAL, KEY_CHARGING_SOUNDS, Global.CHARGING_SOUNDS_ENABLED, DEFAULT_ON);
+ TYPE_SECURE, KEY_CHARGING_SOUNDS, Secure.CHARGING_SOUNDS_ENABLED, DEFAULT_ON);
}
@Override
diff --git a/src/com/android/settings/notification/SettingPref.java b/src/com/android/settings/notification/SettingPref.java
index a651e6a..f7152fa 100644
--- a/src/com/android/settings/notification/SettingPref.java
+++ b/src/com/android/settings/notification/SettingPref.java
@@ -21,6 +21,7 @@
import android.content.res.Resources;
import android.net.Uri;
import android.provider.Settings.Global;
+import android.provider.Settings.Secure;
import android.provider.Settings.System;
import com.android.settings.SettingsPreferenceFragment;
@@ -34,6 +35,7 @@
public class SettingPref {
public static final int TYPE_GLOBAL = 1;
public static final int TYPE_SYSTEM = 2;
+ public static final int TYPE_SECURE = 3;
protected final int mType;
private final String mKey;
@@ -132,6 +134,8 @@
return Global.getUriFor(setting);
case TYPE_SYSTEM:
return System.getUriFor(setting);
+ case TYPE_SECURE:
+ return Secure.getUriFor(setting);
}
throw new IllegalArgumentException();
}
@@ -142,6 +146,8 @@
return Global.putInt(cr, setting, value);
case TYPE_SYSTEM:
return System.putInt(cr, setting, value);
+ case TYPE_SECURE:
+ return Secure.putInt(cr, setting, value);
}
throw new IllegalArgumentException();
}
@@ -152,6 +158,8 @@
return Global.getInt(cr, setting, def);
case TYPE_SYSTEM:
return System.getInt(cr, setting, def);
+ case TYPE_SECURE:
+ return Secure.getInt(cr, setting, def);
}
throw new IllegalArgumentException();
}
diff --git a/src/com/android/settings/notification/ZenModeBackend.java b/src/com/android/settings/notification/ZenModeBackend.java
index 8242e3e..d63bed4 100644
--- a/src/com/android/settings/notification/ZenModeBackend.java
+++ b/src/com/android/settings/notification/ZenModeBackend.java
@@ -136,8 +136,8 @@
}
protected void saveVisualEffectsPolicy(int category, boolean suppress) {
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.ZEN_SETTINGS_UPDATED, 1);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ZEN_SETTINGS_UPDATED, 1);
int suppressedEffects = getNewSuppressedEffects(suppress, category);
savePolicy(mPolicy.priorityCategories, mPolicy.priorityCallSenders,
diff --git a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
index ac9aaba..03e63e3 100644
--- a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
@@ -97,14 +97,14 @@
private void updateZenButtonOnClickListener() {
int zenDuration = getZenDuration();
switch (zenDuration) {
- case Settings.Global.ZEN_DURATION_PROMPT:
+ case Settings.Secure.ZEN_DURATION_PROMPT:
mZenButtonOn.setOnClickListener(v -> {
mMetricsFeatureProvider.action(mContext,
MetricsProto.MetricsEvent.ACTION_ZEN_TOGGLE_DND_BUTTON, false);
new SettingsEnableZenModeDialog().show(mFragment, TAG);
});
break;
- case Settings.Global.ZEN_DURATION_FOREVER:
+ case Settings.Secure.ZEN_DURATION_FOREVER:
mZenButtonOn.setOnClickListener(v -> {
mMetricsFeatureProvider.action(mContext,
MetricsProto.MetricsEvent.ACTION_ZEN_TOGGLE_DND_BUTTON, false);
diff --git a/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
index 3cfd13d..1769871 100644
--- a/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
+++ b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
@@ -63,6 +63,7 @@
private TimePickerPreference mStart;
private TimePickerPreference mEnd;
private SwitchPreference mExitAtAlarm;
+ private AlertDialog mDayDialog;
private ScheduleInfo mSchedule;
@@ -195,7 +196,6 @@
updateEndSummary();
}
-
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
List<AbstractPreferenceController> controllers = new ArrayList<>();
@@ -214,18 +214,27 @@
return MetricsEvent.NOTIFICATION_ZEN_MODE_SCHEDULE_RULE;
}
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (mDayDialog != null && mDayDialog.isShowing()) {
+ mDayDialog.dismiss();
+ mDayDialog = null;
+ }
+ }
+
private void showDaysDialog() {
- new AlertDialog.Builder(mContext)
+ mDayDialog = new AlertDialog.Builder(mContext)
.setTitle(R.string.zen_mode_schedule_rule_days)
.setView(new ZenModeScheduleDaysSelection(mContext, mSchedule.days) {
- @Override
- protected void onChanged(final int[] days) {
- if (mDisableListeners) return;
- if (Arrays.equals(days, mSchedule.days)) return;
- if (DEBUG) Log.d(TAG, "days.onChanged days=" + Arrays.asList(days));
- mSchedule.days = days;
- updateRule(ZenModeConfig.toScheduleConditionId(mSchedule));
- }
+ @Override
+ protected void onChanged(final int[] days) {
+ if (mDisableListeners) return;
+ if (Arrays.equals(days, mSchedule.days)) return;
+ if (DEBUG) Log.d(TAG, "days.onChanged days=" + Arrays.asList(days));
+ mSchedule.days = days;
+ updateRule(ZenModeConfig.toScheduleConditionId(mSchedule));
+ }
})
.setOnDismissListener(new OnDismissListener() {
@Override
@@ -249,7 +258,7 @@
super(context);
mContext = context;
setPersistent(false);
- setOnPreferenceClickListener(new OnPreferenceClickListener(){
+ setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
final TimePickerFragment frag = new TimePickerFragment();
diff --git a/src/com/android/settings/notification/ZenOnboardingActivity.java b/src/com/android/settings/notification/ZenOnboardingActivity.java
index 99bc172..3f12358 100644
--- a/src/com/android/settings/notification/ZenOnboardingActivity.java
+++ b/src/com/android/settings/notification/ZenOnboardingActivity.java
@@ -62,8 +62,8 @@
setMetricsLogger(new MetricsLogger());
Context context = getApplicationContext();
- Settings.Global.putInt(context.getContentResolver(),
- Settings.Global.ZEN_SETTINGS_SUGGESTION_VIEWED, 1);
+ Settings.Secure.putInt(context.getContentResolver(),
+ Settings.Secure.ZEN_SETTINGS_SUGGESTION_VIEWED, 1);
setupUI();
}
@@ -135,8 +135,8 @@
mMetrics.action(MetricsEvent.ACTION_ZEN_ONBOARDING_KEEP_CURRENT_SETTINGS);
}
- Settings.Global.putInt(getApplicationContext().getContentResolver(),
- Settings.Global.ZEN_SETTINGS_UPDATED, 1);
+ Settings.Secure.putInt(getApplicationContext().getContentResolver(),
+ Settings.Secure.ZEN_SETTINGS_UPDATED, 1);
finishAndRemoveTask();
}
@@ -160,11 +160,11 @@
NotificationManager nm = context.getSystemService(NotificationManager.class);
if (NotificationManager.Policy.areAllVisualEffectsSuppressed(
nm.getNotificationPolicy().suppressedVisualEffects)) {
- Settings.Global.putInt(context.getContentResolver(),
- Settings.Global.ZEN_SETTINGS_UPDATED, 1);
+ Settings.Secure.putInt(context.getContentResolver(),
+ Settings.Secure.ZEN_SETTINGS_UPDATED, 1);
}
- return Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.ZEN_SETTINGS_UPDATED, 0) != 0;
+ return Settings.Secure.getInt(context.getContentResolver(),
+ Settings.Secure.ZEN_SETTINGS_UPDATED, 0) != 0;
}
private static boolean showSuggestion(Context context) {
@@ -173,8 +173,8 @@
// SHOW_ZEN_SETTINGS_SUGGESTION is also true when:
// - automatic rule has started DND and user has not seen the first use dialog
- return Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.SHOW_ZEN_SETTINGS_SUGGESTION, 0) != 0;
+ return Settings.Secure.getInt(context.getContentResolver(),
+ Settings.Secure.SHOW_ZEN_SETTINGS_SUGGESTION, 0) != 0;
}
diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java
index 72bac99..ef8d1ee 100644
--- a/src/com/android/settings/overlay/FeatureFactory.java
+++ b/src/com/android/settings/overlay/FeatureFactory.java
@@ -23,7 +23,6 @@
import com.android.settings.R;
import com.android.settings.accounts.AccountFeatureProvider;
import com.android.settings.applications.ApplicationFeatureProvider;
-import com.android.settings.bluetooth.BluetoothFeatureProvider;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
@@ -103,8 +102,6 @@
public abstract UserFeatureProvider getUserFeatureProvider(Context context);
- public abstract BluetoothFeatureProvider getBluetoothFeatureProvider(Context context);
-
public abstract SlicesFeatureProvider getSlicesFeatureProvider();
public abstract AccountFeatureProvider getAccountFeatureProvider();
diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java
index 48d563f..61be109 100644
--- a/src/com/android/settings/overlay/FeatureFactoryImpl.java
+++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java
@@ -22,12 +22,12 @@
import android.net.ConnectivityManager;
import android.os.UserManager;
+import androidx.annotation.Keep;
+
import com.android.settings.accounts.AccountFeatureProvider;
import com.android.settings.accounts.AccountFeatureProviderImpl;
import com.android.settings.applications.ApplicationFeatureProvider;
import com.android.settings.applications.ApplicationFeatureProviderImpl;
-import com.android.settings.bluetooth.BluetoothFeatureProvider;
-import com.android.settings.bluetooth.BluetoothFeatureProviderImpl;
import com.android.settings.connecteddevice.dock.DockUpdaterFeatureProviderImpl;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.DashboardFeatureProviderImpl;
@@ -53,8 +53,6 @@
import com.android.settings.users.UserFeatureProviderImpl;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
-import androidx.annotation.Keep;
-
/**
* {@link FeatureFactory} implementation for AOSP Settings.
*/
@@ -73,7 +71,6 @@
private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
private AssistGestureFeatureProvider mAssistGestureFeatureProvider;
private UserFeatureProvider mUserFeatureProvider;
- private BluetoothFeatureProvider mBluetoothFeatureProvider;
private SlicesFeatureProvider mSlicesFeatureProvider;
private AccountFeatureProvider mAccountFeatureProvider;
private DeviceIndexFeatureProviderImpl mDeviceIndexFeatureProvider;
@@ -192,14 +189,6 @@
}
@Override
- public BluetoothFeatureProvider getBluetoothFeatureProvider(Context context) {
- if (mBluetoothFeatureProvider == null) {
- mBluetoothFeatureProvider = new BluetoothFeatureProviderImpl();
- }
- return mBluetoothFeatureProvider;
- }
-
- @Override
public AssistGestureFeatureProvider getAssistGestureFeatureProvider() {
if (mAssistGestureFeatureProvider == null) {
mAssistGestureFeatureProvider = new AssistGestureFeatureProviderImpl();
diff --git a/src/com/android/settings/overlay/SupportFeatureProvider.java b/src/com/android/settings/overlay/SupportFeatureProvider.java
index 0988fd4..a9b66d6 100644
--- a/src/com/android/settings/overlay/SupportFeatureProvider.java
+++ b/src/com/android/settings/overlay/SupportFeatureProvider.java
@@ -67,9 +67,4 @@
* @param activity Calling activity.
*/
void startSupportV2(Activity activity);
-
- /**
- * Returns a url with information to introduce user to new device.
- */
- String getNewDeviceIntroUrl(Context context);
}
diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java
index 3dc4068..a45bea7 100644
--- a/src/com/android/settings/password/ChooseLockGeneric.java
+++ b/src/com/android/settings/password/ChooseLockGeneric.java
@@ -165,6 +165,11 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ final Activity activity = getActivity();
+ if (!Utils.isDeviceProvisioned(activity) && !canRunBeforeDeviceProvisioned()) {
+ activity.finish();
+ return;
+ }
String chooseLockAction = getActivity().getIntent().getAction();
mFingerprintManager = Utils.getFingerprintManagerOrNull(getActivity());
@@ -249,6 +254,10 @@
addHeaderView();
}
+ protected boolean canRunBeforeDeviceProvisioned() {
+ return false;
+ }
+
protected void addHeaderView() {
if (mForFingerprint) {
setHeaderView(R.layout.choose_lock_generic_fingerprint_header);
diff --git a/src/com/android/settings/password/SetupChooseLockGeneric.java b/src/com/android/settings/password/SetupChooseLockGeneric.java
index 6ca0916..1642bf0 100644
--- a/src/com/android/settings/password/SetupChooseLockGeneric.java
+++ b/src/com/android/settings/password/SetupChooseLockGeneric.java
@@ -130,6 +130,11 @@
return layout.onCreateRecyclerView(inflater, parent, savedInstanceState);
}
+ @Override
+ protected boolean canRunBeforeDeviceProvisioned() {
+ return true;
+ }
+
/***
* Disables preferences that are less secure than required quality and shows only secure
* screen lock options here.
diff --git a/src/com/android/settings/print/PrintServiceSettingsFragment.java b/src/com/android/settings/print/PrintServiceSettingsFragment.java
index 1311be0..345b4ae 100644
--- a/src/com/android/settings/print/PrintServiceSettingsFragment.java
+++ b/src/com/android/settings/print/PrintServiceSettingsFragment.java
@@ -286,7 +286,7 @@
@Override
public Loader<List<PrintServiceInfo>> onCreateLoader(int id, Bundle args) {
- return new PrintServicesLoader(
+ return new SettingsPrintServicesLoader(
(PrintManager) getContext().getSystemService(Context.PRINT_SERVICE), getContext(),
PrintManager.ALL_SERVICES);
}
diff --git a/src/com/android/settings/print/PrintServicesLoader.java b/src/com/android/settings/print/PrintServicesLoader.java
deleted file mode 100644
index 57cddb9..0000000
--- a/src/com/android/settings/print/PrintServicesLoader.java
+++ /dev/null
@@ -1,126 +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.print;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.os.Handler;
-import android.os.Message;
-import android.print.PrintManager;
-import android.printservice.PrintServiceInfo;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.List;
-
-import androidx.loader.content.Loader;
-
-/**
- * Loader for the list of print services. Can be parametrized to select a subset.
- *
- */
-public class PrintServicesLoader extends Loader<List<PrintServiceInfo>> {
- /** What type of services to load. */
- private final int mSelectionFlags;
-
- /** The print manager to be used by this object */
- private final @NonNull PrintManager mPrintManager;
-
- /** Handler to sequentialize the delivery of the results to the main thread */
- private final @NonNull Handler mHandler;
-
- /** Listens for updates to the data from the platform */
- private PrintManager.PrintServicesChangeListener mListener;
-
- /**
- * Create a new PrintServicesLoader.
- *
- * @param printManager The print manager supplying the data
- * @param context Context of the using object
- * @param selectionFlags What type of services to load.
- */
- public PrintServicesLoader(@NonNull PrintManager printManager, @NonNull Context context,
- int selectionFlags) {
- super(Preconditions.checkNotNull(context));
- mHandler = new MyHandler();
- mPrintManager = Preconditions.checkNotNull(printManager);
- mSelectionFlags = Preconditions.checkFlagsArgument(selectionFlags,
- PrintManager.ALL_SERVICES);
- }
-
- @Override
- protected void onForceLoad() {
- queueNewResult();
- }
-
- /**
- * Read the print services and queue it to be delivered on the main thread.
- */
- private void queueNewResult() {
- Message m = mHandler.obtainMessage(0);
- m.obj = mPrintManager.getPrintServices(mSelectionFlags);
- mHandler.sendMessage(m);
- }
-
- @Override
- protected void onStartLoading() {
- mListener = new PrintManager.PrintServicesChangeListener() {
- @Override public void onPrintServicesChanged() {
- queueNewResult();
- }
- };
-
- mPrintManager.addPrintServicesChangeListener(mListener, null);
-
- // Immediately deliver a result
- deliverResult(mPrintManager.getPrintServices(mSelectionFlags));
- }
-
- @Override
- protected void onStopLoading() {
- if (mListener != null) {
- mPrintManager.removePrintServicesChangeListener(mListener);
- mListener = null;
- }
-
- mHandler.removeMessages(0);
- }
-
- @Override
- protected void onReset() {
- onStopLoading();
- }
-
- /**
- * Handler to sequentialize all the updates to the main thread.
- */
- private class MyHandler extends Handler {
- /**
- * Create a new handler on the main thread.
- */
- public MyHandler() {
- super(getContext().getMainLooper());
- }
-
- @Override
- public void handleMessage(Message msg) {
- if (isStarted()) {
- deliverResult((List<PrintServiceInfo>) msg.obj);
- }
- }
- }
-}
diff --git a/src/com/android/settings/print/PrintSettingsFragment.java b/src/com/android/settings/print/PrintSettingsFragment.java
index a6b3d7e..899acc7 100644
--- a/src/com/android/settings/print/PrintSettingsFragment.java
+++ b/src/com/android/settings/print/PrintSettingsFragment.java
@@ -168,7 +168,7 @@
PrintManager printManager =
(PrintManager) getContext().getSystemService(Context.PRINT_SERVICE);
if (printManager != null) {
- return new PrintServicesLoader(printManager, getContext(),
+ return new SettingsPrintServicesLoader(printManager, getContext(),
PrintManager.ALL_SERVICES);
} else {
return null;
diff --git a/src/com/android/settings/print/SettingsPrintServicesLoader.java b/src/com/android/settings/print/SettingsPrintServicesLoader.java
new file mode 100644
index 0000000..758f4d3
--- /dev/null
+++ b/src/com/android/settings/print/SettingsPrintServicesLoader.java
@@ -0,0 +1,82 @@
+/*
+ * 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.print;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.print.PrintManager;
+import android.print.PrintServicesLoader;
+import android.printservice.PrintServiceInfo;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.List;
+
+import androidx.loader.content.Loader;
+
+/**
+ * Loader for the list of print services. Can be parametrized to select a subset.
+ */
+public class SettingsPrintServicesLoader extends Loader<List<PrintServiceInfo>> {
+
+ private PrintServicesLoader mLoader;
+
+ public SettingsPrintServicesLoader(@NonNull PrintManager printManager, @NonNull Context context,
+ int selectionFlags) {
+ super(Preconditions.checkNotNull(context));
+
+ mLoader = new PrintServicesLoader(printManager, context, selectionFlags) {
+ @Override
+ public void deliverResult(List<PrintServiceInfo> data) {
+ super.deliverResult(data);
+
+ // deliver the result to outer Loader class
+ SettingsPrintServicesLoader.this.deliverResult(data);
+ }
+ };
+ }
+
+ @Override
+ protected void onForceLoad() {
+ mLoader.forceLoad();
+ }
+
+ @Override
+ protected void onStartLoading() {
+ mLoader.startLoading();
+ }
+
+ @Override
+ protected void onStopLoading() {
+ mLoader.stopLoading();
+ }
+
+ @Override
+ protected boolean onCancelLoad() {
+ return mLoader.cancelLoad();
+ }
+
+ @Override
+ protected void onAbandon() {
+ mLoader.abandon();
+ }
+
+ @Override
+ protected void onReset() {
+ mLoader.reset();
+ }
+}
diff --git a/src/com/android/settings/search/actionbar/SearchMenuController.java b/src/com/android/settings/search/actionbar/SearchMenuController.java
index 2fcc048..54fae7e 100644
--- a/src/com/android/settings/search/actionbar/SearchMenuController.java
+++ b/src/com/android/settings/search/actionbar/SearchMenuController.java
@@ -24,6 +24,7 @@
import android.view.MenuItem;
import com.android.settings.R;
+import com.android.settings.Utils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.SearchFeatureProvider;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -53,6 +54,9 @@
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ if (!Utils.isDeviceProvisioned(mHost.getContext())) {
+ return;
+ }
if (menu == null) {
return;
}
diff --git a/src/com/android/settings/security/ChangeScreenLockPreferenceController.java b/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
index 156e230..1284b6a 100644
--- a/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
+++ b/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
@@ -84,8 +84,7 @@
@Override
public void updateState(Preference preference) {
if (mPreference != null && mPreference instanceof GearPreference) {
- if (mLockPatternUtils.isSecure(mUserId)
- || !mLockPatternUtils.isLockScreenDisabled(mUserId)) {
+ if (mLockPatternUtils.isSecure(mUserId)) {
((GearPreference) mPreference).setOnGearClickListener(this);
} else {
((GearPreference) mPreference).setOnGearClickListener(null);
diff --git a/src/com/android/settings/security/SecuritySettings.java b/src/com/android/settings/security/SecuritySettings.java
index effbd51..72dd91b 100644
--- a/src/com/android/settings/security/SecuritySettings.java
+++ b/src/com/android/settings/security/SecuritySettings.java
@@ -21,6 +21,7 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
+import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.provider.SearchIndexableResource;
@@ -181,7 +182,12 @@
if (listening) {
final FingerprintManager fpm =
Utils.getFingerprintManagerOrNull(mContext);
- if (fpm != null && fpm.isHardwareDetected()) {
+ final FaceManager faceManager =
+ Utils.getFaceManagerOrNull(mContext);
+ if (faceManager != null && faceManager.isHardwareDetected()) {
+ mSummaryLoader.setSummary(this,
+ mContext.getString(R.string.security_dashboard_summary_face));
+ } else if (fpm != null && fpm.isHardwareDetected()) {
mSummaryLoader.setSummary(this,
mContext.getString(R.string.security_dashboard_summary));
} else {
diff --git a/src/com/android/settings/widget/AppCheckBoxPreference.java b/src/com/android/settings/widget/AppCheckBoxPreference.java
index a0d95e9..bd643ba 100644
--- a/src/com/android/settings/widget/AppCheckBoxPreference.java
+++ b/src/com/android/settings/widget/AppCheckBoxPreference.java
@@ -17,11 +17,16 @@
package com.android.settings.widget;
import android.content.Context;
+import android.text.TextUtils;
import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
import com.android.settings.R;
import androidx.preference.CheckBoxPreference;
+import androidx.preference.PreferenceViewHolder;
/**
* {@link CheckBoxPreference} that used only to display app
@@ -36,4 +41,20 @@
super(context);
setLayoutResource(R.layout.preference_app);
}
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ final TextView appendix = (TextView) holder.findViewById(R.id.appendix);
+ if (appendix != null) {
+ appendix.setVisibility(View.GONE);
+ }
+
+ final LinearLayout layout = (LinearLayout) holder.findViewById(R.id.summary_container);
+ if (layout != null) {
+ // If summary doesn't exist, make it gone
+ layout.setVisibility(TextUtils.isEmpty(getSummary()) ? View.GONE : View.VISIBLE);
+ }
+ }
}
diff --git a/src/com/android/settings/widget/SettingsAppWidgetProvider.java b/src/com/android/settings/widget/SettingsAppWidgetProvider.java
index 74108aa..b8730b9 100644
--- a/src/com/android/settings/widget/SettingsAppWidgetProvider.java
+++ b/src/com/android/settings/widget/SettingsAppWidgetProvider.java
@@ -40,9 +40,6 @@
import android.widget.RemoteViews;
import com.android.settings.R;
-import com.android.settings.bluetooth.Utils;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
/**
* Provides control of power-related settings from a widget.
@@ -54,7 +51,7 @@
new ComponentName("com.android.settings",
"com.android.settings.widget.SettingsAppWidgetProvider");
- private static LocalBluetoothAdapter sLocalBluetoothAdapter = null;
+ private static BluetoothAdapter sBluetoothAdapter = null;
private static final int BUTTON_WIFI = 0;
private static final int BUTTON_BRIGHTNESS = 1;
@@ -450,23 +447,19 @@
@Override
public int getActualState(Context context) {
- if (sLocalBluetoothAdapter == null) {
- LocalBluetoothManager manager = Utils.getLocalBtManager(context);
- if (manager == null) {
- return STATE_UNKNOWN; // On emulator?
- }
- sLocalBluetoothAdapter = manager.getBluetoothAdapter();
- if (sLocalBluetoothAdapter == null) {
+ if (sBluetoothAdapter == null) {
+ sBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ if (sBluetoothAdapter == null) {
return STATE_UNKNOWN; // On emulator?
}
}
- return bluetoothStateToFiveState(sLocalBluetoothAdapter.getBluetoothState());
+ return bluetoothStateToFiveState(sBluetoothAdapter.getState());
}
@Override
protected void requestStateChange(Context context, final boolean desiredState) {
- if (sLocalBluetoothAdapter == null) {
- Log.d(TAG, "No LocalBluetoothManager");
+ if (sBluetoothAdapter == null) {
+ Log.d(TAG, "No BluetoothAdapter");
return;
}
// Actually request the Bluetooth change and persistent
@@ -476,7 +469,11 @@
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... args) {
- sLocalBluetoothAdapter.setBluetoothEnabled(desiredState);
+ if (desiredState) {
+ sBluetoothAdapter.enable();
+ } else {
+ sBluetoothAdapter.disable();
+ }
return null;
}
}.execute();
diff --git a/src/com/android/settings/wifi/LinkablePreference.java b/src/com/android/settings/wifi/LinkablePreference.java
index 9c00ee2..9581e7a 100644
--- a/src/com/android/settings/wifi/LinkablePreference.java
+++ b/src/com/android/settings/wifi/LinkablePreference.java
@@ -23,12 +23,14 @@
import android.util.AttributeSet;
import android.widget.TextView;
-import com.android.settings.LinkifyUtils;
-
import androidx.annotation.Nullable;
+import androidx.core.content.res.TypedArrayUtils;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
+import com.android.settings.LinkifyUtils;
+import com.android.settingslib.R;
+
/**
* A preference with a title that can have linkable content on click.
*/
@@ -38,19 +40,20 @@
private CharSequence mContentTitle;
private CharSequence mContentDescription;
+
public LinkablePreference(Context ctx, AttributeSet attrs, int defStyle) {
super(ctx, attrs, defStyle);
+ setIcon(R.drawable.ic_info_outline_24dp);
setSelectable(false);
}
public LinkablePreference(Context ctx, AttributeSet attrs) {
- super(ctx, attrs);
- setSelectable(false);
+ this(ctx, attrs, TypedArrayUtils.getAttr(
+ ctx, R.attr.footerPreferenceStyle, android.R.attr.preferenceStyle));
}
public LinkablePreference(Context ctx) {
- super(ctx);
- setSelectable(false);
+ this(ctx, null);
}
@Override
@@ -75,21 +78,20 @@
boolean linked = LinkifyUtils.linkify(textView, contentBuilder, mClickListener);
if (linked && mContentTitle != null) {
- // Embolden and enlarge the title.
- Spannable boldSpan = (Spannable) textView.getText();
- boldSpan.setSpan(
- new TextAppearanceSpan(
- getContext(), android.R.style.TextAppearance_Medium),
+ Spannable spannableContent = (Spannable) textView.getText();
+ spannableContent.setSpan(
+ new TextAppearanceSpan(getContext(), android.R.style.TextAppearance_Small),
0,
mContentTitle.length(),
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
- textView.setText(boldSpan);
+ textView.setText(spannableContent);
textView.setMovementMethod(new LinkMovementMethod());
}
}
/**
* Sets the linkable text for the Preference title.
+ *
* @param contentTitle text to set the Preference title.
* @param contentDescription description text to append underneath title, can be null.
* @param clickListener OnClickListener for the link portion of the text.
diff --git a/src/com/android/settings/wifi/WifiDialog.java b/src/com/android/settings/wifi/WifiDialog.java
index a487017..6e94a06 100644
--- a/src/com/android/settings/wifi/WifiDialog.java
+++ b/src/com/android/settings/wifi/WifiDialog.java
@@ -50,12 +50,12 @@
private WifiConfigController mController;
private boolean mHideSubmitButton;
-
+ // TODO(b/111875856) WifiDialog should not mimic full screen UI.
/** Creates a WifiDialog with fullscreen style. It displays in fullscreen mode. */
public static WifiDialog createFullscreen(Context context, WifiDialogListener listener,
AccessPoint accessPoint, int mode) {
return new WifiDialog(context, listener, accessPoint, mode,
- R.style.Theme_Settings_NoActionBar, false /* hideSubmitButton */);
+ R.style.Theme_Settings_WifiDialogFullScreen, false /* hideSubmitButton */);
}
/**
diff --git a/src/com/android/settings/wifi/WifiDialogActivity.java b/src/com/android/settings/wifi/WifiDialogActivity.java
index e5526c9..d864855 100644
--- a/src/com/android/settings/wifi/WifiDialogActivity.java
+++ b/src/com/android/settings/wifi/WifiDialogActivity.java
@@ -52,6 +52,8 @@
@VisibleForTesting
static final String KEY_CONNECT_FOR_CALLER = "connect_for_caller";
+ private WifiDialog mDialog;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
final Intent intent = getIntent();
@@ -67,10 +69,10 @@
accessPoint = new AccessPoint(this, accessPointState);
}
- WifiDialog dialog = WifiDialog.createModal(
+ mDialog = WifiDialog.createModal(
this, this, accessPoint, WifiConfigUiBase.MODE_CONNECT);
- dialog.show();
- dialog.setOnDismissListener(this);
+ mDialog.show();
+ mDialog.setOnDismissListener(this);
}
@Override
@@ -80,6 +82,15 @@
}
@Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (mDialog != null && mDialog.isShowing()) {
+ mDialog.dismiss();
+ mDialog = null;
+ }
+ }
+
+ @Override
public void onForget(WifiDialog dialog) {
final WifiManager wifiManager = getSystemService(WifiManager.class);
final AccessPoint accessPoint = dialog.getController().getAccessPoint();
@@ -147,6 +158,7 @@
@Override
public void onDismiss(DialogInterface dialogInterface) {
+ mDialog = null;
finish();
}
}
diff --git a/tests/robotests/assets/grandfather_not_sharing_pref_controllers_with_search_provider b/tests/robotests/assets/grandfather_not_sharing_pref_controllers_with_search_provider
index b329072..e69de29 100644
--- a/tests/robotests/assets/grandfather_not_sharing_pref_controllers_with_search_provider
+++ b/tests/robotests/assets/grandfather_not_sharing_pref_controllers_with_search_provider
@@ -1 +0,0 @@
-com.android.settings.fuelgauge.PowerUsageSummary
diff --git a/tests/robotests/res/values-mcc999/config.xml b/tests/robotests/res/values-mcc999/config.xml
index 2d95b65..6d82451 100644
--- a/tests/robotests/res/values-mcc999/config.xml
+++ b/tests/robotests/res/values-mcc999/config.xml
@@ -61,6 +61,7 @@
<bool name="config_show_wifi_ip_address">false</bool>
<bool name="config_show_wifi_mac_address">false</bool>
<bool name="config_disable_uninstall_update">true</bool>
+ <bool name="config_show_device_name">false</bool>
<!-- List of a11y components on the device allowed to be enabled by Settings Slices -->
<string-array name="config_settings_slices_accessibility_components" translatable="false">
diff --git a/tests/robotests/src/com/android/settings/SettingsActivityTest.java b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
index d1033ea..3d529e4 100644
--- a/tests/robotests/src/com/android/settings/SettingsActivityTest.java
+++ b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
@@ -25,8 +25,11 @@
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
+import android.content.Context;
import android.content.Intent;
-
+import android.os.Bundle;
+import android.provider.Settings.Global;
+import android.view.View;
import com.android.settings.core.OnActivityResultListener;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -35,6 +38,7 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
@@ -52,15 +56,38 @@
@Mock
private ActivityManager.TaskDescription mTaskDescription;
private SettingsActivity mActivity;
+ private Context mContext;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
mActivity = spy(new SettingsActivity());
}
@Test
+ public void onCreate_deviceNotProvisioned_shouldDisableSearch() {
+ Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 0);
+ final Intent intent = new Intent(mContext, Settings.class);
+ final SettingsActivity activity =
+ Robolectric.buildActivity(SettingsActivity.class, intent).create(Bundle.EMPTY).get();
+
+ assertThat(activity.findViewById(R.id.search_bar).getVisibility())
+ .isEqualTo(View.INVISIBLE);
+ }
+
+ @Test
+ public void onCreate_deviceProvisioned_shouldEnableSearch() {
+ Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 1);
+ final Intent intent = new Intent(mContext, Settings.class);
+ final SettingsActivity activity =
+ Robolectric.buildActivity(SettingsActivity.class, intent).create(Bundle.EMPTY).get();
+
+ assertThat(activity.findViewById(R.id.search_bar).getVisibility()).isEqualTo(View.VISIBLE);
+ }
+
+ @Test
public void launchSettingFragment_nullExtraShowFragment_shouldNotCrash() {
when(mActivity.getSupportFragmentManager()).thenReturn(mFragmentManager);
when(mFragmentManager.beginTransaction()).thenReturn(mock(FragmentTransaction.class));
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java
new file mode 100644
index 0000000..8957f85
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright 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 com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHearingAid;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.BluetoothProfile;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.HearingAidProfile;
+import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothUtils.class})
+public class AccessibilityHearingAidPreferenceControllerTest {
+ private static final String TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1";
+ private static final String TEST_DEVICE_NAME = "TEST_HEARING_AID_BT_DEVICE_NAME";
+ private static final String HEARING_AID_PREFERENCE = "hearing_aid_preference";
+
+ private BluetoothAdapter mBluetoothAdapter;
+ private BluetoothManager mBluetoothManager;
+ private BluetoothDevice mBluetoothDevice;
+ private Context mContext;
+ private Preference mHearingAidPreference;
+ private List<Integer> mProfileSupportedList;
+ private AccessibilityHearingAidPreferenceController mPreferenceController;
+
+ @Mock
+ private CachedBluetoothDevice mCachedBluetoothDevice;
+ @Mock
+ private CachedBluetoothDeviceManager mCachedDeviceManager;
+ @Mock
+ private LocalBluetoothAdapter mLocalBluetoothAdapter;
+ @Mock
+ private LocalBluetoothManager mLocalBluetoothManager;
+ @Mock
+ private LocalBluetoothProfileManager mLocalBluetoothProfileManager;
+ @Mock
+ private HearingAidProfile mHearingAidProfile;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ setupBluetoothEnvironment();
+ setupHearingAidEnvironment();
+ mHearingAidPreference = new Preference(mContext);
+ mHearingAidPreference.setKey(HEARING_AID_PREFERENCE);
+ mPreferenceController = new AccessibilityHearingAidPreferenceController(mContext,
+ HEARING_AID_PREFERENCE);
+ mPreferenceController.setPreference(mHearingAidPreference);
+ mHearingAidPreference.setSummary("");
+ }
+
+ @Test
+ public void onHearingAidStateChanged_connected_updateHearingAidSummary() {
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
+ mPreferenceController.onResume();
+ Intent intent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
+ intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHearingAid.STATE_CONNECTED);
+ sendIntent(intent);
+
+ assertThat(mHearingAidPreference.getSummary()).isEqualTo(TEST_DEVICE_NAME);
+ }
+
+ @Test
+ public void onHearingAidStateChanged_disconnected_updateHearingAidSummary() {
+ mPreferenceController.onResume();
+ Intent intent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
+ intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHearingAid.STATE_DISCONNECTED);
+ sendIntent(intent);
+
+ assertThat(mHearingAidPreference.getSummary()).isEqualTo(
+ mContext.getText(R.string.accessibility_hearingaid_not_connected_summary));
+ }
+
+ @Test
+ public void onBluetoothStateChanged_bluetoothOff_updateHearingAidSummary() {
+ mPreferenceController.onResume();
+ Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
+ intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF);
+ sendIntent(intent);
+
+ assertThat(mHearingAidPreference.getSummary()).isEqualTo(
+ mContext.getText(R.string.accessibility_hearingaid_not_connected_summary));
+ }
+
+ @Test
+ public void handleHearingAidPreferenceClick_noHearingAid_launchHearingAidInstructionDialog() {
+ mPreferenceController = spy(new AccessibilityHearingAidPreferenceController(mContext,
+ HEARING_AID_PREFERENCE));
+ mPreferenceController.setPreference(mHearingAidPreference);
+ doNothing().when(mPreferenceController).launchHearingAidInstructionDialog();
+ mPreferenceController.handlePreferenceTreeClick(mHearingAidPreference);
+
+ verify(mPreferenceController).launchHearingAidInstructionDialog();
+ }
+
+ @Test
+ public void handleHearingAidPreferenceClick_withHearingAid_launchBluetoothDeviceDetailSetting()
+ {
+ mPreferenceController = spy(new AccessibilityHearingAidPreferenceController(mContext,
+ HEARING_AID_PREFERENCE));
+ mPreferenceController.setPreference(mHearingAidPreference);
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
+ when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
+ mPreferenceController.handlePreferenceTreeClick(mHearingAidPreference);
+
+ verify(mPreferenceController).launchBluetoothDeviceDetailSetting(mCachedBluetoothDevice);
+ }
+
+ @Test
+ public void onNotSupportHearingAidProfile_doNotDoReceiverOperation() {
+ //clear bluetooth supported profile
+ mProfileSupportedList.clear();
+ mPreferenceController = new AccessibilityHearingAidPreferenceController(mContext, HEARING_AID_PREFERENCE);
+ mPreferenceController.setPreference(mHearingAidPreference);
+ //not call registerReceiver()
+ mPreferenceController.onResume();
+ verify(mContext, never()).registerReceiver((BroadcastReceiver) any(), (IntentFilter) any());
+
+ //not call unregisterReceiver()
+ mPreferenceController.onPause();
+ verify(mContext, never()).unregisterReceiver((BroadcastReceiver) any());
+ }
+
+ private void setupBluetoothEnvironment() {
+ ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
+ mLocalBluetoothManager = ShadowBluetoothUtils.getLocalBtManager(mContext);
+ mBluetoothManager = new BluetoothManager(mContext);
+ mBluetoothAdapter = mBluetoothManager.getAdapter();
+ when(mLocalBluetoothManager.getBluetoothAdapter()).thenReturn(mLocalBluetoothAdapter);
+ when(mLocalBluetoothAdapter.isEnabled()).thenReturn(true);
+ when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
+ when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
+ when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
+ }
+
+ private void setupHearingAidEnvironment() {
+ mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS);
+ mProfileSupportedList = new ArrayList<Integer>();
+ mProfileSupportedList.add(BluetoothProfile.HEARING_AID);
+ when(mLocalBluetoothAdapter.getSupportedProfiles()).thenReturn(mProfileSupportedList);
+ when(mCachedDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice);
+ when(mCachedBluetoothDevice.getName()).thenReturn(TEST_DEVICE_NAME);
+ when(mCachedBluetoothDevice.isConnectedHearingAidDevice()).thenReturn(true);
+ }
+
+ private void sendIntent(Intent intent) {
+ ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+ verify(mContext).registerReceiver(
+ broadcastReceiverCaptor.capture(), (IntentFilter) any());
+ BroadcastReceiver br = broadcastReceiverCaptor.getValue();
+ br.onReceive(mContext, intent);
+ }
+
+ private List<BluetoothDevice> generateHearingAidDeviceList() {
+ final List<BluetoothDevice> deviceList = new ArrayList<>(1);
+ deviceList.add(mBluetoothDevice);
+ return deviceList;
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java
index 36b6b80..33ac5b6 100644
--- a/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java
@@ -16,6 +16,7 @@
package com.android.settings.accounts;
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.mock;
@@ -25,11 +26,14 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.UserHandle;
+import androidx.preference.Preference;
+
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.dashboard.DashboardFeatureProviderImpl;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -44,8 +48,6 @@
import org.robolectric.Shadows;
import org.robolectric.util.ReflectionHelpers;
-import androidx.preference.Preference;
-
@RunWith(SettingsRobolectricTestRunner.class)
public class AccountDetailDashboardFragmentTest {
@@ -72,12 +74,12 @@
@Test
public void testCategory_isAccountDetail() {
assertThat(new AccountDetailDashboardFragment().getCategoryKey())
- .isEqualTo(CategoryKey.CATEGORY_ACCOUNT_DETAIL);
+ .isEqualTo(CategoryKey.CATEGORY_ACCOUNT_DETAIL);
}
@Test
public void refreshDashboardTiles_HasAccountType_shouldDisplay() {
- final Tile tile = new Tile();
+ final Tile tile = new Tile(new ActivityInfo());
final Bundle metaData = new Bundle();
metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT_DETAIL);
metaData.putString(METADATA_ACCOUNT_TYPE, "com.abc");
@@ -88,7 +90,7 @@
@Test
public void refreshDashboardTiles_NoAccountType_shouldNotDisplay() {
- final Tile tile = new Tile();
+ final Tile tile = new Tile(new ActivityInfo());
final Bundle metaData = new Bundle();
metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT_DETAIL);
tile.metaData = metaData;
@@ -98,7 +100,7 @@
@Test
public void refreshDashboardTiles_OtherAccountType_shouldNotDisplay() {
- final Tile tile = new Tile();
+ final Tile tile = new Tile(new ActivityInfo());
final Bundle metaData = new Bundle();
metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT_DETAIL);
metaData.putString(METADATA_ACCOUNT_TYPE, "com.other");
@@ -114,9 +116,9 @@
final PackageManager packageManager = mock(PackageManager.class);
ReflectionHelpers.setField(dashboardFeatureProvider, "mPackageManager", packageManager);
when(packageManager.resolveActivity(any(Intent.class), anyInt()))
- .thenReturn(mock(ResolveInfo.class));
+ .thenReturn(mock(ResolveInfo.class));
- final Tile tile = new Tile();
+ final Tile tile = new Tile(new ActivityInfo());
tile.key = "key";
tile.metaData = new Bundle();
tile.metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT);
diff --git a/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java
index de558b3..e7902182 100644
--- a/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java
@@ -563,6 +563,45 @@
verify(preferenceGroup, times(1)).removePreference(argThat(titleMatches("Acct12")));
}
+ @Test
+ public void onResume_userReEnabled_shouldAddOneAccountPreference() {
+ final List<UserInfo> infos = new ArrayList<>();
+ infos.add(new UserInfo(1, "user 1", UserInfo.FLAG_DISABLED));
+ when(mUserManager.isManagedProfile()).thenReturn(false);
+ when(mUserManager.isRestrictedProfile()).thenReturn(false);
+ when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
+
+ Account[] accounts = {new Account("Acct1", "com.acct1")};
+ when(mAccountManager.getAccountsAsUser(1)).thenReturn(accounts);
+ when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
+ .thenReturn(accounts);
+
+ AuthenticatorDescription[] authDescs = {
+ new AuthenticatorDescription("com.acct1", "com.android.settings",
+ R.string.account_settings_title, 0 /* iconId */, 0 /* smallIconId */,
+ 0 /* prefId */, false /* customTokens */)
+ };
+ when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs);
+
+ AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class);
+ when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
+ when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class)))
+ .thenReturn(preferenceGroup);
+
+ // First time resume will build the UI with no account
+ mController.onResume();
+ verify(preferenceGroup, never()).addPreference(argThat(titleMatches("Acct1")));
+
+ // Enable the user
+ infos.remove(0 /* index */);
+ infos.add(new UserInfo(1, "user 1", 0 /* flags */));
+
+ // Resume should show the account for the user
+ mController.onResume();
+
+ verify(preferenceGroup).addPreference(argThat(titleMatches("Acct1")));
+ }
+
private static ArgumentMatcher<Preference> titleMatches(String expected) {
return preference -> TextUtils.equals(expected, preference.getTitle());
}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/AlwaysDiscoverableTest.java b/tests/robotests/src/com/android/settings/bluetooth/AlwaysDiscoverableTest.java
index d9261c2..1e323ef 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/AlwaysDiscoverableTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/AlwaysDiscoverableTest.java
@@ -17,41 +17,41 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
+import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class})
public class AlwaysDiscoverableTest {
@Mock
- private LocalBluetoothAdapter mLocalAdapter;
-
- @Mock
private Context mContext;
private AlwaysDiscoverable mAlwaysDiscoverable;
+ private BluetoothAdapter mBluetoothAdapter;
+ private ShadowBluetoothAdapter mShadowBluetoothAdapter;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mAlwaysDiscoverable = new AlwaysDiscoverable(mContext, mLocalAdapter);
+ mAlwaysDiscoverable = new AlwaysDiscoverable(mContext);
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
}
@Test
@@ -76,14 +76,15 @@
public void stopWithoutStart() {
mAlwaysDiscoverable.stop();
// expect no crash
- verify(mLocalAdapter, never()).setScanMode(anyInt());
+ mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
}
@Test
public void startSetsModeAndRegistersReceiver() {
- when(mLocalAdapter.getScanMode()).thenReturn(BluetoothAdapter.SCAN_MODE_NONE);
+ mShadowBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_NONE);
mAlwaysDiscoverable.start();
- verify(mLocalAdapter).setScanMode(eq(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE));
+ assertThat(mBluetoothAdapter.getScanMode())
+ .isEqualTo(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
verify(mContext).registerReceiver(eq(mAlwaysDiscoverable), any());
}
@@ -97,18 +98,18 @@
@Test
public void resetsToDiscoverableModeWhenScanModeChanges() {
mAlwaysDiscoverable.start();
- verify(mLocalAdapter, times(1))
- .setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+ assertThat(mBluetoothAdapter.getScanMode())
+ .isEqualTo(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
sendScanModeChangedIntent(BluetoothAdapter.SCAN_MODE_CONNECTABLE,
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
- verify(mLocalAdapter, times(2))
- .setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+ assertThat(mBluetoothAdapter.getScanMode())
+ .isEqualTo(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
}
private void sendScanModeChangedIntent(int newMode, int previousMode) {
- when(mLocalAdapter.getScanMode()).thenReturn(newMode);
+ mShadowBluetoothAdapter.setScanMode(newMode);
Intent intent = new Intent(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_SCAN_MODE, newMode);
intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_SCAN_MODE, previousMode);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java
index dd5f278..afce68e 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java
@@ -24,22 +24,25 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
+import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class})
public class BluetoothDeviceNamePreferenceControllerTest {
private static final String DEVICE_NAME = "Nightshade";
@@ -48,8 +51,6 @@
private Context mContext;
@Mock
- private LocalBluetoothAdapter mLocalAdapter;
- @Mock
private PreferenceScreen mPreferenceScreen;
private Preference mPreference;
@@ -64,8 +65,7 @@
when(mPreferenceScreen.getContext()).thenReturn(mContext);
mPreference = new Preference(mContext);
mPreference.setKey(KEY_DEVICE_NAME);
- mController = spy(new BluetoothDeviceNamePreferenceController(mContext, mLocalAdapter,
- KEY_DEVICE_NAME));
+ mController = spy(new BluetoothDeviceNamePreferenceController(mContext, KEY_DEVICE_NAME));
doReturn(DEVICE_NAME).when(mController).getDeviceName();
}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java
index 2b5c7e9..0fdfc52 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java
@@ -24,11 +24,11 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
-
+import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -41,15 +41,16 @@
import androidx.fragment.app.FragmentTransaction;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class})
public class BluetoothDeviceRenamePreferenceControllerTest {
private static final String DEVICE_NAME = "Nightshade";
private static final String PREF_KEY = "bt_rename_devices";
- @Mock
- private LocalBluetoothAdapter mLocalAdapter;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Fragment mFragment;
@Mock
@@ -59,6 +60,8 @@
private Context mContext;
private Preference mPreference;
private BluetoothDeviceRenamePreferenceController mController;
+ private BluetoothAdapter mBluetoothAdapter;
+ private ShadowBluetoothAdapter mShadowBluetoothAdapter;
@Before
public void setUp() {
@@ -67,9 +70,10 @@
mContext = spy(RuntimeEnvironment.application);
mPreference = new Preference(mContext);
mPreference.setKey(PREF_KEY);
+ mBluetoothAdapter = ShadowBluetoothAdapter.getDefaultAdapter();
+ mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
- mController = spy(new BluetoothDeviceRenamePreferenceController(mContext, mLocalAdapter,
- PREF_KEY));
+ mController = spy(new BluetoothDeviceRenamePreferenceController(mContext, PREF_KEY));
mController.setFragment(mFragment);
doReturn(DEVICE_NAME).when(mController).getDeviceName();
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
@@ -102,7 +106,7 @@
@Test
public void updatePreferenceState_whenBTisOnPreferenceShouldBeVisible() {
- when(mLocalAdapter.isEnabled()).thenReturn(true);
+ mShadowBluetoothAdapter.setEnabled(true);
mController.updatePreferenceState(mPreference);
@@ -111,7 +115,7 @@
@Test
public void updatePreferenceState_whenBTisOffPreferenceShouldBeHide() {
- when(mLocalAdapter.isEnabled()).thenReturn(false);
+ mShadowBluetoothAdapter.setEnabled(false);
mController.updatePreferenceState(mPreference);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java
index 6936177..927f622 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java
@@ -35,13 +35,12 @@
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
+import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.widget.SwitchBar;
import com.android.settings.widget.SwitchBarController;
import com.android.settings.widget.SwitchWidgetController;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedSwitchPreference;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import org.junit.Before;
@@ -53,11 +52,12 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
import androidx.preference.PreferenceViewHolder;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(shadows = SettingsShadowResources.SettingsShadowTheme.class)
+@Config(shadows = {SettingsShadowResources.SettingsShadowTheme.class, ShadowBluetoothAdapter.class})
public class BluetoothEnablerTest {
private static EnforcedAdmin sFakeEnforcedAdmin;
@@ -74,21 +74,17 @@
@Mock
private RestrictionUtils mRestrictionUtils;
@Mock
- private LocalBluetoothManager mBluetoothManager;
- @Mock
- private LocalBluetoothAdapter mBluetoothAdapter;
- @Mock
private SwitchWidgetController.OnSwitchChangeListener mCallback;
private Context mContext;
private SwitchWidgetController mSwitchController;
private BluetoothEnabler mBluetoothEnabler;
+ private ShadowBluetoothAdapter mShadowBluetoothAdapter;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
- when(mBluetoothManager.getBluetoothAdapter()).thenReturn(mBluetoothAdapter);
mRestrictedSwitchPreference = new RestrictedSwitchPreference(mContext);
mSwitchController = spy(new SwitchBarController(new SwitchBar(mContext)));
@@ -96,12 +92,12 @@
mContext,
mSwitchController,
mMetricsFeatureProvider,
- mBluetoothManager,
123,
mRestrictionUtils);
mHolder = PreferenceViewHolder.createInstanceForTests(mock(View.class));
mRestrictedSwitchPreference.onBindViewHolder(mHolder);
mBluetoothEnabler.setToggleCallback(mCallback);
+ mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
}
@Test
@@ -191,7 +187,7 @@
@Test
public void startWithBluetoothOff_switchIsOff() {
- when(mBluetoothAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_OFF);
+ mShadowBluetoothAdapter.setState(BluetoothAdapter.STATE_OFF);
verify(mSwitchController, never()).setChecked(anyBoolean());
mBluetoothEnabler.resume(mContext);
verify(mSwitchController, never()).setChecked(true);
@@ -199,7 +195,7 @@
@Test
public void startWithBluetoothOn_switchIsOn() {
- when(mBluetoothAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
+ mShadowBluetoothAdapter.setState(BluetoothAdapter.STATE_ON);
verify(mSwitchController, never()).setChecked(anyBoolean());
mBluetoothEnabler.resume(mContext);
verify(mSwitchController, never()).setChecked(false);
@@ -211,7 +207,7 @@
// Start up with bluetooth turned on. The switch should get turned on.
ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class);
when(mContext.registerReceiver(captor.capture(), any(IntentFilter.class))).thenReturn(null);
- when(mBluetoothAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
+ mShadowBluetoothAdapter.setState(BluetoothAdapter.STATE_ON);
verify(mSwitchController, never()).setChecked(anyBoolean());
mBluetoothEnabler.resume(mContext);
verify(mSwitchController, never()).setChecked(false);
@@ -235,7 +231,7 @@
// Start up with bluetooth turned on. The switch should be left off.
ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class);
when(mContext.registerReceiver(captor.capture(), any(IntentFilter.class))).thenReturn(null);
- when(mBluetoothAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_OFF);
+ mShadowBluetoothAdapter.setState(BluetoothAdapter.STATE_OFF);
verify(mSwitchController, never()).setChecked(anyBoolean());
mBluetoothEnabler.resume(mContext);
verify(mSwitchController, never()).setChecked(anyBoolean());
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java
index a4b2141..6491843 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java
@@ -33,8 +33,8 @@
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settingslib.bluetooth.BluetoothDeviceFilter;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.widget.FooterPreference;
@@ -45,16 +45,17 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
import androidx.preference.PreferenceGroup;
@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class})
public class BluetoothPairingDetailTest {
@Mock
private Resources mResource;
- @Mock
- private LocalBluetoothAdapter mLocalAdapter;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private LocalBluetoothManager mLocalManager;
@Mock
@@ -63,6 +64,8 @@
private Context mContext;
private BluetoothProgressCategory mAvailableDevicesCategory;
private FooterPreference mFooterPreference;
+ private BluetoothAdapter mBluetoothAdapter;
+ private ShadowBluetoothAdapter mShadowBluetoothAdapter;
@Before
public void setUp() {
@@ -75,11 +78,13 @@
mAvailableDevicesCategory = spy(new BluetoothProgressCategory(mContext));
mFooterPreference = new FooterPreference(mContext);
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
- mFragment.mLocalAdapter = mLocalAdapter;
+ mFragment.mBluetoothAdapter = mBluetoothAdapter;
mFragment.mLocalManager = mLocalManager;
mFragment.mDeviceListGroup = mPreferenceGroup;
- mFragment.mAlwaysDiscoverable = new AlwaysDiscoverable(mContext, mLocalAdapter);
+ mFragment.mAlwaysDiscoverable = new AlwaysDiscoverable(mContext);
}
@Test
@@ -102,7 +107,7 @@
mFragment.enableScanning();
- verify(mLocalAdapter).startScanning(true);
+ verify(mFragment).startScanning();
verify(mAvailableDevicesCategory).removeAll();
}
@@ -117,7 +122,8 @@
verify(mFragment).addDeviceCategory(mAvailableDevicesCategory,
R.string.bluetooth_preference_found_media_devices,
BluetoothDeviceFilter.UNBONDED_DEVICE_FILTER, false);
- verify(mLocalAdapter).setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+ assertThat(mBluetoothAdapter.getScanMode())
+ .isEqualTo(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
}
@Test
@@ -129,16 +135,16 @@
@Test
public void testUpdateBluetooth_bluetoothOff_turnOnBluetooth() {
- doReturn(false).when(mLocalAdapter).isEnabled();
+ mShadowBluetoothAdapter.setEnabled(false);
mFragment.updateBluetooth();
- verify(mLocalAdapter).enable();
+ assertThat(mBluetoothAdapter.isEnabled()).isTrue();
}
@Test
public void testUpdateBluetooth_bluetoothOn_updateState() {
- doReturn(true).when(mLocalAdapter).isEnabled();
+ mShadowBluetoothAdapter.setEnabled(true);
doNothing().when(mFragment).updateContent(anyInt());
mFragment.updateBluetooth();
@@ -157,27 +163,27 @@
mFragment.updateContent(BluetoothAdapter.STATE_ON);
verify(mFragment).enableScanning();
assertThat(mAvailableDevicesCategory.getPreferenceCount()).isEqualTo(0);
- verify(mLocalAdapter).startScanning(true);
+ verify(mFragment).startScanning();
// Subsequent scan started event will not trigger start/stop nor list clear
mFragment.onScanningStateChanged(true);
- verify(mLocalAdapter, times(1)).startScanning(anyBoolean());
+ verify(mFragment, times(1)).startScanning();
verify(mAvailableDevicesCategory, times(1)).setProgress(true);
// Subsequent scan finished event will trigger scan start without list clean
mFragment.onScanningStateChanged(false);
- verify(mLocalAdapter, times(2)).startScanning(true);
+ verify(mFragment, times(2)).startScanning();
verify(mAvailableDevicesCategory, times(2)).setProgress(true);
// Subsequent scan started event will not trigger any change
mFragment.onScanningStateChanged(true);
- verify(mLocalAdapter, times(2)).startScanning(anyBoolean());
+ verify(mFragment, times(2)).startScanning();
verify(mAvailableDevicesCategory, times(3)).setProgress(true);
- verify(mLocalAdapter, never()).stopScanning();
+ verify(mFragment, never()).stopScanning();
// Disable scanning will trigger scan stop
mFragment.disableScanning();
- verify(mLocalAdapter, times(1)).stopScanning();
+ verify(mFragment, times(1)).stopScanning();
// Subsequent scan start event will not trigger any change besides progress circle
mFragment.onScanningStateChanged(true);
@@ -187,8 +193,8 @@
// progress circle from spinning
mFragment.onScanningStateChanged(false);
verify(mAvailableDevicesCategory, times(1)).setProgress(false);
- verify(mLocalAdapter, times(2)).startScanning(anyBoolean());
- verify(mLocalAdapter, times(1)).stopScanning();
+ verify(mFragment, times(2)).startScanning();
+ verify(mFragment, times(1)).stopScanning();
// Verify that clean up only happen once at initialization
verify(mAvailableDevicesCategory, times(1)).removeAll();
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothSliceBuilderTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothSliceBuilderTest.java
index f85a584..75361d7 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothSliceBuilderTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothSliceBuilderTest.java
@@ -22,6 +22,7 @@
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
+import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
@@ -29,10 +30,7 @@
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.SliceTester;
-import com.android.settings.testutils.shadow.ShadowLocalBluetoothAdapter;
import com.android.settings.testutils.shadow.ShadowLocalBluetoothProfileManager;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
import org.junit.Before;
import org.junit.Test;
@@ -52,7 +50,7 @@
import androidx.slice.widget.SliceLiveData;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(shadows = {ShadowLocalBluetoothAdapter.class, ShadowLocalBluetoothProfileManager.class})
+@Config(shadows = {ShadowLocalBluetoothProfileManager.class})
public class BluetoothSliceBuilderTest {
private Context mContext;
@@ -90,11 +88,10 @@
@Test
public void handleUriChange_updatesBluetooth() {
- final LocalBluetoothAdapter adapter = LocalBluetoothManager.getInstance(mContext,
- null /* callback */).getBluetoothAdapter();
+ final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
final Intent intent = new Intent();
intent.putExtra(android.app.slice.Slice.EXTRA_TOGGLE_STATE, true);
- adapter.setBluetoothEnabled(false /* enabled */);
+ adapter.disable()/* enabled */;
BluetoothSliceBuilder.handleUriChange(mContext, intent);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothSummaryUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothSummaryUpdaterTest.java
index 2ac1ed8..2cab95b 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothSummaryUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothSummaryUpdaterTest.java
@@ -23,7 +23,6 @@
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
@@ -31,8 +30,8 @@
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.widget.SummaryUpdater.OnSummaryChangeListener;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import org.junit.Before;
@@ -42,11 +41,14 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
import java.util.HashSet;
import java.util.Set;
@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class})
public class BluetoothSummaryUpdaterTest {
private static final String DEVICE_NAME = "Nightshade";
@@ -56,8 +58,6 @@
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private LocalBluetoothManager mBluetoothManager;
@Mock
- private LocalBluetoothAdapter mBtAdapter;
- @Mock
private BluetoothDevice mConnectedDevice;
@Mock
private BluetoothDevice mConnectedKeyBoardDevice;
@@ -72,16 +72,13 @@
private final boolean[] mDeviceConnected = {false, false};
private final Set<BluetoothDevice> mBondedDevices = new HashSet<>();
private BluetoothSummaryUpdater mSummaryUpdater;
+ private ShadowBluetoothAdapter mShadowBluetoothAdapter;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application.getApplicationContext();
doCallRealMethod().when(mListener).onSummaryChanged(anyString());
- // Setup mock adapter
- when(mBluetoothManager.getBluetoothAdapter()).thenReturn(mBtAdapter);
- doAnswer(invocation -> mAdapterEnabled[0]).when(mBtAdapter).isEnabled();
- doAnswer(invocation -> mAdapterConnectionState[0]).when(mBtAdapter).getConnectionState();
mSummaryUpdater = new BluetoothSummaryUpdater(mContext, mListener, mBluetoothManager);
// Setup first device
doReturn(DEVICE_NAME).when(mConnectedDevice).getName();
@@ -89,7 +86,11 @@
// Setup second device
doReturn(DEVICE_KEYBOARD_NAME).when(mConnectedKeyBoardDevice).getName();
doAnswer(invocation -> mDeviceConnected[1]).when(mConnectedKeyBoardDevice).isConnected();
- doReturn(mBondedDevices).when(mBtAdapter).getBondedDevices();
+ // Setup BluetoothAdapter
+ mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
+ mShadowBluetoothAdapter.setEnabled(mAdapterEnabled[0]);
+ mShadowBluetoothAdapter.setBondedDevices(mBondedDevices);
+ mShadowBluetoothAdapter.setConnectionState(mAdapterConnectionState[0]);
}
@Test
@@ -108,9 +109,10 @@
@Test
public void register_true_shouldSendSummaryChange() {
- mAdapterEnabled[0] = true;
- mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED;
+ mShadowBluetoothAdapter.setEnabled(true);
+ mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_CONNECTED);
mBondedDevices.add(mConnectedDevice);
+ mShadowBluetoothAdapter.setBondedDevices(mBondedDevices);
mDeviceConnected[0] = true;
mSummaryUpdater.register(true);
@@ -122,8 +124,9 @@
@Test
public void onBluetoothStateChanged_btDisabled_shouldSendDisabledSummary() {
// These states should be ignored
- mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED;
+ mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_CONNECTED);
mBondedDevices.add(mConnectedDevice);
+ mShadowBluetoothAdapter.setBondedDevices(mBondedDevices);
mDeviceConnected[0] = true;
mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_OFF);
@@ -133,9 +136,10 @@
@Test
public void onBluetoothStateChanged_btEnabled_connected_shouldSendConnectedSummary() {
- mAdapterEnabled[0] = true;
- mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED;
+ mShadowBluetoothAdapter.setEnabled(true);
+ mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_CONNECTED);
mBondedDevices.add(mConnectedDevice);
+ mShadowBluetoothAdapter.setBondedDevices(mBondedDevices);
mDeviceConnected[0] = true;
mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_ON);
@@ -146,9 +150,10 @@
@Test
public void onBluetoothStateChanged_btEnabled_connectedMisMatch_shouldSendNotConnected() {
- mAdapterEnabled[0] = true;
- mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED;
+ mShadowBluetoothAdapter.setEnabled(true);
+ mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_CONNECTED);
mBondedDevices.add(mConnectedDevice);
+ mShadowBluetoothAdapter.setBondedDevices(mBondedDevices);
// State mismatch
mDeviceConnected[0] = false;
@@ -159,9 +164,10 @@
@Test
public void onBluetoothStateChanged_btEnabled_notConnected_shouldSendDisconnectedMessage() {
- mAdapterEnabled[0] = true;
- mAdapterConnectionState[0] = BluetoothAdapter.STATE_DISCONNECTED;
+ mShadowBluetoothAdapter.setEnabled(true);
+ mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_DISCONNECTED);
mBondedDevices.add(mConnectedDevice);
+ mShadowBluetoothAdapter.setBondedDevices(mBondedDevices);
// This should be ignored
mDeviceConnected[0] = true;
@@ -172,22 +178,23 @@
@Test
public void onBluetoothStateChanged_ConnectedDisabledEnabled_shouldSendDisconnectedSummary() {
- mAdapterEnabled[0] = true;
- mAdapterConnectionState[0] = BluetoothAdapter.STATE_DISCONNECTED;
+ mShadowBluetoothAdapter.setEnabled(true);
+ mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_DISCONNECTED);
mBondedDevices.add(mConnectedDevice);
+ mShadowBluetoothAdapter.setBondedDevices(mBondedDevices);
mDeviceConnected[0] = false;
mSummaryUpdater.register(true);
verify(mListener).onSummaryChanged(mContext.getString(R.string.disconnected));
- mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED;
+ mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_CONNECTED);
mDeviceConnected[0] = true;
mSummaryUpdater.onConnectionStateChanged(null /* device */,
BluetoothAdapter.STATE_CONNECTED);
verify(mListener).onSummaryChanged(
mContext.getString(R.string.bluetooth_connected_summary, DEVICE_NAME));
- mAdapterEnabled[0] = false;
+ mShadowBluetoothAdapter.setEnabled(false);
mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_OFF);
verify(mListener).onSummaryChanged(mContext.getString(R.string.bluetooth_disabled));
@@ -196,7 +203,7 @@
// There should still be only one invocation of disabled message
verify(mListener).onSummaryChanged(mContext.getString(R.string.bluetooth_disabled));
- mAdapterEnabled[0] = true;
+ mShadowBluetoothAdapter.setEnabled(true);
mDeviceConnected[0] = false;
mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_ON);
verify(mListener, times(2)).onSummaryChanged(mContext.getString(R.string.disconnected));
@@ -205,9 +212,10 @@
@Test
public void onConnectionStateChanged_connected_shouldSendConnectedMessage() {
- mAdapterEnabled[0] = true;
- mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED;
+ mShadowBluetoothAdapter.setEnabled(true);
+ mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_CONNECTED);
mBondedDevices.add(mConnectedDevice);
+ mShadowBluetoothAdapter.setBondedDevices(mBondedDevices);
mDeviceConnected[0] = true;
mSummaryUpdater.onConnectionStateChanged(null /* device */,
@@ -219,9 +227,10 @@
@Test
public void onConnectionStateChanged_inconsistentState_shouldSendDisconnectedMessage() {
- mAdapterEnabled[0] = true;
- mAdapterConnectionState[0] = BluetoothAdapter.STATE_DISCONNECTED;
+ mShadowBluetoothAdapter.setEnabled(true);
+ mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_DISCONNECTED);
mBondedDevices.add(mConnectedDevice);
+ mShadowBluetoothAdapter.setBondedDevices(mBondedDevices);
mDeviceConnected[0] = false;
mSummaryUpdater.onConnectionStateChanged(null /* device */,
@@ -232,8 +241,8 @@
@Test
public void onConnectionStateChanged_noBondedDevice_shouldSendDisconnectedMessage() {
- mAdapterEnabled[0] = true;
- mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED;
+ mShadowBluetoothAdapter.setEnabled(true);
+ mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_CONNECTED);
mSummaryUpdater.onConnectionStateChanged(null /* device */,
BluetoothAdapter.STATE_CONNECTED);
@@ -244,8 +253,8 @@
@Test
public void onConnectionStateChanged_connecting_shouldSendConnectingMessage() {
// No need for bonded devices
- mAdapterEnabled[0] = true;
- mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTING;
+ mShadowBluetoothAdapter.setEnabled(true);
+ mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_CONNECTING);
mSummaryUpdater.onConnectionStateChanged(null /* device */,
BluetoothAdapter.STATE_CONNECTING);
@@ -256,8 +265,8 @@
@Test
public void onConnectionStateChanged_disconnecting_shouldSendDisconnectingMessage() {
// No need for bonded devices
- mAdapterEnabled[0] = true;
- mAdapterConnectionState[0] = BluetoothAdapter.STATE_DISCONNECTING;
+ mShadowBluetoothAdapter.setEnabled(true);
+ mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_DISCONNECTING);
mSummaryUpdater.onConnectionStateChanged(null /* device */,
BluetoothAdapter.STATE_DISCONNECTING);
@@ -268,6 +277,7 @@
@Test
public void getConnectedDeviceSummary_hasConnectedDevice_returnOneDeviceSummary() {
mBondedDevices.add(mConnectedDevice);
+ mShadowBluetoothAdapter.setBondedDevices(mBondedDevices);
mDeviceConnected[0] = true;
final String expectedSummary =
mContext.getString(R.string.bluetooth_connected_summary, DEVICE_NAME);
@@ -279,6 +289,8 @@
public void getConnectedDeviceSummary_multipleDevices_returnMultipleDevicesSummary() {
mBondedDevices.add(mConnectedDevice);
mBondedDevices.add(mConnectedKeyBoardDevice);
+ mShadowBluetoothAdapter.setBondedDevices(mBondedDevices);
+
mDeviceConnected[0] = true;
mDeviceConnected[1] = true;
final String expectedSummary =
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceControllerTest.java
index 9f9aaf4..cca9ff0 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceControllerTest.java
@@ -43,8 +43,6 @@
public static final String BLUETOOTH_INFO_STRING = "When Bluetooth is turned on, your device"
+ " can communicate with other nearby Bluetooth devices.";
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private LocalBluetoothManager mBluetoothManager;
@Mock
private RestrictionUtils mRestrictionUtils;
@Mock
@@ -62,7 +60,7 @@
FakeFeatureFactory.setupForTest();
mController =
- new BluetoothSwitchPreferenceController(mContext, mBluetoothManager, mRestrictionUtils,
+ new BluetoothSwitchPreferenceController(mContext, mRestrictionUtils,
mSwitchController, mFooterPreference);
}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/DeviceListPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/DeviceListPreferenceFragmentTest.java
index 7aacd38..c64b904 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/DeviceListPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/DeviceListPreferenceFragmentTest.java
@@ -18,20 +18,20 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.res.Resources;
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
import com.android.settingslib.core.AbstractPreferenceController;
import org.junit.Before;
@@ -40,12 +40,14 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
import java.util.List;
import androidx.preference.Preference;
@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class})
public class DeviceListPreferenceFragmentTest {
private static final String FOOTAGE_MAC_STRING = "Bluetooth mac: xxxx";
@@ -54,8 +56,7 @@
private Resources mResource;
@Mock
private Context mContext;
- @Mock
- private LocalBluetoothAdapter mLocalAdapter;
+
private TestFragment mFragment;
private Preference mMyDevicePreference;
@@ -66,7 +67,7 @@
mFragment = spy(new TestFragment());
doReturn(mContext).when(mFragment).getContext();
doReturn(mResource).when(mFragment).getResources();
- mFragment.mLocalAdapter = mLocalAdapter;
+ mFragment.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mMyDevicePreference = new Preference(RuntimeEnvironment.application);
}
@@ -84,11 +85,11 @@
@Test
public void testEnableDisableScanning_testStateAfterEanbleDisable() {
mFragment.enableScanning();
- verify(mLocalAdapter).startScanning(true);
+ verify(mFragment).startScanning();
assertThat(mFragment.mScanEnabled).isTrue();
mFragment.disableScanning();
- verify(mLocalAdapter).stopScanning();
+ verify(mFragment).stopScanning();
assertThat(mFragment.mScanEnabled).isFalse();
}
@@ -96,21 +97,21 @@
public void testScanningStateChanged_testScanStarted() {
mFragment.enableScanning();
assertThat(mFragment.mScanEnabled).isTrue();
- verify(mLocalAdapter).startScanning(true);
+ verify(mFragment).startScanning();
mFragment.onScanningStateChanged(true);
- verify(mLocalAdapter, times(1)).startScanning(anyBoolean());
+ verify(mFragment, times(1)).startScanning();
}
@Test
public void testScanningStateChanged_testScanFinished() {
// Could happen when last scanning not done while current scan gets enabled
mFragment.enableScanning();
- verify(mLocalAdapter).startScanning(true);
+ verify(mFragment).startScanning();
assertThat(mFragment.mScanEnabled).isTrue();
mFragment.onScanningStateChanged(false);
- verify(mLocalAdapter, times(2)).startScanning(true);
+ verify(mFragment, times(2)).startScanning();
}
@Test
@@ -118,53 +119,53 @@
// Could happen when last scanning not done while current scan gets enabled
mFragment.enableScanning();
assertThat(mFragment.mScanEnabled).isTrue();
- verify(mLocalAdapter).startScanning(true);
+ verify(mFragment).startScanning();
mFragment.onScanningStateChanged(true);
- verify(mLocalAdapter, times(1)).startScanning(anyBoolean());
+ verify(mFragment, times(1)).startScanning();
mFragment.onScanningStateChanged(false);
- verify(mLocalAdapter, times(2)).startScanning(true);
+ verify(mFragment, times(2)).startScanning();
mFragment.onScanningStateChanged(true);
- verify(mLocalAdapter, times(2)).startScanning(anyBoolean());
+ verify(mFragment, times(2)).startScanning();
mFragment.disableScanning();
- verify(mLocalAdapter).stopScanning();
+ verify(mFragment).stopScanning();
mFragment.onScanningStateChanged(false);
- verify(mLocalAdapter, times(2)).startScanning(anyBoolean());
+ verify(mFragment, times(2)).startScanning();
mFragment.onScanningStateChanged(true);
- verify(mLocalAdapter, times(2)).startScanning(anyBoolean());
+ verify(mFragment, times(2)).startScanning();
}
@Test
public void testScanningStateChanged_testScanFinishedAfterDisable() {
mFragment.enableScanning();
- verify(mLocalAdapter).startScanning(true);
+ verify(mFragment).startScanning();
assertThat(mFragment.mScanEnabled).isTrue();
mFragment.disableScanning();
- verify(mLocalAdapter).stopScanning();
+ verify(mFragment).stopScanning();
assertThat(mFragment.mScanEnabled).isFalse();
mFragment.onScanningStateChanged(false);
- verify(mLocalAdapter, times(1)).startScanning(anyBoolean());
+ verify(mFragment, times(1)).startScanning();
}
@Test
public void testScanningStateChanged_testScanStartedAfterDisable() {
mFragment.enableScanning();
- verify(mLocalAdapter).startScanning(true);
+ verify(mFragment).startScanning();
assertThat(mFragment.mScanEnabled).isTrue();
mFragment.disableScanning();
- verify(mLocalAdapter).stopScanning();
+ verify(mFragment).stopScanning();
assertThat(mFragment.mScanEnabled).isFalse();
mFragment.onScanningStateChanged(true);
- verify(mLocalAdapter, times(1)).startScanning(anyBoolean());
+ verify(mFragment, times(1)).startScanning();
}
/**
diff --git a/tests/robotests/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragmentTest.java
index 2533341..49d72fb 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragmentTest.java
@@ -30,7 +30,6 @@
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResourcesImpl;
import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.testutils.FragmentTestUtils;
@@ -51,10 +50,6 @@
public class LocalDeviceNameDialogFragmentTest {
@Mock
- private LocalBluetoothManager mManager;
- @Mock
- private LocalBluetoothAdapter mAdapter;
- @Mock
private InputMethodManager mInputMethodManager;
private Context mContext;
@@ -65,8 +60,6 @@
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
doReturn(mInputMethodManager).when(mContext).getSystemService(Context.INPUT_METHOD_SERVICE);
- ReflectionHelpers.setStaticField(LocalBluetoothManager.class, "sInstance", mManager);
- when(mManager.getBluetoothAdapter()).thenReturn(mAdapter);
mFragment = spy(LocalDeviceNameDialogFragment.newInstance());
when(mFragment.getContext()).thenReturn(mContext);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java
index 0ecd295..c9edc00 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java
@@ -37,6 +37,7 @@
import com.android.settingslib.testutils.FragmentTestUtils;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
@@ -80,6 +81,7 @@
}
@Test
+ @Ignore
public void deviceNameDisplayIsCorrect() {
String deviceName = "ABC Corp Headphones";
AlertDialog dialog = startDialog(deviceName);
@@ -95,6 +97,7 @@
}
@Test
+ @Ignore
public void deviceNameEditSucceeds() {
String deviceNameInitial = "ABC Corp Headphones";
String deviceNameModified = "My Headphones";
@@ -117,6 +120,7 @@
}
@Test
+ @Ignore
public void deviceNameEditThenCancelDoesntRename() {
String deviceNameInitial = "ABC Corp Headphones";
String deviceNameModified = "My Headphones";
diff --git a/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java
index a88d8ff..def8c4d 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java
@@ -68,6 +68,7 @@
doReturn(mContext).when(mDashboardFragment).getContext();
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
when(mLocalManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
+ when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
mBluetoothDeviceUpdater = spy(new SavedBluetoothDeviceUpdater(mDashboardFragment,
mDevicePreferenceCallback, mLocalManager));
@@ -99,6 +100,8 @@
@Test
public void onProfileConnectionStateChanged_deviceConnected_removePreference() {
+ when(mBluetoothDevice.isConnected()).thenReturn(true);
+
mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP);
@@ -107,6 +110,8 @@
@Test
public void onProfileConnectionStateChanged_deviceDisconnected_addPreference() {
+ when(mBluetoothDevice.isConnected()).thenReturn(false);
+
mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.A2DP);
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java
index 4c7cd51..e6ef2d9 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java
@@ -35,7 +35,6 @@
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.testutils.shadow.ShadowBluetoothPan;
-import com.android.settings.testutils.shadow.ShadowLocalBluetoothAdapter;
import com.android.settingslib.widget.FooterPreference;
import com.android.settingslib.widget.FooterPreferenceMixinCompat;
@@ -47,6 +46,7 @@
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowApplication;
import java.util.ArrayList;
@@ -55,8 +55,7 @@
import androidx.preference.PreferenceScreen;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(shadows = {ShadowBluetoothPan.class, ShadowBluetoothAdapter.class,
- ShadowLocalBluetoothAdapter.class})
+@Config(shadows = {ShadowBluetoothPan.class, ShadowBluetoothAdapter.class})
public class DiscoverableFooterPreferenceControllerTest {
private static final String DEVICE_NAME = "device name";
private static final String KEY = "discoverable_footer_preference";
@@ -75,6 +74,7 @@
private DiscoverableFooterPreferenceController mDiscoverableFooterPreferenceController;
private BroadcastReceiver mBluetoothChangedReceiver;
private ShadowApplication mShadowApplication;
+ private ShadowBluetoothAdapter mShadowBluetoothAdapter;
@Before
public void setUp() {
@@ -90,6 +90,7 @@
mAlwaysDiscoverable);
mBluetoothChangedReceiver = mDiscoverableFooterPreferenceController
.mBluetoothChangedReceiver;
+ mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
}
@Test
@@ -135,7 +136,7 @@
@Test
public void onBluetoothStateChanged_bluetoothOn_updateTitle() {
- ShadowLocalBluetoothAdapter.setName(DEVICE_NAME);
+ mShadowBluetoothAdapter.setName(DEVICE_NAME);
sendBluetoothStateChangedIntent(BluetoothAdapter.STATE_ON);
assertThat(mPreference.getTitle()).isEqualTo(generateTitle(DEVICE_NAME));
@@ -143,7 +144,7 @@
@Test
public void onBluetoothStateChanged_bluetoothOff_updateTitle(){
- ShadowLocalBluetoothAdapter.setName(DEVICE_NAME);
+ mShadowBluetoothAdapter.setName(DEVICE_NAME);
sendBluetoothStateChangedIntent(BluetoothAdapter.STATE_OFF);
assertThat(mPreference.getTitle()).isEqualTo(generateTitle(null));
diff --git a/tests/robotests/src/com/android/settings/dashboard/CategoryManagerTest.java b/tests/robotests/src/com/android/settings/dashboard/CategoryManagerTest.java
new file mode 100644
index 0000000..3bb4a65
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/dashboard/CategoryManagerTest.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2016 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.dashboard;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.util.Pair;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.drawer.CategoryKey;
+import com.android.settingslib.drawer.DashboardCategory;
+import com.android.settingslib.drawer.Tile;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class CategoryManagerTest {
+
+ private ActivityInfo mActivityInfo;
+ private Context mContext;
+ private CategoryManager mCategoryManager;
+ private Map<Pair<String, String>, Tile> mTileByComponentCache;
+ private Map<String, DashboardCategory> mCategoryByKeyMap;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ mActivityInfo = new ActivityInfo();
+ mActivityInfo.applicationInfo = new ApplicationInfo();
+ mTileByComponentCache = new HashMap<>();
+ mCategoryByKeyMap = new HashMap<>();
+ mCategoryManager = CategoryManager.get(mContext);
+ }
+
+ @Test
+ public void getInstance_shouldBeSingleton() {
+ assertThat(mCategoryManager).isSameAs(CategoryManager.get(mContext));
+ }
+
+ @Test
+ public void backwardCompatCleanupForCategory_shouldNotChangeCategoryForNewKeys() {
+ final Tile tile1 = new Tile(mActivityInfo);
+ final Tile tile2 = new Tile(mActivityInfo);
+ tile1.category = CategoryKey.CATEGORY_ACCOUNT;
+ tile2.category = CategoryKey.CATEGORY_ACCOUNT;
+ final DashboardCategory category = new DashboardCategory();
+ category.addTile(tile1);
+ category.addTile(tile2);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_ACCOUNT, category);
+ mTileByComponentCache.put(new Pair<>("PACKAGE", "1"), tile1);
+ mTileByComponentCache.put(new Pair<>("PACKAGE", "2"), tile2);
+
+ mCategoryManager.backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
+
+ assertThat(mCategoryByKeyMap.size()).isEqualTo(1);
+ assertThat(mCategoryByKeyMap.get(CategoryKey.CATEGORY_ACCOUNT)).isNotNull();
+ }
+
+ @Test
+ public void backwardCompatCleanupForCategory_shouldNotChangeCategoryForMixedKeys() {
+ final Tile tile1 = new Tile(mActivityInfo);
+ final Tile tile2 = new Tile(mActivityInfo);
+ final String oldCategory = "com.android.settings.category.wireless";
+ tile1.category = CategoryKey.CATEGORY_ACCOUNT;
+ tile2.category = oldCategory;
+ final DashboardCategory category1 = new DashboardCategory();
+ category1.addTile(tile1);
+ final DashboardCategory category2 = new DashboardCategory();
+ category2.addTile(tile2);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_ACCOUNT, category1);
+ mCategoryByKeyMap.put(oldCategory, category2);
+ mTileByComponentCache.put(new Pair<>("PACKAGE", "CLASS1"), tile1);
+ mTileByComponentCache.put(new Pair<>("PACKAGE", "CLASS2"), tile2);
+
+ mCategoryManager.backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
+
+ assertThat(mCategoryByKeyMap.size()).isEqualTo(2);
+ assertThat(
+ mCategoryByKeyMap.get(CategoryKey.CATEGORY_ACCOUNT).getTilesCount()).isEqualTo(1);
+ assertThat(mCategoryByKeyMap.get(oldCategory).getTilesCount()).isEqualTo(1);
+ }
+
+ @Test
+ public void backwardCompatCleanupForCategory_shouldChangeCategoryForOldKeys() {
+ final Tile tile1 = new Tile(mActivityInfo);
+ final String oldCategory = "com.android.settings.category.wireless";
+ tile1.category = oldCategory;
+ final DashboardCategory category1 = new DashboardCategory();
+ category1.addTile(tile1);
+ mCategoryByKeyMap.put(oldCategory, category1);
+ mTileByComponentCache.put(new Pair<>("PACKAGE", "CLASS1"), tile1);
+
+ mCategoryManager.backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
+
+ // Added 1 more category to category map.
+ assertThat(mCategoryByKeyMap.size()).isEqualTo(2);
+ // The new category map has CATEGORY_NETWORK type now, which contains 1 tile.
+ assertThat(
+ mCategoryByKeyMap.get(CategoryKey.CATEGORY_NETWORK).getTilesCount()).isEqualTo(1);
+ // Old category still exists.
+ assertThat(mCategoryByKeyMap.get(oldCategory).getTilesCount()).isEqualTo(1);
+ }
+
+ @Test
+ public void sortCategories_singlePackage_shouldReorderBasedOnPriority() {
+ // Create some fake tiles that are not sorted.
+ final String testPackage = "com.android.test";
+ final DashboardCategory category = new DashboardCategory();
+ final Tile tile1 = new Tile(mActivityInfo);
+ tile1.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class1"));
+ tile1.priority = 100;
+ final Tile tile2 = new Tile(mActivityInfo);
+ tile2.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class2"));
+ tile2.priority = 50;
+ final Tile tile3 = new Tile(mActivityInfo);
+ tile3.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class3"));
+ tile3.priority = 200;
+ category.addTile(tile1);
+ category.addTile(tile2);
+ category.addTile(tile3);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+ // Sort their priorities
+ mCategoryManager.sortCategories(ShadowApplication.getInstance().getApplicationContext(),
+ mCategoryByKeyMap);
+
+ // Verify they are now sorted.
+ assertThat(category.getTile(0)).isSameAs(tile3);
+ assertThat(category.getTile(1)).isSameAs(tile1);
+ assertThat(category.getTile(2)).isSameAs(tile2);
+ }
+
+ @Test
+ public void sortCategories_multiPackage_shouldReorderBasedOnPackageAndPriority() {
+ // Create some fake tiles that are not sorted.
+ final String testPackage1 = "com.android.test1";
+ final String testPackage2 = "com.android.test2";
+ final DashboardCategory category = new DashboardCategory();
+ final Tile tile1 = new Tile(mActivityInfo);
+ tile1.intent =
+ new Intent().setComponent(new ComponentName(testPackage2, "class1"));
+ tile1.priority = 100;
+ final Tile tile2 = new Tile(mActivityInfo);
+ tile2.intent =
+ new Intent().setComponent(new ComponentName(testPackage1, "class2"));
+ tile2.priority = 100;
+ final Tile tile3 = new Tile(mActivityInfo);
+ tile3.intent =
+ new Intent().setComponent(new ComponentName(testPackage1, "class3"));
+ tile3.priority = 50;
+ category.addTile(tile1);
+ category.addTile(tile2);
+ category.addTile(tile3);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+ // Sort their priorities
+ mCategoryManager.sortCategories(mContext, mCategoryByKeyMap);
+
+ // Verify they are now sorted.
+ assertThat(category.getTile(0)).isSameAs(tile2);
+ assertThat(category.getTile(1)).isSameAs(tile1);
+ assertThat(category.getTile(2)).isSameAs(tile3);
+ }
+
+ @Test
+ public void sortCategories_internalPackageTiles_shouldSkipTileForInternalPackage() {
+ // Create some fake tiles that are not sorted.
+ final String testPackage = mContext.getPackageName();
+ final DashboardCategory category = new DashboardCategory();
+ final Tile tile1 = new Tile(mActivityInfo);
+ tile1.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class1"));
+ tile1.priority = 100;
+ final Tile tile2 = new Tile(mActivityInfo);
+ tile2.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class2"));
+ tile2.priority = 100;
+ final Tile tile3 = new Tile(mActivityInfo);
+ tile3.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class3"));
+ tile3.priority = 50;
+ category.addTile(tile1);
+ category.addTile(tile2);
+ category.addTile(tile3);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+ // Sort their priorities
+ mCategoryManager.sortCategories(mContext, mCategoryByKeyMap);
+
+ // Verify the sorting order is not changed
+ assertThat(category.getTile(0)).isSameAs(tile1);
+ assertThat(category.getTile(1)).isSameAs(tile2);
+ assertThat(category.getTile(2)).isSameAs(tile3);
+ }
+
+ @Test
+ public void sortCategories_internalAndExternalPackageTiles_shouldRetainPriorityOrdering() {
+ // Inject one external tile among internal tiles.
+ final String testPackage = mContext.getPackageName();
+ final String testPackage2 = "com.google.test2";
+ final DashboardCategory category = new DashboardCategory();
+ final Tile tile1 = new Tile(mActivityInfo);
+ tile1.intent = new Intent().setComponent(new ComponentName(testPackage, "class1"));
+ tile1.priority = 2;
+ final Tile tile2 = new Tile(mActivityInfo);
+ tile2.intent = new Intent().setComponent(new ComponentName(testPackage, "class2"));
+ tile2.priority = 1;
+ final Tile tile3 = new Tile(mActivityInfo);
+ tile3.intent = new Intent().setComponent(new ComponentName(testPackage2, "class0"));
+ tile3.priority = 0;
+ final Tile tile4 = new Tile(mActivityInfo);
+ tile4.intent = new Intent().setComponent(new ComponentName(testPackage, "class3"));
+ tile4.priority = -1;
+ category.addTile(tile1);
+ category.addTile(tile2);
+ category.addTile(tile3);
+ category.addTile(tile4);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+ // Sort their priorities
+ mCategoryManager.sortCategories(mContext, mCategoryByKeyMap);
+
+ // Verify the sorting order is not changed
+ assertThat(category.getTile(0)).isSameAs(tile1);
+ assertThat(category.getTile(1)).isSameAs(tile2);
+ assertThat(category.getTile(2)).isSameAs(tile3);
+ assertThat(category.getTile(3)).isSameAs(tile4);
+ }
+
+ @Test
+ public void sortCategories_samePriority_internalPackageTileShouldTakePrecedence() {
+ // Inject one external tile among internal tiles with same priority.
+ final String testPackage = mContext.getPackageName();
+ final String testPackage2 = "com.google.test2";
+ final String testPackage3 = "com.abcde.test3";
+ final DashboardCategory category = new DashboardCategory();
+ final Tile tile1 = new Tile(mActivityInfo);
+ tile1.intent = new Intent().setComponent(new ComponentName(testPackage2, "class1"));
+ tile1.priority = 1;
+ final Tile tile2 = new Tile(mActivityInfo);
+ tile2.intent = new Intent().setComponent(new ComponentName(testPackage, "class2"));
+ tile2.priority = 1;
+ final Tile tile3 = new Tile(mActivityInfo);
+ tile3.intent = new Intent().setComponent(new ComponentName(testPackage3, "class3"));
+ tile3.priority = 1;
+ category.addTile(tile1);
+ category.addTile(tile2);
+ category.addTile(tile3);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+ // Sort their priorities
+ mCategoryManager.sortCategories(mContext, mCategoryByKeyMap);
+
+ // Verify the sorting order is internal first, follow by package name ordering
+ assertThat(category.getTile(0)).isSameAs(tile2);
+ assertThat(category.getTile(1)).isSameAs(tile3);
+ assertThat(category.getTile(2)).isSameAs(tile1);
+ }
+
+ @Test
+ public void filterTiles_noDuplicate_noChange() {
+ // Create some unique tiles
+ final String testPackage = mContext.getPackageName();
+ final DashboardCategory category = new DashboardCategory();
+ final Tile tile1 = new Tile(mActivityInfo);
+ tile1.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class1"));
+ tile1.priority = 100;
+ final Tile tile2 = new Tile(mActivityInfo);
+ tile2.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class2"));
+ tile2.priority = 100;
+ final Tile tile3 = new Tile(mActivityInfo);
+ tile3.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class3"));
+ tile3.priority = 50;
+ category.addTile(tile1);
+ category.addTile(tile2);
+ category.addTile(tile3);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+ mCategoryManager.filterDuplicateTiles(mCategoryByKeyMap);
+
+ assertThat(category.getTilesCount()).isEqualTo(3);
+ }
+
+ @Test
+ public void filterTiles_hasDuplicate_shouldOnlyKeepUniqueTiles() {
+ // Create tiles pointing to same intent.
+ final String testPackage = mContext.getPackageName();
+ final DashboardCategory category = new DashboardCategory();
+ final Tile tile1 = new Tile(mActivityInfo);
+ tile1.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class1"));
+ tile1.priority = 100;
+ final Tile tile2 = new Tile(mActivityInfo);
+ tile2.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class1"));
+ tile2.priority = 100;
+ final Tile tile3 = new Tile(mActivityInfo);
+ tile3.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class1"));
+ tile3.priority = 50;
+ category.addTile(tile1);
+ category.addTile(tile2);
+ category.addTile(tile3);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+ mCategoryManager.filterDuplicateTiles(mCategoryByKeyMap);
+
+ assertThat(category.getTilesCount()).isEqualTo(1);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
index f6786b8..c823433 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
@@ -16,6 +16,7 @@
package com.android.settings.dashboard;
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;
@@ -28,6 +29,7 @@
import android.app.PendingIntent;
import android.content.Context;
+import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
@@ -39,6 +41,8 @@
import android.view.WindowManager;
import android.widget.TextView;
+import androidx.recyclerview.widget.RecyclerView;
+
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.dashboard.conditional.Condition;
@@ -63,8 +67,6 @@
import java.util.ArrayList;
import java.util.List;
-import androidx.recyclerview.widget.RecyclerView;
-
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = SettingsShadowResources.SettingsShadowTheme.class)
public class DashboardAdapterTest {
@@ -79,6 +81,7 @@
private Resources mResources;
@Mock
private WindowManager mWindowManager;
+ private ActivityInfo mActivityInfo;
private FakeFeatureFactory mFactory;
private DashboardAdapter mDashboardAdapter;
private List<Condition> mConditionList;
@@ -87,6 +90,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
mFactory = FakeFeatureFactory.setupForTest();
+ mActivityInfo = new ActivityInfo();
when(mFactory.dashboardFeatureProvider.shouldTintIcon()).thenReturn(true);
when(mContext.getSystemService(Context.WINDOW_SERVICE)).thenReturn(mWindowManager);
@@ -123,7 +127,6 @@
adapter.onBindSuggestion(holder, 0);
- final DashboardData dashboardData = adapter.mDashboardData;
reset(adapter); // clear interactions tracking
final Suggestion suggestionToRemove = suggestions.get(1);
@@ -154,12 +157,12 @@
@Test
public void onSuggestionClosed_notInSuggestionList_shouldNotUpdateSuggestionList() {
final DashboardAdapter adapter =
- spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
- null /* conditions */, null /* suggestionControllerMixin */,
- null /* lifecycle */));
+ spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
+ null /* conditions */, null /* suggestionControllerMixin */,
+ null /* lifecycle */));
final List<Suggestion> suggestions = makeSuggestionsV2("pkg1");
adapter.setSuggestions(suggestions);
- final DashboardData dashboardData = adapter.mDashboardData;
+
reset(adapter); // clear interactions tracking
adapter.onSuggestionClosed(mock(Suggestion.class));
@@ -198,10 +201,12 @@
final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
final DashboardAdapter.DashboardItemHolder holder =
new DashboardAdapter.DashboardItemHolder(view);
- final Tile tile = new Tile();
- tile.icon = Icon.createWithResource(context, R.drawable.ic_settings);
+ final Tile tile = spy(new Tile(mActivityInfo));
+ doReturn(Icon.createWithResource(context, R.drawable.ic_settings))
+ .when(tile).getIcon(context);
final IconCache iconCache = mock(IconCache.class);
- when(iconCache.getIcon(tile.icon)).thenReturn(context.getDrawable(R.drawable.ic_settings));
+ when(iconCache.getIcon(tile.getIcon(context)))
+ .thenReturn(context.getDrawable(R.drawable.ic_settings));
mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
@@ -217,9 +222,9 @@
final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
final DashboardAdapter.DashboardItemHolder holder =
new DashboardAdapter.DashboardItemHolder(view);
- final Tile tile = new Tile();
- tile.icon = Icon.createWithResource(context, R.drawable.ic_settings);
- when(tile.icon.getResPackage()).thenReturn("another.package");
+ final Tile tile = spy(new Tile(mActivityInfo));
+ final Icon icon = Icon.createWithResource(context, R.drawable.ic_settings);
+ doReturn(icon).when(tile).getIcon(context);
final IconCache iconCache = new IconCache(context);
@@ -230,7 +235,8 @@
doReturn("another.package").when(context).getPackageName();
mDashboardAdapter.onBindTile(holder, tile);
- assertThat(iconCache.getIcon(tile.icon)).isInstanceOf(RoundedHomepageIcon.class);
+ assertThat(iconCache.getIcon(tile.getIcon(context)))
+ .isInstanceOf(RoundedHomepageIcon.class);
}
@Test
@@ -239,11 +245,12 @@
final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
final DashboardAdapter.DashboardItemHolder holder =
new DashboardAdapter.DashboardItemHolder(view);
- final Tile tile = new Tile();
+ final Tile tile = spy(new Tile(mActivityInfo));
tile.metaData = new Bundle();
tile.metaData.putInt(TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT,
R.color.memory_critical);
- tile.icon = Icon.createWithResource(context, R.drawable.ic_settings);
+ doReturn(Icon.createWithResource(context, R.drawable.ic_settings))
+ .when(tile).getIcon(context);
final IconCache iconCache = new IconCache(context);
mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
@@ -252,7 +259,8 @@
doReturn("another.package").when(context).getPackageName();
mDashboardAdapter.onBindTile(holder, tile);
- final RoundedHomepageIcon homepageIcon = (RoundedHomepageIcon) iconCache.getIcon(tile.icon);
+ final RoundedHomepageIcon homepageIcon = (RoundedHomepageIcon) iconCache.getIcon(
+ tile.getIcon(context));
assertThat(homepageIcon.mBackgroundColor)
.isEqualTo(RuntimeEnvironment.application.getColor(R.color.memory_critical));
}
@@ -263,12 +271,12 @@
final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
final DashboardAdapter.DashboardItemHolder holder =
new DashboardAdapter.DashboardItemHolder(view);
- final Tile tile = new Tile();
- tile.icon = mock(Icon.class);
- when(tile.icon.getResPackage()).thenReturn("another.package");
+ final Tile tile = spy(new Tile(mActivityInfo));
+ doReturn(mock(Icon.class)).when(tile).getIcon(context);
+ when(tile.getIcon(context).getResPackage()).thenReturn("another.package");
final IconCache iconCache = mock(IconCache.class);
- when(iconCache.getIcon(tile.icon)).thenReturn(mock(RoundedHomepageIcon.class));
+ when(iconCache.getIcon(tile.getIcon(context))).thenReturn(mock(RoundedHomepageIcon.class));
mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
@@ -276,7 +284,8 @@
mDashboardAdapter.onBindTile(holder, tile);
- verify(iconCache, never()).updateIcon(eq(tile.icon), any(RoundedHomepageIcon.class));
+ verify(iconCache, never()).updateIcon(eq(tile.getIcon(context)),
+ any(RoundedHomepageIcon.class));
}
private List<Suggestion> makeSuggestionsV2(String... pkgNames) {
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
index bf1e0ff..963411d 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
@@ -19,7 +19,9 @@
import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_PROFILE;
import static com.android.settingslib.drawer.TileUtils.PROFILE_ALL;
import static com.android.settingslib.drawer.TileUtils.PROFILE_PRIMARY;
+
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
@@ -35,6 +37,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
@@ -43,6 +46,8 @@
import android.os.UserHandle;
import android.os.UserManager;
+import androidx.preference.Preference;
+
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
@@ -53,7 +58,6 @@
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
import com.android.settingslib.drawer.CategoryKey;
-import com.android.settingslib.drawer.CategoryManager;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.drawer.TileUtils;
@@ -74,8 +78,6 @@
import java.util.ArrayList;
-import androidx.preference.Preference;
-
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = ShadowUserManager.class)
public class DashboardFeatureProviderImplTest {
@@ -91,15 +93,17 @@
private FakeFeatureFactory mFeatureFactory;
private Context mContext;
+ private ActivityInfo mActivityInfo;
private DashboardFeatureProviderImpl mImpl;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
+ mActivityInfo = new ActivityInfo();
doReturn(mPackageManager).when(mContext).getPackageManager();
when(mPackageManager.resolveActivity(any(Intent.class), anyInt()))
- .thenReturn(new ResolveInfo());
+ .thenReturn(new ResolveInfo());
mFeatureFactory = FakeFeatureFactory.setupForTest();
mImpl = new DashboardFeatureProviderImpl(mContext);
}
@@ -112,10 +116,11 @@
@Test
public void bindPreference_shouldBindAllData() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile();
+ final Tile tile = spy(new Tile(mActivityInfo));
tile.title = "title";
tile.summary = "summary";
- tile.icon = Icon.createWithBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565));
+ doReturn(Icon.createWithBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565)))
+ .when(tile).getIcon(any(Context.class));
tile.metaData = new Bundle();
tile.metaData.putString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS, "HI");
tile.priority = 10;
@@ -133,7 +138,7 @@
@Test
public void bindPreference_noFragmentMetadata_shouldBindIntent() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.metaData = new Bundle();
tile.priority = 10;
tile.intent = new Intent();
@@ -150,7 +155,7 @@
@Test
public void bindPreference_noFragmentMetadata_shouldBindToProfileSelector() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.metaData = new Bundle();
tile.userHandle = new ArrayList<>();
tile.userHandle.add(mock(UserHandle.class));
@@ -171,7 +176,7 @@
@Test
public void bindPreference_noFragmentMetadataSingleUser_shouldBindToDirectLaunchIntent() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.metaData = new Bundle();
tile.userHandle = new ArrayList<>();
tile.userHandle.add(mock(UserHandle.class));
@@ -196,7 +201,7 @@
@Test
public void bindPreference_toInternalSettingActivity_shouldBindToDirectLaunchIntentAndNotLog() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.metaData = new Bundle();
tile.userHandle = new ArrayList<>();
tile.userHandle.add(mock(UserHandle.class));
@@ -232,7 +237,7 @@
@Test
public void bindPreference_withNullKeyNullPriority_shouldGenerateKeyAndPriority() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
@@ -245,7 +250,7 @@
@Test
public void bindPreference_noSummary_shouldSetSummaryToPlaceholder() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
@@ -258,7 +263,7 @@
@Test
public void bindPreference_hasSummary_shouldSetSummary() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.summary = "test";
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
@@ -272,7 +277,7 @@
@Config(shadows = {ShadowTileUtils.class, ShadowThreadUtils.class})
public void bindPreference_hasSummaryUri_shouldLoadSummaryFromContentProvider() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
tile.metaData = new Bundle();
@@ -288,7 +293,7 @@
@Test
public void bindPreference_withNullKeyTileKey_shouldUseTileKey() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.key = "key";
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
@@ -302,7 +307,7 @@
@Config(shadows = {ShadowTileUtils.class, ShadowThreadUtils.class})
public void bindPreference_withIconUri_shouldLoadIconFromContentProvider() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.key = "key";
tile.intent = new Intent();
tile.intent.setComponent(
@@ -319,7 +324,7 @@
public void bindPreference_withBaseOrder_shouldOffsetPriority() {
final int baseOrder = 100;
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.metaData = new Bundle();
tile.priority = 10;
mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
@@ -332,7 +337,7 @@
public void bindPreference_withOrderMetadata_shouldUseOrderInMetadata() {
final Preference preference = new Preference(RuntimeEnvironment.application);
final int testOrder = -30;
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.metaData = new Bundle();
tile.metaData.putInt(mImpl.META_DATA_KEY_ORDER, testOrder);
tile.priority = 10;
@@ -345,7 +350,7 @@
@Test
public void bindPreference_invalidOrderMetadata_shouldIgnore() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.metaData = new Bundle();
tile.metaData.putString(mImpl.META_DATA_KEY_ORDER, "hello");
tile.priority = 10;
@@ -359,7 +364,7 @@
public void bindPreference_withIntentActionMetadata_shouldSetLaunchAction() {
Activity activity = Robolectric.buildActivity(Activity.class).get();
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.key = "key";
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
@@ -385,7 +390,7 @@
Activity activity = Robolectric.buildActivity(Activity.class).get();
final ShadowApplication application = ShadowApplication.getInstance();
final Preference preference = new Preference(application.getApplicationContext());
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.key = "key";
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
@@ -432,7 +437,7 @@
mImpl = new DashboardFeatureProviderImpl(mActivity);
ReflectionHelpers.setField(mImpl, "mCategoryManager", mCategoryManager);
final DashboardCategory category = new DashboardCategory();
- category.addTile(new Tile());
+ category.addTile(new Tile(mActivityInfo));
when(mCategoryManager
.getTilesByCategory(any(Context.class), eq(CategoryKey.CATEGORY_HOMEPAGE)))
.thenReturn(category);
@@ -462,7 +467,7 @@
@Test
public void openTileIntent_profileSelectionDialog_shouldShow() {
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.metaData = new Bundle();
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
@@ -473,13 +478,13 @@
mImpl.openTileIntent(mActivity, tile);
verify(mActivity, never())
- .startActivityForResult(any(Intent.class), eq(0));
+ .startActivityForResult(any(Intent.class), eq(0));
verify(mActivity).getFragmentManager();
}
@Test
public void openTileIntent_profileSelectionDialog_explicitMetadataShouldShow() {
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.metaData = new Bundle();
tile.metaData.putString(META_DATA_KEY_PROFILE, PROFILE_ALL);
tile.intent = new Intent();
@@ -491,12 +496,13 @@
mImpl.openTileIntent(mActivity, tile);
verify(mActivity, never())
- .startActivityForResult(any(Intent.class), eq(0));
+ .startActivityForResult(any(Intent.class), eq(0));
verify(mActivity).getFragmentManager();
}
+
@Test
public void openTileIntent_profileSelectionDialog_shouldNotShow() {
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.metaData = new Bundle();
tile.metaData.putString(META_DATA_KEY_PROFILE, PROFILE_PRIMARY);
tile.intent = new Intent();
@@ -508,7 +514,7 @@
mImpl.openTileIntent(mActivity, tile);
verify(mActivity)
- .startActivityForResult(any(Intent.class), eq(0));
+ .startActivityForResult(any(Intent.class), eq(0));
verify(mActivity, never()).getFragmentManager();
}
}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
index 3a2f00f..8c1b99b 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
@@ -16,7 +16,10 @@
package com.android.settings.dashboard;
import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -27,9 +30,14 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.graphics.drawable.Icon;
import android.os.Bundle;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -50,15 +58,12 @@
import java.util.ArrayList;
import java.util.List;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceManager;
-import androidx.preference.PreferenceScreen;
-
@RunWith(SettingsRobolectricTestRunner.class)
public class DashboardFragmentTest {
@Mock
private FakeFeatureFactory mFakeFeatureFactory;
+ private ActivityInfo mActivityInfo;
private DashboardCategory mDashboardCategory;
private Context mContext;
private TestFragment mTestFragment;
@@ -67,9 +72,10 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
+ mActivityInfo = new ActivityInfo();
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
mDashboardCategory = new DashboardCategory();
- mDashboardCategory.addTile(new Tile());
+ mDashboardCategory.addTile(new Tile(mActivityInfo));
mTestFragment = new TestFragment(RuntimeEnvironment.application);
when(mFakeFeatureFactory.dashboardFeatureProvider
.getTilesForCategory(nullable(String.class)))
@@ -177,8 +183,8 @@
@Test
public void tintTileIcon_hasMetadata_shouldReturnIconTintableMetadata() {
- final Tile tile = new Tile();
- tile.icon = mock(Icon.class);
+ final Tile tile = spy(new Tile(mActivityInfo));
+ doReturn(mock(Icon.class)).when(tile).getIcon(any(Context.class));
final Bundle metaData = new Bundle();
tile.metaData = metaData;
@@ -191,7 +197,7 @@
@Test
public void tintTileIcon_noIcon_shouldReturnFalse() {
- final Tile tile = new Tile();
+ final Tile tile = new Tile(mActivityInfo);
tile.metaData = new Bundle();
assertThat(mTestFragment.tintTileIcon(tile)).isFalse();
@@ -199,12 +205,12 @@
@Test
public void tintTileIcon_noMetadata_shouldReturnPackageNameCheck() {
- final Tile tile = new Tile();
- tile.icon = mock(Icon.class);
+ final Tile tile = spy(new Tile(mActivityInfo));
+ doReturn(mock(Icon.class)).when(tile).getIcon(any(Context.class));
final Intent intent = new Intent();
tile.intent = intent;
intent.setComponent(
- new ComponentName(RuntimeEnvironment.application.getPackageName(), "TestClass"));
+ new ComponentName(RuntimeEnvironment.application.getPackageName(), "TestClass"));
assertThat(mTestFragment.tintTileIcon(tile)).isFalse();
intent.setComponent(new ComponentName("OtherPackage", "TestClass"));
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardItemAnimatorTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardItemAnimatorTest.java
index ee19654..b1d2031 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardItemAnimatorTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardItemAnimatorTest.java
@@ -18,9 +18,12 @@
import static com.google.common.truth.Truth.assertThat;
+import android.content.pm.ActivityInfo;
import android.view.View;
import android.widget.TextView;
+import androidx.recyclerview.widget.RecyclerView;
+
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.drawer.Tile;
@@ -29,8 +32,6 @@
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
-import androidx.recyclerview.widget.RecyclerView;
-
@RunWith(SettingsRobolectricTestRunner.class)
public class DashboardItemAnimatorTest {
@@ -41,20 +42,20 @@
public void SetUp() {
mDashboardItemAnimator = new DashboardItemAnimator();
mViewHolder = new ViewHolder(new TextView(RuntimeEnvironment.application));
- mViewHolder.itemView.setTag(new Tile());
+ mViewHolder.itemView.setTag(new Tile(new ActivityInfo()));
}
@Test
public void testAnimateChange_NoPositionChange_NoPendingAnimation() {
final boolean hasPendingAnimation =
- mDashboardItemAnimator.animateChange(mViewHolder, mViewHolder, 0, 1, 0, 1);
+ mDashboardItemAnimator.animateChange(mViewHolder, mViewHolder, 0, 1, 0, 1);
assertThat(hasPendingAnimation).isFalse();
}
@Test
public void testAnimateChange_HasPositionChange_HasPendingAnimation() {
final boolean hasPendingAnimation =
- mDashboardItemAnimator.animateChange(mViewHolder, mViewHolder, 0, 0, 1, 1);
+ mDashboardItemAnimator.animateChange(mViewHolder, mViewHolder, 0, 0, 1, 1);
assertThat(hasPendingAnimation).isTrue();
}
@@ -64,7 +65,7 @@
mDashboardItemAnimator.animateMove(mViewHolder, 0, 0, 1, 1);
final boolean hasPendingAnimation =
- mDashboardItemAnimator.animateChange(mViewHolder, mViewHolder, 0, 1, 0, 1);
+ mDashboardItemAnimator.animateChange(mViewHolder, mViewHolder, 0, 1, 0, 1);
assertThat(hasPendingAnimation).isFalse();
}
diff --git a/tests/robotests/src/com/android/settings/dashboard/SummaryLoaderTest.java b/tests/robotests/src/com/android/settings/dashboard/SummaryLoaderTest.java
index 0fac2fc..053bc9c 100644
--- a/tests/robotests/src/com/android/settings/dashboard/SummaryLoaderTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/SummaryLoaderTest.java
@@ -17,11 +17,13 @@
package com.android.settings.dashboard;
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.app.Activity;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -51,7 +53,7 @@
MockitoAnnotations.initMocks(this);
mFeatureFactory = FakeFeatureFactory.setupForTest();
- mTile = new Tile();
+ mTile = new Tile(new ActivityInfo());
mTile.summary = SUMMARY_1;
mCallbackInvoked = false;
@@ -84,7 +86,7 @@
public void testUpdateSummaryToCache_hasCache_shouldUpdate() {
final String testSummary = "test_summary";
final DashboardCategory category = new DashboardCategory();
- final Tile tile = new Tile();
+ final Tile tile = new Tile(new ActivityInfo());
tile.key = "123";
tile.intent = new Intent();
category.addTile(tile);
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
index b1c256f..ffd25c3 100644
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
@@ -17,23 +17,21 @@
package com.android.settings.dashboard.suggestions;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
+
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
import android.content.Context;
+import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.service.settings.suggestions.Suggestion;
-import android.util.Pair;
import com.android.internal.logging.nano.MetricsProto;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
@@ -45,7 +43,6 @@
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.RuntimeEnvironment;
@@ -58,7 +55,7 @@
@Config(shadows = ShadowSecureSettings.class)
public class SuggestionFeatureProviderImplTest {
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ @Mock
private Context mContext;
@Mock
private SuggestionControllerMixinCompat mSuggestionControllerMixin;
@@ -71,6 +68,7 @@
@Mock
private FingerprintManager mFingerprintManager;
+ private ActivityInfo mActivityInfo;
private FakeFeatureFactory mFactory;
private SuggestionFeatureProviderImpl mProvider;
@@ -78,6 +76,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
mFactory = FakeFeatureFactory.setupForTest();
+ mActivityInfo = new ActivityInfo();
when(mContext.getPackageManager()).thenReturn(mPackageManager);
// Explicit casting to object due to MockitoCast bug
when((Object) mContext.getSystemService(FingerprintManager.class))
@@ -145,31 +144,16 @@
@Test
public void filterExclusiveSuggestions_shouldOnlyKeepFirst3() {
final List<Tile> suggestions = new ArrayList<>();
- suggestions.add(new Tile());
- suggestions.add(new Tile());
- suggestions.add(new Tile());
- suggestions.add(new Tile());
- suggestions.add(new Tile());
- suggestions.add(new Tile());
- suggestions.add(new Tile());
+ suggestions.add(new Tile(mActivityInfo));
+ suggestions.add(new Tile(mActivityInfo));
+ suggestions.add(new Tile(mActivityInfo));
+ suggestions.add(new Tile(mActivityInfo));
+ suggestions.add(new Tile(mActivityInfo));
+ suggestions.add(new Tile(mActivityInfo));
+ suggestions.add(new Tile(mActivityInfo));
mProvider.filterExclusiveSuggestions(suggestions);
assertThat(suggestions).hasSize(3);
}
-
- @Test
- public void testGetSmartSuggestionEnabledTaggedData_disabled() {
- assertThat(mProvider.getLoggingTaggedData(mContext)).asList().containsExactly(
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
- }
-
- @Test
- public void testGetSmartSuggestionEnabledTaggedData_enabled() {
- final SuggestionFeatureProvider provider = spy(mProvider);
- when(provider.isSmartSuggestionEnabled(any(Context.class))).thenReturn(true);
-
- assertThat(provider.getLoggingTaggedData(mContext)).asList().containsExactly(
- Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 1));
- }
}
diff --git a/tests/robotests/src/com/android/settings/development/autofill/AutofillLoggingLevelPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/autofill/AutofillLoggingLevelPreferenceControllerTest.java
new file mode 100644
index 0000000..b9da71d
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/autofill/AutofillLoggingLevelPreferenceControllerTest.java
@@ -0,0 +1,144 @@
+/*
+ * 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.development.autofill;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.RemoteException;
+import android.view.autofill.AutofillManager;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+import androidx.preference.PreferenceScreen;
+import androidx.preference.ListPreference;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class AutofillLoggingLevelPreferenceControllerTest {
+
+ private static final int IDX_OFF = 0;
+ private static final int IDX_DEBUG = 1;
+ private static final int IDX_VERBOSE = 2;
+
+ @Mock
+ private ListPreference mPreference;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+
+ private Context mContext;
+ private AutofillLoggingLevelPreferenceController mController;
+ private AutofillTestingHelper mHelper;
+
+ private String[] mListValues;
+ private String[] mListSummaries;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this); // TODO: use @Rule
+ mContext = RuntimeEnvironment.application;
+ mHelper = new AutofillTestingHelper(mContext);
+ final Resources resources = mContext.getResources();
+ mListValues = resources.getStringArray(R.array.autofill_logging_level_values);
+ mListSummaries = resources.getStringArray(R.array.autofill_logging_level_entries);
+ mController = new AutofillLoggingLevelPreferenceController(mContext);
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
+ .thenReturn(mPreference);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_differentPreferenceKey_shouldNotTrigger()
+ throws Exception {
+ when(mPreference.getKey()).thenReturn("SomeRandomKey");
+
+ mHelper.setLoggingLevel(108);
+
+ assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
+
+ assertThat(mHelper.getLoggingLevel()).isEqualTo(108);
+ }
+
+ @Test
+ public void onPreferenceChange_off() throws Exception {
+ mHelper.setLoggingLevel(108);
+
+ mController.onPreferenceChange(mPreference, mListValues[IDX_OFF]);
+
+ assertThat(mHelper.getLoggingLevel()).isEqualTo(AutofillManager.NO_LOGGING);
+ }
+
+ @Test
+ public void onPreferenceChange_debug() throws Exception {
+ mHelper.setLoggingLevel(108);
+
+ mController.onPreferenceChange(mPreference, mListValues[IDX_DEBUG]);
+
+ assertThat(mHelper.getLoggingLevel())
+ .isEqualTo(AutofillManager.FLAG_ADD_CLIENT_DEBUG);
+ }
+
+ @Test
+ public void onPreferenceChange_verbose() throws Exception {
+ mHelper.setLoggingLevel(108);
+
+ mController.onPreferenceChange(mPreference, mListValues[IDX_VERBOSE]);
+
+ assertThat(mHelper.getLoggingLevel())
+ .isEqualTo(AutofillManager.FLAG_ADD_CLIENT_VERBOSE);
+ }
+
+ @Test
+ public void onSettingsChange_off() throws Exception {
+ mHelper.setLoggingLevel(AutofillManager.NO_LOGGING);
+
+ mController.updateState(mPreference);
+
+ verify(mPreference).setValue(mListValues[IDX_OFF]);
+ verify(mPreference).setSummary(mListSummaries[IDX_OFF]);
+ }
+
+ @Test
+ public void onSettingsChange_debug() throws Exception {
+ mHelper.setLoggingLevel(AutofillManager.FLAG_ADD_CLIENT_DEBUG);
+
+ mController.updateState(mPreference);
+
+ verify(mPreference).setValue(mListValues[IDX_DEBUG]);
+ verify(mPreference).setSummary(mListSummaries[IDX_DEBUG]);
+ }
+
+ @Test
+ public void onSettingsChange_verbose() throws Exception {
+ mHelper.setLoggingLevel(AutofillManager.FLAG_ADD_CLIENT_VERBOSE);
+
+ mController.updateState(mPreference);
+
+ verify(mPreference).setValue(mListValues[IDX_VERBOSE]);
+ verify(mPreference).setSummary(mListSummaries[IDX_VERBOSE]);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/development/autofill/AutofillResetOptionsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/autofill/AutofillResetOptionsPreferenceControllerTest.java
new file mode 100644
index 0000000..e560a83
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/autofill/AutofillResetOptionsPreferenceControllerTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.development.autofill;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.RemoteException;
+import android.view.autofill.AutofillManager;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class AutofillResetOptionsPreferenceControllerTest {
+
+ @Mock
+ private SwitchPreference mPreference;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+
+ private Context mContext;
+ private AutofillResetOptionsPreferenceController mController;
+ private AutofillTestingHelper mHelper;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this); // TODO: use @Rule
+ mContext = RuntimeEnvironment.application;
+ mHelper = new AutofillTestingHelper(mContext);
+ mController = new AutofillResetOptionsPreferenceController(mContext);
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
+ .thenReturn(mPreference);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_differentPreferenceKey_shouldNotReset() throws Exception {
+ when(mPreference.getKey()).thenReturn("SomeRandomKey");
+
+ mHelper.setLoggingLevel(4);
+ mHelper.setMaxPartitionsSize(8);
+ mHelper.setMaxVisibleDatasets(15);
+
+ assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
+
+ assertThat(mHelper.getLoggingLevel()).isEqualTo(4);
+ assertThat(mHelper.getMaxPartitionsSize()).isEqualTo(8);
+ assertThat(mHelper.getMaxVisibleDatasets()).isEqualTo(15);
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_correctPreferenceKey_shouldReset() throws Exception {
+ when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
+
+ mHelper.setMaxPartitionsSize(16);
+ mHelper.setMaxVisibleDatasets(23);
+ mHelper.setLoggingLevel(42);
+
+ assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
+
+ assertThat(mHelper.getLoggingLevel())
+ .isEqualTo(AutofillManager.DEFAULT_LOGGING_LEVEL);
+ assertThat(mHelper.getMaxPartitionsSize())
+ .isEqualTo(AutofillManager.DEFAULT_MAX_PARTITIONS_SIZE);
+ assertThat(mHelper.getMaxVisibleDatasets())
+ .isEqualTo(0);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/development/autofill/AutofillTestingHelper.java b/tests/robotests/src/com/android/settings/development/autofill/AutofillTestingHelper.java
new file mode 100644
index 0000000..59090bc
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/autofill/AutofillTestingHelper.java
@@ -0,0 +1,62 @@
+/*
+ * 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.development.autofill;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+
+final class AutofillTestingHelper {
+ private final ContentResolver mResolver;
+
+ public AutofillTestingHelper(Context context) {
+ mResolver = context.getContentResolver();
+ }
+
+ public void setLoggingLevel(int max) {
+ setGlobal(Settings.Global.AUTOFILL_LOGGING_LEVEL, max);
+ }
+
+ public void setMaxPartitionsSize(int max) {
+ setGlobal(Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE, max);
+ }
+
+ public void setMaxVisibleDatasets(int level) {
+ setGlobal(Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS, level);
+ }
+
+ public int getLoggingLevel() throws SettingNotFoundException {
+ return getGlobal(Settings.Global.AUTOFILL_LOGGING_LEVEL);
+ }
+
+ public int getMaxPartitionsSize() throws SettingNotFoundException {
+ return getGlobal(Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE);
+ }
+
+ public int getMaxVisibleDatasets() throws SettingNotFoundException {
+ return getGlobal(Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS);
+ }
+
+ private void setGlobal(String key, int value) {
+ Settings.Global.putInt(mResolver, key, value);
+ }
+
+ private int getGlobal(String key) throws SettingNotFoundException {
+ return Settings.Global.getInt(mResolver, key);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/DeviceNamePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/DeviceNamePreferenceControllerTest.java
index 0e6bf8d..3ca06aa 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/DeviceNamePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/DeviceNamePreferenceControllerTest.java
@@ -16,13 +16,14 @@
package com.android.settings.deviceinfo;
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
@@ -30,36 +31,33 @@
import android.provider.Settings;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.widget.ValidatedEditTextPreference;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Answers;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
import androidx.preference.PreferenceScreen;
@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class})
public class DeviceNamePreferenceControllerTest {
private static final String TESTING_STRING = "Testing";
@Mock
- private LocalBluetoothAdapter mBluetoothAdapter;
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private LocalBluetoothManager mBluetoothManager;
- @Mock
private WifiManager mWifiManager;
@Mock
private PreferenceScreen mScreen;
private ValidatedEditTextPreference mPreference;
private DeviceNamePreferenceController mController;
private Context mContext;
+ private BluetoothAdapter mBluetoothAdapter;
@Before
@@ -69,14 +67,24 @@
shadowApplication.setSystemService(Context.WIFI_SERVICE, mWifiManager);
mContext = shadowApplication.getApplicationContext();
mPreference = new ValidatedEditTextPreference(mContext);
- when(mBluetoothManager.getBluetoothAdapter()).thenReturn(mBluetoothAdapter);
when(mScreen.findPreference(anyString())).thenReturn(mPreference);
final WifiConfiguration configuration = new WifiConfiguration();
configuration.SSID = "test-ap";
when(mWifiManager.getWifiApConfiguration()).thenReturn(configuration);
mController = new DeviceNamePreferenceController(mContext);
- mController.setLocalBluetoothManager(mBluetoothManager);
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ }
+
+ @Test
+ public void getAvailibilityStatus_availableByDefault() {
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+ }
+
+ @Test
+ @Config(qualifiers = "mcc999")
+ public void getAvailabilityStatus_unsupportedWhenSet() {
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
@@ -89,7 +97,6 @@
Settings.Global.putString(
mContext.getContentResolver(), Settings.Global.DEVICE_NAME, "Test");
mController = new DeviceNamePreferenceController(mContext);
- mController.setLocalBluetoothManager(mBluetoothManager);
assertThat(mController.getSummary()).isEqualTo("Test");
}
@@ -118,7 +125,7 @@
mController.displayPreference(mScreen);
mController.onPreferenceChange(mPreference, TESTING_STRING);
- verify(mBluetoothAdapter).setName(eq(TESTING_STRING));
+ assertThat(mBluetoothAdapter.getName()).isEqualTo(TESTING_STRING);
}
@Test
@@ -141,10 +148,11 @@
@Test
public void setDeviceName_ignoresIfCancelPressed() {
+ forceAcceptDeviceName();
mController.displayPreference(mScreen);
mController.onPreferenceChange(mPreference, TESTING_STRING);
- verify(mBluetoothAdapter, never()).setName(eq(TESTING_STRING));
+ assertThat(mBluetoothAdapter.getName()).isEqualTo(TESTING_STRING);
}
private void forceAcceptDeviceName() {
diff --git a/tests/robotests/src/com/android/settings/display/BatteryPercentagePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/BatteryPercentagePreferenceControllerTest.java
index 673abb0..140fc5c 100644
--- a/tests/robotests/src/com/android/settings/display/BatteryPercentagePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/BatteryPercentagePreferenceControllerTest.java
@@ -32,13 +32,15 @@
@RunWith(SettingsRobolectricTestRunner.class)
public class BatteryPercentagePreferenceControllerTest {
+ private static final String PREF_KEY = "battery_percentage";
+
private Context mContext;
private BatteryPercentagePreferenceController mController;
@Before
public void setup() {
mContext = RuntimeEnvironment.application;
- mController = new BatteryPercentagePreferenceController(mContext);
+ mController = new BatteryPercentagePreferenceController(mContext, PREF_KEY);
}
private int getPercentageSetting() {
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryDatabaseManagerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryDatabaseManagerTest.java
index 58bfe0e..41e77e9 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryDatabaseManagerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryDatabaseManagerTest.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.text.format.DateUtils;
+import android.util.SparseLongArray;
import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
import com.android.settings.fuelgauge.batterytip.AppInfo;
@@ -88,7 +89,7 @@
}
@Test
- public void testAllFunctions() {
+ public void allAnomalyFunctions() {
mBatteryDatabaseManager.insertAnomaly(UID_NEW, PACKAGE_NAME_NEW, TYPE_NEW,
AnomalyDatabaseHelper.State.NEW, NOW);
mBatteryDatabaseManager.insertAnomaly(UID_OLD, PACKAGE_NAME_OLD, TYPE_OLD,
@@ -113,7 +114,7 @@
}
@Test
- public void testUpdateAnomalies_updateSuccessfully() {
+ public void updateAnomalies_updateSuccessfully() {
mBatteryDatabaseManager.insertAnomaly(UID_NEW, PACKAGE_NAME_NEW, TYPE_NEW,
AnomalyDatabaseHelper.State.NEW, NOW);
mBatteryDatabaseManager.insertAnomaly(UID_OLD, PACKAGE_NAME_OLD, TYPE_OLD,
@@ -138,7 +139,7 @@
}
@Test
- public void testQueryAnomalies_removeDuplicateByUid() {
+ public void queryAnomalies_removeDuplicateByUid() {
mBatteryDatabaseManager.insertAnomaly(UID_NEW, PACKAGE_NAME_NEW, TYPE_NEW,
AnomalyDatabaseHelper.State.NEW, NOW);
mBatteryDatabaseManager.insertAnomaly(UID_NEW, PACKAGE_NAME_NEW, TYPE_OLD,
@@ -149,4 +150,28 @@
AnomalyDatabaseHelper.State.NEW);
assertThat(newAppInfos).containsExactly(mCombinedAppInfo);
}
+
+ @Test
+ public void allActionFunctions() {
+ final long timestamp = System.currentTimeMillis();
+ mBatteryDatabaseManager.insertAction(AnomalyDatabaseHelper.ActionType.RESTRICTION, UID_OLD,
+ PACKAGE_NAME_OLD, 0);
+ mBatteryDatabaseManager.insertAction(AnomalyDatabaseHelper.ActionType.RESTRICTION, UID_OLD,
+ PACKAGE_NAME_OLD, 1);
+ mBatteryDatabaseManager.insertAction(AnomalyDatabaseHelper.ActionType.RESTRICTION, UID_NEW,
+ PACKAGE_NAME_NEW, timestamp);
+
+ final SparseLongArray timeArray = mBatteryDatabaseManager.queryActionTime(
+ AnomalyDatabaseHelper.ActionType.RESTRICTION);
+ assertThat(timeArray.size()).isEqualTo(2);
+ assertThat(timeArray.get(UID_OLD)).isEqualTo(1);
+ assertThat(timeArray.get(UID_NEW)).isEqualTo(timestamp);
+
+ mBatteryDatabaseManager.deleteAction(AnomalyDatabaseHelper.ActionType.RESTRICTION, UID_NEW,
+ PACKAGE_NAME_NEW);
+ final SparseLongArray recentTimeArray = mBatteryDatabaseManager.queryActionTime(
+ AnomalyDatabaseHelper.ActionType.RESTRICTION);
+ assertThat(recentTimeArray.size()).isEqualTo(1);
+ assertThat(timeArray.get(UID_OLD)).isEqualTo(1);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
index 91cb078..337b950 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
@@ -36,6 +36,7 @@
import com.android.settings.R;
import com.android.settings.applications.LayoutPreference;
+import com.android.settings.core.BasePreferenceController;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.SettingsShadowResourcesImpl;
@@ -68,6 +69,7 @@
})
public class BatteryHeaderPreferenceControllerTest {
+ private static final String PREF_KEY = "battery_header";
private static final int BATTERY_LEVEL = 60;
private static final String TIME_LEFT = "2h30min";
private static final String BATTERY_STATUS = "Charging";
@@ -121,8 +123,11 @@
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- mController = new BatteryHeaderPreferenceController(
- mContext, mActivity, mPreferenceFragment, mLifecycle);
+ mController = new BatteryHeaderPreferenceController(mContext, PREF_KEY);
+ mLifecycle.addObserver(mController);
+ mController.setActivity(mActivity);
+ mController.setFragment(mPreferenceFragment);
+ mController.setLifecycle(mLifecycle);
mController.mBatteryMeterView = mBatteryMeterView;
mController.mBatteryPercentText = mBatteryPercentText;
mController.mSummary1 = mSummary;
@@ -207,4 +212,10 @@
assertThat(mBatteryMeterView.getPowerSave()).isEqualTo(value);
}
}
+
+ @Test
+ public void getAvailabilityStatus_returnAvailableUnsearchable() {
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(
+ BasePreferenceController.AVAILABLE_UNSEARCHABLE);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
index df34b78..b274492 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
@@ -51,9 +51,12 @@
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;
+import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
import com.android.settings.fuelgauge.batterytip.AnomalyInfo;
+import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowThreadUtils;
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
import org.junit.Before;
@@ -148,6 +151,8 @@
private ApplicationInfo mLowApplicationInfo;
@Mock
private PowerWhitelistBackend mPowerWhitelistBackend;
+ @Mock
+ private BatteryDatabaseManager mBatteryDatabaseManager;
private AnomalyInfo mAnomalyInfo;
private BatteryUtils mBatteryUtils;
private FakeFeatureFactory mFeatureFactory;
@@ -225,6 +230,8 @@
.thenReturn(TOTAL_BATTERY_USAGE + BATTERY_SCREEN_USAGE);
when(mBatteryStatsHelper.getStats().getDischargeAmount(anyInt()))
.thenReturn(DISCHARGE_AMOUNT);
+ BatteryDatabaseManager.setUpForTest(mBatteryDatabaseManager);
+ ShadowThreadUtils.setIsMainThread(true);
}
@Test
@@ -570,6 +577,23 @@
}
@Test
+ public void testSetForceAppStandby_restrictApp_recordTime() {
+ mBatteryUtils.setForceAppStandby(UID, HIGH_SDK_PACKAGE, AppOpsManager.MODE_IGNORED);
+
+ verify(mBatteryDatabaseManager).insertAction(
+ eq(AnomalyDatabaseHelper.ActionType.RESTRICTION), eq(UID),
+ eq(HIGH_SDK_PACKAGE), anyLong());
+ }
+
+ @Test
+ public void testSetForceAppStandby_unrestrictApp_deleteTime() {
+ mBatteryUtils.setForceAppStandby(UID, HIGH_SDK_PACKAGE, AppOpsManager.MODE_ALLOWED);
+
+ verify(mBatteryDatabaseManager).deleteAction(AnomalyDatabaseHelper.ActionType.RESTRICTION,
+ UID, HIGH_SDK_PACKAGE);
+ }
+
+ @Test
public void testIsForceAppStandbyEnabled_enabled_returnTrue() {
when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID,
PACKAGE_NAME)).thenReturn(AppOpsManager.MODE_IGNORED);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
index 97e272b..68d9994 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
@@ -223,21 +223,6 @@
}
@Test
- public void preferenceControllers_getPreferenceKeys_existInPreferenceScreen() {
- final Context context = RuntimeEnvironment.application;
- final PowerUsageSummary fragment = new PowerUsageSummary();
- final List<String> preferenceScreenKeys =
- XmlTestUtils.getKeysFromPreferenceXml(context, fragment.getPreferenceScreenResId());
- final List<String> preferenceKeys = new ArrayList<>();
-
- for (AbstractPreferenceController controller : fragment.createPreferenceControllers(context)) {
- preferenceKeys.add(controller.getPreferenceKey());
- }
-
- assertThat(preferenceScreenKeys).containsAllIn(preferenceKeys);
- }
-
- @Test
public void restartBatteryTipLoader() {
//TODO: add policy logic here when BatteryTipPolicy is implemented
doReturn(mLoaderManager).when(mFragment).getLoaderManager();
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/RestrictedAppDetailsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/RestrictedAppDetailsTest.java
index b9ed509..7219f18 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/RestrictedAppDetailsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/RestrictedAppDetailsTest.java
@@ -28,10 +28,13 @@
import android.os.Bundle;
import android.os.UserHandle;
import android.util.IconDrawableFactory;
+import android.util.SparseLongArray;
import com.android.settings.SettingsActivity;
import com.android.settings.core.InstrumentedPreferenceFragment;
+import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
import com.android.settings.fuelgauge.batterytip.AppInfo;
+import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
import com.android.settings.fuelgauge.batterytip.BatteryTipDialogFragment;
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
@@ -52,6 +55,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.CheckBoxPreference;
@@ -76,6 +80,8 @@
private IconDrawableFactory mIconDrawableFactory;
@Mock
private InstrumentedPreferenceFragment mFragment;
+ @Mock
+ private BatteryDatabaseManager mBatteryDatabaseManager;
private PreferenceManager mPreferenceManager;
private RestrictedAppDetails mRestrictedAppDetails;
private Context mContext;
@@ -98,12 +104,14 @@
doReturn(mPreferenceManager).when(mRestrictedAppDetails).getPreferenceManager();
doReturn(mContext).when(mFragment).getContext();
+ doReturn(mContext).when(mRestrictedAppDetails).getContext();
mRestrictedAppDetails.mPackageManager = mPackageManager;
mRestrictedAppDetails.mIconDrawableFactory = mIconDrawableFactory;
mRestrictedAppDetails.mAppInfos = new ArrayList<>();
mRestrictedAppDetails.mAppInfos.add(mAppInfo);
mRestrictedAppDetails.mRestrictedAppListGroup = spy(new PreferenceCategory(mContext));
mRestrictedAppDetails.mBatteryUtils = spy(new BatteryUtils(mContext));
+ mRestrictedAppDetails.mBatteryDatabaseManager = mBatteryDatabaseManager;
doReturn(mPreferenceManager).when(
mRestrictedAppDetails.mRestrictedAppListGroup).getPreferenceManager();
@@ -118,6 +126,10 @@
doReturn(APP_NAME).when(mPackageManager).getApplicationLabel(mApplicationInfo);
doReturn(true).when(mRestrictedAppDetails.mBatteryUtils).isForceAppStandbyEnabled(UID,
PACKAGE_NAME);
+ final SparseLongArray timestampArray = new SparseLongArray();
+ timestampArray.put(UID, System.currentTimeMillis() - TimeUnit.HOURS.toMillis(5));
+ doReturn(timestampArray).when(mBatteryDatabaseManager)
+ .queryActionTime(AnomalyDatabaseHelper.ActionType.RESTRICTION);
mRestrictedAppDetails.refreshUi();
@@ -126,6 +138,7 @@
(CheckBoxPreference) mRestrictedAppDetails.mRestrictedAppListGroup.getPreference(0);
assertThat(preference.getTitle()).isEqualTo(APP_NAME);
assertThat(preference.isChecked()).isTrue();
+ assertThat(preference.getSummary()).isEqualTo("Restricted 5 hours ago");
}
@Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceControllerTest.java
index 7e9ffeb..e7aafef 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceControllerTest.java
@@ -31,6 +31,7 @@
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
+import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
import com.android.settings.fuelgauge.batterytip.tips.SummaryTip;
@@ -100,8 +101,7 @@
mNewBatteryTips = new ArrayList<>();
mNewBatteryTips.add(new SummaryTip(BatteryTip.StateType.INVISIBLE, AVERAGE_TIME_MS));
- mBatteryTipPreferenceController = new BatteryTipPreferenceController(mContext, KEY_PREF,
- mSettingsActivity, mFragment, mBatteryTipListener);
+ mBatteryTipPreferenceController = buildBatteryTipPreferenceController();
mBatteryTipPreferenceController.mPreferenceGroup = mPreferenceGroup;
mBatteryTipPreferenceController.mPrefContext = mContext;
}
@@ -139,8 +139,7 @@
final Bundle bundle = new Bundle();
mBatteryTipPreferenceController.saveInstanceState(bundle);
- final BatteryTipPreferenceController controller = new BatteryTipPreferenceController(
- mContext, KEY_PREF, mSettingsActivity, mFragment, mBatteryTipListener);
+ final BatteryTipPreferenceController controller = buildBatteryTipPreferenceController();
controller.mPreferenceGroup = mPreferenceGroup;
controller.mPrefContext = mContext;
controller.restoreInstanceState(bundle);
@@ -154,8 +153,7 @@
// Battery tip list is null at this time
mBatteryTipPreferenceController.saveInstanceState(bundle);
- final BatteryTipPreferenceController controller = new BatteryTipPreferenceController(
- mContext, KEY_PREF, mSettingsActivity, mFragment, mBatteryTipListener);
+ final BatteryTipPreferenceController controller = buildBatteryTipPreferenceController();
// Should not crash
controller.restoreInstanceState(bundle);
@@ -176,6 +174,12 @@
verify(mBatteryTipListener).onBatteryTipHandled(mBatteryTip);
}
+ @Test
+ public void getAvailabilityStatus_returnAvailableUnsearchable() {
+ assertThat(mBatteryTipPreferenceController.getAvailabilityStatus()).isEqualTo(
+ BasePreferenceController.AVAILABLE_UNSEARCHABLE);
+ }
+
private void assertOnlyContainsSummaryTip(final PreferenceGroup preferenceGroup) {
assertThat(preferenceGroup.getPreferenceCount()).isEqualTo(1);
@@ -185,4 +189,14 @@
assertThat(preference.getSummary()).isEqualTo(
mContext.getString(R.string.battery_tip_summary_summary));
}
+
+ private BatteryTipPreferenceController buildBatteryTipPreferenceController() {
+ final BatteryTipPreferenceController controller = new BatteryTipPreferenceController(
+ mContext, KEY_PREF);
+ controller.setActivity(mSettingsActivity);
+ controller.setFragment(mFragment);
+ controller.setBatteryTipListener(mBatteryTipListener);
+
+ return controller;
+ }
}
diff --git a/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java
index 187f0dc..d6310ab 100644
--- a/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java
@@ -26,6 +26,7 @@
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.wifi.WifiMasterSwitchPreferenceController;
import com.android.settingslib.drawer.CategoryKey;
import org.junit.Before;
@@ -66,6 +67,8 @@
@Test
public void summaryProviderSetListening_hasMobileAndHotspot_shouldReturnMobileSummary() {
+ final WifiMasterSwitchPreferenceController wifiPreferenceController =
+ mock(WifiMasterSwitchPreferenceController.class);
final MobileNetworkPreferenceController mobileNetworkPreferenceController =
mock(MobileNetworkPreferenceController.class);
final TetherPreferenceController tetherPreferenceController =
@@ -74,12 +77,14 @@
final SummaryLoader summaryLoader = mock(SummaryLoader.class);
final SummaryLoader.SummaryProvider provider =
new NetworkDashboardFragment.SummaryProvider(mContext, summaryLoader,
- mobileNetworkPreferenceController, tetherPreferenceController);
+ wifiPreferenceController, mobileNetworkPreferenceController,
+ tetherPreferenceController);
provider.setListening(false);
verifyZeroInteractions(summaryLoader);
+ when(wifiPreferenceController.isAvailable()).thenReturn(true);
when(mobileNetworkPreferenceController.isAvailable()).thenReturn(true);
when(tetherPreferenceController.isAvailable()).thenReturn(true);
@@ -90,6 +95,8 @@
@Test
public void summaryProviderSetListening_noMobileOrHotspot_shouldReturnSimpleSummary() {
+ final WifiMasterSwitchPreferenceController wifiPreferenceController =
+ mock(WifiMasterSwitchPreferenceController.class);
final MobileNetworkPreferenceController mobileNetworkPreferenceController =
mock(MobileNetworkPreferenceController.class);
final TetherPreferenceController tetherPreferenceController =
@@ -98,12 +105,14 @@
final SummaryLoader summaryLoader = mock(SummaryLoader.class);
final SummaryLoader.SummaryProvider provider =
new NetworkDashboardFragment.SummaryProvider(mContext, summaryLoader,
- mobileNetworkPreferenceController, tetherPreferenceController);
+ wifiPreferenceController, mobileNetworkPreferenceController,
+ tetherPreferenceController);
provider.setListening(false);
verifyZeroInteractions(summaryLoader);
+ when(wifiPreferenceController.isAvailable()).thenReturn(true);
when(mobileNetworkPreferenceController.isAvailable()).thenReturn(false);
when(tetherPreferenceController.isAvailable()).thenReturn(false);
diff --git a/tests/robotests/src/com/android/settings/notification/ChargingSoundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ChargingSoundPreferenceControllerTest.java
index d54ef6f..2796049 100644
--- a/tests/robotests/src/com/android/settings/notification/ChargingSoundPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ChargingSoundPreferenceControllerTest.java
@@ -17,13 +17,14 @@
package com.android.settings.notification;
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
-import android.provider.Settings.Global;
+import android.provider.Settings.Secure;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -80,7 +81,7 @@
@Test
public void displayPreference_chargingSoundEnabled_shouldCheckedPreference() {
- Global.putInt(mContentResolver, Global.CHARGING_SOUNDS_ENABLED, 1);
+ Secure.putInt(mContentResolver, Secure.CHARGING_SOUNDS_ENABLED, 1);
mController.displayPreference(mScreen);
@@ -89,7 +90,7 @@
@Test
public void displayPreference_chargingSoundDisabled_shouldUncheckedPreference() {
- Global.putInt(mContentResolver, Global.CHARGING_SOUNDS_ENABLED, 0);
+ Secure.putInt(mContentResolver, Secure.CHARGING_SOUNDS_ENABLED, 0);
mController.displayPreference(mScreen);
@@ -102,7 +103,7 @@
mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, true);
- assertThat(Global.getInt(mContentResolver, Global.CHARGING_SOUNDS_ENABLED, 1))
+ assertThat(Secure.getInt(mContentResolver, Secure.CHARGING_SOUNDS_ENABLED, 1))
.isEqualTo(1);
}
@@ -112,7 +113,7 @@
mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, false);
- assertThat(Global.getInt(mContentResolver, Global.CHARGING_SOUNDS_ENABLED, 1))
+ assertThat(Secure.getInt(mContentResolver, Secure.CHARGING_SOUNDS_ENABLED, 1))
.isEqualTo(0);
}
}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeDurationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeDurationPreferenceControllerTest.java
index b748bcb..bbb2142 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModeDurationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeDurationPreferenceControllerTest.java
@@ -78,8 +78,8 @@
@Test
public void updateState_DurationForever() {
- Settings.Global.putInt(mContentResolver, Settings.Global.ZEN_DURATION,
- Settings.Global.ZEN_DURATION_FOREVER);
+ Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
+ Settings.Secure.ZEN_DURATION_FOREVER);
final Preference mockPref = mock(Preference.class);
mController.updateState(mockPref);
@@ -88,8 +88,8 @@
@Test
public void updateState_DurationPrompt() {
- Settings.Global.putInt(mContentResolver, Settings.Global.ZEN_DURATION,
- Settings.Global.ZEN_DURATION_PROMPT);
+ Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
+ Settings.Secure.ZEN_DURATION_PROMPT);
final Preference mockPref = mock(Preference.class);
mController.updateState(mockPref);
@@ -100,7 +100,7 @@
@Test
public void updateState_DurationCustom() {
int zenDuration = 45;
- Settings.Global.putInt(mContentResolver, Settings.Global.ZEN_DURATION,
+ Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
zenDuration);
final Preference mockPref = mock(Preference.class);
mController.updateState(mockPref);
diff --git a/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java b/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java
index 5846833..5b031aa 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java
@@ -177,16 +177,16 @@
setShowSettingsSuggestion(true);
setWithinTimeThreshold(true);
assertThat(isSuggestionComplete(mContext)).isTrue();
- assertThat(Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.ZEN_SETTINGS_UPDATED, -1)).isEqualTo(1);
+ assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ZEN_SETTINGS_UPDATED, -1)).isEqualTo(1);
}
private void setZenUpdated(boolean updated) {
int zenUpdated = updated ? 1 : 0;
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.ZEN_SETTINGS_UPDATED, zenUpdated);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ZEN_SETTINGS_UPDATED, zenUpdated);
}
private void setWithinTimeThreshold(boolean withinTime) {
@@ -208,8 +208,8 @@
showZenSuggestion = 1;
}
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.SHOW_ZEN_SETTINGS_SUGGESTION, showZenSuggestion);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.SHOW_ZEN_SETTINGS_SUGGESTION, showZenSuggestion);
}
private SharedPreferences getSharedPreferences() {
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java
index 24a45da..369cb3c 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java
@@ -18,19 +18,54 @@
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.provider.Settings.Global;
import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
+import androidx.fragment.app.FragmentActivity;
+
+import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
public class ChooseLockGenericTest {
+ @After
+ public void tearDown() {
+ Global.putInt(RuntimeEnvironment.application.getContentResolver(),
+ Global.DEVICE_PROVISIONED, 1);
+ }
+
+ @Test
+ @Config(shadows = SettingsShadowResources.SettingsShadowTheme.class)
+ public void onCreate_deviceNotProvisioned_shouldFinishActivity() {
+ final Context context = RuntimeEnvironment.application;
+ Global.putInt(context.getContentResolver(), Global.DEVICE_PROVISIONED, 0);
+ final FragmentActivity activity = mock(FragmentActivity.class);
+ when(activity.getContentResolver()).thenReturn(context.getContentResolver());
+ when(activity.getTheme()).thenReturn(context.getTheme());
+
+ final ChooseLockGenericFragment fragment = spy(new ChooseLockGenericFragment());
+ when(fragment.getActivity()).thenReturn(activity);
+ when(fragment.getArguments()).thenReturn(Bundle.EMPTY);
+
+ fragment.onCreate(Bundle.EMPTY);
+ verify(activity).finish();
+ }
+
@Test
public void onActivityResult_nullIntentData_shouldNotCrash() {
ChooseLockGenericFragment fragment = spy(new ChooseLockGenericFragment());
diff --git a/tests/robotests/src/com/android/settings/search/actionbar/SearchMenuControllerTest.java b/tests/robotests/src/com/android/settings/search/actionbar/SearchMenuControllerTest.java
index b36769d..394d5f4 100644
--- a/tests/robotests/src/com/android/settings/search/actionbar/SearchMenuControllerTest.java
+++ b/tests/robotests/src/com/android/settings/search/actionbar/SearchMenuControllerTest.java
@@ -17,11 +17,14 @@
package com.android.settings.search.actionbar;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
+import android.content.Context;
import android.os.Bundle;
+import android.provider.Settings.Global;
import android.view.Menu;
import android.view.MenuItem;
@@ -35,6 +38,7 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
@RunWith(SettingsRobolectricTestRunner.class)
public class SearchMenuControllerTest {
@@ -43,12 +47,16 @@
private Menu mMenu;
private TestPreferenceFragment mPreferenceHost;
private ObservableFragment mHost;
+ private Context mContext;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mHost = new ObservableFragment();
+ mContext = RuntimeEnvironment.application;
+ mHost = spy(new ObservableFragment());
+ when(mHost.getContext()).thenReturn(mContext);
mPreferenceHost = new TestPreferenceFragment();
+ Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 1);
when(mMenu.add(Menu.NONE, Menu.NONE, 0 /* order */, R.string.search_menu))
.thenReturn(mock(MenuItem.class));
@@ -81,9 +89,23 @@
verifyZeroInteractions(mMenu);
}
+ @Test
+ public void init_deviceNotProvisioned_shouldNotAddMenu() {
+ Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 0);
+ SearchMenuController.init(mHost);
+ mHost.getSettingsLifecycle().onCreateOptionsMenu(mMenu, null /* inflater */);
+
+ verifyZeroInteractions(mMenu);
+ }
+
private static class TestPreferenceFragment extends ObservablePreferenceFragment {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
}
+
+ @Override
+ public Context getContext() {
+ return RuntimeEnvironment.application;
+ }
}
}
diff --git a/tests/robotests/src/com/android/settings/security/ChangeScreenLockPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/ChangeScreenLockPreferenceControllerTest.java
index 6cc1704..fda5942 100644
--- a/tests/robotests/src/com/android/settings/security/ChangeScreenLockPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/ChangeScreenLockPreferenceControllerTest.java
@@ -17,17 +17,28 @@
package com.android.settings.security;
import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.os.UserManager;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import androidx.preference.PreferenceScreen;
+import androidx.preference.PreferenceViewHolder;
import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowUtils;
+import com.android.settings.widget.GearPreference;
import org.junit.Before;
import org.junit.Test;
@@ -47,10 +58,15 @@
private UserManager mUserManager;
@Mock
private DevicePolicyManager mDevicePolicyManager;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
private Context mContext;
private FakeFeatureFactory mFeatureFactory;
private ChangeScreenLockPreferenceController mController;
+ private View mGearView;
+ private GearPreference mGearPreference;
+ private PreferenceViewHolder mPreferenceViewHolder;
@Before
public void setUp() {
@@ -75,4 +91,149 @@
public void testDeviceAdministrators_ifDisabled_shouldNotBeShown() {
assertThat(mController.isAvailable()).isFalse();
}
+
+ @Test
+ public void updateState_notSecureDisableKeyguard_shouldNotShowGear() {
+ when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false);
+ when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true);
+ mockGearPreferenceAndViewHolder();
+
+ showPreference();
+
+ assertThat(mGearView.getVisibility()).isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void updateState_notSecureDisableKeyguard_summaryShouldShowOff() {
+ when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false);
+ when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true);
+ mockGearPreferenceAndViewHolder();
+
+ showPreference();
+
+ assertThat(mGearPreference.getSummary())
+ .isEqualTo(mContext.getString(R.string.unlock_set_unlock_mode_off));
+ }
+
+ @Test
+ public void updateState_notSecureWithSwipeKeyguard_shouldNotShowGear() {
+ when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false);
+ when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false);
+ mockGearPreferenceAndViewHolder();
+
+ showPreference();
+
+ assertThat(mGearView.getVisibility()).isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void updateState_notSecureWithSwipeKeyguard_summaryShouldShowSwipe() {
+ when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false);
+ when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false);
+ mockGearPreferenceAndViewHolder();
+
+ showPreference();
+
+ assertThat(mGearPreference.getSummary())
+ .isEqualTo(mContext.getString(R.string.unlock_set_unlock_mode_none));
+ }
+
+ @Test
+ public void updateState_secureWithPinKeyguard_shouldShowGear() {
+ when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+ when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false);
+ doReturn(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX).when(mLockPatternUtils)
+ .getKeyguardStoredPasswordQuality(anyInt());
+ mockGearPreferenceAndViewHolder();
+
+ showPreference();
+
+ assertThat(mGearView.getVisibility()).isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void updateState_secureWithPinKeyguard_summaryShouldShowPin() {
+ when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+ when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false);
+ doReturn(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX).when(mLockPatternUtils)
+ .getKeyguardStoredPasswordQuality(anyInt());
+
+ mockGearPreferenceAndViewHolder();
+
+ showPreference();
+
+ assertThat(mGearPreference.getSummary())
+ .isEqualTo(mContext.getString(R.string.unlock_set_unlock_mode_pin));
+ }
+
+ @Test
+ public void updateState_secureWithPasswordKeyguard_shouldShowGear() {
+ when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+ when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false);
+ doReturn(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX).when(mLockPatternUtils)
+ .getKeyguardStoredPasswordQuality(anyInt());
+ mockGearPreferenceAndViewHolder();
+
+ showPreference();
+
+ assertThat(mGearView.getVisibility()).isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void updateState_secureWithPasswordKeyguard_summaryShouldShowPassword() {
+ when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+ when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false);
+ doReturn(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX).when(mLockPatternUtils)
+ .getKeyguardStoredPasswordQuality(anyInt());
+ mockGearPreferenceAndViewHolder();
+
+ showPreference();
+
+ assertThat(mGearPreference.getSummary())
+ .isEqualTo(mContext.getString(R.string.unlock_set_unlock_mode_password));
+ }
+
+ @Test
+ public void updateState_secureWithPatternKeyguard_shouldShowGear() {
+ when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+ when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false);
+ doReturn(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING).when(mLockPatternUtils)
+ .getKeyguardStoredPasswordQuality(anyInt());
+ mockGearPreferenceAndViewHolder();
+
+ showPreference();
+
+ assertThat(mGearView.getVisibility()).isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void updateState_secureWithPatternKeyguard_summaryShouldShowPattern() {
+ when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+ when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false);
+ doReturn(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING).when(mLockPatternUtils)
+ .getKeyguardStoredPasswordQuality(anyInt());
+ mockGearPreferenceAndViewHolder();
+
+ showPreference();
+
+ assertThat(mGearPreference.getSummary())
+ .isEqualTo(mContext.getString(R.string.unlock_set_unlock_mode_pattern));
+ }
+
+ private void mockGearPreferenceAndViewHolder() {
+ mGearPreference = new GearPreference(mContext, null);
+ mGearView = new View(mContext);
+ PreferenceViewHolder viewHolder = PreferenceViewHolder.createInstanceForTests(
+ LayoutInflater.from(mContext).inflate(
+ mGearPreference.getLayoutResource(), null, false));
+ mPreferenceViewHolder = spy(viewHolder);
+ doReturn(mGearView).when(mPreferenceViewHolder).findViewById(R.id.settings_button);
+ when(mPreferenceScreen.findPreference(anyString())).thenReturn(mGearPreference);
+ }
+
+ private void showPreference() {
+ mController.displayPreference(mPreferenceScreen);
+ mController.updateState(mGearPreference);
+ mGearPreference.onBindViewHolder(mPreferenceViewHolder);
+ }
}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/security/SecuritySettingsTest.java b/tests/robotests/src/com/android/settings/security/SecuritySettingsTest.java
index 7d93ec2..f3cc459 100644
--- a/tests/robotests/src/com/android/settings/security/SecuritySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/security/SecuritySettingsTest.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.pm.PackageManager;
+import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import com.android.settings.R;
@@ -44,6 +45,8 @@
private SummaryLoader mSummaryLoader;
@Mock
private FingerprintManager mFingerprintManager;
+ @Mock
+ private FaceManager mFaceManager;
private SecuritySettings.SummaryProvider mSummaryProvider;
@Before
@@ -51,7 +54,8 @@
MockitoAnnotations.initMocks(this);
when(mContext.getSystemService(Context.FINGERPRINT_SERVICE))
.thenReturn(mFingerprintManager);
-
+ when(mContext.getSystemService(Context.FACE_SERVICE))
+ .thenReturn(mFaceManager);
mSummaryProvider = new SecuritySettings.SummaryProvider(mContext, mSummaryLoader);
}
@@ -63,7 +67,20 @@
}
@Test
+ public void testSummaryProvider_hasFace_hasStaticSummary() {
+ when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE))
+ .thenReturn(true);
+ when(mFaceManager.isHardwareDetected()).thenReturn(true);
+
+ mSummaryProvider.setListening(true);
+
+ verify(mContext).getString(R.string.security_dashboard_summary_face);
+ }
+
+ @Test
public void testSummaryProvider_hasFingerPrint_hasStaticSummary() {
+ when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE))
+ .thenReturn(false);
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
.thenReturn(true);
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
@@ -74,9 +91,11 @@
}
@Test
- public void testSummaryProvider_noFpFeature_shouldSetSummaryWithNoFingerprint() {
+ public void testSummaryProvider_noFpFeature_shouldSetSummaryWithNoBiometrics() {
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
.thenReturn(false);
+ when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE))
+ .thenReturn(false);
mSummaryProvider.setListening(true);
@@ -84,7 +103,9 @@
}
@Test
- public void testSummaryProvider_noFpHardware_shouldSetSummaryWithNoFingerprint() {
+ public void testSummaryProvider_noFpHardware_shouldSetSummaryWithNoBiometrics() {
+ when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE))
+ .thenReturn(false);
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
.thenReturn(true);
when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
@@ -93,4 +114,29 @@
verify(mContext).getString(R.string.security_dashboard_summary_no_fingerprint);
}
+
+ @Test
+ public void testSummaryProvider_noFaceFeature_shouldSetSummaryWithNoBiometrics() {
+ when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
+ .thenReturn(false);
+ when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE))
+ .thenReturn(false);
+
+ mSummaryProvider.setListening(true);
+
+ verify(mContext).getString(R.string.security_dashboard_summary_no_fingerprint);
+ }
+
+ @Test
+ public void testSummaryProvider_noFaceHardware_shouldSetSummaryWithNoBiometrics() {
+ when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE))
+ .thenReturn(true);
+ when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
+ .thenReturn(false);
+ when(mFaceManager.isHardwareDetected()).thenReturn(false);
+
+ mSummaryProvider.setListening(true);
+
+ verify(mContext).getString(R.string.security_dashboard_summary_no_fingerprint);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
index 56df664..39d4417 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -23,7 +23,6 @@
import com.android.settings.accounts.AccountFeatureProvider;
import com.android.settings.applications.ApplicationFeatureProvider;
-import com.android.settings.bluetooth.BluetoothFeatureProvider;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
@@ -62,7 +61,6 @@
public final SuggestionFeatureProvider suggestionsFeatureProvider;
public final UserFeatureProvider userFeatureProvider;
public final AssistGestureFeatureProvider assistGestureFeatureProvider;
- public final BluetoothFeatureProvider bluetoothFeatureProvider;
public final AccountFeatureProvider mAccountFeatureProvider;
public final DeviceIndexFeatureProvider deviceIndexFeatureProvider;
@@ -104,7 +102,6 @@
suggestionsFeatureProvider = mock(SuggestionFeatureProvider.class);
userFeatureProvider = mock(UserFeatureProvider.class);
assistGestureFeatureProvider = mock(AssistGestureFeatureProvider.class);
- bluetoothFeatureProvider = mock(BluetoothFeatureProvider.class);
slicesFeatureProvider = mock(SlicesFeatureProvider.class);
mAccountFeatureProvider = mock(AccountFeatureProvider.class);
deviceIndexFeatureProvider = mock(DeviceIndexFeatureProvider.class);
@@ -176,11 +173,6 @@
}
@Override
- public BluetoothFeatureProvider getBluetoothFeatureProvider(Context context) {
- return bluetoothFeatureProvider;
- }
-
- @Override
public AssistGestureFeatureProvider getAssistGestureFeatureProvider() {
return assistGestureFeatureProvider;
}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowBluetoothAdapter.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowBluetoothAdapter.java
index 2bd2ec3..91afb87 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowBluetoothAdapter.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowBluetoothAdapter.java
@@ -26,6 +26,11 @@
@Implements(value = BluetoothAdapter.class, inheritImplementationMethods = true)
public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBluetoothAdapter {
+
+ private String mName;
+ private int mScanMode;
+ private int mState;
+
/**
* Do nothing, implement it to avoid null pointer error inside BluetoothAdapter
*/
@@ -33,4 +38,32 @@
public List<Integer> getSupportedProfiles() {
return new ArrayList<Integer>();
}
+
+ public void setName(String name) {
+ mName = name;
+ }
+
+ @Implementation
+ public String getName() {
+ return mName;
+ }
+
+ @Implementation
+ public void setScanMode(int scanMode) {
+ mScanMode = scanMode;
+ }
+
+ @Implementation
+ public int getScanMode() {
+ return mScanMode;
+ }
+
+ @Implementation
+ public int getConnectionState() {
+ return mState;
+ }
+
+ public void setConnectionState(int state) {
+ mState = state;
+ }
}
diff --git a/tests/robotests/src/com/android/settings/wallpaper/FallbackHomeActivityTest.java b/tests/robotests/src/com/android/settings/wallpaper/FallbackHomeActivityTest.java
new file mode 100644
index 0000000..57d7798
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wallpaper/FallbackHomeActivityTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.wallpaper;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
+import android.app.WallpaperManager.OnColorsChangedListener;
+import android.os.Handler;
+
+import com.android.settings.FallbackHome;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.android.controller.ActivityController;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadow.api.Shadow;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Build/Install/Run:
+ * make RunSettingsRoboTests -j40 ROBOTEST_FILTER=FallbackHomeActivityTest
+ */
+@RunWith(SettingsRobolectricTestRunner.class)
+public class FallbackHomeActivityTest {
+
+ private ActivityController<FallbackHome> mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mController = Robolectric.buildActivity(FallbackHome.class);
+ }
+
+ @Test
+ @Config(shadows = ShadowWallpaperManager.class)
+ public void wallpaperColorsChangedListener_ensured_removed() {
+ // onCreate adds the first color listener by WallpaperManager returning null colors
+ ActivityController controller = mController.setup();
+ ShadowWallpaperManager shadowManager = Shadow.extract(RuntimeEnvironment.application
+ .getSystemService(WallpaperManager.class));
+ assertThat(shadowManager.size()).isEqualTo(1);
+
+ // Assert onDestroy will remove the original listener
+ controller.destroy();
+ assertThat(shadowManager.size()).isEqualTo(0);
+ }
+
+ @Implements(WallpaperManager.class)
+ public static class ShadowWallpaperManager {
+
+ private final List<OnColorsChangedListener> mListener = new ArrayList<>();
+
+ public int size() {
+ return mListener.size();
+ }
+
+ @Implementation
+ public boolean isWallpaperServiceEnabled() {
+ return true;
+ }
+
+ @Implementation
+ public @Nullable WallpaperColors getWallpaperColors(int which) {
+ return null;
+ }
+
+ @Implementation
+ public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener,
+ @NonNull Handler handler) {
+ mListener.add(listener);
+ }
+
+ @Implementation
+ public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener listener) {
+ mListener.remove(listener);
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/widget/AppCheckBoxPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/AppCheckBoxPreferenceTest.java
index af867e6..e20520f 100644
--- a/tests/robotests/src/com/android/settings/widget/AppCheckBoxPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/widget/AppCheckBoxPreferenceTest.java
@@ -19,6 +19,8 @@
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -28,18 +30,25 @@
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
+import androidx.preference.PreferenceViewHolder;
+
@RunWith(SettingsRobolectricTestRunner.class)
public class AppCheckBoxPreferenceTest {
+ private static final String SUMMARY = "summary info";
+
private Context mContext;
private AppCheckBoxPreference mPreference;
private AppCheckBoxPreference mAttrPreference;
+ private PreferenceViewHolder mPreferenceViewHolder;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mPreference = new AppCheckBoxPreference(mContext);
mAttrPreference = new AppCheckBoxPreference(mContext, null /* attrs */);
+ mPreferenceViewHolder = PreferenceViewHolder.createInstanceForTests(
+ LayoutInflater.from(mContext).inflate(R.layout.preference_app, null));
}
@Test
@@ -47,4 +56,32 @@
assertThat(mPreference.getLayoutResource()).isEqualTo(R.layout.preference_app);
assertThat(mAttrPreference.getLayoutResource()).isEqualTo(R.layout.preference_app);
}
+
+ @Test
+ public void onBindViewHolder_noSummary_layoutGone() {
+ mPreference.setSummary("");
+
+ mPreference.onBindViewHolder(mPreferenceViewHolder);
+
+ assertThat(mPreferenceViewHolder.findViewById(R.id.summary_container).getVisibility())
+ .isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void onBindViewHolder_hasSummary_layoutVisible() {
+ mPreference.setSummary(SUMMARY);
+
+ mPreference.onBindViewHolder(mPreferenceViewHolder);
+
+ assertThat(mPreferenceViewHolder.findViewById(R.id.summary_container).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void onBindViewHolder_appendixGone() {
+ mPreference.onBindViewHolder(mPreferenceViewHolder);
+
+ assertThat(mPreferenceViewHolder.findViewById(R.id.appendix).getVisibility())
+ .isEqualTo(View.GONE);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiDialogTest.java b/tests/robotests/src/com/android/settings/wifi/WifiDialogTest.java
index 7a88131..74378bd 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiDialogTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiDialogTest.java
@@ -37,7 +37,7 @@
WifiDialog fullscreen = WifiDialog.createFullscreen(mContext, mListener, mockAccessPoint,
WifiConfigUiBase.MODE_CONNECT);
assertThat(fullscreen.getContext().getThemeResId())
- .isEqualTo(R.style.Theme_Settings_NoActionBar);
+ .isEqualTo(R.style.Theme_Settings_WifiDialogFullScreen);
}
@Test
diff --git a/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java b/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
index 176d3c4..59f22db 100644
--- a/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
+++ b/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
@@ -19,6 +19,7 @@
import static junit.framework.Assert.fail;
import android.content.Context;
+import android.os.Looper;
import android.platform.test.annotations.Presubmit;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
@@ -52,6 +53,7 @@
@Test
@Presubmit
public void controllersInSearchShouldImplementPreferenceControllerMixin() {
+ Looper.prepare(); // Required by AutofillLoggingLevelPreferenceController
final Set<String> errorClasses = new ArraySet<>();
final SearchIndexableResources resources =