Merge "[Provider Model] Replace WiFi panel to Internet panel"
diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index b138082..3ebe9b1 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -921,11 +921,27 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" <color name="homepage_emergency_background">#F28B82</color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="95"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" <color name="homepage_system_background">#9E9E9E</color>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="95"
+ line="96"
column="5"/>
</issue>
@@ -941,7 +957,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="96"
+ line="97"
column="5"/>
</issue>
@@ -957,7 +973,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="97"
+ line="98"
column="5"/>
</issue>
@@ -973,7 +989,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="98"
+ line="99"
column="5"/>
</issue>
@@ -989,7 +1005,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="99"
+ line="100"
column="5"/>
</issue>
@@ -1005,7 +1021,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="100"
+ line="101"
column="5"/>
</issue>
@@ -1021,7 +1037,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="102"
+ line="103"
column="5"/>
</issue>
@@ -1037,7 +1053,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="108"
+ line="109"
column="5"/>
</issue>
@@ -1053,7 +1069,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="111"
+ line="112"
column="5"/>
</issue>
@@ -1069,7 +1085,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="112"
+ line="113"
column="5"/>
</issue>
@@ -1085,7 +1101,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="113"
+ line="114"
column="5"/>
</issue>
@@ -1101,7 +1117,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="114"
+ line="115"
column="5"/>
</issue>
@@ -1117,7 +1133,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="115"
+ line="116"
column="5"/>
</issue>
@@ -1133,7 +1149,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="116"
+ line="117"
column="5"/>
</issue>
@@ -1149,7 +1165,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="119"
+ line="120"
column="5"/>
</issue>
@@ -1165,7 +1181,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="120"
+ line="121"
column="5"/>
</issue>
@@ -1181,7 +1197,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="121"
+ line="122"
column="5"/>
</issue>
@@ -1197,7 +1213,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="122"
+ line="123"
column="5"/>
</issue>
@@ -1213,7 +1229,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="123"
+ line="124"
column="5"/>
</issue>
@@ -1229,7 +1245,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="126"
+ line="127"
column="5"/>
</issue>
@@ -1245,7 +1261,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="127"
+ line="128"
column="5"/>
</issue>
@@ -1261,7 +1277,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="128"
+ line="129"
column="5"/>
</issue>
@@ -1277,7 +1293,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="129"
+ line="130"
column="5"/>
</issue>
@@ -1293,7 +1309,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="130"
+ line="131"
column="5"/>
</issue>
@@ -1309,7 +1325,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="131"
+ line="132"
column="5"/>
</issue>
@@ -1325,7 +1341,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="138"
+ line="139"
column="5"/>
</issue>
@@ -1341,7 +1357,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="139"
+ line="140"
column="5"/>
</issue>
@@ -1357,7 +1373,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="140"
+ line="141"
column="5"/>
</issue>
@@ -1373,7 +1389,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="149"
+ line="150"
column="5"/>
</issue>
@@ -1389,7 +1405,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="151"
+ line="152"
column="5"/>
</issue>
@@ -1405,7 +1421,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="155"
+ line="156"
column="5"/>
</issue>
@@ -1421,7 +1437,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="156"
+ line="157"
column="5"/>
</issue>
@@ -1437,7 +1453,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="157"
+ line="158"
column="5"/>
</issue>
@@ -1453,7 +1469,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="158"
+ line="159"
column="5"/>
</issue>
@@ -1469,7 +1485,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="159"
+ line="160"
column="5"/>
</issue>
@@ -1485,7 +1501,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="160"
+ line="161"
column="5"/>
</issue>
@@ -1501,7 +1517,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="161"
+ line="162"
column="5"/>
</issue>
@@ -1517,7 +1533,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="162"
+ line="163"
column="5"/>
</issue>
@@ -1533,7 +1549,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="165"
+ line="166"
column="5"/>
</issue>
@@ -1549,7 +1565,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="166"
+ line="167"
column="5"/>
</issue>
@@ -1565,7 +1581,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="167"
+ line="168"
column="5"/>
</issue>
@@ -1581,7 +1597,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="168"
+ line="169"
column="5"/>
</issue>
@@ -1597,7 +1613,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="169"
+ line="170"
column="5"/>
</issue>
@@ -1613,7 +1629,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="170"
+ line="171"
column="5"/>
</issue>
@@ -1629,7 +1645,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="171"
+ line="172"
column="5"/>
</issue>
@@ -1645,7 +1661,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="172"
+ line="173"
column="5"/>
</issue>
@@ -1661,7 +1677,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="175"
+ line="176"
column="5"/>
</issue>
@@ -1677,7 +1693,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="176"
+ line="177"
column="5"/>
</issue>
@@ -1693,7 +1709,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="177"
+ line="178"
column="5"/>
</issue>
@@ -1709,7 +1725,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="178"
+ line="179"
column="5"/>
</issue>
@@ -1725,7 +1741,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="179"
+ line="180"
column="5"/>
</issue>
@@ -1741,7 +1757,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="180"
+ line="181"
column="5"/>
</issue>
@@ -1757,7 +1773,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="183"
+ line="184"
column="5"/>
</issue>
@@ -1773,7 +1789,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="184"
+ line="185"
column="5"/>
</issue>
@@ -1789,7 +1805,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="185"
+ line="186"
column="5"/>
</issue>
@@ -1805,7 +1821,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="186"
+ line="187"
column="5"/>
</issue>
@@ -1821,7 +1837,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="187"
+ line="188"
column="5"/>
</issue>
@@ -1837,7 +1853,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="188"
+ line="189"
column="5"/>
</issue>
@@ -2361,6 +2377,22 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" android:color="@color/homepage_emergency_background" />"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable/ic_homepage_emergency.xml"
+ line="24"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" android:color="@color/homepage_location_background" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -3069,7 +3101,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rAU/strings.xml"
- line="2793"
+ line="2818"
column="64"/>
</issue>
@@ -3085,7 +3117,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rCA/strings.xml"
- line="2793"
+ line="2818"
column="64"/>
</issue>
@@ -3101,7 +3133,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rGB/strings.xml"
- line="2793"
+ line="2818"
column="64"/>
</issue>
@@ -3117,7 +3149,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rIN/strings.xml"
- line="2793"
+ line="2818"
column="64"/>
</issue>
@@ -3133,7 +3165,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rXC/strings.xml"
- line="2793"
+ line="2818"
column="170"/>
</issue>
@@ -3149,7 +3181,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/strings.xml"
- line="6463"
+ line="6537"
column="36"/>
</issue>
@@ -3277,7 +3309,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="176"
+ line="191"
column="45"/>
</issue>
@@ -3293,7 +3325,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="177"
+ line="192"
column="49"/>
</issue>
@@ -3309,7 +3341,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="185"
+ line="200"
column="45"/>
</issue>
@@ -3325,7 +3357,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="186"
+ line="201"
column="49"/>
</issue>
@@ -3341,7 +3373,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="258"
+ line="273"
column="42"/>
</issue>
diff --git a/res/drawable/ic_homepage_emergency.xml b/res/drawable/ic_homepage_emergency.xml
new file mode 100644
index 0000000..081a3fc
--- /dev/null
+++ b/res/drawable/ic_homepage_emergency.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 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.
+ -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item>
+ <com.android.settingslib.widget.AdaptiveIconShapeDrawable
+ android:width="@dimen/dashboard_tile_image_size"
+ android:height="@dimen/dashboard_tile_image_size"
+ android:color="@color/homepage_emergency_background" />
+ </item>
+
+ <item
+ android:width="@dimen/dashboard_tile_foreground_image_size"
+ android:height="@dimen/dashboard_tile_foreground_image_size"
+ android:start="@dimen/dashboard_tile_foreground_image_inset"
+ android:top="@dimen/dashboard_tile_foreground_image_inset"
+ android:drawable="@drawable/ic_settings_emergency" />
+</layer-list>
diff --git a/res/drawable/ic_settings_emergency.xml b/res/drawable/ic_settings_emergency.xml
new file mode 100644
index 0000000..f145346
--- /dev/null
+++ b/res/drawable/ic_settings_emergency.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M9.3207,2V7.359L4.6795,4.6795L2,9.3207L6.6412,12L2,14.6795L4.6795,19.3205L9.3207,16.641V22H14.6797V16.641L19.3207,19.3205L22.0002,14.6795L17.359,12L22.0002,9.3207L19.3207,4.6795L14.6797,7.3588V2H9.3207Z"
+ android:fillColor="?android:attr/colorPrimary"/>
+</vector>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index f8df920..3528f9f 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1532,4 +1532,21 @@
<item>8</item>
<item>12</item>
</string-array>
+
+ <!-- Array of titles list for notification listener notification types. [DO NOT TRANSLATE] -->
+ <string-array name="notif_types_titles" translatable="false">
+ <item>@string/notif_type_ongoing</item>
+ <item>@string/notif_type_conversation</item>
+ <item>@string/notif_type_alerting</item>
+ <item>@string/notif_type_silent</item>
+ </string-array>
+
+ <!-- Values of list for notification listener notification types. Values need to match
+ android.service.notification.NotificationListenerService. [DO NOT TRANSLATE] -->
+ <string-array name="notif_types_values" translatable="false">
+ <item>8</item>
+ <item>1</item>
+ <item>2</item>
+ <item>4</item>
+ </string-array>
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 58b8aa4..2ce3949 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -92,6 +92,7 @@
<color name="homepage_security_background">#0F9D58</color>
<color name="homepage_accounts_background">#F15B8D</color>
<color name="homepage_accessibility_background">#5011C1</color>
+ <color name="homepage_emergency_background">#F28B82</color>
<color name="homepage_system_background">#9E9E9E</color>
<color name="homepage_support_background">#26459C</color>
<color name="homepage_generic_icon_background">#1A73E8</color>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2a63511..5301f30 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2824,16 +2824,12 @@
<string name="night_display_status_title">Status</string>
<!-- Night display screen, setting the color temperature of the display. [CHAR LIMIT=30] -->
<string name="night_display_temperature_title">Intensity</string>
- <!-- Display settings screen, summary format of night display when off. [CHAR LIMIT=NONE] -->
- <string name="night_display_summary_off">Off / <xliff:g name="auto_mode_summary" example="Never turn on automatically">%1$s</xliff:g></string>
<!-- Display settings screen, summary of night display when off and will *never* turn on automatically. [CHAR LIMIT=NONE] -->
<string name="night_display_summary_off_auto_mode_never">Will never turn on automatically</string>
<!-- Display settings screen, summary format of night display when off and will turn on automatically at a user defined time. [CHAR LIMIT=NONE] -->
<string name="night_display_summary_off_auto_mode_custom">Will turn on automatically at <xliff:g name="time" example="6 AM">%1$s</xliff:g></string>
<!-- Display settings screen, summary of night display when off and will turn on automatically at sunset. [CHAR LIMIT=NONE] -->
<string name="night_display_summary_off_auto_mode_twilight">Will turn on automatically at sunset</string>
- <!-- Display settings screen, summary format of night display when on. [CHAR LIMIT=NONE] -->
- <string name="night_display_summary_on">On / <xliff:g name="auto_mode_summary" example="Never turn off automatically">%1$s</xliff:g></string>
<!-- Display settings screen, summary of night display when on and will *never* turn off automatically. [CHAR LIMIT=NONE] -->
<string name="night_display_summary_on_auto_mode_never">Will never turn off automatically</string>
<!-- Display settings screen, summary format of night display when on and will turn off automatically at a user defined time. [CHAR LIMIT=NONE] -->
@@ -2882,16 +2878,12 @@
<string name="dark_ui_auto_mode_custom">Turns on at custom time</string>
<!-- Dark UI screen, setting option name controlling the current activation status. [CHAR LIMIT=30] -->
<string name="dark_ui_status_title">Status</string>
- <!-- Display settings screen, summary format of Dark UI when off. [CHAR LIMIT=NONE] -->
- <string name="dark_ui_summary_off">Off / <xliff:g name="auto_mode_summary" example="Never turn on automatically">%1$s</xliff:g></string>
<!-- Display settings screen, summary of Dark UI when off and will *never* turn on automatically. [CHAR LIMIT=NONE] -->
<string name="dark_ui_summary_off_auto_mode_never">Will never turn on automatically</string>
<!-- Display settings screen, summary of Dark UI when off and will turn on automatically at sunset. [CHAR LIMIT=NONE] -->
<string name="dark_ui_summary_off_auto_mode_auto">Will turn on automatically at sunset</string>
<!-- Display settings screen, summary format of night display when off and will turn on automatically at a user defined time. [CHAR LIMIT=NONE] -->
<string name="dark_ui_summary_off_auto_mode_custom">Will turn on automatically at <xliff:g name="time" example="6 AM">%1$s</xliff:g></string>
- <!-- Display settings screen, summary format of Dark UI when on. [CHAR LIMIT=NONE] -->
- <string name="dark_ui_summary_on">On / <xliff:g name="auto_mode_summary" example="Never turn off automatically">%1$s</xliff:g></string>
<!-- Display settings screen, summary of Dark UI when on and will *never* turn off automatically. [CHAR LIMIT=NONE] -->
<string name="dark_ui_summary_on_auto_mode_never">Will never turn off automatically</string>
<!-- Display settings screen, summary of Dark UI when on and will turn off automatically at sunrise. [CHAR LIMIT=NONE] -->
@@ -4952,6 +4944,8 @@
<string name="audio_and_captions_category_title">Audio & on-screen text</string>
<!-- Title for the accessibility preference category of display services and settings. [CHAR LIMIT=50] -->
<string name="display_category_title">Display</string>
+ <!-- Title for the accessibility text options page. [CHAR LIMIT=50] -->
+ <string name="accessibility_text_and_display_title">Text and display</string>
<!-- Title for the accessibility preference category of interaction control services and settings. [CHAR LIMIT=50] -->
<string name="interaction_control_category_title">Interaction controls</string>
<!-- Title for the accessibility preference category of services downloaded by the user. [CHAR LIMIT=50] -->
@@ -7111,13 +7105,15 @@
<!-- Title for Guest user [CHAR LIMIT=35] -->
<string name="user_guest">Guest</string>
<!-- Label for item to exit guest mode [CHAR LIMIT=35] -->
- <string name="user_exit_guest_title">Remove guest</string>
+ <string name="user_clear_guest_menu">Clear guest data</string>
+ <!-- Label for item to exit guest mode [CHAR LIMIT=35] -->
+ <string name="user_exit_guest_menu">End guest session</string>
<!-- Title of dialog to user to confirm exiting guest. [CHAR LIMIT=50] -->
- <string name="user_exit_guest_confirm_title">Remove guest?</string>
+ <string name="user_exit_guest_confirm_title">End guest session?</string>
<!-- Message to user to confirm exiting guest. [CHAR LIMIT=none] -->
<string name="user_exit_guest_confirm_message">All apps and data in this session will be deleted.</string>
<!-- Label for button in confirmation dialog when exiting guest session [CHAR LIMIT=35] -->
- <string name="user_exit_guest_dialog_remove">Remove</string>
+ <string name="user_exit_guest_dialog_remove">End session</string>
<!-- Title of preference to enable calling[CHAR LIMIT=40] -->
<string name="user_enable_calling">Turn on phone calls</string>
@@ -8587,7 +8583,7 @@
<string name="recent_conversations">Recent conversations</string>
<!-- [CHAR LIMIT=20] button title -->
- <string name="conversation_settings_clear_recents">Clear recents</string>
+ <string name="conversation_settings_clear_recents">Clear all of the recent ones</string>
<!-- a11y string -->
<string name="clear">Clear</string>
@@ -8760,6 +8756,11 @@
</string>
<string name="notification_listener_disable_warning_confirm">Turn off</string>
<string name="notification_listener_disable_warning_cancel">Cancel</string>
+ <string name="notification_listener_type_title">Allowed notification types</string>
+ <string name="notif_type_ongoing">Important ongoing notifications</string>
+ <string name="notif_type_conversation">Conversation notifications</string>
+ <string name="notif_type_alerting">Alerting notifications</string>
+ <string name="notif_type_silent">Silent notifications</string>
<!-- Title for managing VR (virtual reality) helper services. [CHAR LIMIT=50] -->
<string name="vr_listeners_title">VR helper services</string>
@@ -10866,7 +10867,7 @@
<string name="dark_ui_mode">Dark theme</string>
<!-- [CHAR LIMIT=60] Summary string on dark theme explaining why the toggle is disabled while the setting is still on-->
- <string name="dark_ui_mode_disabled_summary_dark_theme_on">On / Temporarily disabled due to Battery Saver</string>
+ <string name="dark_ui_mode_disabled_summary_dark_theme_on">Temporarily disabled due to Battery Saver</string>
<!-- [CHAR LIMIT=60] Summary string on dark theme explaining why the toggle is disabled while the setting is off-->
<string name="dark_ui_mode_disabled_summary_dark_theme_off">Temporarily turned on due to Battery Saver</string>
@@ -10990,6 +10991,9 @@
<!-- Summary for settings suggestion for swipe up to switch apps [CHAR LIMIT=60] -->
<string name="swipe_up_to_switch_apps_suggestion_summary">Turn on the new gesture to switch apps</string>
+ <!-- Preference title for "Safety & emergency" settings page [CHAR LIMIT=60]-->
+ <string name="emergency_settings_preference_title">Safety & emergency</string>
+
<!-- Title text for edge to edge navigation [CHAR LIMIT=60] -->
<string name="edge_to_edge_navigation_title">Gesture navigation</string>
<!-- Summary text for edge to edge navigation [CHAR LIMIT=NONE] -->
@@ -12573,4 +12577,6 @@
<string name="category_name_color">Color</string>
<!-- Others category name [CHAR LIMIT=none] -->
<string name="category_name_others">Others</string>
+ <!-- General category name [CHAR LIMIT=none] -->
+ <string name="category_name_general">General</string>
</resources>
diff --git a/res/values/styles_preference.xml b/res/values/styles_preference.xml
index b88a9fb..6453458 100644
--- a/res/values/styles_preference.xml
+++ b/res/values/styles_preference.xml
@@ -25,16 +25,9 @@
<item name="slicePreferenceStyle">@style/SlicePreference</item>
<item name="seekBarPreferenceStyle">@style/SettingsSeekBarPreference</item>
<item name="twoStateButtonPreferenceStyle">@style/TwoStateButtonPreference</item>
- <item name="preferenceCategoryTitleTextAppearance">@style/TextAppearance.CategoryTitle
- </item>
- <item name="preferenceCategoryStyle">@style/SettingsCategoryPreference</item>
- <!-- For preference category color -->
- <item name="preferenceCategoryTitleTextColor">?android:attr/textColorSecondary</item>
<item name="preferenceFragmentCompatStyle">@style/SettingsPreferenceFragmentStyle</item>
</style>
- <style name="SettingsCategoryPreference" parent="Preference.Category.Material" />
-
<style name="PreferenceTheme.SetupWizard">
<item name="preferenceFragmentCompatStyle">@style/SetupWizardPreferenceFragmentStyle</item>
<item name="preferenceStyle">@style/Preference.Material</item>
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index 6781e28..6efd884 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -45,52 +45,19 @@
android:title="@string/display_category_title">
<Preference
- android:fragment="com.android.settings.display.ToggleFontSizePreferenceFragment"
- android:key="font_size_preference_screen"
+ android:fragment="com.android.settings.accessibility.TextAndDisplayFragment"
+ android:key="text_and_display_preference_screen"
android:persistent="false"
- android:title="@string/title_font_size"
- settings:controller="com.android.settings.display.FontSizePreferenceController"
- settings:searchable="false"/>
+ android:title="@string/accessibility_text_and_display_title"
+ settings:searchable="true"/>
- <com.android.settings.display.ScreenZoomPreference
- android:fragment="com.android.settings.display.ScreenZoomSettings"
- android:key="accessibility_settings_screen_zoom"
- android:persistent="false"
- android:title="@string/screen_zoom_title"
- settings:searchable="false"/>
-
- <SwitchPreference
- android:key="dark_ui_mode_accessibility"
- android:persistent="false"
- android:title="@string/dark_ui_mode"
- settings:controller="com.android.settings.display.DarkUIPreferenceController"
- settings:searchable="false"/>
-
- <Preference
+ <Preference
android:fragment="com.android.settings.accessibility.MagnificationPreferenceFragment"
android:icon="@drawable/ic_accessibility_magnification"
android:key="magnification_preference_screen"
android:persistent="false"
android:title="@string/accessibility_screen_magnification_title"
settings:controller="com.android.settings.accessibility.MagnificationPreferenceController"/>
-
- <SwitchPreference
- android:key="toggle_large_pointer_icon"
- android:persistent="false"
- android:title="@string/accessibility_toggle_large_pointer_icon_title"
- settings:controller="com.android.settings.accessibility.LargePointerIconPreferenceController"/>
-
- <SwitchPreference
- android:key="toggle_disable_animations"
- android:persistent="false"
- android:title="@string/accessibility_disable_animations"
- settings:controller="com.android.settings.accessibility.DisableAnimationsPreferenceController"/>
-
- <SwitchPreference
- android:key="toggle_force_bold_text"
- android:persistent="false"
- android:title="@string/force_bold_text"
- settings:controller="com.android.settings.accessibility.FontWeightAdjustmentPreferenceController"/>
</PreferenceCategory>
<PreferenceCategory
@@ -203,42 +170,12 @@
settings:initialExpandedChildrenCount="1">
<SwitchPreference
- android:key="toggle_high_text_contrast_preference"
- android:persistent="false"
- android:title="@string/accessibility_toggle_high_text_contrast_preference_title"
- settings:controller="com.android.settings.accessibility.HighTextContrastPreferenceController"/>
-
- <Preference
- android:fragment="com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment"
- android:icon="@drawable/ic_daltonizer"
- android:key="daltonizer_preference"
- android:persistent="false"
- android:title="@string/accessibility_display_daltonizer_preference_title"
- settings:controller="com.android.settings.accessibility.DaltonizerPreferenceController"/>
-
- <Preference
- android:fragment="com.android.settings.accessibility.ToggleColorInversionPreferenceFragment"
- android:icon="@drawable/ic_color_inversion"
- android:key="toggle_inversion_preference"
- android:persistent="false"
- android:title="@string/accessibility_display_inversion_preference_title"
- settings:controller="com.android.settings.accessibility.ColorInversionPreferenceController"/>
-
- <SwitchPreference
android:key="accessibility_shortcut_preference"
android:persistent="false"
android:title="@string/accessibility_shortcut_service_on_lock_screen_title"
android:summary="@string/accessibility_shortcut_description"
settings:controller="com.android.settings.accessibility.AccessibilityShortcutPreferenceController"/>
- <!--TODO(b/170973645): Get icon-->
- <Preference
- android:fragment="com.android.settings.accessibility.ToggleReduceBrightColorsPreferenceFragment"
- android:key="reduce_bright_colors_preference"
- android:persistent="false"
- android:title="@string/reduce_bright_colors_preference_title"
- settings:controller="com.android.settings.accessibility.ReduceBrightColorsPreferenceController"/>
-
</PreferenceCategory>
</PreferenceScreen>
diff --git a/res/xml/accessibility_text_and_display.xml b/res/xml/accessibility_text_and_display.xml
new file mode 100644
index 0000000..7dce826
--- /dev/null
+++ b/res/xml/accessibility_text_and_display.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:key="accessibility_text_and_display"
+ android:persistent="false"
+ android:title="@string/accessibility_text_and_display_title">
+
+ <SwitchPreference
+ android:key="toggle_high_text_contrast_preference"
+ android:persistent="false"
+ android:title="@string/accessibility_toggle_high_text_contrast_preference_title"
+ settings:controller="com.android.settings.accessibility.HighTextContrastPreferenceController"/>
+
+ <SwitchPreference
+ android:key="dark_ui_mode_accessibility"
+ android:persistent="false"
+ android:title="@string/dark_ui_mode"
+ settings:controller="com.android.settings.display.DarkUIPreferenceController"
+ settings:searchable="false"/>
+
+ <Preference
+ android:fragment="com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment"
+ android:icon="@drawable/ic_daltonizer"
+ android:key="daltonizer_preference"
+ android:persistent="false"
+ android:title="@string/accessibility_display_daltonizer_preference_title"
+ settings:controller="com.android.settings.accessibility.DaltonizerPreferenceController"/>
+
+ <Preference
+ android:fragment="com.android.settings.accessibility.ToggleColorInversionPreferenceFragment"
+ android:icon="@drawable/ic_color_inversion"
+ android:key="toggle_inversion_preference"
+ android:persistent="false"
+ android:title="@string/accessibility_display_inversion_preference_title"
+ settings:controller="com.android.settings.accessibility.ColorInversionPreferenceController"/>
+
+ <!--TODO(b/170973645): Get icon-->
+ <Preference
+ android:fragment="com.android.settings.accessibility.ToggleReduceBrightColorsPreferenceFragment"
+ android:key="reduce_bright_colors_preference"
+ android:persistent="false"
+ android:title="@string/reduce_bright_colors_preference_title"
+ settings:controller="com.android.settings.accessibility.ReduceBrightColorsPreferenceController"/>
+
+ <SwitchPreference
+ android:key="toggle_disable_animations"
+ android:persistent="false"
+ android:title="@string/accessibility_disable_animations"
+ settings:controller="com.android.settings.accessibility.DisableAnimationsPreferenceController"/>
+
+ <com.android.settings.display.ScreenZoomPreference
+ android:fragment="com.android.settings.display.ScreenZoomSettings"
+ android:key="accessibility_settings_screen_zoom"
+ android:persistent="false"
+ android:title="@string/screen_zoom_title"
+ settings:searchable="false"/>
+
+ <Preference
+ android:fragment="com.android.settings.display.ToggleFontSizePreferenceFragment"
+ android:key="font_size_preference_screen"
+ android:persistent="false"
+ android:title="@string/title_font_size"
+ settings:controller="com.android.settings.display.FontSizePreferenceController"
+ settings:searchable="false"/>
+
+ <SwitchPreference
+ android:key="toggle_force_bold_text"
+ android:persistent="false"
+ android:title="@string/force_bold_text"
+ settings:controller="com.android.settings.accessibility.FontWeightAdjustmentPreferenceController"/>
+
+ <SwitchPreference
+ android:key="toggle_large_pointer_icon"
+ android:persistent="false"
+ android:title="@string/accessibility_toggle_large_pointer_icon_title"
+ settings:controller="com.android.settings.accessibility.LargePointerIconPreferenceController"/>
+
+ <PreferenceCategory
+ android:key="experimental_category"
+ android:persistent="false"
+ android:title="@string/experimental_category_title"
+ settings:initialExpandedChildrenCount="1">
+ </PreferenceCategory>
+</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/display_settings_v2.xml b/res/xml/display_settings_v2.xml
index 4edc335..0b43914 100644
--- a/res/xml/display_settings_v2.xml
+++ b/res/xml/display_settings_v2.xml
@@ -33,10 +33,9 @@
<intent android:action="com.android.intent.action.SHOW_BRIGHTNESS_DIALOG"/>
</com.android.settingslib.RestrictedPreference>
- <Preference
+ <com.android.settings.widget.PrimarySwitchPreference
android:key="auto_brightness_entry"
android:title="@string/auto_brightness_title"
- android:summary="@string/summary_placeholder"
android:fragment="com.android.settings.display.AutoBrightnessSettings"
settings:controller="com.android.settings.display.AutoBrightnessPreferenceController"/>
</PreferenceCategory>
@@ -103,7 +102,7 @@
</PreferenceCategory>
<PreferenceCategory
- android:title="@string/category_name_others">
+ android:title="@string/category_name_general">
<SwitchPreference
android:key="auto_rotate"
diff --git a/res/xml/emergency_settings.xml b/res/xml/emergency_settings.xml
new file mode 100644
index 0000000..41b503e
--- /dev/null
+++ b/res/xml/emergency_settings.xml
@@ -0,0 +1,41 @@
+
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:title="@string/emergency_settings_preference_title">
+ <Preference
+ android:key="emergency_info"
+ android:title="@string/emergency_info_title"
+ android:summary="@string/summary_placeholder"
+ settings:controller="com.android.settings.accounts.EmergencyInfoPreferenceController"/>
+ <Preference
+ android:key="gesture_emergency_summary"
+ android:title="@string/emergency_gesture_screen_title"
+ android:fragment="com.android.settings.gestures.EmergencyGestureSettings"
+ settings:controller="com.android.settings.gestures.EmergencyGestureEntrypointPreferenceController" />
+ <com.android.settingslib.RestrictedPreference
+ android:key="app_and_notif_cell_broadcast_settings"
+ android:title="@string/cell_broadcast_settings"
+ settings:useAdminDisabledSummary="true">
+ <intent
+ android:action="android.intent.action.MAIN"
+ android:targetPackage="@string/cell_broadcast_receiver_package"
+ android:targetClass="com.android.cellbroadcastreceiver.CellBroadcastSettings"/>
+ </com.android.settingslib.RestrictedPreference>
+</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/notification_access_permission_details.xml b/res/xml/notification_access_permission_details.xml
index d956ce9..f7d928d 100644
--- a/res/xml/notification_access_permission_details.xml
+++ b/res/xml/notification_access_permission_details.xml
@@ -17,11 +17,35 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="notification_access_permission_detail_settings"
android:title="@string/manage_notification_access_title">
+ <com.android.settingslib.widget.LayoutPreference
+ android:key="pref_app_header"
+ android:layout="@layout/settings_entity_header"
+ settings:controller="com.android.settings.applications.specialaccess.notificationaccess.HeaderPreferenceController"/>
+
<com.android.settings.widget.FilterTouchesSwitchPreference
android:key="notification_access_switch"
- android:title="@string/notification_access_detail_switch"/>
+ android:title="@string/notification_access_detail_switch"
+ settings:controller="com.android.settings.applications.specialaccess.notificationaccess.ApprovalPreferenceController"/>
+ <MultiSelectListPreference
+ android:key="notification_type_filter"
+ android:title="@string/notification_listener_type_title"
+ android:entries="@array/notif_types_titles"
+ android:entryValues="@array/notif_types_values"
+ android:summary="%s"
+ android:persistent="false"
+ style="@style/SettingsMultiSelectListPreference"
+ settings:controller="com.android.settings.applications.specialaccess.notificationaccess.TypeFilterPreferenceController"/>/>
+
+ <PreferenceCategory
+ android:key="advanced"
+ android:order="50"
+ settings:initialExpandedChildrenCount="0">
+
+
+ </PreferenceCategory>
</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/top_level_settings.xml b/res/xml/top_level_settings.xml
index 367f426..3c65f7b 100644
--- a/res/xml/top_level_settings.xml
+++ b/res/xml/top_level_settings.xml
@@ -125,6 +125,14 @@
android:fragment="com.android.settings.accessibility.AccessibilitySettings"
settings:controller="com.android.settings.accessibility.TopLevelAccessibilityPreferenceController"/>
+ <!-- TODO(b/175158310): Enable this tile when the setting content is more flushed out-->
+ <!-- <Preference-->
+ <!-- android:key="top_level_emergency"-->
+ <!-- android:title="@string/emergency_settings_preference_title"-->
+ <!-- android:icon="@drawable/ic_homepage_emergency"-->
+ <!-- android:order="-10"-->
+ <!-- android:fragment="com.android.settings.emergency.EmergencyDashboardFragment"/>-->
+
<Preference
android:key="top_level_system"
android:title="@string/header_category_system"
diff --git a/res/xml/top_level_settings_grouped.xml b/res/xml/top_level_settings_grouped.xml
index baee7b3..1ae6131 100644
--- a/res/xml/top_level_settings_grouped.xml
+++ b/res/xml/top_level_settings_grouped.xml
@@ -134,6 +134,13 @@
android:order="-20"
android:title="@string/security_settings_title"
settings:controller="com.android.settings.security.TopLevelSecurityEntryPreferenceController"/>
+ <!-- TODO(b/175158310): Enable this tile when the setting content is more flushed out-->
+ <!-- <Preference-->
+ <!-- android:key="top_level_emergency"-->
+ <!-- android:title="@string/emergency_settings_preference_title"-->
+ <!-- android:icon="@drawable/ic_homepage_emergency"-->
+ <!-- android:order="-10"-->
+ <!-- android:fragment="com.android.settings.emergency.EmergencyDashboardFragment"/>-->
</PreferenceCategory>
<PreferenceCategory
diff --git a/res/xml/zen_mode_custom_rule_settings.xml b/res/xml/zen_mode_custom_rule_settings.xml
index 169a94f..8f360b9 100644
--- a/res/xml/zen_mode_custom_rule_settings.xml
+++ b/res/xml/zen_mode_custom_rule_settings.xml
@@ -22,11 +22,11 @@
<PreferenceCategory
android:key="zen_custom_rule_category">
- <com.android.settings.notification.zen.ZenCustomRadioButtonPreference
+ <com.android.settingslib.widget.RadioButtonPreference
android:key="zen_custom_rule_setting_default"
android:title="@string/zen_mode_custom_behavior_summary_default"/>
- <com.android.settings.notification.zen.ZenCustomRadioButtonPreference
+ <com.android.settingslib.widget.RadioButtonPreference
android:key="zen_custom_rule_setting"
android:title="@string/zen_mode_custom_behavior_summary" />
</PreferenceCategory>
diff --git a/res/xml/zen_mode_restrict_notifications_settings.xml b/res/xml/zen_mode_restrict_notifications_settings.xml
index f5e7615..051c208 100644
--- a/res/xml/zen_mode_restrict_notifications_settings.xml
+++ b/res/xml/zen_mode_restrict_notifications_settings.xml
@@ -23,19 +23,19 @@
<PreferenceCategory
android:key="restrict_category"
android:title="@string/zen_mode_restrict_notifications_category">
- <com.android.settings.notification.zen.ZenCustomRadioButtonPreference
+ <com.android.settingslib.widget.RadioButtonPreference
android:key="zen_mute_notifications"
android:title="@string/zen_mode_restrict_notifications_mute"
android:summary="@string/zen_mode_restrict_notifications_mute_summary"
settings:searchable="false"/>
- <com.android.settings.notification.zen.ZenCustomRadioButtonPreference
+ <com.android.settingslib.widget.RadioButtonPreference
android:key="zen_hide_notifications"
android:title="@string/zen_mode_restrict_notifications_hide"
android:summary="@string/zen_mode_restrict_notifications_hide_summary"
settings:searchable="false"/>
- <com.android.settings.notification.zen.ZenCustomRadioButtonPreference
+ <com.android.settingslib.widget.RadioButtonPreference
android:key="zen_custom"
android:title="@string/zen_mode_restrict_notifications_custom"
settings:searchable="false"/>
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index e5bc3f5..4709c66 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -29,7 +29,6 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.graphics.drawable.Drawable;
-import android.hardware.display.ColorDisplayManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -43,7 +42,6 @@
import androidx.core.content.ContextCompat;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
-import androidx.preference.SwitchPreference;
import com.android.internal.accessibility.AccessibilityShortcutController;
import com.android.internal.content.PackageMonitor;
@@ -51,7 +49,6 @@
import com.android.settings.Utils;
import com.android.settings.accessibility.AccessibilityUtil.AccessibilityServiceFragmentType;
import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.display.DarkUIPreferenceController;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedLockUtilsInternal;
@@ -82,23 +79,14 @@
private static final String CATEGORY_EXPERIMENTAL = "experimental_category";
private static final String CATEGORY_DOWNLOADED_SERVICES = "user_installed_services_category";
- private static final String[] CATEGORIES = new String[] {
+ private static final String[] CATEGORIES = new String[]{
CATEGORY_SCREEN_READER, CATEGORY_AUDIO_AND_CAPTIONS, CATEGORY_DISPLAY,
CATEGORY_INTERACTION_CONTROL, CATEGORY_EXPERIMENTAL, CATEGORY_DOWNLOADED_SERVICES
};
// Preferences
- private static final String TOGGLE_INVERSION_PREFERENCE =
- "toggle_inversion_preference";
- private static final String TOGGLE_LARGE_POINTER_ICON =
- "toggle_large_pointer_icon";
- private static final String TOGGLE_DISABLE_ANIMATIONS = "toggle_disable_animations";
private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN =
"magnification_preference_screen";
- private static final String DISPLAY_DALTONIZER_PREFERENCE_SCREEN =
- "daltonizer_preference";
- private static final String DISPLAY_REDUCE_BRIGHT_COLORS_PREFERENCE_SCREEN =
- "reduce_bright_colors_preference";
// Extras passed to sub-fragments.
static final String EXTRA_PREFERENCE_KEY = "preference_key";
@@ -167,13 +155,7 @@
private final Map<ComponentName, PreferenceCategory> mPreBundledServiceComponentToCategoryMap =
new ArrayMap<>();
- private SwitchPreference mToggleLargePointerIconPreference;
- private SwitchPreference mToggleDisableAnimationsPreference;
private Preference mDisplayMagnificationPreferenceScreen;
- private Preference mDisplayDaltonizerPreferenceScreen;
- private Preference mToggleInversionPreference;
- private Preference mReduceBrightColorsPreference;
-
/**
* Check if the color transforms are color accelerated. Some transforms are experimental only
@@ -226,7 +208,6 @@
@Override
public void onAttach(Context context) {
super.onAttach(context);
- use(DarkUIPreferenceController.class).setParentFragment(this);
use(AccessibilityHearingAidPreferenceController.class)
.setFragmentManager(getFragmentManager());
}
@@ -259,8 +240,8 @@
/**
* Returns the summary for the current state of this accessibilityService.
*
- * @param context A valid context
- * @param info The accessibilityService's info
+ * @param context A valid context
+ * @param info The accessibilityService's info
* @param serviceEnabled Whether the accessibility service is enabled.
* @return The service summary
*/
@@ -299,8 +280,8 @@
/**
* Returns the description for the current state of this accessibilityService.
*
- * @param context A valid context
- * @param info The accessibilityService's info
+ * @param context A valid context
+ * @param info The accessibilityService's info
* @param serviceEnabled Whether the accessibility service is enabled.
* @return The service description
*/
@@ -325,24 +306,9 @@
mCategoryToPrefCategoryMap.put(CATEGORIES[i], prefCategory);
}
- // Display inversion.
- mToggleInversionPreference = findPreference(TOGGLE_INVERSION_PREFERENCE);
-
- // Large pointer icon.
- mToggleLargePointerIconPreference = findPreference(TOGGLE_LARGE_POINTER_ICON);
-
- mToggleDisableAnimationsPreference = findPreference(TOGGLE_DISABLE_ANIMATIONS);
-
// Display magnification.
mDisplayMagnificationPreferenceScreen = findPreference(
DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN);
-
- // Display color adjustments.
- mDisplayDaltonizerPreferenceScreen = findPreference(DISPLAY_DALTONIZER_PREFERENCE_SCREEN);
-
- // Reduce brightness.
- mReduceBrightColorsPreference =
- findPreference(DISPLAY_REDUCE_BRIGHT_COLORS_PREFERENCE_SCREEN);
}
private void updateAllPreferences() {
@@ -392,13 +358,13 @@
// Update the order of all the category according to the order defined in xml file.
updateCategoryOrderFromArray(CATEGORY_SCREEN_READER,
- R.array.config_order_screen_reader_services);
+ R.array.config_order_screen_reader_services);
updateCategoryOrderFromArray(CATEGORY_AUDIO_AND_CAPTIONS,
- R.array.config_order_audio_and_caption_services);
+ R.array.config_order_audio_and_caption_services);
updateCategoryOrderFromArray(CATEGORY_INTERACTION_CONTROL,
- R.array.config_order_interaction_control_services);
+ R.array.config_order_interaction_control_services);
updateCategoryOrderFromArray(CATEGORY_DISPLAY,
- R.array.config_order_display_services);
+ R.array.config_order_display_services);
// Need to check each time when updateServicePreferences() called.
if (downloadedServicesCategory.getPreferenceCount() == 0) {
@@ -468,7 +434,7 @@
* key with the string array of preference order which is defined in the xml.
*
* @param categoryKey The key of the category need to update the order
- * @param key The key of the string array which defines the order of category
+ * @param key The key of the string array which defines the order of category
*/
private void updateCategoryOrderFromArray(String categoryKey, int key) {
String[] services = getResources().getStringArray(key);
@@ -486,39 +452,11 @@
}
}
+ /**
+ * Updates preferences related to system configurations.
+ */
protected void updateSystemPreferences() {
- // Move color inversion and color correction preferences to Display category if device
- // supports HWC hardware-accelerated color transform.
- if (ColorDisplayManager.isColorTransformAccelerated(getContext())) {
- PreferenceCategory experimentalCategory =
- mCategoryToPrefCategoryMap.get(CATEGORY_EXPERIMENTAL);
- PreferenceCategory displayCategory =
- mCategoryToPrefCategoryMap.get(CATEGORY_DISPLAY);
- experimentalCategory.removePreference(mToggleInversionPreference);
- experimentalCategory.removePreference(mDisplayDaltonizerPreferenceScreen);
- experimentalCategory.removePreference(mReduceBrightColorsPreference);
- mDisplayMagnificationPreferenceScreen.setSummary(
- ToggleScreenMagnificationPreferenceFragment.getServiceSummary(getContext()));
- mDisplayDaltonizerPreferenceScreen.setOrder(
- mDisplayMagnificationPreferenceScreen.getOrder() + 1);
- mDisplayDaltonizerPreferenceScreen.setSummary(AccessibilityUtil.getSummary(
- getContext(), Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED));
- mToggleInversionPreference.setOrder(
- mDisplayDaltonizerPreferenceScreen.getOrder() + 1);
- mToggleLargePointerIconPreference.setOrder(
- mToggleInversionPreference.getOrder() + 1);
- mToggleDisableAnimationsPreference.setOrder(
- mToggleLargePointerIconPreference.getOrder() + 1);
- mToggleInversionPreference.setSummary(AccessibilityUtil.getSummary(
- getContext(), Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED));
- mReduceBrightColorsPreference.setOrder(
- mToggleDisableAnimationsPreference.getOrder() + 1);
- mReduceBrightColorsPreference.setSummary(AccessibilityUtil.getSummary(
- getContext(), Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED));
- displayCategory.addPreference(mToggleInversionPreference);
- displayCategory.addPreference(mDisplayDaltonizerPreferenceScreen);
- displayCategory.addPreference(mReduceBrightColorsPreference);
- }
+ // Do nothing.
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
diff --git a/src/com/android/settings/accessibility/TextAndDisplayFragment.java b/src/com/android/settings/accessibility/TextAndDisplayFragment.java
new file mode 100644
index 0000000..b496e3d
--- /dev/null
+++ b/src/com/android/settings/accessibility/TextAndDisplayFragment.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.hardware.display.ColorDisplayManager;
+import android.os.Bundle;
+import android.provider.Settings;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.SwitchPreference;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.display.DarkUIPreferenceController;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.search.SearchIndexable;
+
+/** Accessibility settings for text and display. */
+@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
+public class TextAndDisplayFragment extends DashboardFragment {
+
+ private static final String TAG = "TextAndDisplayFragment";
+
+ private static final String CATEGORY_EXPERIMENTAL = "experimental_category";
+
+ // Preferences
+ private static final String DISPLAY_DALTONIZER_PREFERENCE_SCREEN = "daltonizer_preference";
+ private static final String TOGGLE_INVERSION_PREFERENCE = "toggle_inversion_preference";
+ private static final String DISPLAY_REDUCE_BRIGHT_COLORS_PREFERENCE_SCREEN =
+ "reduce_bright_colors_preference";
+ private static final String TOGGLE_DISABLE_ANIMATIONS = "toggle_disable_animations";
+ private static final String TOGGLE_LARGE_POINTER_ICON = "toggle_large_pointer_icon";
+
+ private Preference mDisplayDaltonizerPreferenceScreen;
+ private Preference mToggleInversionPreference;
+ private Preference mReduceBrightColorsPreference;
+ private SwitchPreference mToggleDisableAnimationsPreference;
+ private SwitchPreference mToggleLargePointerIconPreference;
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.ACCESSIBILITY_TEXT_AND_DISPLAY;
+ }
+
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ initializeAllPreferences();
+ updateSystemPreferences();
+ }
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ use(DarkUIPreferenceController.class).setParentFragment(this);
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.accessibility_text_and_display;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ private void initializeAllPreferences() {
+ // Display color adjustments.
+ mDisplayDaltonizerPreferenceScreen = findPreference(DISPLAY_DALTONIZER_PREFERENCE_SCREEN);
+
+ // Display inversion.
+ mToggleInversionPreference = findPreference(TOGGLE_INVERSION_PREFERENCE);
+
+ // Reduce brightness.
+ mReduceBrightColorsPreference =
+ findPreference(DISPLAY_REDUCE_BRIGHT_COLORS_PREFERENCE_SCREEN);
+
+ // Disable animation.
+ mToggleDisableAnimationsPreference = findPreference(TOGGLE_DISABLE_ANIMATIONS);
+
+ // Large pointer icon.
+ mToggleLargePointerIconPreference = findPreference(TOGGLE_LARGE_POINTER_ICON);
+ }
+
+ /**
+ * Updates preferences related to system configurations.
+ */
+ private void updateSystemPreferences() {
+ final PreferenceCategory experimentalCategory = getPreferenceScreen().findPreference(
+ CATEGORY_EXPERIMENTAL);
+ if (ColorDisplayManager.isColorTransformAccelerated(getContext())) {
+ mDisplayDaltonizerPreferenceScreen.setSummary(AccessibilityUtil.getSummary(
+ getContext(), Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED));
+ mToggleInversionPreference.setSummary(AccessibilityUtil.getSummary(
+ getContext(), Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED));
+ mReduceBrightColorsPreference.setSummary(AccessibilityUtil.getSummary(
+ getContext(), Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED));
+ getPreferenceScreen().removePreference(experimentalCategory);
+ } else {
+ // Move following preferences to experimental category if device don't supports HWC
+ // hardware-accelerated color transform.
+ getPreferenceScreen().removePreference(mDisplayDaltonizerPreferenceScreen);
+ getPreferenceScreen().removePreference(mToggleInversionPreference);
+ getPreferenceScreen().removePreference(mReduceBrightColorsPreference);
+ getPreferenceScreen().removePreference(mToggleDisableAnimationsPreference);
+ getPreferenceScreen().removePreference(mToggleLargePointerIconPreference);
+ experimentalCategory.addPreference(mDisplayDaltonizerPreferenceScreen);
+ experimentalCategory.addPreference(mToggleInversionPreference);
+ experimentalCategory.addPreference(mReduceBrightColorsPreference);
+ experimentalCategory.addPreference(mToggleDisableAnimationsPreference);
+ experimentalCategory.addPreference(mToggleLargePointerIconPreference);
+ }
+ }
+
+ public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider(R.xml.accessibility_text_and_display);
+}
diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java b/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java
new file mode 100644
index 0000000..a43b9fd
--- /dev/null
+++ b/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications.specialaccess.notificationaccess;
+
+import android.app.NotificationManager;
+import android.app.settings.SettingsEnums;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.AsyncTask;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.SwitchPreference;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.overlay.FeatureFactory;
+
+public class ApprovalPreferenceController extends BasePreferenceController {
+
+ private static final String TAG = "ApprovalPrefController";
+
+ private PackageInfo mPkgInfo;
+ private ComponentName mCn;
+ private PreferenceFragmentCompat mParent;
+ private NotificationManager mNm;
+ private PackageManager mPm;
+
+ public ApprovalPreferenceController(Context context, String key) {
+ super(context, key);
+ }
+
+ public ApprovalPreferenceController setPkgInfo(PackageInfo pkgInfo) {
+ mPkgInfo = pkgInfo;
+ return this;
+ }
+
+ public ApprovalPreferenceController setCn(ComponentName cn) {
+ mCn = cn;
+ return this;
+ }
+
+ public ApprovalPreferenceController setParent(PreferenceFragmentCompat parent) {
+ mParent = parent;
+ return this;
+ }
+
+ public ApprovalPreferenceController setNm(NotificationManager nm) {
+ mNm = nm;
+ return this;
+ }
+
+ public ApprovalPreferenceController setPm(PackageManager pm) {
+ mPm = pm;
+ return this;
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public void updateState(Preference pref) {
+ final SwitchPreference preference = (SwitchPreference) pref;
+ final CharSequence label = mPkgInfo.applicationInfo.loadLabel(mPm);
+ preference.setChecked(isServiceEnabled(mCn));
+ preference.setOnPreferenceChangeListener((p, newValue) -> {
+ final boolean access = (Boolean) newValue;
+ if (!access) {
+ if (!isServiceEnabled(mCn)) {
+ return true; // already disabled
+ }
+ // show a friendly dialog
+ new FriendlyWarningDialogFragment()
+ .setServiceInfo(mCn, label, mParent)
+ .show(mParent.getFragmentManager(), "friendlydialog");
+ return false;
+ } else {
+ if (isServiceEnabled(mCn)) {
+ return true; // already enabled
+ }
+ // show a scary dialog
+ new ScaryWarningDialogFragment()
+ .setServiceInfo(mCn, label, mParent)
+ .show(mParent.getFragmentManager(), "dialog");
+ return false;
+ }
+ });
+ }
+
+ public void disable(final ComponentName cn) {
+ logSpecialPermissionChange(true, cn.getPackageName());
+ mNm.setNotificationListenerAccessGranted(cn, false);
+ AsyncTask.execute(() -> {
+ if (!mNm.isNotificationPolicyAccessGrantedForPackage(
+ cn.getPackageName())) {
+ mNm.removeAutomaticZenRules(cn.getPackageName());
+ }
+ });
+ }
+
+ protected void enable(ComponentName cn) {
+ logSpecialPermissionChange(true, cn.getPackageName());
+ mNm.setNotificationListenerAccessGranted(cn, true);
+ }
+
+ protected boolean isServiceEnabled(ComponentName cn) {
+ return mNm.isNotificationListenerAccessGranted(cn);
+ }
+
+ @VisibleForTesting
+ void logSpecialPermissionChange(boolean enable, String packageName) {
+ final int logCategory = enable ? SettingsEnums.APP_SPECIAL_PERMISSION_NOTIVIEW_ALLOW
+ : SettingsEnums.APP_SPECIAL_PERMISSION_NOTIVIEW_DENY;
+ FeatureFactory.getFactory(mContext).getMetricsFeatureProvider().action(mContext,
+ logCategory, packageName);
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/HeaderPreferenceController.java b/src/com/android/settings/applications/specialaccess/notificationaccess/HeaderPreferenceController.java
new file mode 100644
index 0000000..94736e4
--- /dev/null
+++ b/src/com/android/settings/applications/specialaccess/notificationaccess/HeaderPreferenceController.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications.specialaccess.notificationaccess;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.util.IconDrawableFactory;
+import android.view.View;
+
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.widget.EntityHeaderController;
+import com.android.settingslib.applications.AppUtils;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.LayoutPreference;
+
+public class HeaderPreferenceController extends BasePreferenceController
+ implements PreferenceControllerMixin, LifecycleObserver {
+
+ private DashboardFragment mFragment;
+ private EntityHeaderController mHeaderController;
+ private PackageInfo mPackageInfo;
+ private PackageManager mPm;
+ private CharSequence mServiceName;
+
+ public HeaderPreferenceController(Context context, String key) {
+ super(context, key);
+ }
+
+ public HeaderPreferenceController setFragment(DashboardFragment fragment) {
+ mFragment = fragment;
+ return this;
+ }
+
+ public HeaderPreferenceController setPackageInfo(PackageInfo packageInfo) {
+ mPackageInfo = packageInfo;
+ return this;
+ }
+
+ public HeaderPreferenceController setPm(PackageManager pm) {
+ mPm = pm;
+ return this;
+ }
+
+ public HeaderPreferenceController setServiceName(CharSequence serviceName) {
+ mServiceName = serviceName;
+ return this;
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ if (mFragment == null) {
+ return;
+ }
+ LayoutPreference pref = screen.findPreference(getPreferenceKey());
+ mHeaderController = EntityHeaderController.newInstance(
+ mFragment.getActivity(), mFragment, pref.findViewById(R.id.entity_header));
+ pref = mHeaderController
+ .setRecyclerView(mFragment.getListView(), mFragment.getSettingsLifecycle())
+ .setIcon(IconDrawableFactory.newInstance(mFragment.getActivity())
+ .getBadgedIcon(mPackageInfo.applicationInfo))
+ .setLabel(mPackageInfo.applicationInfo.loadLabel(mPm))
+ .setSummary(mServiceName)
+ .setIsInstantApp(AppUtils.isInstant(mPackageInfo.applicationInfo))
+ .setPackageName(mPackageInfo.packageName)
+ .setUid(mPackageInfo.applicationInfo.uid)
+ .setHasAppInfoLink(true)
+ .setButtonActions(EntityHeaderController.ActionType.ACTION_NONE,
+ EntityHeaderController.ActionType.ACTION_NONE)
+ .done(mFragment.getActivity(), mContext);
+ pref.findViewById(R.id.entity_header).setVisibility(View.VISIBLE);
+ }
+
+ @OnLifecycleEvent(Lifecycle.Event.ON_START)
+ public void onStart() {
+ if (mHeaderController != null) {
+ mHeaderController.styleActionBar(mFragment.getActivity());
+ }
+ }
+}
diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetails.java b/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetails.java
index 58a6d7f..9f4b693 100644
--- a/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetails.java
+++ b/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetails.java
@@ -16,52 +16,55 @@
package com.android.settings.applications.specialaccess.notificationaccess;
+import static com.android.settings.applications.AppInfoBase.ARG_PACKAGE_NAME;
+
import android.app.Activity;
import android.app.NotificationManager;
import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
-import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.service.notification.NotificationListenerService;
-import android.util.IconDrawableFactory;
import android.util.Log;
import android.util.Slog;
-import androidx.annotation.VisibleForTesting;
-import androidx.appcompat.app.AlertDialog;
-import androidx.preference.Preference;
-import androidx.preference.SwitchPreference;
+import androidx.preference.PreferenceScreen;
import com.android.settings.R;
-import com.android.settings.applications.AppInfoBase;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.widget.EntityHeaderController;
-import com.android.settingslib.applications.AppUtils;
+import com.android.settings.SettingsActivity;
+import com.android.settings.applications.manageapplications.ManageApplications;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.notification.NotificationBackend;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import java.util.List;
import java.util.Objects;
-public class NotificationAccessDetails extends AppInfoBase {
+public class NotificationAccessDetails extends DashboardFragment {
private static final String TAG = "NotifAccessDetails";
- private static final String SWITCH_PREF_KEY = "notification_access_switch";
- private boolean mCreated;
private ComponentName mComponentName;
private CharSequence mServiceName;
+ protected PackageInfo mPackageInfo;
+ protected int mUserId;
+ protected String mPackageName;
+ protected RestrictedLockUtils.EnforcedAdmin mAppsControlDisallowedAdmin;
+ protected boolean mAppsControlDisallowedBySystem;
private boolean mIsNls;
-
- private NotificationManager mNm;
private PackageManager mPm;
@Override
- public void onCreate(Bundle savedInstanceState) {
+ public void onAttach(Context context) {
+ super.onAttach(context);
final Intent intent = getIntent();
if (mComponentName == null && intent != null) {
String cn = intent.getStringExtra(Settings.EXTRA_NOTIFICATION_LISTENER_COMPONENT_NAME);
@@ -73,38 +76,24 @@
}
}
}
- super.onCreate(savedInstanceState);
- mNm = getContext().getSystemService(NotificationManager.class);
mPm = getPackageManager();
- addPreferencesFromResource(R.xml.notification_access_permission_details);
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- if (mCreated) {
- Log.w(TAG, "onActivityCreated: ignoring duplicate call");
- return;
- }
- mCreated = true;
- if (mPackageInfo == null) return;
+ retrieveAppEntry();
loadNotificationListenerService();
- final Activity activity = getActivity();
- final Preference pref = EntityHeaderController
- .newInstance(activity, this, null /* header */)
- .setRecyclerView(getListView(), getSettingsLifecycle())
- .setIcon(IconDrawableFactory.newInstance(getContext())
- .getBadgedIcon(mPackageInfo.applicationInfo))
- .setLabel(mPackageInfo.applicationInfo.loadLabel(mPm))
- .setSummary(mServiceName)
- .setIsInstantApp(AppUtils.isInstant(mPackageInfo.applicationInfo))
- .setPackageName(mPackageName)
- .setUid(mPackageInfo.applicationInfo.uid)
- .setHasAppInfoLink(true)
- .setButtonActions(EntityHeaderController.ActionType.ACTION_NONE,
- EntityHeaderController.ActionType.ACTION_NONE)
- .done(activity, getPrefContext());
- getPreferenceScreen().addPreference(pref);
+ use(ApprovalPreferenceController.class)
+ .setPkgInfo(mPackageInfo)
+ .setCn(mComponentName)
+ .setNm(context.getSystemService(NotificationManager.class))
+ .setPm(context.getPackageManager())
+ .setParent(this);
+ use(HeaderPreferenceController.class)
+ .setFragment(this)
+ .setPackageInfo(mPackageInfo)
+ .setPm(context.getPackageManager())
+ .setServiceName(mServiceName);
+ use(TypeFilterPreferenceController.class)
+ .setNm(new NotificationBackend())
+ .setCn(mComponentName)
+ .setUserId(mUserId);
}
@Override
@@ -112,9 +101,7 @@
return SettingsEnums.NOTIFICATION_ACCESS_DETAIL;
}
- @Override
protected boolean refreshUi() {
- final Context context = getContext();
if (mComponentName == null) {
// No service given
Slog.d(TAG, "No component name provided");
@@ -130,72 +117,78 @@
Slog.d(TAG, "NLSes aren't allowed in work profiles");
return false;
}
- updatePreference(findPreference(SWITCH_PREF_KEY));
return true;
}
@Override
- protected AlertDialog createDialog(int id, int errorCode) {
- return null;
+ public void onResume() {
+ super.onResume();
+ mAppsControlDisallowedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
+ getActivity(), UserManager.DISALLOW_APPS_CONTROL, mUserId);
+ mAppsControlDisallowedBySystem = RestrictedLockUtilsInternal.hasBaseUserRestriction(
+ getActivity(), UserManager.DISALLOW_APPS_CONTROL, mUserId);
+
+ if (!refreshUi()) {
+ setIntentAndFinish(true /* appChanged */);
+ }
}
- public void updatePreference(SwitchPreference preference) {
- final CharSequence label = mPackageInfo.applicationInfo.loadLabel(mPm);
- preference.setChecked(isServiceEnabled(mComponentName));
- preference.setOnPreferenceChangeListener((p, newValue) -> {
- final boolean access = (Boolean) newValue;
- if (!access) {
- if (!isServiceEnabled(mComponentName)) {
- return true; // already disabled
- }
- // show a friendly dialog
- new FriendlyWarningDialogFragment()
- .setServiceInfo(mComponentName, label, this)
- .show(getFragmentManager(), "friendlydialog");
- return false;
- } else {
- if (isServiceEnabled(mComponentName)) {
- return true; // already enabled
- }
- // show a scary dialog
- new ScaryWarningDialogFragment()
- .setServiceInfo(mComponentName, label, this)
- .show(getFragmentManager(), "dialog");
- return false;
+ protected void setIntentAndFinish(boolean appChanged) {
+ Log.i(TAG, "appChanged=" + appChanged);
+ Intent intent = new Intent();
+ intent.putExtra(ManageApplications.APP_CHG, appChanged);
+ SettingsActivity sa = (SettingsActivity) getActivity();
+ sa.finishPreferencePanel(Activity.RESULT_OK, intent);
+ }
+
+ protected void retrieveAppEntry() {
+ final Bundle args = getArguments();
+ mPackageName = (args != null) ? args.getString(ARG_PACKAGE_NAME) : null;
+ Intent intent = (args == null) ?
+ getIntent() : (Intent) args.getParcelable("intent");
+ if (mPackageName == null) {
+ if (intent != null && intent.getData() != null) {
+ mPackageName = intent.getData().getSchemeSpecificPart();
}
- });
+ }
+ if (intent != null && intent.hasExtra(Intent.EXTRA_USER_HANDLE)) {
+ mUserId = ((UserHandle) intent.getParcelableExtra(
+ Intent.EXTRA_USER_HANDLE)).getIdentifier();
+ } else {
+ mUserId = UserHandle.myUserId();
+ }
+
+ try {
+ mPackageInfo = mPm.getPackageInfoAsUser(mPackageName,
+ PackageManager.MATCH_DISABLED_COMPONENTS |
+ PackageManager.GET_SIGNING_CERTIFICATES |
+ PackageManager.GET_PERMISSIONS, mUserId);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "Exception when retrieving package:" + mPackageName, e);
+ }
}
- @VisibleForTesting
- void logSpecialPermissionChange(boolean enable, String packageName) {
- int logCategory = enable ? SettingsEnums.APP_SPECIAL_PERMISSION_NOTIVIEW_ALLOW
- : SettingsEnums.APP_SPECIAL_PERMISSION_NOTIVIEW_DENY;
- FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider().action(getContext(),
- logCategory, packageName);
- }
-
+ // Dialogs only have access to the parent fragment, not the controller, so pass the information
+ // along to keep business logic out of this file
public void disable(final ComponentName cn) {
- logSpecialPermissionChange(true, cn.getPackageName());
- mNm.setNotificationListenerAccessGranted(cn, false);
- AsyncTask.execute(() -> {
- if (!mNm.isNotificationPolicyAccessGrantedForPackage(
- cn.getPackageName())) {
- mNm.removeAutomaticZenRules(cn.getPackageName());
- }
- });
- refreshUi();
+ final PreferenceScreen screen = getPreferenceScreen();
+ ApprovalPreferenceController controller = use(ApprovalPreferenceController.class);
+ controller.disable(cn);
+ controller.updateState(screen.findPreference(controller.getPreferenceKey()));
+ TypeFilterPreferenceController dependent1 = use(TypeFilterPreferenceController.class);
+ dependent1.updateState(screen.findPreference(dependent1.getPreferenceKey()));
}
protected void enable(ComponentName cn) {
- logSpecialPermissionChange(true, cn.getPackageName());
- mNm.setNotificationListenerAccessGranted(cn, true);
- refreshUi();
+ final PreferenceScreen screen = getPreferenceScreen();
+ ApprovalPreferenceController controller = use(ApprovalPreferenceController.class);
+ controller.enable(cn);
+ controller.updateState(screen.findPreference(controller.getPreferenceKey()));
+ TypeFilterPreferenceController dependent1 = use(TypeFilterPreferenceController.class);
+ dependent1.updateState(screen.findPreference(dependent1.getPreferenceKey()));
}
- protected boolean isServiceEnabled(ComponentName cn) {
- return mNm.isNotificationListenerAccessGranted(cn);
- }
-
+ // To save binder calls, load this in the fragment rather than each preference controller
protected void loadNotificationListenerService() {
mIsNls = false;
@@ -218,4 +211,14 @@
}
}
}
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.notification_access_permission_details;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
}
\ No newline at end of file
diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/TypeFilterPreferenceController.java b/src/com/android/settings/applications/specialaccess/notificationaccess/TypeFilterPreferenceController.java
new file mode 100644
index 0000000..9d7fcc1
--- /dev/null
+++ b/src/com/android/settings/applications/specialaccess/notificationaccess/TypeFilterPreferenceController.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2021 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.applications.specialaccess.notificationaccess;
+
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_SILENT;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.service.notification.NotificationListenerFilter;
+
+import androidx.preference.MultiSelectListPreference;
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.notification.NotificationBackend;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class TypeFilterPreferenceController extends BasePreferenceController implements
+ PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
+
+ private static final String TAG = "TypeFilterPrefCntlr";
+
+ private ComponentName mCn;
+ private int mUserId;
+ private NotificationBackend mNm;
+ private NotificationListenerFilter mNlf;
+
+ public TypeFilterPreferenceController(Context context, String key) {
+ super(context, key);
+ }
+
+ public TypeFilterPreferenceController setCn(ComponentName cn) {
+ mCn = cn;
+ return this;
+ }
+
+ public TypeFilterPreferenceController setUserId(int userId) {
+ mUserId = userId;
+ return this;
+ }
+
+ public TypeFilterPreferenceController setNm(NotificationBackend nm) {
+ mNm = nm;
+ return this;
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ if (mNm.isNotificationListenerAccessGranted(mCn)) {
+ return AVAILABLE;
+ } else {
+ return DISABLED_DEPENDENT_SETTING;
+ }
+ }
+
+ @Override
+ public void updateState(Preference pref) {
+ mNlf = mNm.getListenerFilter(mCn, mUserId);
+ Set<String> values = new HashSet<>();
+ Set<String> entries = new HashSet<>();
+
+ if (hasFlag(mNlf.getTypes(), FLAG_FILTER_TYPE_ONGOING)) {
+ values.add(String.valueOf(FLAG_FILTER_TYPE_ONGOING));
+ entries.add(mContext.getString(R.string.notif_type_ongoing));
+ }
+ if (hasFlag(mNlf.getTypes(), FLAG_FILTER_TYPE_CONVERSATIONS)) {
+ values.add(String.valueOf(FLAG_FILTER_TYPE_CONVERSATIONS));
+ entries.add(mContext.getString(R.string.notif_type_conversation));
+ }
+ if (hasFlag(mNlf.getTypes(), FLAG_FILTER_TYPE_ALERTING)) {
+ values.add(String.valueOf(FLAG_FILTER_TYPE_ALERTING));
+ entries.add(mContext.getString(R.string.notif_type_alerting));
+ }
+ if (hasFlag(mNlf.getTypes(), FLAG_FILTER_TYPE_SILENT)) {
+ values.add(String.valueOf(FLAG_FILTER_TYPE_SILENT));
+ entries.add(mContext.getString(R.string.notif_type_silent));
+ }
+
+ final MultiSelectListPreference preference = (MultiSelectListPreference) pref;
+ preference.setValues(values);
+ super.updateState(preference);
+ pref.setEnabled(getAvailabilityStatus() == AVAILABLE);
+ }
+
+ private boolean hasFlag(int value, int flag) {
+ return (value & flag) != 0;
+ }
+
+ public CharSequence getSummary() {
+ Set<String> entries = new HashSet<>();
+ if (hasFlag(mNlf.getTypes(), FLAG_FILTER_TYPE_ONGOING)) {
+ entries.add(mContext.getString(R.string.notif_type_ongoing));
+ }
+ if (hasFlag(mNlf.getTypes(), FLAG_FILTER_TYPE_CONVERSATIONS)) {
+ entries.add(mContext.getString(R.string.notif_type_conversation));
+ }
+ if (hasFlag(mNlf.getTypes(), FLAG_FILTER_TYPE_ALERTING)) {
+ entries.add(mContext.getString(R.string.notif_type_alerting));
+ }
+ if (hasFlag(mNlf.getTypes(), FLAG_FILTER_TYPE_SILENT)) {
+ entries.add(mContext.getString(R.string.notif_type_silent));
+ }
+ return String.join(System.lineSeparator(), entries);
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ // retrieve latest in case the package filter has changed
+ mNlf = mNm.getListenerFilter(mCn, mUserId);
+
+ Set<String> set = (Set<String>) newValue;
+
+ int newFilter = 0;
+ for (String filterType : set) {
+ newFilter |= Integer.parseInt(filterType);
+ }
+ mNlf.setTypes(newFilter);
+ preference.setSummary(getSummary());
+ mNm.setListenerFilter(mCn, mUserId, mNlf);
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
index f8a4f39..2e326b0 100644
--- a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
+++ b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
@@ -29,6 +29,7 @@
import com.android.settings.deviceinfo.StorageDashboardFragment;
import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
import com.android.settings.display.NightDisplaySettings;
+import com.android.settings.emergency.EmergencyDashboardFragment;
import com.android.settings.enterprise.EnterprisePrivacySettings;
import com.android.settings.fuelgauge.PowerUsageSummary;
import com.android.settings.fuelgauge.SmartBatterySettings;
@@ -81,6 +82,8 @@
CategoryKey.CATEGORY_BATTERY);
PARENT_TO_CATEGORY_KEY_MAP.put(DisplaySettings.class.getName(),
CategoryKey.CATEGORY_DISPLAY);
+ PARENT_TO_CATEGORY_KEY_MAP.put(EmergencyDashboardFragment.class.getName(),
+ CategoryKey.CATEGORY_EMERGENCY);
PARENT_TO_CATEGORY_KEY_MAP.put(SoundSettings.class.getName(),
CategoryKey.CATEGORY_SOUND);
PARENT_TO_CATEGORY_KEY_MAP.put(StorageDashboardFragment.class.getName(),
diff --git a/src/com/android/settings/display/NightDisplayPreferenceController.java b/src/com/android/settings/display/NightDisplayPreferenceController.java
index 0198007..003373c 100644
--- a/src/com/android/settings/display/NightDisplayPreferenceController.java
+++ b/src/com/android/settings/display/NightDisplayPreferenceController.java
@@ -17,6 +17,7 @@
import android.hardware.display.ColorDisplayManager;
import android.hardware.display.NightDisplayListener;
+import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
@@ -32,6 +33,7 @@
private final ColorDisplayManager mColorDisplayManager;
private final NightDisplayListener mNightDisplayListener;
+ private final NightDisplayTimeFormatter mTimeFormatter;
private PrimarySwitchPreference mPreference;
public NightDisplayPreferenceController(Context context, String key) {
@@ -39,6 +41,7 @@
mColorDisplayManager = context.getSystemService(ColorDisplayManager.class);
mNightDisplayListener = new NightDisplayListener(context);
+ mTimeFormatter = new NightDisplayTimeFormatter(context);
}
public static boolean isSuggestionComplete(Context context) {
@@ -87,6 +90,12 @@
}
@Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ preference.setSummary(mTimeFormatter.getAutoModeSummary(mContext, mColorDisplayManager));
+ }
+
+ @Override
public void onActivated(boolean activated) {
updateState(mPreference);
}
diff --git a/src/com/android/settings/display/NightDisplayTimeFormatter.java b/src/com/android/settings/display/NightDisplayTimeFormatter.java
index 1449ac1..aa715de 100644
--- a/src/com/android/settings/display/NightDisplayTimeFormatter.java
+++ b/src/com/android/settings/display/NightDisplayTimeFormatter.java
@@ -17,8 +17,8 @@
package com.android.settings.display;
import android.content.Context;
-
import android.hardware.display.ColorDisplayManager;
+
import com.android.settings.R;
import java.text.DateFormat;
@@ -45,13 +45,6 @@
return mTimeFormatter.format(c.getTime());
}
- public String getAutoModeTimeSummary(Context context, ColorDisplayManager manager) {
- final int summaryFormatResId =
- manager.isNightDisplayActivated() ? R.string.night_display_summary_on
- : R.string.night_display_summary_off;
- return context.getString(summaryFormatResId, getAutoModeSummary(context, manager));
- }
-
public String getAutoModeSummary(Context context, ColorDisplayManager manager) {
final boolean isActivated = manager.isNightDisplayActivated();
final int autoMode = manager.getNightDisplayAutoMode();
diff --git a/src/com/android/settings/display/ScreenTimeoutSettings.java b/src/com/android/settings/display/ScreenTimeoutSettings.java
index 83f904a..a90c886 100644
--- a/src/com/android/settings/display/ScreenTimeoutSettings.java
+++ b/src/com/android/settings/display/ScreenTimeoutSettings.java
@@ -37,13 +37,13 @@
import com.android.settings.support.actionbar.HelpMenuController;
import com.android.settings.support.actionbar.HelpResourceProvider;
import com.android.settings.widget.RadioButtonPickerFragment;
-import com.android.settings.widget.RadioButtonPreferenceWithExtraWidget;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.search.SearchIndexableRaw;
import com.android.settingslib.widget.CandidateInfo;
import com.android.settingslib.widget.FooterPreference;
+import com.android.settingslib.widget.RadioButtonPreference;
import com.google.common.annotations.VisibleForTesting;
@@ -152,8 +152,8 @@
}
for (CandidateInfo info : candidateList) {
- RadioButtonPreferenceWithExtraWidget pref =
- new RadioButtonPreferenceWithExtraWidget(getPrefContext());
+ RadioButtonPreference pref =
+ new RadioButtonPreference(getPrefContext());
bindPreference(pref, info.getKey(), info, defaultKey);
screen.addPreference(pref);
}
diff --git a/src/com/android/settings/display/darkmode/DarkModePreference.java b/src/com/android/settings/display/darkmode/DarkModePreference.java
index baaa1f7..c69bb01 100644
--- a/src/com/android/settings/display/darkmode/DarkModePreference.java
+++ b/src/com/android/settings/display/darkmode/DarkModePreference.java
@@ -74,10 +74,10 @@
return;
}
final int mode = mUiModeManager.getNightMode();
- String detail;
+ String summary;
if (mode == UiModeManager.MODE_NIGHT_AUTO) {
- detail = getContext().getString(active
+ summary = getContext().getString(active
? R.string.dark_ui_summary_on_auto_mode_auto
: R.string.dark_ui_summary_off_auto_mode_auto);
} else if (mode == UiModeManager.MODE_NIGHT_CUSTOM) {
@@ -85,17 +85,14 @@
? mUiModeManager.getCustomNightModeEnd()
: mUiModeManager.getCustomNightModeStart();
final String timeStr = mFormat.of(time);
- detail = getContext().getString(active
+ summary = getContext().getString(active
? R.string.dark_ui_summary_on_auto_mode_custom
: R.string.dark_ui_summary_off_auto_mode_custom, timeStr);
} else {
- detail = getContext().getString(active
+ summary = getContext().getString(active
? R.string.dark_ui_summary_on_auto_mode_never
: R.string.dark_ui_summary_off_auto_mode_never);
}
- String summary = getContext().getString(active
- ? R.string.dark_ui_summary_on
- : R.string.dark_ui_summary_off, detail);
setSummary(summary);
}
diff --git a/src/com/android/settings/emergency/EmergencyDashboardFragment.java b/src/com/android/settings/emergency/EmergencyDashboardFragment.java
new file mode 100644
index 0000000..c786767
--- /dev/null
+++ b/src/com/android/settings/emergency/EmergencyDashboardFragment.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2021 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.emergency;
+
+import android.app.settings.SettingsEnums;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.search.SearchIndexable;
+
+
+/**
+ * {@link DashboardFragment} that hosts emergency/safety related settings.
+ */
+@SearchIndexable
+public class EmergencyDashboardFragment extends DashboardFragment {
+
+ private static final String TAG = "EmergencyDashboard";
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.emergency_settings;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.EMERGENCY_SOS_GESTURE_SETTINGS;
+ }
+
+ public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider(R.xml.emergency_settings);
+}
diff --git a/src/com/android/settings/emergency/OWNERS b/src/com/android/settings/emergency/OWNERS
new file mode 100644
index 0000000..5707f87
--- /dev/null
+++ b/src/com/android/settings/emergency/OWNERS
@@ -0,0 +1 @@
+zhfan@google.com
\ No newline at end of file
diff --git a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
index bed14a8..ddcdd59 100644
--- a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
+++ b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
@@ -21,9 +21,6 @@
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_GONE;
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_SETTING;
-
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
@@ -49,7 +46,6 @@
import com.android.settings.support.actionbar.HelpResourceProvider;
import com.android.settings.utils.CandidateInfoExtra;
import com.android.settings.widget.RadioButtonPickerFragment;
-import com.android.settings.widget.RadioButtonPreferenceWithExtraWidget;
import com.android.settings.widget.VideoPreference;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.widget.CandidateInfo;
@@ -119,8 +115,8 @@
return;
}
for (CandidateInfo info : candidateList) {
- RadioButtonPreferenceWithExtraWidget pref =
- new RadioButtonPreferenceWithExtraWidget(getPrefContext());
+ RadioButtonPreference pref =
+ new RadioButtonPreference(getPrefContext());
bindPreference(pref, info.getKey(), info, defaultKey);
bindPreferenceExtra(pref, info.getKey(), info, defaultKey, systemDefaultKey);
screen.addPreference(pref);
@@ -131,20 +127,15 @@
@Override
public void bindPreferenceExtra(RadioButtonPreference pref,
String key, CandidateInfo info, String defaultKey, String systemDefaultKey) {
- if (!(info instanceof CandidateInfoExtra)
- || !(pref instanceof RadioButtonPreferenceWithExtraWidget)) {
+ if (!(info instanceof CandidateInfoExtra)) {
return;
}
pref.setSummary(((CandidateInfoExtra) info).loadSummary());
- RadioButtonPreferenceWithExtraWidget p = (RadioButtonPreferenceWithExtraWidget) pref;
if (info.getKey() == KEY_SYSTEM_NAV_GESTURAL) {
- p.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_SETTING);
- p.setExtraWidgetOnClickListener((v) -> startActivity(new Intent(
+ pref.setExtraWidgetOnClickListener((v) -> startActivity(new Intent(
GestureNavigationSettingsFragment.GESTURE_NAVIGATION_SETTINGS)));
- } else {
- p.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_GONE);
}
}
diff --git a/src/com/android/settings/network/NetworkMobileProviderController.java b/src/com/android/settings/network/NetworkMobileProviderController.java
index 4c29256..5dc6c0d 100644
--- a/src/com/android/settings/network/NetworkMobileProviderController.java
+++ b/src/com/android/settings/network/NetworkMobileProviderController.java
@@ -24,6 +24,7 @@
import androidx.preference.PreferenceScreen;
import com.android.settings.core.BasePreferenceController;
+import com.android.settings.wifi.WifiPickerTrackerHelper;
import com.android.settingslib.core.lifecycle.Lifecycle;
/**
@@ -115,4 +116,10 @@
}
mPreferenceCategory.setVisible(available);
}
+
+ public void setWifiPickerTrackerHelper(WifiPickerTrackerHelper helper) {
+ if (mSubscriptionsController != null) {
+ mSubscriptionsController.setWifiPickerTrackerHelper(helper);
+ }
+ }
}
diff --git a/src/com/android/settings/network/NetworkProviderSettings.java b/src/com/android/settings/network/NetworkProviderSettings.java
index c2881ac..c4c767b 100644
--- a/src/com/android/settings/network/NetworkProviderSettings.java
+++ b/src/com/android/settings/network/NetworkProviderSettings.java
@@ -27,19 +27,12 @@
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
import android.net.NetworkTemplate;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
import android.os.PowerManager;
-import android.os.Process;
-import android.os.SimpleClock;
-import android.os.SystemClock;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.FeatureFlagUtils;
@@ -74,6 +67,7 @@
import com.android.settings.wifi.WifiConfigUiBase2;
import com.android.settings.wifi.WifiConnectListener;
import com.android.settings.wifi.WifiDialog2;
+import com.android.settings.wifi.WifiPickerTrackerHelper;
import com.android.settings.wifi.WifiUtils;
import com.android.settings.wifi.details2.WifiNetworkDetailsFragment2;
import com.android.settings.wifi.dpp.WifiDppUtils;
@@ -88,8 +82,6 @@
import com.android.wifitrackerlib.WifiEntry.ConnectCallback;
import com.android.wifitrackerlib.WifiPickerTracker;
-import java.time.Clock;
-import java.time.ZoneOffset;
import java.util.List;
import java.util.Optional;
@@ -115,11 +107,6 @@
static final int MENU_ID_FORGET = Menu.FIRST + 3;
static final int MENU_ID_MODIFY = Menu.FIRST + 4;
- // Max age of tracked WifiEntries
- private static final long MAX_SCAN_AGE_MILLIS = 15_000;
- // Interval between initiating WifiPickerTracker scans
- private static final long SCAN_INTERVAL_MILLIS = 10_000;
-
@VisibleForTesting
static final int ADD_NETWORK_REQUEST = 2;
static final int CONFIG_NETWORK_REQUEST = 3;
@@ -187,11 +174,9 @@
*/
private boolean mIsRestricted;
- // Worker thread used for WifiPickerTracker work
- private HandlerThread mWorkerThread;
-
@VisibleForTesting
WifiPickerTracker mWifiPickerTracker;
+ private WifiPickerTrackerHelper mWifiPickerTrackerHelper;
private WifiDialog2 mDialog;
@@ -279,27 +264,9 @@
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- final Context context = getContext();
- mWorkerThread = new HandlerThread(TAG
- + "{" + Integer.toHexString(System.identityHashCode(this)) + "}",
- Process.THREAD_PRIORITY_BACKGROUND);
- mWorkerThread.start();
- final Clock elapsedRealtimeClock = new SimpleClock(ZoneOffset.UTC) {
- @Override
- public long millis() {
- return SystemClock.elapsedRealtime();
- }
- };
- mWifiPickerTracker = new WifiPickerTracker(getSettingsLifecycle(), context,
- context.getSystemService(WifiManager.class),
- context.getSystemService(ConnectivityManager.class),
- context.getSystemService(NetworkScoreManager.class),
- new Handler(Looper.getMainLooper()),
- mWorkerThread.getThreadHandler(),
- elapsedRealtimeClock,
- MAX_SCAN_AGE_MILLIS,
- SCAN_INTERVAL_MILLIS,
- this);
+ mWifiPickerTrackerHelper =
+ new WifiPickerTrackerHelper(getSettingsLifecycle(), getContext(), this);
+ mWifiPickerTracker = mWifiPickerTrackerHelper.getWifiPickerTracker();
final Activity activity = getActivity();
@@ -356,6 +323,10 @@
if (intent.hasExtra(EXTRA_START_CONNECT_SSID)) {
mOpenSsid = intent.getStringExtra(EXTRA_START_CONNECT_SSID);
}
+
+ if (mNetworkMobileProviderController != null) {
+ mNetworkMobileProviderController.setWifiPickerTrackerHelper(mWifiPickerTrackerHelper);
+ }
}
@Override
@@ -365,13 +336,6 @@
}
@Override
- public void onDestroyView() {
- mWorkerThread.quit();
-
- super.onDestroyView();
- }
-
- @Override
public void onStart() {
super.onStart();
diff --git a/src/com/android/settings/network/SubscriptionsPreferenceController.java b/src/com/android/settings/network/SubscriptionsPreferenceController.java
index a17fc60..6e67543 100644
--- a/src/com/android/settings/network/SubscriptionsPreferenceController.java
+++ b/src/com/android/settings/network/SubscriptionsPreferenceController.java
@@ -50,6 +50,7 @@
import com.android.settings.network.telephony.MobileNetworkUtils;
import com.android.settings.network.telephony.SignalStrengthListener;
import com.android.settings.widget.GearPreference;
+import com.android.settings.wifi.WifiPickerTrackerHelper;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.net.SignalStrengthUtil;
@@ -84,6 +85,7 @@
private MobileDataEnabledListener mDataEnabledListener;
private DataConnectivityListener mConnectivityListener;
private SignalStrengthListener mSignalStrengthListener;
+ private WifiPickerTrackerHelper mWifiPickerTrackerHelper;
@VisibleForTesting
final BroadcastReceiver mDataSubscriptionChangedReceiver = new BroadcastReceiver() {
@@ -215,7 +217,7 @@
mPreferenceGroup.removeAll();
mSubsGearPref = new GearPreference(mContext, null);
mSubsGearPref.setOnPreferenceClickListener(preference -> {
- //TODO(b/176141379) Wait for wifiManager#selectCarrier(int subscriptionId)
+ connectCarrierNetwork();
return true;
});
mSubsGearPref.setOnGearClickListener(p ->
@@ -466,6 +468,20 @@
ProxySubscriptionManager.getInstance(context), subId) != null);
}
+ public void setWifiPickerTrackerHelper(WifiPickerTrackerHelper helper) {
+ mWifiPickerTrackerHelper = helper;
+ }
+
+ @VisibleForTesting
+ public void connectCarrierNetwork() {
+ if (mTelephonyManager == null || !mTelephonyManager.isDataEnabled()) {
+ return;
+ }
+ if (mWifiPickerTrackerHelper != null) {
+ mWifiPickerTrackerHelper.connectCarrierNetwork(null /* ConnectCallback */);
+ }
+ }
+
SubsPrefCtrlInjector createSubsPrefCtrlInjector() {
return new SubsPrefCtrlInjector();
}
diff --git a/src/com/android/settings/network/telephony/MobileDataDialogFragment.java b/src/com/android/settings/network/telephony/MobileDataDialogFragment.java
index c8a1e98..180d503 100644
--- a/src/com/android/settings/network/telephony/MobileDataDialogFragment.java
+++ b/src/com/android/settings/network/telephony/MobileDataDialogFragment.java
@@ -28,6 +28,7 @@
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settings.wifi.WifiPickerTrackerHelper;
/**
@@ -50,6 +51,8 @@
private int mType;
private int mSubId;
+ private WifiPickerTrackerHelper mWifiPickerTrackerHelper;
+
public static MobileDataDialogFragment newInstance(int type, int subId) {
final MobileDataDialogFragment dialogFragment = new MobileDataDialogFragment();
@@ -65,6 +68,8 @@
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSubscriptionManager = getContext().getSystemService(SubscriptionManager.class);
+ mWifiPickerTrackerHelper = new WifiPickerTrackerHelper(getSettingsLifecycle(), getContext(),
+ null /* WifiPickerTrackerCallback */);
}
@Override
@@ -124,11 +129,17 @@
case TYPE_DISABLE_DIALOG:
MobileNetworkUtils.setMobileDataEnabled(getContext(), mSubId, false /* enabled */,
false /* disableOtherSubscriptions */);
+ if (mWifiPickerTrackerHelper != null) {
+ mWifiPickerTrackerHelper.setCarrierNetworkEnabled(false);
+ }
break;
case TYPE_MULTI_SIM_DIALOG:
mSubscriptionManager.setDefaultDataSubId(mSubId);
MobileNetworkUtils.setMobileDataEnabled(getContext(), mSubId, true /* enabled */,
true /* disableOtherSubscriptions */);
+ if (mWifiPickerTrackerHelper != null) {
+ mWifiPickerTrackerHelper.setCarrierNetworkEnabled(true);
+ }
break;
default:
throw new IllegalArgumentException("unknown type " + mType);
diff --git a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
index 91c46df..78bc0a0 100644
--- a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
+++ b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
@@ -32,6 +32,7 @@
import com.android.settings.R;
import com.android.settings.network.MobileDataContentObserver;
+import com.android.settings.wifi.WifiPickerTrackerHelper;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -54,6 +55,8 @@
@VisibleForTesting
boolean mNeedDialog;
+ private WifiPickerTrackerHelper mWifiPickerTrackerHelper;
+
public MobileDataPreferenceController(Context context, String key) {
super(context, key);
mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
@@ -107,6 +110,9 @@
if (!mNeedDialog) {
// Update data directly if we don't need dialog
MobileNetworkUtils.setMobileDataEnabled(mContext, mSubId, isChecked, false);
+ if (mWifiPickerTrackerHelper != null) {
+ mWifiPickerTrackerHelper.setCarrierNetworkEnabled(isChecked);
+ }
return true;
}
@@ -149,6 +155,10 @@
.createForSubscriptionId(mSubId);
}
+ public void setWifiPickerTrackerHelper(WifiPickerTrackerHelper helper) {
+ mWifiPickerTrackerHelper = helper;
+ }
+
@VisibleForTesting
boolean isDialogNeeded() {
final boolean enableData = !isChecked();
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index 2a11521..7c45949 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -43,6 +43,7 @@
import com.android.settings.network.telephony.gsm.AutoSelectPreferenceController;
import com.android.settings.network.telephony.gsm.OpenNetworkSelectPagePreferenceController;
import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.wifi.WifiPickerTrackerHelper;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.utils.ThreadUtils;
@@ -147,6 +148,9 @@
use(DisableSimFooterPreferenceController.class).init(mSubId);
use(NrDisabledInDsdsFooterPreferenceController.class).init(mSubId);
use(MobileDataPreferenceController.class).init(getFragmentManager(), mSubId);
+ use(MobileDataPreferenceController.class).setWifiPickerTrackerHelper(
+ new WifiPickerTrackerHelper(getSettingsLifecycle(), context,
+ null /* WifiPickerTrackerCallback */));
use(RoamingPreferenceController.class).init(getFragmentManager(), mSubId);
use(ApnPreferenceController.class).init(mSubId);
use(CarrierPreferenceController.class).init(mSubId);
diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java
index 6d51eb3..43d1700 100644
--- a/src/com/android/settings/notification/NotificationBackend.java
+++ b/src/com/android/settings/notification/NotificationBackend.java
@@ -45,6 +45,7 @@
import android.os.ServiceManager;
import android.os.UserHandle;
import android.service.notification.ConversationChannelWrapper;
+import android.service.notification.NotificationListenerFilter;
import android.text.format.DateUtils;
import android.util.IconDrawableFactory;
import android.util.Log;
@@ -593,6 +594,32 @@
}
}
+ public NotificationListenerFilter getListenerFilter(ComponentName cn, int userId) {
+ try {
+ return sINM.getListenerFilter(cn, userId);
+ } catch (Exception e) {
+ Log.w(TAG, "Error calling NoMan", e);
+ }
+ return new NotificationListenerFilter();
+ }
+
+ public void setListenerFilter(ComponentName cn, int userId, NotificationListenerFilter nlf) {
+ try {
+ sINM.setListenerFilter(cn, userId, nlf);
+ } catch (Exception e) {
+ Log.w(TAG, "Error calling NoMan", e);
+ }
+ }
+
+ public boolean isNotificationListenerAccessGranted(ComponentName cn) {
+ try {
+ return sINM.isNotificationListenerAccessGranted(cn);
+ } catch (Exception e) {
+ Log.w(TAG, "Error calling NoMan", e);
+ }
+ return false;
+ }
+
/**
* NotificationsSentState contains how often an app sends notifications and how recently it sent
* one.
diff --git a/src/com/android/settings/notification/zen/ZenCustomRadioButtonPreference.java b/src/com/android/settings/notification/zen/ZenCustomRadioButtonPreference.java
deleted file mode 100644
index 57f4891..0000000
--- a/src/com/android/settings/notification/zen/ZenCustomRadioButtonPreference.java
+++ /dev/null
@@ -1,144 +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.notification.zen;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.RadioButton;
-
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-import com.android.settingslib.TwoTargetPreference;
-
-/**
- * A radio button preference with a divider and a settings icon that links to another screen.
- */
-public class ZenCustomRadioButtonPreference extends TwoTargetPreference
- implements View.OnClickListener {
-
- private RadioButton mButton;
- private boolean mChecked;
-
- private OnGearClickListener mOnGearClickListener;
- private OnRadioButtonClickListener mOnRadioButtonClickListener;
-
- public ZenCustomRadioButtonPreference(Context context, AttributeSet attrs,
- int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- setLayoutResource(R.layout.preference_two_target_radio);
- }
-
- public ZenCustomRadioButtonPreference(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- setLayoutResource(R.layout.preference_two_target_radio);
- }
-
- public ZenCustomRadioButtonPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
- setLayoutResource(R.layout.preference_two_target_radio);
- }
-
- public ZenCustomRadioButtonPreference(Context context) {
- super(context);
- setLayoutResource(R.layout.preference_two_target_radio);
- }
-
- @Override
- protected int getSecondTargetResId() {
- return R.layout.preference_widget_gear;
- }
-
- public void setOnGearClickListener(OnGearClickListener l) {
- mOnGearClickListener = l;
- notifyChanged();
- }
-
- public void setOnRadioButtonClickListener(OnRadioButtonClickListener l) {
- mOnRadioButtonClickListener = l;
- notifyChanged();
- }
-
- @Override
- public void onBindViewHolder(PreferenceViewHolder holder) {
- super.onBindViewHolder(holder);
- View buttonFrame = holder.findViewById(R.id.checkbox_frame);
- if (buttonFrame != null) {
- buttonFrame.setOnClickListener(this);
- }
- mButton = (RadioButton) holder.findViewById(android.R.id.checkbox);
- if (mButton != null) {
- mButton.setChecked(mChecked);
- }
-
- final View gear = holder.findViewById(android.R.id.widget_frame);
- final View divider = holder.findViewById(R.id.two_target_divider);
- if (mOnGearClickListener != null) {
- divider.setVisibility(View.VISIBLE);
- gear.setVisibility(View.VISIBLE);
- gear.setOnClickListener(this);
- } else {
- divider.setVisibility(View.GONE);
- gear.setVisibility(View.GONE);
- gear.setOnClickListener(null);
- }
- }
-
- public boolean isChecked() {
- return mButton != null && mChecked;
- }
-
- public void setChecked(boolean checked) {
- mChecked = checked;
- if (mButton != null) {
- mButton.setChecked(checked);
- }
- }
-
- public RadioButton getRadioButton() {
- return mButton;
- }
-
- @Override
- public void onClick() {
- if (mOnRadioButtonClickListener != null) {
- mOnRadioButtonClickListener.onRadioButtonClick(this);
- }
- }
-
- @Override
- public void onClick(View v) {
- if (v.getId() == android.R.id.widget_frame) {
- if (mOnGearClickListener != null) {
- mOnGearClickListener.onGearClick(this);
- }
- } else if (v.getId() == R.id.checkbox_frame) {
- if (mOnRadioButtonClickListener != null) {
- mOnRadioButtonClickListener.onRadioButtonClick(this);
- }
- }
- }
-
- public interface OnGearClickListener {
- void onGearClick(ZenCustomRadioButtonPreference p);
- }
-
- public interface OnRadioButtonClickListener {
- void onRadioButtonClick(ZenCustomRadioButtonPreference p);
- }
-}
diff --git a/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java
index e77f4ea..5afe0b6 100644
--- a/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java
@@ -16,9 +16,6 @@
package com.android.settings.notification.zen;
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_GONE;
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_SETTING;
-
import android.app.NotificationManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
@@ -37,7 +34,6 @@
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.notification.NotificationBackend;
import com.android.settings.notification.app.ConversationListSettings;
-import com.android.settings.widget.RadioButtonPreferenceWithExtraWidget;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.widget.RadioButtonPreference;
@@ -186,13 +182,10 @@
}
private RadioButtonPreference makeRadioPreference(String key, int titleId) {
- RadioButtonPreferenceWithExtraWidget pref =
- new RadioButtonPreferenceWithExtraWidget(mPreferenceCategory.getContext());
+ final RadioButtonPreference pref =
+ new RadioButtonPreference(mPreferenceCategory.getContext());
if (KEY_ALL.equals(key) || KEY_IMPORTANT.equals(key)) {
pref.setExtraWidgetOnClickListener(mConversationSettingsWidgetClickListener);
- pref.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_SETTING);
- } else {
- pref.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_GONE);
}
pref.setKey(key);
pref.setTitle(titleId);
diff --git a/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java b/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java
index abf2ced..482865c 100644
--- a/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java
@@ -19,9 +19,6 @@
import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_GONE;
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_SETTING;
-
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
@@ -35,7 +32,6 @@
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
-import com.android.settings.widget.RadioButtonPreferenceWithExtraWidget;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.widget.RadioButtonPreference;
@@ -67,7 +63,7 @@
private final boolean mIsMessages; // if this is false, then this preference is for calls
private PreferenceCategory mPreferenceCategory;
- private List<RadioButtonPreferenceWithExtraWidget> mRadioButtonPreferences = new ArrayList<>();
+ private List<RadioButtonPreference> mRadioButtonPreferences = new ArrayList<>();
public ZenModePrioritySendersPreferenceController(Context context, String key,
Lifecycle lifecycle, boolean isMessages) {
@@ -114,7 +110,7 @@
public void updateState(Preference preference) {
final int currSetting = getPrioritySenders();
- for (RadioButtonPreferenceWithExtraWidget pref : mRadioButtonPreferences) {
+ for (RadioButtonPreference pref : mRadioButtonPreferences) {
pref.setChecked(keyToSetting(pref.getKey()) == currSetting);
}
}
@@ -126,7 +122,7 @@
}
private void updateSummaries() {
- for (RadioButtonPreferenceWithExtraWidget pref : mRadioButtonPreferences) {
+ for (RadioButtonPreference pref : mRadioButtonPreferences) {
pref.setSummary(getSummary(pref.getKey()));
}
}
@@ -169,9 +165,9 @@
}
}
- private RadioButtonPreferenceWithExtraWidget makeRadioPreference(String key, int titleId) {
- RadioButtonPreferenceWithExtraWidget pref =
- new RadioButtonPreferenceWithExtraWidget(mPreferenceCategory.getContext());
+ private RadioButtonPreference makeRadioPreference(String key, int titleId) {
+ final RadioButtonPreference pref =
+ new RadioButtonPreference(mPreferenceCategory.getContext());
pref.setKey(key);
pref.setTitle(titleId);
pref.setOnClickListener(mRadioButtonClickListener);
@@ -179,9 +175,6 @@
View.OnClickListener widgetClickListener = getWidgetClickListener(key);
if (widgetClickListener != null) {
pref.setExtraWidgetOnClickListener(widgetClickListener);
- pref.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_SETTING);
- } else {
- pref.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_GONE);
}
mPreferenceCategory.addPreference(pref);
diff --git a/src/com/android/settings/notification/zen/ZenModeVisEffectsAllPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeVisEffectsAllPreferenceController.java
index f729be8..735ce79 100644
--- a/src/com/android/settings/notification/zen/ZenModeVisEffectsAllPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModeVisEffectsAllPreferenceController.java
@@ -24,12 +24,13 @@
import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
public class ZenModeVisEffectsAllPreferenceController
extends AbstractZenModePreferenceController
- implements ZenCustomRadioButtonPreference.OnRadioButtonClickListener {
+ implements RadioButtonPreference.OnClickListener {
- private ZenCustomRadioButtonPreference mPreference;
+ private RadioButtonPreference mPreference;
protected static final int EFFECTS = Policy.SUPPRESSED_EFFECT_SCREEN_OFF
| Policy.SUPPRESSED_EFFECT_SCREEN_ON
@@ -50,7 +51,7 @@
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
- mPreference.setOnRadioButtonClickListener(this);
+ mPreference.setOnClickListener(this);
}
@Override
@@ -68,7 +69,7 @@
}
@Override
- public void onRadioButtonClick(ZenCustomRadioButtonPreference p) {
+ public void onRadioButtonClicked(RadioButtonPreference p) {
mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_ZEN_SOUND_AND_VIS_EFFECTS, true);
mBackend.saveVisualEffectsPolicy(EFFECTS, true);
diff --git a/src/com/android/settings/notification/zen/ZenModeVisEffectsCustomPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeVisEffectsCustomPreferenceController.java
index a772eb5..535dca3 100644
--- a/src/com/android/settings/notification/zen/ZenModeVisEffectsCustomPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModeVisEffectsCustomPreferenceController.java
@@ -26,11 +26,12 @@
import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
public class ZenModeVisEffectsCustomPreferenceController
extends AbstractZenModePreferenceController {
- private ZenCustomRadioButtonPreference mPreference;
+ private RadioButtonPreference mPreference;
protected static final int INTERRUPTIVE_EFFECTS =
NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT
@@ -53,12 +54,11 @@
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
- mPreference.setOnGearClickListener(p -> {
+ mPreference.setExtraWidgetOnClickListener(p -> {
launchCustomSettings();
-
});
- mPreference.setOnRadioButtonClickListener(p -> {
+ mPreference.setOnClickListener(p -> {
launchCustomSettings();
});
}
diff --git a/src/com/android/settings/notification/zen/ZenModeVisEffectsNonePreferenceController.java b/src/com/android/settings/notification/zen/ZenModeVisEffectsNonePreferenceController.java
index 84037b9..8723ea8 100644
--- a/src/com/android/settings/notification/zen/ZenModeVisEffectsNonePreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModeVisEffectsNonePreferenceController.java
@@ -24,12 +24,13 @@
import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
public class ZenModeVisEffectsNonePreferenceController
extends AbstractZenModePreferenceController
- implements ZenCustomRadioButtonPreference.OnRadioButtonClickListener {
+ implements RadioButtonPreference.OnClickListener {
- private ZenCustomRadioButtonPreference mPreference;
+ private RadioButtonPreference mPreference;
protected static final int EFFECTS = Policy.SUPPRESSED_EFFECT_SCREEN_OFF
| Policy.SUPPRESSED_EFFECT_SCREEN_ON
@@ -50,7 +51,7 @@
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
- mPreference.setOnRadioButtonClickListener(this);
+ mPreference.setOnClickListener(this);
}
@Override
@@ -67,7 +68,7 @@
}
@Override
- public void onRadioButtonClick(ZenCustomRadioButtonPreference preference) {
+ public void onRadioButtonClicked(RadioButtonPreference preference) {
mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_ZEN_SOUND_ONLY, true);
mBackend.saveVisualEffectsPolicy(EFFECTS, false);
diff --git a/src/com/android/settings/notification/zen/ZenRuleCustomPolicyPreferenceController.java b/src/com/android/settings/notification/zen/ZenRuleCustomPolicyPreferenceController.java
index 56b98ff..2cf8679 100644
--- a/src/com/android/settings/notification/zen/ZenRuleCustomPolicyPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenRuleCustomPolicyPreferenceController.java
@@ -25,11 +25,12 @@
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
public class ZenRuleCustomPolicyPreferenceController extends
AbstractZenCustomRulePreferenceController {
- private ZenCustomRadioButtonPreference mPreference;
+ private RadioButtonPreference mPreference;
public ZenRuleCustomPolicyPreferenceController(Context context, Lifecycle lifecycle,
String key) {
@@ -41,13 +42,12 @@
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
- mPreference.setOnGearClickListener(p -> {
+ mPreference.setExtraWidgetOnClickListener(p -> {
setCustomPolicy();
launchCustomSettings();
-
});
- mPreference.setOnRadioButtonClickListener(p -> {
+ mPreference.setOnClickListener(p -> {
setCustomPolicy();
launchCustomSettings();
});
diff --git a/src/com/android/settings/notification/zen/ZenRuleDefaultPolicyPreferenceController.java b/src/com/android/settings/notification/zen/ZenRuleDefaultPolicyPreferenceController.java
index 268156b..372f152 100644
--- a/src/com/android/settings/notification/zen/ZenRuleDefaultPolicyPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenRuleDefaultPolicyPreferenceController.java
@@ -26,11 +26,12 @@
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
public class ZenRuleDefaultPolicyPreferenceController extends
AbstractZenCustomRulePreferenceController implements PreferenceControllerMixin {
- private ZenCustomRadioButtonPreference mPreference;
+ private RadioButtonPreference mPreference;
public ZenRuleDefaultPolicyPreferenceController(Context context, Lifecycle lifecycle,
String key) {
@@ -42,7 +43,7 @@
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
- mPreference.setOnRadioButtonClickListener(p -> {
+ mPreference.setOnClickListener(p -> {
mRule.setZenPolicy(null);
mBackend.updateZenRule(mId, mRule);
});
diff --git a/src/com/android/settings/notification/zen/ZenRuleVisEffectsAllPreferenceController.java b/src/com/android/settings/notification/zen/ZenRuleVisEffectsAllPreferenceController.java
index fb46209..6e9152f 100644
--- a/src/com/android/settings/notification/zen/ZenRuleVisEffectsAllPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenRuleVisEffectsAllPreferenceController.java
@@ -27,11 +27,12 @@
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
public class ZenRuleVisEffectsAllPreferenceController extends
AbstractZenCustomRulePreferenceController implements PreferenceControllerMixin {
- private ZenCustomRadioButtonPreference mPreference;
+ private RadioButtonPreference mPreference;
public ZenRuleVisEffectsAllPreferenceController(Context context, Lifecycle lifecycle,
String key) {
@@ -43,7 +44,7 @@
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
- mPreference.setOnRadioButtonClickListener(p -> {
+ mPreference.setOnClickListener(p -> {
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_ZEN_SOUND_ONLY,
Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_RULE_ID, mId));
mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
diff --git a/src/com/android/settings/notification/zen/ZenRuleVisEffectsCustomPreferenceController.java b/src/com/android/settings/notification/zen/ZenRuleVisEffectsCustomPreferenceController.java
index 68ab818..d7c5f86 100644
--- a/src/com/android/settings/notification/zen/ZenRuleVisEffectsCustomPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenRuleVisEffectsCustomPreferenceController.java
@@ -27,11 +27,12 @@
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
public class ZenRuleVisEffectsCustomPreferenceController extends
AbstractZenCustomRulePreferenceController implements PreferenceControllerMixin {
- private ZenCustomRadioButtonPreference mPreference;
+ private RadioButtonPreference mPreference;
public ZenRuleVisEffectsCustomPreferenceController(Context context, Lifecycle lifecycle,
String key) {
@@ -43,12 +44,12 @@
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
- mPreference.setOnGearClickListener(p -> {
+ mPreference.setOnClickListener(p -> {
launchCustomSettings();
});
- mPreference.setOnRadioButtonClickListener(p -> {
+ mPreference.setExtraWidgetOnClickListener(p -> {
launchCustomSettings();
});
}
diff --git a/src/com/android/settings/notification/zen/ZenRuleVisEffectsNonePreferenceController.java b/src/com/android/settings/notification/zen/ZenRuleVisEffectsNonePreferenceController.java
index cb3e690..5484ed5 100644
--- a/src/com/android/settings/notification/zen/ZenRuleVisEffectsNonePreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenRuleVisEffectsNonePreferenceController.java
@@ -27,11 +27,12 @@
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
public class ZenRuleVisEffectsNonePreferenceController extends
AbstractZenCustomRulePreferenceController implements PreferenceControllerMixin {
- private ZenCustomRadioButtonPreference mPreference;
+ private RadioButtonPreference mPreference;
public ZenRuleVisEffectsNonePreferenceController(Context context, Lifecycle lifecycle,
String key) {
@@ -43,7 +44,7 @@
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
- mPreference.setOnRadioButtonClickListener(p -> {
+ mPreference.setOnClickListener(p -> {
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_ZEN_SOUND_AND_VIS_EFFECTS,
Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_RULE_ID, mId));
mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java
index b9aa68a..a15075e 100644
--- a/src/com/android/settings/overlay/FeatureFactory.java
+++ b/src/com/android/settings/overlay/FeatureFactory.java
@@ -41,6 +41,7 @@
import com.android.settings.security.SecurityFeatureProvider;
import com.android.settings.slices.SlicesFeatureProvider;
import com.android.settings.users.UserFeatureProvider;
+import com.android.settings.wifi.WifiTrackerLibProvider;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
/**
@@ -143,6 +144,11 @@
public abstract FaceFeatureProvider getFaceFeatureProvider();
+ /**
+ * Gets implementation for the WifiTrackerLib.
+ */
+ public abstract WifiTrackerLibProvider getWifiTrackerLibProvider();
+
public static final class FactoryNotFoundException extends RuntimeException {
public FactoryNotFoundException(Throwable throwable) {
super("Unable to create factory. Did you misconfigure Proguard?", throwable);
diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java
index d4d396f..ebbe87c 100644
--- a/src/com/android/settings/overlay/FeatureFactoryImpl.java
+++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java
@@ -62,6 +62,8 @@
import com.android.settings.slices.SlicesFeatureProviderImpl;
import com.android.settings.users.UserFeatureProvider;
import com.android.settings.users.UserFeatureProviderImpl;
+import com.android.settings.wifi.WifiTrackerLibProvider;
+import com.android.settings.wifi.WifiTrackerLibProviderImpl;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
/**
@@ -90,6 +92,7 @@
private BluetoothFeatureProvider mBluetoothFeatureProvider;
private AwareFeatureProvider mAwareFeatureProvider;
private FaceFeatureProvider mFaceFeatureProvider;
+ private WifiTrackerLibProvider mWifiTrackerLibProvider;
@Override
public SupportFeatureProvider getSupportFeatureProvider(Context context) {
@@ -278,4 +281,12 @@
}
return mFaceFeatureProvider;
}
+
+ @Override
+ public WifiTrackerLibProvider getWifiTrackerLibProvider() {
+ if (mWifiTrackerLibProvider == null) {
+ mWifiTrackerLibProvider = new WifiTrackerLibProviderImpl();
+ }
+ return mWifiTrackerLibProvider;
+ }
}
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index 0c6205f..7c487ba 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -343,7 +343,7 @@
final Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS)
.setPackage(Utils.SETTINGS_PACKAGE_NAME);
final PendingIntent noOpIntent = PendingIntent.getActivity(getContext(),
- 0 /* requestCode */, settingsIntent, 0 /* flags */);
+ 0 /* requestCode */, settingsIntent, PendingIntent.FLAG_IMMUTABLE);
return noOpIntent;
}
diff --git a/src/com/android/settings/users/UserDetailsSettings.java b/src/com/android/settings/users/UserDetailsSettings.java
index 53d9849..5005399 100644
--- a/src/com/android/settings/users/UserDetailsSettings.java
+++ b/src/com/android/settings/users/UserDetailsSettings.java
@@ -243,7 +243,7 @@
mDefaultGuestRestrictions = mUserManager.getDefaultGuestRestrictions();
mPhonePref.setChecked(
!mDefaultGuestRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS));
- mRemoveUserPref.setTitle(R.string.user_exit_guest_title);
+ mRemoveUserPref.setTitle(R.string.user_exit_guest_menu);
} else {
mPhonePref.setChecked(!mUserManager.hasUserRestriction(
UserManager.DISALLOW_OUTGOING_CALLS, new UserHandle(userId)));
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 63ccb6b..8ba5432 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -31,6 +31,7 @@
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
@@ -164,6 +165,7 @@
private final Object mUserLock = new Object();
private UserManager mUserManager;
private static SparseArray<Bitmap> sDarkDefaultUserBitmapCache = new SparseArray<>();
+ private static Bitmap sRemoveGuestBitmap = null;
private MultiUserSwitchBarController mSwitchBarController;
private EditUserInfoController mEditUserInfoController =
@@ -177,6 +179,7 @@
// A place to cache the generated default avatar
private Drawable mDefaultIconDrawable;
+ private Drawable mRemoveGuestIconDrawable;
// TODO: Replace current Handler solution to something that doesn't leak memory and works
// TODO: during a configuration change
@@ -383,8 +386,8 @@
private void loadProfile() {
if (isCurrentUserGuest()) {
// No need to load profile information
- mMePreference.setIcon(getEncircledDefaultIcon());
- mMePreference.setTitle(R.string.user_exit_guest_title);
+ mMePreference.setIcon(getEncircledRemoveGuestIcon());
+ mMePreference.setTitle(R.string.user_clear_guest_menu);
mMePreference.setSelectable(true);
// removing a guest will result in switching back to the admin user
mMePreference.setEnabled(canSwitchUserNow());
@@ -899,7 +902,7 @@
} else {
setPhotoId(pref, user);
}
- } else {
+ } else if (!user.isGuest()) {
// Icon not available yet, print a placeholder
pref.setIcon(getEncircledDefaultIcon());
}
@@ -1044,6 +1047,14 @@
return mDefaultIconDrawable;
}
+ private Drawable getEncircledRemoveGuestIcon() {
+ if (mRemoveGuestIconDrawable == null) {
+ mRemoveGuestIconDrawable = encircle(
+ getRemoveGuestIconAsBitmap(getContext().getResources()));
+ }
+ return mRemoveGuestIconDrawable;
+ }
+
private void setPhotoId(Preference pref, UserInfo user) {
Bitmap bitmap = mUserIcons.get(user.id);
if (bitmap != null) {
@@ -1123,6 +1134,23 @@
}
/**
+ * Returns a remove guest icon (as a {@link Bitmap})
+ *
+ * @param resources resources object to fetch the remove guest icon.
+ */
+ private static Bitmap getRemoveGuestIconAsBitmap(Resources resources) {
+ if (sRemoveGuestBitmap == null) {
+ Drawable icon = resources.getDrawable(R.drawable.ic_delete, null).mutate();
+ icon.setColorFilter(
+ resources.getColor(com.android.internal.R.color.user_icon_default_gray, null),
+ PorterDuff.Mode.SRC_IN);
+ icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
+ sRemoveGuestBitmap = UserIcons.convertToBitmap(icon);
+ }
+ return sRemoveGuestBitmap;
+ }
+
+ /**
* Assign the default photo to user with {@paramref userId}
*
* @param context used to get the {@link UserManager}
diff --git a/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidget.java b/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidget.java
deleted file mode 100644
index 2b28ec1..0000000
--- a/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidget.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.settings.widget;
-
-import android.content.Context;
-import android.view.View;
-import android.widget.ImageView;
-
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-import com.android.settingslib.widget.RadioButtonPreference;
-
-public class RadioButtonPreferenceWithExtraWidget extends RadioButtonPreference {
- public static final int EXTRA_WIDGET_VISIBILITY_GONE = 0;
- public static final int EXTRA_WIDGET_VISIBILITY_INFO = 1;
- public static final int EXTRA_WIDGET_VISIBILITY_SETTING = 2;
-
- private View mExtraWidgetDivider;
- private ImageView mExtraWidget;
-
- private int mExtraWidgetVisibility = EXTRA_WIDGET_VISIBILITY_GONE;
- private View.OnClickListener mExtraWidgetOnClickListener;
-
- public RadioButtonPreferenceWithExtraWidget(Context context) {
- super(context, null);
- setLayoutResource(R.layout.preference_radio_with_extra_widget);
- }
-
- @Override
- public void onBindViewHolder(PreferenceViewHolder view) {
- super.onBindViewHolder(view);
-
- mExtraWidget = (ImageView) view.findViewById(R.id.radio_extra_widget);
- mExtraWidgetDivider = view.findViewById(R.id.radio_extra_widget_divider);
- setExtraWidgetVisibility(mExtraWidgetVisibility);
-
- if (mExtraWidgetOnClickListener != null) {
- setExtraWidgetOnClickListener(mExtraWidgetOnClickListener);
- }
- }
-
- public void setExtraWidgetVisibility(int visibility) {
- mExtraWidgetVisibility = visibility;
- if (mExtraWidget == null || mExtraWidgetDivider == null) {
- return;
- }
-
- if (visibility == EXTRA_WIDGET_VISIBILITY_GONE) {
- mExtraWidget.setClickable(false);
- mExtraWidget.setVisibility(View.GONE);
- mExtraWidgetDivider.setVisibility(View.GONE);
- } else {
- mExtraWidget.setClickable(true);
- mExtraWidget.setVisibility(View.VISIBLE);
- mExtraWidgetDivider.setVisibility(View.VISIBLE);
- if (mExtraWidgetVisibility == EXTRA_WIDGET_VISIBILITY_INFO) {
- mExtraWidget.setImageResource(R.drawable.ic_settings_about);
- mExtraWidget.setContentDescription(
- getContext().getResources().getText(R.string.information_label));
- } else if (mExtraWidgetVisibility == EXTRA_WIDGET_VISIBILITY_SETTING) {
- mExtraWidget.setImageResource(R.drawable.ic_settings_accent);
- mExtraWidget.setContentDescription(
- getContext().getResources().getText(R.string.settings_label));
- }
- }
- }
-
- public void setExtraWidgetOnClickListener(View.OnClickListener listener) {
- mExtraWidgetOnClickListener = listener;
- if (mExtraWidget != null) {
- mExtraWidget.setEnabled(true);
- mExtraWidget.setOnClickListener(listener);
- }
- }
-}
\ No newline at end of file
diff --git a/src/com/android/settings/wifi/ConfigureWifiEntryFragment.java b/src/com/android/settings/wifi/ConfigureWifiEntryFragment.java
index 881aaea..c36a298 100644
--- a/src/com/android/settings/wifi/ConfigureWifiEntryFragment.java
+++ b/src/com/android/settings/wifi/ConfigureWifiEntryFragment.java
@@ -21,9 +21,6 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
-import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
@@ -40,6 +37,7 @@
import com.android.settings.R;
import com.android.settings.core.InstrumentedFragment;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settings.wifi.details2.WifiNetworkDetailsFragment2;
import com.android.wifitrackerlib.NetworkDetailsTracker;
import com.android.wifitrackerlib.WifiEntry;
@@ -222,17 +220,17 @@
}
};
- mNetworkDetailsTracker = NetworkDetailsTracker.createNetworkDetailsTracker(
- getSettingsLifecycle(),
- context,
- context.getSystemService(WifiManager.class),
- context.getSystemService(ConnectivityManager.class),
- context.getSystemService(NetworkScoreManager.class),
- new Handler(Looper.getMainLooper()),
- mWorkerThread.getThreadHandler(),
- elapsedRealtimeClock,
- MAX_SCAN_AGE_MILLIS,
- SCAN_INTERVAL_MILLIS,
- getArguments().getString(WifiNetworkDetailsFragment2.KEY_CHOSEN_WIFIENTRY_KEY));
+ mNetworkDetailsTracker = FeatureFactory.getFactory(context)
+ .getWifiTrackerLibProvider()
+ .createNetworkDetailsTracker(
+ getSettingsLifecycle(),
+ context,
+ new Handler(Looper.getMainLooper()),
+ mWorkerThread.getThreadHandler(),
+ elapsedRealtimeClock,
+ MAX_SCAN_AGE_MILLIS,
+ SCAN_INTERVAL_MILLIS,
+ getArguments().getString(
+ WifiNetworkDetailsFragment2.KEY_CHOSEN_WIFIENTRY_KEY));
}
}
diff --git a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
index 887f09f..11f3612 100644
--- a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
+++ b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
@@ -24,11 +24,8 @@
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
-import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.NetworkRequestMatchCallback;
import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback;
import android.os.Bundle;
@@ -54,6 +51,7 @@
import androidx.preference.internal.PreferenceImageView;
import com.android.settings.R;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.Utils;
import com.android.wifitrackerlib.WifiEntry;
import com.android.wifitrackerlib.WifiPickerTracker;
@@ -113,16 +111,15 @@
}
};
final Context context = getContext();
- mWifiPickerTracker = new WifiPickerTracker(getSettingsLifecycle(), context,
- context.getSystemService(WifiManager.class),
- context.getSystemService(ConnectivityManager.class),
- context.getSystemService(NetworkScoreManager.class),
- new Handler(Looper.getMainLooper()),
- mWorkerThread.getThreadHandler(),
- elapsedRealtimeClock,
- MAX_SCAN_AGE_MILLIS,
- SCAN_INTERVAL_MILLIS,
- this);
+ mWifiPickerTracker = FeatureFactory.getFactory(context)
+ .getWifiTrackerLibProvider()
+ .createWifiPickerTracker(getSettingsLifecycle(), context,
+ new Handler(Looper.getMainLooper()),
+ mWorkerThread.getThreadHandler(),
+ elapsedRealtimeClock,
+ MAX_SCAN_AGE_MILLIS,
+ SCAN_INTERVAL_MILLIS,
+ this);
}
@Override
diff --git a/src/com/android/settings/wifi/WifiConnectionPreferenceController.java b/src/com/android/settings/wifi/WifiConnectionPreferenceController.java
index 13d5082..3b2669c 100644
--- a/src/com/android/settings/wifi/WifiConnectionPreferenceController.java
+++ b/src/com/android/settings/wifi/WifiConnectionPreferenceController.java
@@ -17,9 +17,6 @@
package com.android.settings.wifi;
import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
-import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
@@ -36,6 +33,7 @@
import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settings.wifi.details2.WifiNetworkDetailsFragment2;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -115,16 +113,15 @@
return SystemClock.elapsedRealtime();
}
};
- mWifiPickerTracker = new WifiPickerTracker(lifecycle, context,
- context.getSystemService(WifiManager.class),
- context.getSystemService(ConnectivityManager.class),
- context.getSystemService(NetworkScoreManager.class),
- new Handler(Looper.getMainLooper()),
- mWorkerThread.getThreadHandler(),
- elapsedRealtimeClock,
- MAX_SCAN_AGE_MILLIS,
- SCAN_INTERVAL_MILLIS,
- this);
+ mWifiPickerTracker = FeatureFactory.getFactory(context)
+ .getWifiTrackerLibProvider()
+ .createWifiPickerTracker(lifecycle, context,
+ new Handler(Looper.getMainLooper()),
+ mWorkerThread.getThreadHandler(),
+ elapsedRealtimeClock,
+ MAX_SCAN_AGE_MILLIS,
+ SCAN_INTERVAL_MILLIS,
+ this);
}
/**
diff --git a/src/com/android/settings/wifi/WifiDialogActivity.java b/src/com/android/settings/wifi/WifiDialogActivity.java
index 000ed3e..1c5a8ed 100644
--- a/src/com/android/settings/wifi/WifiDialogActivity.java
+++ b/src/com/android/settings/wifi/WifiDialogActivity.java
@@ -18,9 +18,7 @@
import android.content.DialogInterface;
import android.content.Intent;
-import android.net.ConnectivityManager;
import android.net.NetworkInfo;
-import android.net.NetworkScoreManager;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.ActionListener;
@@ -38,6 +36,7 @@
import com.android.settings.R;
import com.android.settings.SetupWizardUtils;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settings.wifi.dpp.WifiDppUtils;
import com.android.settingslib.core.lifecycle.ObservableActivity;
import com.android.settingslib.wifi.AccessPoint;
@@ -124,18 +123,17 @@
return SystemClock.elapsedRealtime();
}
};
- mNetworkDetailsTracker = NetworkDetailsTracker.createNetworkDetailsTracker(
- getLifecycle(),
- this,
- getSystemService(WifiManager.class),
- getSystemService(ConnectivityManager.class),
- getSystemService(NetworkScoreManager.class),
- new Handler(Looper.getMainLooper()),
- mWorkerThread.getThreadHandler(),
- elapsedRealtimeClock,
- MAX_SCAN_AGE_MILLIS,
- SCAN_INTERVAL_MILLIS,
- mIntent.getStringExtra(KEY_CHOSEN_WIFIENTRY_KEY));
+ mNetworkDetailsTracker = FeatureFactory.getFactory(this)
+ .getWifiTrackerLibProvider()
+ .createNetworkDetailsTracker(
+ getLifecycle(),
+ this,
+ new Handler(Looper.getMainLooper()),
+ mWorkerThread.getThreadHandler(),
+ elapsedRealtimeClock,
+ MAX_SCAN_AGE_MILLIS,
+ SCAN_INTERVAL_MILLIS,
+ mIntent.getStringExtra(KEY_CHOSEN_WIFIENTRY_KEY));
} else {
final Bundle accessPointState = mIntent.getBundleExtra(KEY_ACCESS_POINT_STATE);
if (accessPointState != null) {
diff --git a/src/com/android/settings/wifi/WifiPickerTrackerHelper.java b/src/com/android/settings/wifi/WifiPickerTrackerHelper.java
new file mode 100644
index 0000000..c20f355
--- /dev/null
+++ b/src/com/android/settings/wifi/WifiPickerTrackerHelper.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2021 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.wifi;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Process;
+import android.os.SimpleClock;
+import android.os.SystemClock;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.wifitrackerlib.MergedCarrierEntry;
+import com.android.wifitrackerlib.WifiEntry;
+import com.android.wifitrackerlib.WifiPickerTracker;
+
+import java.time.Clock;
+import java.time.ZoneOffset;
+
+public class WifiPickerTrackerHelper implements LifecycleObserver {
+
+ private static final String TAG = "WifiPickerTrackerHelper";
+
+ // Max age of tracked WifiEntries
+ private static final long MAX_SCAN_AGE_MILLIS = 15_000;
+ // Interval between initiating WifiPickerTracker scans
+ private static final long SCAN_INTERVAL_MILLIS = 10_000;
+ // Clock used for evaluating the age of scans
+ private static final Clock ELAPSED_REALTIME_CLOCK = new SimpleClock(ZoneOffset.UTC) {
+ @Override
+ public long millis() {
+ return SystemClock.elapsedRealtime();
+ }
+ };
+
+ private WifiPickerTracker mWifiPickerTracker;
+ // Worker thread used for WifiPickerTracker work
+ private HandlerThread mWorkerThread;
+
+ public WifiPickerTrackerHelper(@NonNull Lifecycle lifecycle, @NonNull Context context,
+ @Nullable WifiPickerTracker.WifiPickerTrackerCallback listener) {
+ if (lifecycle == null) {
+ throw new IllegalArgumentException("lifecycle must be non-null.");
+ }
+ lifecycle.addObserver(this);
+ mWorkerThread = new HandlerThread(TAG
+ + "{" + Integer.toHexString(System.identityHashCode(this)) + "}",
+ Process.THREAD_PRIORITY_BACKGROUND);
+ mWorkerThread.start();
+
+ mWifiPickerTracker = FeatureFactory.getFactory(context)
+ .getWifiTrackerLibProvider()
+ .createWifiPickerTracker(lifecycle, context,
+ new Handler(Looper.getMainLooper()),
+ mWorkerThread.getThreadHandler(),
+ ELAPSED_REALTIME_CLOCK,
+ MAX_SCAN_AGE_MILLIS,
+ SCAN_INTERVAL_MILLIS,
+ listener);
+
+ }
+
+ @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
+ public void onDestroy() {
+ mWorkerThread.quit();
+ }
+
+ public @NonNull WifiPickerTracker getWifiPickerTracker() {
+ return mWifiPickerTracker;
+ }
+
+ public boolean setCarrierNetworkEnabled(boolean enable) {
+ final MergedCarrierEntry mergedCarrierEntry = mWifiPickerTracker.getMergedCarrierEntry();
+ if (mergedCarrierEntry == null) {
+ return false;
+ }
+ mergedCarrierEntry.setEnabled(enable);
+ return true;
+ }
+
+ public boolean connectCarrierNetwork(@Nullable WifiEntry.ConnectCallback callback) {
+ final MergedCarrierEntry mergedCarrierEntry = mWifiPickerTracker.getMergedCarrierEntry();
+ if (mergedCarrierEntry == null || !mergedCarrierEntry.canConnect()) {
+ return false;
+ }
+ mergedCarrierEntry.connect(callback);
+ return true;
+ }
+
+ @VisibleForTesting
+ void setWifiPickerTracker(@NonNull WifiPickerTracker wifiPickerTracker) {
+ mWifiPickerTracker = wifiPickerTracker;
+ }
+
+ @VisibleForTesting
+ void setWorkerThread(@NonNull HandlerThread workerThread) {
+ mWorkerThread = workerThread;
+ }
+}
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 2804393..cf8242b 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -27,8 +27,6 @@
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
import android.net.NetworkTemplate;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
@@ -66,6 +64,7 @@
import com.android.settings.datausage.DataUsagePreference;
import com.android.settings.datausage.DataUsageUtils;
import com.android.settings.location.ScanningSettings;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.SwitchBarController;
import com.android.settings.wifi.details2.WifiNetworkDetailsFragment2;
@@ -283,16 +282,15 @@
return SystemClock.elapsedRealtime();
}
};
- mWifiPickerTracker = new WifiPickerTracker(getSettingsLifecycle(), context,
- context.getSystemService(WifiManager.class),
- context.getSystemService(ConnectivityManager.class),
- context.getSystemService(NetworkScoreManager.class),
- new Handler(Looper.getMainLooper()),
- mWorkerThread.getThreadHandler(),
- elapsedRealtimeClock,
- MAX_SCAN_AGE_MILLIS,
- SCAN_INTERVAL_MILLIS,
- this);
+ mWifiPickerTracker = FeatureFactory.getFactory(context)
+ .getWifiTrackerLibProvider()
+ .createWifiPickerTracker(getSettingsLifecycle(), context,
+ new Handler(Looper.getMainLooper()),
+ mWorkerThread.getThreadHandler(),
+ elapsedRealtimeClock,
+ MAX_SCAN_AGE_MILLIS,
+ SCAN_INTERVAL_MILLIS,
+ this);
final Activity activity = getActivity();
diff --git a/src/com/android/settings/wifi/WifiTrackerLibProvider.java b/src/com/android/settings/wifi/WifiTrackerLibProvider.java
new file mode 100644
index 0000000..10b3373
--- /dev/null
+++ b/src/com/android/settings/wifi/WifiTrackerLibProvider.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.wifi;
+
+import android.content.Context;
+import android.os.Handler;
+
+import androidx.lifecycle.Lifecycle;
+
+import com.android.wifitrackerlib.NetworkDetailsTracker;
+import com.android.wifitrackerlib.WifiPickerTracker;
+
+import java.time.Clock;
+
+/**
+ * Provides the objects instances from the AOSP WifiTrackerLib.
+ */
+public interface WifiTrackerLibProvider {
+
+ /** Create a new instance of WifiPickerTracker */
+ WifiPickerTracker createWifiPickerTracker(
+ Lifecycle lifecycle, Context context,
+ Handler mainHandler, Handler workerHandler, Clock clock,
+ long maxScanAgeMillis, long scanIntervalMillis,
+ WifiPickerTracker.WifiPickerTrackerCallback listener);
+
+ /** Create a new instance of NetworkDetailsTracker */
+ NetworkDetailsTracker createNetworkDetailsTracker(
+ Lifecycle lifecycle, Context context,
+ Handler mainHandler, Handler workerHandler, Clock clock,
+ long maxScanAgeMillis, long scanIntervalMillis,
+ String key);
+
+}
diff --git a/src/com/android/settings/wifi/WifiTrackerLibProviderImpl.java b/src/com/android/settings/wifi/WifiTrackerLibProviderImpl.java
new file mode 100644
index 0000000..f835409
--- /dev/null
+++ b/src/com/android/settings/wifi/WifiTrackerLibProviderImpl.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.wifi;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkScoreManager;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+
+import androidx.lifecycle.Lifecycle;
+
+import com.android.wifitrackerlib.NetworkDetailsTracker;
+import com.android.wifitrackerlib.WifiPickerTracker;
+
+import java.time.Clock;
+
+/**
+ * Implementation of AOSP WifiTrackerLibProvider.
+ */
+public class WifiTrackerLibProviderImpl implements WifiTrackerLibProvider {
+
+ /**
+ * Create an instance of WifiPickerTracker.
+ */
+ @Override
+ public WifiPickerTracker createWifiPickerTracker(
+ Lifecycle lifecycle, Context context,
+ Handler mainHandler, Handler workerHandler, Clock clock,
+ long maxScanAgeMillis, long scanIntervalMillis,
+ WifiPickerTracker.WifiPickerTrackerCallback listener) {
+ return new WifiPickerTracker(
+ lifecycle, context,
+ context.getSystemService(WifiManager.class),
+ context.getSystemService(ConnectivityManager.class),
+ context.getSystemService(NetworkScoreManager.class),
+ mainHandler, workerHandler, clock,
+ maxScanAgeMillis, scanIntervalMillis,
+ listener);
+ }
+
+ /**
+ * Create an instance of NetworkDetailsTracker.
+ */
+ @Override
+ public NetworkDetailsTracker createNetworkDetailsTracker(
+ Lifecycle lifecycle, Context context,
+ Handler mainHandler, Handler workerHandler, Clock clock,
+ long maxScanAgeMillis, long scanIntervalMillis,
+ String key) {
+ return NetworkDetailsTracker.createNetworkDetailsTracker(
+ lifecycle, context,
+ context.getSystemService(WifiManager.class),
+ context.getSystemService(ConnectivityManager.class),
+ context.getSystemService(NetworkScoreManager.class),
+ mainHandler, workerHandler, clock,
+ maxScanAgeMillis, scanIntervalMillis,
+ key);
+ }
+}
diff --git a/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragment.java b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragment.java
index 3921488..46f4414 100644
--- a/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragment.java
+++ b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragment.java
@@ -24,8 +24,6 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
-import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiManager;
@@ -60,6 +58,7 @@
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.InstrumentedFragment;
+import com.android.settings.overlay.FeatureFactory;
import com.android.wifitrackerlib.WifiEntry;
import com.android.wifitrackerlib.WifiPickerTracker;
@@ -191,16 +190,15 @@
return SystemClock.elapsedRealtime();
}
};
- mWifiPickerTracker = new WifiPickerTracker(getSettingsLifecycle(), mActivity,
- mActivity.getSystemService(WifiManager.class),
- mActivity.getSystemService(ConnectivityManager.class),
- mActivity.getSystemService(NetworkScoreManager.class),
- new Handler(Looper.getMainLooper()),
- mWorkerThread.getThreadHandler(),
- elapsedRealtimeClock,
- MAX_SCAN_AGE_MILLIS,
- SCAN_INTERVAL_MILLIS,
- this);
+ mWifiPickerTracker = FeatureFactory.getFactory(mActivity.getApplicationContext())
+ .getWifiTrackerLibProvider()
+ .createWifiPickerTracker(getSettingsLifecycle(), mActivity,
+ new Handler(Looper.getMainLooper()),
+ mWorkerThread.getThreadHandler(),
+ elapsedRealtimeClock,
+ MAX_SCAN_AGE_MILLIS,
+ SCAN_INTERVAL_MILLIS,
+ this);
return inflater.inflate(R.layout.wifi_add_app_networks, container, false);
}
diff --git a/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java b/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java
index d0708ea..b154a9b 100644
--- a/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java
+++ b/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java
@@ -22,7 +22,6 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.HandlerThread;
@@ -42,6 +41,7 @@
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settings.wifi.WifiConfigUiBase2;
import com.android.settings.wifi.WifiDialog2;
import com.android.settingslib.RestrictedLockUtils;
@@ -239,18 +239,17 @@
}
};
- mNetworkDetailsTracker = NetworkDetailsTracker.createNetworkDetailsTracker(
- getSettingsLifecycle(),
- context,
- context.getSystemService(WifiManager.class),
- context.getSystemService(ConnectivityManager.class),
- context.getSystemService(NetworkScoreManager.class),
- new Handler(Looper.getMainLooper()),
- mWorkerThread.getThreadHandler(),
- elapsedRealtimeClock,
- MAX_SCAN_AGE_MILLIS,
- SCAN_INTERVAL_MILLIS,
- getArguments().getString(KEY_CHOSEN_WIFIENTRY_KEY));
+ mNetworkDetailsTracker = FeatureFactory.getFactory(context)
+ .getWifiTrackerLibProvider()
+ .createNetworkDetailsTracker(
+ getSettingsLifecycle(),
+ context,
+ new Handler(Looper.getMainLooper()),
+ mWorkerThread.getThreadHandler(),
+ elapsedRealtimeClock,
+ MAX_SCAN_AGE_MILLIS,
+ SCAN_INTERVAL_MILLIS,
+ getArguments().getString(KEY_CHOSEN_WIFIENTRY_KEY));
}
/**
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
index cee3ccd..5c80024 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
@@ -25,8 +25,6 @@
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
-import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
import android.net.wifi.EasyConnectStatusCallback;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
@@ -57,6 +55,7 @@
import androidx.lifecycle.ViewModelProviders;
import com.android.settings.R;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settings.wifi.qrcode.QrCamera;
import com.android.settings.wifi.qrcode.QrDecorateView;
import com.android.wifitrackerlib.WifiEntry;
@@ -363,16 +362,15 @@
}
};
final Context context = getContext();
- mWifiPickerTracker = new WifiPickerTracker(getSettingsLifecycle(), context,
- context.getSystemService(WifiManager.class),
- context.getSystemService(ConnectivityManager.class),
- context.getSystemService(NetworkScoreManager.class),
- new Handler(Looper.getMainLooper()),
- mWorkerThread.getThreadHandler(),
- elapsedRealtimeClock,
- MAX_SCAN_AGE_MILLIS,
- SCAN_INTERVAL_MILLIS,
- null /* listener */);
+ mWifiPickerTracker = FeatureFactory.getFactory(context)
+ .getWifiTrackerLibProvider()
+ .createWifiPickerTracker(getSettingsLifecycle(), context,
+ new Handler(Looper.getMainLooper()),
+ mWorkerThread.getThreadHandler(),
+ elapsedRealtimeClock,
+ MAX_SCAN_AGE_MILLIS,
+ SCAN_INTERVAL_MILLIS,
+ null /* listener */);
// setTitle for TalkBack
if (mIsConfiguratorMode) {
diff --git a/src/com/android/settings/wifi/slice/WifiScanWorker.java b/src/com/android/settings/wifi/slice/WifiScanWorker.java
index a87b36a..78b0d33 100644
--- a/src/com/android/settings/wifi/slice/WifiScanWorker.java
+++ b/src/com/android/settings/wifi/slice/WifiScanWorker.java
@@ -19,8 +19,6 @@
import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT;
import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.NetworkScoreManager;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.HandlerThread;
@@ -34,6 +32,7 @@
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settingslib.utils.ThreadUtils;
import com.android.wifitrackerlib.MergedCarrierEntry;
@@ -79,16 +78,15 @@
return SystemClock.elapsedRealtime();
}
};
- mWifiPickerTracker = new WifiPickerTracker(getLifecycle(), context,
- context.getSystemService(WifiManager.class),
- context.getSystemService(ConnectivityManager.class),
- context.getSystemService(NetworkScoreManager.class),
- ThreadUtils.getUiThreadHandler(),
- mWorkerThread.getThreadHandler(),
- elapsedRealtimeClock,
- MAX_SCAN_AGE_MILLIS,
- SCAN_INTERVAL_MILLIS,
- this);
+ mWifiPickerTracker = FeatureFactory.getFactory(context)
+ .getWifiTrackerLibProvider()
+ .createWifiPickerTracker(getLifecycle(), context,
+ ThreadUtils.getUiThreadHandler(),
+ mWorkerThread.getThreadHandler(),
+ elapsedRealtimeClock,
+ MAX_SCAN_AGE_MILLIS,
+ SCAN_INTERVAL_MILLIS,
+ this);
mLifecycleRegistry.markState(Lifecycle.State.INITIALIZED);
mLifecycleRegistry.markState(Lifecycle.State.CREATED);
diff --git a/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java
new file mode 100644
index 0000000..0eaf008
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.os.Vibrator;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+/** Tests for {@link RingVibrationIntensityPreferenceController}. */
+@RunWith(RobolectricTestRunner.class)
+public class RingVibrationIntensityPreferenceControllerTest {
+ @Mock
+ private Vibrator mVibrator;
+
+ private RingVibrationIntensityPreferenceController mController;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ final Context mContext = spy(ApplicationProvider.getApplicationContext());
+ doReturn(mVibrator).when(mContext).getSystemService(Vibrator.class);
+ mController = new RingVibrationIntensityPreferenceController(mContext);
+ }
+
+ @Test
+ public void getAvailabilityStatus_available() {
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+ }
+
+ @Test
+ public void getDefaultIntensity_success() {
+ doReturn(/* toBeReturned= */ 5).when(mVibrator).getDefaultRingVibrationIntensity();
+
+ assertThat(mController.getDefaultIntensity()).isEqualTo(/* expected= */ 5);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/TextAndDisplayFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/TextAndDisplayFragmentTest.java
new file mode 100644
index 0000000..96756ecd
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/TextAndDisplayFragmentTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+import com.android.settings.testutils.XmlTestUtils;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class TextAndDisplayFragmentTest {
+
+ private Context mContext = ApplicationProvider.getApplicationContext();
+
+ @Test
+ public void getNonIndexableKeys_existInXmlLayout() {
+ final List<String> niks = TextAndDisplayFragment.SEARCH_INDEX_DATA_PROVIDER
+ .getNonIndexableKeys(mContext);
+ final List<String> keys =
+ XmlTestUtils.getKeysFromPreferenceXml(mContext,
+ R.xml.accessibility_text_and_display);
+
+ assertThat(keys).containsAtLeastElementsIn(niks);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetailsTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetailsTest.java
deleted file mode 100644
index 26a78d0..0000000
--- a/tests/robotests/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetailsTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.applications.specialaccess.notificationaccess;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.testutils.FakeFeatureFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class NotificationAccessDetailsTest {
-
- private Context mContext;
- private FakeFeatureFactory mFeatureFactory;
- private NotificationAccessDetails mFragment;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mFeatureFactory = FakeFeatureFactory.setupForTest();
- mFragment = spy(new NotificationAccessDetails());
- mContext = RuntimeEnvironment.application;
- doReturn(mContext).when(mFragment).getContext();
-
- }
-
- @Test
- public void logSpecialPermissionChange() {
- mFragment.logSpecialPermissionChange(true, "app");
- verify(mFeatureFactory.metricsFeatureProvider).action(
- mContext,
- MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_NOTIVIEW_ALLOW,
- "app");
-
- mFragment.logSpecialPermissionChange(false, "app");
- verify(mFeatureFactory.metricsFeatureProvider).action(
- mContext,
- MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_NOTIVIEW_DENY,
- "app");
- }
-}
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenCustomRadioButtonPreferenceTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenCustomRadioButtonPreferenceTest.java
deleted file mode 100644
index f6e51cd..0000000
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenCustomRadioButtonPreferenceTest.java
+++ /dev/null
@@ -1,110 +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.notification.zen;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.RadioButton;
-
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-import com.android.settings.notification.zen.ZenCustomRadioButtonPreference;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class ZenCustomRadioButtonPreferenceTest {
-
- private Context mContext;
-
- @Before
- public void setUp() {
- mContext = RuntimeEnvironment.application;
- }
-
- @Test
- public void createNewPreference_shouldSetLayout() {
- final ZenCustomRadioButtonPreference preference
- = new ZenCustomRadioButtonPreference(mContext);
-
- assertThat(preference.getLayoutResource()).isEqualTo(R.layout.preference_two_target_radio);
- assertThat(preference.getWidgetLayoutResource())
- .isEqualTo(R.layout.preference_widget_gear);
- }
-
- @Test
- public void setChecked_shouldUpdateButtonCheckedState() {
- final ZenCustomRadioButtonPreference preference =
- new ZenCustomRadioButtonPreference(mContext);
- final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
- LayoutInflater.from(mContext).inflate(
- R.layout.preference_two_target_radio, null));
- final RadioButton toggle = (RadioButton) holder.findViewById(android.R.id.checkbox);
- preference.onBindViewHolder(holder);
-
- preference.setChecked(true);
- assertThat(toggle.isChecked()).isTrue();
-
- preference.setChecked(false);
- assertThat(toggle.isChecked()).isFalse();
- }
-
- @Test
- public void clickRadioButton_shouldNotifyRadioButtonClicked() {
- final ZenCustomRadioButtonPreference preference
- = new ZenCustomRadioButtonPreference(mContext);
- final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
- LayoutInflater.from(mContext).inflate(R.layout.preference_two_target_radio, null));
- final View toggle = holder.findViewById(R.id.checkbox_frame);
-
- ZenCustomRadioButtonPreference.OnRadioButtonClickListener l = mock(
- ZenCustomRadioButtonPreference.OnRadioButtonClickListener.class);
- preference.setOnRadioButtonClickListener(l);
- preference.onBindViewHolder(holder);
-
- toggle.performClick();
- verify(l).onRadioButtonClick(preference);
- }
-
- @Test
- public void clickWidgetView_shouldNotifyWidgetClicked() {
- final ZenCustomRadioButtonPreference preference =
- new ZenCustomRadioButtonPreference(mContext);
- final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
- LayoutInflater.from(mContext).inflate(R.layout.preference_two_target_radio, null));
- final View widgetView = holder.findViewById(android.R.id.widget_frame);
-
- ZenCustomRadioButtonPreference.OnGearClickListener l = mock(
- ZenCustomRadioButtonPreference.OnGearClickListener.class);
- preference.setOnGearClickListener(l);
- preference.onBindViewHolder(holder);
-
- widgetView.performClick();
- verify(l).onGearClick(preference);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsAllPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsAllPreferenceControllerTest.java
index 05537f3..45a40d3 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsAllPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsAllPreferenceControllerTest.java
@@ -40,11 +40,9 @@
import androidx.preference.PreferenceScreen;
-import com.android.settings.notification.zen.ZenCustomRadioButtonPreference;
-import com.android.settings.notification.zen.ZenModeBackend;
-import com.android.settings.notification.zen.ZenModeVisEffectsAllPreferenceController;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
import org.junit.Before;
import org.junit.Test;
@@ -63,7 +61,7 @@
@Mock
private ZenModeBackend mBackend;
@Mock
- private ZenCustomRadioButtonPreference mockPref;
+ private RadioButtonPreference mPref;
private Context mContext;
private FakeFeatureFactory mFeatureFactory;
@Mock
@@ -86,7 +84,7 @@
mContext, mock(Lifecycle.class), PREF_KEY);
ReflectionHelpers.setField(mController, "mBackend", mBackend);
- when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPref);
mController.displayPreference(mScreen);
}
@@ -98,9 +96,9 @@
@Test
public void updateState_notChecked() {
mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 1);
- mController.updateState(mockPref);
+ mController.updateState(mPref);
- verify(mockPref).setChecked(false);
+ verify(mPref).setChecked(false);
}
@Test
@@ -115,9 +113,9 @@
| SUPPRESSED_EFFECT_PEEK
| SUPPRESSED_EFFECT_NOTIFICATION_LIST;
mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, allSuppressed);
- mController.updateState(mockPref);
+ mController.updateState(mPref);
- verify(mockPref).setChecked(true);
+ verify(mPref).setChecked(true);
}
@Test
@@ -132,7 +130,7 @@
| SUPPRESSED_EFFECT_PEEK
| SUPPRESSED_EFFECT_NOTIFICATION_LIST;
mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 1);
- mController.onRadioButtonClick(mockPref);
+ mController.onRadioButtonClicked(mPref);
verify(mBackend).saveVisualEffectsPolicy(allSuppressed, true);
verify(mFeatureFactory.metricsFeatureProvider).action(eq(mContext),
eq(ACTION_ZEN_SOUND_AND_VIS_EFFECTS),
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsCustomPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsCustomPreferenceControllerTest.java
index baea9ef..88c2c50 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsCustomPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsCustomPreferenceControllerTest.java
@@ -38,11 +38,9 @@
import androidx.preference.PreferenceScreen;
-import com.android.settings.notification.zen.ZenCustomRadioButtonPreference;
-import com.android.settings.notification.zen.ZenModeBackend;
-import com.android.settings.notification.zen.ZenModeVisEffectsCustomPreferenceController;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
import org.junit.Before;
import org.junit.Test;
@@ -61,7 +59,7 @@
@Mock
private ZenModeBackend mBackend;
@Mock
- private ZenCustomRadioButtonPreference mockPref;
+ private RadioButtonPreference mPref;
private Context mContext;
@Mock
private PreferenceScreen mScreen;
@@ -83,7 +81,7 @@
mContext, mock(Lifecycle.class), PREF_KEY);
ReflectionHelpers.setField(mController, "mBackend", mBackend);
- when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPref);
mController.displayPreference(mScreen);
}
@@ -102,9 +100,9 @@
@Test
public void updateState_notChecked_noVisEffects() {
mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 0);
- mController.updateState(mockPref);
+ mController.updateState(mPref);
- verify(mockPref).setChecked(false);
+ verify(mPref).setChecked(false);
}
@Test
@@ -119,25 +117,25 @@
| SUPPRESSED_EFFECT_PEEK
| SUPPRESSED_EFFECT_NOTIFICATION_LIST;
mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, allSuppressed);
- mController.updateState(mockPref);
+ mController.updateState(mPref);
- verify(mockPref).setChecked(false);
+ verify(mPref).setChecked(false);
}
@Test
public void updateState_checked() {
mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 2);
- mController.updateState(mockPref);
+ mController.updateState(mPref);
- verify(mockPref).setChecked(true);
+ verify(mPref).setChecked(true);
}
@Test
public void updateState_listeners() {
mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 2);
- mController.updateState(mockPref);
+ mController.updateState(mPref);
- verify(mockPref).setOnGearClickListener(any());
- verify(mockPref).setOnRadioButtonClickListener(any());
+ verify(mPref).setExtraWidgetOnClickListener(any());
+ verify(mPref).setOnClickListener(any());
}
}
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsNonePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsNonePreferenceControllerTest.java
index aacb109..79c6cb8 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsNonePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeVisEffectsNonePreferenceControllerTest.java
@@ -40,11 +40,9 @@
import androidx.preference.PreferenceScreen;
-import com.android.settings.notification.zen.ZenCustomRadioButtonPreference;
-import com.android.settings.notification.zen.ZenModeBackend;
-import com.android.settings.notification.zen.ZenModeVisEffectsNonePreferenceController;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
import org.junit.Before;
import org.junit.Test;
@@ -63,7 +61,7 @@
@Mock
private ZenModeBackend mBackend;
@Mock
- private ZenCustomRadioButtonPreference mockPref;
+ private RadioButtonPreference mMockPref;
private Context mContext;
private FakeFeatureFactory mFeatureFactory;
@Mock
@@ -86,7 +84,7 @@
mContext, mock(Lifecycle.class), PREF_KEY);
ReflectionHelpers.setField(mController, "mBackend", mBackend);
- when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
mController.displayPreference(mScreen);
}
@@ -98,17 +96,17 @@
@Test
public void updateState_notChecked() {
mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 1);
- mController.updateState(mockPref);
+ mController.updateState(mMockPref);
- verify(mockPref).setChecked(false);
+ verify(mMockPref).setChecked(false);
}
@Test
public void updateState_checked() {
mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 0);
- mController.updateState(mockPref);
+ mController.updateState(mMockPref);
- verify(mockPref).setChecked(true);
+ verify(mMockPref).setChecked(true);
}
@Test
@@ -123,7 +121,7 @@
| SUPPRESSED_EFFECT_PEEK
| SUPPRESSED_EFFECT_NOTIFICATION_LIST;
mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 1);
- mController.onRadioButtonClick(mockPref);
+ mController.onRadioButtonClicked(mMockPref);
verify(mBackend).saveVisualEffectsPolicy(allSuppressed, false);
verify(mFeatureFactory.metricsFeatureProvider).action(nullable(Context.class),
eq(ACTION_ZEN_SOUND_ONLY),
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleCustomPolicyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleCustomPolicyPreferenceControllerTest.java
index f6fa5b7..f149541 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleCustomPolicyPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleCustomPolicyPreferenceControllerTest.java
@@ -27,6 +27,7 @@
import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
import org.junit.Before;
import org.junit.Test;
@@ -47,7 +48,7 @@
@Mock
private NotificationManager mNotificationManager;
@Mock
- private ZenCustomRadioButtonPreference mockPref;
+ private RadioButtonPreference mMockPref;
@Mock
private PreferenceScreen mScreen;
@@ -70,21 +71,21 @@
PREF_KEY);
ReflectionHelpers.setField(mController, "mBackend", mBackend);
when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
- when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
mController.displayPreference(mScreen);
}
@Test
public void updateState_nullZenPolicy() {
updateControllerZenPolicy(null);
- mController.updateState(mockPref);
- verify(mockPref).setChecked(false);
+ mController.updateState(mMockPref);
+ verify(mMockPref).setChecked(false);
}
@Test
public void updateState_hasZenPolicy() {
updateControllerZenPolicy(new ZenPolicy.Builder().build());
- mController.updateState(mockPref);
- verify(mockPref).setChecked(true);
+ mController.updateState(mMockPref);
+ verify(mMockPref).setChecked(true);
}
}
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleDefaultPolicyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleDefaultPolicyPreferenceControllerTest.java
index 7091ceb..c0258e4 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleDefaultPolicyPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleDefaultPolicyPreferenceControllerTest.java
@@ -27,6 +27,7 @@
import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
import org.junit.Before;
import org.junit.Test;
@@ -47,7 +48,7 @@
@Mock
private NotificationManager mNotificationManager;
@Mock
- private ZenCustomRadioButtonPreference mockPref;
+ private RadioButtonPreference mMockPref;
@Mock
private PreferenceScreen mScreen;
@@ -70,21 +71,21 @@
PREF_KEY);
ReflectionHelpers.setField(mController, "mBackend", mBackend);
when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
- when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
mController.displayPreference(mScreen);
}
@Test
public void updateState_nullZenPolicy() {
updateControllerZenPolicy(null);
- mController.updateState(mockPref);
- verify(mockPref).setChecked(true);
+ mController.updateState(mMockPref);
+ verify(mMockPref).setChecked(true);
}
@Test
public void updateState_hasZenPolicy() {
updateControllerZenPolicy(new ZenPolicy.Builder().build());
- mController.updateState(mockPref);
- verify(mockPref).setChecked(false);
+ mController.updateState(mMockPref);
+ verify(mMockPref).setChecked(false);
}
}
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenRulePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenRulePreferenceControllerTest.java
index 13963db..e3fef19 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenRulePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenRulePreferenceControllerTest.java
@@ -28,10 +28,8 @@
import androidx.preference.PreferenceScreen;
-import com.android.settings.notification.zen.AbstractZenCustomRulePreferenceController;
-import com.android.settings.notification.zen.ZenCustomRadioButtonPreference;
-import com.android.settings.notification.zen.ZenModeBackend;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
import org.junit.Before;
import org.junit.Test;
@@ -51,7 +49,7 @@
@Mock
private NotificationManager mNotificationManager;
@Mock
- private ZenCustomRadioButtonPreference mockPref;
+ private RadioButtonPreference mMockPref;
@Mock
private PreferenceScreen mScreen;
@@ -67,7 +65,7 @@
mContext = RuntimeEnvironment.application;
mController = new TestablePreferenceController(mContext,"test", mock(Lifecycle.class));
ReflectionHelpers.setField(mController, "mBackend", mBackend);
- when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
mController.displayPreference(mScreen);
}
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsAllPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsAllPreferenceControllerTest.java
index f30587f..edbcd06 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsAllPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsAllPreferenceControllerTest.java
@@ -27,6 +27,7 @@
import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
import org.junit.Before;
import org.junit.Test;
@@ -47,7 +48,7 @@
@Mock
private NotificationManager mNotificationManager;
@Mock
- private ZenCustomRadioButtonPreference mockPref;
+ private RadioButtonPreference mMockPref;
@Mock
private PreferenceScreen mScreen;
@@ -69,7 +70,7 @@
PREF_KEY);
ReflectionHelpers.setField(mController, "mBackend", mBackend);
when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
- when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
mController.displayPreference(mScreen);
}
@@ -78,8 +79,8 @@
updateControllerZenPolicy(new ZenPolicy.Builder()
.hideAllVisualEffects()
.build());
- mController.updateState(mockPref);
- verify(mockPref).setChecked(false);
+ mController.updateState(mMockPref);
+ verify(mMockPref).setChecked(false);
}
@Test
@@ -87,8 +88,8 @@
updateControllerZenPolicy(new ZenPolicy.Builder()
.showAllVisualEffects()
.build());
- mController.updateState(mockPref);
- verify(mockPref).setChecked(true);
+ mController.updateState(mMockPref);
+ verify(mMockPref).setChecked(true);
}
@Test
@@ -97,8 +98,8 @@
.showPeeking(true)
.showBadges(false)
.build());
- mController.updateState(mockPref);
+ mController.updateState(mMockPref);
- verify(mockPref).setChecked(false);
+ verify(mMockPref).setChecked(false);
}
}
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsCustomPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsCustomPreferenceControllerTest.java
index 99b76ce..ece5d5f 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsCustomPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsCustomPreferenceControllerTest.java
@@ -27,6 +27,7 @@
import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
import org.junit.Before;
import org.junit.Test;
@@ -47,7 +48,7 @@
@Mock
private NotificationManager mNotificationManager;
@Mock
- private ZenCustomRadioButtonPreference mockPref;
+ private RadioButtonPreference mMockPref;
@Mock
private PreferenceScreen mScreen;
@@ -69,7 +70,7 @@
PREF_KEY);
ReflectionHelpers.setField(mController, "mBackend", mBackend);
when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
- when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
mController.displayPreference(mScreen);
}
@@ -78,8 +79,8 @@
updateControllerZenPolicy(new ZenPolicy.Builder()
.hideAllVisualEffects()
.build());
- mController.updateState(mockPref);
- verify(mockPref).setChecked(false);
+ mController.updateState(mMockPref);
+ verify(mMockPref).setChecked(false);
}
@Test
@@ -87,8 +88,8 @@
updateControllerZenPolicy(new ZenPolicy.Builder()
.showAllVisualEffects()
.build());
- mController.updateState(mockPref);
- verify(mockPref).setChecked(false);
+ mController.updateState(mMockPref);
+ verify(mMockPref).setChecked(false);
}
@Test
@@ -97,8 +98,8 @@
.showPeeking(true)
.showBadges(false)
.build());
- mController.updateState(mockPref);
+ mController.updateState(mMockPref);
- verify(mockPref).setChecked(true);
+ verify(mMockPref).setChecked(true);
}
}
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsNonePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsNonePreferenceControllerTest.java
index 510da5f..2daf4fb 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsNonePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenRuleVisEffectsNonePreferenceControllerTest.java
@@ -27,6 +27,7 @@
import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
import org.junit.Before;
import org.junit.Test;
@@ -47,7 +48,7 @@
@Mock
private NotificationManager mNotificationManager;
@Mock
- private ZenCustomRadioButtonPreference mockPref;
+ private RadioButtonPreference mMockPref;
@Mock
private PreferenceScreen mScreen;
@@ -69,7 +70,7 @@
PREF_KEY);
ReflectionHelpers.setField(mController, "mBackend", mBackend);
when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
- when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
mController.displayPreference(mScreen);
}
@@ -78,8 +79,8 @@
updateControllerZenPolicy(new ZenPolicy.Builder()
.hideAllVisualEffects()
.build());
- mController.updateState(mockPref);
- verify(mockPref).setChecked(true);
+ mController.updateState(mMockPref);
+ verify(mMockPref).setChecked(true);
}
@Test
@@ -87,8 +88,8 @@
updateControllerZenPolicy(new ZenPolicy.Builder()
.showAllVisualEffects()
.build());
- mController.updateState(mockPref);
- verify(mockPref).setChecked(false);
+ mController.updateState(mMockPref);
+ verify(mMockPref).setChecked(false);
}
@Test
@@ -97,8 +98,8 @@
.showPeeking(true)
.showBadges(false)
.build());
- mController.updateState(mockPref);
+ mController.updateState(mMockPref);
- verify(mockPref).setChecked(false);
+ verify(mMockPref).setChecked(false);
}
}
diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
index b5c6c44..c2c67e3 100644
--- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
@@ -565,7 +565,8 @@
final Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS)
.setPackage(Utils.SETTINGS_PACKAGE_NAME);
PendingIntent settingsPendingIntent =
- PendingIntent.getActivity(mContext, 0, settingsIntent, 0);
+ PendingIntent.getActivity(mContext, 0, settingsIntent,
+ PendingIntent.FLAG_IMMUTABLE);
assertThat(pendingIntent).isEqualTo(settingsPendingIntent);
}
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
index 2c68269..6fb2eae 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -43,6 +43,7 @@
import com.android.settings.security.SecurityFeatureProvider;
import com.android.settings.slices.SlicesFeatureProvider;
import com.android.settings.users.UserFeatureProvider;
+import com.android.settings.wifi.WifiTrackerLibProvider;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import org.mockito.Answers;
@@ -77,6 +78,8 @@
public SearchFeatureProvider searchFeatureProvider;
public ContextualCardFeatureProvider mContextualCardFeatureProvider;
+ public WifiTrackerLibProvider wifiTrackerLibProvider;
+
/**
* Call this in {@code @Before} method of the test class to use fake factory.
*/
@@ -120,6 +123,7 @@
mBluetoothFeatureProvider = mock(BluetoothFeatureProvider.class);
mAwareFeatureProvider = mock(AwareFeatureProvider.class);
mFaceFeatureProvider = mock(FaceFeatureProvider.class);
+ wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class);
}
@Override
@@ -231,4 +235,9 @@
public FaceFeatureProvider getFaceFeatureProvider() {
return mFaceFeatureProvider;
}
+
+ @Override
+ public WifiTrackerLibProvider getWifiTrackerLibProvider() {
+ return wifiTrackerLibProvider;
+ }
}
diff --git a/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
index 90c9172..50ddd2a 100644
--- a/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
@@ -363,7 +363,7 @@
mFragment.initialize(mActivity, mArguments);
verify(mRemoveUserPref).setOnPreferenceClickListener(mFragment);
- verify(mRemoveUserPref).setTitle(R.string.user_exit_guest_title);
+ verify(mRemoveUserPref).setTitle(R.string.user_exit_guest_menu);
verify(mFragment, never()).removePreference(KEY_REMOVE_USER);
}
diff --git a/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidgetTest.java b/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidgetTest.java
deleted file mode 100644
index 2e2d786..0000000
--- a/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidgetTest.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.settings.widget;
-
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_GONE;
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_INFO;
-import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_SETTING;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertEquals;
-
-import android.app.Application;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class RadioButtonPreferenceWithExtraWidgetTest {
-
- private Application mContext;
- private RadioButtonPreferenceWithExtraWidget mPreference;
-
- private TextView mSummary;
- private ImageView mExtraWidget;
- private View mExtraWidgetDivider;
-
- private boolean mIsClickListenerCalled = false;
- private View.OnClickListener mClickListener = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mIsClickListenerCalled = true;
- }
- };
-
- @Before
- public void setUp() {
- mContext = RuntimeEnvironment.application;
- mPreference = new RadioButtonPreferenceWithExtraWidget(mContext);
- mPreference.setSummary("test summary");
-
- View view = LayoutInflater.from(mContext)
- .inflate(R.layout.preference_radio_with_extra_widget, null);
- PreferenceViewHolder preferenceViewHolder =
- PreferenceViewHolder.createInstanceForTests(view);
- mPreference.onBindViewHolder(preferenceViewHolder);
-
- mSummary = view.findViewById(android.R.id.summary);
- mExtraWidget = view.findViewById(R.id.radio_extra_widget);
- mExtraWidgetDivider = view.findViewById(R.id.radio_extra_widget_divider);
- }
-
- @Test
- public void shouldHaveRadioPreferenceWithExtraWidgetLayout() {
- assertThat(mPreference.getLayoutResource())
- .isEqualTo(R.layout.preference_radio_with_extra_widget);
- }
-
- @Test
- public void iconSpaceReservedShouldBeFalse() {
- assertThat(mPreference.isIconSpaceReserved()).isFalse();
- }
-
- @Test
- public void summaryShouldBeVisible() {
- assertEquals(View.VISIBLE, mSummary.getVisibility());
- }
-
- @Test
- public void testSetExtraWidgetVisibility_gone() {
- mPreference.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_GONE);
- assertEquals(View.GONE, mExtraWidget.getVisibility());
- assertEquals(View.GONE, mExtraWidgetDivider.getVisibility());
- assertThat(mExtraWidget.isClickable()).isFalse();
- }
-
- @Test
- public void testSetExtraWidgetVisibility_info() {
- mPreference.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_INFO);
- assertEquals(View.VISIBLE, mExtraWidget.getVisibility());
- assertEquals(View.VISIBLE, mExtraWidgetDivider.getVisibility());
- assertThat(mExtraWidget.isClickable()).isTrue();
- assertEquals(mContext.getResources().getText(R.string.information_label),
- mExtraWidget.getContentDescription());
- }
-
- @Test
- public void testSetExtraWidgetVisibility_setting() {
- mPreference.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_SETTING);
- assertEquals(View.VISIBLE, mExtraWidget.getVisibility());
- assertEquals(View.VISIBLE, mExtraWidgetDivider.getVisibility());
- assertThat(mExtraWidget.isClickable()).isTrue();
- assertEquals(mContext.getResources().getText(R.string.settings_label),
- mExtraWidget.getContentDescription());
- }
-
- @Test
- public void testSetExtraWidgetOnClickListener() {
- mPreference.setExtraWidgetOnClickListener(mClickListener);
-
- assertThat(mIsClickListenerCalled).isFalse();
- mExtraWidget.callOnClick();
- assertThat(mIsClickListenerCalled).isTrue();
- }
-
- @Test
- public void extraWidgetStaysEnabledWhenPreferenceIsDisabled() {
- mPreference.setEnabled(false);
- mExtraWidget.setEnabled(false);
-
- assertThat(mExtraWidget.isEnabled()).isFalse();
- mPreference.setExtraWidgetOnClickListener(mClickListener);
- assertThat(mExtraWidget.isEnabled()).isTrue();
- }
-}
diff --git a/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragmentTest.java b/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragmentTest.java
index 70c7810..24d4c47 100644
--- a/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragmentTest.java
@@ -20,6 +20,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@@ -41,6 +42,7 @@
import androidx.fragment.app.FragmentActivity;
import com.android.settings.R;
+import com.android.settings.testutils.FakeFeatureFactory;
import com.android.wifitrackerlib.WifiEntry;
import com.android.wifitrackerlib.WifiPickerTracker;
@@ -82,6 +84,8 @@
@Mock
private WifiEntry mWifiEntry;
+ private FakeFeatureFactory mFakeFeatureFactory;
+
@Mock
private WifiPickerTracker mWifiPickerTracker;
@@ -106,6 +110,8 @@
mSavedWpaConfigurationEntry = generateRegularWifiConfiguration(FAKE_NEW_SAVED_WPA_SSID,
WifiConfiguration.KeyMgmt.WPA_PSK, "\"1234567890\"");
+ mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+
mAddAppNetworksFragment.mWifiPickerTracker = mWifiPickerTracker;
setUpOneScannedNetworkWithScanedLevel4();
}
@@ -485,6 +491,9 @@
}
private void setupFragment() {
+ when(mFakeFeatureFactory.wifiTrackerLibProvider.createWifiPickerTracker(
+ any(), any(), any(), any(), any(), anyLong(), anyLong(), any()))
+ .thenReturn(mWifiPickerTracker);
FragmentController.setupFragment(mAddAppNetworksFragment);
}
diff --git a/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java
new file mode 100644
index 0000000..064f813
--- /dev/null
+++ b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications.specialaccess.notificationaccess;
+
+import static com.google.common.truth.Truth.assertThat;
+
+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.NotificationManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+
+import androidx.preference.SwitchPreference;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.testutils.FakeFeatureFactory;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class ApprovalPreferenceControllerTest {
+
+ private Context mContext;
+ private FakeFeatureFactory mFeatureFactory;
+ @Mock
+ private NotificationAccessDetails mFragment;
+ private ApprovalPreferenceController mController;
+ @Mock
+ NotificationManager mNm;
+ @Mock
+ PackageManager mPm;
+ PackageInfo mPkgInfo;
+ ComponentName mCn = new ComponentName("a", "b");
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mFeatureFactory = FakeFeatureFactory.setupForTest();
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ doReturn(mContext).when(mFragment).getContext();
+
+ mPkgInfo = new PackageInfo();
+ mPkgInfo.applicationInfo = mock(ApplicationInfo.class);
+ when(mPkgInfo.applicationInfo.loadLabel(mPm)).thenReturn("LABEL");
+
+ mController = new ApprovalPreferenceController(mContext, "key");
+ mController.setCn(mCn);
+ mController.setNm(mNm);
+ mController.setParent(mFragment);
+ mController.setPkgInfo(mPkgInfo);
+ }
+
+ @Test
+ public void updateState_checked() {
+ when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+ SwitchPreference pref = new SwitchPreference(mContext);
+
+ mController.updateState(pref);
+ assertThat(pref.isChecked()).isTrue();
+ }
+
+ @Test
+ public void enable() {
+ mController.enable(mCn);
+ verify(mFeatureFactory.metricsFeatureProvider).action(
+ mContext,
+ MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_NOTIVIEW_ALLOW,
+ "a");
+
+ verify(mNm).setNotificationListenerAccessGranted(mCn, true);
+ }
+
+ @Test
+ public void disable() {
+ mController.disable(mCn);
+ verify(mFeatureFactory.metricsFeatureProvider).action(
+ mContext,
+ MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_NOTIVIEW_ALLOW,
+ "a");
+
+ verify(mNm).setNotificationListenerAccessGranted(mCn, false);
+ }
+}
diff --git a/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/TypeFilterPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/TypeFilterPreferenceControllerTest.java
new file mode 100644
index 0000000..3014066
--- /dev/null
+++ b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/TypeFilterPreferenceControllerTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2021 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.applications.specialaccess.notificationaccess;
+
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_SILENT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.service.notification.NotificationListenerFilter;
+import android.util.ArraySet;
+
+import androidx.preference.MultiSelectListPreference;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.notification.NotificationBackend;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+public class TypeFilterPreferenceControllerTest {
+
+ private Context mContext;
+ private TypeFilterPreferenceController mController;
+ @Mock
+ NotificationBackend mNm;
+ ComponentName mCn = new ComponentName("a", "b");
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = ApplicationProvider.getApplicationContext();
+
+ mController = new TypeFilterPreferenceController(mContext, "key");
+ mController.setCn(mCn);
+ mController.setNm(mNm);
+ mController.setUserId(0);
+ }
+
+ @Test
+ public void updateState_enabled() {
+ when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+ when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
+ MultiSelectListPreference pref = new MultiSelectListPreference(mContext);
+
+ mController.updateState(pref);
+ assertThat(pref.isEnabled()).isTrue();
+ }
+
+ @Test
+ public void updateState_disabled() {
+ when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(false);
+ when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
+ MultiSelectListPreference pref = new MultiSelectListPreference(mContext);
+
+ mController.updateState(pref);
+ assertThat(pref.isEnabled()).isFalse();
+ }
+
+ @Test
+ public void updateState() {
+ NotificationListenerFilter nlf = new NotificationListenerFilter(FLAG_FILTER_TYPE_ONGOING
+ | FLAG_FILTER_TYPE_SILENT, new ArraySet<>());
+ when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+ when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
+
+ MultiSelectListPreference pref = new MultiSelectListPreference(mContext);
+ mController.updateState(pref);
+
+ assertThat(pref.getValues()).containsExactlyElementsIn(
+ new String[] {String.valueOf(FLAG_FILTER_TYPE_ONGOING),
+ String.valueOf(FLAG_FILTER_TYPE_SILENT)});
+ assertThat(pref.getSummary()).isNotNull();
+ }
+
+ @Test
+ public void getSummary() {
+ NotificationListenerFilter nlf = new NotificationListenerFilter(FLAG_FILTER_TYPE_ONGOING
+ | FLAG_FILTER_TYPE_CONVERSATIONS, new ArraySet<>());
+ when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+ when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
+
+ MultiSelectListPreference pref = new MultiSelectListPreference(mContext);
+ mController.updateState(pref);
+
+ assertThat(mController.getSummary().toString()).ignoringCase().contains("ongoing");
+ assertThat(mController.getSummary().toString()).ignoringCase().contains("conversation");
+ }
+
+ @Test
+ public void onPreferenceChange() {
+ NotificationListenerFilter nlf = new NotificationListenerFilter(FLAG_FILTER_TYPE_ONGOING
+ | FLAG_FILTER_TYPE_CONVERSATIONS, new ArraySet<>());
+ when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+ when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
+
+ MultiSelectListPreference pref = new MultiSelectListPreference(mContext);
+
+ mController.onPreferenceChange(pref, Set.of("8", "1", "4"));
+
+ ArgumentCaptor<NotificationListenerFilter> captor =
+ ArgumentCaptor.forClass(NotificationListenerFilter.class);
+ verify(mNm).setListenerFilter(eq(mCn), eq(0), captor.capture());
+ assertThat(captor.getValue().getTypes()).isEqualTo(FLAG_FILTER_TYPE_CONVERSATIONS
+ | FLAG_FILTER_TYPE_SILENT | FLAG_FILTER_TYPE_ONGOING);
+ }
+}
diff --git a/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java b/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java
index f9450db..076ce2b 100644
--- a/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java
+++ b/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java
@@ -22,6 +22,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -50,9 +51,11 @@
import com.android.settings.Utils;
import com.android.settings.network.telephony.NetworkProviderWorker;
+import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.ResourcesUtils;
import com.android.settings.wifi.slice.WifiSliceItem;
import com.android.wifitrackerlib.WifiEntry;
+import com.android.wifitrackerlib.WifiPickerTracker;
import org.junit.Before;
import org.junit.Test;
@@ -100,12 +103,22 @@
@Mock
GridRowBuilder mMockGridRowBuilderAllNetworkUnavailable;
+ private FakeFeatureFactory mFeatureFactory;
+ @Mock
+ private WifiPickerTracker mWifiPickerTracker;
+
@Before
@UiThreadTest
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(ApplicationProvider.getApplicationContext());
+ mFeatureFactory = FakeFeatureFactory.setupForTest();
+ when(mFeatureFactory.wifiTrackerLibProvider
+ .createWifiPickerTracker(
+ any(), any(), any(), any(), any(), anyLong(), anyLong(), any()))
+ .thenReturn(mWifiPickerTracker);
+
when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager);
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
diff --git a/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java
index 5ee4c42..27dd2aa 100644
--- a/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java
@@ -28,6 +28,7 @@
import static org.mockito.ArgumentMatchers.eq;;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -59,6 +60,7 @@
import com.android.settings.Utils;
import com.android.settings.network.SubscriptionsPreferenceController.SubsPrefCtrlInjector;
import com.android.settings.testutils.ResourcesUtils;
+import com.android.settings.wifi.WifiPickerTrackerHelper;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.After;
@@ -90,6 +92,8 @@
private Lifecycle mLifecycle;
@Mock
private LifecycleOwner mLifecycleOwner;
+ @Mock
+ private WifiPickerTrackerHelper mWifiPickerTrackerHelper;
private LifecycleRegistry mLifecycleRegistry;
private int mOnChildUpdatedCount;
private Context mContext;
@@ -529,6 +533,26 @@
assertThat(icon).isEqualTo(actualIcon);
}
+ @Test
+ public void connectCarrierNetwork_isDataEnabled_helperConnect() {
+ when(mTelephonyManager.isDataEnabled()).thenReturn(true);
+ mController.setWifiPickerTrackerHelper(mWifiPickerTrackerHelper);
+
+ mController.connectCarrierNetwork();
+
+ verify(mWifiPickerTrackerHelper).connectCarrierNetwork(any());
+ }
+
+ @Test
+ public void connectCarrierNetwork_isNotDataEnabled_helperNeverConnect() {
+ when(mTelephonyManager.isDataEnabled()).thenReturn(false);
+ mController.setWifiPickerTrackerHelper(mWifiPickerTrackerHelper);
+
+ mController.connectCarrierNetwork();
+
+ verify(mWifiPickerTrackerHelper, never()).connectCarrierNetwork(any());
+ }
+
private void setupGetIconConditions(int subId, boolean isActiveCellularNetwork,
boolean isDataEnable, int dataState, int servicestate) {
doReturn(mTelephonyManagerForSub).when(mTelephonyManager).createForSubscriptionId(subId);
diff --git a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
index 47851b9..d20fc12 100644
--- a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -41,6 +41,7 @@
import com.android.settings.security.SecurityFeatureProvider;
import com.android.settings.slices.SlicesFeatureProvider;
import com.android.settings.users.UserFeatureProvider;
+import com.android.settings.wifi.WifiTrackerLibProvider;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
/**
@@ -72,6 +73,8 @@
public SearchFeatureProvider searchFeatureProvider;
public ContextualCardFeatureProvider mContextualCardFeatureProvider;
+ public WifiTrackerLibProvider wifiTrackerLibProvider;
+
/**
* Call this in {@code @Before} method of the test class to use fake factory.
*/
@@ -106,6 +109,7 @@
mBluetoothFeatureProvider = mock(BluetoothFeatureProvider.class);
mAwareFeatureProvider = mock(AwareFeatureProvider.class);
mFaceFeatureProvider = mock(FaceFeatureProvider.class);
+ wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class);
}
@Override
@@ -217,4 +221,9 @@
public FaceFeatureProvider getFaceFeatureProvider() {
return mFaceFeatureProvider;
}
+
+ @Override
+ public WifiTrackerLibProvider getWifiTrackerLibProvider() {
+ return wifiTrackerLibProvider;
+ }
}
diff --git a/tests/unit/src/com/android/settings/wifi/WifiPickerTrackerHelperTest.java b/tests/unit/src/com/android/settings/wifi/WifiPickerTrackerHelperTest.java
new file mode 100644
index 0000000..2991550
--- /dev/null
+++ b/tests/unit/src/com/android/settings/wifi/WifiPickerTrackerHelperTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2021 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.wifi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.os.HandlerThread;
+
+import androidx.lifecycle.Lifecycle;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.wifitrackerlib.MergedCarrierEntry;
+import com.android.wifitrackerlib.WifiEntry;
+import com.android.wifitrackerlib.WifiPickerTracker;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+@RunWith(AndroidJUnit4.class)
+public class WifiPickerTrackerHelperTest {
+
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+ @Mock
+ public WifiPickerTracker mWifiPickerTracker;
+ @Mock
+ public MergedCarrierEntry mMergedCarrierEntry;
+ @Mock
+ public WifiEntry.ConnectCallback mConnectCallback;
+
+ private WifiPickerTrackerHelper mWifiPickerTrackerHelper;
+
+ private FakeFeatureFactory mFeatureFactory;
+
+ @Before
+ public void setUp() {
+ mFeatureFactory = FakeFeatureFactory.setupForTest();
+ when(mFeatureFactory.wifiTrackerLibProvider
+ .createWifiPickerTracker(
+ any(), any(), any(), any(), any(), anyLong(), anyLong(), any()))
+ .thenReturn(mWifiPickerTracker);
+ mWifiPickerTrackerHelper = new WifiPickerTrackerHelper(mock(Lifecycle.class),
+ ApplicationProvider.getApplicationContext(), null);
+ }
+
+ @Test
+ public void getWifiPickerTracker_returnNonNull() {
+ assertThat(mWifiPickerTrackerHelper.getWifiPickerTracker()).isNotNull();
+ }
+
+ @Test
+ public void onDestroy_workerThreadQuit() {
+ final HandlerThread workerThread = mock(HandlerThread.class);
+ mWifiPickerTrackerHelper.setWorkerThread(workerThread);
+
+ mWifiPickerTrackerHelper.onDestroy();
+
+ verify(workerThread).quit();
+ }
+
+ @Test
+ public void setCarrierNetworkEnabled_returnTrueAndSetEnabled() {
+ mWifiPickerTrackerHelper.setWifiPickerTracker(mWifiPickerTracker);
+ when(mWifiPickerTracker.getMergedCarrierEntry()).thenReturn(mMergedCarrierEntry);
+
+ assertThat(mWifiPickerTrackerHelper.setCarrierNetworkEnabled(true)).isTrue();
+ verify(mMergedCarrierEntry).setEnabled(true);
+
+ assertThat(mWifiPickerTrackerHelper.setCarrierNetworkEnabled(false)).isTrue();
+ verify(mMergedCarrierEntry).setEnabled(false);
+ }
+
+ @Test
+ public void setCarrierNetworkEnabled_mergedCarrierEntryIsNull_returnFalse() {
+ mWifiPickerTrackerHelper.setWifiPickerTracker(mWifiPickerTracker);
+ when(mWifiPickerTracker.getMergedCarrierEntry()).thenReturn(null);
+
+ assertThat(mWifiPickerTrackerHelper.setCarrierNetworkEnabled(true)).isFalse();
+ assertThat(mWifiPickerTrackerHelper.setCarrierNetworkEnabled(false)).isFalse();
+ }
+
+ @Test
+ public void connectCarrierNetwork_returnTrueAndConnect() {
+ mWifiPickerTrackerHelper.setWifiPickerTracker(mWifiPickerTracker);
+ when(mWifiPickerTracker.getMergedCarrierEntry()).thenReturn(mMergedCarrierEntry);
+ when(mMergedCarrierEntry.canConnect()).thenReturn(true);
+
+ assertThat(mWifiPickerTrackerHelper.connectCarrierNetwork(mConnectCallback)).isTrue();
+ verify(mMergedCarrierEntry).connect(mConnectCallback);
+ }
+
+ @Test
+ public void connectCarrierNetwork_mergedCarrierEntryIsNull_returnFalse() {
+ mWifiPickerTrackerHelper.setWifiPickerTracker(mWifiPickerTracker);
+ when(mWifiPickerTracker.getMergedCarrierEntry()).thenReturn(null);
+
+ assertThat(mWifiPickerTrackerHelper.connectCarrierNetwork(mConnectCallback)).isFalse();
+ }
+
+ @Test
+ public void connectCarrierNetwork_canConnectIsFalse_returnFalseAndNeverConnect() {
+ mWifiPickerTrackerHelper.setWifiPickerTracker(mWifiPickerTracker);
+ when(mWifiPickerTracker.getMergedCarrierEntry()).thenReturn(mMergedCarrierEntry);
+ when(mMergedCarrierEntry.canConnect()).thenReturn(false);
+
+ assertThat(mWifiPickerTrackerHelper.connectCarrierNetwork(mConnectCallback)).isFalse();
+ verify(mMergedCarrierEntry, never()).connect(mConnectCallback);
+ }
+}