Snap for 4793185 from c96606500f to pi-release
Change-Id: I0a96977ee310814f0b5a3036a08162b71cc8ea39
This commit is contained in:
@@ -3137,6 +3137,8 @@
|
||||
android:value="com.android.settings.accounts.AccountDashboardFragment"/>
|
||||
<meta-data android:name="com.android.settings.category"
|
||||
android:value="com.android.settings.category.ia.homepage"/>
|
||||
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
|
||||
android:value="true" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/layout-land/choose_lock_pattern.xml"
|
||||
line="170"
|
||||
line="178"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
@@ -417,22 +417,6 @@
|
||||
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="fingerprint_indicator_background_resting">#12000000</color>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="51"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
@@ -445,7 +429,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="53"
|
||||
line="52"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -461,7 +445,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="54"
|
||||
line="53"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -477,7 +461,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="56"
|
||||
line="55"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -493,7 +477,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="59"
|
||||
line="58"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -509,7 +493,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="60"
|
||||
line="59"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -525,7 +509,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="62"
|
||||
line="61"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -541,7 +525,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="63"
|
||||
line="62"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -557,7 +541,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="64"
|
||||
line="63"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -573,7 +557,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="65"
|
||||
line="64"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -589,7 +573,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="67"
|
||||
line="66"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -605,7 +589,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="70"
|
||||
line="69"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -621,7 +605,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="72"
|
||||
line="71"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -637,7 +621,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="73"
|
||||
line="72"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -653,7 +637,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="76"
|
||||
line="75"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -669,7 +653,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="77"
|
||||
line="76"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -685,7 +669,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="78"
|
||||
line="77"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -701,7 +685,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="79"
|
||||
line="78"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -717,7 +701,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="80"
|
||||
line="79"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -733,7 +717,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="83"
|
||||
line="82"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -749,7 +733,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="84"
|
||||
line="83"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -765,7 +749,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="85"
|
||||
line="84"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -781,7 +765,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="86"
|
||||
line="85"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -797,7 +781,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="87"
|
||||
line="86"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -813,7 +797,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="88"
|
||||
line="87"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -829,7 +813,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="89"
|
||||
line="88"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -845,7 +829,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="90"
|
||||
line="89"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -861,7 +845,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="91"
|
||||
line="90"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -877,7 +861,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="92"
|
||||
line="91"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -893,7 +877,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="93"
|
||||
line="92"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -909,7 +893,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="95"
|
||||
line="94"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -921,11 +905,11 @@
|
||||
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="gestures_setting_background_color">#f4f4f4</color>"
|
||||
errorLine1=" <color name="gestures_setting_background_color">#ffffff</color>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="98"
|
||||
line="97"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -941,7 +925,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="100"
|
||||
line="99"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -957,7 +941,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="103"
|
||||
line="102"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -973,7 +957,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="106"
|
||||
line="105"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -989,7 +973,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="109"
|
||||
line="108"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1005,7 +989,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="112"
|
||||
line="111"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1021,7 +1005,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="113"
|
||||
line="112"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1037,7 +1021,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="116"
|
||||
line="115"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1053,7 +1037,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="117"
|
||||
line="116"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1069,7 +1053,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="118"
|
||||
line="117"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1085,7 +1069,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="119"
|
||||
line="118"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1101,7 +1085,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="120"
|
||||
line="119"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1117,7 +1101,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="121"
|
||||
line="120"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1133,7 +1117,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="122"
|
||||
line="121"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1149,7 +1133,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="123"
|
||||
line="122"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1165,7 +1149,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="124"
|
||||
line="123"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1181,7 +1165,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="125"
|
||||
line="124"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1197,7 +1181,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="126"
|
||||
line="125"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1213,7 +1197,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="127"
|
||||
line="126"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1229,7 +1213,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="128"
|
||||
line="127"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1245,7 +1229,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="133"
|
||||
line="132"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1261,7 +1245,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="134"
|
||||
line="133"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1277,7 +1261,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="135"
|
||||
line="134"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1293,7 +1277,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="136"
|
||||
line="135"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1309,7 +1293,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="137"
|
||||
line="136"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1325,7 +1309,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="138"
|
||||
line="137"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
@@ -1505,38 +1489,6 @@
|
||||
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=" android:background="@color/gestures_setting_background_color""
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/layout/gesture_preference.xml"
|
||||
line="57"
|
||||
column="9"/>
|
||||
</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:background="@color/gestures_setting_background_color"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/layout/gesture_preference.xml"
|
||||
line="78"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
@@ -2189,7 +2141,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/layout/radio_info.xml"
|
||||
line="111"
|
||||
line="116"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@@ -2205,7 +2157,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/layout/radio_info.xml"
|
||||
line="141"
|
||||
line="135"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@@ -2221,7 +2173,23 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/layout/radio_info.xml"
|
||||
line="279"
|
||||
line="165"
|
||||
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:background="#000000" />"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/layout/radio_info.xml"
|
||||
line="303"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@@ -2401,22 +2369,6 @@
|
||||
column="17"/>
|
||||
</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:background="@color/suggestion_condition_background">"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/layout/settings_main_dashboard.xml"
|
||||
line="30"
|
||||
column="9"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
@@ -2477,7 +2429,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values-en-rXC/strings.xml"
|
||||
line="2535"
|
||||
line="2531"
|
||||
column="168"/>
|
||||
</issue>
|
||||
|
||||
@@ -2493,7 +2445,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values-en-rAU/strings.xml"
|
||||
line="2536"
|
||||
line="2532"
|
||||
column="64"/>
|
||||
</issue>
|
||||
|
||||
@@ -2509,7 +2461,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values-en-rCA/strings.xml"
|
||||
line="2536"
|
||||
line="2532"
|
||||
column="64"/>
|
||||
</issue>
|
||||
|
||||
@@ -2525,7 +2477,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values-en-rGB/strings.xml"
|
||||
line="2536"
|
||||
line="2532"
|
||||
column="64"/>
|
||||
</issue>
|
||||
|
||||
@@ -2541,7 +2493,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values-en-rIN/strings.xml"
|
||||
line="2536"
|
||||
line="2532"
|
||||
column="64"/>
|
||||
</issue>
|
||||
|
||||
@@ -2557,7 +2509,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/strings.xml"
|
||||
line="5899"
|
||||
line="5920"
|
||||
column="36"/>
|
||||
</issue>
|
||||
|
||||
@@ -2573,7 +2525,7 @@
|
||||
errorLine2=" ^">
|
||||
<location
|
||||
file="res/values/styles.xml"
|
||||
line="246"
|
||||
line="248"
|
||||
column="41"/>
|
||||
</issue>
|
||||
|
||||
@@ -2589,7 +2541,7 @@
|
||||
errorLine2=" ^">
|
||||
<location
|
||||
file="res/values/styles.xml"
|
||||
line="436"
|
||||
line="465"
|
||||
column="44"/>
|
||||
</issue>
|
||||
|
||||
@@ -2605,7 +2557,7 @@
|
||||
errorLine2=" ^">
|
||||
<location
|
||||
file="res/values/styles.xml"
|
||||
line="442"
|
||||
line="471"
|
||||
column="44"/>
|
||||
</issue>
|
||||
|
||||
@@ -2621,26 +2573,10 @@
|
||||
errorLine2=" ^">
|
||||
<location
|
||||
file="res/values/styles.xml"
|
||||
line="443"
|
||||
line="472"
|
||||
column="44"/>
|
||||
</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=" <item name="android:background">@color/suggestion_condition_background</item>"
|
||||
errorLine2=" ^">
|
||||
<location
|
||||
file="res/values/styles.xml"
|
||||
line="461"
|
||||
column="41"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
@@ -2861,7 +2797,7 @@
|
||||
errorLine2=" ^">
|
||||
<location
|
||||
file="res/values/themes.xml"
|
||||
line="348"
|
||||
line="349"
|
||||
column="45"/>
|
||||
</issue>
|
||||
|
||||
@@ -2877,7 +2813,7 @@
|
||||
errorLine2=" ^">
|
||||
<location
|
||||
file="res/values/themes.xml"
|
||||
line="349"
|
||||
line="350"
|
||||
column="49"/>
|
||||
</issue>
|
||||
|
||||
@@ -2893,7 +2829,7 @@
|
||||
errorLine2=" ^">
|
||||
<location
|
||||
file="res/values/themes.xml"
|
||||
line="357"
|
||||
line="358"
|
||||
column="45"/>
|
||||
</issue>
|
||||
|
||||
@@ -2909,7 +2845,7 @@
|
||||
errorLine2=" ^">
|
||||
<location
|
||||
file="res/values/themes.xml"
|
||||
line="358"
|
||||
line="359"
|
||||
column="49"/>
|
||||
</issue>
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 19 KiB |
@@ -16,10 +16,12 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="48.0"
|
||||
android:viewportHeight="48.0">
|
||||
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M24.0,4.0C12.9,4.0 4.0,12.9 4.0,24.0s8.9,20.0 20.0,20.0c11.1,0.0 20.0,-8.9 20.0,-20.0S35.1,4.0 24.0,4.0zM34.0,31.2L31.2,34.0L24.0,26.8L16.8,34.0L14.0,31.2l7.2,-7.2L14.0,16.8l2.8,-2.8l7.2,7.2l7.2,-7.2l2.8,2.8L26.8,24.0L34.0,31.2z"/>
|
||||
android:pathData="M12,2C6.47,2 2,6.47 2,12c0,5.53 4.47,10 10,10c5.53,0 10,-4.47 10,-10C22,6.47 17.53,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8s8,3.59 8,8S16.41,20 12,20z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M15.59,7l-3.59,3.59l-3.59,-3.59l-1.41,1.41l3.59,3.59l-3.59,3.59l1.41,1.41l3.59,-3.59l3.59,3.59l1.41,-1.41l-3.59,-3.59l3.59,-3.59z"/>
|
||||
</vector>
|
||||
|
||||
@@ -21,11 +21,6 @@
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M1 18v2c0 .55 .45 1 1 1h2c0-1.66-1.34-3-3-3zm0-2.94c-.01 .51 .32 .93 .82 1.02
|
||||
2.08 .36 3.74 2 4.1 4.08 .09 .48 .5 .84 .99 .84 .61 0 1.09-.54 1-1.14a6.996
|
||||
6.996 0 0 0-5.8-5.78c-.59-.09-1.09 .38 -1.11 .98 zm0-4.03c-.01 .52 .34 .96 .85
|
||||
1.01 4.26 .43 7.68 3.82 8.1 8.08 .05 .5 .48 .88 .99 .88 .59 0 1.06-.51
|
||||
1-1.1-.52-5.21-4.66-9.34-9.87-9.85-.57-.05-1.05 .4 -1.07 .98 zM21 3H3c-1.1 0-2
|
||||
.9-2 2v3h2V5h18v14h-7v2h7c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/>
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M21,3H3C1.9,3 1,3.9 1,5v3h2V5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2V5C23,3.9 22.1,3 21,3zM1,18v3h3C4,19.34 2.66,18 1,18zM1,14v2c2.76,0 5,2.24 5,5h2C8,17.13 4.87,14 1,14zM1,10v2c4.97,0 9,4.03 9,9h2C12,14.92 7.07,10 1,10z"/>
|
||||
</vector>
|
||||
|
||||
@@ -16,10 +16,16 @@ Copyright (C) 2015 The Android Open Source Project
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24.0dp"
|
||||
android:height="24.0dp"
|
||||
android:tint="?android:attr/colorControlNormal"
|
||||
android:viewportWidth="48.0"
|
||||
android:viewportHeight="48.0">
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12.0,38.0c0.0,2.21 1.79,4.0 4.0,4.0l16.0,0.0c2.21,0.0 4.0,-1.79 4.0,-4.0L36.0,14.0L12.0,14.0l0.0,24.0zM38.0,8.0l-7.0,0.0l-2.0,-2.0L19.0,6.0l-2.0,2.0l-7.0,0.0l0.0,4.0l28.0,0.0L38.0,8.0z"/>
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M15,4V3H9v1H4v2h1v13c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V6h1V4H15zM17,19H7V6h10V19z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M9,8h2v9h-2z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M13,8h2v9h-2z"/>
|
||||
</vector>
|
||||
|
||||
@@ -21,5 +21,5 @@
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M11.4,1.02C6.62,1.33 3,5.52 3,10.31v5.89C3,18.66 4.34,20 6,20h2c0.55,0 1,-0.45 1,-1v-6c0,-0.55 -0.45,-1 -1,-1H5v-1.71C5,6.45 7.96,3.11 11.79,3 15.76,2.89 19,6.06 19,10v2h-3c-0.55,0 -1,0.45 -1,1v6c0,0.55 0.45,1 1,1h2c1.66,0 3,-1.34 3,-3v-7c0,-5.17 -4.36,-9.32 -9.6,-8.98z"/>
|
||||
android:pathData="M19,15v3c0,0.55 -0.45,1 -1,1h-1v-4H19M7,15v4H6c-0.55,0 -1,-0.45 -1,-1v-3H7M12,2c-4.97,0 -9,4.03 -9,9v7c0,1.66 1.34,3 3,3h3v-8H5v-2c0,-3.87 3.13,-7 7,-7s7,3.13 7,7v2h-4v8h3c1.66,0 3,-1.34 3,-3v-7C21,6.03 16.97,2 12,2L12,2z"/>
|
||||
</vector>
|
||||
|
||||
@@ -19,11 +19,6 @@
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 16.81c-.72
|
||||
0-1.3-.58-1.3-1.3s.58-1.3 1.3-1.3 1.3 .58 1.3 1.3-.58 1.3-1.3
|
||||
1.3zm1.07-4.62c-.09 .52 -.59 .87 -1.13 .79 -.57-.08-.94-.66-.83-1.23 .52 -2.61
|
||||
2.66-2.84 2.87-4.5 .12 -.96-.42-1.87-1.34-2.17-1.04-.33-2.21 .16 -2.55 1.37-.12
|
||||
.45 -.52 .74 -.97 .74 -.66 0-1.13-.63-.96-1.27 .63 -2.25 2.91-3.38 5.05-2.74
|
||||
1.71 .51 2.84 2.16 2.78 3.95-.07 2.44-2.49 2.61-2.92 5.06z"
|
||||
android:fillColor="#FFFFFFFF"/>
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M11,18h2v-2h-2V18zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8s8,3.59 8,8S16.41,20 12,20zM12,6c-2.21,0 -4,1.79 -4,4h2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2c0,2 -3,1.75 -3,5h2c0,-2.25 3,-2.5 3,-5C16,7.79 14.21,6 12,6z"/>
|
||||
</vector>
|
||||
|
||||
@@ -22,11 +22,11 @@
|
||||
android:tint="?android:attr/textColorSecondary">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,17L12,17c0.55,0 1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1l0,0c-0.55,0 -1,0.45 -1,1v4C11,16.55 11.45,17 12,17z"/>
|
||||
android:pathData="M11,7h2v2h-2z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,2c-5.52,0 -10,4.48 -10,10s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8s8,3.59 8,8S16.41,20 12,20z"/>
|
||||
android:pathData="M11,11h2v6h-2z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,9.1L12,9.1c0.61,0 1.1,-0.49 1.1,-1.1l0,0c0,-0.61 -0.49,-1.1 -1.1,-1.1l0,0c-0.61,0 -1.1,0.49 -1.1,1.1l0,0C10.9,8.61 11.39,9.1 12,9.1z"/>
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10s10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8c0,-4.41 3.59,-8 8,-8s8,3.59 8,8C20,16.41 16.41,20 12,20z"/>
|
||||
</vector>
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
<!--
|
||||
Copyright (C) 2015 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="48.0"
|
||||
android:viewportHeight="48.0"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12.0,38.0c0.0,2.21 1.79,4.0 4.0,4.0l16.0,0.0c2.21,0.0 4.0,-1.79 4.0,-4.0L36.0,14.0L12.0,14.0l0.0,24.0zM38.0,8.0l-7.0,0.0l-2.0,-2.0L19.0,6.0l-2.0,2.0l-7.0,0.0l0.0,4.0l28.0,0.0L38.0,8.0z"/>
|
||||
</vector>
|
||||
@@ -21,11 +21,11 @@
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,17L12,17c0.55,0 1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1l0,0c-0.55,0 -1,0.45 -1,1v4C11,16.55 11.45,17 12,17z"/>
|
||||
android:pathData="M11,7h2v2h-2z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,2c-5.52,0 -10,4.48 -10,10s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8s8,3.59 8,8S16.41,20 12,20z"/>
|
||||
android:pathData="M11,11h2v6h-2z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,9.1L12,9.1c0.61,0 1.1,-0.49 1.1,-1.1l0,0c0,-0.61 -0.49,-1.1 -1.1,-1.1l0,0c-0.61,0 -1.1,0.49 -1.1,1.1l0,0C10.9,8.61 11.39,9.1 12,9.1z"/>
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10s10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8c0,-4.41 3.59,-8 8,-8s8,3.59 8,8C20,16.41 16.41,20 12,20z"/>
|
||||
</vector>
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M12,17L12,17c0.55,0 1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1l0,0c-0.55,0 -1,0.45 -1,1v4C11,16.55 11.45,17 12,17z"/>
|
||||
android:pathData="M11,7h2v2h-2z"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M12,2c-5.52,0 -10,4.48 -10,10s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8s8,3.59 8,8S16.41,20 12,20z"/>
|
||||
android:pathData="M11,11h2v6h-2z"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M12,9.1L12,9.1c0.61,0 1.1,-0.49 1.1,-1.1l0,0c0,-0.61 -0.49,-1.1 -1.1,-1.1l0,0c-0.61,0 -1.1,0.49 -1.1,1.1l0,0C10.9,8.61 11.39,9.1 12,9.1z"/>
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10s10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8c0,-4.41 3.59,-8 8,-8s8,3.59 8,8C20,16.41 16.41,20 12,20z"/>
|
||||
</vector>
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:textAppearance="@style/TextAppearance.SuggestionTitle"
|
||||
android:textColor="?android:attr/colorAccent" />
|
||||
android:textColor="?android:attr/textColorPrimary" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/additional_icons"
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
android:id="@+id/owner_info_edit_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@dimen/min_tap_target_size"
|
||||
android:gravity="top"
|
||||
android:hint="@string/owner_info_settings_edit_text_hint"
|
||||
android:inputType="textMultiLine|textCapSentences"
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingStart="16dip"
|
||||
android:paddingEnd="16dip"
|
||||
android:src="@drawable/ic_menu_delete"
|
||||
android:src="@drawable/ic_delete"
|
||||
android:contentDescription="@string/user_delete_user_description"
|
||||
android:layout_gravity="center"
|
||||
android:background="?android:attr/selectableItemBackground" />
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingStart="16dip"
|
||||
android:paddingEnd="16dip"
|
||||
android:src="@drawable/ic_menu_delete"
|
||||
android:src="@drawable/ic_delete"
|
||||
android:contentDescription="@string/user_delete_user_description"
|
||||
android:layout_gravity="center"
|
||||
android:background="?android:attr/selectableItemBackground" />
|
||||
|
||||
@@ -291,7 +291,6 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/wifi_item_content"
|
||||
android:textSize="14sp"
|
||||
android:text="@string/wifi_show_password" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingStart="16dip"
|
||||
android:paddingEnd="16dip"
|
||||
android:src="@drawable/ic_menu_delete"
|
||||
android:src="@drawable/ic_delete"
|
||||
android:contentDescription="@string/zen_mode_delete_rule"
|
||||
android:layout_gravity="center"
|
||||
android:background="?android:attr/selectableItemBackground" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/action_delete"
|
||||
android:title="@string/delete"
|
||||
android:icon="@android:drawable/ic_menu_delete"/>
|
||||
android:icon="@drawable/ic_delete"/>
|
||||
<item android:id="@+id/action_select_all"
|
||||
android:title="@string/select_all"
|
||||
android:showAsAction="ifRoom" />
|
||||
|
||||
Binary file not shown.
@@ -235,6 +235,22 @@
|
||||
<item>@string/wifi_security_psk_generic</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Security types for wireless tether -->
|
||||
<string-array name="wifi_tether_security">
|
||||
<!-- Do not translate. -->
|
||||
<item>@string/wifi_security_wpa2</item>
|
||||
<!-- Do not translate. -->
|
||||
<item>@string/wifi_security_none</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Values for security type for wireless tether -->
|
||||
<string-array name="wifi_tether_security_values">
|
||||
<!-- Do not translate. -->
|
||||
<item>4</item>
|
||||
<!-- Do not translate. -->
|
||||
<item>0</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Match this with the constants in WifiDialog. --> <skip />
|
||||
<!-- Wi-Fi settings. The type of EAP method a Wi-Fi network has. -->
|
||||
<string-array name="wifi_eap_method">
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
<!-- Whether to show Camera laser sensor switch in Developer Options -->
|
||||
<bool name="config_show_camera_laser_sensor">false</bool>
|
||||
|
||||
<!-- Whether to show logical camera default switch in Developer Options -->
|
||||
<bool name="config_show_logical_camera_default">false</bool>
|
||||
|
||||
<!-- Whether to show Connected MAC Randomization in Developer Options
|
||||
as not all devices can support dynamic MAC address change. -->
|
||||
<bool name="config_wifi_support_connected_mac_randomization">false</bool>
|
||||
@@ -131,4 +134,7 @@
|
||||
<!-- List of a11y components on the device allowed to be enabled by Settings Slices -->
|
||||
<string-array name="config_settings_slices_accessibility_components" translatable="false"/>
|
||||
|
||||
<!-- Whether or not to show the night light suggestion. -->
|
||||
<bool name="config_night_light_suggestion_enabled">true</bool>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -402,6 +402,17 @@
|
||||
<!-- Summary for bluetooth item in connection detail page. (phone)-->
|
||||
<string name="bluetooth_pref_summary" product="default">Allow your phone to communicate with nearby Bluetooth devices</string>
|
||||
|
||||
<!-- UI debug setting: Disable Bluetooth A2DP hardware offload [CHAR LIMIT=40] -->
|
||||
<string name="bluetooth_disable_a2dp_hw_offload">Disable Bluetooth A2DP hardware offload</string>
|
||||
<!-- UI debug setting: Disable Bluetooth A2DP hardware offload [CHAR LIMIT=20] -->
|
||||
<string name="bluetooth_disable_a2dp_hw_offload_dialog_title">Restart Device?</string>
|
||||
<!-- UI debug setting: Disable Bluetooth A2DP hardware offload [CHAR LIMIT=60] -->
|
||||
<string name="bluetooth_disable_a2dp_hw_offload_dialog_message">You need to restart your device to change this setting.</string>
|
||||
<!-- UI debug setting: Disable Bluetooth A2DP hardware offload [CHAR LIMIT=10] -->
|
||||
<string name="bluetooth_disable_a2dp_hw_offload_dialog_confirm">Restart</string>
|
||||
<!-- UI debug setting: Disable Bluetooth A2DP hardware offload [CHAR LIMIT=10] -->
|
||||
<string name="bluetooth_disable_a2dp_hw_offload_dialog_cancel">Cancel</string>
|
||||
|
||||
<!-- Title for Bluetooth device group with media capability group [CHAR LIMIT=none]-->
|
||||
<string name="connected_device_available_media_title">Available media devices</string>
|
||||
<!-- Title for Bluetooth device group with media capability group [CHAR LIMIT=none]-->
|
||||
@@ -9113,6 +9124,9 @@
|
||||
<!-- Title for Camera laser sensor switch [CHAR LIMIT=NONE] -->
|
||||
<string name="camera_laser_sensor_switch">Camera Laser Sensor</string>
|
||||
|
||||
<!-- Title for logical camera default switch [CHAR LIMIT=NONE] -->
|
||||
<string name="logical_camera_default_switch">Logical Camera As Default</string>
|
||||
|
||||
<!-- Title of the setting to disable the automatic update -->
|
||||
<string name="ota_disable_automatic_update">Automatic system updates</string>
|
||||
|
||||
|
||||
@@ -200,6 +200,7 @@
|
||||
<item name="android:textAlignment">viewStart</item>
|
||||
<item name="android:textAppearance">@android:style/TextAppearance.Material.Subhead</item>
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
<item name="android:minHeight">@dimen/min_tap_target_size</item>
|
||||
</style>
|
||||
|
||||
<style name="wifi_item_spinner" parent="wifi_item_content">
|
||||
@@ -219,6 +220,7 @@
|
||||
<item name="android:layout_marginStart">4dip</item>
|
||||
<item name="android:textSize">18sp</item>
|
||||
<item name="android:textAlignment">viewStart</item>
|
||||
<item name="android:minHeight">@dimen/min_tap_target_size</item>
|
||||
</style>
|
||||
|
||||
<style name="wifi_section">
|
||||
@@ -285,6 +287,7 @@
|
||||
<item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
<item name="android:textAlignment">viewStart</item>
|
||||
<item name="android:minHeight">@dimen/min_tap_target_size</item>
|
||||
</style>
|
||||
|
||||
<style name="vpn_warning">
|
||||
|
||||
@@ -284,6 +284,7 @@
|
||||
<style name="Widget.SwitchBar.Switch" parent="@android:style/Widget.Material.CompoundButton.Switch">
|
||||
<item name="android:trackTint">@color/switchbar_switch_track_tint</item>
|
||||
<item name="android:thumbTint">@color/switchbar_switch_thumb_tint</item>
|
||||
<item name="android:minHeight">@dimen/min_tap_target_size</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.CryptKeeper" parent="@android:style/Theme.Material.NoActionBar">
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/bluetooth_pairing_pref_title">
|
||||
|
||||
<Preference
|
||||
android:key="bt_pair_rename_devices"
|
||||
android:title="@string/bluetooth_device_name"
|
||||
android:summary="@string/summary_placeholder" />
|
||||
android:summary="@string/summary_placeholder"
|
||||
settings:controller="com.android.settings.bluetooth.BluetoothDeviceRenamePreferenceController"/>
|
||||
|
||||
<com.android.settings.bluetooth.BluetoothProgressCategory
|
||||
android:key="available_devices"
|
||||
|
||||
@@ -19,6 +19,12 @@
|
||||
android:key="bluetooth_switchbar_screen"
|
||||
android:title="@string/bluetooth_settings_title">
|
||||
|
||||
<Preference
|
||||
android:key="bluetooth_screen_bt_pair_rename_devices"
|
||||
android:title="@string/bluetooth_device_name"
|
||||
android:summary="@string/summary_placeholder"
|
||||
settings:controller="com.android.settings.bluetooth.BluetoothDeviceRenamePreferenceController"/>
|
||||
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
android:key="bluetooth_screen_add_bt_devices"
|
||||
android:title="@string/bluetooth_pairing_pref_title"
|
||||
|
||||
@@ -46,26 +46,13 @@
|
||||
android:title="@string/connected_device_previously_connected_title"
|
||||
android:icon="@drawable/ic_devices_other_black"
|
||||
android:fragment="com.android.settings.connecteddevice.PreviouslyConnectedDeviceDashboardFragment"
|
||||
settings:allowDividerAbove="true"/>
|
||||
|
||||
<Preference
|
||||
android:fragment="com.android.settings.connecteddevice.BluetoothDashboardFragment"
|
||||
android:key="bluetooth_settings"
|
||||
android:title="@string/bluetooth_settings_title"
|
||||
android:icon="@drawable/ic_settings_bluetooth"/>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="dashboard_tile_placeholder" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="toggle_nfc"
|
||||
android:title="@string/nfc_quick_toggle_title"
|
||||
android:icon="@drawable/ic_nfc"
|
||||
android:summary="@string/nfc_quick_toggle_summary"/>
|
||||
settings:allowDividerAbove="true"
|
||||
settings:controller="com.android.settings.connecteddevice.PreviouslyConnectedDevicePreferenceController"/>
|
||||
|
||||
<Preference
|
||||
android:key="connection_preferences"
|
||||
android:title="@string/connected_device_connections_title"
|
||||
android:fragment="com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment"/>
|
||||
android:fragment="com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment"
|
||||
settings:controller="com.android.settings.connecteddevice.AdvancedConnectedDeviceController"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -20,12 +20,26 @@
|
||||
android:key="connected_devices_advanced_screen"
|
||||
android:title="@string/connected_device_connections_title">
|
||||
|
||||
<Preference
|
||||
android:fragment="com.android.settings.connecteddevice.BluetoothDashboardFragment"
|
||||
android:key="bluetooth_settings"
|
||||
android:title="@string/bluetooth_settings_title"
|
||||
android:icon="@drawable/ic_settings_bluetooth"
|
||||
android:order="-9"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="toggle_nfc"
|
||||
android:title="@string/nfc_quick_toggle_title"
|
||||
android:icon="@drawable/ic_nfc"
|
||||
android:summary="@string/nfc_quick_toggle_summary"
|
||||
android:order="-7"/>
|
||||
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
android:fragment="com.android.settings.nfc.AndroidBeam"
|
||||
android:key="android_beam_settings"
|
||||
android:title="@string/android_beam_settings_title"
|
||||
android:icon="@drawable/ic_android"
|
||||
android:order="-4"/>
|
||||
android:order="-6"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="bluetooth_on_while_driving"
|
||||
@@ -33,7 +47,7 @@
|
||||
android:icon="@drawable/ic_settings_bluetooth"
|
||||
android:summary="@string/bluetooth_on_while_driving_summary"
|
||||
settings:controller="com.android.settings.connecteddevice.BluetoothOnWhileDrivingPreferenceController"
|
||||
android:order="-2"/>
|
||||
android:order="-4"/>
|
||||
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
android:key="connected_device_printing"
|
||||
@@ -41,7 +55,7 @@
|
||||
android:summary="@string/summary_placeholder"
|
||||
android:icon="@drawable/ic_settings_print"
|
||||
android:fragment="com.android.settings.print.PrintSettingsFragment"
|
||||
android:order="-1"/>
|
||||
android:order="-3"/>
|
||||
|
||||
<Preference
|
||||
android:key="bt_received_files"
|
||||
@@ -50,6 +64,6 @@
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="dashboard_tile_placeholder"
|
||||
android:order="50"/>
|
||||
android:order="-8"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -192,6 +192,10 @@
|
||||
android:key="camera_laser_sensor_switch"
|
||||
android:title="@string/camera_laser_sensor_switch" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="logical_camera_default_switch"
|
||||
android:title="@string/logical_camera_default_switch" />
|
||||
|
||||
<Preference
|
||||
android:key="feature_flags_dashboard"
|
||||
android:title="@string/feature_flags_dashboard_title"
|
||||
@@ -254,6 +258,10 @@
|
||||
android:title="@string/bluetooth_disable_absolute_volume"
|
||||
android:summary="@string/bluetooth_disable_absolute_volume_summary" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="bluetooth_disable_a2dp_hw_offload"
|
||||
android:title="@string/bluetooth_disable_a2dp_hw_offload" />
|
||||
|
||||
<ListPreference
|
||||
android:key="bluetooth_select_avrcp_version"
|
||||
android:title="@string/bluetooth_select_avrcp_version_string"
|
||||
|
||||
@@ -109,8 +109,7 @@
|
||||
android:dialogTitle="@string/ringtone_title"
|
||||
android:summary="@string/summary_placeholder"
|
||||
android:ringtoneType="ringtone"
|
||||
android:order="-100"
|
||||
settings:allowDividerAbove="true"/>
|
||||
android:order="-100"/>
|
||||
|
||||
<!-- Default notification ringtone -->
|
||||
<com.android.settings.DefaultRingtonePreference
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
android:key="forget_vpn"
|
||||
android:title="@string/vpn_forget_long"
|
||||
android:icon="@drawable/ic_menu_delete"
|
||||
android:icon="@drawable/ic_delete"
|
||||
settings:userRestriction="no_config_vpn"
|
||||
settings:useAdminDisabledSummary="true" />
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -19,13 +19,20 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/wifi_hotspot_checkbox_text"
|
||||
settings:initialExpandedChildrenCount="2">
|
||||
settings:initialExpandedChildrenCount="3">
|
||||
|
||||
<com.android.settings.widget.ValidatedEditTextPreference
|
||||
android:key="wifi_tether_network_name"
|
||||
android:title="@string/wifi_hotspot_name_title"
|
||||
android:summary="@string/summary_placeholder" />
|
||||
|
||||
<ListPreference
|
||||
android:key="wifi_tether_security"
|
||||
android:title="@string/wifi_security"
|
||||
android:summary="@string/summary_placeholder"
|
||||
android:entries="@array/wifi_tether_security"
|
||||
android:entryValues="@array/wifi_tether_security_values" />
|
||||
|
||||
<com.android.settings.widget.ValidatedEditTextPreference
|
||||
android:key="wifi_tether_network_password"
|
||||
android:persistent="false"
|
||||
@@ -34,7 +41,7 @@
|
||||
<SwitchPreference
|
||||
android:key="wifi_tether_auto_turn_off"
|
||||
android:title="@string/wifi_hotspot_auto_off_title"
|
||||
android:summary="@string/wifi_hotspot_auto_off_summary"/>
|
||||
android:summary="@string/wifi_hotspot_auto_off_summary" />
|
||||
|
||||
<com.android.settings.widget.HotspotApBandSelectionPreference
|
||||
android:key="wifi_tether_network_ap_band"
|
||||
@@ -42,5 +49,5 @@
|
||||
android:dialogLayout="@layout/hotspot_ap_band_selection_dialog"
|
||||
android:dialogTitle="@string/wifi_hotspot_ap_band_title"
|
||||
android:negativeButtonText="@string/cancel"
|
||||
android:positiveButtonText="@string/apply"/>
|
||||
android:positiveButtonText="@string/apply" />
|
||||
</PreferenceScreen>
|
||||
@@ -361,7 +361,7 @@ public class AccountPreferenceController extends AbstractPreferenceController
|
||||
RestrictedPreference preference = new RestrictedPreference(
|
||||
mParent.getPreferenceManager().getContext());
|
||||
preference.setTitle(R.string.remove_managed_profile_label);
|
||||
preference.setIcon(R.drawable.ic_menu_delete);
|
||||
preference.setIcon(R.drawable.ic_delete);
|
||||
preference.setOnPreferenceClickListener(this);
|
||||
preference.setOrder(ORDER_LAST);
|
||||
return preference;
|
||||
|
||||
@@ -32,7 +32,6 @@ import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStart;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||
@@ -44,16 +43,16 @@ public class BluetoothDeviceNamePreferenceController extends BasePreferenceContr
|
||||
LifecycleObserver, OnStart, OnStop {
|
||||
private static final String TAG = "BluetoothNamePrefCtrl";
|
||||
|
||||
public static final String KEY_DEVICE_NAME = "device_name";
|
||||
|
||||
|
||||
@VisibleForTesting
|
||||
Preference mPreference;
|
||||
private LocalBluetoothManager mLocalManager;
|
||||
private LocalBluetoothAdapter mLocalAdapter;
|
||||
|
||||
public BluetoothDeviceNamePreferenceController(Context context, Lifecycle lifecycle) {
|
||||
this(context, (LocalBluetoothAdapter) null);
|
||||
/**
|
||||
* Constructor exclusively used for Slice.
|
||||
*/
|
||||
public BluetoothDeviceNamePreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
|
||||
mLocalManager = Utils.getLocalBtManager(context);
|
||||
if (mLocalManager == null) {
|
||||
@@ -61,22 +60,12 @@ public class BluetoothDeviceNamePreferenceController extends BasePreferenceContr
|
||||
return;
|
||||
}
|
||||
mLocalAdapter = mLocalManager.getBluetoothAdapter();
|
||||
|
||||
if (lifecycle != null) {
|
||||
lifecycle.addObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor exclusively used for Slice.
|
||||
*/
|
||||
public BluetoothDeviceNamePreferenceController(Context context) {
|
||||
this(context, (Lifecycle) null);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
BluetoothDeviceNamePreferenceController(Context context, LocalBluetoothAdapter localAdapter) {
|
||||
super(context, KEY_DEVICE_NAME);
|
||||
BluetoothDeviceNamePreferenceController(Context context, LocalBluetoothAdapter localAdapter,
|
||||
String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mLocalAdapter = localAdapter;
|
||||
}
|
||||
|
||||
@@ -102,11 +91,6 @@ public class BluetoothDeviceNamePreferenceController extends BasePreferenceContr
|
||||
return mLocalAdapter != null ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_DEVICE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
updateDeviceName(preference);
|
||||
@@ -134,7 +118,7 @@ public class BluetoothDeviceNamePreferenceController extends BasePreferenceContr
|
||||
public Preference createBluetoothDeviceNamePreference(PreferenceScreen screen, int order) {
|
||||
mPreference = new Preference(screen.getContext());
|
||||
mPreference.setOrder(order);
|
||||
mPreference.setKey(KEY_DEVICE_NAME);
|
||||
mPreference.setKey(getPreferenceKey());
|
||||
screen.addPreference(mPreference);
|
||||
|
||||
return mPreference;
|
||||
|
||||
@@ -26,44 +26,35 @@ import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
public class BluetoothDeviceRenamePreferenceController extends
|
||||
BluetoothDeviceNamePreferenceController {
|
||||
|
||||
private final Fragment mFragment;
|
||||
private String mPrefKey;
|
||||
private Fragment mFragment;
|
||||
private MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
|
||||
public BluetoothDeviceRenamePreferenceController(Context context, String prefKey,
|
||||
Fragment fragment, Lifecycle lifecycle) {
|
||||
super(context, lifecycle);
|
||||
mPrefKey = prefKey;
|
||||
mFragment = fragment;
|
||||
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor exclusively used for Slice.
|
||||
*/
|
||||
public BluetoothDeviceRenamePreferenceController(Context context, String prefKey) {
|
||||
super(context, (Lifecycle) null);
|
||||
mPrefKey = prefKey;
|
||||
mFragment = null;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
BluetoothDeviceRenamePreferenceController(Context context, String prefKey, Fragment fragment,
|
||||
LocalBluetoothAdapter localAdapter) {
|
||||
super(context, localAdapter);
|
||||
mPrefKey = prefKey;
|
||||
mFragment = fragment;
|
||||
public BluetoothDeviceRenamePreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return mPrefKey;
|
||||
@VisibleForTesting
|
||||
BluetoothDeviceRenamePreferenceController(Context context, LocalBluetoothAdapter localAdapter,
|
||||
String preferenceKey) {
|
||||
super(context, localAdapter, preferenceKey);
|
||||
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link Fragment} that used to show {@link LocalDeviceNameDialogFragment}
|
||||
* in {@code handlePreferenceTreeClick}
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public void setFragment(Fragment fragment) {
|
||||
mFragment = fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,7 +69,7 @@ public class BluetoothDeviceRenamePreferenceController extends
|
||||
|
||||
@Override
|
||||
public boolean handlePreferenceTreeClick(Preference preference) {
|
||||
if (TextUtils.equals(mPrefKey, preference.getKey()) && mFragment != null) {
|
||||
if (TextUtils.equals(getPreferenceKey(), preference.getKey()) && mFragment != null) {
|
||||
mMetricsFeatureProvider.action(mContext,
|
||||
MetricsProto.MetricsEvent.ACTION_BLUETOOTH_RENAME);
|
||||
LocalDeviceNameDialogFragment.newInstance()
|
||||
|
||||
@@ -30,12 +30,8 @@ import com.android.settings.R;
|
||||
import com.android.settings.search.Indexable;
|
||||
import com.android.settingslib.bluetooth.BluetoothDeviceFilter;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.widget.FooterPreference;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* BluetoothPairingDetail is a page to scan bluetooth devices and pair them.
|
||||
*/
|
||||
@@ -47,7 +43,6 @@ public class BluetoothPairingDetail extends DeviceListPreferenceFragment impleme
|
||||
static final String KEY_AVAIL_DEVICES = "available_devices";
|
||||
@VisibleForTesting
|
||||
static final String KEY_FOOTER_PREF = "footer_preference";
|
||||
private static final String KEY_RENAME_DEVICES = "bt_pair_rename_devices";
|
||||
|
||||
@VisibleForTesting
|
||||
BluetoothProgressCategory mAvailableDevicesCategory;
|
||||
@@ -80,6 +75,12 @@ public class BluetoothPairingDetail extends DeviceListPreferenceFragment impleme
|
||||
mAvailableDevicesCategory.setProgress(mLocalAdapter.isDiscovering());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
use(BluetoothDeviceRenamePreferenceController.class).setFragment(this);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void updateBluetooth() {
|
||||
if (mLocalAdapter.isEnabled()) {
|
||||
@@ -199,16 +200,6 @@ public class BluetoothPairingDetail extends DeviceListPreferenceFragment impleme
|
||||
return R.xml.bluetooth_pairing_detail;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||
final List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(
|
||||
new BluetoothDeviceRenamePreferenceController(context, KEY_RENAME_DEVICES, this,
|
||||
getLifecycle()));
|
||||
|
||||
return controllers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceListKey() {
|
||||
return KEY_AVAIL_DEVICES;
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
package com.android.settings.connecteddevice;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.nfc.NfcPreferenceController;
|
||||
|
||||
/**
|
||||
* Controller that used to show which component is available
|
||||
*/
|
||||
public class AdvancedConnectedDeviceController extends BasePreferenceController {
|
||||
|
||||
public AdvancedConnectedDeviceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
return mContext.getText(getConnectedDevicesSummaryResourceId(mContext));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Connected Devices summary that depend on {@link NfcPreferenceController} or
|
||||
* diving mode are available
|
||||
*/
|
||||
public static int getConnectedDevicesSummaryResourceId(Context context) {
|
||||
final NfcPreferenceController nfcPreferenceController =
|
||||
new NfcPreferenceController(context);
|
||||
final boolean isDrivingModeAvailable = false;
|
||||
|
||||
return getConnectedDevicesSummaryResourceId(nfcPreferenceController,
|
||||
isDrivingModeAvailable);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static int getConnectedDevicesSummaryResourceId(NfcPreferenceController
|
||||
nfcPreferenceController, boolean isDrivingModeAvailable) {
|
||||
final int resId;
|
||||
|
||||
if (nfcPreferenceController.isAvailable()) {
|
||||
if (isDrivingModeAvailable) {
|
||||
// NFC available, driving mode available
|
||||
resId = R.string.connected_devices_dashboard_summary;
|
||||
} else {
|
||||
// NFC available, driving mode not available
|
||||
resId = R.string.connected_devices_dashboard_no_driving_mode_summary;
|
||||
}
|
||||
} else {
|
||||
if (isDrivingModeAvailable) {
|
||||
// NFC not available, driving mode available
|
||||
resId = R.string.connected_devices_dashboard_no_nfc_summary;
|
||||
} else {
|
||||
// NFC not available, driving mode not available
|
||||
resId = R.string.connected_devices_dashboard_no_driving_mode_no_nfc_summary;
|
||||
}
|
||||
}
|
||||
|
||||
return resId;
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import com.android.settings.R;
|
||||
import com.android.settings.bluetooth.BluetoothFilesPreferenceController;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.nfc.AndroidBeamPreferenceController;
|
||||
import com.android.settings.nfc.NfcPreferenceController;
|
||||
import com.android.settings.print.PrintSettingPreferenceController;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
@@ -78,10 +79,16 @@ public class AdvancedConnectedDeviceDashboardFragment extends DashboardFragment
|
||||
|
||||
final PrintSettingPreferenceController printerController =
|
||||
new PrintSettingPreferenceController(context);
|
||||
final NfcPreferenceController nfcPreferenceController =
|
||||
new NfcPreferenceController(context);
|
||||
|
||||
if (lifecycle != null) {
|
||||
lifecycle.addObserver(beamPreferenceController);
|
||||
lifecycle.addObserver(printerController);
|
||||
lifecycle.addObserver(nfcPreferenceController);
|
||||
}
|
||||
|
||||
controllers.add(nfcPreferenceController);
|
||||
controllers.add(printerController);
|
||||
|
||||
return controllers;
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.support.annotation.VisibleForTesting;
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.bluetooth.BluetoothDeviceRenamePreferenceController;
|
||||
import com.android.settings.bluetooth.BluetoothSwitchPreferenceController;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
@@ -78,6 +79,12 @@ public class BluetoothDashboardFragment extends DashboardFragment {
|
||||
mFooterPreference = mFooterPreferenceMixin.createFooterPreference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
use(BluetoothDeviceRenamePreferenceController.class).setFragment(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
@@ -26,10 +26,7 @@ import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.dashboard.SummaryLoader;
|
||||
import com.android.settings.nfc.NfcPreferenceController;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -62,30 +59,12 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment {
|
||||
return R.xml.connected_devices;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||
return buildPreferenceControllers(context, getLifecycle());
|
||||
}
|
||||
|
||||
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
|
||||
Lifecycle lifecycle) {
|
||||
final List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
final NfcPreferenceController nfcPreferenceController =
|
||||
new NfcPreferenceController(context);
|
||||
controllers.add(nfcPreferenceController);
|
||||
|
||||
if (lifecycle != null) {
|
||||
lifecycle.addObserver(nfcPreferenceController);
|
||||
}
|
||||
|
||||
return controllers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
use(AvailableMediaDeviceGroupController.class).init(this);
|
||||
use(ConnectedDeviceGroupController.class).init(this);
|
||||
use(PreviouslyConnectedDevicePreferenceController.class).init(this);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -138,12 +117,6 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment {
|
||||
return Arrays.asList(sir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AbstractPreferenceController> createPreferenceControllers(Context
|
||||
context) {
|
||||
return buildPreferenceControllers(context, null /* lifecycle */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNonIndexableKeys(Context context) {
|
||||
List<String> keys = super.getNonIndexableKeys(context);
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.connecteddevice;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import android.util.Log;
|
||||
import com.android.settings.bluetooth.BluetoothDeviceUpdater;
|
||||
import com.android.settings.bluetooth.SavedBluetoothDeviceUpdater;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStart;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
public class PreviouslyConnectedDevicePreferenceController extends BasePreferenceController
|
||||
implements LifecycleObserver, OnStart, OnStop, DevicePreferenceCallback {
|
||||
|
||||
private Preference mPreference;
|
||||
private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
|
||||
private int mPreferenceSize;
|
||||
|
||||
public PreviouslyConnectedDevicePreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
|
||||
? AVAILABLE
|
||||
: CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
if (isAvailable()) {
|
||||
mPreference = screen.findPreference(getPreferenceKey());
|
||||
mBluetoothDeviceUpdater.setPrefContext(screen.getContext());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
mBluetoothDeviceUpdater.registerCallback();
|
||||
updatePreferenceOnSizeChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
mBluetoothDeviceUpdater.unregisterCallback();
|
||||
}
|
||||
|
||||
public void init(DashboardFragment fragment) {
|
||||
mBluetoothDeviceUpdater = new SavedBluetoothDeviceUpdater(fragment.getContext(),
|
||||
fragment, PreviouslyConnectedDevicePreferenceController.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceAdded(Preference preference) {
|
||||
mPreferenceSize++;
|
||||
updatePreferenceOnSizeChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceRemoved(Preference preference) {
|
||||
mPreferenceSize--;
|
||||
updatePreferenceOnSizeChanged();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setBluetoothDeviceUpdater(BluetoothDeviceUpdater bluetoothDeviceUpdater) {
|
||||
mBluetoothDeviceUpdater = bluetoothDeviceUpdater;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setPreferenceSize(int size) {
|
||||
mPreferenceSize = size;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setPreference(Preference preference) {
|
||||
mPreference = preference;
|
||||
}
|
||||
|
||||
private void updatePreferenceOnSizeChanged() {
|
||||
if (isAvailable()) {
|
||||
mPreference.setEnabled(mPreferenceSize != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ package com.android.settings.core;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.content.Context;
|
||||
import android.content.IntentFilter;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -220,6 +221,14 @@ public abstract class BasePreferenceController extends AbstractPreferenceControl
|
||||
return SliceData.SliceType.INTENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an {@link IntentFilter} that includes all broadcasts which can affect the state of
|
||||
* this Setting.
|
||||
*/
|
||||
public IntentFilter getIntentFilter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates non-indexable keys for search provider.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.development;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.SystemProperties;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
|
||||
|
||||
public class BluetoothA2dpHwOffloadPreferenceController extends DeveloperOptionsPreferenceController
|
||||
implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
|
||||
|
||||
private static final String PREFERENCE_KEY = "bluetooth_disable_a2dp_hw_offload";
|
||||
private final DevelopmentSettingsDashboardFragment mFragment;
|
||||
|
||||
static final String A2DP_OFFLOAD_DISABLED_PROPERTY = "persist.bluetooth.a2dp_offload.disabled";
|
||||
static final String A2DP_OFFLOAD_SUPPORTED_PROPERTY = "ro.bluetooth.a2dp_offload.supported";
|
||||
|
||||
public BluetoothA2dpHwOffloadPreferenceController(Context context,
|
||||
DevelopmentSettingsDashboardFragment fragment) {
|
||||
super(context);
|
||||
mFragment = fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return PREFERENCE_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
BluetoothA2dpHwOffloadRebootDialog.show(mFragment, this);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
final boolean offloadSupported =
|
||||
SystemProperties.getBoolean(A2DP_OFFLOAD_SUPPORTED_PROPERTY, false);
|
||||
if (offloadSupported) {
|
||||
final boolean offloadDisabled =
|
||||
SystemProperties.getBoolean(A2DP_OFFLOAD_DISABLED_PROPERTY, false);
|
||||
((SwitchPreference) mPreference).setChecked(offloadDisabled);
|
||||
} else {
|
||||
mPreference.setEnabled(false);
|
||||
((SwitchPreference) mPreference).setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeveloperOptionsSwitchDisabled() {
|
||||
super.onDeveloperOptionsSwitchDisabled();
|
||||
((SwitchPreference) mPreference).setChecked(true);
|
||||
SystemProperties.set(A2DP_OFFLOAD_DISABLED_PROPERTY, "true");
|
||||
}
|
||||
|
||||
public void onA2dpHwDialogConfirmed() {
|
||||
final boolean offloadDisabled =
|
||||
SystemProperties.getBoolean(A2DP_OFFLOAD_DISABLED_PROPERTY, false);
|
||||
SystemProperties.set(A2DP_OFFLOAD_DISABLED_PROPERTY, Boolean.toString(!offloadDisabled));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.development;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.FragmentManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
|
||||
public class BluetoothA2dpHwOffloadRebootDialog extends InstrumentedDialogFragment
|
||||
implements DialogInterface.OnClickListener {
|
||||
|
||||
public static final String TAG = "BluetoothA2dpHwOffloadReboot";
|
||||
|
||||
public static void show(DevelopmentSettingsDashboardFragment host,
|
||||
BluetoothA2dpHwOffloadPreferenceController controller) {
|
||||
final FragmentManager manager = host.getActivity().getFragmentManager();
|
||||
if (manager.findFragmentByTag(TAG) == null) {
|
||||
final BluetoothA2dpHwOffloadRebootDialog dialog =
|
||||
new BluetoothA2dpHwOffloadRebootDialog();
|
||||
dialog.setTargetFragment(host, 0 /* requestCode */);
|
||||
dialog.show(manager, TAG);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsProto.MetricsEvent.DIALOG_BLUETOOTH_DISABLE_A2DP_HW_OFFLOAD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setMessage(R.string.bluetooth_disable_a2dp_hw_offload_dialog_message)
|
||||
.setTitle(R.string.bluetooth_disable_a2dp_hw_offload_dialog_title)
|
||||
.setPositiveButton(
|
||||
R.string.bluetooth_disable_a2dp_hw_offload_dialog_confirm, this)
|
||||
.setNegativeButton(
|
||||
R.string.bluetooth_disable_a2dp_hw_offload_dialog_cancel, this)
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
final OnA2dpHwDialogConfirmedListener host =
|
||||
(OnA2dpHwDialogConfirmedListener) getTargetFragment();
|
||||
if (host == null) {
|
||||
return;
|
||||
}
|
||||
if (which == DialogInterface.BUTTON_POSITIVE) {
|
||||
host.onA2dpHwDialogConfirmed();
|
||||
PowerManager pm = getContext().getSystemService(PowerManager.class);
|
||||
pm.reboot(null);
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnA2dpHwDialogConfirmedListener {
|
||||
/**
|
||||
* Called when the user presses reboot on the warning dialog.
|
||||
*/
|
||||
void onA2dpHwDialogConfirmed();
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,8 @@ import java.util.List;
|
||||
|
||||
public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFragment
|
||||
implements SwitchBar.OnSwitchChangeListener, OemUnlockDialogHost, AdbDialogHost,
|
||||
AdbClearKeysDialogHost, LogPersistDialogHost {
|
||||
AdbClearKeysDialogHost, LogPersistDialogHost,
|
||||
BluetoothA2dpHwOffloadRebootDialog.OnA2dpHwDialogConfirmedListener {
|
||||
|
||||
private static final String TAG = "DevSettingsDashboard";
|
||||
|
||||
@@ -269,6 +270,13 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
controller.onDisableLogPersistDialogRejected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onA2dpHwDialogConfirmed() {
|
||||
final BluetoothA2dpHwOffloadPreferenceController controller =
|
||||
getDevelopmentOptionsController(BluetoothA2dpHwOffloadPreferenceController.class);
|
||||
controller.onA2dpHwDialogConfirmed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
boolean handledResult = false;
|
||||
@@ -397,6 +405,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
controllers.add(new LogPersistPreferenceController(context, fragment, lifecycle));
|
||||
controllers.add(new ConnectivityMonitorPreferenceController(context));
|
||||
controllers.add(new CameraLaserSensorPreferenceController(context));
|
||||
controllers.add(new LogicalCameraDefaultPreferenceController(context));
|
||||
controllers.add(new WifiDisplayCertificationPreferenceController(context));
|
||||
controllers.add(new WifiVerboseLoggingPreferenceController(context));
|
||||
controllers.add(new WifiConnectedMacRandomizationPreferenceController(context));
|
||||
@@ -405,6 +414,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
controllers.add(new BluetoothDeviceNoNamePreferenceController(context));
|
||||
controllers.add(new BluetoothAbsoluteVolumePreferenceController(context));
|
||||
controllers.add(new BluetoothAvrcpVersionPreferenceController(context));
|
||||
controllers.add(new BluetoothA2dpHwOffloadPreferenceController(context, fragment));
|
||||
controllers.add(new BluetoothAudioCodecPreferenceController(context, lifecycle,
|
||||
bluetoothA2dpConfigStore));
|
||||
controllers.add(new BluetoothAudioSampleRatePreferenceController(context, lifecycle,
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.development;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.SystemProperties;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
|
||||
|
||||
public class LogicalCameraDefaultPreferenceController extends DeveloperOptionsPreferenceController
|
||||
implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
|
||||
|
||||
private static final String KEY_LOGICAL_CAMERA_DEFAULT_SWITCH = "logical_camera_default_switch";
|
||||
@VisibleForTesting
|
||||
static final String BUILD_TYPE = "ro.build.type";
|
||||
@VisibleForTesting
|
||||
static final String PROPERTY_LOGICAL_CAMERA_DEFAULT = "persist.camera.logical.default";
|
||||
@VisibleForTesting
|
||||
static final int ENABLED = 1;
|
||||
@VisibleForTesting
|
||||
static final int DISABLED = 0;
|
||||
@VisibleForTesting
|
||||
static final String USERDEBUG_BUILD = "userdebug";
|
||||
@VisibleForTesting
|
||||
static final String ENG_BUILD = "eng";
|
||||
@VisibleForTesting
|
||||
static final String USER_BUILD = "user";
|
||||
|
||||
public LogicalCameraDefaultPreferenceController(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mContext.getResources().getBoolean(R.bool.config_show_logical_camera_default);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_LOGICAL_CAMERA_DEFAULT_SWITCH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final boolean isEnabled = (Boolean) newValue;
|
||||
String value = Integer.toString(isEnabled ? ENABLED : DISABLED);
|
||||
SystemProperties.set(PROPERTY_LOGICAL_CAMERA_DEFAULT, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
final boolean enabled = isLogicalCameraDefault();
|
||||
((SwitchPreference) mPreference).setChecked(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeveloperOptionsSwitchDisabled() {
|
||||
super.onDeveloperOptionsSwitchDisabled();
|
||||
SystemProperties.set(PROPERTY_LOGICAL_CAMERA_DEFAULT, Integer.toString(DISABLED));
|
||||
((SwitchPreference) mPreference).setChecked(false);
|
||||
}
|
||||
|
||||
private boolean isLogicalCameraDefault() {
|
||||
final String prop = SystemProperties.get(PROPERTY_LOGICAL_CAMERA_DEFAULT,
|
||||
Integer.toString(DISABLED));
|
||||
return TextUtils.equals(Integer.toString(ENABLED), prop);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import android.content.Context;
|
||||
import com.android.internal.app.ColorDisplayController;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settings.R;
|
||||
|
||||
public class NightDisplayPreferenceController extends AbstractPreferenceController implements
|
||||
PreferenceControllerMixin {
|
||||
@@ -29,6 +30,12 @@ public class NightDisplayPreferenceController extends AbstractPreferenceControll
|
||||
}
|
||||
|
||||
public static boolean isSuggestionComplete(Context context) {
|
||||
final boolean isEnabled = context.getResources().getBoolean(
|
||||
R.bool.config_night_light_suggestion_enabled);
|
||||
// The suggestion is always complete if not enabled.
|
||||
if (!isEnabled) {
|
||||
return true;
|
||||
}
|
||||
final ColorDisplayController controller = new ColorDisplayController(context);
|
||||
return controller.getAutoMode() != ColorDisplayController.AUTO_MODE_DISABLED;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@ import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.anomaly.Anomaly;
|
||||
import com.android.settings.fuelgauge.batterytip.AnomalyInfo;
|
||||
import com.android.settings.fuelgauge.batterytip.StatsManagerConfig;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
|
||||
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
||||
@@ -511,10 +513,25 @@ public class BatteryUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPreOApp(final String[] packageNames) {
|
||||
if (ArrayUtils.isEmpty(packageNames)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String packageName : packageNames) {
|
||||
if (isPreOApp(packageName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if we should hide anomaly app represented by {@code uid}
|
||||
*/
|
||||
public boolean shouldHideAnomaly(PowerWhitelistBackend powerWhitelistBackend, int uid) {
|
||||
public boolean shouldHideAnomaly(PowerWhitelistBackend powerWhitelistBackend, int uid,
|
||||
AnomalyInfo anomalyInfo) {
|
||||
final String[] packageNames = mPackageManager.getPackagesForUid(uid);
|
||||
if (ArrayUtils.isEmpty(packageNames)) {
|
||||
// Don't show it if app has been uninstalled
|
||||
@@ -522,7 +539,13 @@ public class BatteryUtils {
|
||||
}
|
||||
|
||||
return isSystemUid(uid) || powerWhitelistBackend.isWhitelisted(packageNames)
|
||||
|| (isSystemApp(mPackageManager, packageNames) && !hasLauncherEntry(packageNames));
|
||||
|| (isSystemApp(mPackageManager, packageNames) && !hasLauncherEntry(packageNames))
|
||||
|| (isExcessiveBackgroundAnomaly(anomalyInfo) && !isPreOApp(packageNames));
|
||||
}
|
||||
|
||||
private boolean isExcessiveBackgroundAnomaly(AnomalyInfo anomalyInfo) {
|
||||
return anomalyInfo.anomalyType
|
||||
== StatsManagerConfig.AnomalyType.EXCESSIVE_BACKGROUND_SERVICE;
|
||||
}
|
||||
|
||||
private boolean isSystemUid(int uid) {
|
||||
|
||||
@@ -155,44 +155,36 @@ public class AnomalyDetectionJobService extends JobService {
|
||||
final String packageName = batteryUtils.getPackageName(uid);
|
||||
final long versionCode = batteryUtils.getAppLongVersionCode(packageName);
|
||||
|
||||
final boolean anomalyDetected;
|
||||
if (isExcessiveBackgroundAnomaly(anomalyInfo)) {
|
||||
anomalyDetected = batteryUtils.isPreOApp(packageName);
|
||||
if (batteryUtils.shouldHideAnomaly(powerWhitelistBackend, uid, anomalyInfo)) {
|
||||
metricsFeatureProvider.action(context,
|
||||
MetricsProto.MetricsEvent.ACTION_ANOMALY_IGNORED,
|
||||
packageName,
|
||||
Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT,
|
||||
anomalyInfo.anomalyType),
|
||||
Pair.create(MetricsProto.MetricsEvent.FIELD_APP_VERSION_CODE,
|
||||
versionCode));
|
||||
} else {
|
||||
anomalyDetected = true;
|
||||
if (autoFeatureOn && anomalyInfo.autoRestriction) {
|
||||
// Auto restrict this app
|
||||
batteryUtils.setForceAppStandby(uid, packageName,
|
||||
AppOpsManager.MODE_IGNORED);
|
||||
databaseManager.insertAnomaly(uid, packageName, anomalyInfo.anomalyType,
|
||||
AnomalyDatabaseHelper.State.AUTO_HANDLED,
|
||||
timeMs);
|
||||
} else {
|
||||
databaseManager.insertAnomaly(uid, packageName, anomalyInfo.anomalyType,
|
||||
AnomalyDatabaseHelper.State.NEW,
|
||||
timeMs);
|
||||
}
|
||||
metricsFeatureProvider.action(context,
|
||||
MetricsProto.MetricsEvent.ACTION_ANOMALY_TRIGGERED,
|
||||
packageName,
|
||||
Pair.create(MetricsProto.MetricsEvent.FIELD_ANOMALY_TYPE,
|
||||
anomalyInfo.anomalyType),
|
||||
Pair.create(MetricsProto.MetricsEvent.FIELD_APP_VERSION_CODE,
|
||||
versionCode));
|
||||
}
|
||||
|
||||
if (anomalyDetected) {
|
||||
if (batteryUtils.shouldHideAnomaly(powerWhitelistBackend, uid)) {
|
||||
metricsFeatureProvider.action(context,
|
||||
MetricsProto.MetricsEvent.ACTION_ANOMALY_IGNORED,
|
||||
packageName,
|
||||
Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT,
|
||||
anomalyInfo.anomalyType),
|
||||
Pair.create(MetricsProto.MetricsEvent.FIELD_APP_VERSION_CODE,
|
||||
versionCode));
|
||||
} else {
|
||||
if (autoFeatureOn && anomalyInfo.autoRestriction) {
|
||||
// Auto restrict this app
|
||||
batteryUtils.setForceAppStandby(uid, packageName,
|
||||
AppOpsManager.MODE_IGNORED);
|
||||
databaseManager.insertAnomaly(uid, packageName, anomalyInfo.anomalyType,
|
||||
AnomalyDatabaseHelper.State.AUTO_HANDLED,
|
||||
timeMs);
|
||||
} else {
|
||||
databaseManager.insertAnomaly(uid, packageName, anomalyInfo.anomalyType,
|
||||
AnomalyDatabaseHelper.State.NEW,
|
||||
timeMs);
|
||||
}
|
||||
metricsFeatureProvider.action(context,
|
||||
MetricsProto.MetricsEvent.ACTION_ANOMALY_TRIGGERED,
|
||||
packageName,
|
||||
Pair.create(MetricsProto.MetricsEvent.FIELD_ANOMALY_TYPE,
|
||||
anomalyInfo.anomalyType),
|
||||
Pair.create(MetricsProto.MetricsEvent.FIELD_APP_VERSION_CODE,
|
||||
versionCode));
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException | IndexOutOfBoundsException e) {
|
||||
Log.e(TAG, "Parse stats dimensions value error.", e);
|
||||
}
|
||||
@@ -229,11 +221,6 @@ public class AnomalyDetectionJobService extends JobService {
|
||||
return UID_NULL;
|
||||
}
|
||||
|
||||
private boolean isExcessiveBackgroundAnomaly(AnomalyInfo anomalyInfo) {
|
||||
return anomalyInfo.anomalyType
|
||||
== StatsManagerConfig.AnomalyType.EXCESSIVE_BACKGROUND_SERVICE;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
JobWorkItem dequeueWork(JobParameters parameters) {
|
||||
synchronized (mLock) {
|
||||
|
||||
@@ -103,6 +103,7 @@ public class RestrictAppTip extends BatteryTip {
|
||||
} else {
|
||||
mState = tip.getState();
|
||||
mShowDialog = tip.shouldShowDialog();
|
||||
mRestrictAppList = ((RestrictAppTip) tip).mRestrictAppList;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -721,7 +721,7 @@ public class ApnEditor extends SettingsPreferenceFragment
|
||||
// If it's a new APN, then cancel will delete the new entry in onPause
|
||||
if (!mNewApn && !mReadOnlyApn) {
|
||||
menu.add(0, MENU_DELETE, 0, R.string.menu_delete)
|
||||
.setIcon(R.drawable.ic_menu_delete);
|
||||
.setIcon(R.drawable.ic_delete);
|
||||
}
|
||||
menu.add(0, MENU_SAVE, 0, R.string.menu_save)
|
||||
.setIcon(android.R.drawable.ic_menu_save);
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package com.android.settings.notification;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.IntentFilter;
|
||||
import android.media.AudioManager;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.support.v7.preference.Preference;
|
||||
@@ -57,4 +59,12 @@ public abstract class AdjustVolumeRestrictedPreferenceController extends
|
||||
UserManager.DISALLOW_ADJUST_VOLUME, UserHandle.myUserId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntentFilter getIntentFilter() {
|
||||
final IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(AudioManager.VOLUME_CHANGED_ACTION);
|
||||
filter.addAction(AudioManager.STREAM_MUTE_CHANGED_ACTION);
|
||||
filter.addAction(AudioManager.MASTER_MUTE_CHANGED_ACTION);
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,16 +26,22 @@ import android.os.UserHandle;
|
||||
import android.preference.SeekBarVolumizer;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.ListPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.RingtonePreference;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.sound.HandsFreeProfileOutputPreferenceController;
|
||||
import com.android.settings.sound.MediaOutputPreferenceController;
|
||||
import com.android.settings.widget.PreferenceCategoryController;
|
||||
import com.android.settings.widget.UpdatableListPreferenceDialogFragment;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.core.instrumentation.Instrumentable;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -68,6 +74,9 @@ public class SoundSettings extends DashboardFragment {
|
||||
};
|
||||
|
||||
private RingtonePreference mRequestPreference;
|
||||
private UpdatableListPreferenceDialogFragment mDialogFragment;
|
||||
private String mMediaOutputControllerKey;
|
||||
private String mHfpOutputControllerKey;
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
@@ -82,6 +91,11 @@ public class SoundSettings extends DashboardFragment {
|
||||
if (!TextUtils.isEmpty(selectedPreference)) {
|
||||
mRequestPreference = (RingtonePreference) findPreference(selectedPreference);
|
||||
}
|
||||
|
||||
UpdatableListPreferenceDialogFragment dialogFragment =
|
||||
(UpdatableListPreferenceDialogFragment) getFragmentManager()
|
||||
.findFragmentByTag(TAG);
|
||||
mDialogFragment = dialogFragment;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +125,23 @@ public class SoundSettings extends DashboardFragment {
|
||||
return super.onPreferenceTreeClick(preference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayPreferenceDialog(Preference preference) {
|
||||
final int metricsCategory;
|
||||
if (mHfpOutputControllerKey.equals(preference.getKey())) {
|
||||
metricsCategory = MetricsProto.MetricsEvent.DIALOG_SWITCH_HFP_DEVICES;
|
||||
} else if (mMediaOutputControllerKey.equals(preference.getKey())) {
|
||||
metricsCategory = MetricsProto.MetricsEvent.DIALOG_SWITCH_A2DP_DEVICES;
|
||||
} else {
|
||||
metricsCategory = Instrumentable.METRICS_CATEGORY_UNKNOWN;
|
||||
}
|
||||
|
||||
mDialogFragment = UpdatableListPreferenceDialogFragment.
|
||||
newInstance(preference.getKey(), metricsCategory);
|
||||
mDialogFragment.setTargetFragment(this, 0);
|
||||
mDialogFragment.show(getFragmentManager(), TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLogTag() {
|
||||
return TAG;
|
||||
@@ -152,6 +183,14 @@ public class SoundSettings extends DashboardFragment {
|
||||
volumeControllers.add(use(NotificationVolumePreferenceController.class));
|
||||
volumeControllers.add(use(CallVolumePreferenceController.class));
|
||||
|
||||
use(MediaOutputPreferenceController.class).setCallback(listPreference ->
|
||||
onPreferenceDataChanged(listPreference));
|
||||
mMediaOutputControllerKey = use(MediaOutputPreferenceController.class).getPreferenceKey();
|
||||
use(HandsFreeProfileOutputPreferenceController.class).setCallback(listPreference ->
|
||||
onPreferenceDataChanged(listPreference));
|
||||
mHfpOutputControllerKey =
|
||||
use(HandsFreeProfileOutputPreferenceController.class).getPreferenceKey();
|
||||
|
||||
for (VolumeSeekBarPreferenceController controller : volumeControllers) {
|
||||
controller.setCallback(mVolumeCallback);
|
||||
getLifecycle().addObserver(controller);
|
||||
@@ -287,4 +326,10 @@ public class SoundSettings extends DashboardFragment {
|
||||
workSoundController.enableWorkSync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onPreferenceDataChanged(ListPreference preference) {
|
||||
if (mDialogFragment != null) {
|
||||
mDialogFragment.onListPreferenceUpdated(preference);
|
||||
}
|
||||
}
|
||||
}
|
||||
158
src/com/android/settings/notification/ZenModeSliceBuilder.java
Normal file
158
src/com/android/settings/notification/ZenModeSliceBuilder.java
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
|
||||
|
||||
import android.annotation.ColorInt;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.Uri;
|
||||
import android.provider.Settings;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SubSettings;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.search.DatabaseIndexingUtils;
|
||||
import com.android.settings.slices.SettingsSliceProvider;
|
||||
import com.android.settings.slices.SliceBroadcastReceiver;
|
||||
import com.android.settings.slices.SliceBuilderUtils;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.builders.ListBuilder;
|
||||
import androidx.slice.builders.SliceAction;
|
||||
|
||||
import android.support.v4.graphics.drawable.IconCompat;
|
||||
|
||||
public class ZenModeSliceBuilder {
|
||||
|
||||
private static final String TAG = "ZenModeSliceBuilder";
|
||||
|
||||
private static final String ZEN_MODE_KEY = "zen_mode";
|
||||
|
||||
/**
|
||||
* Backing Uri for the Zen Mode Slice.
|
||||
*/
|
||||
public static final Uri ZEN_MODE_URI = new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.appendPath(ZEN_MODE_KEY)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Action notifying a change on the Zen Mode Slice.
|
||||
*/
|
||||
public static final String ACTION_ZEN_MODE_SLICE_CHANGED =
|
||||
"com.android.settings.notification.ZEN_MODE_CHANGED";
|
||||
|
||||
public static final IntentFilter INTENT_FILTER = new IntentFilter();
|
||||
|
||||
static {
|
||||
INTENT_FILTER.addAction(NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED);
|
||||
INTENT_FILTER.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED);
|
||||
INTENT_FILTER.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL);
|
||||
}
|
||||
|
||||
private ZenModeSliceBuilder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a ZenMode Slice bound to {@link #ZEN_MODE_URI}.
|
||||
* <p>
|
||||
* Note that you should register a listener for {@link #INTENT_FILTER} to get changes for
|
||||
* ZenMode.
|
||||
*/
|
||||
public static Slice getSlice(Context context) {
|
||||
final boolean isZenModeEnabled = isZenModeEnabled(context);
|
||||
final CharSequence title = context.getText(R.string.zen_mode_settings_title);
|
||||
@ColorInt final int color = Utils.getColorAccent(context);
|
||||
final PendingIntent toggleAction = getBroadcastIntent(context);
|
||||
final PendingIntent primaryAction = getPrimaryAction(context);
|
||||
final SliceAction primarySliceAction = new SliceAction(primaryAction,
|
||||
(IconCompat) null /* icon */, title);
|
||||
final SliceAction toggleSliceAction = new SliceAction(toggleAction, null /* actionTitle */,
|
||||
isZenModeEnabled);
|
||||
|
||||
return new ListBuilder(context, ZEN_MODE_URI, ListBuilder.INFINITY)
|
||||
.setAccentColor(color)
|
||||
.addRow(b -> b
|
||||
.setTitle(title)
|
||||
.addEndItem(toggleSliceAction)
|
||||
.setPrimaryAction(primarySliceAction))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the current ZenMode status to the boolean value keyed by
|
||||
* {@link android.app.slice.Slice#EXTRA_TOGGLE_STATE} on {@param intent}.
|
||||
*/
|
||||
public static void handleUriChange(Context context, Intent intent) {
|
||||
final boolean zenModeOn = intent.getBooleanExtra(EXTRA_TOGGLE_STATE, false);
|
||||
final int zenMode;
|
||||
if (zenModeOn) {
|
||||
zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
|
||||
} else {
|
||||
zenMode = Settings.Global.ZEN_MODE_OFF;
|
||||
}
|
||||
NotificationManager.from(context).setZenMode(zenMode, null /* conditionId */, TAG);
|
||||
// Do not notifyChange on Uri. The service takes longer to update the current value than it
|
||||
// does for the Slice to check the current value again. Let {@link SliceBroadcastRelay}
|
||||
// handle it.
|
||||
}
|
||||
|
||||
private static boolean isZenModeEnabled(Context context) {
|
||||
final NotificationManager manager = context.getSystemService(NotificationManager.class);
|
||||
final int zenMode = manager.getZenMode();
|
||||
|
||||
switch (zenMode) {
|
||||
case Settings.Global.ZEN_MODE_ALARMS:
|
||||
case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
|
||||
case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
|
||||
return true;
|
||||
case Settings.Global.ZEN_MODE_OFF:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static PendingIntent getPrimaryAction(Context context) {
|
||||
final String screenTitle = context.getText(R.string.zen_mode_settings_title).toString();
|
||||
final Uri contentUri = new Uri.Builder().appendPath(ZEN_MODE_KEY).build();
|
||||
final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
|
||||
ZenModeSettings.class.getName(), ZEN_MODE_KEY, screenTitle,
|
||||
MetricsEvent.NOTIFICATION_ZEN_MODE)
|
||||
.setClassName(context.getPackageName(), SubSettings.class.getName())
|
||||
.setData(contentUri);
|
||||
|
||||
return PendingIntent.getActivity(context, 0 /* requestCode */,
|
||||
intent, 0 /* flags */);
|
||||
}
|
||||
|
||||
private static PendingIntent getBroadcastIntent(Context context) {
|
||||
final Intent intent = new Intent(ACTION_ZEN_MODE_SLICE_CHANGED)
|
||||
.setClass(context, SliceBroadcastReceiver.class);
|
||||
return PendingIntent.getBroadcast(context, 0 /* requestCode */, intent,
|
||||
PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,9 @@ public class ZenModeVisEffectsAllPreferenceController
|
||||
extends AbstractZenModePreferenceController
|
||||
implements ZenCustomRadioButtonPreference.OnRadioButtonClickListener {
|
||||
|
||||
private final String KEY;
|
||||
private ZenCustomRadioButtonPreference mPreference;
|
||||
|
||||
protected static final int EFFECTS = Policy.SUPPRESSED_EFFECT_SCREEN_OFF
|
||||
| Policy.SUPPRESSED_EFFECT_SCREEN_ON
|
||||
| Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
|
||||
@@ -41,6 +44,14 @@ public class ZenModeVisEffectsAllPreferenceController
|
||||
public ZenModeVisEffectsAllPreferenceController(Context context, Lifecycle lifecycle,
|
||||
String key) {
|
||||
super(context, key, lifecycle);
|
||||
KEY = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = (ZenCustomRadioButtonPreference) screen.findPreference(KEY);
|
||||
mPreference.setOnRadioButtonClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -54,17 +65,7 @@ public class ZenModeVisEffectsAllPreferenceController
|
||||
|
||||
boolean everythingBlocked = Policy.areAllVisualEffectsSuppressed(
|
||||
mBackend.mPolicy.suppressedVisualEffects);
|
||||
ZenCustomRadioButtonPreference pref = (ZenCustomRadioButtonPreference) preference;
|
||||
pref.setOnRadioButtonClickListener(this);
|
||||
pref.setChecked(everythingBlocked);
|
||||
}
|
||||
|
||||
protected void deselect(PreferenceScreen screen) {
|
||||
ZenCustomRadioButtonPreference preference =
|
||||
(ZenCustomRadioButtonPreference) screen.findPreference(getPreferenceKey());
|
||||
if (preference != null) {
|
||||
preference.setChecked(false);
|
||||
}
|
||||
mPreference.setChecked(everythingBlocked);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.settings.notification;
|
||||
import android.app.NotificationManager.Policy;
|
||||
import android.content.Context;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
@@ -28,6 +29,9 @@ import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
public class ZenModeVisEffectsCustomPreferenceController
|
||||
extends AbstractZenModePreferenceController {
|
||||
|
||||
private final String KEY;
|
||||
private ZenCustomRadioButtonPreference mPreference;
|
||||
|
||||
protected static final int INTERRUPTIVE_EFFECTS = Policy.SUPPRESSED_EFFECT_AMBIENT
|
||||
| Policy.SUPPRESSED_EFFECT_PEEK
|
||||
| Policy.SUPPRESSED_EFFECT_LIGHTS
|
||||
@@ -36,6 +40,7 @@ public class ZenModeVisEffectsCustomPreferenceController
|
||||
public ZenModeVisEffectsCustomPreferenceController(Context context, Lifecycle lifecycle,
|
||||
String key) {
|
||||
super(context, key, lifecycle);
|
||||
KEY = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -43,20 +48,25 @@ public class ZenModeVisEffectsCustomPreferenceController
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = (ZenCustomRadioButtonPreference) screen.findPreference(KEY);
|
||||
|
||||
mPreference.setOnGearClickListener(p -> {
|
||||
launchCustomSettings();
|
||||
});
|
||||
|
||||
mPreference.setOnRadioButtonClickListener(p -> {
|
||||
launchCustomSettings();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
|
||||
ZenCustomRadioButtonPreference pref = (ZenCustomRadioButtonPreference) preference;
|
||||
pref.setChecked(areCustomOptionsSelected());
|
||||
|
||||
pref.setOnGearClickListener(p -> {
|
||||
launchCustomSettings();
|
||||
});
|
||||
|
||||
pref.setOnRadioButtonClickListener(p -> {
|
||||
launchCustomSettings();
|
||||
});
|
||||
mPreference.setChecked(areCustomOptionsSelected());
|
||||
}
|
||||
|
||||
protected boolean areCustomOptionsSelected() {
|
||||
|
||||
@@ -28,6 +28,9 @@ public class ZenModeVisEffectsNonePreferenceController
|
||||
extends AbstractZenModePreferenceController
|
||||
implements ZenCustomRadioButtonPreference.OnRadioButtonClickListener {
|
||||
|
||||
private final String KEY;
|
||||
private ZenCustomRadioButtonPreference mPreference;
|
||||
|
||||
protected static final int EFFECTS = Policy.SUPPRESSED_EFFECT_SCREEN_OFF
|
||||
| Policy.SUPPRESSED_EFFECT_SCREEN_ON
|
||||
| Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
|
||||
@@ -41,6 +44,14 @@ public class ZenModeVisEffectsNonePreferenceController
|
||||
public ZenModeVisEffectsNonePreferenceController(Context context, Lifecycle lifecycle,
|
||||
String key) {
|
||||
super(context, key, lifecycle);
|
||||
KEY = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = (ZenCustomRadioButtonPreference) screen.findPreference(KEY);
|
||||
mPreference.setOnRadioButtonClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -53,9 +64,7 @@ public class ZenModeVisEffectsNonePreferenceController
|
||||
super.updateState(preference);
|
||||
|
||||
boolean nothingBlocked = mBackend.mPolicy.suppressedVisualEffects == 0;
|
||||
ZenCustomRadioButtonPreference pref = (ZenCustomRadioButtonPreference) preference;
|
||||
pref.setOnRadioButtonClickListener(this);
|
||||
pref.setChecked(nothingBlocked);
|
||||
mPreference.setChecked(nothingBlocked);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,12 +73,4 @@ public class ZenModeVisEffectsNonePreferenceController
|
||||
MetricsProto.MetricsEvent.ACTION_ZEN_SOUND_ONLY, true);
|
||||
mBackend.saveVisualEffectsPolicy(EFFECTS, false);
|
||||
}
|
||||
|
||||
protected void deselect(PreferenceScreen screen) {
|
||||
ZenCustomRadioButtonPreference preference =
|
||||
(ZenCustomRadioButtonPreference) screen.findPreference(getPreferenceKey());
|
||||
if (preference != null) {
|
||||
preference.setChecked(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,10 @@ import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.slices.SettingsSliceProvider;
|
||||
|
||||
import java.util.List;
|
||||
@@ -48,6 +50,12 @@ public interface DeviceIndexFeatureProvider {
|
||||
|
||||
default void updateIndex(Context context, boolean force) {
|
||||
if (!isIndexingEnabled()) {
|
||||
Log.w(TAG, "Skipping: device index is not enabled");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Utils.isDeviceProvisioned(context)) {
|
||||
Log.w(TAG, "Skipping: device is not provisioned");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,41 +18,40 @@ package com.android.settings.slices;
|
||||
|
||||
import static android.Manifest.permission.READ_SEARCH_INDEXABLES;
|
||||
|
||||
import static com.android.settings.wifi.calling.WifiCallingSliceHelper.PATH_WIFI_CALLING;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.app.slice.SliceManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.provider.Settings;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v4.graphics.drawable.IconCompat;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.SliceProvider;
|
||||
import androidx.slice.builders.ListBuilder;
|
||||
import androidx.slice.builders.SliceAction;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.wifi.WifiSliceBuilder;
|
||||
import com.android.settings.wifi.calling.WifiCallingSliceHelper;
|
||||
import com.android.settings.notification.ZenModeSliceBuilder;
|
||||
import com.android.settingslib.SliceBroadcastRelay;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.SliceProvider;
|
||||
|
||||
/**
|
||||
* A {@link SliceProvider} for Settings to enabled inline results in system apps.
|
||||
*
|
||||
@@ -84,10 +83,6 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
*/
|
||||
public static final String SLICE_AUTHORITY = "com.android.settings.slices";
|
||||
|
||||
public static final String PATH_WIFI = "wifi";
|
||||
public static final String ACTION_WIFI_CHANGED =
|
||||
"com.android.settings.slice.action.WIFI_CHANGED";
|
||||
|
||||
/**
|
||||
* Action passed for changes to Toggle Slices.
|
||||
*/
|
||||
@@ -111,8 +106,6 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
public static final String EXTRA_SLICE_PLATFORM_DEFINED =
|
||||
"com.android.settings.slice.extra.platform";
|
||||
|
||||
// TODO -- Associate slice URI with search result instead of separate hardcoded thing
|
||||
|
||||
@VisibleForTesting
|
||||
SlicesDatabaseAccessor mSlicesDatabaseAccessor;
|
||||
|
||||
@@ -121,6 +114,8 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
@VisibleForTesting
|
||||
Map<Uri, SliceData> mSliceDataCache;
|
||||
|
||||
final Set<Uri> mRegisteredUris = new ArraySet<>();
|
||||
|
||||
public SettingsSliceProvider() {
|
||||
super(READ_SEARCH_INDEXABLES);
|
||||
}
|
||||
@@ -146,28 +141,42 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
|
||||
@Override
|
||||
public void onSlicePinned(Uri sliceUri) {
|
||||
if (WifiSliceBuilder.WIFI_URI.equals(sliceUri)) {
|
||||
registerIntentToUri(WifiSliceBuilder.INTENT_FILTER , sliceUri);
|
||||
return;
|
||||
} else if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(sliceUri)) {
|
||||
registerIntentToUri(ZenModeSliceBuilder.INTENT_FILTER, sliceUri);
|
||||
mRegisteredUris.add(sliceUri);
|
||||
return;
|
||||
}
|
||||
|
||||
// Start warming the slice, we expect someone will want it soon.
|
||||
loadSliceInBackground(sliceUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSliceUnpinned(Uri sliceUri) {
|
||||
if (mRegisteredUris.contains(sliceUri)) {
|
||||
Log.d(TAG, "Unregistering uri broadcast relay: " + sliceUri);
|
||||
SliceBroadcastRelay.unregisterReceivers(getContext(), sliceUri);
|
||||
mRegisteredUris.remove(sliceUri);
|
||||
}
|
||||
mSliceDataCache.remove(sliceUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Slice onBindSlice(Uri sliceUri) {
|
||||
String path = sliceUri.getPath();
|
||||
// If adding a new Slice, do not directly match Slice URIs.
|
||||
// Use {@link SlicesDatabaseAccessor}.
|
||||
switch (path) {
|
||||
case "/" + PATH_WIFI:
|
||||
return createWifiSlice(sliceUri);
|
||||
case "/" + PATH_WIFI_CALLING:
|
||||
return FeatureFactory.getFactory(getContext())
|
||||
.getSlicesFeatureProvider()
|
||||
.getNewWifiCallingSliceHelper(getContext())
|
||||
.createWifiCallingSlice(sliceUri);
|
||||
if (WifiCallingSliceHelper.WIFI_CALLING_URI.equals(sliceUri)) {
|
||||
return FeatureFactory.getFactory(getContext())
|
||||
.getSlicesFeatureProvider()
|
||||
.getNewWifiCallingSliceHelper(getContext())
|
||||
.createWifiCallingSlice(sliceUri);
|
||||
} else if (WifiSliceBuilder.WIFI_URI.equals(sliceUri)) {
|
||||
return WifiSliceBuilder.getSlice(getContext());
|
||||
} else if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(sliceUri)) {
|
||||
return ZenModeSliceBuilder.getSlice(getContext());
|
||||
}
|
||||
|
||||
SliceData cachedSliceData = mSliceWeakDataCache.get(sliceUri);
|
||||
@@ -223,11 +232,12 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
true /* isPlatformSlice */);
|
||||
final List<String> oemKeys = mSlicesDatabaseAccessor.getSliceKeys(
|
||||
false /* isPlatformSlice */);
|
||||
final List<Uri> allUris = buildUrisFromKeys(platformKeys,
|
||||
SettingsSlicesContract.AUTHORITY);
|
||||
allUris.addAll(buildUrisFromKeys(oemKeys, SettingsSliceProvider.SLICE_AUTHORITY));
|
||||
descendants.addAll(buildUrisFromKeys(platformKeys, SettingsSlicesContract.AUTHORITY));
|
||||
descendants.addAll(buildUrisFromKeys(oemKeys, SettingsSliceProvider.SLICE_AUTHORITY));
|
||||
descendants.addAll(getSpecialCaseUris(true /* isPlatformSlice */));
|
||||
descendants.addAll(getSpecialCaseUris(false /* isPlatformSlice */));
|
||||
|
||||
return allUris;
|
||||
return descendants;
|
||||
}
|
||||
|
||||
// Path is anything but empty, "action", or "intent". Return empty list.
|
||||
@@ -242,7 +252,9 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
// Can assume authority belongs to the provider. Return all Uris for the authority.
|
||||
final boolean isPlatformUri = TextUtils.equals(authority, SettingsSlicesContract.AUTHORITY);
|
||||
final List<String> keys = mSlicesDatabaseAccessor.getSliceKeys(isPlatformUri);
|
||||
return buildUrisFromKeys(keys, authority);
|
||||
descendants.addAll(buildUrisFromKeys(keys, authority));
|
||||
descendants.addAll(getSpecialCaseUris(isPlatformUri));
|
||||
return descendants;
|
||||
}
|
||||
|
||||
private List<Uri> buildUrisFromKeys(List<String> keys, String authority) {
|
||||
@@ -267,7 +279,15 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
long startBuildTime = System.currentTimeMillis();
|
||||
|
||||
final SliceData sliceData = mSlicesDatabaseAccessor.getSliceDataFromUri(uri);
|
||||
List<Uri> pinnedSlices = getContext().getSystemService(
|
||||
|
||||
final BasePreferenceController controller = SliceBuilderUtils.getPreferenceController(
|
||||
getContext(), sliceData);
|
||||
final IntentFilter filter = controller.getIntentFilter();
|
||||
if (filter != null) {
|
||||
registerIntentToUri(filter, uri);
|
||||
}
|
||||
|
||||
final List<Uri> pinnedSlices = getContext().getSystemService(
|
||||
SliceManager.class).getPinnedSlices();
|
||||
if (pinnedSlices.contains(uri)) {
|
||||
mSliceDataCache.put(uri, sliceData);
|
||||
@@ -295,55 +315,34 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
return new Slice.Builder(uri).build();
|
||||
}
|
||||
|
||||
// TODO (b/70622039) remove this when the proper wifi slice is enabled.
|
||||
private Slice createWifiSlice(Uri sliceUri) {
|
||||
// Get wifi state
|
||||
WifiManager wifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
|
||||
int wifiState = wifiManager.getWifiState();
|
||||
boolean wifiEnabled = false;
|
||||
String state;
|
||||
switch (wifiState) {
|
||||
case WifiManager.WIFI_STATE_DISABLED:
|
||||
case WifiManager.WIFI_STATE_DISABLING:
|
||||
state = getContext().getString(R.string.disconnected);
|
||||
break;
|
||||
case WifiManager.WIFI_STATE_ENABLED:
|
||||
case WifiManager.WIFI_STATE_ENABLING:
|
||||
state = wifiManager.getConnectionInfo().getSSID();
|
||||
wifiEnabled = true;
|
||||
break;
|
||||
case WifiManager.WIFI_STATE_UNKNOWN:
|
||||
default:
|
||||
state = ""; // just don't show anything?
|
||||
break;
|
||||
private List<Uri> getSpecialCaseUris(boolean isPlatformUri) {
|
||||
if (isPlatformUri) {
|
||||
return getSpecialCasePlatformUris();
|
||||
}
|
||||
|
||||
boolean finalWifiEnabled = wifiEnabled;
|
||||
return new ListBuilder(getContext(), sliceUri)
|
||||
.setColor(R.color.material_blue_500)
|
||||
.addRow(b -> b
|
||||
.setTitle(getContext().getString(R.string.wifi_settings))
|
||||
.setTitleItem(Icon.createWithResource(getContext(), R.drawable.wifi_signal))
|
||||
.setSubtitle(state)
|
||||
.addEndItem(new SliceAction(getBroadcastIntent(ACTION_WIFI_CHANGED),
|
||||
null, finalWifiEnabled))
|
||||
.setPrimaryAction(
|
||||
new SliceAction(getIntent(Settings.ACTION_WIFI_SETTINGS),
|
||||
(IconCompat) null, null)))
|
||||
.build();
|
||||
return getSpecialCaseOemUris();
|
||||
}
|
||||
|
||||
private PendingIntent getIntent(String action) {
|
||||
Intent intent = new Intent(action);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
PendingIntent pi = PendingIntent.getActivity(getContext(), 0, intent, 0);
|
||||
return pi;
|
||||
private List<Uri> getSpecialCasePlatformUris() {
|
||||
return Arrays.asList(
|
||||
WifiSliceBuilder.WIFI_URI
|
||||
);
|
||||
}
|
||||
|
||||
private PendingIntent getBroadcastIntent(String action) {
|
||||
Intent intent = new Intent(action);
|
||||
intent.setClass(getContext(), SliceBroadcastReceiver.class);
|
||||
return PendingIntent.getBroadcast(getContext(), 0, intent,
|
||||
PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
private List<Uri> getSpecialCaseOemUris() {
|
||||
return Arrays.asList(
|
||||
ZenModeSliceBuilder.ZEN_MODE_URI
|
||||
);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
/**
|
||||
* Registers an IntentFilter in SysUI to notify changes to {@param sliceUri} when broadcasts to
|
||||
* {@param intentFilter} happen.
|
||||
*/
|
||||
void registerIntentToUri(IntentFilter intentFilter, Uri sliceUri) {
|
||||
Log.d(TAG, "Registering Uri for broadcast relay: " + sliceUri);
|
||||
mRegisteredUris.add(sliceUri);
|
||||
SliceBroadcastRelay.registerReceiver(getContext(), sliceUri, SliceBroadcastReceiver.class,
|
||||
intentFilter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,20 +16,19 @@
|
||||
|
||||
package com.android.settings.slices;
|
||||
|
||||
import static com.android.settings.notification.ZenModeSliceBuilder.ACTION_ZEN_MODE_SLICE_CHANGED;
|
||||
import static com.android.settings.slices.SettingsSliceProvider.ACTION_SLIDER_CHANGED;
|
||||
import static com.android.settings.slices.SettingsSliceProvider.ACTION_TOGGLE_CHANGED;
|
||||
import static com.android.settings.slices.SettingsSliceProvider.ACTION_WIFI_CHANGED;
|
||||
import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_KEY;
|
||||
import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_PLATFORM_DEFINED;
|
||||
import static com.android.settings.wifi.calling.WifiCallingSliceHelper.ACTION_WIFI_CALLING_CHANGED;
|
||||
import static com.android.settings.wifi.WifiSliceBuilder.ACTION_WIFI_SLICE_CHANGED;
|
||||
|
||||
import android.app.slice.Slice;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Handler;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
@@ -39,7 +38,10 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.SliderPreferenceController;
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
import com.android.settings.notification.ZenModeSliceBuilder;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.wifi.WifiSliceBuilder;
|
||||
import com.android.settingslib.SliceBroadcastRelay;
|
||||
|
||||
/**
|
||||
* Responds to actions performed on slices and notifies slices of updates in state changes.
|
||||
@@ -48,9 +50,6 @@ public class SliceBroadcastReceiver extends BroadcastReceiver {
|
||||
|
||||
private static String TAG = "SettSliceBroadcastRec";
|
||||
|
||||
/**
|
||||
* TODO (b/) move wifi action into generalized case.
|
||||
*/
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
final String action = intent.getAction();
|
||||
@@ -67,25 +66,24 @@ public class SliceBroadcastReceiver extends BroadcastReceiver {
|
||||
final int newPosition = intent.getIntExtra(Slice.EXTRA_RANGE_VALUE, -1);
|
||||
handleSliderAction(context, key, newPosition, isPlatformSlice);
|
||||
break;
|
||||
case ACTION_WIFI_CHANGED:
|
||||
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
boolean newState = intent.getBooleanExtra(Slice.EXTRA_TOGGLE_STATE,
|
||||
wm.isWifiEnabled());
|
||||
wm.setWifiEnabled(newState);
|
||||
// Wait a bit for wifi to update (TODO: is there a better way to do this?)
|
||||
Handler h = new Handler();
|
||||
h.postDelayed(() -> {
|
||||
Uri uri = SliceBuilderUtils.getUri(SettingsSliceProvider.PATH_WIFI,
|
||||
false /* isPlatformSlice */);
|
||||
context.getContentResolver().notifyChange(uri, null);
|
||||
}, 1000);
|
||||
case ACTION_WIFI_SLICE_CHANGED:
|
||||
WifiSliceBuilder.handleUriChange(context, intent);
|
||||
break;
|
||||
case ACTION_WIFI_CALLING_CHANGED:
|
||||
FeatureFactory.getFactory(context)
|
||||
.getSlicesFeatureProvider()
|
||||
.getNewWifiCallingSliceHelper(context)
|
||||
.handleWifiCallingChanged(intent);
|
||||
.getSlicesFeatureProvider()
|
||||
.getNewWifiCallingSliceHelper(context)
|
||||
.handleWifiCallingChanged(intent);
|
||||
break;
|
||||
case ACTION_ZEN_MODE_SLICE_CHANGED:
|
||||
ZenModeSliceBuilder.handleUriChange(context, intent);
|
||||
break;
|
||||
default:
|
||||
final String uriString = intent.getStringExtra(SliceBroadcastRelay.EXTRA_URI);
|
||||
if (!TextUtils.isEmpty(uriString)) {
|
||||
final Uri uri = Uri.parse(uriString);
|
||||
context.getContentResolver().notifyChange(uri, null /* observer */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@ import android.util.Pair;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.SubSettings;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
@@ -47,6 +46,7 @@ import com.android.settings.core.SliderPreferenceController;
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.search.DatabaseIndexingUtils;
|
||||
import com.android.settingslib.SliceBroadcastRelay;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
import android.support.v4.graphics.drawable.IconCompat;
|
||||
@@ -54,6 +54,7 @@ import android.support.v4.graphics.drawable.IconCompat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.builders.ListBuilder;
|
||||
@@ -345,7 +346,10 @@ public class SliceBuilderUtils {
|
||||
final String keywordString = data.getKeywords();
|
||||
if (keywordString != null) {
|
||||
final String[] keywordArray = keywordString.split(",");
|
||||
keywords.addAll(Arrays.asList(keywordArray));
|
||||
final List<String> strippedKeywords = Arrays.stream(keywordArray)
|
||||
.map(s -> s = s.trim())
|
||||
.collect(Collectors.toList());
|
||||
keywords.addAll(strippedKeywords);
|
||||
}
|
||||
|
||||
return keywords;
|
||||
|
||||
@@ -45,7 +45,11 @@ public class SliceDeepLinkSpringBoard extends Activity {
|
||||
// This shouldn't matter since the slice is shown instead of the device
|
||||
// index caring about the launch uri.
|
||||
Uri slice = Uri.parse(intent.getStringExtra(EXTRA_SLICE));
|
||||
Log.e(TAG, "Slice intent launched: " + slice);
|
||||
SlicesDatabaseAccessor slicesDatabaseAccessor = new SlicesDatabaseAccessor(this);
|
||||
// Sadly have to block here because we don't know where to go.
|
||||
final SliceData sliceData = slicesDatabaseAccessor.getSliceDataFromUri(slice);
|
||||
Intent launchIntent = SliceBuilderUtils.getContentIntent(this, sliceData);
|
||||
startActivity(launchIntent);
|
||||
} else {
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
|
||||
protected final LocalBluetoothProfileManager mProfileManager;
|
||||
protected int mSelectedIndex;
|
||||
protected Preference mPreference;
|
||||
protected AudioSwitchCallback mAudioSwitchPreferenceCallback;
|
||||
|
||||
private final AudioManagerAudioDeviceCallback mAudioManagerAudioDeviceCallback;
|
||||
private final LocalBluetoothManager mLocalBluetoothManager;
|
||||
@@ -85,6 +86,10 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
|
||||
private final WiredHeadsetBroadcastReceiver mReceiver;
|
||||
private final Handler mHandler;
|
||||
|
||||
public interface AudioSwitchCallback {
|
||||
void onPreferenceDataChanged(ListPreference preference);
|
||||
}
|
||||
|
||||
public AudioSwitchPreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
@@ -131,7 +136,7 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
|
||||
final BluetoothDevice btDevice = mConnectedDevices.get(connectedDeviceIndex);
|
||||
mSelectedIndex = connectedDeviceIndex;
|
||||
setActiveBluetoothDevice(btDevice);
|
||||
listPreference.setSummary(btDevice.getName());
|
||||
listPreference.setSummary(btDevice.getAliasName());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -207,6 +212,10 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
|
||||
public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
|
||||
}
|
||||
|
||||
public void setCallback(AudioSwitchCallback callback) {
|
||||
mAudioSwitchPreferenceCallback = callback;
|
||||
}
|
||||
|
||||
protected boolean isStreamFromOutputDevice(int streamType, int device) {
|
||||
return (device & mAudioManager.getDevicesForStream(streamType)) != 0;
|
||||
}
|
||||
@@ -319,7 +328,7 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
|
||||
mediaValues[mSelectedIndex] = mContext.getText(R.string.media_output_default_summary);
|
||||
for (int i = 0, size = mConnectedDevices.size(); i < size; i++) {
|
||||
final BluetoothDevice btDevice = mConnectedDevices.get(i);
|
||||
mediaOutputs[i] = btDevice.getName();
|
||||
mediaOutputs[i] = btDevice.getAliasName();
|
||||
mediaValues[i] = btDevice.getAddress();
|
||||
if (btDevice.equals(activeDevice)) {
|
||||
// select the active connected device.
|
||||
@@ -335,6 +344,7 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
|
||||
listPreference.setEntryValues(mediaValues);
|
||||
listPreference.setValueIndex(mSelectedIndex);
|
||||
listPreference.setSummary(mediaOutputs[mSelectedIndex]);
|
||||
mAudioSwitchPreferenceCallback.onPreferenceDataChanged(listPreference);
|
||||
}
|
||||
|
||||
private int getConnectedDeviceIndex(String hardwareAddress) {
|
||||
|
||||
@@ -66,7 +66,11 @@ public class HandsFreeProfileOutputPreferenceController extends
|
||||
if (numDevices == 0) {
|
||||
// No connected devices, disable switch entry.
|
||||
mPreference.setVisible(false);
|
||||
preference.setSummary(mContext.getText(R.string.media_output_default_summary));
|
||||
final CharSequence summary = mContext.getText(R.string.media_output_default_summary);
|
||||
final CharSequence[] defaultMediaOutput = new CharSequence[]{summary};
|
||||
mSelectedIndex = getDefaultDeviceIndex();
|
||||
preference.setSummary(summary);
|
||||
setPreference(defaultMediaOutput, defaultMediaOutput, preference);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,11 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro
|
||||
if (numDevices == 0) {
|
||||
// Disable switch entry if there is no connected devices.
|
||||
mPreference.setVisible(false);
|
||||
preference.setSummary(mContext.getText(R.string.media_output_default_summary));
|
||||
final CharSequence summary = mContext.getText(R.string.media_output_default_summary);
|
||||
final CharSequence[] defaultMediaOutput = new CharSequence[]{summary};
|
||||
mSelectedIndex = getDefaultDeviceIndex();
|
||||
preference.setSummary(summary);
|
||||
setPreference(defaultMediaOutput, defaultMediaOutput, preference);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import android.support.annotation.IntDef;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.TextUtils;
|
||||
import android.util.IconDrawableFactory;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -146,9 +147,7 @@ public class EntityHeaderController {
|
||||
* accessibility purposes.
|
||||
*/
|
||||
public EntityHeaderController setIcon(ApplicationsState.AppEntry appEntry) {
|
||||
if (appEntry.icon != null) {
|
||||
mIcon = appEntry.icon.getConstantState().newDrawable(mAppContext.getResources());
|
||||
}
|
||||
mIcon = IconDrawableFactory.newInstance(mAppContext).getBadgedIcon(appEntry.info);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.widget;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v14.preference.PreferenceDialogFragment;
|
||||
import android.support.v7.preference.ListPreference;
|
||||
import android.widget.ArrayAdapter;
|
||||
import com.android.settingslib.core.instrumentation.Instrumentable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* {@link PreferenceDialogFragment} that updates the available options
|
||||
* when {@code onListPreferenceUpdated} is called."
|
||||
*/
|
||||
public class UpdatableListPreferenceDialogFragment extends PreferenceDialogFragment implements
|
||||
Instrumentable {
|
||||
|
||||
private static final String SAVE_STATE_INDEX = "UpdatableListPreferenceDialogFragment.index";
|
||||
private static final String SAVE_STATE_ENTRIES =
|
||||
"UpdatableListPreferenceDialogFragment.entries";
|
||||
private static final String SAVE_STATE_ENTRY_VALUES =
|
||||
"UpdatableListPreferenceDialogFragment.entryValues";
|
||||
private static final String METRICS_CATEGORY_KEY = "metrics_category_key";
|
||||
private ArrayAdapter mAdapter;
|
||||
private int mClickedDialogEntryIndex;
|
||||
private ArrayList<CharSequence> mEntries;
|
||||
private CharSequence[] mEntryValues;
|
||||
private int mMetricsCategory = Instrumentable.METRICS_CATEGORY_UNKNOWN;
|
||||
|
||||
public static UpdatableListPreferenceDialogFragment newInstance(
|
||||
String key, int metricsCategory) {
|
||||
UpdatableListPreferenceDialogFragment fragment =
|
||||
new UpdatableListPreferenceDialogFragment();
|
||||
Bundle args = new Bundle(1);
|
||||
args.putString(ARG_KEY, key);
|
||||
args.putInt(METRICS_CATEGORY_KEY, metricsCategory);
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
final Bundle bundle = getArguments();
|
||||
mMetricsCategory =
|
||||
bundle.getInt(METRICS_CATEGORY_KEY, Instrumentable.METRICS_CATEGORY_UNKNOWN);
|
||||
if (savedInstanceState == null) {
|
||||
mEntries = new ArrayList<>();
|
||||
setPreferenceData(getListPreference());
|
||||
} else {
|
||||
mClickedDialogEntryIndex = savedInstanceState.getInt(SAVE_STATE_INDEX, 0);
|
||||
mEntries = savedInstanceState.getCharSequenceArrayList(SAVE_STATE_ENTRIES);
|
||||
mEntryValues =
|
||||
savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRY_VALUES);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putInt(SAVE_STATE_INDEX, mClickedDialogEntryIndex);
|
||||
outState.putCharSequenceArrayList(SAVE_STATE_ENTRIES, mEntries);
|
||||
outState.putCharSequenceArray(SAVE_STATE_ENTRY_VALUES, mEntryValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDialogClosed(boolean positiveResult) {
|
||||
final ListPreference preference = getListPreference();
|
||||
if (positiveResult && mClickedDialogEntryIndex >= 0) {
|
||||
final String value = mEntryValues[mClickedDialogEntryIndex].toString();
|
||||
if (preference.callChangeListener(value)) {
|
||||
preference.setValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setAdapter(ArrayAdapter adapter) {
|
||||
mAdapter = adapter;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setEntries(ArrayList<CharSequence> entries) {
|
||||
mEntries = entries;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
ArrayAdapter getAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setMetricsCategory(Bundle bundle) {
|
||||
mMetricsCategory =
|
||||
bundle.getInt(METRICS_CATEGORY_KEY, Instrumentable.METRICS_CATEGORY_UNKNOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
|
||||
super.onPrepareDialogBuilder(builder);
|
||||
final TypedArray a = getContext().obtainStyledAttributes(
|
||||
null,
|
||||
com.android.internal.R.styleable.AlertDialog,
|
||||
com.android.internal.R.attr.alertDialogStyle, 0);
|
||||
|
||||
mAdapter = new ArrayAdapter<>(
|
||||
getContext(),
|
||||
a.getResourceId(
|
||||
com.android.internal.R.styleable.AlertDialog_singleChoiceItemLayout,
|
||||
com.android.internal.R.layout.select_dialog_singlechoice),
|
||||
mEntries);
|
||||
|
||||
builder.setSingleChoiceItems(mAdapter, mClickedDialogEntryIndex,
|
||||
(dialog, which) -> {
|
||||
mClickedDialogEntryIndex = which;
|
||||
onClick(dialog, -1);
|
||||
dialog.dismiss();
|
||||
});
|
||||
builder.setPositiveButton(null, null);
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return mMetricsCategory;
|
||||
}
|
||||
|
||||
private ListPreference getListPreference() {
|
||||
return (ListPreference) getPreference();
|
||||
}
|
||||
|
||||
private void setPreferenceData(ListPreference preference) {
|
||||
mEntries.clear();
|
||||
mClickedDialogEntryIndex = preference.findIndexOfValue(preference.getValue());
|
||||
for (CharSequence entry : preference.getEntries()) {
|
||||
mEntries.add(entry);
|
||||
}
|
||||
mEntryValues = preference.getEntryValues();
|
||||
}
|
||||
|
||||
public void onListPreferenceUpdated(ListPreference preference) {
|
||||
if (mAdapter != null) {
|
||||
setPreferenceData(preference);
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
178
src/com/android/settings/wifi/WifiSliceBuilder.java
Normal file
178
src/com/android/settings/wifi/WifiSliceBuilder.java
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* 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.wifi;
|
||||
|
||||
import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
|
||||
import static android.provider.SettingsSlicesContract.KEY_WIFI;
|
||||
|
||||
import android.annotation.ColorInt;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.net.wifi.WifiSsid;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SubSettings;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.search.DatabaseIndexingUtils;
|
||||
import com.android.settings.slices.SliceBroadcastReceiver;
|
||||
import com.android.settings.slices.SliceBuilderUtils;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.builders.ListBuilder;
|
||||
import androidx.slice.builders.SliceAction;
|
||||
|
||||
import android.support.v4.graphics.drawable.IconCompat;
|
||||
import android.text.TextUtils;
|
||||
|
||||
/**
|
||||
* Utility class to build a Wifi Slice, and handle all associated actions.
|
||||
*/
|
||||
public class WifiSliceBuilder {
|
||||
|
||||
/**
|
||||
* Backing Uri for the Wifi Slice.
|
||||
*/
|
||||
public static final Uri WIFI_URI = new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(SettingsSlicesContract.AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.appendPath(KEY_WIFI)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Action notifying a change on the Wifi Slice.
|
||||
*/
|
||||
public static final String ACTION_WIFI_SLICE_CHANGED =
|
||||
"com.android.settings.wifi.action.WIFI_CHANGED";
|
||||
|
||||
public static final IntentFilter INTENT_FILTER = new IntentFilter();
|
||||
|
||||
static {
|
||||
INTENT_FILTER.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
|
||||
INTENT_FILTER.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
|
||||
}
|
||||
|
||||
private WifiSliceBuilder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Wifi Slice bound to {@link #WIFI_URI}.
|
||||
* <p>
|
||||
* Note that you should register a listener for {@link #INTENT_FILTER} to get changes for Wifi.
|
||||
*/
|
||||
public static Slice getSlice(Context context) {
|
||||
final boolean isWifiEnabled = isWifiEnabled(context);
|
||||
final IconCompat icon = IconCompat.createWithResource(context,
|
||||
R.drawable.ic_settings_wireless);
|
||||
final String title = context.getString(R.string.wifi_settings);
|
||||
final CharSequence summary = getSummary(context);
|
||||
@ColorInt final int color = Utils.getColorAccent(context);
|
||||
final PendingIntent toggleAction = getBroadcastIntent(context);
|
||||
final PendingIntent primaryAction = getPrimaryAction(context);
|
||||
final SliceAction primarySliceAction = new SliceAction(primaryAction, icon, title);
|
||||
final SliceAction toggleSliceAction = new SliceAction(toggleAction, null /* actionTitle */,
|
||||
isWifiEnabled);
|
||||
|
||||
return new ListBuilder(context, WIFI_URI, ListBuilder.INFINITY)
|
||||
.setAccentColor(color)
|
||||
.addRow(b -> b
|
||||
.setTitle(title)
|
||||
.setSubtitle(summary)
|
||||
.addEndItem(toggleSliceAction)
|
||||
.setPrimaryAction(primarySliceAction))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the current wifi status to the boolean value keyed by
|
||||
* {@link android.app.slice.Slice#EXTRA_TOGGLE_STATE} on {@param intent}.
|
||||
*/
|
||||
public static void handleUriChange(Context context, Intent intent) {
|
||||
final WifiManager wifiManager = context.getSystemService(WifiManager.class);
|
||||
final boolean newState = intent.getBooleanExtra(EXTRA_TOGGLE_STATE,
|
||||
wifiManager.isWifiEnabled());
|
||||
wifiManager.setWifiEnabled(newState);
|
||||
// Do not notifyChange on Uri. The service takes longer to update the current value than it
|
||||
// does for the Slice to check the current value again. Let {@link SliceBroadcastRelay}
|
||||
// handle it.
|
||||
}
|
||||
|
||||
private static boolean isWifiEnabled(Context context) {
|
||||
final WifiManager wifiManager = context.getSystemService(WifiManager.class);
|
||||
|
||||
switch (wifiManager.getWifiState()) {
|
||||
case WifiManager.WIFI_STATE_ENABLED:
|
||||
case WifiManager.WIFI_STATE_ENABLING:
|
||||
return true;
|
||||
case WifiManager.WIFI_STATE_DISABLED:
|
||||
case WifiManager.WIFI_STATE_DISABLING:
|
||||
case WifiManager.WIFI_STATE_UNKNOWN:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static CharSequence getSummary(Context context) {
|
||||
final WifiManager wifiManager = context.getSystemService(WifiManager.class);
|
||||
|
||||
switch (wifiManager.getWifiState()) {
|
||||
case WifiManager.WIFI_STATE_ENABLED:
|
||||
final String ssid = WifiInfo.removeDoubleQuotes(wifiManager.getConnectionInfo()
|
||||
.getSSID());
|
||||
if (TextUtils.equals(ssid, WifiSsid.NONE)) {
|
||||
return context.getText(R.string.disconnected);
|
||||
}
|
||||
return ssid;
|
||||
case WifiManager.WIFI_STATE_ENABLING:
|
||||
return context.getText(R.string.disconnected);
|
||||
case WifiManager.WIFI_STATE_DISABLED:
|
||||
case WifiManager.WIFI_STATE_DISABLING:
|
||||
return context.getText(R.string.switch_off_text);
|
||||
case WifiManager.WIFI_STATE_UNKNOWN:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static PendingIntent getPrimaryAction(Context context) {
|
||||
final String screenTitle = context.getText(R.string.wifi_settings).toString();
|
||||
final Uri contentUri = new Uri.Builder().appendPath(KEY_WIFI).build();
|
||||
final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
|
||||
WifiSettings.class.getName(), KEY_WIFI, screenTitle,
|
||||
MetricsEvent.DIALOG_WIFI_AP_EDIT);
|
||||
intent.setClassName(context.getPackageName(), SubSettings.class.getName());
|
||||
intent.setData(contentUri);
|
||||
|
||||
return PendingIntent.getActivity(context, 0 /* requestCode */,
|
||||
intent, 0 /* flags */);
|
||||
}
|
||||
|
||||
private static PendingIntent getBroadcastIntent(Context context) {
|
||||
final Intent intent = new Intent(ACTION_WIFI_SLICE_CHANGED);
|
||||
intent.setClass(context, SliceBroadcastReceiver.class);
|
||||
return PendingIntent.getBroadcast(context, 0 /* requestCode */, intent,
|
||||
PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@ public class WifiUtils {
|
||||
|
||||
public static boolean isHotspotPasswordValid(String password) {
|
||||
if (TextUtils.isEmpty(password)) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
final int length = password.length();
|
||||
|
||||
@@ -20,6 +20,7 @@ import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
@@ -38,6 +39,7 @@ import androidx.slice.builders.SliceAction;
|
||||
import com.android.ims.ImsManager;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.slices.SettingsSliceProvider;
|
||||
import com.android.settings.slices.SliceBroadcastReceiver;
|
||||
import com.android.settings.slices.SliceBuilderUtils;
|
||||
|
||||
@@ -76,16 +78,20 @@ public class WifiCallingSliceHelper {
|
||||
public static final String ACTION_WIFI_CALLING_SETTINGS_ACTIVITY =
|
||||
"android.settings.WIFI_CALLING_SETTINGS";
|
||||
|
||||
/**
|
||||
* Full {@link Uri} for the Wifi Calling Slice.
|
||||
*/
|
||||
public static final Uri WIFI_CALLING_URI = new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||
.appendPath(PATH_WIFI_CALLING)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Timeout for querying wifi calling setting from ims manager.
|
||||
*/
|
||||
private static final int TIMEOUT_MILLIS = 2000;
|
||||
|
||||
/**
|
||||
* Time for which data contained in the slice can remain fresh.
|
||||
*/
|
||||
private static final int SLICE_TTL_MILLIS = 60000;
|
||||
|
||||
protected SubscriptionManager mSubscriptionManager;
|
||||
private final Context mContext;
|
||||
|
||||
@@ -182,7 +188,7 @@ public class WifiCallingSliceHelper {
|
||||
|
||||
final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.wifi_signal);
|
||||
final String title = mContext.getString(R.string.wifi_calling_settings_title);
|
||||
return new ListBuilder(mContext, sliceUri, SLICE_TTL_MILLIS)
|
||||
return new ListBuilder(mContext, sliceUri, ListBuilder.INFINITY)
|
||||
.setColor(R.color.material_blue_500)
|
||||
.addRow(b -> b
|
||||
.setTitle(title)
|
||||
@@ -260,7 +266,7 @@ public class WifiCallingSliceHelper {
|
||||
private Slice getNonActionableWifiCallingSlice(String title, String subtitle, Uri sliceUri,
|
||||
PendingIntent primaryActionIntent) {
|
||||
final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.wifi_signal);
|
||||
return new ListBuilder(mContext, sliceUri, SLICE_TTL_MILLIS)
|
||||
return new ListBuilder(mContext, sliceUri, ListBuilder.INFINITY)
|
||||
.setColor(R.color.material_blue_500)
|
||||
.addRow(b -> b
|
||||
.setTitle(title)
|
||||
|
||||
@@ -31,7 +31,6 @@ import java.util.UUID;
|
||||
public class WifiTetherPasswordPreferenceController extends WifiTetherBasePreferenceController
|
||||
implements ValidatedEditTextPreference.Validator {
|
||||
|
||||
private static final String TAG = "WifiTetherPswdPref";
|
||||
private static final String PREF_KEY = "wifi_tether_network_password";
|
||||
|
||||
private String mPassword;
|
||||
@@ -49,10 +48,11 @@ public class WifiTetherPasswordPreferenceController extends WifiTetherBasePrefer
|
||||
@Override
|
||||
public void updateDisplay() {
|
||||
final WifiConfiguration config = mWifiManager.getWifiApConfiguration();
|
||||
if (config != null) {
|
||||
mPassword = config.preSharedKey;
|
||||
} else {
|
||||
if (config == null || (config.getAuthType() == WifiConfiguration.KeyMgmt.WPA2_PSK
|
||||
&& TextUtils.isEmpty(config.preSharedKey))) {
|
||||
mPassword = generateRandomPassword();
|
||||
} else {
|
||||
mPassword = config.preSharedKey;
|
||||
}
|
||||
((ValidatedEditTextPreference) mPreference).setValidator(this);
|
||||
((ValidatedEditTextPreference) mPreference).setIsPassword(true);
|
||||
@@ -68,17 +68,27 @@ public class WifiTetherPasswordPreferenceController extends WifiTetherBasePrefer
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
/**
|
||||
* This method returns the current password if it is valid for the indicated security type. If
|
||||
* the password currently set is invalid it will forcefully set a random password that is valid.
|
||||
*
|
||||
* @param securityType The security type for the password.
|
||||
* @return The current password if it is valid for the indicated security type. A new randomly
|
||||
* generated password if it is not.
|
||||
*/
|
||||
public String getPasswordValidated(int securityType) {
|
||||
// don't actually overwrite unless we get a new config in case it was accidentally toggled.
|
||||
if (securityType == WifiConfiguration.KeyMgmt.NONE) {
|
||||
return "";
|
||||
} else if (!isTextValid(mPassword)) {
|
||||
mPassword = generateRandomPassword();
|
||||
updatePasswordDisplay((EditTextPreference) mPreference);
|
||||
}
|
||||
return mPassword;
|
||||
}
|
||||
|
||||
public int getSecuritySettingForPassword() {
|
||||
// We should return NONE when no password is set
|
||||
if (TextUtils.isEmpty(mPassword)) {
|
||||
return WifiConfiguration.KeyMgmt.NONE;
|
||||
}
|
||||
// Only other currently supported type is WPA2 so we'll try that
|
||||
return WifiConfiguration.KeyMgmt.WPA2_PSK;
|
||||
public void updateVisibility(int securityType) {
|
||||
mPreference.setVisible(securityType != WifiConfiguration.KeyMgmt.NONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,9 +108,11 @@ public class WifiTetherPasswordPreferenceController extends WifiTetherBasePrefer
|
||||
if (!TextUtils.isEmpty(mPassword)) {
|
||||
pref.setIsSummaryPassword(true);
|
||||
pref.setSummary(mPassword);
|
||||
pref.setVisible(true);
|
||||
} else {
|
||||
pref.setIsSummaryPassword(false);
|
||||
pref.setSummary(R.string.wifi_hotspot_no_password_subtext);
|
||||
pref.setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ public class WifiTetherPreferenceController extends AbstractPreferenceController
|
||||
private static final String WIFI_TETHER_SETTINGS = "wifi_tether";
|
||||
private static final IntentFilter AIRPLANE_INTENT_FILTER = new IntentFilter(
|
||||
Intent.ACTION_AIRPLANE_MODE_CHANGED);
|
||||
private static final int ID_NULL = -1;
|
||||
|
||||
private final ConnectivityManager mConnectivityManager;
|
||||
private final String[] mWifiRegexs;
|
||||
@@ -152,7 +153,7 @@ public class WifiTetherPreferenceController extends AbstractPreferenceController
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
|
||||
clearSummaryForAirplaneMode();
|
||||
clearSummaryForAirplaneMode(R.string.wifi_hotspot_off_subtext);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -194,10 +195,16 @@ public class WifiTetherPreferenceController extends AbstractPreferenceController
|
||||
}
|
||||
|
||||
private void clearSummaryForAirplaneMode() {
|
||||
clearSummaryForAirplaneMode(ID_NULL);
|
||||
}
|
||||
|
||||
private void clearSummaryForAirplaneMode(int defaultId) {
|
||||
boolean isAirplaneMode = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
|
||||
if (isAirplaneMode) {
|
||||
mPreference.setSummary(R.string.wifi_tether_disabled_by_airplane);
|
||||
} else if (defaultId != ID_NULL){
|
||||
mPreference.setSummary(defaultId);
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.android.settings.wifi.tether;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.net.wifi.WifiConfiguration;
|
||||
import android.support.v7.preference.ListPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
public class WifiTetherSecurityPreferenceController extends WifiTetherBasePreferenceController {
|
||||
|
||||
private static final String PREF_KEY = "wifi_tether_security";
|
||||
|
||||
private final String[] mSecurityEntries;
|
||||
private int mSecurityValue;
|
||||
|
||||
public WifiTetherSecurityPreferenceController(Context context,
|
||||
OnTetherConfigUpdateListener listener) {
|
||||
super(context, listener);
|
||||
mSecurityEntries = mContext.getResources().getStringArray(R.array.wifi_tether_security);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return PREF_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDisplay() {
|
||||
final WifiConfiguration config = mWifiManager.getWifiApConfiguration();
|
||||
if (config != null && config.getAuthType() == WifiConfiguration.KeyMgmt.NONE) {
|
||||
mSecurityValue = WifiConfiguration.KeyMgmt.NONE;
|
||||
|
||||
} else {
|
||||
mSecurityValue = WifiConfiguration.KeyMgmt.WPA2_PSK;
|
||||
}
|
||||
|
||||
final ListPreference preference = (ListPreference) mPreference;
|
||||
preference.setSummary(getSummaryForSecurityType(mSecurityValue));
|
||||
preference.setValue(String.valueOf(mSecurityValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
mSecurityValue = Integer.parseInt((String) newValue);
|
||||
preference.setSummary(getSummaryForSecurityType(mSecurityValue));
|
||||
mListener.onTetherConfigUpdated();
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getSecurityType() {
|
||||
return mSecurityValue;
|
||||
}
|
||||
|
||||
private String getSummaryForSecurityType(int securityType) {
|
||||
if (securityType == WifiConfiguration.KeyMgmt.NONE) {
|
||||
return mSecurityEntries[1];
|
||||
}
|
||||
// WPA2 PSK
|
||||
return mSecurityEntries[0];
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,6 @@ import android.net.wifi.WifiManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserManager;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
@@ -41,7 +40,6 @@ import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class WifiTetherSettings extends RestrictedDashboardFragment
|
||||
implements WifiTetherBasePreferenceController.OnTetherConfigUpdateListener {
|
||||
@@ -54,6 +52,7 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
|
||||
private WifiTetherSSIDPreferenceController mSSIDPreferenceController;
|
||||
private WifiTetherPasswordPreferenceController mPasswordPreferenceController;
|
||||
private WifiTetherApBandPreferenceController mApBandPreferenceController;
|
||||
private WifiTetherSecurityPreferenceController mSecurityPreferenceController;
|
||||
|
||||
private WifiManager mWifiManager;
|
||||
private boolean mRestartWifiApAfterConfigChange;
|
||||
@@ -128,10 +127,12 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
|
||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||
final List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
mSSIDPreferenceController = new WifiTetherSSIDPreferenceController(context, this);
|
||||
mSecurityPreferenceController = new WifiTetherSecurityPreferenceController(context, this);
|
||||
mPasswordPreferenceController = new WifiTetherPasswordPreferenceController(context, this);
|
||||
mApBandPreferenceController = new WifiTetherApBandPreferenceController(context, this);
|
||||
|
||||
controllers.add(mSSIDPreferenceController);
|
||||
controllers.add(mSecurityPreferenceController);
|
||||
controllers.add(mPasswordPreferenceController);
|
||||
controllers.add(mApBandPreferenceController);
|
||||
controllers.add(
|
||||
@@ -142,6 +143,8 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
|
||||
@Override
|
||||
public void onTetherConfigUpdated() {
|
||||
final WifiConfiguration config = buildNewConfig();
|
||||
mPasswordPreferenceController.updateVisibility(config.getAuthType());
|
||||
|
||||
/**
|
||||
* if soft AP is stopped, bring up
|
||||
* else restart with new config
|
||||
@@ -158,11 +161,11 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
|
||||
|
||||
private WifiConfiguration buildNewConfig() {
|
||||
final WifiConfiguration config = new WifiConfiguration();
|
||||
final int securityType = mSecurityPreferenceController.getSecurityType();
|
||||
|
||||
config.SSID = mSSIDPreferenceController.getSSID();
|
||||
config.preSharedKey = mPasswordPreferenceController.getPassword();
|
||||
config.allowedKeyManagement.set(
|
||||
mPasswordPreferenceController.getSecuritySettingForPassword());
|
||||
config.allowedKeyManagement.set(securityType);
|
||||
config.preSharedKey = mPasswordPreferenceController.getPasswordValidated(securityType);
|
||||
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
|
||||
config.apBand = mApBandPreferenceController.getBandIndex();
|
||||
return config;
|
||||
@@ -176,6 +179,8 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
|
||||
private void updateDisplayWithNewConfig() {
|
||||
use(WifiTetherSSIDPreferenceController.class)
|
||||
.updateDisplay();
|
||||
use(WifiTetherSecurityPreferenceController.class)
|
||||
.updateDisplay();
|
||||
use(WifiTetherPasswordPreferenceController.class)
|
||||
.updateDisplay();
|
||||
use(WifiTetherApBandPreferenceController.class)
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
<bool name="config_show_wifi_ip_address">false</bool>
|
||||
<bool name="config_show_wifi_mac_address">false</bool>
|
||||
<bool name="config_disable_uninstall_update">true</bool>
|
||||
<bool name="config_show_logical_camera_default">false</bool>
|
||||
|
||||
<!-- List of a11y components on the device allowed to be enabled by Settings Slices -->
|
||||
<string-array name="config_settings_slices_accessibility_components" translatable="false">
|
||||
|
||||
@@ -22,4 +22,5 @@
|
||||
<bool name="config_show_connectivity_monitor">true</bool>
|
||||
<bool name="config_display_recent_apps">true</bool>
|
||||
<bool name="config_wifi_support_connected_mac_randomization">true</bool>
|
||||
</resources>
|
||||
<bool name="config_show_logical_camera_default">true</bool>
|
||||
</resources>
|
||||
|
||||
@@ -43,6 +43,7 @@ public class BluetoothDeviceNamePreferenceControllerTest {
|
||||
|
||||
private static final String DEVICE_NAME = "Nightshade";
|
||||
private static final int ORDER = 1;
|
||||
private static final String KEY_DEVICE_NAME = "test_key_name";
|
||||
|
||||
private Context mContext;
|
||||
@Mock
|
||||
@@ -61,8 +62,9 @@ public class BluetoothDeviceNamePreferenceControllerTest {
|
||||
|
||||
when(mPreferenceScreen.getContext()).thenReturn(mContext);
|
||||
mPreference = new Preference(mContext);
|
||||
mPreference.setKey(BluetoothDeviceNamePreferenceController.KEY_DEVICE_NAME);
|
||||
mController = spy(new BluetoothDeviceNamePreferenceController(mContext, mLocalAdapter));
|
||||
mPreference.setKey(KEY_DEVICE_NAME);
|
||||
mController = spy(new BluetoothDeviceNamePreferenceController(mContext, mLocalAdapter,
|
||||
KEY_DEVICE_NAME));
|
||||
doReturn(DEVICE_NAME).when(mController).getDeviceName();
|
||||
}
|
||||
|
||||
@@ -82,7 +84,7 @@ public class BluetoothDeviceNamePreferenceControllerTest {
|
||||
Preference preference =
|
||||
mController.createBluetoothDeviceNamePreference(mPreferenceScreen, ORDER);
|
||||
|
||||
assertThat(preference.getKey()).isEqualTo(mController.KEY_DEVICE_NAME);
|
||||
assertThat(preference.getKey()).isEqualTo(mController.getPreferenceKey());
|
||||
assertThat(preference.getOrder()).isEqualTo(ORDER);
|
||||
verify(mPreferenceScreen).addPreference(preference);
|
||||
}
|
||||
|
||||
@@ -67,8 +67,9 @@ public class BluetoothDeviceRenamePreferenceControllerTest {
|
||||
mPreference = new Preference(mContext);
|
||||
mPreference.setKey(PREF_KEY);
|
||||
|
||||
mController = spy(new BluetoothDeviceRenamePreferenceController(
|
||||
mContext, PREF_KEY, mFragment, mLocalAdapter));
|
||||
mController = spy(new BluetoothDeviceRenamePreferenceController(mContext, mLocalAdapter,
|
||||
PREF_KEY));
|
||||
mController.setFragment(mFragment);
|
||||
doReturn(DEVICE_NAME).when(mController).getDeviceName();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
package com.android.settings.connecteddevice;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
|
||||
import android.content.Context;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.nfc.NfcPreferenceController;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowNfcAdapter;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(shadows = ShadowNfcAdapter.class)
|
||||
public class AdvancedConnectedDeviceControllerTest {
|
||||
|
||||
private static final String KEY = "test_key";
|
||||
|
||||
private Context mContext;
|
||||
private NfcPreferenceController mNfcController;
|
||||
private ShadowNfcAdapter mShadowNfcAdapter;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
mNfcController = new NfcPreferenceController(mContext);
|
||||
mShadowNfcAdapter = shadowOf(ShadowNfcAdapter.getNfcAdapter(mContext));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_returnStatusIsAvailable() {
|
||||
AdvancedConnectedDeviceController controller =
|
||||
new AdvancedConnectedDeviceController(mContext, KEY);
|
||||
|
||||
assertThat(controller.getAvailabilityStatus()).isEqualTo(
|
||||
AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConnectedDevicesSummaryResourceId_NFCAndDrivingModeAvailable() {
|
||||
// NFC available, driving mode available
|
||||
final boolean isDrivingModeAvailable = true;
|
||||
mShadowNfcAdapter.setEnabled(true);
|
||||
assertThat(AdvancedConnectedDeviceController
|
||||
.getConnectedDevicesSummaryResourceId(mNfcController, isDrivingModeAvailable))
|
||||
.isEqualTo(R.string.connected_devices_dashboard_summary);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConnectedDevicesSummaryResourceId_NFCAvailableAndDrivingModeNotAvailable() {
|
||||
// NFC is available, driving mode not available
|
||||
final boolean isDrivingModeAvailable = false;
|
||||
mShadowNfcAdapter.setEnabled(true);
|
||||
assertThat(AdvancedConnectedDeviceController
|
||||
.getConnectedDevicesSummaryResourceId(mNfcController, isDrivingModeAvailable))
|
||||
.isEqualTo(R.string.connected_devices_dashboard_no_driving_mode_summary);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConnectedDevicesSummaryResourceId_NFCNotAvailableDrivingModeAvailable() {
|
||||
// NFC not available, driving mode available
|
||||
final boolean isDrivingModeAvailable = true;
|
||||
ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null);
|
||||
assertThat(AdvancedConnectedDeviceController
|
||||
.getConnectedDevicesSummaryResourceId(mNfcController, isDrivingModeAvailable))
|
||||
.isEqualTo(R.string.connected_devices_dashboard_no_nfc_summary);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConnectedDevicesSummaryResourceId_NFCAndDrivingModeNotAvailable() {
|
||||
// NFC not available, driving mode not available
|
||||
final boolean isDrivingModeAvailable = false;
|
||||
ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null);
|
||||
assertThat(AdvancedConnectedDeviceController
|
||||
.getConnectedDevicesSummaryResourceId(mNfcController, isDrivingModeAvailable))
|
||||
.isEqualTo(R.string.connected_devices_dashboard_no_driving_mode_no_nfc_summary);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
package com.android.settings.connecteddevice;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
import android.support.v7.preference.Preference;
|
||||
|
||||
import com.android.settings.bluetooth.BluetoothDeviceUpdater;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class PreviouslyConnectedDevicePreferenceControllerTest {
|
||||
|
||||
private final String KEY = "test_key";
|
||||
|
||||
@Mock
|
||||
private DashboardFragment mDashboardFragment;
|
||||
@Mock
|
||||
private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
|
||||
private Context mContext;
|
||||
private PreviouslyConnectedDevicePreferenceController mPreConnectedDeviceController;
|
||||
private Preference mPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
doReturn(mContext).when(mDashboardFragment).getContext();
|
||||
doReturn(mPackageManager).when(mContext).getPackageManager();
|
||||
mPreConnectedDeviceController =
|
||||
new PreviouslyConnectedDevicePreferenceController(mContext, KEY);
|
||||
mPreConnectedDeviceController.setBluetoothDeviceUpdater(mBluetoothDeviceUpdater);
|
||||
|
||||
mPreference = new Preference(mContext);
|
||||
mPreConnectedDeviceController.setPreference(mPreference);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void callbackCanRegisterAndUnregister() {
|
||||
// register the callback in onStart()
|
||||
mPreConnectedDeviceController.onStart();
|
||||
verify(mBluetoothDeviceUpdater).registerCallback();
|
||||
|
||||
// unregister the callback in onStop()
|
||||
mPreConnectedDeviceController.onStop();
|
||||
verify(mBluetoothDeviceUpdater).unregisterCallback();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_noBluetoothFeature_returnUnSupported() {
|
||||
doReturn(false).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
|
||||
assertThat(mPreConnectedDeviceController.getAvailabilityStatus()).isEqualTo(
|
||||
CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
@Test
|
||||
public void getAvailabilityStatus_hasBluetoothFeature_returnSupported() {
|
||||
doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
|
||||
assertThat(mPreConnectedDeviceController.getAvailabilityStatus()).isEqualTo(
|
||||
AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceAdded_addFirstDevice_preferenceIsEnable() {
|
||||
doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
|
||||
mPreConnectedDeviceController.setPreferenceSize(0);
|
||||
mPreConnectedDeviceController.onDeviceAdded(mPreference);
|
||||
|
||||
assertThat(mPreference.isEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeviceRemoved_removeLastDevice_preferenceIsDisable() {
|
||||
doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
|
||||
mPreConnectedDeviceController.setPreferenceSize(1);
|
||||
mPreConnectedDeviceController.onDeviceRemoved(mPreference);
|
||||
|
||||
assertThat(mPreference.isEnabled()).isFalse();
|
||||
}
|
||||
}
|
||||
@@ -162,13 +162,6 @@ public class SuggestionFeatureProviderImplTest {
|
||||
assertThat(suggestions).hasSize(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nightDisplaySuggestion_isNotCompleted_byDefault() {
|
||||
final ComponentName componentName =
|
||||
new ComponentName(mContext, NightDisplaySuggestionActivity.class);
|
||||
assertThat(mProvider.isSuggestionComplete(mContext, componentName)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSmartSuggestionEnabledTaggedData_disabled() {
|
||||
assertThat(mProvider.getLoggingTaggedData(mContext)).asList().containsExactly(
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.development;
|
||||
|
||||
import static com.android.settings.development.BluetoothA2dpHwOffloadPreferenceController.A2DP_OFFLOAD_DISABLED_PROPERTY;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.SystemProperties;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class BluetoothA2dpHwOffloadPreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
@Mock
|
||||
private DevelopmentSettingsDashboardFragment mFragment;
|
||||
|
||||
private Context mContext;
|
||||
private SwitchPreference mPreference;
|
||||
private BluetoothA2dpHwOffloadPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mPreference = new SwitchPreference(mContext);
|
||||
mController = spy(new BluetoothA2dpHwOffloadPreferenceController(mContext, mFragment));
|
||||
when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
|
||||
.thenReturn(mPreference);
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onA2dpHwDialogConfirmed_shouldChangeProperty() {
|
||||
SystemProperties.set(A2DP_OFFLOAD_DISABLED_PROPERTY, Boolean.toString(false));
|
||||
|
||||
mController.onA2dpHwDialogConfirmed();
|
||||
final boolean mode = SystemProperties.getBoolean(A2DP_OFFLOAD_DISABLED_PROPERTY, false);
|
||||
assertThat(mode).isTrue();
|
||||
|
||||
mController.onA2dpHwDialogConfirmed();
|
||||
final boolean mode2 = SystemProperties.getBoolean(A2DP_OFFLOAD_DISABLED_PROPERTY, false);
|
||||
assertThat(mode2).isFalse();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.development;
|
||||
|
||||
import static com.android.settings.development.LogicalCameraDefaultPreferenceController.ENG_BUILD;
|
||||
import static com.android.settings.development.LogicalCameraDefaultPreferenceController.USERDEBUG_BUILD;
|
||||
import static com.android.settings.development.LogicalCameraDefaultPreferenceController.USER_BUILD;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.os.SystemProperties;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class LogicalCameraDefaultPreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
@Mock
|
||||
private SwitchPreference mPreference;
|
||||
|
||||
private LogicalCameraDefaultPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mController = new LogicalCameraDefaultPreferenceController(RuntimeEnvironment.application);
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
|
||||
mController.displayPreference(mScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "mcc999")
|
||||
public void isAvailable_withConfigNoShow_shouldReturnFalse() {
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_withUserdebugBuild_shouldReturnTrue() {
|
||||
SystemProperties.set(LogicalCameraDefaultPreferenceController.BUILD_TYPE, USERDEBUG_BUILD);
|
||||
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_withEngBuild_shouldReturnTrue() {
|
||||
SystemProperties.set(LogicalCameraDefaultPreferenceController.BUILD_TYPE, ENG_BUILD);
|
||||
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_withUserBuild_shouldReturnTrue() {
|
||||
SystemProperties.set(LogicalCameraDefaultPreferenceController.BUILD_TYPE, USER_BUILD);
|
||||
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_logicalCameraDefaultEnabled_shouldCheckedPreference() {
|
||||
SystemProperties.set(LogicalCameraDefaultPreferenceController.PROPERTY_LOGICAL_CAMERA_DEFAULT,
|
||||
Integer.toString(LogicalCameraDefaultPreferenceController.ENABLED));
|
||||
SystemProperties.set(LogicalCameraDefaultPreferenceController.BUILD_TYPE, USERDEBUG_BUILD);
|
||||
|
||||
mController.updateState(mScreen);
|
||||
|
||||
verify(mPreference).setChecked(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_logicalCameraDefaultEnabled_shouldUncheckedPreference() {
|
||||
SystemProperties.set(LogicalCameraDefaultPreferenceController.PROPERTY_LOGICAL_CAMERA_DEFAULT,
|
||||
Integer.toString(LogicalCameraDefaultPreferenceController.DISABLED));
|
||||
SystemProperties.set(
|
||||
LogicalCameraDefaultPreferenceController.BUILD_TYPE, USERDEBUG_BUILD);
|
||||
|
||||
mController.updateState(mScreen);
|
||||
|
||||
verify(mPreference).setChecked(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_preferenceChecked_shouldEnableLogicalCameraDefault() {
|
||||
mController.onPreferenceChange(mPreference, true);
|
||||
|
||||
assertThat(Integer.toString(LogicalCameraDefaultPreferenceController.ENABLED)).isEqualTo(
|
||||
SystemProperties.get(
|
||||
LogicalCameraDefaultPreferenceController.PROPERTY_LOGICAL_CAMERA_DEFAULT,
|
||||
Integer.toString(LogicalCameraDefaultPreferenceController.ENABLED)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_preferenceUnchecked_shouldDisableLogicalCameraDefault() {
|
||||
mController.onPreferenceChange(mPreference, false);
|
||||
|
||||
assertThat(Integer.toString(LogicalCameraDefaultPreferenceController.DISABLED)).isEqualTo(
|
||||
SystemProperties.get(
|
||||
LogicalCameraDefaultPreferenceController.PROPERTY_LOGICAL_CAMERA_DEFAULT,
|
||||
Integer.toString(LogicalCameraDefaultPreferenceController.ENABLED)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeveloperOptionsSwitchDisabled_preferenceShouldBeEnabled() {
|
||||
mController.onDeveloperOptionsSwitchDisabled();
|
||||
|
||||
verify(mPreference).setEnabled(false);
|
||||
verify(mPreference).setChecked(false);
|
||||
assertThat(Integer.toString(LogicalCameraDefaultPreferenceController.DISABLED)).isEqualTo(
|
||||
SystemProperties.get(
|
||||
LogicalCameraDefaultPreferenceController.PROPERTY_LOGICAL_CAMERA_DEFAULT,
|
||||
Integer.toString(LogicalCameraDefaultPreferenceController.ENABLED)));
|
||||
}
|
||||
}
|
||||
@@ -6,15 +6,22 @@ import android.app.Application;
|
||||
import android.content.ComponentName;
|
||||
import android.provider.Settings.Secure;
|
||||
import com.android.internal.app.ColorDisplayController;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Settings.NightDisplaySuggestionActivity;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
SettingsShadowResources.class
|
||||
})
|
||||
public class NightDisplayPreferenceControllerTest {
|
||||
|
||||
private NightDisplayPreferenceController mPreferenceController;
|
||||
@@ -27,6 +34,7 @@ public class NightDisplayPreferenceControllerTest {
|
||||
@After
|
||||
public void tearDown() {
|
||||
mPreferenceController = null;
|
||||
SettingsShadowResources.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -58,4 +66,16 @@ public class NightDisplayPreferenceControllerTest {
|
||||
new ComponentName(context, NightDisplaySuggestionActivity.class);
|
||||
assertThat(mPreferenceController.isSuggestionComplete(context)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nightDisplaySuggestion_isCompleted_ifDisabled() {
|
||||
final Application context = RuntimeEnvironment.application;
|
||||
Secure.putInt(context.getContentResolver(),
|
||||
Secure.NIGHT_DISPLAY_AUTO_MODE, ColorDisplayController.AUTO_MODE_DISABLED);
|
||||
SettingsShadowResources.overrideResource(R.bool.config_night_light_suggestion_enabled, false);
|
||||
|
||||
final ComponentName componentName =
|
||||
new ComponentName(context, NightDisplaySuggestionActivity.class);
|
||||
assertThat(mPreferenceController.isSuggestionComplete(context)).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,8 @@ import com.android.internal.os.BatterySipper;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.anomaly.Anomaly;
|
||||
import com.android.settings.fuelgauge.batterytip.AnomalyInfo;
|
||||
import com.android.settings.fuelgauge.batterytip.StatsManagerConfig;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
||||
@@ -106,6 +108,9 @@ public class BatteryUtilsTest {
|
||||
private static final String HIGH_SDK_PACKAGE = "com.android.package.high";
|
||||
private static final String LOW_SDK_PACKAGE = "com.android.package.low";
|
||||
|
||||
private static final String INFO_EXCESSIVE = "anomaly_type=4,auto_restriction=false";
|
||||
private static final String INFO_WAKELOCK = "anomaly_type=1,auto_restriction=false";
|
||||
|
||||
@Mock
|
||||
private BatteryStats.Uid mUid;
|
||||
@Mock
|
||||
@@ -146,6 +151,7 @@ public class BatteryUtilsTest {
|
||||
private ApplicationInfo mLowApplicationInfo;
|
||||
@Mock
|
||||
private PowerWhitelistBackend mPowerWhitelistBackend;
|
||||
private AnomalyInfo mAnomalyInfo;
|
||||
private BatteryUtils mBatteryUtils;
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
private PowerUsageFeatureProvider mProvider;
|
||||
@@ -211,6 +217,7 @@ public class BatteryUtilsTest {
|
||||
mBatteryUtils.mPowerUsageFeatureProvider = mProvider;
|
||||
doReturn(0L).when(mBatteryUtils)
|
||||
.getForegroundServiceTotalTimeUs(any(BatteryStats.Uid.class), anyLong());
|
||||
mAnomalyInfo = new AnomalyInfo(INFO_WAKELOCK);
|
||||
|
||||
mUsageList = new ArrayList<>();
|
||||
mUsageList.add(mNormalBatterySipper);
|
||||
@@ -532,15 +539,26 @@ public class BatteryUtilsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsLegacyApp_SdkLowerThanO_ReturnTrue() {
|
||||
public void testIsPreOApp_SdkLowerThanO_ReturnTrue() {
|
||||
assertThat(mBatteryUtils.isPreOApp(LOW_SDK_PACKAGE)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsLegacyApp_SdkLargerOrEqualThanO_ReturnFalse() {
|
||||
public void testIsPreOApp_SdkLargerOrEqualThanO_ReturnFalse() {
|
||||
assertThat(mBatteryUtils.isPreOApp(HIGH_SDK_PACKAGE)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsPreOApp_containPreOApp_ReturnTrue() {
|
||||
assertThat(
|
||||
mBatteryUtils.isPreOApp(new String[]{HIGH_SDK_PACKAGE, LOW_SDK_PACKAGE})).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsPreOApp_emptyList_ReturnFalse() {
|
||||
assertThat(mBatteryUtils.isPreOApp(new String[]{})).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetForceAppStandby_forcePreOApp_forceTwoRestrictions() {
|
||||
mBatteryUtils.setForceAppStandby(UID, LOW_SDK_PACKAGE, AppOpsManager.MODE_IGNORED);
|
||||
@@ -591,7 +609,8 @@ public class BatteryUtilsTest {
|
||||
doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);
|
||||
mHighApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
|
||||
|
||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID)).isTrue();
|
||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID,
|
||||
mAnomalyInfo)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -600,7 +619,8 @@ public class BatteryUtilsTest {
|
||||
doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);
|
||||
mHighApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
|
||||
|
||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID)).isTrue();
|
||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID,
|
||||
mAnomalyInfo)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -608,7 +628,8 @@ public class BatteryUtilsTest {
|
||||
final int systemUid = Process.ROOT_UID;
|
||||
doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(systemUid);
|
||||
|
||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, systemUid)).isTrue();
|
||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, systemUid,
|
||||
mAnomalyInfo)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -616,13 +637,33 @@ public class BatteryUtilsTest {
|
||||
doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);
|
||||
doReturn(true).when(mPowerWhitelistBackend).isWhitelisted(new String[]{HIGH_SDK_PACKAGE});
|
||||
|
||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID)).isTrue();
|
||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID,
|
||||
mAnomalyInfo)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldHideAnomaly_normalApp_returnFalse() {
|
||||
doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);
|
||||
|
||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID)).isFalse();
|
||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID,
|
||||
mAnomalyInfo)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldHideAnomaly_excessivePriorOApp_returnFalse() {
|
||||
doReturn(new String[]{LOW_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);
|
||||
mAnomalyInfo = new AnomalyInfo(INFO_EXCESSIVE);
|
||||
|
||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID,
|
||||
mAnomalyInfo)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldHideAnomaly_excessiveOApp_returnTrue() {
|
||||
doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);
|
||||
mAnomalyInfo = new AnomalyInfo(INFO_EXCESSIVE);
|
||||
|
||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID,
|
||||
mAnomalyInfo)).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ public class AnomalyDetectionJobServiceTest {
|
||||
doReturn(false).when(mPowerWhitelistBackend).isSysWhitelisted(SYSTEM_PACKAGE);
|
||||
doReturn(Process.FIRST_APPLICATION_UID).when(
|
||||
mAnomalyDetectionJobService).extractUidFromStatsDimensionsValue(any());
|
||||
doReturn(true).when(mBatteryUtils).shouldHideAnomaly(any(), anyInt());
|
||||
doReturn(true).when(mBatteryUtils).shouldHideAnomaly(any(), anyInt(), any());
|
||||
|
||||
mAnomalyDetectionJobService.saveAnomalyToDatabase(mContext,
|
||||
mUserManager, mBatteryDatabaseManager, mBatteryUtils, mPolicy,
|
||||
|
||||
@@ -60,6 +60,7 @@ public class RestrictAppTipTest {
|
||||
private RestrictAppTip mHandledBatteryTip;
|
||||
private RestrictAppTip mInvisibleBatteryTip;
|
||||
private List<AppInfo> mUsageAppList;
|
||||
private AppInfo mAppInfo;
|
||||
@Mock
|
||||
private ApplicationInfo mApplicationInfo;
|
||||
@Mock
|
||||
@@ -77,15 +78,16 @@ public class RestrictAppTipTest {
|
||||
PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.MATCH_ANY_USER);
|
||||
doReturn(DISPLAY_NAME).when(mApplicationInfo).loadLabel(mPackageManager);
|
||||
|
||||
mUsageAppList = new ArrayList<>();
|
||||
mUsageAppList.add(new AppInfo.Builder()
|
||||
mAppInfo = new AppInfo.Builder()
|
||||
.setPackageName(PACKAGE_NAME)
|
||||
.addAnomalyType(ANOMALY_WAKEUP)
|
||||
.addAnomalyType(ANOMALY_WAKELOCK)
|
||||
.build());
|
||||
.build();
|
||||
mUsageAppList = new ArrayList<>();
|
||||
mUsageAppList.add(mAppInfo);
|
||||
mNewBatteryTip = new RestrictAppTip(BatteryTip.StateType.NEW, mUsageAppList);
|
||||
mHandledBatteryTip = new RestrictAppTip(BatteryTip.StateType.HANDLED, mUsageAppList);
|
||||
mInvisibleBatteryTip = new RestrictAppTip(BatteryTip.StateType.INVISIBLE, mUsageAppList);
|
||||
mInvisibleBatteryTip = new RestrictAppTip(BatteryTip.StateType.INVISIBLE, new ArrayList<>());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -164,6 +166,13 @@ public class RestrictAppTipTest {
|
||||
assertThat(mHandledBatteryTip.getState()).isEqualTo(BatteryTip.StateType.NEW);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void update_newHandledAnomalyComes_containHandledAnomaly() {
|
||||
mInvisibleBatteryTip.updateState(mHandledBatteryTip);
|
||||
assertThat(mInvisibleBatteryTip.getState()).isEqualTo(BatteryTip.StateType.HANDLED);
|
||||
assertThat(mInvisibleBatteryTip.getRestrictAppList()).containsExactly(mAppInfo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toString_containsAppData() {
|
||||
assertThat(mNewBatteryTip.toString()).isEqualTo(
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.android.settings.notification;
|
||||
|
||||
import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.provider.Settings;
|
||||
import android.support.v4.graphics.drawable.IconCompat;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.SliceTester;
|
||||
import com.android.settings.testutils.shadow.ShadowNotificationManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.SliceItem;
|
||||
import androidx.slice.SliceMetadata;
|
||||
import androidx.slice.SliceProvider;
|
||||
import androidx.slice.core.SliceAction;
|
||||
import androidx.slice.widget.SliceLiveData;
|
||||
|
||||
@Config(shadows = ShadowNotificationManager.class)
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class ZenModeSliceBuilderTest {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
|
||||
// Prevent crash in SliceMetadata.
|
||||
Resources resources = spy(mContext.getResources());
|
||||
doReturn(60).when(resources).getDimensionPixelSize(anyInt());
|
||||
doReturn(resources).when(mContext).getResources();
|
||||
|
||||
// Set-up specs for SliceMetadata.
|
||||
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getZenModeSlice_correctSliceContent() {
|
||||
final Slice dndSlice = ZenModeSliceBuilder.getSlice(mContext);
|
||||
final SliceMetadata metadata = SliceMetadata.from(mContext, dndSlice);
|
||||
|
||||
final List<SliceAction> toggles = metadata.getToggles();
|
||||
assertThat(toggles).hasSize(1);
|
||||
|
||||
final SliceAction primaryAction = metadata.getPrimaryAction();
|
||||
assertThat(primaryAction.getIcon()).isNull();
|
||||
|
||||
final List<SliceItem> sliceItems = dndSlice.getItems();
|
||||
SliceTester.assertTitle(sliceItems, mContext.getString(R.string.zen_mode_settings_title));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleUriChange_turnOn_zenModeTurnsOn() {
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra(EXTRA_TOGGLE_STATE, true);
|
||||
NotificationManager.from(mContext).setZenMode(Settings.Global.ZEN_MODE_OFF, null, "");
|
||||
|
||||
ZenModeSliceBuilder.handleUriChange(mContext, intent);
|
||||
|
||||
final int zenMode = NotificationManager.from(mContext).getZenMode();
|
||||
assertThat(zenMode).isEqualTo(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleUriChange_turnOff_zenModeTurnsOff() {
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra(EXTRA_TOGGLE_STATE, false);
|
||||
NotificationManager.from(mContext).setZenMode(
|
||||
Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, "");
|
||||
|
||||
ZenModeSliceBuilder.handleUriChange(mContext, intent);
|
||||
|
||||
final int zenMode = NotificationManager.from(mContext).getZenMode();
|
||||
assertThat(zenMode).isEqualTo(Settings.Global.ZEN_MODE_OFF);
|
||||
}
|
||||
}
|
||||
@@ -85,6 +85,7 @@ public class ZenModeVisEffectsCustomPreferenceControllerTest {
|
||||
ReflectionHelpers.setField(mController, "mBackend", mBackend);
|
||||
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
|
||||
mController.displayPreference(mScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
package com.android.settings.search;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
@@ -24,6 +23,7 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.job.JobScheduler;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
@@ -47,7 +47,7 @@ public class DeviceIndexFeatureProviderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyDisabled() {
|
||||
public void updateIndex_disabled_shouldDoNothing() {
|
||||
when(mProvider.isIndexingEnabled()).thenReturn(false);
|
||||
|
||||
mProvider.updateIndex(mActivity, false);
|
||||
@@ -55,7 +55,20 @@ public class DeviceIndexFeatureProviderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyIndexing() {
|
||||
public void updateIndex_enabled_unprovisioned_shouldDoNothing() {
|
||||
when(mProvider.isIndexingEnabled()).thenReturn(true);
|
||||
Settings.Global.putInt(mActivity.getContentResolver(),
|
||||
Settings.Global.DEVICE_PROVISIONED, 0);
|
||||
|
||||
mProvider.updateIndex(mActivity, false);
|
||||
|
||||
verify(mProvider, never()).index(any(), any(), any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateIndex_enabled_provisioned_shouldIndex() {
|
||||
Settings.Global.putInt(mActivity.getContentResolver(),
|
||||
Settings.Global.DEVICE_PROVISIONED, 1);
|
||||
JobScheduler jobScheduler = mock(JobScheduler.class);
|
||||
when(mProvider.isIndexingEnabled()).thenReturn(true);
|
||||
when(mActivity.getSystemService(JobScheduler.class)).thenReturn(jobScheduler);
|
||||
|
||||
@@ -18,9 +18,13 @@
|
||||
package com.android.settings.slices;
|
||||
|
||||
import static android.content.ContentResolver.SCHEME_CONTENT;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.slice.SliceManager;
|
||||
@@ -31,6 +35,8 @@ import android.net.Uri;
|
||||
import android.os.StrictMode;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
|
||||
import com.android.settings.wifi.WifiSliceBuilder;
|
||||
import com.android.settings.notification.ZenModeSliceBuilder;
|
||||
import com.android.settings.testutils.DatabaseTestUtils;
|
||||
import com.android.settings.testutils.FakeToggleController;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
@@ -45,6 +51,8 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
|
||||
@@ -70,6 +78,14 @@ public class SettingsSliceProviderTest {
|
||||
private SQLiteDatabase mDb;
|
||||
private SliceManager mManager;
|
||||
|
||||
private static final List<Uri> SPECIAL_CASE_PLATFORM_URIS = Arrays.asList(
|
||||
WifiSliceBuilder.WIFI_URI
|
||||
);
|
||||
|
||||
private static final List<Uri> SPECIAL_CASE_OEM_URIS = Arrays.asList(
|
||||
ZenModeSliceBuilder.ZEN_MODE_URI
|
||||
);
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
@@ -94,7 +110,7 @@ public class SettingsSliceProviderTest {
|
||||
@Test
|
||||
public void testInitialSliceReturned_emptySlice() {
|
||||
insertSpecialCase(KEY);
|
||||
Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
|
||||
final Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
|
||||
Slice slice = mProvider.onBindSlice(uri);
|
||||
|
||||
assertThat(slice.getUri()).isEqualTo(uri);
|
||||
@@ -104,7 +120,7 @@ public class SettingsSliceProviderTest {
|
||||
@Test
|
||||
public void testLoadSlice_returnsSliceFromAccessor() {
|
||||
insertSpecialCase(KEY);
|
||||
Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
|
||||
final Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
|
||||
|
||||
mProvider.loadSlice(uri);
|
||||
SliceData data = mProvider.mSliceWeakDataCache.get(uri);
|
||||
@@ -114,9 +130,19 @@ public class SettingsSliceProviderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadSlice_doesntCacheWithoutPin() {
|
||||
public void loadSlice_registersIntentFilter() {
|
||||
insertSpecialCase(KEY);
|
||||
Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
|
||||
final Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
|
||||
|
||||
mProvider.loadSlice(uri);
|
||||
|
||||
verify(mProvider).registerIntentToUri(eq(FakeToggleController.INTENT_FILTER), eq(uri));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadSlice_doesNotCacheWithoutPin() {
|
||||
insertSpecialCase(KEY);
|
||||
final Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
|
||||
|
||||
mProvider.loadSlice(uri);
|
||||
SliceData data = mProvider.mSliceDataCache.get(uri);
|
||||
@@ -127,7 +153,7 @@ public class SettingsSliceProviderTest {
|
||||
@Test
|
||||
public void testLoadSlice_cachesWithPin() {
|
||||
insertSpecialCase(KEY);
|
||||
Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
|
||||
final Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
|
||||
when(mManager.getPinnedSlices()).thenReturn(Arrays.asList(uri));
|
||||
|
||||
mProvider.loadSlice(uri);
|
||||
@@ -213,6 +239,7 @@ public class SettingsSliceProviderTest {
|
||||
.build();
|
||||
|
||||
final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
|
||||
descendants.removeAll(SPECIAL_CASE_OEM_URIS);
|
||||
|
||||
assertThat(descendants).isEmpty();
|
||||
}
|
||||
@@ -226,6 +253,7 @@ public class SettingsSliceProviderTest {
|
||||
.build();
|
||||
|
||||
final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
|
||||
descendants.removeAll(SPECIAL_CASE_PLATFORM_URIS);
|
||||
|
||||
assertThat(descendants).isEmpty();
|
||||
}
|
||||
@@ -239,6 +267,7 @@ public class SettingsSliceProviderTest {
|
||||
.build();
|
||||
|
||||
final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
|
||||
descendants.removeAll(SPECIAL_CASE_OEM_URIS);
|
||||
|
||||
assertThat(descendants).isEmpty();
|
||||
}
|
||||
@@ -252,16 +281,18 @@ public class SettingsSliceProviderTest {
|
||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.build();
|
||||
final Uri expectedUri = new Uri.Builder()
|
||||
final Collection<Uri> expectedUris = new HashSet<>();
|
||||
expectedUris.addAll(SPECIAL_CASE_OEM_URIS);
|
||||
expectedUris.add(new Uri.Builder()
|
||||
.scheme(SCHEME_CONTENT)
|
||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.appendPath(key)
|
||||
.build();
|
||||
.build());
|
||||
|
||||
final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
|
||||
|
||||
assertThat(descendants).containsExactly(expectedUri);
|
||||
assertThat(descendants).containsExactlyElementsIn(expectedUris);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -272,16 +303,18 @@ public class SettingsSliceProviderTest {
|
||||
.scheme(SCHEME_CONTENT)
|
||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||
.build();
|
||||
final Uri expectedUri = new Uri.Builder()
|
||||
final Collection<Uri> expectedUris = new HashSet<>();
|
||||
expectedUris.addAll(SPECIAL_CASE_OEM_URIS);
|
||||
expectedUris.add(new Uri.Builder()
|
||||
.scheme(SCHEME_CONTENT)
|
||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.appendPath(key)
|
||||
.build();
|
||||
.build());
|
||||
|
||||
final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
|
||||
|
||||
assertThat(descendants).containsExactly(expectedUri);
|
||||
assertThat(descendants).containsExactlyElementsIn(expectedUris);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -293,16 +326,18 @@ public class SettingsSliceProviderTest {
|
||||
.authority(SettingsSlicesContract.AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.build();
|
||||
final Uri expectedUri = new Uri.Builder()
|
||||
final Collection<Uri> expectedUris = new HashSet<>();
|
||||
expectedUris.addAll(SPECIAL_CASE_PLATFORM_URIS);
|
||||
expectedUris.add(new Uri.Builder()
|
||||
.scheme(SCHEME_CONTENT)
|
||||
.authority(SettingsSlicesContract.AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.appendPath(key)
|
||||
.build();
|
||||
.build());
|
||||
|
||||
final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
|
||||
|
||||
assertThat(descendants).containsExactly(expectedUri);
|
||||
assertThat(descendants).containsExactlyElementsIn(expectedUris);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -313,16 +348,18 @@ public class SettingsSliceProviderTest {
|
||||
.scheme(SCHEME_CONTENT)
|
||||
.authority(SettingsSlicesContract.AUTHORITY)
|
||||
.build();
|
||||
final Uri expectedUri = new Uri.Builder()
|
||||
final Collection<Uri> expectedUris = new HashSet<>();
|
||||
expectedUris.addAll(SPECIAL_CASE_PLATFORM_URIS);
|
||||
expectedUris.add(new Uri.Builder()
|
||||
.scheme(SCHEME_CONTENT)
|
||||
.authority(SettingsSlicesContract.AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.appendPath(key)
|
||||
.build();
|
||||
.build());
|
||||
|
||||
final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
|
||||
|
||||
assertThat(descendants).containsExactly(expectedUri);
|
||||
assertThat(descendants).containsExactlyElementsIn(expectedUris);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -334,22 +371,32 @@ public class SettingsSliceProviderTest {
|
||||
final Uri uri = new Uri.Builder()
|
||||
.scheme(SCHEME_CONTENT)
|
||||
.build();
|
||||
final Uri expectedPlatformUri = new Uri.Builder()
|
||||
final Collection<Uri> expectedUris = new HashSet<>();
|
||||
expectedUris.addAll(SPECIAL_CASE_PLATFORM_URIS);
|
||||
expectedUris.addAll(SPECIAL_CASE_OEM_URIS);
|
||||
expectedUris.add(new Uri.Builder()
|
||||
.scheme(SCHEME_CONTENT)
|
||||
.authority(SettingsSlicesContract.AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.appendPath(platformKey)
|
||||
.build();
|
||||
final Uri expectedOemUri = new Uri.Builder()
|
||||
.build());
|
||||
expectedUris.add(new Uri.Builder()
|
||||
.scheme(SCHEME_CONTENT)
|
||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.appendPath(oemKey)
|
||||
.build();
|
||||
.build());
|
||||
|
||||
final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri);
|
||||
|
||||
assertThat(descendants).containsExactly(expectedPlatformUri, expectedOemUri);
|
||||
assertThat(descendants).containsExactlyElementsIn(expectedUris);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindSlice_wifiSlice_returnsWifiSlice() {
|
||||
final Slice wifiSlice = mProvider.onBindSlice(WifiSliceBuilder.WIFI_URI);
|
||||
|
||||
assertThat(wifiSlice.getUri()).isEqualTo(WifiSliceBuilder.WIFI_URI);
|
||||
}
|
||||
|
||||
private void insertSpecialCase(String key) {
|
||||
@@ -364,7 +411,7 @@ public class SettingsSliceProviderTest {
|
||||
values.put(SlicesDatabaseHelper.IndexColumns.SCREENTITLE, "s");
|
||||
values.put(SlicesDatabaseHelper.IndexColumns.ICON_RESOURCE, 1234);
|
||||
values.put(SlicesDatabaseHelper.IndexColumns.FRAGMENT, "test");
|
||||
values.put(SlicesDatabaseHelper.IndexColumns.CONTROLLER, "test");
|
||||
values.put(SlicesDatabaseHelper.IndexColumns.CONTROLLER, PREF_CONTROLLER);
|
||||
values.put(SlicesDatabaseHelper.IndexColumns.PLATFORM_SLICE, isPlatformSlice);
|
||||
values.put(SlicesDatabaseHelper.IndexColumns.SLICE_TYPE, SliceData.SliceType.INTENT);
|
||||
|
||||
|
||||
@@ -226,7 +226,7 @@ public class AudioOutputSwitchPreferenceControllerTest {
|
||||
|
||||
mController.onPreferenceChange(mPreference, TEST_DEVICE_ADDRESS_1);
|
||||
|
||||
assertThat(mPreference.getSummary()).isEqualTo(mBluetoothDevice.getName());
|
||||
assertThat(mPreference.getSummary()).isEqualTo(TEST_DEVICE_NAME_1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -246,7 +246,7 @@ public class AudioOutputSwitchPreferenceControllerTest {
|
||||
|
||||
mController.onPreferenceChange(mPreference, TEST_DEVICE_ADDRESS_2);
|
||||
|
||||
assertThat(mPreference.getSummary()).isEqualTo(secondBluetoothDevice.getName());
|
||||
assertThat(mPreference.getSummary()).isEqualTo(TEST_DEVICE_NAME_2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.settings.sound;
|
||||
|
||||
|
||||
import static android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
|
||||
import static android.media.AudioSystem.DEVICE_OUT_HEARING_AID;
|
||||
import static android.media.AudioSystem.DEVICE_OUT_USB_HEADSET;
|
||||
@@ -93,6 +92,8 @@ public class HandsFreeProfileOutputPreferenceControllerTest {
|
||||
private HeadsetProfile mHeadsetProfile;
|
||||
@Mock
|
||||
private HearingAidProfile mHearingAidProfile;
|
||||
@Mock
|
||||
private AudioSwitchPreferenceController.AudioSwitchCallback mAudioSwitchPreferenceCallback;
|
||||
|
||||
private Context mContext;
|
||||
private PreferenceScreen mScreen;
|
||||
@@ -156,6 +157,7 @@ public class HandsFreeProfileOutputPreferenceControllerTest {
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
mScreen.addPreference(mPreference);
|
||||
mController.displayPreference(mScreen);
|
||||
mController.setCallback(mAudioSwitchPreferenceCallback);
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -251,7 +253,7 @@ public class HandsFreeProfileOutputPreferenceControllerTest {
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.isVisible()).isTrue();
|
||||
assertThat(mPreference.getSummary()).isEqualTo(mBluetoothDevice.getName());
|
||||
assertThat(mPreference.getSummary()).isEqualTo(TEST_DEVICE_NAME_1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -273,7 +275,7 @@ public class HandsFreeProfileOutputPreferenceControllerTest {
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.isVisible()).isTrue();
|
||||
assertThat(mPreference.getSummary()).isEqualTo(mSecondBluetoothDevice.getName());
|
||||
assertThat(mPreference.getSummary()).isEqualTo(TEST_DEVICE_NAME_2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -94,6 +94,8 @@ public class MediaOutputPreferenceControllerTest {
|
||||
private A2dpProfile mA2dpProfile;
|
||||
@Mock
|
||||
private HearingAidProfile mHearingAidProfile;
|
||||
@Mock
|
||||
private AudioSwitchPreferenceController.AudioSwitchCallback mAudioSwitchPreferenceCallback;
|
||||
|
||||
private Context mContext;
|
||||
private PreferenceScreen mScreen;
|
||||
@@ -157,6 +159,7 @@ public class MediaOutputPreferenceControllerTest {
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
mScreen.addPreference(mPreference);
|
||||
mController.displayPreference(mScreen);
|
||||
mController.setCallback(mAudioSwitchPreferenceCallback);
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -302,7 +305,7 @@ public class MediaOutputPreferenceControllerTest {
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.isVisible()).isTrue();
|
||||
assertThat(mPreference.getSummary()).isEqualTo(mBluetoothDevice.getName());
|
||||
assertThat(mPreference.getSummary()).isEqualTo(TEST_DEVICE_NAME_1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -323,7 +326,7 @@ public class MediaOutputPreferenceControllerTest {
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.isVisible()).isTrue();
|
||||
assertThat(mPreference.getSummary()).isEqualTo(mSecondBluetoothDevice.getName());
|
||||
assertThat(mPreference.getSummary()).isEqualTo(TEST_DEVICE_NAME_2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
package com.android.settings.testutils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
@@ -28,6 +30,9 @@ public class FakeToggleController extends TogglePreferenceController {
|
||||
|
||||
public static final String AVAILABILITY_KEY = "fake_toggle_availability_key";
|
||||
|
||||
public static final IntentFilter INTENT_FILTER = new IntentFilter(
|
||||
WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
|
||||
|
||||
private final int ON = 1;
|
||||
private final int OFF = 0;
|
||||
|
||||
@@ -52,4 +57,9 @@ public class FakeToggleController extends TogglePreferenceController {
|
||||
return Settings.Global.getInt(mContext.getContentResolver(),
|
||||
AVAILABILITY_KEY, AVAILABLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntentFilter getIntentFilter() {
|
||||
return INTENT_FILTER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.testutils;
|
||||
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.IconDrawableFactory;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
@Implements(IconDrawableFactory.class)
|
||||
public class ShadowIconDrawableFactory {
|
||||
|
||||
@Implementation
|
||||
public Drawable getBadgedIcon(ApplicationInfo appInfo) {
|
||||
return new ColorDrawable(Color.BLUE);
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.SliceItem;
|
||||
@@ -211,7 +212,7 @@ public class SliceTester {
|
||||
assertKeywords(metadata, sliceData);
|
||||
}
|
||||
|
||||
private static void assertTitle(List<SliceItem> sliceItems, String title) {
|
||||
public static void assertTitle(List<SliceItem> sliceItems, String title) {
|
||||
boolean hasTitle = false;
|
||||
for (SliceItem item : sliceItems) {
|
||||
List<SliceItem> titleItems = SliceQuery.findAll(item, FORMAT_TEXT, HINT_TITLE,
|
||||
@@ -230,8 +231,9 @@ public class SliceTester {
|
||||
|
||||
private static void assertKeywords(SliceMetadata metadata, SliceData data) {
|
||||
final List<String> keywords = metadata.getSliceKeywords();
|
||||
final Set<String> expectedKeywords = new HashSet<>(
|
||||
Arrays.asList(data.getKeywords().split(",")));
|
||||
final Set<String> expectedKeywords = Arrays.stream(data.getKeywords().split(","))
|
||||
.map(s -> s = s.trim())
|
||||
.collect(Collectors.toSet());
|
||||
expectedKeywords.add(data.getTitle());
|
||||
expectedKeywords.add(data.getScreenTitle().toString());
|
||||
assertThat(keywords).containsExactlyElementsIn(expectedKeywords);
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
@@ -39,12 +40,14 @@ import android.support.v7.preference.Preference;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.applications.LayoutPreference;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.ShadowIconDrawableFactory;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -53,6 +56,7 @@ import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class EntityHeaderControllerTest {
|
||||
@@ -68,12 +72,10 @@ public class EntityHeaderControllerTest {
|
||||
private LayoutInflater mLayoutInflater;
|
||||
private PackageInfo mInfo;
|
||||
private EntityHeaderController mController;
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
mShadowContext = RuntimeEnvironment.application;
|
||||
when(mActivity.getApplicationContext()).thenReturn(mShadowContext);
|
||||
when(mContext.getApplicationContext()).thenReturn(mContext);
|
||||
@@ -254,6 +256,23 @@ public class EntityHeaderControllerTest {
|
||||
.isEqualTo(description);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowIconDrawableFactory.class)
|
||||
public void setIcon_usingAppEntry_shouldLoadIconFromDrawableFactory() {
|
||||
final View view = mLayoutInflater
|
||||
.inflate(R.layout.settings_entity_header, null /* root */);
|
||||
final ApplicationsState.AppEntry entry = mock(ApplicationsState.AppEntry.class);
|
||||
entry.info = new ApplicationInfo();
|
||||
mController = EntityHeaderController.newInstance(mActivity, mFragment, view);
|
||||
mController.setIcon(entry).done(mActivity);
|
||||
final ImageView iconView = view.findViewById(R.id.entity_header_icon);
|
||||
|
||||
// Icon is set
|
||||
assertThat(iconView.getDrawable()).isNotNull();
|
||||
// ... and entry.icon is still empty. This means the icon didn't come from cache.
|
||||
assertThat(entry.icon).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindButton_hasAppNotifIntent_shouldShowButton() {
|
||||
final View appLinks = mLayoutInflater
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.widget;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.preference.ListPreference;
|
||||
import android.widget.ArrayAdapter;
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(shadows = ShadowBluetoothUtils.class)
|
||||
public class UpdatableListPreferenceDialogFragmentTest {
|
||||
|
||||
private Context mContext;
|
||||
private UpdatableListPreferenceDialogFragment mUpdatableListPrefDlgFragment;
|
||||
private static final String KEY = "Test_Key";
|
||||
private ArrayAdapter mAdapter;
|
||||
private ArrayList<CharSequence> mEntries;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
|
||||
mUpdatableListPrefDlgFragment = UpdatableListPreferenceDialogFragment
|
||||
.newInstance(KEY, MetricsProto.MetricsEvent.DIALOG_SWITCH_A2DP_DEVICES);
|
||||
mEntries = spy(new ArrayList<>());
|
||||
mUpdatableListPrefDlgFragment.setEntries(mEntries);
|
||||
mUpdatableListPrefDlgFragment.
|
||||
setMetricsCategory(mUpdatableListPrefDlgFragment.getArguments());
|
||||
initAdapter();
|
||||
}
|
||||
|
||||
private void initAdapter() {
|
||||
mAdapter = spy(new ArrayAdapter<>(
|
||||
mContext,
|
||||
com.android.internal.R.layout.select_dialog_singlechoice,
|
||||
mEntries));
|
||||
mUpdatableListPrefDlgFragment.setAdapter(mAdapter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMetricsCategory() {
|
||||
assertThat(mUpdatableListPrefDlgFragment.getMetricsCategory())
|
||||
.isEqualTo(MetricsProto.MetricsEvent.DIALOG_SWITCH_A2DP_DEVICES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onListPreferenceUpdated_verifyAdapterCanBeUpdate() {
|
||||
assertThat(mUpdatableListPrefDlgFragment.getAdapter().getCount()).
|
||||
isEqualTo(0);
|
||||
|
||||
ListPreference listPreference = new ListPreference(mContext);
|
||||
final CharSequence[] charSequences = {"Test_DEVICE_1", "Test_DEVICE_2"};
|
||||
listPreference.setEntries(charSequences);
|
||||
mUpdatableListPrefDlgFragment.onListPreferenceUpdated(listPreference);
|
||||
|
||||
assertThat(mUpdatableListPrefDlgFragment.getAdapter().getCount()).
|
||||
isEqualTo(2);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user