diff --git a/res/drawable/ic_battery_alert_24dp.xml b/res/drawable/ic_battery_alert_24dp.xml index cadd882ecc5..5a512f720ae 100644 --- a/res/drawable/ic_battery_alert_24dp.xml +++ b/res/drawable/ic_battery_alert_24dp.xml @@ -21,5 +21,8 @@ android:tint="?android:attr/colorError"> + android:pathData="M13,17h-2v-2h2V17zM13,13h-2V8h2V13z"/> + diff --git a/res/drawable/ic_battery_charging_full.xml b/res/drawable/ic_battery_charging_full.xml index c2a614ea3ce..830853230a4 100644 --- a/res/drawable/ic_battery_charging_full.xml +++ b/res/drawable/ic_battery_charging_full.xml @@ -19,6 +19,9 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> + android:fillColor="#FF000000" + android:pathData="M16.2,22.5H7.8c-1.3,0 -2.3,-1 -2.3,-2.3V5.8c0,-1.3 1,-2.3 2.3,-2.3h0.7v-2h7v2h0.7c1.3,0 2.3,1.1 2.3,2.3v14.3C18.5,21.5 17.5,22.5 16.2,22.5zM7.8,5.5c-0.2,0 -0.3,0.2 -0.3,0.3v14.3c0,0.2 0.2,0.3 0.3,0.3h8.3c0.2,0 0.3,-0.1 0.3,-0.3V5.8c0,-0.2 -0.1,-0.3 -0.3,-0.3h-2.7v-2h-3v2H7.8z"/> + diff --git a/res/drawable/ic_battery_saver_accent_24dp.xml b/res/drawable/ic_battery_saver_accent_24dp.xml new file mode 100644 index 00000000000..c8def54883d --- /dev/null +++ b/res/drawable/ic_battery_saver_accent_24dp.xml @@ -0,0 +1,29 @@ + + + + + + diff --git a/res/drawable/ic_battery_status_bad_24dp.xml b/res/drawable/ic_battery_status_bad_24dp.xml index 167d2fe9587..d841f08a218 100644 --- a/res/drawable/ic_battery_status_bad_24dp.xml +++ b/res/drawable/ic_battery_status_bad_24dp.xml @@ -18,9 +18,10 @@ Copyright (C) 2018 The Android Open Source Project android:height="24dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> - + android:pathData="M15,14l-2,0l0,2l-2,0l0,-2l-2,0l0,-2l2,0l0,-2l2,0l0,2l2,0z"/> + diff --git a/res/drawable/ic_battery_status_good_24dp.xml b/res/drawable/ic_battery_status_good_24dp.xml index 1f29023e194..4628ee588c9 100644 --- a/res/drawable/ic_battery_status_good_24dp.xml +++ b/res/drawable/ic_battery_status_good_24dp.xml @@ -18,9 +18,10 @@ Copyright (C) 2018 The Android Open Source Project android:height="24dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> - + android:pathData="M16.2,22.5H7.8c-1.3,0 -2.3,-1 -2.3,-2.3V5.8c0,-1.3 1,-2.3 2.3,-2.3h0.7v-2h7v2h0.7c1.3,0 2.3,1.1 2.3,2.3v14.3C18.5,21.5 17.5,22.5 16.2,22.5zM7.8,5.5c-0.2,0 -0.3,0.2 -0.3,0.3v14.3c0,0.2 0.2,0.3 0.3,0.3h8.3c0.2,0 0.3,-0.1 0.3,-0.3V5.8c0,-0.2 -0.1,-0.3 -0.3,-0.3h-2.7v-2h-3v2H7.8z"/> + diff --git a/res/drawable/ic_battery_status_maybe_24dp.xml b/res/drawable/ic_battery_status_maybe_24dp.xml index 0289c927260..64451be7304 100644 --- a/res/drawable/ic_battery_status_maybe_24dp.xml +++ b/res/drawable/ic_battery_status_maybe_24dp.xml @@ -18,9 +18,10 @@ Copyright (C) 2018 The Android Open Source Project android:height="24dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> - + android:pathData="M13,17h-2v-2h2V17zM13,13h-2V8h2V13z"/> + diff --git a/res/drawable/ic_folder_vd_theme_24.xml b/res/drawable/ic_folder_vd_theme_24.xml index 0d27773754d..34e301f2b57 100644 --- a/res/drawable/ic_folder_vd_theme_24.xml +++ b/res/drawable/ic_folder_vd_theme_24.xml @@ -21,5 +21,5 @@ android:tint="?android:attr/colorControlNormal"> - \ No newline at end of file + android:pathData="M20,6h-8l-2,-2H4C2.9,4 2.01,4.9 2.01,6L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V8C22,6.9 21.1,6 20,6zM20,18H4V8h16V18z"/> + diff --git a/res/drawable/ic_media_stream_off.xml b/res/drawable/ic_media_stream_off.xml new file mode 100644 index 00000000000..c8d5978fb3a --- /dev/null +++ b/res/drawable/ic_media_stream_off.xml @@ -0,0 +1,28 @@ + + + + + diff --git a/res/drawable/ic_settings_24dp.xml b/res/drawable/ic_settings_24dp.xml index da343457cad..ac4c43bd35b 100644 --- a/res/drawable/ic_settings_24dp.xml +++ b/res/drawable/ic_settings_24dp.xml @@ -21,6 +21,9 @@ android:viewportHeight="24.0" android:tint="?android:attr/colorControlNormal"> + android:fillColor="#FFFFFFFF" + android:pathData="M13.85,22.25h-3.7c-0.74,0 -1.36,-0.54 -1.45,-1.27l-0.27,-1.89c-0.27,-0.14 -0.53,-0.29 -0.79,-0.46l-1.8,0.72c-0.7,0.26 -1.47,-0.03 -1.81,-0.65L2.2,15.53c-0.35,-0.66 -0.2,-1.44 0.36,-1.88l1.53,-1.19c-0.01,-0.15 -0.02,-0.3 -0.02,-0.46c0,-0.15 0.01,-0.31 0.02,-0.46l-1.52,-1.19C1.98,9.9 1.83,9.09 2.2,8.47l1.85,-3.19c0.34,-0.62 1.11,-0.9 1.79,-0.63l1.81,0.73c0.26,-0.17 0.52,-0.32 0.78,-0.46l0.27,-1.91c0.09,-0.7 0.71,-1.25 1.44,-1.25h3.7c0.74,0 1.36,0.54 1.45,1.27l0.27,1.89c0.27,0.14 0.53,0.29 0.79,0.46l1.8,-0.72c0.71,-0.26 1.48,0.03 1.82,0.65l1.84,3.18c0.36,0.66 0.2,1.44 -0.36,1.88l-1.52,1.19c0.01,0.15 0.02,0.3 0.02,0.46s-0.01,0.31 -0.02,0.46l1.52,1.19c0.56,0.45 0.72,1.23 0.37,1.86l-1.86,3.22c-0.34,0.62 -1.11,0.9 -1.8,0.63l-1.8,-0.72c-0.26,0.17 -0.52,0.32 -0.78,0.46l-0.27,1.91C15.21,21.71 14.59,22.25 13.85,22.25zM13.32,20.72c0,0.01 0,0.01 0,0.02L13.32,20.72zM10.68,20.7l0,0.02C10.69,20.72 10.69,20.71 10.68,20.7zM10.62,20.25h2.76l0.37,-2.55l0.53,-0.22c0.44,-0.18 0.88,-0.44 1.34,-0.78l0.45,-0.34l2.38,0.96l1.38,-2.4l-2.03,-1.58l0.07,-0.56c0.03,-0.26 0.06,-0.51 0.06,-0.78c0,-0.27 -0.03,-0.53 -0.06,-0.78l-0.07,-0.56l2.03,-1.58l-1.39,-2.4l-2.39,0.96l-0.45,-0.35c-0.42,-0.32 -0.87,-0.58 -1.33,-0.77L13.75,6.3l-0.37,-2.55h-2.76L10.25,6.3L9.72,6.51C9.28,6.7 8.84,6.95 8.38,7.3L7.93,7.63L5.55,6.68L4.16,9.07l2.03,1.58l-0.07,0.56C6.09,11.47 6.06,11.74 6.06,12c0,0.26 0.02,0.53 0.06,0.78l0.07,0.56l-2.03,1.58l1.38,2.4l2.39,-0.96l0.45,0.35c0.43,0.33 0.86,0.58 1.33,0.77l0.53,0.22L10.62,20.25zM18.22,17.72c0,0.01 -0.01,0.02 -0.01,0.03L18.22,17.72zM5.77,17.71l0.01,0.02C5.78,17.72 5.77,17.71 5.77,17.71zM3.93,9.47L3.93,9.47C3.93,9.47 3.93,9.47 3.93,9.47zM18.22,6.27c0,0.01 0.01,0.02 0.01,0.02L18.22,6.27zM5.79,6.25L5.78,6.27C5.78,6.27 5.79,6.26 5.79,6.25zM13.31,3.28c0,0.01 0,0.01 0,0.02L13.31,3.28zM10.69,3.26l0,0.02C10.69,3.27 10.69,3.27 10.69,3.26z"/> + diff --git a/res/drawable/ic_settings_24dp_inverse.xml b/res/drawable/ic_settings_24dp_inverse.xml deleted file mode 100644 index 6f70d21e256..00000000000 --- a/res/drawable/ic_settings_24dp_inverse.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - \ No newline at end of file diff --git a/res/drawable/ic_settings_accounts.xml b/res/drawable/ic_settings_accounts.xml index d152b147ac4..7f182866d48 100644 --- a/res/drawable/ic_settings_accounts.xml +++ b/res/drawable/ic_settings_accounts.xml @@ -14,15 +14,14 @@ limitations under the License. --> + android:pathData="M19,3H5C3.89,3 3,3.9 3,5v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2V5C21,3.9 20.1,3 19,3zM19,5v10.79C16.52,14.37 13.23,14 12,14s-4.52,0.37 -7,1.79V5H19zM5,19v-0.77C6.74,16.66 10.32,16 12,16s5.26,0.66 7,2.23V19H5z"/> + diff --git a/res/drawable/ic_settings_backup.xml b/res/drawable/ic_settings_backup.xml index 8a9997a387c..231eadd91eb 100644 --- a/res/drawable/ic_settings_backup.xml +++ b/res/drawable/ic_settings_backup.xml @@ -14,12 +14,12 @@ limitations under the License. --> + android:pathData="M17.92,10.02C17.45,7.18 14.97,5 12,5C9.82,5 7.83,6.18 6.78,8.06C4.09,8.41 2,10.74 2,13.5C2,16.53 4.47,19 7.5,19h10c2.48,0 4.5,-2.02 4.5,-4.5C22,12.16 20.21,10.23 17.92,10.02zM17.5,17h-10C5.57,17 4,15.43 4,13.5c0,-1.89 1.54,-3.46 3.44,-3.49L8.08,10l0.26,-0.59C8.97,7.94 10.41,7 12,7c2.21,0 4,1.79 4,4v1h1.5c1.38,0 2.5,1.12 2.5,2.5S18.88,17 17.5,17zM14.09,11.09l1.41,1.41l-2.79,2.79L12,16l-0.71,-0.71L8.5,12.5l1.41,-1.41L11,12.17V9.5h2v2.67L14.09,11.09z"/> diff --git a/res/drawable/ic_settings_display.xml b/res/drawable/ic_settings_display.xml index de71508b841..7f0aacdf986 100644 --- a/res/drawable/ic_settings_display.xml +++ b/res/drawable/ic_settings_display.xml @@ -21,8 +21,5 @@ android:tint="?android:attr/colorControlNormal"> + android:pathData="M20,8.69V4h-4.69L12,0.69L8.69,4H4v4.69L0.69,12L4,15.31V20h4.69L12,23.31L15.31,20H20v-4.69L23.31,12L20,8.69zM18,14.48V18h-3.52L12,20.48L9.52,18H6v-3.52L3.52,12L6,9.52V6h3.52L12,3.52L14.48,6H18v3.52L20.48,12L18,14.48zM12,17c2.76,0 5,-2.24 5,-5s-2.24,-5 -5,-5V17z"/> diff --git a/res/drawable/ic_settings_display_white.xml b/res/drawable/ic_settings_display_white.xml index 4a41691912b..62dc21f305b 100644 --- a/res/drawable/ic_settings_display_white.xml +++ b/res/drawable/ic_settings_display_white.xml @@ -20,8 +20,5 @@ android:viewportHeight="24.0"> + android:pathData="M20,8.69V4h-4.69L12,0.69L8.69,4H4v4.69L0.69,12L4,15.31V20h4.69L12,23.31L15.31,20H20v-4.69L23.31,12L20,8.69zM18,14.48V18h-3.52L12,20.48L9.52,18H6v-3.52L3.52,12L6,9.52V6h3.52L12,3.52L14.48,6H18v3.52L20.48,12L18,14.48zM12,17c2.76,0 5,-2.24 5,-5s-2.24,-5 -5,-5V17z"/> diff --git a/res/drawable/ic_settings_location.xml b/res/drawable/ic_settings_location.xml index c774b2eb414..34bd4f098b7 100644 --- a/res/drawable/ic_settings_location.xml +++ b/res/drawable/ic_settings_location.xml @@ -21,5 +21,8 @@ android:tint="?android:attr/colorControlNormal"> + android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13C19,5.13 15.87,2 12,2zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9z"/> + diff --git a/res/drawable/ic_settings_multiuser.xml b/res/drawable/ic_settings_multiuser.xml index 4dd83a50e24..2d857c5ac61 100644 --- a/res/drawable/ic_settings_multiuser.xml +++ b/res/drawable/ic_settings_multiuser.xml @@ -21,5 +21,5 @@ android:tint="?android:attr/colorControlNormal"> + android:pathData="M12,6c1.1,0 2,0.9 2,2s-0.9,2 -2,2s-2,-0.9 -2,-2S10.9,6 12,6M12,15c2.7,0 5.8,1.29 6,2v1H6l0,-0.99C6.2,16.29 9.3,15 12,15M12,4C9.79,4 8,5.79 8,8s1.79,4 4,4s4,-1.79 4,-4S14.21,4 12,4L12,4zM12,13c-2.67,0 -8,1.34 -8,4v3h16v-3C20,14.34 14.67,13 12,13L12,13z"/> diff --git a/res/drawable/ic_settings_security.xml b/res/drawable/ic_settings_security.xml index 34accd0d380..055babc768e 100644 --- a/res/drawable/ic_settings_security.xml +++ b/res/drawable/ic_settings_security.xml @@ -21,5 +21,5 @@ android:tint="?android:attr/colorControlNormal"> + android:pathData="M18,8h-1V6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2H6c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V10C20,8.9 19.1,8 18,8zM9,6c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v2H9V6zM18,20H6V10h12V20zM12,17c1.1,0 2,-0.9 2,-2c0,-1.1 -0.9,-2 -2,-2c-1.1,0 -2,0.9 -2,2C10,16.1 10.9,17 12,17z"/> diff --git a/res/drawable/ic_settings_security_white.xml b/res/drawable/ic_settings_security_white.xml index d6c5b64bb77..544ebef31d8 100644 --- a/res/drawable/ic_settings_security_white.xml +++ b/res/drawable/ic_settings_security_white.xml @@ -20,5 +20,5 @@ android:viewportHeight="24.0"> + android:pathData="M18,8h-1V6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2H6c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V10C20,8.9 19.1,8 18,8zM9,6c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v2H9V6zM18,20H6V10h12V20zM12,17c1.1,0 2,-0.9 2,-2c0,-1.1 -0.9,-2 -2,-2c-1.1,0 -2,0.9 -2,2C10,16.1 10.9,17 12,17z"/> diff --git a/res/drawable/ic_system_update.xml b/res/drawable/ic_system_update.xml index ef8f9913bc3..3325fdd5c01 100644 --- a/res/drawable/ic_system_update.xml +++ b/res/drawable/ic_system_update.xml @@ -20,6 +20,6 @@ android:viewportHeight="24.0" android:tint="?android:attr/colorControlNormal"> + android:fillColor="#FFFFFFFF" + android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7l0,-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7zM16,12.5l-4,4l-4,-4l1.41,-1.41L11,12.67V8.5V8h2v0.5v4.17l1.59,-1.59L16,12.5z"/> diff --git a/res/drawable/ic_system_update_vd_theme_24.xml b/res/drawable/ic_system_update_vd_theme_24.xml index d68ea13774d..d1fc0616bf0 100644 --- a/res/drawable/ic_system_update_vd_theme_24.xml +++ b/res/drawable/ic_system_update_vd_theme_24.xml @@ -21,5 +21,5 @@ android:tint="?android:attr/colorControlNormal"> - \ No newline at end of file + android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7l0,-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7zM16,12.5l-4,4l-4,-4l1.41,-1.41L11,12.67V8.5V8h2v0.5v4.17l1.59,-1.59L16,12.5z"/> + diff --git a/res/layout/apps_filter_spinner.xml b/res/layout/apps_filter_spinner.xml index 3eebbb02f51..3faff507a2b 100644 --- a/res/layout/apps_filter_spinner.xml +++ b/res/layout/apps_filter_spinner.xml @@ -39,7 +39,7 @@ android:layout_height="56dp" android:contentDescription="@string/configure" android:scaleType="center" - android:src="@drawable/ic_settings_24dp_inverse" + android:src="@drawable/ic_settings_24dp" android:visibility="gone" /> diff --git a/res/layout/wifi_dialog.xml b/res/layout/wifi_dialog.xml index fe891e1f830..233072745b8 100644 --- a/res/layout/wifi_dialog.xml +++ b/res/layout/wifi_dialog.xml @@ -604,6 +604,7 @@ no + + + @string/systemui_theme_wallpaper + @string/systemui_theme_light + @string/systemui_theme_dark + + + + + 0 + 1 + 2 + + @string/prevent_ringing_option_vibrate @string/prevent_ringing_option_mute diff --git a/res/values/config.xml b/res/values/config.xml index 284b653a24d..8e55ea95e36 100755 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -38,9 +38,6 @@ false - - false - false diff --git a/res/values/strings.xml b/res/values/strings.xml index 3870fb656ab..2b4f49b17f9 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -9112,15 +9112,6 @@ To apply color change, turn off screen - - Connectivity Monitor - - - ConnectivityMonitor will collect logs when it detects a connectivity problem and prompt notification to user to file a bug - - - To apply connectivity monitor change, reboot device - Camera Laser Sensor @@ -9883,12 +9874,21 @@ - Device theme + Color theme Default Changing the theme requires a restart. + + Device theme + + Automatic (based on wallpaper) + + Light + + Dark + Network name diff --git a/res/xml/battery_saver_settings.xml b/res/xml/battery_saver_settings.xml index 116079d5247..0460459d961 100644 --- a/res/xml/battery_saver_settings.xml +++ b/res/xml/battery_saver_settings.xml @@ -18,32 +18,35 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:settings="http://schemas.android.com/apk/res-auto" android:title="@string/battery_saver" - android:key="battery_saver"> + android:key="battery_saver_page"> + settings:controller="com.android.settings.fuelgauge.batterysaver.AutoBatterySaverPreferenceController" /> + android:min="5" /> + settings:textOff="@string/battery_saver_button_turn_off" + settings:platform_slice="true" + settings:controller="com.android.settings.fuelgauge.batterysaver.BatterySaverButtonPreferenceController" /> + android:selectable="false" /> diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index 872837eb228..3c56e918103 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -183,11 +183,6 @@ android:entries="@array/select_logpersist_titles" android:entryValues="@array/select_logpersist_values" /> - - diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml index 90198ae70cf..c75b90ce46c 100644 --- a/res/xml/display_settings.xml +++ b/res/xml/display_settings.xml @@ -131,9 +131,16 @@ + + @@ -57,7 +57,7 @@ @@ -73,7 +73,7 @@ diff --git a/src/com/android/settings/applications/AppStateNotificationBridge.java b/src/com/android/settings/applications/AppStateNotificationBridge.java index a96a3b1ad7b..6cf64c3e57b 100644 --- a/src/com/android/settings/applications/AppStateNotificationBridge.java +++ b/src/com/android/settings/applications/AppStateNotificationBridge.java @@ -15,9 +15,13 @@ */ package com.android.settings.applications; +import android.app.usage.IUsageStatsManager; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManager; import android.content.Context; +import android.os.RemoteException; +import android.os.UserHandle; +import android.os.UserManager; import android.text.format.DateUtils; import android.util.ArrayMap; import android.view.View; @@ -25,6 +29,7 @@ import android.view.ViewGroup; import android.widget.Switch; import com.android.settings.R; +import com.android.settings.Utils; import com.android.settings.notification.NotificationBackend; import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.applications.ApplicationsState.AppEntry; @@ -33,6 +38,7 @@ import com.android.settingslib.utils.StringUtil; import java.util.ArrayList; import java.util.Comparator; +import java.util.List; import java.util.Map; /** @@ -42,17 +48,24 @@ import java.util.Map; public class AppStateNotificationBridge extends AppStateBaseBridge { private final Context mContext; - private UsageStatsManager mUsageStatsManager; + private IUsageStatsManager mUsageStatsManager; + protected List mUserIds; private NotificationBackend mBackend; private static final int DAYS_TO_CHECK = 7; public AppStateNotificationBridge(Context context, ApplicationsState appState, - Callback callback, UsageStatsManager usageStatsManager, - NotificationBackend backend) { + Callback callback, IUsageStatsManager usageStatsManager, + UserManager userManager, NotificationBackend backend) { super(appState, callback); mContext = context; mUsageStatsManager = usageStatsManager; mBackend = backend; + mUserIds = new ArrayList<>(); + mUserIds.add(mContext.getUserId()); + int workUserId = Utils.getManagedProfileId(userManager, mContext.getUserId()); + if (workUserId != UserHandle.USER_NULL) { + mUserIds.add(workUserId); + } } @Override @@ -62,7 +75,8 @@ public class AppStateNotificationBridge extends AppStateBaseBridge { final Map map = getAggregatedUsageEvents(); for (AppEntry entry : apps) { - NotificationsSentState stats = map.get(entry.info.packageName); + NotificationsSentState stats = + map.get(getKey(UserHandle.getUserId(entry.info.uid), entry.info.packageName)); calculateAvgSentCounts(stats); addBlockStatus(entry, stats); entry.extraInfo = stats; @@ -71,8 +85,8 @@ public class AppStateNotificationBridge extends AppStateBaseBridge { @Override protected void updateExtraInfo(AppEntry entry, String pkg, int uid) { - Map map = getAggregatedUsageEvents(); - NotificationsSentState stats = map.get(entry.info.packageName); + NotificationsSentState stats = getAggregatedUsageEvents( + UserHandle.getUserId(entry.info.uid), entry.info.packageName); calculateAvgSentCounts(stats); addBlockStatus(entry, stats); entry.extraInfo = stats; @@ -116,18 +130,59 @@ public class AppStateNotificationBridge extends AppStateBaseBridge { long now = System.currentTimeMillis(); long startTime = now - (DateUtils.DAY_IN_MILLIS * DAYS_TO_CHECK); - UsageEvents events = mUsageStatsManager.queryEvents(startTime, now); + for (int userId : mUserIds) { + UsageEvents events = null; + try { + events = mUsageStatsManager.queryEventsForUser( + startTime, now, userId, mContext.getPackageName()); + } catch (RemoteException e) { + e.printStackTrace(); + } + if (events != null) { + UsageEvents.Event event = new UsageEvents.Event(); + while (events.hasNextEvent()) { + events.getNextEvent(event); + NotificationsSentState stats = + aggregatedStats.get(getKey(userId, event.getPackageName())); + if (stats == null) { + stats = new NotificationsSentState(); + aggregatedStats.put(getKey(userId, event.getPackageName()), stats); + } + + if (event.getEventType() == UsageEvents.Event.NOTIFICATION_INTERRUPTION) { + if (event.getTimeStamp() > stats.lastSent) { + stats.lastSent = event.getTimeStamp(); + } + stats.sentCount++; + } + + } + } + } + return aggregatedStats; + } + + protected NotificationsSentState getAggregatedUsageEvents(int userId, String pkg) { + NotificationsSentState stats = null; + + long now = System.currentTimeMillis(); + long startTime = now - (DateUtils.DAY_IN_MILLIS * DAYS_TO_CHECK); + UsageEvents events = null; + try { + events = mUsageStatsManager.queryEventsForPackageForUser( + startTime, now, userId, pkg, mContext.getPackageName()); + } catch (RemoteException e) { + e.printStackTrace(); + } if (events != null) { UsageEvents.Event event = new UsageEvents.Event(); while (events.hasNextEvent()) { events.getNextEvent(event); - NotificationsSentState stats = aggregatedStats.get(event.getPackageName()); - if (stats == null) { - stats = new NotificationsSentState(); - aggregatedStats.put(event.getPackageName(), stats); - } if (event.getEventType() == UsageEvents.Event.NOTIFICATION_INTERRUPTION) { + if (stats == null) { + stats = new NotificationsSentState(); + } if (event.getTimeStamp() > stats.lastSent) { stats.lastSent = event.getTimeStamp(); } @@ -136,7 +191,7 @@ public class AppStateNotificationBridge extends AppStateBaseBridge { } } - return aggregatedStats; + return stats; } private static NotificationsSentState getNotificationsSentState(AppEntry entry) { @@ -149,6 +204,10 @@ public class AppStateNotificationBridge extends AppStateBaseBridge { return null; } + protected static String getKey(int userId, String pkg) { + return userId + "|" + pkg; + } + public View.OnClickListener getSwitchOnClickListener(final AppEntry entry) { if (entry != null) { return v -> { diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java index 328d4a28146..a00ea8e2e68 100644 --- a/src/com/android/settings/applications/manageapplications/ManageApplications.java +++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java @@ -41,6 +41,7 @@ import static com.android.settings.applications.manageapplications.AppFilterRegi import android.annotation.Nullable; import android.annotation.StringRes; import android.app.Activity; +import android.app.usage.IUsageStatsManager; import android.app.usage.UsageStatsManager; import android.content.Context; import android.content.Intent; @@ -48,6 +49,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageItemInfo; import android.os.Bundle; import android.os.Environment; +import android.os.ServiceManager; import android.os.UserHandle; import android.os.UserManager; import android.preference.PreferenceFrameLayout; @@ -224,7 +226,8 @@ public class ManageApplications extends InstrumentedFragment private View mSpinnerHeader; private Spinner mFilterSpinner; private FilterSpinnerAdapter mFilterAdapter; - private UsageStatsManager mUsageStatsManager; + private IUsageStatsManager mUsageStatsManager; + private UserManager mUserManager; private NotificationBackend mNotificationBackend; private ResetAppsHelper mResetAppsHelper; private String mVolumeUuid; @@ -293,8 +296,9 @@ public class ManageApplications extends InstrumentedFragment screenTitle = R.string.change_wifi_state_title; } else if (className.equals(Settings.NotificationAppListActivity.class.getName())) { mListType = LIST_TYPE_NOTIFICATION; - mUsageStatsManager = - (UsageStatsManager) getContext().getSystemService(Context.USAGE_STATS_SERVICE); + mUsageStatsManager = IUsageStatsManager.Stub.asInterface( + ServiceManager.getService(Context.USAGE_STATS_SERVICE)); + mUserManager = UserManager.get(getContext()); mNotificationBackend = new NotificationBackend(); mSortOrder = R.id.sort_order_recent_notification; screenTitle = R.string.app_notifications_title; @@ -875,6 +879,7 @@ public class ManageApplications extends InstrumentedFragment if (mManageApplications.mListType == LIST_TYPE_NOTIFICATION) { mExtraInfoBridge = new AppStateNotificationBridge(mContext, mState, this, manageApplications.mUsageStatsManager, + manageApplications.mUserManager, manageApplications.mNotificationBackend); } else if (mManageApplications.mListType == LIST_TYPE_USAGE_ACCESS) { mExtraInfoBridge = new AppStateUsageBridge(mContext, mState, this); diff --git a/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java b/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java index e6452def3d7..da759a33e5e 100644 --- a/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java +++ b/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java @@ -17,6 +17,8 @@ package com.android.settings.bluetooth; import static android.app.slice.Slice.EXTRA_TOGGLE_STATE; +import static androidx.slice.builders.ListBuilder.ICON_IMAGE; + import android.annotation.ColorInt; import android.app.PendingIntent; import android.bluetooth.BluetoothAdapter; diff --git a/src/com/android/settings/dashboard/conditional/BatterySaverCondition.java b/src/com/android/settings/dashboard/conditional/BatterySaverCondition.java index 728154d5d6d..fdd1508db81 100644 --- a/src/com/android/settings/dashboard/conditional/BatterySaverCondition.java +++ b/src/com/android/settings/dashboard/conditional/BatterySaverCondition.java @@ -47,7 +47,7 @@ public class BatterySaverCondition extends Condition implements @Override public Drawable getIcon() { - return new BatterySaverDrawable(mManager.getContext(), 0); + return mManager.getContext().getDrawable(R.drawable.ic_battery_saver_accent_24dp); } @Override diff --git a/src/com/android/settings/development/BluetoothA2dpHwOffloadPreferenceController.java b/src/com/android/settings/development/BluetoothA2dpHwOffloadPreferenceController.java index 553a63e5954..01ec156e754 100644 --- a/src/com/android/settings/development/BluetoothA2dpHwOffloadPreferenceController.java +++ b/src/com/android/settings/development/BluetoothA2dpHwOffloadPreferenceController.java @@ -69,8 +69,15 @@ public class BluetoothA2dpHwOffloadPreferenceController extends DeveloperOptions @Override protected void onDeveloperOptionsSwitchDisabled() { super.onDeveloperOptionsSwitchDisabled(); - ((SwitchPreference) mPreference).setChecked(true); - SystemProperties.set(A2DP_OFFLOAD_DISABLED_PROPERTY, "true"); + final boolean offloadSupported = + SystemProperties.getBoolean(A2DP_OFFLOAD_SUPPORTED_PROPERTY, false); + if (offloadSupported) { + ((SwitchPreference) mPreference).setChecked(false); + SystemProperties.set(A2DP_OFFLOAD_DISABLED_PROPERTY, "false"); + } else { + ((SwitchPreference) mPreference).setChecked(true); + SystemProperties.set(A2DP_OFFLOAD_DISABLED_PROPERTY, "true"); + } } public void onA2dpHwDialogConfirmed() { diff --git a/src/com/android/settings/development/ConnectivityMonitorPreferenceController.java b/src/com/android/settings/development/ConnectivityMonitorPreferenceController.java deleted file mode 100644 index 85b562d8384..00000000000 --- a/src/com/android/settings/development/ConnectivityMonitorPreferenceController.java +++ /dev/null @@ -1,100 +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.development; - -import android.content.Context; -import android.os.SystemProperties; -import android.support.v14.preference.SwitchPreference; -import android.support.v7.preference.Preference; -import android.text.TextUtils; -import android.widget.Toast; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.settings.R; -import com.android.settings.core.PreferenceControllerMixin; -import com.android.settingslib.development.DeveloperOptionsPreferenceController; - -public class ConnectivityMonitorPreferenceController extends DeveloperOptionsPreferenceController - implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin { - - private static final String KEY_CONNECTIVITY_MONITOR_SWITCH = "connectivity_monitor_switch"; - @VisibleForTesting - static final String BUILD_TYPE = "ro.build.type"; - @VisibleForTesting - static final String PROPERTY_CONNECTIVITY_MONITOR = "persist.radio.enable_tel_mon"; - - @VisibleForTesting - static final String ENABLED_STATUS = "enabled"; - @VisibleForTesting - static final String DISABLED_STATUS = "disabled"; - @VisibleForTesting - static final String USER_ENABLED_STATUS = "user_enabled"; - @VisibleForTesting - static final String USER_DISABLED_STATUS = "user_disabled"; - - @VisibleForTesting - static final String USERDEBUG_BUILD = "userdebug"; - @VisibleForTesting - static final String ENG_BUILD = "eng"; - - public ConnectivityMonitorPreferenceController(Context context) { - super(context); - } - - @Override - public String getPreferenceKey() { - return KEY_CONNECTIVITY_MONITOR_SWITCH; - } - - @Override - public boolean isAvailable() { - final String buildType = SystemProperties.get(BUILD_TYPE); - return mContext.getResources().getBoolean(R.bool.config_show_connectivity_monitor) - && (TextUtils.equals(buildType, USERDEBUG_BUILD) - || TextUtils.equals(buildType, ENG_BUILD)); - } - - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - final boolean isEnabled = (Boolean) newValue; - SystemProperties.set(PROPERTY_CONNECTIVITY_MONITOR, - isEnabled ? USER_ENABLED_STATUS : USER_DISABLED_STATUS); - Toast.makeText(mContext, R.string.connectivity_monitor_toast, - Toast.LENGTH_LONG).show(); - return true; - } - - @Override - public void updateState(Preference preference) { - final boolean enabled = isConnectivityMonitorEnabled(); - ((SwitchPreference) mPreference).setChecked(enabled); - } - - @Override - protected void onDeveloperOptionsSwitchDisabled() { - super.onDeveloperOptionsSwitchDisabled(); - SystemProperties.set(PROPERTY_CONNECTIVITY_MONITOR, USER_DISABLED_STATUS); - ((SwitchPreference) mPreference).setChecked(false); - } - - private boolean isConnectivityMonitorEnabled() { - final String cmStatus = SystemProperties.get(PROPERTY_CONNECTIVITY_MONITOR, - DISABLED_STATUS); - return TextUtils.equals(ENABLED_STATUS, cmStatus) || TextUtils.equals(USER_ENABLED_STATUS, - cmStatus); - } -} diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java index bc749c1d683..eb1a2dd9369 100644 --- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java @@ -403,7 +403,6 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra controllers.add(new VerifyAppsOverUsbPreferenceController(context)); controllers.add(new LogdSizePreferenceController(context)); controllers.add(new LogPersistPreferenceController(context, fragment, lifecycle)); - controllers.add(new ConnectivityMonitorPreferenceController(context)); controllers.add(new CameraLaserSensorPreferenceController(context)); controllers.add(new LogicalCameraDefaultPreferenceController(context)); controllers.add(new WifiDisplayCertificationPreferenceController(context)); diff --git a/src/com/android/settings/display/SystemUiThemePreferenceController.java b/src/com/android/settings/display/SystemUiThemePreferenceController.java new file mode 100644 index 00000000000..3cdc85cf600 --- /dev/null +++ b/src/com/android/settings/display/SystemUiThemePreferenceController.java @@ -0,0 +1,73 @@ +/* + * 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.display; + +import static android.provider.Settings.Secure.THEME_MODE; + +import android.content.Context; +import android.provider.Settings; +import android.support.v7.preference.ListPreference; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.util.FeatureFlagUtils; + +import com.android.settings.core.BasePreferenceController; +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.core.AbstractPreferenceController; + +/** + * Setting where user can pick if SystemUI will be light, dark or try to match + * the wallpaper colors. + */ +public class SystemUiThemePreferenceController extends BasePreferenceController + implements Preference.OnPreferenceChangeListener { + + private ListPreference mSystemUiThemePref; + + public SystemUiThemePreferenceController(Context context, String preferenceKey) { + super(context, preferenceKey); + } + + @Override + public int getAvailabilityStatus() { + boolean enabled = FeatureFlagUtils.isEnabled(mContext, "settings_systemui_theme"); + return enabled ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mSystemUiThemePref = (ListPreference) screen.findPreference(getPreferenceKey()); + int value = Settings.Secure.getInt(mContext.getContentResolver(), THEME_MODE, 0); + mSystemUiThemePref.setValue(Integer.toString(value)); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + int value = Integer.parseInt((String) newValue); + Settings.Secure.putInt(mContext.getContentResolver(), THEME_MODE, value); + refreshSummary(preference); + return true; + } + + @Override + public CharSequence getSummary() { + int value = Settings.Secure.getInt(mContext.getContentResolver(), THEME_MODE, 0); + int index = mSystemUiThemePref.findIndexOfValue(Integer.toString(value)); + return mSystemUiThemePref.getEntries()[index]; + } +} diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceController.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceController.java index b23a5f08a70..9485868d20c 100644 --- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceController.java +++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceController.java @@ -18,12 +18,12 @@ package com.android.settings.fuelgauge.batterysaver; import android.content.Context; import android.os.PowerManager; -import android.support.annotation.VisibleForTesting; import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import com.android.settings.core.TogglePreferenceController; import com.android.settings.fuelgauge.BatterySaverReceiver; -import com.android.settings.widget.TwoStateButtonPreferenceController; -import com.android.settingslib.core.lifecycle.Lifecycle; +import com.android.settings.widget.TwoStateButtonPreference; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; @@ -33,21 +33,29 @@ import com.android.settingslib.fuelgauge.BatterySaverUtils; * Controller to update the battery saver button */ public class BatterySaverButtonPreferenceController extends - TwoStateButtonPreferenceController implements + TogglePreferenceController implements LifecycleObserver, OnStart, OnStop, BatterySaverReceiver.BatterySaverListener { - private static final String KEY = "battery_saver_button_container"; - private BatterySaverReceiver mBatterySaverReceiver; - @VisibleForTesting - PowerManager mPowerManager; - public BatterySaverButtonPreferenceController(Context context, Lifecycle lifecycle) { - super(context, KEY); + private final BatterySaverReceiver mBatterySaverReceiver; + private final PowerManager mPowerManager; + + private TwoStateButtonPreference mPreference; + + public BatterySaverButtonPreferenceController(Context context, String key) { + super(context, key); mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mBatterySaverReceiver = new BatterySaverReceiver(context); mBatterySaverReceiver.setBatterySaverListener(this); - if (lifecycle != null) { - lifecycle.addObserver(this); - } + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public boolean isSliceable() { + return true; } @Override @@ -60,30 +68,44 @@ public class BatterySaverButtonPreferenceController extends mBatterySaverReceiver.setListening(false); } + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = (TwoStateButtonPreference) screen.findPreference(getPreferenceKey()); + } + + @Override + public boolean isChecked() { + return mPowerManager.isPowerSaveMode(); + } + + @Override + public boolean setChecked(boolean stateOn) { + // This screen already shows a warning, so we don't need another warning. + return BatterySaverUtils.setPowerSaveMode(mContext, stateOn, + false /* needFirstTimeWarning */); + } + @Override public void updateState(Preference preference) { super.updateState(preference); - setButtonVisibility(!mPowerManager.isPowerSaveMode()); - } - - @Override - public int getAvailabilityStatus() { - return AVAILABLE; - } - - @Override - public void onButtonClicked(boolean stateOn) { - // This screen already shows a warning, so we don't need another warning. - BatterySaverUtils.setPowerSaveMode(mContext, stateOn, /*needFirstTimeWarning*/ false); + if (mPreference != null) { + mPreference.setChecked(isChecked()); + } } @Override public void onPowerSaveModeChanged() { - setButtonVisibility(!mPowerManager.isPowerSaveMode()); + final boolean isChecked = isChecked(); + if (mPreference != null && mPreference.isChecked() != isChecked) { + mPreference.setChecked(isChecked); + } } @Override public void onBatteryChanged(boolean pluggedIn) { - setButtonEnabled(!pluggedIn); + if (mPreference != null) { + mPreference.setButtonEnabled(!pluggedIn); + } } } diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java index 8009e954e38..26f9e171212 100644 --- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java +++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java @@ -73,7 +73,6 @@ public class BatterySaverSettings extends DashboardFragment { final List controllers = new ArrayList<>(); controllers.add(new AutoBatterySaverPreferenceController(context)); controllers.add(new AutoBatterySeekBarPreferenceController(context, lifecycle)); - controllers.add(new BatterySaverButtonPreferenceController(context, lifecycle)); return controllers; } diff --git a/src/com/android/settings/location/LocationSliceBuilder.java b/src/com/android/settings/location/LocationSliceBuilder.java new file mode 100644 index 00000000000..e69ccfba54c --- /dev/null +++ b/src/com/android/settings/location/LocationSliceBuilder.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.location; + +import static android.provider.SettingsSlicesContract.KEY_LOCATION; + +import static androidx.slice.builders.ListBuilder.ICON_IMAGE; + +import android.annotation.ColorInt; +import android.app.PendingIntent; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.provider.SettingsSlicesContract; + +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.settings.R; +import com.android.settings.SubSettings; +import com.android.settings.Utils; +import com.android.settings.search.DatabaseIndexingUtils; + +import androidx.slice.Slice; +import androidx.slice.builders.ListBuilder; +import androidx.slice.builders.SliceAction; + +import android.support.v4.graphics.drawable.IconCompat; + +/** + * Utility class to build an intent-based Location Slice. + */ +public class LocationSliceBuilder { + + /** + * Backing Uri for the Location Slice. + */ + public static final Uri LOCATION_URI = new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(SettingsSlicesContract.AUTHORITY) + .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) + .appendPath(KEY_LOCATION) + .build(); + + private LocationSliceBuilder() { + } + + /** + * Return a Location Slice bound to {@link #LOCATION_URI}. + */ + public static Slice getSlice(Context context) { + final IconCompat icon = IconCompat.createWithResource(context, + R.drawable.ic_signal_location); + final String title = context.getString(R.string.location_settings_title); + @ColorInt final int color = Utils.getColorAccent(context); + final PendingIntent primaryAction = getPrimaryAction(context); + final SliceAction primarySliceAction = new SliceAction(primaryAction, icon, title); + + return new ListBuilder(context, LOCATION_URI, ListBuilder.INFINITY) + .setAccentColor(color) + .addRow(b -> b + .setTitle(title) + .setTitleItem(icon, ICON_IMAGE) + .setPrimaryAction(primarySliceAction)) + .build(); + } + + private static PendingIntent getPrimaryAction(Context context) { + final String screenTitle = context.getText(R.string.location_settings_title).toString(); + final Uri contentUri = new Uri.Builder().appendPath(KEY_LOCATION).build(); + final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context, + LocationSettings.class.getName(), KEY_LOCATION, screenTitle, + MetricsEvent.LOCATION) + .setClassName(context.getPackageName(), SubSettings.class.getName()) + .setData(contentUri); + + return PendingIntent.getActivity(context, 0 /* requestCode */, + intent, 0 /* flags */); + } +} diff --git a/src/com/android/settings/notification/MediaVolumePreferenceController.java b/src/com/android/settings/notification/MediaVolumePreferenceController.java index 46f57292a37..74ce7695f35 100644 --- a/src/com/android/settings/notification/MediaVolumePreferenceController.java +++ b/src/com/android/settings/notification/MediaVolumePreferenceController.java @@ -55,6 +55,6 @@ public class MediaVolumePreferenceController extends @Override public int getMuteIcon() { - return com.android.internal.R.drawable.ic_audio_media_mute; + return R.drawable.ic_media_stream_off; } } diff --git a/src/com/android/settings/notification/NotificationPreferenceController.java b/src/com/android/settings/notification/NotificationPreferenceController.java index 1e477c41fd2..0c5dc0e268f 100644 --- a/src/com/android/settings/notification/NotificationPreferenceController.java +++ b/src/com/android/settings/notification/NotificationPreferenceController.java @@ -83,28 +83,6 @@ public abstract class NotificationPreferenceController extends AbstractPreferenc return true; } - /** - * Displays or removes preference in this controller. - */ - @Override - public void displayPreference(PreferenceScreen screen) { - if (isAvailable()) { - final Preference preference = screen.findPreference(getPreferenceKey()); - if (mPreference != null && preference == null) { - screen.addPreference(mPreference); - } - if (preference != null) { - mPreference = preference; - } - if (mPreference != null && this instanceof Preference.OnPreferenceChangeListener) { - mPreference.setOnPreferenceChangeListener( - (Preference.OnPreferenceChangeListener) this); - } - } else { - findAndRemovePreference(screen, getPreferenceKey()); - } - } - // finds the preference recursively and removes it from its parent private void findAndRemovePreference(PreferenceGroup prefGroup, String key) { final int preferenceCount = prefGroup.getPreferenceCount(); diff --git a/src/com/android/settings/notification/NotificationVolumePreferenceController.java b/src/com/android/settings/notification/NotificationVolumePreferenceController.java index 59954620539..c82d04b858c 100644 --- a/src/com/android/settings/notification/NotificationVolumePreferenceController.java +++ b/src/com/android/settings/notification/NotificationVolumePreferenceController.java @@ -56,7 +56,7 @@ public class NotificationVolumePreferenceController extends @Override public int getMuteIcon() { - return com.android.internal.R.drawable.ic_audio_ring_notif_mute; + return R.drawable.ic_notifications_off_24dp; } } diff --git a/src/com/android/settings/notification/RingVolumePreferenceController.java b/src/com/android/settings/notification/RingVolumePreferenceController.java index d58eabd4a78..47bb56fe354 100644 --- a/src/com/android/settings/notification/RingVolumePreferenceController.java +++ b/src/com/android/settings/notification/RingVolumePreferenceController.java @@ -126,12 +126,12 @@ public class RingVolumePreferenceController extends VolumeSeekBarPreferenceContr if (mPreference != null) { if (mRingerMode == AudioManager.RINGER_MODE_VIBRATE) { mMuteIcon = R.drawable.ic_volume_ringer_vibrate; - mPreference.showIcon(com.android.internal.R.drawable.ic_audio_ring_notif_vibrate); + mPreference.showIcon(R.drawable.ic_volume_ringer_vibrate); } else if (mRingerMode == AudioManager.RINGER_MODE_SILENT) { mMuteIcon = R.drawable.ic_notifications_off_24dp; - mPreference.showIcon(com.android.internal.R.drawable.ic_audio_ring_notif_mute); + mPreference.showIcon(R.drawable.ic_notifications_off_24dp); } else { - mPreference.showIcon(com.android.internal.R.drawable.ic_audio_ring_notif); + mPreference.showIcon(R.drawable.ic_notifications); } } } diff --git a/src/com/android/settings/notification/ZenModeSliceBuilder.java b/src/com/android/settings/notification/ZenModeSliceBuilder.java index 0edf214179c..aedd0b3e4c3 100644 --- a/src/com/android/settings/notification/ZenModeSliceBuilder.java +++ b/src/com/android/settings/notification/ZenModeSliceBuilder.java @@ -18,6 +18,8 @@ package com.android.settings.notification; import static android.app.slice.Slice.EXTRA_TOGGLE_STATE; +import static androidx.slice.builders.ListBuilder.ICON_IMAGE; + import android.annotation.ColorInt; import android.app.NotificationManager; import android.app.PendingIntent; diff --git a/src/com/android/settings/search/DeviceIndexFeatureProvider.java b/src/com/android/settings/search/DeviceIndexFeatureProvider.java index bf75ee81c3e..1c25399c8fa 100644 --- a/src/com/android/settings/search/DeviceIndexFeatureProvider.java +++ b/src/com/android/settings/search/DeviceIndexFeatureProvider.java @@ -31,6 +31,7 @@ import com.android.settings.Utils; import com.android.settings.slices.SettingsSliceProvider; import java.util.List; +import java.util.Locale; import java.util.Objects; public interface DeviceIndexFeatureProvider { @@ -39,15 +40,21 @@ public interface DeviceIndexFeatureProvider { String TAG = "DeviceIndex"; String INDEX_VERSION = "settings:index_version"; + String INDEX_LANGUAGE = "settings:language"; // Increment when new items are added to ensure they get pushed to the device index. String VERSION = Build.FINGERPRINT; + // When the device language changes, re-index so Slices trigger in device language. + Locale LANGUAGE = Locale.getDefault(); + boolean isIndexingEnabled(); void index(Context context, CharSequence title, Uri sliceUri, Uri launchUri, List keywords); + void clearIndex(Context context); + default void updateIndex(Context context, boolean force) { if (!isIndexingEnabled()) { Log.w(TAG, "Skipping: device index is not enabled"); @@ -59,12 +66,14 @@ public interface DeviceIndexFeatureProvider { return; } - if (!force && Objects.equals( - Settings.Secure.getString(context.getContentResolver(), INDEX_VERSION), VERSION)) { + if (!force && skipIndex(context)) { // No need to update. return; } + // Prevent scheduling multiple jobs + setIndexState(context); + final ComponentName jobComponent = new ComponentName(context.getPackageName(), DeviceIndexUpdateJobService.class.getName()); final int jobId = context.getResources().getInteger(R.integer.device_index_update); @@ -77,7 +86,6 @@ public interface DeviceIndexFeatureProvider { .setOverrideDeadline(1) .build()); - Settings.Secure.putString(context.getContentResolver(), INDEX_VERSION, VERSION); } static Uri createDeepLink(String s) { @@ -86,4 +94,18 @@ public interface DeviceIndexFeatureProvider { .appendQueryParameter(INTENT, s) .build(); } + + static boolean skipIndex(Context context) { + final boolean isSameVersion = Objects.equals( + Settings.Secure.getString(context.getContentResolver(), INDEX_VERSION), VERSION); + final boolean isSameLanguage = Objects.equals( + Settings.Secure.getString(context.getContentResolver(), INDEX_LANGUAGE), LANGUAGE); + return isSameLanguage && isSameVersion; + } + + static void setIndexState(Context context) { + Settings.Secure.putString(context.getContentResolver(), INDEX_VERSION, VERSION); + Settings.Secure.putString(context.getContentResolver(), INDEX_LANGUAGE, + LANGUAGE.toString()); + } } diff --git a/src/com/android/settings/search/DeviceIndexFeatureProviderImpl.java b/src/com/android/settings/search/DeviceIndexFeatureProviderImpl.java index 7a11bd46789..087ecf83dbc 100644 --- a/src/com/android/settings/search/DeviceIndexFeatureProviderImpl.java +++ b/src/com/android/settings/search/DeviceIndexFeatureProviderImpl.java @@ -31,4 +31,9 @@ public class DeviceIndexFeatureProviderImpl implements DeviceIndexFeatureProvide List keywords) { // Not enabled by default. } + + @Override + public void clearIndex(Context context) { + // Not enabled by default. + } } diff --git a/src/com/android/settings/search/DeviceIndexUpdateJobService.java b/src/com/android/settings/search/DeviceIndexUpdateJobService.java index 19b7d5e60b6..97b0a61ca6b 100644 --- a/src/com/android/settings/search/DeviceIndexUpdateJobService.java +++ b/src/com/android/settings/search/DeviceIndexUpdateJobService.java @@ -25,6 +25,7 @@ import android.content.ContentResolver; import android.content.Intent; import android.net.Uri; import android.net.Uri.Builder; +import android.provider.SettingsSlicesContract; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; @@ -84,11 +85,19 @@ public class DeviceIndexUpdateJobService extends JobService { .scheme(ContentResolver.SCHEME_CONTENT) .authority(SettingsSliceProvider.SLICE_AUTHORITY) .build(); + final Uri platformBaseUri = new Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(SettingsSlicesContract.AUTHORITY) + .build(); final Collection slices = manager.getSliceDescendants(baseUri); + slices.addAll(manager.getSliceDescendants(platformBaseUri)); + if (DEBUG) { Log.d(TAG, "Indexing " + slices.size() + " slices"); } + indexProvider.clearIndex(this /* context */); + for (Uri slice : slices) { if (!mRunningJob) { return; diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java index 3ed6185563c..47736dfac2e 100644 --- a/src/com/android/settings/slices/SettingsSliceProvider.java +++ b/src/com/android/settings/slices/SettingsSliceProvider.java @@ -33,6 +33,7 @@ import android.util.KeyValueListParser; import android.util.Log; import android.util.Pair; +import com.android.settings.location.LocationSliceBuilder; import com.android.settings.overlay.FeatureFactory; import com.android.settings.core.BasePreferenceController; import com.android.settings.wifi.WifiSliceBuilder; @@ -175,6 +176,13 @@ public class SettingsSliceProvider extends SliceProvider { @Override public Slice onBindSlice(Uri sliceUri) { + final Set blockedKeys = getBlockedKeys(); + final String key = sliceUri.getLastPathSegment(); + if (blockedKeys.contains(key)) { + Log.e(TAG, "Requested blocked slice with Uri: " + sliceUri); + return null; + } + // If adding a new Slice, do not directly match Slice URIs. // Use {@link SlicesDatabaseAccessor}. if (WifiCallingSliceHelper.WIFI_CALLING_URI.equals(sliceUri)) { @@ -188,6 +196,8 @@ public class SettingsSliceProvider extends SliceProvider { return ZenModeSliceBuilder.getSlice(getContext()); } else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(sliceUri)) { return BluetoothSliceBuilder.getSlice(getContext()); + } else if (LocationSliceBuilder.LOCATION_URI.equals(sliceUri)) { + return LocationSliceBuilder.getSlice(getContext()); } SliceData cachedSliceData = mSliceWeakDataCache.get(sliceUri); @@ -289,10 +299,17 @@ public class SettingsSliceProvider extends SliceProvider { void loadSlice(Uri uri) { long startBuildTime = System.currentTimeMillis(); - final SliceData sliceData = mSlicesDatabaseAccessor.getSliceDataFromUri(uri); + final SliceData sliceData; + try { + sliceData = mSlicesDatabaseAccessor.getSliceDataFromUri(uri); + } catch (IllegalStateException e) { + Log.e(TAG, "Could not get slice data for uri: " + uri, e); + return; + } final BasePreferenceController controller = SliceBuilderUtils.getPreferenceController( getContext(), sliceData); + final IntentFilter filter = controller.getIntentFilter(); if (filter != null) { registerIntentToUri(filter, uri); @@ -336,7 +353,8 @@ public class SettingsSliceProvider extends SliceProvider { private List getSpecialCasePlatformUris() { return Arrays.asList( WifiSliceBuilder.WIFI_URI, - BluetoothSliceBuilder.BLUETOOTH_URI + BluetoothSliceBuilder.BLUETOOTH_URI, + LocationSliceBuilder.LOCATION_URI ); } diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java index feb7042552d..be433b7e658 100644 --- a/src/com/android/settings/slices/SliceBuilderUtils.java +++ b/src/com/android/settings/slices/SliceBuilderUtils.java @@ -86,8 +86,13 @@ public class SliceBuilderUtils { FeatureFactory.getFactory(context).getMetricsFeatureProvider() .action(context, MetricsEvent.ACTION_SETTINGS_SLICE_REQUESTED, sliceNamePair); - if (controller.getAvailabilityStatus() != AVAILABLE) { - return buildUnavailableSlice(context, sliceData, controller); + if (!controller.isAvailable()) { + // Cannot guarantee setting page is accessible, let the presenter handle error case. + return null; + } + + if (controller.getAvailabilityStatus() == DISABLED_DEPENDENT_SETTING) { + return buildUnavailableSlice(context, sliceData); } switch (sliceData.getSliceType()) { @@ -176,14 +181,6 @@ public class SliceBuilderUtils { return PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */); } - /** - * @return {@link PendingIntent} to the Settings home page. - */ - public static PendingIntent getSettingsIntent(Context context) { - final Intent intent = new Intent(Settings.ACTION_SETTINGS); - return PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */); - } - /** * @return the summary text for a {@link Slice} built for {@param sliceData}. */ @@ -282,6 +279,7 @@ public class SliceBuilderUtils { final PendingIntent actionIntent = getSliderAction(context, sliceData); final PendingIntent contentIntent = getContentPendingIntent(context, sliceData); final IconCompat icon = IconCompat.createWithResource(context, sliceData.getIconResource()); + final CharSequence subtitleText = getSubtitleText(context, controller, sliceData); @ColorInt final int color = Utils.getColorAccent(context); final SliceAction primaryAction = new SliceAction(contentIntent, icon, sliceData.getTitle()); @@ -289,12 +287,14 @@ public class SliceBuilderUtils { return new ListBuilder(context, sliceData.getUri(), ListBuilder.INFINITY) .setAccentColor(color) - .addInputRange(builder -> builder + .setHeader(builder -> builder .setTitle(sliceData.getTitle()) + .setSubtitle(subtitleText) + .setPrimaryAction(primaryAction)) + .addInputRange(builder -> builder .setMax(sliderController.getMaxSteps()) .setValue(sliderController.getSliderPosition()) - .setInputAction(actionIntent) - .setPrimaryAction(primaryAction)) + .setInputAction(actionIntent)) .setKeywords(keywords) .build(); } @@ -355,40 +355,20 @@ public class SliceBuilderUtils { return keywords; } - private static Slice buildUnavailableSlice(Context context, SliceData data, - BasePreferenceController controller) { + private static Slice buildUnavailableSlice(Context context, SliceData data) { final String title = data.getTitle(); final List keywords = buildSliceKeywords(data); @ColorInt final int color = Utils.getColorAccent(context); - final String summary; - final SliceAction primaryAction; + final CharSequence summary = context.getText(R.string.disabled_dependent_setting_summary); final IconCompat icon = IconCompat.createWithResource(context, data.getIconResource()); - - switch (controller.getAvailabilityStatus()) { - case UNSUPPORTED_ON_DEVICE: - summary = context.getString(R.string.unsupported_setting_summary); - primaryAction = new SliceAction(getSettingsIntent(context), icon, title); - break; - case DISABLED_FOR_USER: - summary = context.getString(R.string.disabled_for_user_setting_summary); - primaryAction = new SliceAction(getContentPendingIntent(context, data), icon, - title); - break; - case DISABLED_DEPENDENT_SETTING: - summary = context.getString(R.string.disabled_dependent_setting_summary); - primaryAction = new SliceAction(getContentPendingIntent(context, data), icon, - title); - break; - case CONDITIONALLY_UNAVAILABLE: - default: - summary = context.getString(R.string.unknown_unavailability_setting_summary); - primaryAction = new SliceAction(getSettingsIntent(context), icon, title); - } + final SliceAction primaryAction = new SliceAction(getContentPendingIntent(context, data), + icon, title); return new ListBuilder(context, data.getUri(), ListBuilder.INFINITY) .setAccentColor(color) .addRow(builder -> builder .setTitle(title) + .setTitleItem(icon) .setSubtitle(summary) .setPrimaryAction(primaryAction)) .setKeywords(keywords) diff --git a/src/com/android/settings/widget/TwoStateButtonPreference.java b/src/com/android/settings/widget/TwoStateButtonPreference.java index 6b5fbbb0e11..78d48747b26 100644 --- a/src/com/android/settings/widget/TwoStateButtonPreference.java +++ b/src/com/android/settings/widget/TwoStateButtonPreference.java @@ -18,8 +18,10 @@ package com.android.settings.widget; import android.content.Context; import android.content.res.TypedArray; +import android.support.annotation.VisibleForTesting; import android.support.v4.content.res.TypedArrayUtils; import android.util.AttributeSet; +import android.view.View; import android.widget.Button; import com.android.settings.R; @@ -28,12 +30,21 @@ import com.android.settings.applications.LayoutPreference; /** * Preference that presents a button with two states(On vs Off) */ -public class TwoStateButtonPreference extends LayoutPreference { +public class TwoStateButtonPreference extends LayoutPreference implements + View.OnClickListener { + + private boolean mIsChecked; + private final Button mButtonOn; + private final Button mButtonOff; + public TwoStateButtonPreference(Context context, AttributeSet attrs) { super(context, attrs, TypedArrayUtils.getAttr( context, R.attr.twoStateButtonPreferenceStyle, android.R.attr.preferenceStyle)); - if (attrs != null) { + if (attrs == null) { + mButtonOn = null; + mButtonOff = null; + } else { final TypedArray styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.TwoStateButtonPreference); final int textOnId = styledAttrs.getResourceId( @@ -44,19 +55,52 @@ public class TwoStateButtonPreference extends LayoutPreference { R.string.summary_placeholder); styledAttrs.recycle(); - final Button buttonOn = getStateOnButton(); - buttonOn.setText(textOnId); - final Button buttonOff = getStateOffButton(); - buttonOff.setText(textOffId); + mButtonOn = findViewById(R.id.state_on_button); + mButtonOn.setText(textOnId); + mButtonOn.setOnClickListener(this); + mButtonOff = findViewById(R.id.state_off_button); + mButtonOff.setText(textOffId); + mButtonOff.setOnClickListener(this); + setChecked(isChecked()); } } - public Button getStateOnButton() { - return findViewById(R.id.state_on_button); + @Override + public void onClick(View v) { + final boolean stateOn = v.getId() == R.id.state_on_button; + setChecked(stateOn); + callChangeListener(stateOn); } + public void setChecked(boolean checked) { + // Update state + mIsChecked = checked; + // And update UI + if (checked) { + mButtonOn.setVisibility(View.GONE); + mButtonOff.setVisibility(View.VISIBLE); + } else { + mButtonOn.setVisibility(View.VISIBLE); + mButtonOff.setVisibility(View.GONE); + } + } + public boolean isChecked() { + return mIsChecked; + } + + public void setButtonEnabled(boolean enabled) { + mButtonOn.setEnabled(enabled); + mButtonOff.setEnabled(enabled); + } + + @VisibleForTesting + public Button getStateOnButton() { + return mButtonOn; + } + + @VisibleForTesting public Button getStateOffButton() { - return findViewById(R.id.state_off_button); + return mButtonOff; } } \ No newline at end of file diff --git a/src/com/android/settings/widget/TwoStateButtonPreferenceController.java b/src/com/android/settings/widget/TwoStateButtonPreferenceController.java deleted file mode 100644 index 47699ef0a7b..00000000000 --- a/src/com/android/settings/widget/TwoStateButtonPreferenceController.java +++ /dev/null @@ -1,78 +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.widget; - -import android.content.Context; -import android.support.v7.preference.PreferenceScreen; -import android.view.View; -import android.widget.Button; - -import com.android.settings.R; -import com.android.settings.core.BasePreferenceController; - -/** - * Controller to update the button with two states(On vs Off). - */ -public abstract class TwoStateButtonPreferenceController extends BasePreferenceController - implements View.OnClickListener { - private Button mButtonOn; - private Button mButtonOff; - - public TwoStateButtonPreferenceController(Context context, String key) { - super(context, key); - } - - @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - final TwoStateButtonPreference preference = - (TwoStateButtonPreference) screen.findPreference(getPreferenceKey()); - mButtonOn = preference.getStateOnButton(); - mButtonOn.setOnClickListener(this); - mButtonOff = preference.getStateOffButton(); - mButtonOff.setOnClickListener(this); - } - - protected void setButtonVisibility(boolean stateOn) { - if (stateOn) { - mButtonOff.setVisibility(View.GONE); - mButtonOn.setVisibility(View.VISIBLE); - } else { - mButtonOff.setVisibility(View.VISIBLE); - mButtonOn.setVisibility(View.GONE); - } - } - - protected void setButtonEnabled(boolean enabled) { - mButtonOn.setEnabled(enabled); - mButtonOff.setEnabled(enabled); - } - - @Override - public void onClick(View v) { - final boolean stateOn = v.getId() == R.id.state_on_button; - onButtonClicked(stateOn); - } - - /** - * Callback when button is clicked - * - * @param stateOn {@code true} if stateOn button is clicked, otherwise it means stateOff - * button is clicked - */ - public abstract void onButtonClicked(boolean stateOn); -} \ No newline at end of file diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java index 79196f16d45..26e7b5724db 100644 --- a/src/com/android/settings/wifi/WifiConfigController.java +++ b/src/com/android/settings/wifi/WifiConfigController.java @@ -220,8 +220,6 @@ public class WifiConfigController implements TextWatcher, mMeteredSettingsSpinner = mView.findViewById(R.id.metered_settings); mHiddenSettingsSpinner = mView.findViewById(R.id.hidden_settings); mHiddenSettingsSpinner.setOnItemSelectedListener(this); - mHiddenSettingsSpinner.setVisibility(View.GONE); - mHiddenSettingsSpinner.setEnabled(false); mHiddenWarningView = mView.findViewById(R.id.hidden_settings_warning); mHiddenWarningView.setVisibility( mHiddenSettingsSpinner.getSelectedItemPosition() == NOT_HIDDEN_NETWORK @@ -241,8 +239,7 @@ public class WifiConfigController implements TextWatcher, showProxyFields(); mView.findViewById(R.id.wifi_advanced_toggle).setVisibility(View.VISIBLE); // Hidden option can be changed only when the user adds a network manually. - mHiddenSettingsSpinner.setVisibility(View.VISIBLE); - mHiddenSettingsSpinner.setEnabled(true); + mView.findViewById(R.id.hidden_settings_field).setVisibility(View.VISIBLE); ((CheckBox) mView.findViewById(R.id.wifi_advanced_togglebox)) .setOnCheckedChangeListener(this); diff --git a/src/com/android/settings/wifi/WifiSliceBuilder.java b/src/com/android/settings/wifi/WifiSliceBuilder.java index 96d1b82b86a..7df7f19ad78 100644 --- a/src/com/android/settings/wifi/WifiSliceBuilder.java +++ b/src/com/android/settings/wifi/WifiSliceBuilder.java @@ -19,6 +19,8 @@ package com.android.settings.wifi; import static android.app.slice.Slice.EXTRA_TOGGLE_STATE; import static android.provider.SettingsSlicesContract.KEY_WIFI; +import static androidx.slice.builders.ListBuilder.ICON_IMAGE; + import android.annotation.ColorInt; import android.app.PendingIntent; import android.content.ContentResolver; diff --git a/src/com/android/settings/wifi/calling/WifiCallingSliceHelper.java b/src/com/android/settings/wifi/calling/WifiCallingSliceHelper.java index a554e74352f..cec8545bfb7 100644 --- a/src/com/android/settings/wifi/calling/WifiCallingSliceHelper.java +++ b/src/com/android/settings/wifi/calling/WifiCallingSliceHelper.java @@ -25,6 +25,7 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.PersistableBundle; +import android.provider.Settings; import android.support.v4.graphics.drawable.IconCompat; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; @@ -121,7 +122,7 @@ public class WifiCallingSliceHelper { return getNonActionableWifiCallingSlice( mContext.getString(R.string.wifi_calling_settings_title), mContext.getString(R.string.wifi_calling_not_supported, carrierName), - sliceUri, SliceBuilderUtils.getSettingsIntent(mContext)); + sliceUri, getSettingsIntent(mContext)); } final ImsManager imsManager = getImsManager(subId); @@ -132,7 +133,7 @@ public class WifiCallingSliceHelper { return getNonActionableWifiCallingSlice( mContext.getString(R.string.wifi_calling_settings_title), mContext.getString(R.string.wifi_calling_not_supported, carrierName), - sliceUri, SliceBuilderUtils.getSettingsIntent(mContext)); + sliceUri, getSettingsIntent(mContext)); } try { @@ -338,6 +339,14 @@ public class WifiCallingSliceHelper { return intent; } + /** + * @return {@link PendingIntent} to the Settings home page. + */ + public static PendingIntent getSettingsIntent(Context context) { + final Intent intent = new Intent(Settings.ACTION_SETTINGS); + return PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */); + } + private PendingIntent getBroadcastIntent(String action) { final Intent intent = new Intent(action); intent.setClass(mContext, SliceBroadcastReceiver.class); diff --git a/tests/robotests/src/com/android/settings/applications/AppStateNotificationBridgeTest.java b/tests/robotests/src/com/android/settings/applications/AppStateNotificationBridgeTest.java index 9437a00766f..8e3bb4254a0 100644 --- a/tests/robotests/src/com/android/settings/applications/AppStateNotificationBridgeTest.java +++ b/tests/robotests/src/com/android/settings/applications/AppStateNotificationBridgeTest.java @@ -36,17 +36,21 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.usage.IUsageStatsManager; import android.app.usage.UsageEvents; import android.app.usage.UsageEvents.Event; -import android.app.usage.UsageStatsManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.os.Looper; import android.os.Parcel; +import android.os.RemoteException; +import android.os.UserHandle; +import android.os.UserManager; import android.view.ViewGroup; import android.widget.Switch; @@ -79,7 +83,9 @@ public class AppStateNotificationBridgeTest { @Mock private ApplicationsState mState; @Mock - private UsageStatsManager mUsageStats; + private IUsageStatsManager mUsageStats; + @Mock + private UserManager mUserManager; @Mock private NotificationBackend mBackend; private Context mContext; @@ -92,10 +98,12 @@ public class AppStateNotificationBridgeTest { when(mState.getBackgroundLooper()).thenReturn(mock(Looper.class)); when(mBackend.getNotificationsBanned(anyString(), anyInt())).thenReturn(true); when(mBackend.isSystemApp(any(), any())).thenReturn(true); + // most tests assume no work profile + when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{}); mContext = RuntimeEnvironment.application.getApplicationContext(); mBridge = new AppStateNotificationBridge(mContext, mState, - mock(AppStateBaseBridge.Callback.class), mUsageStats, mBackend); + mock(AppStateBaseBridge.Callback.class), mUsageStats, mUserManager, mBackend); } private AppEntry getMockAppEntry(String pkg) { @@ -115,14 +123,15 @@ public class AppStateNotificationBridgeTest { } @Test - public void testGetAggregatedUsageEvents_noEvents() { - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(mock(UsageEvents.class)); + public void testGetAggregatedUsageEvents_noEvents() throws Exception { + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) + .thenReturn(mock(UsageEvents.class)); assertThat(mBridge.getAggregatedUsageEvents()).isEmpty(); } @Test - public void testGetAggregatedUsageEvents_onlyNotificationEvents() { + public void testGetAggregatedUsageEvents_onlyNotificationEvents() throws Exception { List events = new ArrayList<>(); Event good = new Event(); good.mEventType = Event.NOTIFICATION_INTERRUPTION; @@ -136,14 +145,15 @@ public class AppStateNotificationBridgeTest { events.add(bad); UsageEvents usageEvents = getUsageEvents(events); - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents); + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) + .thenReturn(usageEvents); Map map = mBridge.getAggregatedUsageEvents(); - assertThat(map.get(PKG1).sentCount).isEqualTo(1); + assertThat(map.get(mBridge.getKey(0, PKG1)).sentCount).isEqualTo(1); } @Test - public void testGetAggregatedUsageEvents_multipleEventsAgg() { + public void testGetAggregatedUsageEvents_multipleEventsAgg() throws Exception { List events = new ArrayList<>(); Event good = new Event(); good.mEventType = Event.NOTIFICATION_INTERRUPTION; @@ -157,15 +167,16 @@ public class AppStateNotificationBridgeTest { events.add(good1); UsageEvents usageEvents = getUsageEvents(events); - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents); + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) + .thenReturn(usageEvents); Map map = mBridge.getAggregatedUsageEvents(); - assertThat(map.get(PKG1).sentCount).isEqualTo(2); - assertThat(map.get(PKG1).lastSent).isEqualTo(6); + assertThat(map.get(mBridge.getKey(0, PKG1)).sentCount).isEqualTo(2); + assertThat(map.get(mBridge.getKey(0, PKG1)).lastSent).isEqualTo(6); } @Test - public void testGetAggregatedUsageEvents_multiplePkgs() { + public void testGetAggregatedUsageEvents_multiplePkgs() throws Exception { List events = new ArrayList<>(); Event good = new Event(); good.mEventType = Event.NOTIFICATION_INTERRUPTION; @@ -179,19 +190,21 @@ public class AppStateNotificationBridgeTest { events.add(good1); UsageEvents usageEvents = getUsageEvents(events); - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents); + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) + .thenReturn(usageEvents); Map map = mBridge.getAggregatedUsageEvents(); - assertThat(map.get(PKG1).sentCount).isEqualTo(1); - assertThat(map.get(PKG2).sentCount).isEqualTo(1); - assertThat(map.get(PKG1).lastSent).isEqualTo(6); - assertThat(map.get(PKG2).lastSent).isEqualTo(1); + assertThat(map.get(mBridge.getKey(0, PKG1)).sentCount).isEqualTo(1); + assertThat(map.get(mBridge.getKey(0, PKG2)).sentCount).isEqualTo(1); + assertThat(map.get(mBridge.getKey(0, PKG1)).lastSent).isEqualTo(6); + assertThat(map.get(mBridge.getKey(0, PKG2)).lastSent).isEqualTo(1); } @Test - public void testLoadAllExtraInfo_noEvents() { - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(mock(UsageEvents.class)); + public void testLoadAllExtraInfo_noEvents() throws RemoteException { + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) + .thenReturn(mock(UsageEvents.class)); ArrayList apps = new ArrayList<>(); apps.add(getMockAppEntry(PKG1)); when(mSession.getAllApps()).thenReturn(apps); @@ -201,7 +214,7 @@ public class AppStateNotificationBridgeTest { } @Test - public void testLoadAllExtraInfo_multipleEventsAgg() { + public void testLoadAllExtraInfo_multipleEventsAgg() throws RemoteException { List events = new ArrayList<>(); for (int i = 0; i < 7; i++) { Event good = new Event(); @@ -212,7 +225,8 @@ public class AppStateNotificationBridgeTest { } UsageEvents usageEvents = getUsageEvents(events); - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents); + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) + .thenReturn(usageEvents); ArrayList apps = new ArrayList<>(); apps.add(getMockAppEntry(PKG1)); @@ -229,7 +243,7 @@ public class AppStateNotificationBridgeTest { } @Test - public void testLoadAllExtraInfo_multiplePkgs() { + public void testLoadAllExtraInfo_multiplePkgs() throws RemoteException { List events = new ArrayList<>(); for (int i = 0; i < 8; i++) { Event good = new Event(); @@ -245,7 +259,8 @@ public class AppStateNotificationBridgeTest { events.add(good1); UsageEvents usageEvents = getUsageEvents(events); - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents); + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) + .thenReturn(usageEvents); ArrayList apps = new ArrayList<>(); apps.add(getMockAppEntry(PKG1)); @@ -265,8 +280,66 @@ public class AppStateNotificationBridgeTest { } @Test - public void testUpdateExtraInfo_noEvents() { - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(mock(UsageEvents.class)); + public void testLoadAllExtraInfo_multipleUsers() throws RemoteException { + // has work profile + when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{1}); + mBridge = new AppStateNotificationBridge(mContext, mState, + mock(AppStateBaseBridge.Callback.class), mUsageStats, mUserManager, mBackend); + + List eventsProfileOwner = new ArrayList<>(); + for (int i = 0; i < 8; i++) { + Event good = new Event(); + good.mEventType = Event.NOTIFICATION_INTERRUPTION; + good.mPackage = PKG1; + good.mTimeStamp = i; + eventsProfileOwner.add(good); + } + + List eventsProfile = new ArrayList<>(); + for (int i = 0; i < 4; i++) { + Event good = new Event(); + good.mEventType = Event.NOTIFICATION_INTERRUPTION; + good.mPackage = PKG1; + good.mTimeStamp = i; + eventsProfile.add(good); + } + + UsageEvents usageEventsOwner = getUsageEvents(eventsProfileOwner); + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), eq(0), anyString())) + .thenReturn(usageEventsOwner); + + UsageEvents usageEventsProfile = getUsageEvents(eventsProfile); + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), eq(1), anyString())) + .thenReturn(usageEventsProfile); + + ArrayList apps = new ArrayList<>(); + AppEntry owner = getMockAppEntry(PKG1); + owner.info.uid = 1; + apps.add(owner); + + AppEntry profile = getMockAppEntry(PKG1); + profile.info.uid = UserHandle.PER_USER_RANGE + 1; + apps.add(profile); + when(mSession.getAllApps()).thenReturn(apps); + + mBridge.loadAllExtraInfo(); + + assertThat(((NotificationsSentState) apps.get(0).extraInfo).sentCount).isEqualTo(8); + assertThat(((NotificationsSentState) apps.get(0).extraInfo).lastSent).isEqualTo(7); + assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentWeekly).isEqualTo(0); + assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentDaily).isEqualTo(1); + + assertThat(((NotificationsSentState) apps.get(1).extraInfo).sentCount).isEqualTo(4); + assertThat(((NotificationsSentState) apps.get(1).extraInfo).lastSent).isEqualTo(3); + assertThat(((NotificationsSentState) apps.get(1).extraInfo).avgSentWeekly).isEqualTo(4); + assertThat(((NotificationsSentState) apps.get(1).extraInfo).avgSentDaily).isEqualTo(1); + } + + @Test + public void testUpdateExtraInfo_noEvents() throws RemoteException { + when(mUsageStats.queryEventsForPackageForUser( + anyLong(), anyLong(), anyInt(), anyString(), anyString())) + .thenReturn(mock(UsageEvents.class)); AppEntry entry = getMockAppEntry(PKG1); mBridge.updateExtraInfo(entry, "", 0); @@ -274,7 +347,7 @@ public class AppStateNotificationBridgeTest { } @Test - public void testUpdateExtraInfo_multipleEventsAgg() { + public void testUpdateExtraInfo_multipleEventsAgg() throws RemoteException { List events = new ArrayList<>(); for (int i = 0; i < 13; i++) { Event good = new Event(); @@ -285,7 +358,8 @@ public class AppStateNotificationBridgeTest { } UsageEvents usageEvents = getUsageEvents(events); - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents); + when(mUsageStats.queryEventsForPackageForUser( + anyLong(), anyLong(), anyInt(), anyString(), anyString())).thenReturn(usageEvents); AppEntry entry = getMockAppEntry(PKG1); mBridge.updateExtraInfo(entry, "", 0); diff --git a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java index 66fa212023b..89b7d5e9e31 100644 --- a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java +++ b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java @@ -40,6 +40,7 @@ import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.os.Looper; +import android.os.UserManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.Menu; @@ -272,6 +273,10 @@ public class ManageApplicationsTest { @Test public void applicationsAdapter_onBindViewHolder_updateSwitch_notifications() { ManageApplications manageApplications = mock(ManageApplications.class); + when(manageApplications.getActivity()).thenReturn(mock(Activity.class)); + UserManager um = mock(UserManager.class); + when(um.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{}); + ReflectionHelpers.setField(manageApplications, "mUserManager", um); manageApplications.mListType = LIST_TYPE_NOTIFICATION; ApplicationViewHolder holder = mock(ApplicationViewHolder.class); ReflectionHelpers.setField(holder, "itemView", mock(View.class)); @@ -293,6 +298,9 @@ public class ManageApplicationsTest { manageApplications.mListType = LIST_TYPE_MAIN; ApplicationViewHolder holder = mock(ApplicationViewHolder.class); ReflectionHelpers.setField(holder, "itemView", mock(View.class)); + UserManager um = mock(UserManager.class); + when(um.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{}); + ReflectionHelpers.setField(manageApplications, "mUserManager", um); ManageApplications.ApplicationsAdapter adapter = new ManageApplications.ApplicationsAdapter(mState, manageApplications, mock(AppFilterItem.class), @@ -308,6 +316,10 @@ public class ManageApplicationsTest { @Test public void sortOrderSavedOnRebuild() { ManageApplications manageApplications = mock(ManageApplications.class); + when(manageApplications.getActivity()).thenReturn(mock(Activity.class)); + UserManager um = mock(UserManager.class); + when(um.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{}); + ReflectionHelpers.setField(manageApplications, "mUserManager", um); manageApplications.mListType = LIST_TYPE_NOTIFICATION; manageApplications.mSortOrder = -1; ManageApplications.ApplicationsAdapter adapter = diff --git a/tests/robotests/src/com/android/settings/development/ConnectivityMonitorPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/ConnectivityMonitorPreferenceControllerTest.java deleted file mode 100644 index 9a02936c966..00000000000 --- a/tests/robotests/src/com/android/settings/development/ConnectivityMonitorPreferenceControllerTest.java +++ /dev/null @@ -1,191 +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.development; - -import static com.android.settings.development.ConnectivityMonitorPreferenceController.ENG_BUILD; -import static com.android.settings.development.ConnectivityMonitorPreferenceController.USERDEBUG_BUILD; -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.SystemProperties; -import android.support.v14.preference.SwitchPreference; -import android.support.v7.preference.PreferenceScreen; - -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 org.robolectric.annotation.Config; - -@RunWith(SettingsRobolectricTestRunner.class) -public class ConnectivityMonitorPreferenceControllerTest { - - private static final String USER_BUILD = "user"; - - @Mock - private PreferenceScreen mScreen; - @Mock - private SwitchPreference mPreference; - - private Context mContext; - private ConnectivityMonitorPreferenceController mController; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; - mController = new ConnectivityMonitorPreferenceController(mContext); - when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); - mController.displayPreference(mScreen); - } - - @Test - public void isAvailable_trueShowFlagWithUserdebugBuild_shouldReturnTrue() { - SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD); - - assertThat(mController.isAvailable()).isTrue(); - } - - @Test - public void isAvailable_trueShowFlagWithEngBuild_shouldReturnTrue() { - SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, ENG_BUILD); - - assertThat(mController.isAvailable()).isTrue(); - } - - @Test - public void isAvailable_trueShowFlagWithUserBuild_shouldReturnFalse() { - SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, USER_BUILD); - - assertThat(mController.isAvailable()).isFalse(); - } - - @Test - @Config(qualifiers = "mcc999") - public void isAvailable_falseShowFlagWithUserdebugBuild_shouldReturnFalse() { - SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD); - - assertThat(mController.isAvailable()).isFalse(); - } - - @Test - @Config(qualifiers = "mcc999") - public void isAvailable_falseShowFlagWithEngBuild_shouldReturnFalse() { - SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, ENG_BUILD); - - assertThat(mController.isAvailable()).isFalse(); - } - - @Test - @Config(qualifiers = "mcc999") - public void isAvailable_falseShowFlagWithUserBuild_shouldReturnFalse() { - SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, USER_BUILD); - - assertThat(mController.isAvailable()).isFalse(); - } - - @Test - public void updateState_connectivityMonitorEnabled_shouldCheckedPreference() { - SystemProperties.set(ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR, - ConnectivityMonitorPreferenceController.ENABLED_STATUS); - SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD); - - mController.updateState(mPreference); - - verify(mPreference).setChecked(true); - } - - @Test - public void updateState_connectivityMonitorUserEnabled_shouldCheckedPreference() { - SystemProperties.set(ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR, - ConnectivityMonitorPreferenceController.USER_ENABLED_STATUS); - SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD); - - mController.updateState(mPreference); - - verify(mPreference).setChecked(true); - } - - @Test - public void updateState_connectivityMonitorDisabled_shouldUncheckedPreference() { - SystemProperties.set(ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR, - ConnectivityMonitorPreferenceController.DISABLED_STATUS); - SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD); - - mController.updateState(mPreference); - - verify(mPreference).setChecked(false); - } - - @Test - public void updateState_connectivityMonitorUserDisabled_shouldUncheckedPreference() { - SystemProperties.set(ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR, - ConnectivityMonitorPreferenceController.USER_DISABLED_STATUS); - SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD); - - mController.updateState(mPreference); - - verify(mPreference).setChecked(false); - } - - @Test - public void onPreferenceChange_preferenceChecked_shouldEnableConnectivityMonitor() { - SystemProperties.set( - ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR, - ConnectivityMonitorPreferenceController.USER_ENABLED_STATUS); - - mController.handlePreferenceTreeClick(mPreference); - - assertThat(ConnectivityMonitorPreferenceController.USER_ENABLED_STATUS).isEqualTo( - SystemProperties.get( - ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR, - ConnectivityMonitorPreferenceController.DISABLED_STATUS)); - } - - @Test - public void onPreferenceChange_preferenceUnchecked_shouldDisableConnectivityMonitor() { - SystemProperties.set( - ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR, - ConnectivityMonitorPreferenceController.USER_DISABLED_STATUS); - - mController.handlePreferenceTreeClick(mPreference); - - assertThat(ConnectivityMonitorPreferenceController.USER_DISABLED_STATUS).isEqualTo( - SystemProperties.get( - ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR, - ConnectivityMonitorPreferenceController.DISABLED_STATUS)); - } - - @Test - public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() { - mController.onDeveloperOptionsSwitchDisabled(); - - String mode = SystemProperties.get( - ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR, - null /* default */); - - assertThat(mode).isEqualTo(ConnectivityMonitorPreferenceController.USER_DISABLED_STATUS); - verify(mPreference).setEnabled(false); - verify(mPreference).setChecked(false); - } -} diff --git a/tests/robotests/src/com/android/settings/display/SystemUiThemePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/SystemUiThemePreferenceControllerTest.java new file mode 100644 index 00000000000..83fb3eb4186 --- /dev/null +++ b/tests/robotests/src/com/android/settings/display/SystemUiThemePreferenceControllerTest.java @@ -0,0 +1,88 @@ +/* + * 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.display; + +import static android.provider.Settings.Secure.THEME_MODE; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.provider.Settings; +import android.support.v7.preference.ListPreference; +import android.support.v7.preference.PreferenceScreen; + +import com.android.settings.R; +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; + +@RunWith(SettingsRobolectricTestRunner.class) +public class SystemUiThemePreferenceControllerTest { + + @Mock + private PreferenceScreen mPreferenceScreen; + @Mock + private ListPreference mListPreference; + private Context mContext; + private SystemUiThemePreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + when(mPreferenceScreen.findPreference(anyString())).thenReturn(mListPreference); + CharSequence[] entries = mContext.getResources().getStringArray( + R.array.systemui_theme_entries); + when(mListPreference.getEntries()).thenReturn(entries); + mController = spy(new SystemUiThemePreferenceController(mContext, "systemui_theme")); + } + + @Test + public void displayPreference_readsSetting() { + Settings.Secure.putInt(mContext.getContentResolver(), THEME_MODE, 2); + mController.displayPreference(mPreferenceScreen); + verify(mListPreference).setValue(eq("2")); + } + + @Test + public void onPreferenceChange_writesSetting() { + Settings.Secure.putInt(mContext.getContentResolver(), THEME_MODE, 2); + mController.displayPreference(mPreferenceScreen); + mController.onPreferenceChange(mListPreference, "0"); + int value = Settings.Secure.getInt(mContext.getContentResolver(), THEME_MODE, 2); + assertThat(value).isEqualTo(0); + } + + @Test + public void onPreferenceChange_updatesSummary() { + mController.displayPreference(mPreferenceScreen); + mController.onPreferenceChange(mListPreference, "0"); + verify(mController).getSummary(); + } + +} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerTest.java index 14f6533f0f3..641a15f4d13 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerTest.java @@ -21,17 +21,13 @@ import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; -import android.arch.lifecycle.LifecycleOwner; import android.content.Context; import android.os.PowerManager; import android.support.v7.preference.PreferenceScreen; -import android.view.View; import android.widget.Button; -import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.widget.TwoStateButtonPreference; -import com.android.settingslib.core.lifecycle.Lifecycle; import org.junit.Before; import org.junit.Test; @@ -41,6 +37,7 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowPowerManager; +import org.robolectric.util.ReflectionHelpers; @RunWith(SettingsRobolectricTestRunner.class) @Config(shadows = ShadowPowerManager.class) @@ -48,67 +45,58 @@ public class BatterySaverButtonPreferenceControllerTest { private BatterySaverButtonPreferenceController mController; private Context mContext; - private Lifecycle mLifecycle; - private LifecycleOwner mLifecycleOwner; private Button mButtonOn; private Button mButtonOff; private PowerManager mPowerManager; - @Mock private TwoStateButtonPreference mPreference; + @Mock private PreferenceScreen mPreferenceScreen; @Before public void setUp() { MockitoAnnotations.initMocks(this); - - mLifecycleOwner = () -> mLifecycle; - mLifecycle = new Lifecycle(mLifecycleOwner); mContext = spy(RuntimeEnvironment.application); + mButtonOn = new Button(mContext); + mButtonOff = new Button(mContext); mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); + mPreference = spy(new TwoStateButtonPreference(mContext, null /* AttributeSet */)); + ReflectionHelpers.setField(mPreference, "mButtonOn", mButtonOn); + ReflectionHelpers.setField(mPreference, "mButtonOff", mButtonOff); doReturn(mPreference).when(mPreferenceScreen).findPreference(anyString()); - mButtonOn = new Button(mContext); - mButtonOn.setId(R.id.state_on_button); - doReturn(mButtonOn).when(mPreference).getStateOnButton(); - mButtonOff = new Button(mContext); - mButtonOff.setId(R.id.state_off_button); - doReturn(mButtonOff).when(mPreference).getStateOffButton(); - - mController = new BatterySaverButtonPreferenceController(mContext, mLifecycle); + mController = new BatterySaverButtonPreferenceController(mContext, "test_key"); mController.displayPreference(mPreferenceScreen); } @Test - public void testUpdateState_lowPowerOn_displayButtonOff() { + public void updateState_lowPowerOn_preferenceIsChecked() { mPowerManager.setPowerSaveMode(true); mController.updateState(mPreference); - assertThat(mButtonOn.getVisibility()).isEqualTo(View.GONE); - assertThat(mButtonOff.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mPreference.isChecked()).isTrue(); } @Test - public void testUpdateState_lowPowerOff_displayButtonOn() { + public void testUpdateState_lowPowerOff_preferenceIsUnchecked() { mPowerManager.setPowerSaveMode(false); mController.updateState(mPreference); - assertThat(mButtonOn.getVisibility()).isEqualTo(View.VISIBLE); - assertThat(mButtonOff.getVisibility()).isEqualTo(View.GONE); + assertThat(mPreference.isChecked()).isFalse(); } @Test - public void testOnClick_clickButtonOn_setPowerSaveMode() { - mController.onClick(mButtonOn); + public void setChecked_on_setPowerSaveMode() { + mController.setChecked(true); assertThat(mPowerManager.isPowerSaveMode()).isTrue(); } @Test - public void testOnClick_clickButtonOff_clearPowerSaveMode() { - mController.onClick(mButtonOff); + public void setChecked_off_unsetPowerSaveMode() { + mController.setChecked(false); assertThat(mPowerManager.isPowerSaveMode()).isFalse(); } diff --git a/tests/robotests/src/com/android/settings/location/LocationSliceBuilderTest.java b/tests/robotests/src/com/android/settings/location/LocationSliceBuilderTest.java new file mode 100644 index 00000000000..22928bfee95 --- /dev/null +++ b/tests/robotests/src/com/android/settings/location/LocationSliceBuilderTest.java @@ -0,0 +1,65 @@ +package com.android.settings.location; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; + +import android.content.Context; +import android.content.res.Resources; +import android.support.v4.graphics.drawable.IconCompat; + +import com.android.settings.R; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.SliceTester; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RuntimeEnvironment; + +import java.util.List; + +import androidx.slice.Slice; +import androidx.slice.SliceItem; +import androidx.slice.SliceMetadata; +import androidx.slice.SliceProvider; +import androidx.slice.core.SliceAction; +import androidx.slice.widget.SliceLiveData; + +@RunWith(SettingsRobolectricTestRunner.class) +public class LocationSliceBuilderTest { + + private Context mContext; + + @Before + public void setUp() { + mContext = spy(RuntimeEnvironment.application); + + // Prevent crash in SliceMetadata. + Resources resources = spy(mContext.getResources()); + doReturn(60).when(resources).getDimensionPixelSize(anyInt()); + doReturn(resources).when(mContext).getResources(); + + // Set-up specs for SliceMetadata. + SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); + } + + @Test + public void getLocationSlice_correctSliceContent() { + final Slice LocationSlice = LocationSliceBuilder.getSlice(mContext); + final SliceMetadata metadata = SliceMetadata.from(mContext, LocationSlice); + + final List toggles = metadata.getToggles(); + assertThat(toggles).isEmpty(); + + final SliceAction primaryAction = metadata.getPrimaryAction(); + final IconCompat expectedToggleIcon = IconCompat.createWithResource(mContext, + R.drawable.ic_signal_location); + assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedToggleIcon.toString()); + + final List sliceItems = LocationSlice.getItems(); + SliceTester.assertTitle(sliceItems, mContext.getString(R.string.location_settings_title)); + } +} diff --git a/tests/robotests/src/com/android/settings/search/DeviceIndexFeatureProviderTest.java b/tests/robotests/src/com/android/settings/search/DeviceIndexFeatureProviderTest.java index d4c15802b99..a900db033bc 100644 --- a/tests/robotests/src/com/android/settings/search/DeviceIndexFeatureProviderTest.java +++ b/tests/robotests/src/com/android/settings/search/DeviceIndexFeatureProviderTest.java @@ -23,6 +23,7 @@ import static org.mockito.Mockito.when; import android.app.Activity; import android.app.job.JobScheduler; +import android.os.Build; import android.provider.Settings; import com.android.settings.testutils.FakeFeatureFactory; @@ -76,4 +77,51 @@ public class DeviceIndexFeatureProviderTest { mProvider.updateIndex(mActivity, false); verify(jobScheduler).schedule(any()); } + + @Test + public void updateIndex_enabled_provisioned_newBuild_shouldIndex() { + Settings.Global.putInt(mActivity.getContentResolver(), + Settings.Global.DEVICE_PROVISIONED, 1); + DeviceIndexFeatureProvider.setIndexState(mActivity); + Settings.Global.putString(mActivity.getContentResolver(), + DeviceIndexFeatureProvider.INDEX_VERSION, "new version"); + Settings.Global.putString(mActivity.getContentResolver(), + DeviceIndexFeatureProvider.LANGUAGE.toString(), + DeviceIndexFeatureProvider.INDEX_LANGUAGE); + JobScheduler jobScheduler = mock(JobScheduler.class); + when(mProvider.isIndexingEnabled()).thenReturn(true); + when(mActivity.getSystemService(JobScheduler.class)).thenReturn(jobScheduler); + + mProvider.updateIndex(mActivity, false); + verify(jobScheduler).schedule(any()); + } + + @Test + public void updateIndex_enabled_provisioned_newIndex_shouldIndex() { + Settings.Global.putInt(mActivity.getContentResolver(), + Settings.Global.DEVICE_PROVISIONED, 1); + DeviceIndexFeatureProvider.setIndexState(mActivity); + Settings.Global.putString(mActivity.getContentResolver(), + DeviceIndexFeatureProvider.INDEX_LANGUAGE, "new language"); + JobScheduler jobScheduler = mock(JobScheduler.class); + when(mProvider.isIndexingEnabled()).thenReturn(true); + when(mActivity.getSystemService(JobScheduler.class)).thenReturn(jobScheduler); + + mProvider.updateIndex(mActivity, false); + verify(jobScheduler).schedule(any()); + } + + @Test + public void updateIndex_enabled_provisioned_sameBuild_sameLang_shouldNotIndex() { + Settings.Global.putInt(mActivity.getContentResolver(), + Settings.Global.DEVICE_PROVISIONED, 1); + DeviceIndexFeatureProvider.setIndexState(mActivity); + JobScheduler jobScheduler = mock(JobScheduler.class); + when(mProvider.isIndexingEnabled()).thenReturn(true); + when(mActivity.getSystemService(JobScheduler.class)).thenReturn(jobScheduler); + + mProvider.updateIndex(mActivity, false); + + verify(mProvider, never()).index(any(), any(), any(), any(), any()); + } } diff --git a/tests/robotests/src/com/android/settings/search/DeviceIndexUpdateJobServiceTest.java b/tests/robotests/src/com/android/settings/search/DeviceIndexUpdateJobServiceTest.java index ec16893de24..b5de9737db2 100644 --- a/tests/robotests/src/com/android/settings/search/DeviceIndexUpdateJobServiceTest.java +++ b/tests/robotests/src/com/android/settings/search/DeviceIndexUpdateJobServiceTest.java @@ -124,6 +124,7 @@ public class DeviceIndexUpdateJobServiceTest { DeviceIndexFeatureProvider indexFeatureProvider = FakeFeatureFactory.getFactory(mActivity) .getDeviceIndexFeatureProvider(); + verify(indexFeatureProvider).clearIndex(any()); verify(indexFeatureProvider, times(1)).index(any(), any(), any(), any(), any()); } diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java index 722f481d10f..df960d8a912 100644 --- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java +++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java @@ -22,19 +22,23 @@ import static android.content.ContentResolver.SCHEME_CONTENT; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.slice.SliceManager; +import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.os.StrictMode; import android.provider.SettingsSlicesContract; +import android.util.ArraySet; +import com.android.settings.location.LocationSliceBuilder; import com.android.settings.wifi.WifiSliceBuilder; import com.android.settings.bluetooth.BluetoothSliceBuilder; import com.android.settings.notification.ZenModeSliceBuilder; @@ -54,6 +58,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Set; import androidx.slice.Slice; @@ -81,7 +86,8 @@ public class SettingsSliceProviderTest { private static final List SPECIAL_CASE_PLATFORM_URIS = Arrays.asList( WifiSliceBuilder.WIFI_URI, - BluetoothSliceBuilder.BLUETOOTH_URI + BluetoothSliceBuilder.BLUETOOTH_URI, + LocationSliceBuilder.LOCATION_URI ); private static final List SPECIAL_CASE_OEM_URIS = Arrays.asList( @@ -189,6 +195,24 @@ public class SettingsSliceProviderTest { assertThat(newThreadPolicy.toString()).isEqualTo(oldThreadPolicy.toString()); } + @Test + public void onBindSlice_requestsBlockedSlice_retunsNull() { + final String blockedKey = "blocked_key"; + final Set blockedSet = new ArraySet<>(); + blockedSet.add(blockedKey); + doReturn(blockedSet).when(mProvider).getBlockedKeys(); + final Uri blockedUri = new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(SettingsSliceProvider.SLICE_AUTHORITY) + .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) + .appendPath(blockedKey) + .build(); + + final Slice slice = mProvider.onBindSlice(blockedUri); + + assertThat(slice).isNull(); + } + @Test public void testLoadSlice_cachedEntryRemovedOnUnpin() { SliceData data = getDummyData(); @@ -401,6 +425,18 @@ public class SettingsSliceProviderTest { assertThat(wifiSlice.getUri()).isEqualTo(WifiSliceBuilder.WIFI_URI); } + @Test + public void onSlicePinned_noIntentRegistered_specialCaseUri_doesNotCrash() { + final Uri uri = new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(SettingsSlicesContract.AUTHORITY) + .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) + .appendPath(SettingsSlicesContract.KEY_LOCATION) + .build(); + + mProvider.onSlicePinned(uri); + } + private void insertSpecialCase(String key) { insertSpecialCase(key, true); } diff --git a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java index 00e8fe17d08..96e475e9fbe 100644 --- a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java +++ b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java @@ -336,7 +336,7 @@ public class SliceBuilderUtilsTest { final Slice slice = SliceBuilderUtils.buildSlice(mContext, data); - SliceTester.testSettingsUnavailableSlice(mContext, slice, data); + assertThat(slice).isNull(); } @Test @@ -349,7 +349,7 @@ public class SliceBuilderUtilsTest { final Slice slice = SliceBuilderUtils.buildSlice(mContext, data); - SliceTester.testSettingsUnavailableSlice(mContext, slice, data); + assertThat(slice).isNull(); } @Test @@ -394,7 +394,7 @@ public class SliceBuilderUtilsTest { .isEqualTo(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_NAME); assertThat(capturedLoggingPair.second) .isEqualTo(data.getKey()); - SliceTester.testSettingsUnavailableSlice(mContext, slice, data); + assertThat(slice).isNull(); } @Test @@ -408,16 +408,6 @@ public class SliceBuilderUtilsTest { assertThat(intentData).isEqualTo(expectedUri); } - @Test - public void getSettingsIntent_createsIntentToSettings() { - final Intent intent = new Intent(Settings.ACTION_SETTINGS); - final PendingIntent expectedIntent = PendingIntent.getActivity(mContext, 0, intent, 0); - - final PendingIntent settingsIntent = SliceBuilderUtils.getSettingsIntent(mContext); - - assertThat(expectedIntent).isEqualTo(settingsIntent); - } - private SliceData getDummyData() { return getDummyData(TOGGLE_CONTROLLER, SUMMARY, SliceData.SliceType.SWITCH, SCREEN_TITLE); } diff --git a/tests/robotests/src/com/android/settings/testutils/SliceTester.java b/tests/robotests/src/com/android/settings/testutils/SliceTester.java index f617aa95c8f..7dd22aa092a 100644 --- a/tests/robotests/src/com/android/settings/testutils/SliceTester.java +++ b/tests/robotests/src/com/android/settings/testutils/SliceTester.java @@ -150,14 +150,17 @@ public class SliceTester { final int color = colorItem.getInt(); assertThat(color).isEqualTo(Utils.getColorAccent(context)); - final IconCompat expectedToggleIcon = IconCompat.createWithResource(context, + final SliceAction primaryAction = metadata.getPrimaryAction(); + + final IconCompat expectedIcon = IconCompat.createWithResource(context, sliceData.getIconResource()); + assertThat(expectedIcon.toString()).isEqualTo(primaryAction.getIcon().toString()); final long sliceTTL = metadata.getExpiry(); assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY); // Check primary intent - final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction(); + final PendingIntent primaryPendingIntent = primaryAction.getAction(); assertThat(primaryPendingIntent).isEqualTo( SliceBuilderUtils.getContentPendingIntent(context, sliceData)); @@ -191,20 +194,8 @@ public class SliceTester { assertThat(toggles).isEmpty(); final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction(); - final int availabilityStatus = SliceBuilderUtils.getPreferenceController(context, - sliceData).getAvailabilityStatus(); - switch (availabilityStatus) { - case UNSUPPORTED_ON_DEVICE: - case CONDITIONALLY_UNAVAILABLE: - assertThat(primaryPendingIntent).isEqualTo( - SliceBuilderUtils.getSettingsIntent(context)); - break; - case DISABLED_FOR_USER: - case DISABLED_DEPENDENT_SETTING: - assertThat(primaryPendingIntent).isEqualTo( - SliceBuilderUtils.getContentPendingIntent(context, sliceData)); - break; - } + assertThat(primaryPendingIntent).isEqualTo(SliceBuilderUtils.getContentPendingIntent( + context, sliceData)); final List sliceItems = slice.getItems(); assertTitle(sliceItems, sliceData.getTitle()); diff --git a/tests/robotests/src/com/android/settings/widget/TwoStateButtonPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/widget/TwoStateButtonPreferenceTest.java similarity index 60% rename from tests/robotests/src/com/android/settings/widget/TwoStateButtonPreferenceControllerTest.java rename to tests/robotests/src/com/android/settings/widget/TwoStateButtonPreferenceTest.java index d6df25df47f..c88e7f87d00 100644 --- a/tests/robotests/src/com/android/settings/widget/TwoStateButtonPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/widget/TwoStateButtonPreferenceTest.java @@ -17,34 +17,27 @@ package com.android.settings.widget; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import android.content.Context; -import android.support.v7.preference.PreferenceScreen; import android.view.View; import android.widget.Button; +import com.android.settings.R; 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 org.robolectric.util.ReflectionHelpers; @RunWith(SettingsRobolectricTestRunner.class) -public class TwoStateButtonPreferenceControllerTest { +public class TwoStateButtonPreferenceTest { - private static final String KEY = "pref_key"; - - @Mock - private PreferenceScreen mPreferenceScreen; - @Mock private TwoStateButtonPreference mPreference; - private TwoStateButtonPreferenceController mController; private Context mContext; private Button mButtonOn; private Button mButtonOff; @@ -53,35 +46,34 @@ public class TwoStateButtonPreferenceControllerTest { public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); - doReturn(mPreference).when(mPreferenceScreen).findPreference(anyString()); + mPreference = spy(new TwoStateButtonPreference(mContext, null /* AttributeSet */)); mButtonOn = new Button(mContext); - doReturn(mButtonOn).when(mPreference).getStateOnButton(); + mButtonOn.setId(R.id.state_on_button); mButtonOff = new Button(mContext); - doReturn(mButtonOff).when(mPreference).getStateOffButton(); - - mController = new TestButtonsPreferenceController(mContext, KEY); - mController.displayPreference(mPreferenceScreen); + mButtonOff.setId(R.id.state_off_button); + ReflectionHelpers.setField(mPreference, "mButtonOn", mButtonOn); + ReflectionHelpers.setField(mPreference, "mButtonOff", mButtonOff); } @Test public void testSetButtonVisibility_stateOn_onlyShowButtonOn() { - mController.setButtonVisibility(true /* stateOn */); - - assertThat(mButtonOn.getVisibility()).isEqualTo(View.VISIBLE); - assertThat(mButtonOff.getVisibility()).isEqualTo(View.GONE); - } - - @Test - public void testSetButtonVisibility_stateOff_onlyShowButtonOff() { - mController.setButtonVisibility(false /* stateOn */); + mPreference.setChecked(true /* stateOn */); assertThat(mButtonOn.getVisibility()).isEqualTo(View.GONE); assertThat(mButtonOff.getVisibility()).isEqualTo(View.VISIBLE); } + @Test + public void testSetButtonVisibility_stateOff_onlyShowButtonOff() { + mPreference.setChecked(false /* stateOn */); + + assertThat(mButtonOn.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mButtonOff.getVisibility()).isEqualTo(View.GONE); + } + @Test public void testSetButtonEnabled_enabled_buttonEnabled() { - mController.setButtonEnabled(true /* enabled */); + mPreference.setButtonEnabled(true /* enabled */); assertThat(mButtonOn.isEnabled()).isTrue(); assertThat(mButtonOff.isEnabled()).isTrue(); @@ -89,30 +81,18 @@ public class TwoStateButtonPreferenceControllerTest { @Test public void testSetButtonEnabled_disabled_buttonDisabled() { - mController.setButtonEnabled(false /* enabled */); + mPreference.setButtonEnabled(false /* enabled */); assertThat(mButtonOn.isEnabled()).isFalse(); assertThat(mButtonOff.isEnabled()).isFalse(); } - /** - * Controller to test methods in {@link TwoStateButtonPreferenceController} - */ - public static class TestButtonsPreferenceController - extends TwoStateButtonPreferenceController { + @Test + public void onClick_shouldPropagateChangeToListener() { + mPreference.onClick(mButtonOn); + verify(mPreference).callChangeListener(true); - TestButtonsPreferenceController(Context context, String key) { - super(context, key); - } - - @Override - public void onButtonClicked(boolean stateOn) { - //do nothing - } - - @Override - public int getAvailabilityStatus() { - return AVAILABLE; - } + mPreference.onClick(mButtonOff); + verify(mPreference).callChangeListener(false); } } diff --git a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java index ddbc851952a..43e87d83050 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java @@ -259,26 +259,13 @@ public class WifiConfigControllerTest { } @Test - public void hiddenView_isDisabledWhenAppropriate() { - View hiddenSpinner = mView.findViewById(R.id.hidden_settings); - assertThat(hiddenSpinner.isEnabled()).isFalse(); + public void hiddenField_visibilityUpdatesCorrectly() { + View hiddenField = mView.findViewById(R.id.hidden_settings_field); + assertThat(hiddenField.getVisibility()).isEqualTo(View.GONE); mController = new TestWifiConfigController(mConfigUiBase, mView, null /* accessPoint */, WifiConfigUiBase.MODE_CONNECT); - assertThat(hiddenSpinner.isEnabled()).isTrue(); - } - - - @Test - public void hiddenSpinner_visibilityUpdatesCorrectly() { - View hiddenSpinner = mView.findViewById(R.id.hidden_settings); - assertThat(hiddenSpinner.isEnabled()).isFalse(); - assertThat(hiddenSpinner.getVisibility()).isEqualTo(View.GONE); - - mController = new TestWifiConfigController(mConfigUiBase, mView, null /* accessPoint */, - WifiConfigUiBase.MODE_CONNECT); - assertThat(hiddenSpinner.isEnabled()).isTrue(); - assertThat(hiddenSpinner.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(hiddenField.getVisibility()).isEqualTo(View.VISIBLE); } public class TestWifiConfigController extends WifiConfigController { diff --git a/tests/robotests/src/com/android/settings/wifi/WifiSliceBuilderTest.java b/tests/robotests/src/com/android/settings/wifi/WifiSliceBuilderTest.java index 865785fc745..605a661a307 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiSliceBuilderTest.java +++ b/tests/robotests/src/com/android/settings/wifi/WifiSliceBuilderTest.java @@ -26,7 +26,6 @@ import static org.mockito.Mockito.spy; import android.content.Context; import com.android.settings.R; -import com.android.settings.wifi.WifiSliceBuilder; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.SliceTester; diff --git a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSliceHelperTest.java b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSliceHelperTest.java index ac3ff3ff635..21f6daa3428 100644 --- a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSliceHelperTest.java +++ b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSliceHelperTest.java @@ -114,7 +114,7 @@ public class WifiCallingSliceHelperTest { final Slice slice = mWfcSliceHelper.createWifiCallingSlice(mWfcURI); testWifiCallingSettingsUnavailableSlice(slice, null, - SliceBuilderUtils.getSettingsIntent(mContext)); + WifiCallingSliceHelper.getSettingsIntent(mContext)); } @Test @@ -125,7 +125,7 @@ public class WifiCallingSliceHelperTest { assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1); testWifiCallingSettingsUnavailableSlice(slice, null, - SliceBuilderUtils.getSettingsIntent(mContext)); + WifiCallingSliceHelper.getSettingsIntent(mContext)); } @Test