Merge "Fix VisibleForTesting annotation in AppStateAppOpsBridge"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 1766ffb..c526d6f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1013,6 +1013,7 @@
android:parentActivityName="Settings">
<intent-filter android:priority="1">
<action android:name="android.settings.DEVICE_INFO_SETTINGS" />
+ <action android:name="android.settings.DEVICE_NAME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
@@ -2012,13 +2013,21 @@
</intent-filter>
</activity>
- <activity android:name=".deviceinfo.UsbModeChooserActivity"
+ <activity android:name=".connecteddevice.usb.UsbModeChooserActivity"
android:excludeFromRecents="true"
android:exported="true"
android:permission="android.permission.MANAGE_USB"
android:theme="@*android:style/Theme.DeviceDefault.Settings.Dialog.NoActionBar">
</activity>
+ <activity android:name=".Settings$UsbDetailsActivity"
+ android:excludeFromRecents="true"
+ android:permission="android.permission.MANAGE_USB"
+ android:exported="true">
+ <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+ android:value="com.android.settings.connecteddevice.usb.UsbDetailsFragment"/>
+ </activity>
+
<activity android:name=".RemoteBugreportActivity"
android:excludeFromRecents="true"
android:exported="true"
@@ -3189,16 +3198,11 @@
<activity android:name="Settings$AdvancedConnectedDeviceActivity"
android:label="@string/connected_device_connections_title"
android:taskAffinity="com.android.settings"
- android:parentActivityName="Settings$ConnectedDeviceDashboardActivity"
- android:enabled="false">
+ android:parentActivityName="Settings$ConnectedDeviceDashboardActivity">
<intent-filter android:priority="1">
<action android:name="com.android.settings.ADVANCED_CONNECTED_DEVICE_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment" />
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index f3050c4..21b9a09 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -265,43 +265,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="setup_divider_color_dark">#33ffffff</color>"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="res/values/colors.xml"
- line="33"
- 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="setup_divider_color_light">#33000000</color>"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="res/values/colors.xml"
- line="34"
- 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="setup_lock_pattern_view_regular_color_dark">#ffbdbdbd</color>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="35"
+ line="33"
column="5"/>
</issue>
@@ -317,7 +285,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="37"
+ line="35"
column="5"/>
</issue>
@@ -333,7 +301,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="39"
+ line="37"
column="5"/>
</issue>
@@ -349,7 +317,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="40"
+ line="38"
column="5"/>
</issue>
@@ -365,7 +333,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="41"
+ line="39"
column="5"/>
</issue>
@@ -381,7 +349,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="43"
+ line="41"
column="5"/>
</issue>
@@ -397,7 +365,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="44"
+ line="42"
column="5"/>
</issue>
@@ -413,7 +381,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="46"
+ line="44"
column="5"/>
</issue>
@@ -429,7 +397,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="51"
+ line="49"
column="5"/>
</issue>
@@ -445,7 +413,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="52"
+ line="50"
column="5"/>
</issue>
@@ -461,7 +429,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="53"
+ line="51"
column="5"/>
</issue>
@@ -477,7 +445,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="55"
+ line="53"
column="5"/>
</issue>
@@ -493,7 +461,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="56"
+ line="54"
column="5"/>
</issue>
@@ -509,7 +477,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="58"
+ line="56"
column="5"/>
</issue>
@@ -525,7 +493,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="61"
+ line="59"
column="5"/>
</issue>
@@ -541,7 +509,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="62"
+ line="60"
column="5"/>
</issue>
@@ -557,7 +525,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="66"
+ line="64"
column="5"/>
</issue>
@@ -573,7 +541,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="67"
+ line="65"
column="5"/>
</issue>
@@ -589,7 +557,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="68"
+ line="66"
column="5"/>
</issue>
@@ -605,7 +573,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="69"
+ line="67"
column="5"/>
</issue>
@@ -621,7 +589,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="71"
+ line="69"
column="5"/>
</issue>
@@ -637,7 +605,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="74"
+ line="72"
column="5"/>
</issue>
@@ -653,7 +621,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="76"
+ line="74"
column="5"/>
</issue>
@@ -669,7 +637,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="77"
+ line="75"
column="5"/>
</issue>
@@ -685,7 +653,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="80"
+ line="78"
column="5"/>
</issue>
@@ -701,7 +669,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="81"
+ line="79"
column="5"/>
</issue>
@@ -717,7 +685,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="82"
+ line="80"
column="5"/>
</issue>
@@ -733,7 +701,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="83"
+ line="81"
column="5"/>
</issue>
@@ -749,7 +717,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="84"
+ line="82"
column="5"/>
</issue>
@@ -765,7 +733,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="87"
+ line="85"
column="5"/>
</issue>
@@ -781,7 +749,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="88"
+ line="86"
column="5"/>
</issue>
@@ -797,7 +765,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="89"
+ line="87"
column="5"/>
</issue>
@@ -813,7 +781,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="90"
+ line="88"
column="5"/>
</issue>
@@ -829,7 +797,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="91"
+ line="89"
column="5"/>
</issue>
@@ -845,7 +813,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="92"
+ line="90"
column="5"/>
</issue>
@@ -861,7 +829,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="93"
+ line="91"
column="5"/>
</issue>
@@ -877,7 +845,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="94"
+ line="92"
column="5"/>
</issue>
@@ -893,7 +861,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="95"
+ line="93"
column="5"/>
</issue>
@@ -909,7 +877,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="96"
+ line="94"
column="5"/>
</issue>
@@ -925,7 +893,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="97"
+ line="95"
column="5"/>
</issue>
@@ -941,7 +909,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="100"
+ line="98"
column="5"/>
</issue>
@@ -957,7 +925,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="102"
+ line="100"
column="5"/>
</issue>
@@ -973,7 +941,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="105"
+ line="103"
column="5"/>
</issue>
@@ -989,7 +957,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="107"
+ line="105"
column="5"/>
</issue>
@@ -1005,7 +973,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="110"
+ line="108"
column="5"/>
</issue>
@@ -1021,7 +989,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="113"
+ line="111"
column="5"/>
</issue>
@@ -1037,7 +1005,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="116"
+ line="114"
column="5"/>
</issue>
@@ -1053,7 +1021,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="119"
+ line="117"
column="5"/>
</issue>
@@ -1069,7 +1037,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="120"
+ line="118"
column="5"/>
</issue>
@@ -1085,7 +1053,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="123"
+ line="121"
column="5"/>
</issue>
@@ -1101,7 +1069,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="124"
+ line="122"
column="5"/>
</issue>
@@ -1117,7 +1085,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="125"
+ line="123"
column="5"/>
</issue>
@@ -1133,7 +1101,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="126"
+ line="124"
column="5"/>
</issue>
@@ -1149,7 +1117,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="127"
+ line="125"
column="5"/>
</issue>
@@ -1165,7 +1133,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="128"
+ line="126"
column="5"/>
</issue>
@@ -1181,7 +1149,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="129"
+ line="127"
column="5"/>
</issue>
@@ -1197,7 +1165,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="130"
+ line="128"
column="5"/>
</issue>
@@ -1213,7 +1181,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="131"
+ line="129"
column="5"/>
</issue>
@@ -1229,7 +1197,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="132"
+ line="130"
column="5"/>
</issue>
@@ -1245,7 +1213,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="133"
+ line="131"
column="5"/>
</issue>
@@ -1261,7 +1229,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="134"
+ line="132"
column="5"/>
</issue>
@@ -1277,7 +1245,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/colors.xml"
- line="135"
+ line="133"
column="5"/>
</issue>
@@ -2493,7 +2461,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rAU/strings.xml"
- line="2354"
+ line="2395"
column="64"/>
</issue>
@@ -2509,7 +2477,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rCA/strings.xml"
- line="2354"
+ line="2395"
column="64"/>
</issue>
@@ -2525,7 +2493,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rGB/strings.xml"
- line="2354"
+ line="2395"
column="64"/>
</issue>
@@ -2541,7 +2509,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rIN/strings.xml"
- line="2354"
+ line="2395"
column="64"/>
</issue>
@@ -2573,7 +2541,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/strings.xml"
- line="5651"
+ line="5638"
column="36"/>
</issue>
@@ -2665,27 +2633,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=" <item name="setup_divider_color">@color/setup_divider_color_dark</item>"
- errorLine2=" ^">
+ errorLine1=" <item name="wifi_signal_color">@color/setup_wizard_wifi_color_dark</item>"
+ errorLine2=" ^">
<location
file="res/values/themes.xml"
line="33"
- column="42"/>
- </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="wifi_signal_color">@color/setup_wizard_wifi_color_dark</item>"
- errorLine2=" ^">
- <location
- file="res/values/themes.xml"
- line="35"
column="40"/>
</issue>
@@ -2697,27 +2649,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=" <item name="setup_divider_color">@color/setup_divider_color_light</item>"
- errorLine2=" ^">
- <location
- file="res/values/themes.xml"
- line="53"
- column="42"/>
- </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="wifi_signal_color">@color/setup_wizard_wifi_color_light</item>"
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="55"
+ line="52"
column="40"/>
</issue>
@@ -2729,27 +2665,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=" <item name="setup_divider_color">@color/setup_divider_color_dark</item>"
- errorLine2=" ^">
- <location
- file="res/values/themes.xml"
- line="72"
- column="42"/>
- </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="wifi_signal_color">@color/setup_wizard_wifi_color_dark</item>"
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="74"
+ line="70"
column="40"/>
</issue>
@@ -2761,27 +2681,43 @@
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="setup_divider_color">@color/setup_divider_color_light</item>"
- errorLine2=" ^">
- <location
- file="res/values/themes.xml"
- line="92"
- column="42"/>
- </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="wifi_signal_color">@color/setup_wizard_wifi_color_light</item>"
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="94"
+ line="89"
+ column="40"/>
+ </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="wifi_signal_color">@color/setup_wizard_wifi_color_dark</item>"
+ errorLine2=" ^">
+ <location
+ file="res/values/themes.xml"
+ line="107"
+ column="40"/>
+ </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="wifi_signal_color">@color/setup_wizard_wifi_color_light</item>"
+ errorLine2=" ^">
+ <location
+ file="res/values/themes.xml"
+ line="126"
column="40"/>
</issue>
@@ -2797,7 +2733,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="154"
+ line="200"
column="43"/>
</issue>
@@ -2813,7 +2749,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="155"
+ line="201"
column="42"/>
</issue>
@@ -2829,7 +2765,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="156"
+ line="202"
column="45"/>
</issue>
@@ -2845,7 +2781,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="233"
+ line="279"
column="47"/>
</issue>
@@ -2861,7 +2797,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="308"
+ line="347"
column="45"/>
</issue>
@@ -2877,7 +2813,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="309"
+ line="348"
column="49"/>
</issue>
@@ -2893,7 +2829,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="317"
+ line="356"
column="45"/>
</issue>
@@ -2909,7 +2845,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="318"
+ line="357"
column="49"/>
</issue>
diff --git a/res/color/preference_highligh_color.xml b/res/color/preference_highligh_color.xml
new file mode 100644
index 0000000..0a8f770
--- /dev/null
+++ b/res/color/preference_highligh_color.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:alpha="0.1" android:color="?android:attr/colorAccent" />
+</selector>
\ No newline at end of file
diff --git a/res/values/bools.xml b/res/values/bools.xml
index ab8a6fd..617ab7b 100644
--- a/res/values/bools.xml
+++ b/res/values/bools.xml
@@ -158,4 +158,13 @@
<!-- Whether system_update_settings should be shown or not. -->
<bool name="config_show_system_update_settings">true</bool>
+
+ <!-- Whether device_model should be shown or not. -->
+ <bool name="config_show_device_model">true</bool>
+
+ <!-- Whether wifi_ip_address should be shown or not. -->
+ <bool name="config_show_wifi_ip_address">true</bool>
+
+ <!-- Whether wifi_mac_address should be shown or not. -->
+ <bool name="config_show_wifi_mac_address">true</bool>
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index e10b4cb..3d86208 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -30,8 +30,6 @@
<color name="divider_color">#20ffffff</color>
<color name="title_color">@android:color/holo_blue_light</color>
- <color name="setup_divider_color_dark">#33ffffff</color>
- <color name="setup_divider_color_light">#33000000</color>
<color name="setup_lock_pattern_view_regular_color_dark">#ffbdbdbd</color>
<color name="setup_lock_pattern_view_regular_color_light">@color/lock_pattern_view_regular_color</color>
<color name="setup_lock_pattern_view_success_color_dark">#ff84ffff</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index d6f3cb5..12193c4 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -119,8 +119,8 @@
<!-- The following two margins need to match, with the caveat that
the second should be negative. The second one ensures that the icons and text
align despite the additional padding caused by the search bar's card background. -->
- <dimen name="search_bar_margin">8dp</dimen>
- <dimen name="search_bar_negative_margin">-8dp</dimen>
+ <dimen name="search_bar_margin">16dp</dimen>
+ <dimen name="search_bar_negative_margin">-16dp</dimen>
<dimen name="search_bar_height">48dp</dimen>
<dimen name="search_bar_corner_radius">2dp</dimen>
diff --git a/res/values/ids.xml b/res/values/ids.xml
index dcf279a..66af163 100644
--- a/res/values/ids.xml
+++ b/res/values/ids.xml
@@ -17,7 +17,7 @@
*/
-->
<resources>
- <item type="id" name="preference_highlight_key" />
+ <item type="id" name="preference_highlighted" />
<item type="id" name="lock_none" />
<item type="id" name="lock_pin" />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 4cf03dd..4b2c673 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -6145,7 +6145,7 @@
<!-- User settings -->
<skip/>
- <!-- User settings screen title [CHAR LIMIT=25] -->
+ <!-- User settings screen title [CHAR LIMIT=40] -->
<string name="user_settings_title">Multiple users</string>
<!-- User settings header for list of users and profiles [CHAR LIMIT=40] -->
<string name="user_list_title">Users & profiles</string>
@@ -8005,15 +8005,15 @@
<!-- Title of one of the choices in a dialog (with title defined in usb_use) that lets the user
select what the USB connection for this device should be used for. This choice
is for powering the other device only. -->
- <string name="usb_use_power_only">Supply power</string>
+ <string name="usb_use_power_only">Charging connected device</string>
<!-- Decription of one of the choices in a dialog (with title defined in usb_use) that lets the
user select what the USB connection for this device should be used for. This choice
is for powering the other device. -->
- <string name="usb_use_power_only_desc">Charge the connected device. Works only with devices that support USB charging.</string>
+ <string name="usb_use_power_only_desc">Other settings unavailable when turned on</string>
<!-- Title of one of the choices in a dialog (with title defined in usb_use) that lets the user
select what the USB connection for this device should be used for. This choice
is for transferring files via MTP. -->
- <string name="usb_use_file_transfers">Transfer files</string>
+ <string name="usb_use_file_transfers">File Transfer</string>
<!-- Description of one of the choices in a dialog (with title defined in usb_use) that lets the user
select what the USB connection for this device should be used for. This choice
is for transferring files via MTP. -->
@@ -8021,23 +8021,31 @@
<!-- Title of one of the choices in a dialog (with title defined in usb_use) that lets the user
select what the USB connection for this device should be used for. This choice
is for transferring photos via PTP. -->
- <string name="usb_use_photo_transfers">Transfer photos (PTP)</string>
+ <string name="usb_use_photo_transfers">PTP</string>
<!-- Description of one of the choices in a dialog (with title defined in usb_use) that lets the user
select what the USB connection for this device should be used for. This choice
is for transferring photos via PTP. -->
<string name="usb_use_photo_transfers_desc">Transfer photos or files if MTP is not supported (PTP)</string>
<!-- Title of one of the choices in a dialog (with title defined in usb_use) that lets the user
select what the USB connection for this device should be used for. This choice
+ is for USB tethering. -->
+ <string name="usb_use_tethering">USB tethering</string>
+ <!-- Title of one of the choices in a dialog (with title defined in usb_use) that lets the user
+ select what the USB connection for this device should be used for. This choice
is for entering MIDI mode. -->
- <string name="usb_use_MIDI">Use device as MIDI</string>
+ <string name="usb_use_MIDI">MIDI</string>
<!-- Description of one of the choices in a dialog (with title defined in usb_use) that lets the user
select what the USB connection for this device should be used for. This choice
is for entering MIDI mode. -->
<string name="usb_use_MIDI_desc">Use this device as MIDI</string>
<!-- The title used in a dialog which lets the user select what the USB connection
- for this device should be used for. Choices are usb_use_charging_only,
- usb_use_file_transfer, use_use_photo_transfer, and usb_use_MIDI -->
- <string name="usb_use">Use USB to</string>
+ for this device should be used for. These options are more commonly used.
+ Choices are usb_use_file_transfer.-->
+ <string name="usb_use">Use USB for</string>
+ <!-- The title used in a dialog which lets the user select what the USB connection
+ for this device should be used for. These options are less commonly used.
+ Choices are usb_use_tethering, usb_use_photo_transfers, usb_use_MIDI, and usb_use_power_only.-->
+ <string name="usb_use_also">Also use USB for</string>
<!-- Settings item title for USB preference [CHAR LIMIT=35] -->
<string name="usb_pref">USB</string>
@@ -8045,13 +8053,27 @@
<!-- Settings item summary for USB preference when set to charging only [CHAR LIMIT=NONE] -->
<string name="usb_summary_charging_only">Charging this device</string>
<!-- Settings item summary for USB preference when set to powering the other device only [CHAR LIMIT=NONE] -->
- <string name="usb_summary_power_only">Supplying power</string>
+ <string name="usb_summary_power_only">Charging connected device</string>
<!-- Settings item summary for USB preference when set to transferring files via MTP [CHAR LIMIT=NONE] -->
- <string name="usb_summary_file_transfers">Transferring files</string>
+ <string name="usb_summary_file_transfers">File transfer</string>
+ <!-- Settings item summary for USB preference when set to USB tethering [CHAR LIMIT=NONE] -->
+ <string name="usb_summary_tether">USB tethering</string>
<!-- Settings item summary for USB preference when set to transferring photos via PTP [CHAR LIMIT=NONE] -->
- <string name="usb_summary_photo_transfers">Transferring photos (PTP)</string>
+ <string name="usb_summary_photo_transfers">PTP</string>
<!-- Settings item summary for USB preference when set to entering MIDI mode [CHAR LIMIT=NONE] -->
- <string name="usb_summary_MIDI">Using device as MIDI</string>
+ <string name="usb_summary_MIDI">MIDI</string>
+ <!-- Settings item summary for USB preference when set to transferring files via MTP
+ and powering other device [CHAR LIMIT=NONE] -->
+ <string name="usb_summary_file_transfers_power">File transfer and supplying power</string>
+ <!-- Settings item summary for USB preference when set to USB tethering
+ and powering other device [CHAR LIMIT=NONE] -->
+ <string name="usb_summary_tether_power">USB tethering and supplying power</string>
+ <!-- Settings item summary for USB preference when set to transferring photos via PTP
+ and powering other device [CHAR LIMIT=NONE] -->
+ <string name="usb_summary_photo_transfers_power">PTP and supplying power</string>
+ <!-- Settings item summary for USB preference when set to entering MIDI mode
+ and powering other device [CHAR LIMIT=NONE] -->
+ <string name="usb_summary_MIDI_power">MIDI and supplying power</string>
<!-- Settings item title for SMS Mirroring preference [CHAR LIMIT=35] -->
<string name="sms_mirroring_pref">SMS Mirroring</string>
@@ -8407,7 +8429,7 @@
<string name="condition_airplane_summary">Wi-Fi, Bluetooth, and mobile network are turned off. You can\'t make phone calls or connect to the internet.</string>
<!-- Title of condition that do not disturb is on [CHAR LIMIT=30] -->
- <string name="condition_zen_title">Do not disturb is on (<xliff:g name="zen_mode_type" example="Alarms only">%1$s</xliff:g>)</string>
+ <string name="condition_zen_title">Do Not Disturb is on</string>
<!-- Title of condition that battery saver is on [CHAR LIMIT=30] -->
<string name="condition_battery_title">Battery Saver is on</string>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index d4ccdde..e0f3989 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -18,7 +18,6 @@
<attr name="fingerprint_layout_theme" format="reference" />
<attr name="ic_menu_moreoverflow" format="reference" />
<attr name="ic_wps" format="reference" />
- <attr name="setup_divider_color" format="reference" />
<attr name="side_margin" format="reference|dimension" />
<attr name="wifi_signal_color" format="reference" />
@@ -30,7 +29,6 @@
<item name="fingerprint_layout_theme">@style/FingerprintLayoutTheme</item>
<item name="ic_menu_moreoverflow">@*android:drawable/ic_menu_moreoverflow_material</item>
<item name="ic_wps">@drawable/ic_wps_dark</item>
- <item name="setup_divider_color">@color/setup_divider_color_dark</item>
<item name="side_margin">0dip</item>
<item name="wifi_signal_color">@color/setup_wizard_wifi_color_dark</item>
<item name="wifi_signal">@drawable/wifi_signal</item>
@@ -50,7 +48,6 @@
<item name="fingerprint_layout_theme">@style/FingerprintLayoutTheme</item>
<item name="ic_menu_moreoverflow">@*android:drawable/ic_menu_moreoverflow_material</item>
<item name="ic_wps">@drawable/ic_wps_light</item>
- <item name="setup_divider_color">@color/setup_divider_color_light</item>
<item name="side_margin">0dip</item>
<item name="wifi_signal_color">@color/setup_wizard_wifi_color_light</item>
<item name="wifi_signal">@drawable/wifi_signal</item>
@@ -69,7 +66,6 @@
<item name="fingerprint_layout_theme">@style/FingerprintLayoutTheme</item>
<item name="ic_menu_moreoverflow">@*android:drawable/ic_menu_moreoverflow_material</item>
<item name="ic_wps">@drawable/ic_wps_dark</item>
- <item name="setup_divider_color">@color/setup_divider_color_dark</item>
<item name="side_margin">0dip</item>
<item name="wifi_signal_color">@color/setup_wizard_wifi_color_dark</item>
<item name="wifi_signal">@drawable/wifi_signal</item>
@@ -89,7 +85,43 @@
<item name="fingerprint_layout_theme">@style/FingerprintLayoutTheme</item>
<item name="ic_menu_moreoverflow">@*android:drawable/ic_menu_moreoverflow_material</item>
<item name="ic_wps">@drawable/ic_wps_light</item>
- <item name="setup_divider_color">@color/setup_divider_color_light</item>
+ <item name="side_margin">0dip</item>
+ <item name="wifi_signal_color">@color/setup_wizard_wifi_color_light</item>
+ <item name="wifi_signal">@drawable/wifi_signal</item>
+ <item name="wifi_friction">@drawable/wifi_friction</item>
+ <item name="preferenceBackgroundColor">?android:attr/colorBackground</item>
+ <item name="preferenceTheme">@style/PreferenceTheme.SetupWizard</item>
+
+ <item name="*android:lockPatternStyle">@style/LockPatternStyle.Setup</item>
+ </style>
+
+ <style name="GlifV3Theme" parent="SuwThemeGlifV3">
+ <!-- For all Alert Dialogs -->
+ <item name="android:alertDialogTheme">@style/GlifV2ThemeAlertDialog</item>
+ <item name="android:windowBackground">?android:attr/colorBackground</item>
+ <item name="*android:preferencePanelStyle">@*android:style/PreferencePanel.Dialog</item>
+ <item name="fingerprint_layout_theme">@style/FingerprintLayoutTheme</item>
+ <item name="ic_menu_moreoverflow">@*android:drawable/ic_menu_moreoverflow_material</item>
+ <item name="ic_wps">@drawable/ic_wps_dark</item>
+ <item name="side_margin">0dip</item>
+ <item name="wifi_signal_color">@color/setup_wizard_wifi_color_dark</item>
+ <item name="wifi_signal">@drawable/wifi_signal</item>
+ <item name="wifi_friction">@drawable/wifi_friction</item>
+ <item name="preferenceBackgroundColor">?android:attr/colorBackground</item>
+ <item name="preferenceTheme">@style/PreferenceTheme.SetupWizard</item>
+
+ <!-- LockPatternView colors -->
+ <item name="*android:lockPatternStyle">@style/LockPatternStyle.Setup</item>
+ </style>
+
+ <style name="GlifV3Theme.Light" parent="SuwThemeGlifV3.Light">
+ <!-- For all Alert Dialogs -->
+ <item name="android:alertDialogTheme">@style/GlifV2ThemeAlertDialog.Light</item>
+ <item name="android:windowBackground">?android:attr/colorBackground</item>
+ <item name="*android:preferencePanelStyle">@*android:style/PreferencePanel.Dialog</item>
+ <item name="fingerprint_layout_theme">@style/FingerprintLayoutTheme</item>
+ <item name="ic_menu_moreoverflow">@*android:drawable/ic_menu_moreoverflow_material</item>
+ <item name="ic_wps">@drawable/ic_wps_light</item>
<item name="side_margin">0dip</item>
<item name="wifi_signal_color">@color/setup_wizard_wifi_color_light</item>
<item name="wifi_signal">@drawable/wifi_signal</item>
@@ -128,6 +160,20 @@
<item name="android:windowAnimationStyle">@null</item>
</style>
+ <style name="GlifV3Theme.Transparent">
+ <item name="android:windowBackground">@android:color/transparent</item>
+ <item name="android:windowNoTitle">true</item>
+ <item name="android:windowIsFloating">true</item>
+ <item name="android:windowAnimationStyle">@null</item>
+ </style>
+
+ <style name="GlifV3Theme.Light.Transparent">
+ <item name="android:windowBackground">@android:color/transparent</item>
+ <item name="android:windowNoTitle">true</item>
+ <item name="android:windowIsFloating">true</item>
+ <item name="android:windowAnimationStyle">@null</item>
+ </style>
+
<style name="SuwSuggestionThemeGlif.Light" parent="SuwThemeGlif.Light">
<item name="android:windowAnimationStyle">@android:style/Animation.Activity</item>
@@ -290,13 +336,6 @@
<item name="android:colorAccent">@*android:color/white</item>
</style>
- <style name="Theme.FingerprintEnroll" parent="SuwThemeGlif.Light">
- <item name="android:textAppearanceListItemSmall">@android:style/TextAppearance.Material.Body1</item>
-
- <item name="suwDividerCondition">both</item>
- <item name="suwListItemIconColor">?android:attr/colorAccent</item>
- </style>
-
<style name="FallbackHome" parent="@android:style/Theme.DeviceDefault.NoActionBar">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
diff --git a/res/xml/connected_devices_advanced.xml b/res/xml/connected_devices_advanced.xml
index 8ca6b81..0b75abf 100644
--- a/res/xml/connected_devices_advanced.xml
+++ b/res/xml/connected_devices_advanced.xml
@@ -57,16 +57,6 @@
android:order="-2"/>
<Preference
- android:key="usb_mode"
- android:title="@string/usb_pref"
- android:icon="@drawable/ic_usb"
- android:order="-1">
- <intent android:action="android.intent.action.MAIN"
- android:targetPackage="com.android.settings"
- android:targetClass="com.android.settings.deviceinfo.UsbModeChooserActivity"/>
- </Preference>
-
- <Preference
android:key="bt_received_files"
android:icon="@drawable/ic_folder_vd_theme_24"
android:title="@string/bluetooth_show_received_files" />
diff --git a/res/xml/connected_devices_old.xml b/res/xml/connected_devices_old.xml
index 3eb62ea..cc7b5b4 100644
--- a/res/xml/connected_devices_old.xml
+++ b/res/xml/connected_devices_old.xml
@@ -53,7 +53,7 @@
android:order="-2">
<intent android:action="android.intent.action.MAIN"
android:targetPackage="com.android.settings"
- android:targetClass="com.android.settings.deviceinfo.UsbModeChooserActivity"/>
+ android:targetClass="com.android.settings.connecteddevice.usb.UsbModeChooserActivity"/>
</Preference>
<PreferenceCategory
diff --git a/res/xml/usb_details_fragment.xml b/res/xml/usb_details_fragment.xml
new file mode 100644
index 0000000..30ca993
--- /dev/null
+++ b/res/xml/usb_details_fragment.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:title="@string/device_details_title">
+
+ <com.android.settings.applications.LayoutPreference
+ android:key="usb_device_header"
+ android:layout="@layout/settings_entity_header"
+ android:selectable="false"/>
+
+ <PreferenceCategory
+ android:key="usb_main_options"
+ android:title="@string/usb_use"/>
+
+ <PreferenceCategory
+ android:key="usb_secondary_options"
+ android:title="@string/usb_use_also"/>
+
+</PreferenceScreen>
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 7bd85cd..741bfda 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -96,6 +96,7 @@
public static class ZenAccessSettingsActivity extends SettingsActivity { /* empty */ }
public static class ConditionProviderSettingsActivity extends SettingsActivity { /* empty */ }
public static class UsbSettingsActivity extends SettingsActivity { /* empty */ }
+ public static class UsbDetailsActivity extends SettingsActivity { /* empty */ }
public static class TrustedCredentialsSettingsActivity extends SettingsActivity { /* empty */ }
public static class PaymentSettingsActivity extends SettingsActivity { /* empty */ }
public static class PrintSettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index c5d477a..2a593c2 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -30,9 +30,7 @@
import android.support.annotation.XmlRes;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup;
-import android.support.v7.preference.PreferenceGroupAdapter;
import android.support.v7.preference.PreferenceScreen;
-import android.support.v7.preference.PreferenceViewHolder;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
@@ -49,6 +47,7 @@
import com.android.settings.search.actionbar.SearchMenuController;
import com.android.settings.support.actionbar.HelpMenuController;
import com.android.settings.support.actionbar.HelpResourceProvider;
+import com.android.settings.widget.HighlightablePreferenceGroupAdapter;
import com.android.settings.widget.LoadingViewController;
import com.android.settingslib.CustomDialogPreference;
import com.android.settingslib.CustomEditTextPreference;
@@ -65,9 +64,6 @@
private static final String TAG = "SettingsPreference";
- @VisibleForTesting
- static final int DELAY_HIGHLIGHT_DURATION_MILLIS = 600;
-
private static final String SAVE_HIGHLIGHTED_KEY = "android:preference_highlighted";
protected final FooterPreferenceMixin mFooterPreferenceMixin =
@@ -75,14 +71,11 @@
private static final int ORDER_FIRST = -1;
- private static final int ORDER_LAST = Integer.MAX_VALUE -1;
private SettingsDialogFragment mDialogFragment;
// Cache the content resolver for async callbacks
private ContentResolver mContentResolver;
- private String mPreferenceKey;
-
private RecyclerView.Adapter mCurrentRootAdapter;
private boolean mIsDataSetObserverRegistered = false;
private RecyclerView.AdapterDataObserver mDataSetObserver =
@@ -146,8 +139,9 @@
// Check if we should keep the preferences expanded.
if (arguments != null) {
- mPreferenceKey = arguments.getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY);
- if (!TextUtils.isEmpty(mPreferenceKey)) {
+ final String highlightKey =
+ arguments.getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY);
+ if (!TextUtils.isEmpty(highlightKey)) {
final PreferenceScreen screen = getPreferenceScreen();
if (screen != null) {
screen.setInitialExpandedChildrenCount(Integer.MAX_VALUE);
@@ -205,7 +199,9 @@
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
- outState.putBoolean(SAVE_HIGHLIGHTED_KEY, mPreferenceHighlighted);
+ if (mAdapter != null) {
+ outState.putBoolean(SAVE_HIGHLIGHTED_KEY, mAdapter.isHighlightRequested());
+ }
}
@Override
@@ -217,10 +213,7 @@
@Override
public void onResume() {
super.onResume();
-
- if (mPreferenceKey != null) {
- highlightPreferenceIfNeeded();
- }
+ highlightPreferenceIfNeeded();
}
@Override
@@ -263,13 +256,11 @@
}
public void highlightPreferenceIfNeeded() {
- if (isAdded() && !mPreferenceHighlighted &&!TextUtils.isEmpty(mPreferenceKey)) {
- getView().postDelayed(new Runnable() {
- @Override
- public void run() {
- highlightPreference(mPreferenceKey);
- }
- }, DELAY_HIGHLIGHT_DURATION_MILLIS);
+ if (!isAdded()) {
+ return;
+ }
+ if (mAdapter != null) {
+ mAdapter.requestHighlight(getView(), getListView());
}
}
@@ -340,24 +331,6 @@
return mEmptyView;
}
- /**
- * Return a valid ListView position or -1 if none is found
- */
- private int canUseListViewForHighLighting(String key) {
- if (getListView() == null) {
- return -1;
- }
-
- RecyclerView listView = getListView();
- RecyclerView.Adapter adapter = listView.getAdapter();
-
- if (adapter != null && adapter instanceof PreferenceGroupAdapter) {
- return findListPositionFromKey((PreferenceGroupAdapter) adapter, key);
- }
-
- return -1;
- }
-
@Override
public RecyclerView.LayoutManager onCreateLayoutManager() {
mLayoutManager = new LinearLayoutManager(getContext());
@@ -366,7 +339,9 @@
@Override
protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) {
- mAdapter = new HighlightablePreferenceGroupAdapter(preferenceScreen);
+ mAdapter = new HighlightablePreferenceGroupAdapter(preferenceScreen,
+ getArguments().getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY),
+ mPreferenceHighlighted);
return mAdapter;
}
@@ -375,7 +350,7 @@
}
protected void cacheRemoveAllPrefs(PreferenceGroup group) {
- mPreferenceCache = new ArrayMap<String, Preference>();
+ mPreferenceCache = new ArrayMap<>();
final int N = group.getPreferenceCount();
for (int i = 0; i < N; i++) {
Preference p = group.getPreference(i);
@@ -401,29 +376,6 @@
return mPreferenceCache != null ? mPreferenceCache.size() : 0;
}
- private void highlightPreference(String key) {
- final int position = canUseListViewForHighLighting(key);
- if (position < 0) {
- return;
- }
-
- mPreferenceHighlighted = true;
- mLayoutManager.scrollToPosition(position);
- mAdapter.highlight(position);
- }
-
- private int findListPositionFromKey(PreferenceGroupAdapter adapter, String key) {
- final int count = adapter.getItemCount();
- for (int n = 0; n < count; n++) {
- final Preference preference = adapter.getItem(n);
- final String preferenceKey = preference.getKey();
- if (preferenceKey != null && preferenceKey.equals(key)) {
- return n;
- }
- }
- return -1;
- }
-
protected boolean removePreference(String key) {
return removePreference(getPreferenceScreen(), key);
}
@@ -692,11 +644,11 @@
}
protected boolean hasNextButton() {
- return ((ButtonBarHandler)getActivity()).hasNextButton();
+ return ((ButtonBarHandler) getActivity()).hasNextButton();
}
protected Button getNextButton() {
- return ((ButtonBarHandler)getActivity()).getNextButton();
+ return ((ButtonBarHandler) getActivity()).getNextButton();
}
public void finish() {
@@ -741,45 +693,10 @@
} else {
Log.w(TAG,
"Parent isn't SettingsActivity nor PreferenceActivity, thus there's no way to "
- + "launch the given Fragment (name: " + fragmentClass
- + ", requestCode: " + requestCode + ")");
+ + "launch the given Fragment (name: " + fragmentClass
+ + ", requestCode: " + requestCode + ")");
return false;
}
}
- public static class HighlightablePreferenceGroupAdapter extends PreferenceGroupAdapter {
-
- @VisibleForTesting(otherwise=VisibleForTesting.NONE)
- int initialHighlightedPosition = -1;
-
- private int mHighlightPosition = -1;
-
- public HighlightablePreferenceGroupAdapter(PreferenceGroup preferenceGroup) {
- super(preferenceGroup);
- }
-
- public void highlight(int position) {
- mHighlightPosition = position;
- initialHighlightedPosition = position;
- notifyDataSetChanged();
- }
-
- @Override
- public void onBindViewHolder(PreferenceViewHolder holder, int position) {
- super.onBindViewHolder(holder, position);
- if (position == mHighlightPosition) {
- View v = holder.itemView;
- v.post(() -> {
- if (v.getBackground() != null) {
- final int centerX = v.getWidth() / 2;
- final int centerY = v.getHeight() / 2;
- v.getBackground().setHotspot(centerX, centerY);
- }
- v.setPressed(true);
- v.setPressed(false);
- mHighlightPosition = -1;
- });
- }
- }
- }
}
diff --git a/src/com/android/settings/SetupWizardUtils.java b/src/com/android/settings/SetupWizardUtils.java
index e3e49eb..85acc8a 100644
--- a/src/com/android/settings/SetupWizardUtils.java
+++ b/src/com/android/settings/SetupWizardUtils.java
@@ -34,6 +34,10 @@
}
if (theme != null) {
switch (theme) {
+ case WizardManagerHelper.THEME_GLIF_V3_LIGHT:
+ return R.style.GlifV3Theme_Light;
+ case WizardManagerHelper.THEME_GLIF_V3:
+ return R.style.GlifV3Theme;
case WizardManagerHelper.THEME_GLIF_V2_LIGHT:
return R.style.GlifV2Theme_Light;
case WizardManagerHelper.THEME_GLIF_V2:
@@ -50,7 +54,11 @@
public static int getTransparentTheme(Intent intent) {
final int suwTheme = getTheme(intent);
int wifiDialogTheme = R.style.GlifV2Theme_Light_Transparent;
- if (suwTheme == R.style.GlifV2Theme) {
+ if (suwTheme == R.style.GlifV3Theme) {
+ wifiDialogTheme = R.style.GlifV3Theme_Transparent;
+ } else if (suwTheme == R.style.GlifV3Theme_Light) {
+ wifiDialogTheme = R.style.GlifV3Theme_Light_Transparent;
+ } else if (suwTheme == R.style.GlifV2Theme) {
wifiDialogTheme = R.style.GlifV2Theme_Transparent;
} else if (suwTheme == R.style.GlifTheme_Light) {
wifiDialogTheme = R.style.SetupWizardTheme_Light_Transparent;
diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
index a99ba65..7cc5d1a 100755
--- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
+++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
@@ -162,13 +162,12 @@
mUserManager = (UserManager) activity.getSystemService(Context.USER_SERVICE);
mPm = activity.getPackageManager();
- retrieveAppEntry();
- startListeningToPackageRemove();
-
if (!ensurePackageInfoAvailable(activity)) {
return;
}
+ startListeningToPackageRemove();
+
mForceStopOptionsMenuController =
new ForceStopOptionsMenuController(activity, this /* parent */, mDpm,
mMetricsFeatureProvider, getLifecycle());
@@ -205,6 +204,10 @@
@Override
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ retrieveAppEntry();
+ if (mPackageInfo == null) {
+ return null;
+ }
final String packageName = getPackageName();
final List<AbstractPreferenceController> controllers = new ArrayList<>();
final Lifecycle lifecycle = getLifecycle();
@@ -262,9 +265,6 @@
}
ApplicationsState.AppEntry getAppEntry() {
- if (mAppEntry == null) {
- retrieveAppEntry();
- }
return mAppEntry;
}
@@ -273,9 +273,6 @@
}
PackageInfo getPackageInfo() {
- if (mAppEntry == null) {
- retrieveAppEntry();
- }
return mPackageInfo;
}
@@ -361,7 +358,12 @@
PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER)
.execute((Object) null);
}
- // continue with following operations
+ if (!refreshUi()) {
+ onPackageRemoved();
+ } else {
+ startListeningToPackageRemove();
+ }
+ break;
case REQUEST_REMOVE_DEVICE_ADMIN:
if (!refreshUi()) {
setIntentAndFinish(true, true);
@@ -622,7 +624,8 @@
return mPackageName;
}
- private void retrieveAppEntry() {
+ @VisibleForTesting
+ void retrieveAppEntry() {
final Activity activity = getActivity();
if (activity == null) {
return;
diff --git a/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
index 2a136bc..9ac6ebd 100644
--- a/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
@@ -24,8 +24,9 @@
import com.android.settings.bluetooth.BluetoothFilesPreferenceController;
import com.android.settings.bluetooth.BluetoothMasterSwitchPreferenceController;
import com.android.settings.bluetooth.BluetoothSwitchPreferenceController;
+import com.android.settings.connecteddevice.usb.UsbBackend;
+import com.android.settings.connecteddevice.usb.UsbModePreferenceController;
import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.deviceinfo.UsbBackend;
import com.android.settings.nfc.NfcPreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentOld.java b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentOld.java
index 7097b36..bde5e81 100644
--- a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentOld.java
+++ b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentOld.java
@@ -26,9 +26,10 @@
import com.android.settings.SettingsActivity;
import com.android.settings.bluetooth.BluetoothMasterSwitchPreferenceController;
import com.android.settings.bluetooth.Utils;
+import com.android.settings.connecteddevice.usb.UsbBackend;
+import com.android.settings.connecteddevice.usb.UsbModePreferenceController;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.dashboard.SummaryLoader;
-import com.android.settings.deviceinfo.UsbBackend;
import com.android.settings.nfc.NfcPreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java b/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java
index 3cccc15..3d5d0e5 100644
--- a/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java
+++ b/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java
@@ -20,6 +20,7 @@
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceScreen;
+import com.android.settings.connecteddevice.usb.ConnectedUsbDeviceUpdater;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.bluetooth.BluetoothDeviceUpdater;
import com.android.settings.bluetooth.ConnectedBluetoothDeviceUpdater;
@@ -48,7 +49,7 @@
public ConnectedDeviceGroupController(DashboardFragment fragment, Lifecycle lifecycle) {
super(fragment.getContext());
init(lifecycle, new ConnectedBluetoothDeviceUpdater(fragment, this),
- new ConnectedUsbDeviceUpdater(fragment.getContext(), this));
+ new ConnectedUsbDeviceUpdater(fragment, this));
}
@VisibleForTesting
diff --git a/src/com/android/settings/connecteddevice/UsbConnectionBroadcastReceiver.java b/src/com/android/settings/connecteddevice/UsbConnectionBroadcastReceiver.java
deleted file mode 100644
index 07a7691..0000000
--- a/src/com/android/settings/connecteddevice/UsbConnectionBroadcastReceiver.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.connecteddevice;
-
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.hardware.usb.UsbManager;
-
-/**
- * Receiver to receive usb update and use {@link UsbConnectionListener} to invoke callback
- */
-public class UsbConnectionBroadcastReceiver extends BroadcastReceiver {
- private Context mContext;
- private UsbConnectionListener mUsbConnectionListener;
- private boolean mListeningToUsbEvents;
- private boolean mConnected;
-
- public UsbConnectionBroadcastReceiver(Context context,
- UsbConnectionListener usbConnectionListener) {
- mContext = context;
- mUsbConnectionListener = usbConnectionListener;
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- mConnected = intent != null
- && intent.getExtras().getBoolean(UsbManager.USB_CONNECTED);
- if (mUsbConnectionListener != null) {
- mUsbConnectionListener.onUsbConnectionChanged(mConnected);
- }
- }
-
- public void register() {
- if (!mListeningToUsbEvents) {
- final IntentFilter intentFilter = new IntentFilter(UsbManager.ACTION_USB_STATE);
- final Intent intent = mContext.registerReceiver(this, intentFilter);
- mConnected = intent != null
- && intent.getExtras().getBoolean(UsbManager.USB_CONNECTED);
- mListeningToUsbEvents = true;
- }
- }
-
- public void unregister() {
- if (mListeningToUsbEvents) {
- mContext.unregisterReceiver(this);
- mListeningToUsbEvents = false;
- }
- }
-
- public boolean isConnected() {
- return mConnected;
- }
-
- /**
- * Interface definition for a callback to be invoked when usb connection is changed.
- */
- interface UsbConnectionListener {
- void onUsbConnectionChanged(boolean connected);
- }
-}
diff --git a/src/com/android/settings/connecteddevice/ConnectedUsbDeviceUpdater.java b/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdater.java
similarity index 65%
rename from src/com/android/settings/connecteddevice/ConnectedUsbDeviceUpdater.java
rename to src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdater.java
index 0468b0f..dd29902 100644
--- a/src/com/android/settings/connecteddevice/ConnectedUsbDeviceUpdater.java
+++ b/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdater.java
@@ -13,22 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.settings.connecteddevice;
+package com.android.settings.connecteddevice.usb;
import android.content.Context;
-import android.content.Intent;
+import android.os.Bundle;
import android.support.annotation.VisibleForTesting;
+import android.support.v14.preference.PreferenceFragment;
import com.android.settings.R;
-import com.android.settings.deviceinfo.UsbBackend;
-import com.android.settings.deviceinfo.UsbModeChooserActivity;
+import com.android.settings.SettingsActivity;
+import com.android.settings.connecteddevice.DevicePreferenceCallback;
+import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.widget.GearPreference;
/**
* Controller to maintain connected usb device
*/
public class ConnectedUsbDeviceUpdater {
- private Context mContext;
+ private PreferenceFragment mFragment;
private UsbBackend mUsbBackend;
private DevicePreferenceCallback mDevicePreferenceCallback;
@VisibleForTesting
@@ -36,8 +38,9 @@
@VisibleForTesting
UsbConnectionBroadcastReceiver mUsbReceiver;
- private UsbConnectionBroadcastReceiver.UsbConnectionListener mUsbConnectionListener =
- (connected) -> {
+ @VisibleForTesting
+ UsbConnectionBroadcastReceiver.UsbConnectionListener mUsbConnectionListener =
+ (connected, newMode) -> {
if (connected) {
mUsbPreference.setSummary(
UsbModePreferenceController.getSummary(mUsbBackend.getCurrentMode()));
@@ -47,18 +50,19 @@
}
};
- public ConnectedUsbDeviceUpdater(Context context,
+ public ConnectedUsbDeviceUpdater(DashboardFragment fragment,
DevicePreferenceCallback devicePreferenceCallback) {
- this(context, devicePreferenceCallback, new UsbBackend(context));
+ this(fragment, devicePreferenceCallback, new UsbBackend(fragment.getContext()));
}
@VisibleForTesting
- ConnectedUsbDeviceUpdater(Context context, DevicePreferenceCallback devicePreferenceCallback,
- UsbBackend usbBackend) {
- mContext = context;
+ ConnectedUsbDeviceUpdater(DashboardFragment fragment,
+ DevicePreferenceCallback devicePreferenceCallback, UsbBackend usbBackend) {
+ mFragment = fragment;
mDevicePreferenceCallback = devicePreferenceCallback;
mUsbBackend = usbBackend;
- mUsbReceiver = new UsbConnectionBroadcastReceiver(context, mUsbConnectionListener);
+ mUsbReceiver = new UsbConnectionBroadcastReceiver(fragment.getContext(),
+ mUsbConnectionListener, mUsbBackend);
}
public void registerCallback() {
@@ -76,8 +80,12 @@
mUsbPreference.setIcon(R.drawable.ic_usb);
mUsbPreference.setSelectable(false);
mUsbPreference.setOnGearClickListener((GearPreference p) -> {
- final Intent intent = new Intent(mContext, UsbModeChooserActivity.class);
- mContext.startActivity(intent);
+ // New version - uses a separate screen.
+ final Bundle args = new Bundle();
+ final SettingsActivity activity = (SettingsActivity) mFragment.getContext();
+ activity.startPreferencePanel(mFragment,
+ UsbDetailsFragment.class.getName(), args,
+ R.string.device_details_title, null /* titleText */, null /* resultTo */, 0);
});
forceUpdate();
@@ -87,6 +95,5 @@
// Register so we can get the connection state from sticky intent.
//TODO(b/70336520): Use an API to get data instead of sticky intent
mUsbReceiver.register();
- mUsbConnectionListener.onUsbConnectionChanged(mUsbReceiver.isConnected());
}
}
diff --git a/src/com/android/settings/connecteddevice/usb/OWNERS b/src/com/android/settings/connecteddevice/usb/OWNERS
new file mode 100644
index 0000000..add985c
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/usb/OWNERS
@@ -0,0 +1,3 @@
+# Default reviewers for this and subdirectories.
+zhangjerry@google.com
+badhri@google.com
diff --git a/src/com/android/settings/connecteddevice/usb/UsbBackend.java b/src/com/android/settings/connecteddevice/usb/UsbBackend.java
new file mode 100644
index 0000000..cdfb6b0
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/usb/UsbBackend.java
@@ -0,0 +1,247 @@
+/*
+ * 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.
+ */
+package com.android.settings.connecteddevice.usb;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.hardware.usb.UsbManager;
+import android.hardware.usb.UsbPort;
+import android.hardware.usb.UsbPortStatus;
+import android.net.ConnectivityManager;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.annotation.VisibleForTesting;
+
+public class UsbBackend {
+
+ public static final int MODE_POWER_MASK = 0x01;
+ public static final int MODE_POWER_SINK = 0x00;
+ public static final int MODE_POWER_SOURCE = 0x01;
+
+ public static final int MODE_DATA_MASK = 0x0f << 1;
+ public static final int MODE_DATA_NONE = 0;
+ public static final int MODE_DATA_MTP = 0x01 << 1;
+ public static final int MODE_DATA_PTP = 0x01 << 2;
+ public static final int MODE_DATA_MIDI = 0x01 << 3;
+ public static final int MODE_DATA_TETHER = 0x01 << 4;
+
+ private final boolean mFileTransferRestricted;
+ private final boolean mFileTransferRestrictedBySystem;
+ private final boolean mTetheringRestricted;
+ private final boolean mTetheringRestrictedBySystem;
+ private final boolean mMidiSupported;
+ private final boolean mTetheringSupported;
+
+ private UsbManager mUsbManager;
+ @VisibleForTesting
+ UsbManagerPassThrough mUsbManagerPassThrough;
+ private UsbPort mPort;
+ private UsbPortStatus mPortStatus;
+
+ private Context mContext;
+
+ public UsbBackend(Context context) {
+ this(context, new UserRestrictionUtil(context), null);
+ }
+
+ @VisibleForTesting
+ public UsbBackend(Context context, UserRestrictionUtil userRestrictionUtil,
+ UsbManagerPassThrough usbManagerPassThrough) {
+ mContext = context;
+ mUsbManager = context.getSystemService(UsbManager.class);
+
+ mUsbManagerPassThrough = usbManagerPassThrough;
+ if (mUsbManagerPassThrough == null) {
+ mUsbManagerPassThrough = new UsbManagerPassThrough(mUsbManager);
+ }
+
+ mFileTransferRestricted = userRestrictionUtil.isUsbFileTransferRestricted();
+ mFileTransferRestrictedBySystem = userRestrictionUtil.isUsbFileTransferRestrictedBySystem();
+ mTetheringRestricted = userRestrictionUtil.isUsbTetheringRestricted();
+ mTetheringRestrictedBySystem = userRestrictionUtil.isUsbTetheringRestrictedBySystem();
+
+ mMidiSupported = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MIDI);
+ ConnectivityManager cm =
+ (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ mTetheringSupported = cm.isTetheringSupported();
+
+ UsbPort[] ports = mUsbManager.getPorts();
+ if (ports == null) {
+ return;
+ }
+ // For now look for a connected port, in the future we should identify port in the
+ // notification and pick based on that.
+ final int N = ports.length;
+ for (int i = 0; i < N; i++) {
+ UsbPortStatus status = mUsbManager.getPortStatus(ports[i]);
+ if (status.isConnected()) {
+ mPort = ports[i];
+ mPortStatus = status;
+ break;
+ }
+ }
+ }
+
+ public int getCurrentMode() {
+ if (mPort != null) {
+ int power = mPortStatus.getCurrentPowerRole() == UsbPort.POWER_ROLE_SOURCE
+ && mPortStatus.isConnected()
+ ? MODE_POWER_SOURCE : MODE_POWER_SINK;
+ return power | getUsbDataMode();
+ }
+ return MODE_POWER_SINK | getUsbDataMode();
+ }
+
+ public int getUsbDataMode() {
+ long functions = mUsbManagerPassThrough.getCurrentFunctions();
+ if (functions == UsbManager.FUNCTION_MTP) {
+ return MODE_DATA_MTP;
+ } else if (functions == UsbManager.FUNCTION_PTP) {
+ return MODE_DATA_PTP;
+ } else if (functions == UsbManager.FUNCTION_MIDI) {
+ return MODE_DATA_MIDI;
+ } else if (functions == UsbManager.FUNCTION_RNDIS) {
+ return MODE_DATA_TETHER;
+ }
+ return MODE_DATA_NONE;
+ }
+
+ private void setUsbFunction(int mode) {
+ switch (mode) {
+ case MODE_DATA_MTP:
+ mUsbManager.setCurrentFunctions(UsbManager.FUNCTION_MTP);
+ break;
+ case MODE_DATA_PTP:
+ mUsbManager.setCurrentFunctions(UsbManager.FUNCTION_PTP);
+ break;
+ case MODE_DATA_MIDI:
+ mUsbManager.setCurrentFunctions(UsbManager.FUNCTION_MIDI);
+ break;
+ case MODE_DATA_TETHER:
+ mUsbManager.setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
+ break;
+ default:
+ mUsbManager.setCurrentFunctions(UsbManager.FUNCTION_NONE);
+ break;
+ }
+ }
+
+ public void setMode(int mode) {
+ if (mPort != null) {
+ int powerRole = modeToPower(mode);
+ // If we aren't using any data modes and we support host mode, then go to host mode
+ // so maybe? the other device can provide data if it wants, otherwise go into device
+ // mode because we have no choice.
+ int dataRole = (mode & MODE_DATA_MASK) == MODE_DATA_NONE
+ && mPortStatus.isRoleCombinationSupported(powerRole, UsbPort.DATA_ROLE_HOST)
+ ? UsbPort.DATA_ROLE_HOST : UsbPort.DATA_ROLE_DEVICE;
+ mUsbManager.setPortRoles(mPort, powerRole, dataRole);
+ }
+ setUsbFunction(mode & MODE_DATA_MASK);
+ }
+
+ private int modeToPower(int mode) {
+ return (mode & MODE_POWER_MASK) == MODE_POWER_SOURCE
+ ? UsbPort.POWER_ROLE_SOURCE : UsbPort.POWER_ROLE_SINK;
+ }
+
+ public boolean isModeDisallowed(int mode) {
+ if (mFileTransferRestricted && ((mode & MODE_DATA_MASK) == MODE_DATA_MTP
+ || (mode & MODE_DATA_MASK) == MODE_DATA_PTP)) {
+ return true;
+ } else if (mTetheringRestricted && ((mode & MODE_DATA_MASK) == MODE_DATA_TETHER)) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isModeDisallowedBySystem(int mode) {
+ if (mFileTransferRestrictedBySystem && ((mode & MODE_DATA_MASK) == MODE_DATA_MTP
+ || (mode & MODE_DATA_MASK) == MODE_DATA_PTP)) {
+ return true;
+ } else if (mTetheringRestrictedBySystem && ((mode & MODE_DATA_MASK) == MODE_DATA_TETHER)) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isModeSupported(int mode) {
+ if (!mMidiSupported && (mode & MODE_DATA_MASK) == MODE_DATA_MIDI) {
+ return false;
+ }
+ if (!mTetheringSupported && (mode & MODE_DATA_MASK) == MODE_DATA_TETHER) {
+ return false;
+ }
+ if (mPort != null) {
+ int power = modeToPower(mode);
+ if ((mode & MODE_DATA_MASK) != 0) {
+ // We have a port and data, need to be in device mode.
+ return mPortStatus.isRoleCombinationSupported(power,
+ UsbPort.DATA_ROLE_DEVICE);
+ } else {
+ // No data needed, we can do this power mode in either device or host.
+ return mPortStatus.isRoleCombinationSupported(power, UsbPort.DATA_ROLE_DEVICE)
+ || mPortStatus.isRoleCombinationSupported(power, UsbPort.DATA_ROLE_HOST);
+ }
+ }
+ // No port, support sink modes only.
+ return (mode & MODE_POWER_MASK) != MODE_POWER_SOURCE;
+ }
+
+ // Wrapper class to enable testing with UserManager APIs
+ public static class UserRestrictionUtil {
+ private UserManager mUserManager;
+
+ public UserRestrictionUtil(Context context) {
+ mUserManager = UserManager.get(context);
+ }
+
+ public boolean isUsbFileTransferRestricted() {
+ return mUserManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER);
+ }
+
+ public boolean isUsbTetheringRestricted() {
+ return mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
+ }
+
+ public boolean isUsbFileTransferRestrictedBySystem() {
+ return mUserManager.hasBaseUserRestriction(
+ UserManager.DISALLOW_USB_FILE_TRANSFER, UserHandle.of(UserHandle.myUserId()));
+ }
+
+ public boolean isUsbTetheringRestrictedBySystem() {
+ return mUserManager.hasBaseUserRestriction(
+ UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.of(UserHandle.myUserId()));
+ }
+ }
+
+ // Temporary pass-through to allow roboelectric to use getCurrentFunctions()
+ public static class UsbManagerPassThrough {
+ private UsbManager mUsbManager;
+
+ public UsbManagerPassThrough(UsbManager manager) {
+ mUsbManager = manager;
+ }
+
+ public long getCurrentFunctions() {
+ return mUsbManager.getCurrentFunctions();
+ }
+
+ public long usbFunctionsFromString(String str) {
+ return UsbManager.usbFunctionsFromString(str);
+ }
+ }
+}
diff --git a/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiver.java b/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiver.java
new file mode 100644
index 0000000..91d22dc
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiver.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.connecteddevice.usb;
+
+
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.usb.UsbManager;
+import android.hardware.usb.UsbPort;
+import android.hardware.usb.UsbPortStatus;
+
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnResume;
+import com.android.settingslib.core.lifecycle.events.OnPause;
+
+/**
+ * Receiver to receive usb update and use {@link UsbConnectionListener} to invoke callback
+ */
+public class UsbConnectionBroadcastReceiver extends BroadcastReceiver implements LifecycleObserver,
+ OnResume, OnPause {
+ private Context mContext;
+ private UsbConnectionListener mUsbConnectionListener;
+ private boolean mListeningToUsbEvents;
+ private int mMode;
+ private boolean mConnected;
+ private UsbBackend mUsbBackend;
+
+ public UsbConnectionBroadcastReceiver(Context context,
+ UsbConnectionListener usbConnectionListener, UsbBackend backend) {
+ mContext = context;
+ mUsbConnectionListener = usbConnectionListener;
+ mUsbBackend = backend;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (UsbManager.ACTION_USB_STATE.equals(intent.getAction())) {
+ mConnected = intent.getExtras().getBoolean(UsbManager.USB_CONNECTED)
+ || intent.getExtras().getBoolean(UsbManager.USB_HOST_CONNECTED);
+ if (mConnected) {
+ mMode &= UsbBackend.MODE_POWER_MASK;
+ if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_MTP)
+ && intent.getExtras().getBoolean(UsbManager.USB_DATA_UNLOCKED, false)) {
+ mMode |= UsbBackend.MODE_DATA_MTP;
+ }
+ if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_PTP)
+ && intent.getExtras().getBoolean(UsbManager.USB_DATA_UNLOCKED, false)) {
+ mMode |= UsbBackend.MODE_DATA_PTP;
+ }
+ if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_MIDI)) {
+ mMode |= UsbBackend.MODE_DATA_MIDI;
+ }
+ if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_RNDIS)) {
+ mMode |= UsbBackend.MODE_DATA_TETHER;
+ }
+ }
+ } else if (UsbManager.ACTION_USB_PORT_CHANGED.equals(intent.getAction())) {
+ mMode &= UsbBackend.MODE_DATA_MASK;
+ UsbPortStatus portStatus = intent.getExtras()
+ .getParcelable(UsbManager.EXTRA_PORT_STATUS);
+ if (portStatus != null) {
+ mConnected = portStatus.isConnected();
+ if (mConnected) {
+ mMode |= portStatus.getCurrentPowerRole() == UsbPort.POWER_ROLE_SOURCE
+ ? UsbBackend.MODE_POWER_SOURCE : UsbBackend.MODE_POWER_SINK;
+ }
+ }
+ }
+ if (mUsbConnectionListener != null) {
+ mUsbConnectionListener.onUsbConnectionChanged(mConnected, mMode);
+ }
+ }
+
+ public void register() {
+ if (!mListeningToUsbEvents) {
+ mMode = mUsbBackend.getCurrentMode();
+ mConnected = false;
+ final IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(UsbManager.ACTION_USB_STATE);
+ intentFilter.addAction(UsbManager.ACTION_USB_PORT_CHANGED);
+ mContext.registerReceiver(this, intentFilter);
+ mListeningToUsbEvents = true;
+ }
+ }
+
+ public void unregister() {
+ if (mListeningToUsbEvents) {
+ mContext.unregisterReceiver(this);
+ mListeningToUsbEvents = false;
+ }
+ }
+
+ public boolean isConnected() {
+ return mConnected;
+ }
+
+ @Override
+ public void onResume() {
+ register();
+ }
+
+ @Override
+ public void onPause() {
+ unregister();
+ }
+
+ /**
+ * Interface definition for a callback to be invoked when usb connection is changed.
+ */
+ interface UsbConnectionListener {
+ void onUsbConnectionChanged(boolean connected, int newMode);
+ }
+}
diff --git a/src/com/android/settings/connecteddevice/usb/UsbDetailsController.java b/src/com/android/settings/connecteddevice/usb/UsbDetailsController.java
new file mode 100644
index 0000000..09c7554
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/usb/UsbDetailsController.java
@@ -0,0 +1,54 @@
+/*
+ * 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.connecteddevice.usb;
+
+import android.content.Context;
+import android.support.annotation.UiThread;
+import android.support.v14.preference.PreferenceFragment;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+/**
+ * This class provides common members and refresh functionality for usb controllers.
+ */
+public abstract class UsbDetailsController extends AbstractPreferenceController
+ implements PreferenceControllerMixin {
+
+ protected final Context mContext;
+ protected final PreferenceFragment mFragment;
+ protected final UsbBackend mUsbBackend;
+
+ public UsbDetailsController(Context context, PreferenceFragment fragment, UsbBackend backend) {
+ super(context);
+ mContext = context;
+ mFragment = fragment;
+ mUsbBackend = backend;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ /**
+ * This method is called when the USB mode has changed and the controller needs to update.
+ * @param newMode the new mode, made up of OR'd values from UsbBackend
+ */
+ @UiThread
+ protected abstract void refresh(int newMode);
+}
diff --git a/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java b/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java
new file mode 100644
index 0000000..c861188
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java
@@ -0,0 +1,131 @@
+/*
+ * 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.connecteddevice.usb;
+
+import android.content.Context;
+import android.hardware.usb.UsbManager;
+import android.os.Bundle;
+import android.provider.SearchIndexableResource;
+import android.support.annotation.VisibleForTesting;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import com.google.android.collect.Lists;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Controls the USB device details and provides updates to individual controllers.
+ */
+public class UsbDetailsFragment extends DashboardFragment {
+ private static final String TAG = UsbDetailsFragment.class.getSimpleName();
+
+ private List<UsbDetailsController> mControllers;
+ private UsbBackend mUsbBackend;
+
+ @VisibleForTesting
+ UsbConnectionBroadcastReceiver mUsbReceiver;
+
+ private UsbConnectionBroadcastReceiver.UsbConnectionListener mUsbConnectionListener =
+ (connected, newMode) -> {
+ if (!connected) {
+ this.finish();
+ } else {
+ for (UsbDetailsController controller : mControllers) {
+ controller.refresh(newMode);
+ }
+ }
+ };
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.USB_DEVICE_DETAILS;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.usb_details_fragment;
+ }
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ super.onCreatePreferences(savedInstanceState, rootKey);
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ mUsbBackend = new UsbBackend(context);
+ mControllers = createControllerList(context, mUsbBackend, this);
+ mUsbReceiver = new UsbConnectionBroadcastReceiver(context, mUsbConnectionListener,
+ mUsbBackend);
+ this.getLifecycle().addObserver(mUsbReceiver);
+
+ List<AbstractPreferenceController> ret = new ArrayList<>();
+ ret.addAll(mControllers);
+ return ret;
+ }
+
+ private static List<UsbDetailsController> createControllerList(Context context,
+ UsbBackend usbBackend, DashboardFragment fragment) {
+ List<UsbDetailsController> ret = new ArrayList<>();
+ ret.add(new UsbDetailsHeaderController(context, fragment, usbBackend));
+ ret.add(new UsbDetailsProfilesController(context, fragment,
+ usbBackend, Lists.newArrayList(UsbManager.USB_FUNCTION_MTP), "usb_main_options"));
+ ret.add(new UsbDetailsProfilesController(context, fragment,
+ usbBackend, Lists.newArrayList(UsbDetailsProfilesController.KEY_POWER,
+ UsbManager.USB_FUNCTION_RNDIS, UsbManager.USB_FUNCTION_MIDI,
+ UsbManager.USB_FUNCTION_PTP), "usb_secondary_options"));
+ return ret;
+ }
+
+ /**
+ * For Search.
+ */
+ public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider() {
+ @Override
+ public List<SearchIndexableResource> getXmlResourcesToIndex(
+ Context context, boolean enabled) {
+ return new ArrayList<>();
+ }
+
+ @Override
+ public List<String> getNonIndexableKeys(Context context) {
+ return super.getNonIndexableKeys(context);
+ }
+
+ @Override
+ public List<AbstractPreferenceController> getPreferenceControllers(
+ Context context) {
+ List<AbstractPreferenceController> ret = new ArrayList<>();
+ ret.addAll(createControllerList(context, new UsbBackend(context), null));
+ return ret;
+ }
+ };
+}
diff --git a/src/com/android/settings/connecteddevice/usb/UsbDetailsHeaderController.java b/src/com/android/settings/connecteddevice/usb/UsbDetailsHeaderController.java
new file mode 100644
index 0000000..7ac0235
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/usb/UsbDetailsHeaderController.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.connecteddevice.usb;
+
+import android.content.Context;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.applications.LayoutPreference;
+import com.android.settings.widget.EntityHeaderController;
+
+/**
+ * This class adds a header with device name and current function.
+ */
+public class UsbDetailsHeaderController extends UsbDetailsController {
+ private static final String KEY_DEVICE_HEADER = "usb_device_header";
+
+ private EntityHeaderController mHeaderController;
+
+ public UsbDetailsHeaderController(Context context, PreferenceFragment fragment,
+ UsbBackend backend) {
+ super(context, fragment, backend);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ final LayoutPreference headerPreference =
+ (LayoutPreference) screen.findPreference(KEY_DEVICE_HEADER);
+ mHeaderController = EntityHeaderController.newInstance(mFragment.getActivity(), mFragment,
+ headerPreference.findViewById(R.id.entity_header));
+ screen.addPreference(headerPreference);
+ }
+
+
+ @Override
+ protected void refresh(int newMode) {
+ mHeaderController.setLabel(mContext.getString(R.string.usb_pref));
+ mHeaderController.setIcon(mContext.getDrawable(R.drawable.ic_usb));
+ mHeaderController.setSummary(
+ mContext.getString(UsbModePreferenceController.getSummary(newMode)));
+ mHeaderController.done(mFragment.getActivity(), true /* rebindActions */);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_DEVICE_HEADER;
+ }
+}
diff --git a/src/com/android/settings/connecteddevice/usb/UsbDetailsProfilesController.java b/src/com/android/settings/connecteddevice/usb/UsbDetailsProfilesController.java
new file mode 100644
index 0000000..1375b4c
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/usb/UsbDetailsProfilesController.java
@@ -0,0 +1,147 @@
+/*
+ * 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.connecteddevice.usb;
+
+import com.android.settings.R;
+import android.content.Context;
+import android.hardware.usb.UsbManager;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceCategory;
+import android.support.v7.preference.PreferenceScreen;
+
+import java.util.List;
+
+/**
+ * This class adds switches for toggling individual USB options, such as "transfer files",
+ * "supply power", "usb tethering", etc.
+ */
+public class UsbDetailsProfilesController extends UsbDetailsController
+ implements Preference.OnPreferenceClickListener {
+
+ static final String KEY_POWER = "power";
+
+ private PreferenceCategory mProfilesContainer;
+ private List<String> mOptions;
+ private String mKey;
+
+ public UsbDetailsProfilesController(Context context, PreferenceFragment fragment,
+ UsbBackend backend, List<String> options, String key) {
+ super(context, fragment, backend);
+ mOptions = options;
+ mKey = key;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mProfilesContainer = (PreferenceCategory) screen.findPreference(getPreferenceKey());
+ }
+
+ /**
+ * Gets a switch preference for the particular option, creating it if needed.
+ */
+ private SwitchPreference getProfilePreference(String key, int titleId) {
+ SwitchPreference pref = (SwitchPreference) mProfilesContainer.findPreference(key);
+ if (pref == null) {
+ pref = new SwitchPreference(mProfilesContainer.getContext());
+ pref.setKey(key);
+ pref.setTitle(titleId);
+ pref.setOnPreferenceClickListener(this);
+ mProfilesContainer.addPreference(pref);
+ }
+ return pref;
+ }
+
+ @Override
+ protected void refresh(int mode) {
+ SwitchPreference pref;
+ for (String option : mOptions) {
+ int newMode;
+ int summary = -1;
+ int title;
+ if (option.equals(UsbManager.USB_FUNCTION_MTP)) {
+ newMode = UsbBackend.MODE_DATA_MTP;
+ title = R.string.usb_use_file_transfers;
+ } else if (option.equals(KEY_POWER)) {
+ newMode = UsbBackend.MODE_POWER_SOURCE;
+ title = R.string.usb_use_power_only;
+ summary = R.string.usb_use_power_only_desc;
+ } else if (option.equals(UsbManager.USB_FUNCTION_PTP)) {
+ newMode = UsbBackend.MODE_DATA_PTP;
+ title = R.string.usb_use_photo_transfers;
+ } else if (option.equals(UsbManager.USB_FUNCTION_MIDI)) {
+ newMode = UsbBackend.MODE_DATA_MIDI;
+ title = R.string.usb_use_MIDI;
+ } else if (option.equals(UsbManager.USB_FUNCTION_RNDIS)) {
+ newMode = UsbBackend.MODE_DATA_TETHER;
+ title = R.string.usb_use_tethering;
+ } else {
+ continue;
+ }
+
+ pref = getProfilePreference(option, title);
+ // Only show supported and allowed options
+ if (mUsbBackend.isModeSupported(newMode)
+ && !mUsbBackend.isModeDisallowedBySystem(newMode)
+ && !mUsbBackend.isModeDisallowed(newMode)) {
+ if (summary != -1) {
+ pref.setSummary(summary);
+ }
+ pref.setChecked((mode & newMode) != 0);
+ } else {
+ mProfilesContainer.removePreference(pref);
+ }
+ }
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ SwitchPreference profilePref = (SwitchPreference) preference;
+ String key = profilePref.getKey();
+ int mode = mUsbBackend.getCurrentMode();
+ int thisMode = 0;
+ if (key.equals(KEY_POWER)) {
+ thisMode = UsbBackend.MODE_POWER_SOURCE;
+ } else if (key.equals(UsbManager.USB_FUNCTION_MTP)) {
+ thisMode = UsbBackend.MODE_DATA_MTP;
+ } else if (key.equals(UsbManager.USB_FUNCTION_PTP)) {
+ thisMode = UsbBackend.MODE_DATA_PTP;
+ } else if (key.equals(UsbManager.USB_FUNCTION_RNDIS)) {
+ thisMode = UsbBackend.MODE_DATA_TETHER;
+ } else if (key.equals(UsbManager.USB_FUNCTION_MIDI)) {
+ thisMode = UsbBackend.MODE_DATA_MIDI;
+ }
+ if (profilePref.isChecked()) {
+ if (!key.equals(KEY_POWER)) {
+ // Only one non power mode can currently be set at once.
+ mode &= UsbBackend.MODE_POWER_MASK;
+ }
+ mode |= thisMode;
+ } else {
+ mode &= ~thisMode;
+ }
+ mUsbBackend.setMode(mode);
+ return false;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return mKey;
+ }
+}
diff --git a/src/com/android/settings/deviceinfo/UsbModeChooserActivity.java b/src/com/android/settings/connecteddevice/usb/UsbModeChooserActivity.java
similarity index 98%
rename from src/com/android/settings/deviceinfo/UsbModeChooserActivity.java
rename to src/com/android/settings/connecteddevice/usb/UsbModeChooserActivity.java
index 8ba3781..b3b0718 100644
--- a/src/com/android/settings/deviceinfo/UsbModeChooserActivity.java
+++ b/src/com/android/settings/connecteddevice/usb/UsbModeChooserActivity.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.deviceinfo;
+package com.android.settings.connecteddevice.usb;
import android.annotation.Nullable;
import android.app.Activity;
diff --git a/src/com/android/settings/connecteddevice/UsbModePreferenceController.java b/src/com/android/settings/connecteddevice/usb/UsbModePreferenceController.java
similarity index 72%
rename from src/com/android/settings/connecteddevice/UsbModePreferenceController.java
rename to src/com/android/settings/connecteddevice/usb/UsbModePreferenceController.java
index 8693520..e342460 100644
--- a/src/com/android/settings/connecteddevice/UsbModePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/usb/UsbModePreferenceController.java
@@ -13,15 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.settings.connecteddevice;
+package com.android.settings.connecteddevice.usb;
import android.content.Context;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.deviceinfo.UsbBackend;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnPause;
@@ -33,27 +33,27 @@
private static final String KEY_USB_MODE = "usb_mode";
private UsbBackend mUsbBackend;
- private UsbConnectionBroadcastReceiver mUsbReceiver;
+ @VisibleForTesting
+ UsbConnectionBroadcastReceiver mUsbReceiver;
private Preference mUsbPreference;
public UsbModePreferenceController(Context context, UsbBackend usbBackend) {
super(context);
mUsbBackend = usbBackend;
- mUsbReceiver = new UsbConnectionBroadcastReceiver(mContext, (connected) -> {
- updateSummary(mUsbPreference);
- });
+ mUsbReceiver = new UsbConnectionBroadcastReceiver(mContext, (connected, newMode) -> {
+ updateSummary(mUsbPreference, connected, newMode);
+ }, mUsbBackend);
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mUsbPreference = screen.findPreference(KEY_USB_MODE);
- updateSummary(mUsbPreference);
}
@Override
public void updateState(Preference preference) {
- updateSummary(preference);
+ updateSummary(preference, mUsbReceiver.isConnected(), mUsbBackend.getCurrentMode());
}
@Override
@@ -88,17 +88,24 @@
return R.string.usb_summary_photo_transfers;
case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_MIDI:
return R.string.usb_summary_MIDI;
+ case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_TETHER:
+ return R.string.usb_summary_tether;
+ case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_MTP:
+ return R.string.usb_summary_file_transfers_power;
+ case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_PTP:
+ return R.string.usb_summary_photo_transfers_power;
+ case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_MIDI:
+ return R.string.usb_summary_MIDI_power;
+ case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_TETHER:
+ return R.string.usb_summary_tether_power;
+ default:
+ return R.string.usb_summary_charging_only;
}
- return 0;
}
- private void updateSummary(Preference preference) {
- updateSummary(preference, mUsbBackend.getCurrentMode());
- }
-
- private void updateSummary(Preference preference, int mode) {
+ private void updateSummary(Preference preference, boolean connected, int mode) {
if (preference != null) {
- if (mUsbReceiver.isConnected()) {
+ if (connected) {
preference.setEnabled(true);
preference.setSummary(getSummary(mode));
} else {
@@ -107,5 +114,4 @@
}
}
}
-
}
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index af85ac9..f43c3c8 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -58,6 +58,7 @@
import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragmentOld;
+import com.android.settings.connecteddevice.usb.UsbDetailsFragment;
import com.android.settings.datausage.DataPlanUsageSummary;
import com.android.settings.datausage.DataUsageList;
import com.android.settings.datausage.DataUsageSummary;
@@ -242,6 +243,7 @@
NetworkDashboardFragment.class.getName(),
ConnectedDeviceDashboardFragment.class.getName(),
ConnectedDeviceDashboardFragmentOld.class.getName(),
+ UsbDetailsFragment.class.getName(),
AppAndNotificationDashboardFragment.class.getName(),
AccountDashboardFragment.class.getName(),
EnterprisePrivacySettings.class.getName(),
diff --git a/src/com/android/settings/dashboard/conditional/DndCondition.java b/src/com/android/settings/dashboard/conditional/DndCondition.java
index a60c362..6498db6 100644
--- a/src/com/android/settings/dashboard/conditional/DndCondition.java
+++ b/src/com/android/settings/dashboard/conditional/DndCondition.java
@@ -15,9 +15,7 @@
*/
package com.android.settings.dashboard.conditional;
-import android.app.ActivityManager;
import android.app.NotificationManager;
-import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -31,6 +29,8 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.notification.ZenModeSettings;
public class DndCondition extends Condition {
@@ -80,19 +80,6 @@
mZen = bundle.getInt(KEY_STATE, Global.ZEN_MODE_OFF);
}
- private CharSequence getZenState() {
- switch (mZen) {
- case Settings.Global.ZEN_MODE_ALARMS:
- return mManager.getContext().getString(R.string.zen_mode_option_alarms);
- case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
- return mManager.getContext().getString(
- R.string.zen_mode_option_important_interruptions);
- case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
- return mManager.getContext().getString(R.string.zen_mode_option_no_interruptions);
- }
- return null;
- }
-
@Override
public Icon getIcon() {
return Icon.createWithResource(mManager.getContext(), R.drawable.ic_zen);
@@ -100,17 +87,13 @@
@Override
public CharSequence getTitle() {
- return mManager.getContext().getString(R.string.condition_zen_title, getZenState());
+ return mManager.getContext().getString(R.string.condition_zen_title);
}
@Override
public CharSequence getSummary() {
- final boolean isForever = mConfig != null && mConfig.manualRule != null
- && mConfig.manualRule.conditionId == null;
- return isForever ? mManager.getContext().getString(com.android.internal.R.string.zen_mode_forever_dnd)
- : ZenModeConfig.getConditionSummary(mManager.getContext(), mConfig,
- ActivityManager.getCurrentUser(),
- false);
+ return ZenModeConfig.getDescription(mManager.getContext(), mZen != Global.ZEN_MODE_OFF,
+ mConfig);
}
@Override
@@ -120,8 +103,9 @@
@Override
public void onPrimaryClick() {
- StatusBarManager statusBar = mManager.getContext().getSystemService(StatusBarManager.class);
- statusBar.expandSettingsPanel("dnd");
+ Utils.startWithFragment(mManager.getContext(), ZenModeSettings.class.getName(), null,
+ null, 0, R.string.zen_mode_settings_title, null,
+ MetricsEvent.NOTIFICATION_ZEN_MODE);
}
@Override
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
index 070e758..9bcf2a2 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
@@ -116,7 +116,7 @@
mConfig.setCardLayout(holder, suggestionCount, position);
final Icon icon = suggestion.getIcon();
final Drawable drawable = mCache.getIcon(icon);
- if (drawable != null && TextUtils.equals(icon.getResPackage(), mContext.getPackageName())) {
+ if ((suggestion.getFlags() & Suggestion.FLAG_ICON_TINTABLE) != 0) {
drawable.setTint(Utils.getColorAccent(mContext));
}
holder.icon.setImageDrawable(drawable);
diff --git a/src/com/android/settings/development/SelectUsbConfigPreferenceController.java b/src/com/android/settings/development/SelectUsbConfigPreferenceController.java
index 77a9a75..63eb24c 100644
--- a/src/com/android/settings/development/SelectUsbConfigPreferenceController.java
+++ b/src/com/android/settings/development/SelectUsbConfigPreferenceController.java
@@ -27,11 +27,11 @@
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
-import android.text.TextUtils;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.connecteddevice.usb.UsbBackend;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnCreate;
@@ -48,6 +48,8 @@
private final String[] mListValues;
private final String[] mListSummaries;
private final UsbManager mUsbManager;
+ @VisibleForTesting
+ UsbBackend.UsbManagerPassThrough mUsbManagerPassThrough;
private BroadcastReceiver mUsbReceiver;
private ListPreference mPreference;
@@ -57,6 +59,7 @@
mListValues = context.getResources().getStringArray(R.array.usb_configuration_values);
mListSummaries = context.getResources().getStringArray(R.array.usb_configuration_titles);
mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
+ mUsbManagerPassThrough = new UsbBackend.UsbManagerPassThrough(mUsbManager);
mUsbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -95,7 +98,8 @@
return false;
}
- writeUsbConfigurationOption(newValue.toString());
+ writeUsbConfigurationOption(mUsbManagerPassThrough
+ .usbFunctionsFromString(newValue.toString()));
updateUsbConfigurationValues();
return true;
}
@@ -129,14 +133,15 @@
}
@VisibleForTesting
- void setCurrentFunction(String newValue, boolean usbDataUnlocked) {
- mUsbManager.setCurrentFunction(newValue, usbDataUnlocked);
+ void setCurrentFunctions(long functions) {
+ mUsbManager.setCurrentFunctions(functions);
}
private void updateUsbConfigurationValues() {
+ long functions = mUsbManagerPassThrough.getCurrentFunctions();
int index = 0;
for (int i = 0; i < mListValues.length; i++) {
- if (mUsbManager.isFunctionEnabled(mListValues[i])) {
+ if (functions == mUsbManagerPassThrough.usbFunctionsFromString(mListValues[i])) {
index = i;
break;
}
@@ -145,11 +150,7 @@
mPreference.setSummary(mListSummaries[index]);
}
- private void writeUsbConfigurationOption(String newValue) {
- if (TextUtils.equals(newValue, "none")) {
- setCurrentFunction(newValue, false);
- } else {
- setCurrentFunction(newValue, true);
- }
+ private void writeUsbConfigurationOption(long newValue) {
+ setCurrentFunctions(newValue);
}
}
diff --git a/src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java b/src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java
index ee069da..831c630 100644
--- a/src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java
@@ -41,7 +41,7 @@
@Override
public boolean isAvailable() {
- return true;
+ return mContext.getResources().getBoolean(R.bool.config_show_device_model);
}
@Override
diff --git a/src/com/android/settings/deviceinfo/IpAddressPreferenceController.java b/src/com/android/settings/deviceinfo/IpAddressPreferenceController.java
index f4e2f8c..1af6397 100644
--- a/src/com/android/settings/deviceinfo/IpAddressPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/IpAddressPreferenceController.java
@@ -19,6 +19,8 @@
import android.content.Context;
import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.R;
+
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.deviceinfo.AbstractIpAddressPreferenceController;
@@ -31,5 +33,10 @@
super(context, lifecycle);
}
+ @Override
+ public boolean isAvailable() {
+ return mContext.getResources().getBoolean(R.bool.config_show_wifi_ip_address);
+ }
+
// This space intentionally left blank
}
diff --git a/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java
index 93f75bf..4eb2ddd 100644
--- a/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java
@@ -58,7 +58,7 @@
@Override
public boolean isAvailable() {
- return true;
+ return mTelephonyManager.isVoiceCapable();
}
@Override
diff --git a/src/com/android/settings/deviceinfo/UsbBackend.java b/src/com/android/settings/deviceinfo/UsbBackend.java
deleted file mode 100644
index 5d2502b..0000000
--- a/src/com/android/settings/deviceinfo/UsbBackend.java
+++ /dev/null
@@ -1,202 +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.
- */
-package com.android.settings.deviceinfo;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.hardware.usb.UsbManager;
-import android.hardware.usb.UsbPort;
-import android.hardware.usb.UsbPortStatus;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.support.annotation.VisibleForTesting;
-
-public class UsbBackend {
-
- public static final int MODE_POWER_MASK = 0x01;
- public static final int MODE_POWER_SINK = 0x00;
- public static final int MODE_POWER_SOURCE = 0x01;
-
- public static final int MODE_DATA_MASK = 0x03 << 1;
- public static final int MODE_DATA_NONE = 0x00 << 1;
- public static final int MODE_DATA_MTP = 0x01 << 1;
- public static final int MODE_DATA_PTP = 0x02 << 1;
- public static final int MODE_DATA_MIDI = 0x03 << 1;
-
- private final boolean mRestricted;
- private final boolean mRestrictedBySystem;
- private final boolean mMidi;
-
- private UsbManager mUsbManager;
- private UsbPort mPort;
- private UsbPortStatus mPortStatus;
-
- private Context mContext;
-
- public UsbBackend(Context context) {
- this(context, new UserRestrictionUtil(context));
- }
-
- @VisibleForTesting
- public UsbBackend(Context context, UserRestrictionUtil userRestrictionUtil) {
- mContext = context;
- mUsbManager = context.getSystemService(UsbManager.class);
-
- mRestricted = userRestrictionUtil.isUsbFileTransferRestricted();
- mRestrictedBySystem = userRestrictionUtil.isUsbFileTransferRestrictedBySystem();
- mMidi = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MIDI);
-
- UsbPort[] ports = mUsbManager.getPorts();
- if (ports == null) {
- return;
- }
- // For now look for a connected port, in the future we should identify port in the
- // notification and pick based on that.
- final int N = ports.length;
- for (int i = 0; i < N; i++) {
- UsbPortStatus status = mUsbManager.getPortStatus(ports[i]);
- if (status.isConnected()) {
- mPort = ports[i];
- mPortStatus = status;
- break;
- }
- }
- }
-
- public int getCurrentMode() {
- if (mPort != null) {
- int power = mPortStatus.getCurrentPowerRole() == UsbPort.POWER_ROLE_SOURCE
- ? MODE_POWER_SOURCE : MODE_POWER_SINK;
- return power | getUsbDataMode();
- }
- return MODE_POWER_SINK | getUsbDataMode();
- }
-
- public int getUsbDataMode() {
- if (!isUsbDataUnlocked()) {
- return MODE_DATA_NONE;
- } else if (mUsbManager.isFunctionEnabled(UsbManager.USB_FUNCTION_MTP)) {
- return MODE_DATA_MTP;
- } else if (mUsbManager.isFunctionEnabled(UsbManager.USB_FUNCTION_PTP)) {
- return MODE_DATA_PTP;
- } else if (mUsbManager.isFunctionEnabled(UsbManager.USB_FUNCTION_MIDI)) {
- return MODE_DATA_MIDI;
- }
- return MODE_DATA_NONE; // ...
- }
-
- private boolean isUsbDataUnlocked() {
- Intent intent = mContext.registerReceiver(null,
- new IntentFilter(UsbManager.ACTION_USB_STATE));
- return intent == null ?
- false : intent.getBooleanExtra(UsbManager.USB_DATA_UNLOCKED, false);
- }
-
- private void setUsbFunction(int mode) {
- switch (mode) {
- case MODE_DATA_MTP:
- mUsbManager.setCurrentFunction(UsbManager.USB_FUNCTION_MTP, true);
- break;
- case MODE_DATA_PTP:
- mUsbManager.setCurrentFunction(UsbManager.USB_FUNCTION_PTP, true);
- break;
- case MODE_DATA_MIDI:
- mUsbManager.setCurrentFunction(UsbManager.USB_FUNCTION_MIDI, true);
- break;
- default:
- mUsbManager.setCurrentFunction(null, false);
- break;
- }
- }
-
- public void setMode(int mode) {
- if (mPort != null) {
- int powerRole = modeToPower(mode);
- // If we aren't using any data modes and we support host mode, then go to host mode
- // so maybe? the other device can provide data if it wants, otherwise go into device
- // mode because we have no choice.
- int dataRole = (mode & MODE_DATA_MASK) == MODE_DATA_NONE
- && mPortStatus.isRoleCombinationSupported(powerRole, UsbPort.DATA_ROLE_HOST)
- ? UsbPort.DATA_ROLE_HOST : UsbPort.DATA_ROLE_DEVICE;
- mUsbManager.setPortRoles(mPort, powerRole, dataRole);
- }
- setUsbFunction(mode & MODE_DATA_MASK);
- }
-
- private int modeToPower(int mode) {
- return (mode & MODE_POWER_MASK) == MODE_POWER_SOURCE
- ? UsbPort.POWER_ROLE_SOURCE : UsbPort.POWER_ROLE_SINK;
- }
-
- public boolean isModeDisallowed(int mode) {
- if (mRestricted && (mode & MODE_DATA_MASK) != MODE_DATA_NONE
- && (mode & MODE_DATA_MASK) != MODE_DATA_MIDI) {
- // No USB data modes are supported.
- return true;
- }
- return false;
- }
-
- public boolean isModeDisallowedBySystem(int mode) {
- if (mRestrictedBySystem && (mode & MODE_DATA_MASK) != MODE_DATA_NONE
- && (mode & MODE_DATA_MASK) != MODE_DATA_MIDI) {
- // No USB data modes are supported.
- return true;
- }
- return false;
- }
-
- public boolean isModeSupported(int mode) {
- if (!mMidi && (mode & MODE_DATA_MASK) == MODE_DATA_MIDI) {
- return false;
- }
-
- if (mPort != null) {
- int power = modeToPower(mode);
- if ((mode & MODE_DATA_MASK) != 0) {
- // We have a port and data, need to be in device mode.
- return mPortStatus.isRoleCombinationSupported(power,
- UsbPort.DATA_ROLE_DEVICE);
- } else {
- // No data needed, we can do this power mode in either device or host.
- return mPortStatus.isRoleCombinationSupported(power, UsbPort.DATA_ROLE_DEVICE)
- || mPortStatus.isRoleCombinationSupported(power, UsbPort.DATA_ROLE_HOST);
- }
- }
- // No port, support sink modes only.
- return (mode & MODE_POWER_MASK) != MODE_POWER_SOURCE;
- }
-
- // Wrapper class to enable testing with UserManager APIs
- public static class UserRestrictionUtil {
- private UserManager mUserManager;
-
- public UserRestrictionUtil(Context context) {
- mUserManager = UserManager.get(context);
- }
-
- public boolean isUsbFileTransferRestricted() {
- return mUserManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER);
- }
-
- public boolean isUsbFileTransferRestrictedBySystem() {
- return mUserManager.hasBaseUserRestriction(
- UserManager.DISALLOW_USB_FILE_TRANSFER, UserHandle.of(UserHandle.myUserId()));
- }
- }
-}
diff --git a/src/com/android/settings/deviceinfo/WifiMacAddressPreferenceController.java b/src/com/android/settings/deviceinfo/WifiMacAddressPreferenceController.java
index 92390d7..8375310 100644
--- a/src/com/android/settings/deviceinfo/WifiMacAddressPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/WifiMacAddressPreferenceController.java
@@ -19,6 +19,7 @@
import android.content.Context;
import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.R;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.deviceinfo.AbstractWifiMacAddressPreferenceController;
@@ -31,5 +32,10 @@
super(context, lifecycle);
}
+ @Override
+ public boolean isAvailable() {
+ return mContext.getResources().getBoolean(R.bool.config_show_wifi_mac_address);
+ }
+
// This space intentionally left blank
}
diff --git a/src/com/android/settings/fingerprint/FingerprintEnrollBase.java b/src/com/android/settings/fingerprint/FingerprintEnrollBase.java
index 7c34f2d..5a148d3 100644
--- a/src/com/android/settings/fingerprint/FingerprintEnrollBase.java
+++ b/src/com/android/settings/fingerprint/FingerprintEnrollBase.java
@@ -48,7 +48,6 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setTheme(R.style.Theme_FingerprintEnroll);
mToken = getIntent().getByteArrayExtra(
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
if (savedInstanceState != null && mToken == null) {
diff --git a/src/com/android/settings/inputmethod/PhysicalKeyboardPreferenceController.java b/src/com/android/settings/inputmethod/PhysicalKeyboardPreferenceController.java
index ec0aecd..f80b68f 100644
--- a/src/com/android/settings/inputmethod/PhysicalKeyboardPreferenceController.java
+++ b/src/com/android/settings/inputmethod/PhysicalKeyboardPreferenceController.java
@@ -66,12 +66,12 @@
@Override
public void onPause() {
- mIm.registerInputDeviceListener(this, null);
+ mIm.unregisterInputDeviceListener(this);
}
@Override
public void onResume() {
- mIm.unregisterInputDeviceListener(this);
+ mIm.registerInputDeviceListener(this, null);
}
@Override
diff --git a/src/com/android/settings/location/LocationEnabler.java b/src/com/android/settings/location/LocationEnabler.java
index 30ecf2e..fd557a3 100644
--- a/src/com/android/settings/location/LocationEnabler.java
+++ b/src/com/android/settings/location/LocationEnabler.java
@@ -169,7 +169,7 @@
if (admin == null) {
admin = RestrictedLockUtils.checkIfRestrictionEnforced(
- mContext, UserManager.DISALLOW_CONFIG_LOCATION_MODE, userId);
+ mContext, UserManager.DISALLOW_CONFIG_LOCATION, userId);
}
return admin;
}
diff --git a/src/com/android/settings/search/SearchIndexableResourcesImpl.java b/src/com/android/settings/search/SearchIndexableResourcesImpl.java
index 38dc15d..1edc2de 100644
--- a/src/com/android/settings/search/SearchIndexableResourcesImpl.java
+++ b/src/com/android/settings/search/SearchIndexableResourcesImpl.java
@@ -21,6 +21,8 @@
import com.android.settings.DateTimeSettings;
import com.android.settings.DisplaySettings;
import com.android.settings.LegalSettings;
+import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragmentOld;
+import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
import com.android.settings.accessibility.AccessibilitySettings;
import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
import com.android.settings.accessibility.MagnificationPreferenceFragment;
@@ -34,7 +36,7 @@
import com.android.settings.bluetooth.BluetoothSettings;
import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
-import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragmentOld;
+import com.android.settings.connecteddevice.usb.UsbDetailsFragment;
import com.android.settings.datausage.DataUsageSummary;
import com.android.settings.deletionhelper.AutomaticStorageManagerSettings;
import com.android.settings.development.DevelopmentSettingsDashboardFragment;
@@ -167,6 +169,7 @@
addIndex(PowerUsageSummary.class);
addIndex(BatterySaverSettings.class);
addIndex(LockscreenDashboardFragment.class);
+ addIndex(UsbDetailsFragment.class);
addIndex(WifiDisplaySettings.class);
addIndex(ZenModeBehaviorSettings.class);
addIndex(ZenModeAutomationSettings.class);
diff --git a/src/com/android/settings/users/UserCapabilities.java b/src/com/android/settings/users/UserCapabilities.java
index 084a5db..f1bfae9 100644
--- a/src/com/android/settings/users/UserCapabilities.java
+++ b/src/com/android/settings/users/UserCapabilities.java
@@ -34,6 +34,7 @@
boolean mCanAddGuest;
boolean mDisallowAddUser;
boolean mDisallowAddUserSetByAdmin;
+ boolean mDisallowSwitchUser;
RestrictedLockUtils.EnforcedAdmin mEnforcedAdmin;
private UserCapabilities() {}
@@ -79,6 +80,9 @@
final boolean canAddUsersWhenLocked = mIsAdmin || Settings.Global.getInt(
context.getContentResolver(), Settings.Global.ADD_USERS_WHEN_LOCKED, 0) == 1;
mCanAddGuest = !mIsGuest && !mDisallowAddUser && canAddUsersWhenLocked;
+
+ UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ mDisallowSwitchUser = userManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH);
}
public boolean isAdmin() {
@@ -109,6 +113,7 @@
", mCanAddGuest=" + mCanAddGuest +
", mDisallowAddUser=" + mDisallowAddUser +
", mEnforcedAdmin=" + mEnforcedAdmin +
+ ", mDisallowSwitchUser=" + mDisallowSwitchUser +
'}';
}
}
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index fcb8aef..f6bacd8 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -309,7 +309,7 @@
public void onDestroy() {
super.onDestroy();
- if (!mUserCaps.mEnabled) {
+ if (mUserCaps == null || !mUserCaps.mEnabled) {
return;
}
@@ -757,8 +757,12 @@
synchronized (mUserLock) {
if (userType == USER_TYPE_USER) {
mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST);
- mHandler.sendMessage(mHandler.obtainMessage(
- MESSAGE_SETUP_USER, user.id, user.serialNumber));
+ // Skip setting up user which results in user switching when the
+ // restriction is set.
+ if (!mUserCaps.mDisallowSwitchUser) {
+ mHandler.sendMessage(mHandler.obtainMessage(
+ MESSAGE_SETUP_USER, user.id, user.serialNumber));
+ }
} else {
mHandler.sendMessage(mHandler.obtainMessage(
MESSAGE_CONFIG_USER, user.id, user.serialNumber));
@@ -845,8 +849,12 @@
} else {
pref.setSummary(R.string.user_summary_not_set_up);
}
- pref.setOnPreferenceClickListener(this);
- pref.setSelectable(true);
+ // Disallow setting up user which results in user switching when the restriction is
+ // set.
+ if (!mUserCaps.mDisallowSwitchUser) {
+ pref.setOnPreferenceClickListener(this);
+ pref.setSelectable(true);
+ }
} else if (user.isRestricted()) {
pref.setSummary(R.string.user_summary_restricted_profile);
}
@@ -885,8 +893,13 @@
pref.setTitle(R.string.user_guest);
pref.setIcon(getEncircledDefaultIcon());
userPreferences.add(pref);
- pref.setDisabledByAdmin(
- mUserCaps.mDisallowAddUser ? mUserCaps.mEnforcedAdmin : null);
+ if (mUserCaps.mDisallowAddUser) {
+ pref.setDisabledByAdmin(mUserCaps.mEnforcedAdmin);
+ } else if (mUserCaps.mDisallowSwitchUser) {
+ pref.setDisabledByAdmin(RestrictedLockUtils.getDeviceOwner(context));
+ } else {
+ pref.setDisabledByAdmin(null);
+ }
int finalGuestId = guestId;
pref.setOnPreferenceClickListener(preference -> {
int id = finalGuestId;
diff --git a/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java b/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
new file mode 100644
index 0000000..e1999ef
--- /dev/null
+++ b/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.widget;
+
+import android.content.Context;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.PreferenceGroup;
+import android.support.v7.preference.PreferenceGroupAdapter;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.support.v7.widget.RecyclerView;
+import android.text.TextUtils;
+import android.util.TypedValue;
+import android.view.View;
+
+import com.android.settings.R;
+
+public class HighlightablePreferenceGroupAdapter extends PreferenceGroupAdapter {
+
+ @VisibleForTesting
+ static final long DELAY_HIGHLIGHT_DURATION_MILLIS = 600L;
+ private static final long HIGHLIGHT_DURATION = 5000L;
+
+ private final int mHighlightColor;
+ private final int mNormalBackgroundRes;
+ private final String mHighlightKey;
+
+ private boolean mHighlightRequested;
+ private int mHighlightPosition = RecyclerView.NO_POSITION;
+
+ public HighlightablePreferenceGroupAdapter(PreferenceGroup preferenceGroup, String key,
+ boolean highlightRequested) {
+ super(preferenceGroup);
+ mHighlightKey = key;
+ mHighlightRequested = highlightRequested;
+ final Context context = preferenceGroup.getContext();
+ final TypedValue outValue = new TypedValue();
+ context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
+ outValue, true /* resolveRefs */);
+ mNormalBackgroundRes = outValue.resourceId;
+ mHighlightColor = context.getColor(R.color.preference_highligh_color);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder, int position) {
+ super.onBindViewHolder(holder, position);
+ updateBackground(holder, position);
+ }
+
+ @VisibleForTesting
+ void updateBackground(PreferenceViewHolder holder, int position) {
+ View v = holder.itemView;
+ if (position == mHighlightPosition) {
+ v.setBackgroundColor(mHighlightColor);
+ v.setTag(R.id.preference_highlighted, true);
+ v.postDelayed(() -> {
+ mHighlightPosition = RecyclerView.NO_POSITION;
+ removeHighlightBackground(v);
+ }, HIGHLIGHT_DURATION);
+ } else if (Boolean.TRUE.equals(v.getTag(R.id.preference_highlighted))) {
+ removeHighlightBackground(v);
+ }
+ }
+
+ public void requestHighlight(View root, RecyclerView recyclerView) {
+ if (mHighlightRequested || recyclerView == null || TextUtils.isEmpty(mHighlightKey)) {
+ return;
+ }
+ root.postDelayed(() -> {
+ final int position = getPreferenceAdapterPosition(mHighlightKey);
+ if (position < 0) {
+ return;
+ }
+ mHighlightRequested = true;
+ recyclerView.getLayoutManager().scrollToPosition(position);
+ mHighlightPosition = position;
+ notifyItemChanged(position);
+ }, DELAY_HIGHLIGHT_DURATION_MILLIS);
+ }
+
+ public boolean isHighlightRequested() {
+ return mHighlightRequested;
+ }
+
+ private void removeHighlightBackground(View v) {
+ v.setBackgroundResource(mNormalBackgroundRes);
+ v.setTag(R.id.preference_highlighted, false);
+ }
+}
diff --git a/src/com/android/settings/wifi/ConfigureWifiSettings.java b/src/com/android/settings/wifi/ConfigureWifiSettings.java
index 3cd925e..b359bf3 100644
--- a/src/com/android/settings/wifi/ConfigureWifiSettings.java
+++ b/src/com/android/settings/wifi/ConfigureWifiSettings.java
@@ -63,10 +63,7 @@
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- int tileLimit = 1;
- if (mWifiWakeupPreferenceController.isAvailable()) {
- tileLimit++;
- }
+ int tileLimit = 2;
if (mUseOpenWifiPreferenceController.isAvailable()) {
tileLimit++;
}
@@ -82,8 +79,7 @@
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
final NetworkScoreManagerWrapper networkScoreManagerWrapper =
new NetworkScoreManagerWrapper(context.getSystemService(NetworkScoreManager.class));
- mWifiWakeupPreferenceController = new WifiWakeupPreferenceController(
- context, getLifecycle());
+ mWifiWakeupPreferenceController = new WifiWakeupPreferenceController(context);
mUseOpenWifiPreferenceController = new UseOpenWifiPreferenceController(context, this,
networkScoreManagerWrapper, getLifecycle());
final WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index e32bef4..22f8c43 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -911,17 +911,10 @@
private void setAdditionalSettingsSummaries() {
mAdditionalSettingsPreferenceCategory.addPreference(mConfigureWifiSettingsPreference);
- final int defaultWakeupAvailable = getResources().getInteger(
- com.android.internal.R.integer.config_wifi_wakeup_available);
- boolean wifiWakeupAvailable = Settings.Global.getInt(
- getContentResolver(), Settings.Global.WIFI_WAKEUP_AVAILABLE, defaultWakeupAvailable)
- == 1;
- if (wifiWakeupAvailable) {
- mConfigureWifiSettingsPreference.setSummary(getString(
- isWifiWakeupEnabled()
- ? R.string.wifi_configure_settings_preference_summary_wakeup_on
- : R.string.wifi_configure_settings_preference_summary_wakeup_off));
- }
+ mConfigureWifiSettingsPreference.setSummary(getString(
+ isWifiWakeupEnabled()
+ ? R.string.wifi_configure_settings_preference_summary_wakeup_on
+ : R.string.wifi_configure_settings_preference_summary_wakeup_off));
int numSavedNetworks = mWifiTracker.getNumSavedNetworks();
if (numSavedNetworks > 0) {
mAdditionalSettingsPreferenceCategory.addPreference(mSavedNetworksPreference);
@@ -942,8 +935,6 @@
Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1
&& Settings.Global.getInt(contentResolver,
Settings.Global.AIRPLANE_MODE_ON, 0) == 0
- && Settings.Global.getInt(contentResolver,
- Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 0) == 1
&& !powerManager.isPowerSaveMode();
}
diff --git a/src/com/android/settings/wifi/WifiWakeupPreferenceController.java b/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
index a3170c0..bc9f2a0 100644
--- a/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
+++ b/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
@@ -31,52 +31,28 @@
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.wrapper.NetworkScoreManagerWrapper;
import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnPause;
-import com.android.settingslib.core.lifecycle.events.OnResume;
/**
* {@link PreferenceControllerMixin} that controls whether the Wi-Fi Wakeup feature should be
* enabled.
*/
public class WifiWakeupPreferenceController extends AbstractPreferenceController
- implements PreferenceControllerMixin, LifecycleObserver, OnResume, OnPause {
+ implements PreferenceControllerMixin {
private static final String KEY_ENABLE_WIFI_WAKEUP = "enable_wifi_wakeup";
- private SettingObserver mSettingObserver;
- public WifiWakeupPreferenceController(Context context, Lifecycle lifecycle) {
+ public WifiWakeupPreferenceController(Context context) {
super(context);
- lifecycle.addObserver(this);
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
- mSettingObserver = new SettingObserver(screen.findPreference(KEY_ENABLE_WIFI_WAKEUP));
- }
-
- @Override
- public void onResume() {
- if (mSettingObserver != null) {
- mSettingObserver.register(mContext.getContentResolver(), true /* register */);
- }
- }
-
- @Override
- public void onPause() {
- if (mSettingObserver != null) {
- mSettingObserver.register(mContext.getContentResolver(), false /* register */);
- }
}
@Override
public boolean isAvailable() {
- final int defaultValue = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_wifi_wakeup_available);
- return Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.WIFI_WAKEUP_AVAILABLE, defaultValue) == 1;
+ return true;
}
@Override
@@ -110,45 +86,12 @@
boolean wifiScanningEnabled = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1;
- boolean networkRecommendationsEnabled = Settings.Global.getInt(
- mContext.getContentResolver(),
- Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 0) == 1;
- enableWifiWakeup.setEnabled(networkRecommendationsEnabled && wifiScanningEnabled);
+ enableWifiWakeup.setEnabled(wifiScanningEnabled);
- if (!networkRecommendationsEnabled) {
- enableWifiWakeup.setSummary(R.string.wifi_wakeup_summary_scoring_disabled);
- } else if (!wifiScanningEnabled) {
- enableWifiWakeup.setSummary(R.string.wifi_wakeup_summary_scanning_disabled);
- } else {
+ if (wifiScanningEnabled) {
enableWifiWakeup.setSummary(R.string.wifi_wakeup_summary);
- }
- }
-
- class SettingObserver extends ContentObserver {
- private final Uri NETWORK_RECOMMENDATIONS_ENABLED_URI =
- Settings.Global.getUriFor(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED);
-
- private final Preference mPreference;
-
- public SettingObserver(Preference preference) {
- super(new Handler());
- mPreference = preference;
- }
-
- public void register(ContentResolver cr, boolean register) {
- if (register) {
- cr.registerContentObserver(NETWORK_RECOMMENDATIONS_ENABLED_URI, false, this);
- } else {
- cr.unregisterContentObserver(this);
- }
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- super.onChange(selfChange, uri);
- if (NETWORK_RECOMMENDATIONS_ENABLED_URI.equals(uri)) {
- updateState(mPreference);
- }
+ } else {
+ enableWifiWakeup.setSummary(R.string.wifi_wakeup_summary_scanning_disabled);
}
}
}
diff --git a/tests/robotests/res/values-mcc999/config.xml b/tests/robotests/res/values-mcc999/config.xml
index e755f27..137a089 100644
--- a/tests/robotests/res/values-mcc999/config.xml
+++ b/tests/robotests/res/values-mcc999/config.xml
@@ -57,4 +57,7 @@
<bool name="config_show_color_inversion_preference">false</bool>
<bool name="config_show_system_update_settings">false</bool>
<bool name="config_wifi_support_connected_mac_randomization">false</bool>
+ <bool name="config_show_device_model">false</bool>
+ <bool name="config_show_wifi_ip_address">false</bool>
+ <bool name="config_show_wifi_mac_address">false</bool>
</resources>
diff --git a/tests/robotests/src/android/hardware/usb/UsbManagerExtras.java b/tests/robotests/src/android/hardware/usb/UsbManagerExtras.java
new file mode 100644
index 0000000..b9bccd2
--- /dev/null
+++ b/tests/robotests/src/android/hardware/usb/UsbManagerExtras.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2010 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 android.hardware.usb;
+
+import android.annotation.SystemService;
+import android.content.Context;
+import android.hardware.usb.gadget.V1_0.GadgetFunction;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringJoiner;
+
+/**
+ * Definitions that were added to UsbManager in P.
+ *
+ * Copied partially from frameworks/base/core/java/android/hardware/usb/UsbManager to
+ * fix issues with roboelectric during test.
+ */
+@SystemService(Context.USB_SERVICE)
+public class UsbManagerExtras {
+ public static final long NONE = 0;
+ public static final long MTP = GadgetFunction.MTP;
+ public static final long PTP = GadgetFunction.PTP;
+ public static final long RNDIS = GadgetFunction.RNDIS;
+ public static final long MIDI = GadgetFunction.MIDI;
+ public static final long ACCESSORY = GadgetFunction.ACCESSORY;
+ public static final long AUDIO_SOURCE = GadgetFunction.AUDIO_SOURCE;
+ public static final long ADB = GadgetFunction.ADB;
+
+ private static final long SETTABLE_FUNCTIONS = MTP | PTP | RNDIS | MIDI;
+
+ private static final Map<String, Long> STR_MAP = new HashMap<>();
+
+ static {
+ STR_MAP.put(UsbManager.USB_FUNCTION_MTP, MTP);
+ STR_MAP.put(UsbManager.USB_FUNCTION_PTP, PTP);
+ STR_MAP.put(UsbManager.USB_FUNCTION_RNDIS, RNDIS);
+ STR_MAP.put(UsbManager.USB_FUNCTION_MIDI, MIDI);
+ STR_MAP.put(UsbManager.USB_FUNCTION_ACCESSORY, ACCESSORY);
+ STR_MAP.put(UsbManager.USB_FUNCTION_AUDIO_SOURCE, AUDIO_SOURCE);
+ STR_MAP.put(UsbManager.USB_FUNCTION_ADB, ADB);
+ }
+
+ /**
+ * Returns whether the given functions are valid inputs to UsbManager.
+ * Currently the empty functions or any of MTP, PTP, RNDIS, MIDI are accepted.
+ */
+ public static boolean isSettableFunctions(long functions) {
+ return (~SETTABLE_FUNCTIONS & functions) == 0;
+ }
+
+ /**
+ * Returns the string representation of the given functions.
+ */
+ public static String usbFunctionsToString(long functions) {
+ StringJoiner joiner = new StringJoiner(",");
+ if ((functions | MTP) != 0) {
+ joiner.add(UsbManager.USB_FUNCTION_MTP);
+ }
+ if ((functions | PTP) != 0) {
+ joiner.add(UsbManager.USB_FUNCTION_PTP);
+ }
+ if ((functions | RNDIS) != 0) {
+ joiner.add(UsbManager.USB_FUNCTION_RNDIS);
+ }
+ if ((functions | MIDI) != 0) {
+ joiner.add(UsbManager.USB_FUNCTION_MIDI);
+ }
+ if ((functions | ACCESSORY) != 0) {
+ joiner.add(UsbManager.USB_FUNCTION_ACCESSORY);
+ }
+ if ((functions | AUDIO_SOURCE) != 0) {
+ joiner.add(UsbManager.USB_FUNCTION_AUDIO_SOURCE);
+ }
+ if ((functions | ADB) != 0) {
+ joiner.add(UsbManager.USB_FUNCTION_ADB);
+ }
+ return joiner.toString();
+ }
+
+ /**
+ * Parses a string of usb functions and returns a mask of the same functions.
+ */
+ public static long usbFunctionsFromString(String functions) {
+ if (functions == null) {
+ return 0;
+ }
+ long ret = 0;
+ for (String function : functions.split(",")) {
+ if (STR_MAP.containsKey(function)) {
+ ret |= STR_MAP.get(function);
+ }
+ }
+ return ret;
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java b/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java
index 21061c1..1b3e9ca 100644
--- a/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java
@@ -78,4 +78,14 @@
assertResId(SetupWizardUtils.getTheme(intent)).isEqualTo(R.style.GlifV2Theme_Light);
}
+ @Test
+ public void testGetTheme_glifV3Light_shouldReturnThemeResource() {
+ SettingsShadowSystemProperties.set(SetupWizardUtils.SYSTEM_PROP_SETUPWIZARD_THEME,
+ WizardManagerHelper.THEME_GLIF_V3_LIGHT);
+ Intent intent = new Intent();
+
+ assertResId(SetupWizardUtils.getTheme(intent)).isEqualTo(R.style.GlifV3Theme_Light);
+ assertResId(SetupWizardUtils.getTransparentTheme(intent))
+ .isEqualTo(R.style.GlifV3Theme_Light_Transparent);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
index 87b82ad..fabf9ae 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
@@ -19,6 +19,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -191,6 +192,22 @@
}
@Test
+ public void onActivityResult_packageUninstalled_shouldFinishAndRemoveTask() {
+ doReturn(false).when(mFragment).refreshUi();
+
+ mFragment.onActivityResult(mFragment.REQUEST_UNINSTALL, 0, mock(Intent.class));
+
+ verify(mActivity).finishAndRemoveTask();
+ }
+
+ @Test
+ public void getPreferenceControllers_noPackageInfo_shouldReturnNull() {
+ doNothing().when(mFragment).retrieveAppEntry();
+
+ assertThat(mFragment.getPreferenceControllers(mShadowContext)).isNull();
+ }
+
+ @Test
public void getNumberOfUserWithPackageInstalled_twoUsersInstalled_shouldReturnTwo()
throws PackageManager.NameNotFoundException{
final String packageName = "Package1";
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java
index 78be742..b478c4e 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java
@@ -31,6 +31,7 @@
import com.android.settings.TestConfig;
import com.android.settings.bluetooth.ConnectedBluetoothDeviceUpdater;
+import com.android.settings.connecteddevice.usb.ConnectedUsbDeviceUpdater;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.core.lifecycle.Lifecycle;
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedUsbDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdaterTest.java
similarity index 79%
rename from tests/robotests/src/com/android/settings/connecteddevice/ConnectedUsbDeviceUpdaterTest.java
rename to tests/robotests/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdaterTest.java
index 16cd3a7..011d620 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedUsbDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdaterTest.java
@@ -13,18 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License
*/
-package com.android.settings.connecteddevice;
+package com.android.settings.connecteddevice.usb;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.content.Context;
import com.android.settings.R;
import com.android.settings.TestConfig;
-import com.android.settings.deviceinfo.UsbBackend;
+import com.android.settings.connecteddevice.DevicePreferenceCallback;
+import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
@@ -42,6 +44,8 @@
private ConnectedUsbDeviceUpdater mDeviceUpdater;
@Mock
+ private DashboardFragment mFragment;
+ @Mock
private UsbConnectionBroadcastReceiver mUsbReceiver;
@Mock
private DevicePreferenceCallback mDevicePreferenceCallback;
@@ -53,7 +57,8 @@
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
- mDeviceUpdater = new ConnectedUsbDeviceUpdater(mContext, mDevicePreferenceCallback,
+ when(mFragment.getContext()).thenReturn(mContext);
+ mDeviceUpdater = new ConnectedUsbDeviceUpdater(mFragment, mDevicePreferenceCallback,
mUsbBackend);
mDeviceUpdater.mUsbReceiver = mUsbReceiver;
}
@@ -70,18 +75,18 @@
@Test
public void testInitUsbPreference_usbConnected_preferenceAdded() {
- doReturn(true).when(mUsbReceiver).isConnected();
-
mDeviceUpdater.initUsbPreference(mContext);
+ mDeviceUpdater.mUsbConnectionListener.onUsbConnectionChanged(true /* connected */,
+ UsbBackend.MODE_DATA_NONE);
verify(mDevicePreferenceCallback).onDeviceAdded(mDeviceUpdater.mUsbPreference);
}
@Test
public void testInitUsbPreference_usbDisconnected_preferenceRemoved() {
- doReturn(false).when(mUsbReceiver).isConnected();
-
mDeviceUpdater.initUsbPreference(mContext);
+ mDeviceUpdater.mUsbConnectionListener.onUsbConnectionChanged(false /* connected */,
+ UsbBackend.MODE_DATA_NONE);
verify(mDevicePreferenceCallback).onDeviceRemoved(mDeviceUpdater.mUsbPreference);
}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/UsbBackendTest.java b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbBackendTest.java
similarity index 81%
rename from tests/robotests/src/com/android/settings/deviceinfo/UsbBackendTest.java
rename to tests/robotests/src/com/android/settings/connecteddevice/usb/UsbBackendTest.java
index ce384a5..40cfd73 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/UsbBackendTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbBackendTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.deviceinfo;
+package com.android.settings.connecteddevice.usb;
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
import static org.mockito.Matchers.argThat;
@@ -25,7 +25,9 @@
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.usb.UsbManager;
+import android.net.ConnectivityManager;
+import com.android.settings.connecteddevice.usb.UsbBackend;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
@@ -46,6 +48,8 @@
private UsbManager mUsbManager;
@Mock
private UsbBackend.UserRestrictionUtil mUserRestrictionUtil;
+ @Mock
+ private ConnectivityManager mConnectivityManager;
@Before
public void setUp() {
@@ -53,22 +57,13 @@
when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MIDI))
.thenReturn(true);
when((Object)mContext.getSystemService(UsbManager.class)).thenReturn(mUsbManager);
+ when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
+ .thenReturn((Object) mConnectivityManager);
}
@Test
public void constructor_noUsbPort_shouldNotCrash() {
- UsbBackend usbBackend = new UsbBackend(mContext, mUserRestrictionUtil);
+ UsbBackend usbBackend = new UsbBackend(mContext, mUserRestrictionUtil, null);
// Should not crash
}
-
- @Test
- public void getCurrentMode_shouldRegisterReceiverToGetUsbState() {
- UsbBackend usbBackend = new UsbBackend(mContext, mUserRestrictionUtil);
-
- usbBackend.getCurrentMode();
-
- verify(mContext).registerReceiver(eq(null),
- argThat(intentFilter -> intentFilter != null &&
- UsbManager.ACTION_USB_STATE.equals(intentFilter.getAction(0))));
- }
}
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/UsbConnectionBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiverTest.java
similarity index 81%
rename from tests/robotests/src/com/android/settings/connecteddevice/UsbConnectionBroadcastReceiverTest.java
rename to tests/robotests/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiverTest.java
index 06bd5b7..50b47e0 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/UsbConnectionBroadcastReceiverTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiverTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License
*/
-package com.android.settings.connecteddevice;
+package com.android.settings.connecteddevice.usb;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -52,6 +52,8 @@
@Mock
private UsbConnectionBroadcastReceiver.UsbConnectionListener mListener;
+ @Mock
+ private UsbBackend mUsbBackend;
@Before
public void setUp() {
@@ -59,27 +61,42 @@
mShadowApplication = ShadowApplication.getInstance();
mContext = RuntimeEnvironment.application;
- mReceiver = new UsbConnectionBroadcastReceiver(mContext, mListener);
+ mReceiver = new UsbConnectionBroadcastReceiver(mContext, mListener, mUsbBackend);
}
@Test
public void testOnReceive_usbConnected_invokeCallback() {
final Intent intent = new Intent();
+ intent.setAction(UsbManager.ACTION_USB_STATE);
intent.putExtra(UsbManager.USB_CONNECTED, true);
mReceiver.onReceive(mContext, intent);
- verify(mListener).onUsbConnectionChanged(true);
+ verify(mListener).onUsbConnectionChanged(true /* connected */, UsbBackend.MODE_DATA_NONE);
}
@Test
public void testOnReceive_usbDisconnected_invokeCallback() {
final Intent intent = new Intent();
+ intent.setAction(UsbManager.ACTION_USB_STATE);
intent.putExtra(UsbManager.USB_CONNECTED, false);
mReceiver.onReceive(mContext, intent);
- verify(mListener).onUsbConnectionChanged(false);
+ verify(mListener).onUsbConnectionChanged(false /* connected */, UsbBackend.MODE_DATA_NONE);
+ }
+
+ @Test
+ public void testOnReceive_usbConnectedMtpEnabled_invokeCallback() {
+ final Intent intent = new Intent();
+ intent.setAction(UsbManager.ACTION_USB_STATE);
+ intent.putExtra(UsbManager.USB_CONNECTED, true);
+ intent.putExtra(UsbManager.USB_FUNCTION_MTP, true);
+ intent.putExtra(UsbManager.USB_DATA_UNLOCKED, true);
+
+ mReceiver.onReceive(mContext, intent);
+
+ verify(mListener).onUsbConnectionChanged(true /* connected */, UsbBackend.MODE_DATA_MTP);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDetailsHeaderControllerTest.java
new file mode 100644
index 0000000..e1f9078
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDetailsHeaderControllerTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.connecteddevice.usb;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.arch.lifecycle.LifecycleOwner;
+import android.content.Context;
+import android.support.v7.preference.PreferenceManager;
+import android.support.v7.preference.PreferenceScreen;
+import android.support.v14.preference.PreferenceFragment;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.applications.LayoutPreference;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
+import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
+import com.android.settings.widget.EntityHeaderController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
+ shadows = {ShadowEntityHeaderController.class, SettingsShadowResources.class})
+public class UsbDetailsHeaderControllerTest {
+
+ private UsbDetailsHeaderController mDetailsHeaderController;
+ private Context mContext;
+ private Lifecycle mLifecycle;
+ private LifecycleOwner mLifecycleOwner;
+ private LayoutPreference mPreference;
+ private PreferenceManager mPreferenceManager;
+ private PreferenceScreen mScreen;
+
+ @Mock
+ private UsbBackend mUsbBackend;
+ @Mock
+ private PreferenceFragment mFragment;
+ @Mock
+ private Activity mActivity;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private EntityHeaderController mHeaderController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = RuntimeEnvironment.application;
+ mLifecycleOwner = () -> mLifecycle;
+ mLifecycle = new Lifecycle(mLifecycleOwner);
+ mPreferenceManager = new PreferenceManager(mContext);
+ mScreen = mPreferenceManager.createPreferenceScreen(mContext);
+
+ when(mFragment.getActivity()).thenReturn(mActivity);
+ when(mActivity.getApplicationContext()).thenReturn(mContext);
+ when(mFragment.getContext()).thenReturn(mContext);
+ when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
+ when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
+
+ ShadowEntityHeaderController.setUseMock(mHeaderController);
+ mDetailsHeaderController = new UsbDetailsHeaderController(mContext, mFragment, mUsbBackend);
+ mPreference = new LayoutPreference(mContext, R.layout.settings_entity_header);
+ mPreference.setKey(mDetailsHeaderController.getPreferenceKey());
+ mScreen.addPreference(mPreference);
+ }
+
+ @After
+ public void tearDown() {
+ ShadowEntityHeaderController.reset();
+ }
+
+ @Test
+ public void displayRefresh_charging_shouldSetHeader() {
+ mDetailsHeaderController.displayPreference(mScreen);
+ mDetailsHeaderController.refresh(UsbBackend.MODE_DATA_NONE);
+ verify(mHeaderController).setLabel(mContext.getString(R.string.usb_pref));
+ verify(mHeaderController).setIcon(mContext.getDrawable(R.drawable.ic_usb));
+ verify(mHeaderController).setSummary(
+ mContext.getString(R.string.usb_summary_charging_only));
+ verify(mHeaderController).done(mActivity, true);
+ }
+
+ @Test
+ public void displayRefresh_mtp_shouldSetHeader() {
+ mDetailsHeaderController.displayPreference(mScreen);
+ mDetailsHeaderController.refresh(UsbBackend.MODE_DATA_MTP);
+ verify(mHeaderController).setLabel(mContext.getString(R.string.usb_pref));
+ verify(mHeaderController).setIcon(mContext.getDrawable(R.drawable.ic_usb));
+ verify(mHeaderController).setSummary(
+ mContext.getString(R.string.usb_summary_file_transfers));
+ verify(mHeaderController).done(mActivity, true);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDetailsProfilesControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDetailsProfilesControllerTest.java
new file mode 100644
index 0000000..557d836
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDetailsProfilesControllerTest.java
@@ -0,0 +1,238 @@
+/*
+ * 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.connecteddevice.usb;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.content.Context;
+import android.hardware.usb.UsbManager;
+import android.support.v7.preference.PreferenceCategory;
+import android.support.v7.preference.PreferenceManager;
+import android.support.v7.preference.PreferenceScreen;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v14.preference.SwitchPreference;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import com.google.android.collect.Lists;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class UsbDetailsProfilesControllerTest {
+
+ private UsbDetailsProfilesController mDetailsProfilesController;
+ private Context mContext;
+ private Lifecycle mLifecycle;
+ private PreferenceCategory mPreference;
+ private PreferenceManager mPreferenceManager;
+ private PreferenceScreen mScreen;
+ private List<String> mOptions;
+
+ @Mock
+ private UsbBackend mUsbBackend;
+ @Mock
+ private PreferenceFragment mFragment;
+ @Mock
+ private Activity mActivity;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = RuntimeEnvironment.application;
+ mLifecycle = new Lifecycle(() -> mLifecycle);
+ mPreferenceManager = new PreferenceManager(mContext);
+ mScreen = mPreferenceManager.createPreferenceScreen(mContext);
+
+ when(mFragment.getActivity()).thenReturn(mActivity);
+ when(mActivity.getApplicationContext()).thenReturn(mContext);
+ when(mFragment.getContext()).thenReturn(mContext);
+ when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
+ when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
+
+ mOptions = Lists.newArrayList(UsbManager.USB_FUNCTION_MTP, UsbManager.USB_FUNCTION_PTP,
+ UsbManager.USB_FUNCTION_MIDI, UsbDetailsProfilesController.KEY_POWER);
+ mDetailsProfilesController = new UsbDetailsProfilesController(mContext, mFragment,
+ mUsbBackend, mOptions, "usb_options");
+ mPreference = new PreferenceCategory(mContext);
+ mPreference.setKey(mDetailsProfilesController.getPreferenceKey());
+ mScreen.addPreference(mPreference);
+ }
+
+ @Test
+ public void testDisplayRefresh_allAllowed_shouldCreateSwitches() {
+ when(mUsbBackend.isModeSupported(anyInt())).thenReturn(true);
+ when(mUsbBackend.isModeDisallowed(anyInt())).thenReturn(false);
+ when(mUsbBackend.isModeDisallowedBySystem(anyInt())).thenReturn(false);
+
+ mDetailsProfilesController.displayPreference(mScreen);
+ mDetailsProfilesController.refresh(UsbBackend.MODE_DATA_NONE);
+ List<SwitchPreference> switches = getProfileSwitches();
+
+ for (int i = 0; i < switches.size(); i++) {
+ assertThat(switches.get(i).getKey().equals(mOptions.get(i)));
+ }
+ }
+
+ @Test
+ public void testDisplayRefresh_onlyMidiAllowed_shouldCreateOnlyMidiSwitch() {
+ when(mUsbBackend.isModeSupported(anyInt())).thenReturn(true);
+ when(mUsbBackend.isModeDisallowed(anyInt())).thenReturn(false);
+ when(mUsbBackend.isModeDisallowedBySystem(UsbBackend.MODE_DATA_MIDI)).thenReturn(false);
+ when(mUsbBackend.isModeDisallowedBySystem(UsbBackend.MODE_DATA_MTP)).thenReturn(true);
+ when(mUsbBackend.isModeDisallowedBySystem(UsbBackend.MODE_DATA_PTP)).thenReturn(true);
+ when(mUsbBackend.isModeDisallowedBySystem(UsbBackend.MODE_POWER_SOURCE)).thenReturn(true);
+
+ mDetailsProfilesController.displayPreference(mScreen);
+ mDetailsProfilesController.refresh(UsbBackend.MODE_DATA_NONE);
+ List<SwitchPreference> switches = getProfileSwitches();
+ assertThat(switches.size()).isEqualTo(1);
+ assertThat(switches.get(0).getKey()).isEqualTo(UsbManager.USB_FUNCTION_MIDI);
+ }
+
+ @Test
+ public void testDisplayRefresh_mtpEnabled_shouldCheckSwitches() {
+ when(mUsbBackend.isModeSupported(anyInt())).thenReturn(true);
+ when(mUsbBackend.isModeDisallowed(anyInt())).thenReturn(false);
+ when(mUsbBackend.isModeDisallowedBySystem(anyInt())).thenReturn(false);
+
+ mDetailsProfilesController.displayPreference(mScreen);
+ mDetailsProfilesController.refresh(UsbBackend.MODE_DATA_MTP);
+ List<SwitchPreference> switches = getProfileSwitches();
+
+ assertThat(switches.get(0).getKey().equals(UsbManager.USB_FUNCTION_MTP));
+ assertThat(switches.get(0).isChecked());
+ }
+
+ @Test
+ public void testDisplayRefresh_mtpSupplyPowerEnabled_shouldCheckSwitches() {
+ when(mUsbBackend.isModeSupported(anyInt())).thenReturn(true);
+ when(mUsbBackend.isModeDisallowed(anyInt())).thenReturn(false);
+ when(mUsbBackend.isModeDisallowedBySystem(anyInt())).thenReturn(false);
+
+ mDetailsProfilesController.displayPreference(mScreen);
+ mDetailsProfilesController.refresh(UsbBackend.MODE_DATA_MTP | UsbBackend.MODE_POWER_SOURCE);
+ List<SwitchPreference> switches = getProfileSwitches();
+
+ assertThat(switches.get(0).getKey()).isEqualTo(UsbManager.USB_FUNCTION_MTP);
+ assertThat(switches.get(0).isChecked());
+ assertThat(switches.get(3).getKey()).isEqualTo(UsbDetailsProfilesController.KEY_POWER);
+ assertThat(switches.get(3).isChecked());
+ }
+
+ @Test
+ public void testOnClickMtp_noneEnabled_shouldEnableMtp() {
+ when(mUsbBackend.isModeSupported(anyInt())).thenReturn(true);
+ when(mUsbBackend.isModeDisallowed(anyInt())).thenReturn(false);
+ when(mUsbBackend.isModeDisallowedBySystem(anyInt())).thenReturn(false);
+
+ mDetailsProfilesController.displayPreference(mScreen);
+ mDetailsProfilesController.refresh(UsbBackend.MODE_DATA_NONE);
+ List<SwitchPreference> switches = getProfileSwitches();
+ switches.get(0).performClick();
+
+ assertThat(switches.get(0).getKey()).isEqualTo(UsbManager.USB_FUNCTION_MTP);
+ verify(mUsbBackend).setMode(UsbBackend.MODE_DATA_MTP);
+ assertThat(switches.get(0).isChecked());
+ }
+
+ @Test
+ public void testOnClickMtp_supplyingPowerEnabled_shouldEnableBoth() {
+ when(mUsbBackend.isModeSupported(anyInt())).thenReturn(true);
+ when(mUsbBackend.isModeDisallowed(anyInt())).thenReturn(false);
+ when(mUsbBackend.isModeDisallowedBySystem(anyInt())).thenReturn(false);
+
+ mDetailsProfilesController.displayPreference(mScreen);
+ mDetailsProfilesController.refresh(UsbBackend.MODE_POWER_SOURCE);
+ when(mUsbBackend.getCurrentMode()).thenReturn(UsbBackend.MODE_POWER_SOURCE);
+ List<SwitchPreference> switches = getProfileSwitches();
+ switches.get(0).performClick();
+
+ assertThat(switches.get(0).getKey()).isEqualTo(UsbManager.USB_FUNCTION_MTP);
+ verify(mUsbBackend).setMode(UsbBackend.MODE_DATA_MTP | UsbBackend.MODE_POWER_SOURCE);
+ assertThat(switches.get(0).isChecked());
+ assertThat(switches.get(3).getKey()).isEqualTo(UsbDetailsProfilesController.KEY_POWER);
+ assertThat(switches.get(3).isChecked());
+ }
+
+ @Test
+ public void testOnClickMtp_ptpEnabled_shouldEnableMtpOnly() {
+ when(mUsbBackend.isModeSupported(anyInt())).thenReturn(true);
+ when(mUsbBackend.isModeDisallowed(anyInt())).thenReturn(false);
+ when(mUsbBackend.isModeDisallowedBySystem(anyInt())).thenReturn(false);
+
+ mDetailsProfilesController.displayPreference(mScreen);
+ mDetailsProfilesController.refresh(UsbBackend.MODE_DATA_PTP);
+ when(mUsbBackend.getCurrentMode()).thenReturn(UsbBackend.MODE_DATA_PTP);
+ List<SwitchPreference> switches = getProfileSwitches();
+ switches.get(0).performClick();
+
+ assertThat(switches.get(0).getKey()).isEqualTo(UsbManager.USB_FUNCTION_MTP);
+ verify(mUsbBackend).setMode(UsbBackend.MODE_DATA_MTP);
+ assertThat(switches.get(0).isChecked());
+ assertThat(switches.get(1).getKey()).isEqualTo(UsbManager.USB_FUNCTION_PTP);
+ assertThat(!switches.get(1).isChecked());
+ }
+
+ @Test
+ public void testOnClickMtp_mtpEnabled_shouldDisableMtp() {
+ when(mUsbBackend.isModeSupported(anyInt())).thenReturn(true);
+ when(mUsbBackend.isModeDisallowed(anyInt())).thenReturn(false);
+ when(mUsbBackend.isModeDisallowedBySystem(anyInt())).thenReturn(false);
+
+ mDetailsProfilesController.displayPreference(mScreen);
+ mDetailsProfilesController.refresh(UsbBackend.MODE_DATA_MTP);
+ when(mUsbBackend.getCurrentMode()).thenReturn(UsbBackend.MODE_DATA_MTP);
+ List<SwitchPreference> switches = getProfileSwitches();
+ switches.get(0).performClick();
+
+ assertThat(switches.get(0).getKey()).isEqualTo(UsbManager.USB_FUNCTION_MTP);
+ verify(mUsbBackend).setMode(UsbBackend.MODE_DATA_NONE);
+ assertThat(!switches.get(0).isChecked());
+ }
+
+ private List<SwitchPreference> getProfileSwitches() {
+ ArrayList<SwitchPreference> result = new ArrayList<>();
+ for (int i = 0; i < mPreference.getPreferenceCount(); i++) {
+ result.add((SwitchPreference) mPreference.getPreference(i));
+ }
+ return result;
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/UsbModeChooserActivityTest.java b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbModeChooserActivityTest.java
similarity index 96%
rename from tests/robotests/src/com/android/settings/deviceinfo/UsbModeChooserActivityTest.java
rename to tests/robotests/src/com/android/settings/connecteddevice/usb/UsbModeChooserActivityTest.java
index 1817bfb..c02212b 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/UsbModeChooserActivityTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbModeChooserActivityTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.settings.deviceinfo;
+package com.android.settings.connecteddevice.usb;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.anyInt;
@@ -22,6 +22,7 @@
import android.widget.TextView;
import com.android.settings.R;
+import com.android.settings.connecteddevice.usb.UsbModeChooserActivity;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/UsbModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbModePreferenceControllerTest.java
similarity index 67%
rename from tests/robotests/src/com/android/settings/connecteddevice/UsbModePreferenceControllerTest.java
rename to tests/robotests/src/com/android/settings/connecteddevice/usb/UsbModePreferenceControllerTest.java
index 7edde6e..d15a57f 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/UsbModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbModePreferenceControllerTest.java
@@ -1,16 +1,12 @@
-package com.android.settings.connecteddevice;
+package com.android.settings.connecteddevice.usb;
import android.content.Context;
-import android.content.Intent;
-import android.hardware.usb.UsbManager;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
-import com.android.settings.deviceinfo.UsbBackend;
-import com.android.settings.deviceinfo.UsbModeChooserActivity;
import org.junit.Before;
import org.junit.Test;
@@ -24,6 +20,7 @@
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -33,6 +30,8 @@
private UsbBackend mUsbBackend;
@Mock(answer = RETURNS_DEEP_STUBS)
private PreferenceScreen mScreen;
+ @Mock
+ private UsbConnectionBroadcastReceiver mUsbConnectionBroadcastReceiver;
private Context mContext;
private UsbModePreferenceController mController;
@@ -42,61 +41,67 @@
MockitoAnnotations.initMocks(this);
mContext = ShadowApplication.getInstance().getApplicationContext();
mController = new UsbModePreferenceController(mContext, mUsbBackend);
+ mController.mUsbReceiver = mUsbConnectionBroadcastReceiver;
}
@Test
public void testGetSummary_chargeDevice() {
- assertThat(mController.getSummary(UsbModeChooserActivity.DEFAULT_MODES[0]))
+ assertThat(mController.getSummary(0))
.isEqualTo(R.string.usb_summary_charging_only);
}
@Test
public void testGetSummary_supplyPower() {
- assertThat(mController.getSummary(UsbModeChooserActivity.DEFAULT_MODES[1]))
+ assertThat(mController.getSummary(UsbBackend.MODE_POWER_SOURCE))
.isEqualTo(R.string.usb_summary_power_only);
}
@Test
public void testGetSummary_TransferFiles() {
- assertThat(mController.getSummary(UsbModeChooserActivity.DEFAULT_MODES[2]))
+ assertThat(mController.getSummary(UsbBackend.MODE_DATA_MTP))
.isEqualTo(R.string.usb_summary_file_transfers);
}
@Test
public void testGetSummary_TransferPhoto() {
- assertThat(mController.getSummary(UsbModeChooserActivity.DEFAULT_MODES[3]))
+ assertThat(mController.getSummary(UsbBackend.MODE_DATA_PTP))
.isEqualTo(R.string.usb_summary_photo_transfers);
}
@Test
public void testGetSummary_MIDI() {
- assertThat(mController.getSummary(UsbModeChooserActivity.DEFAULT_MODES[4]))
+ assertThat(mController.getSummary(UsbBackend.MODE_DATA_MIDI))
.isEqualTo(R.string.usb_summary_MIDI);
}
@Test
+ public void testGetSummary_Tethering() {
+ assertThat(mController.getSummary(UsbBackend.MODE_DATA_TETHER))
+ .isEqualTo(R.string.usb_summary_tether);
+ }
+
+ @Test
public void testPreferenceSummary_usbDisconnected() {
final Preference preference = new Preference(mContext);
preference.setKey("usb_mode");
preference.setEnabled(true);
+ when(mUsbBackend.getCurrentMode()).thenReturn(UsbBackend.MODE_POWER_SINK);
+ when(mUsbConnectionBroadcastReceiver.isConnected()).thenReturn(false);
mController.updateState(preference);
+
+ assertThat(preference.getKey()).isEqualTo("usb_mode");
assertThat(preference.getSummary()).isEqualTo(
mContext.getString(R.string.disconnected));
}
@Test
- public void testUsbBoradcastReceiver_usbConnected_shouldUpdateSummary() {
+ public void testUsbBroadcastReceiver_usbConnected_shouldUpdateSummary() {
final Preference preference = new Preference(mContext);
preference.setKey("usb_mode");
preference.setEnabled(true);
- when(mUsbBackend.getCurrentMode()).thenReturn(UsbModeChooserActivity.DEFAULT_MODES[0]);
- when(mScreen.findPreference("usb_mode")).thenReturn(preference);
-
- mController.displayPreference(mScreen);
- mController.onResume();
- final Intent intent = new Intent(UsbManager.ACTION_USB_STATE);
- intent.putExtra(UsbManager.USB_CONNECTED, true);
- mContext.sendStickyBroadcast(intent);
+ when(mUsbBackend.getCurrentMode()).thenReturn(UsbBackend.MODE_POWER_SINK);
+ when(mUsbConnectionBroadcastReceiver.isConnected()).thenReturn(true);
+ mController.updateState(preference);
assertThat(preference.getSummary()).isEqualTo(
mContext.getString(R.string.usb_summary_charging_only));
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java
index ebf3dc7..825aee9 100644
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java
@@ -215,11 +215,9 @@
}
@Test
- public void onBindViewHolder_differentPackage_shouldNotTintIcon()
- throws PendingIntent.CanceledException {
+ public void onBindViewHolder_iconNotTintable_shouldNotTintIcon()
+ throws PendingIntent.CanceledException {
final Icon icon = mock(Icon.class);
- when(icon.getResPackage()).thenReturn("pkg1");
- when(mActivity.getPackageName()).thenReturn("pkg2");
final Suggestion suggestion = new Suggestion.Builder("pkg1")
.setPendingIntent(mock(PendingIntent.class))
.setIcon(icon)
@@ -243,15 +241,14 @@
}
@Test
- public void onBindViewHolder_samePackage_shouldTintIcon()
- throws PendingIntent.CanceledException {
+ public void onBindViewHolder_iconTintable_shouldTintIcon()
+ throws PendingIntent.CanceledException {
final Icon icon = mock(Icon.class);
- final String packageName = "pkg1";
- when(icon.getResPackage()).thenReturn(packageName);
- when(mActivity.getPackageName()).thenReturn(packageName);
- final Suggestion suggestion = new Suggestion.Builder(packageName)
+ final int FLAG_ICON_TINTABLE = 1 << 1;
+ final Suggestion suggestion = new Suggestion.Builder("pkg1")
.setPendingIntent(mock(PendingIntent.class))
.setIcon(icon)
+ .setFlags(FLAG_ICON_TINTABLE)
.build();
final List<Suggestion> suggestions = new ArrayList<>();
suggestions.add(suggestion);
diff --git a/tests/robotests/src/com/android/settings/development/SelectUsbConfigPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/SelectUsbConfigPreferenceControllerTest.java
index 8719bb4..67a6d6b 100644
--- a/tests/robotests/src/com/android/settings/development/SelectUsbConfigPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/SelectUsbConfigPreferenceControllerTest.java
@@ -25,6 +25,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
@@ -37,11 +38,13 @@
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.usb.UsbManager;
+import android.hardware.usb.UsbManagerExtras;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.TestConfig;
+import com.android.settings.connecteddevice.usb.UsbBackend;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -69,6 +72,8 @@
private UsbManager mUsbManager;
@Mock
private PackageManager mPackageManager;
+ @Mock
+ private UsbBackend.UsbManagerPassThrough mUsbManagerPassThrough;
private Context mContext;
private LifecycleOwner mLifecycleOwner;
@@ -101,6 +106,13 @@
mController = spy(new SelectUsbConfigPreferenceController(mContext, mLifecycle));
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
mController.displayPreference(mScreen);
+ mController.mUsbManagerPassThrough = mUsbManagerPassThrough;
+
+ when(mUsbManagerPassThrough.usbFunctionsFromString("mtp")).thenReturn(UsbManagerExtras.MTP);
+ when(mUsbManagerPassThrough.usbFunctionsFromString("rndis"))
+ .thenReturn(UsbManagerExtras.RNDIS);
+ when(mUsbManagerPassThrough.usbFunctionsFromString("none"))
+ .thenReturn(UsbManagerExtras.NONE);
}
@@ -111,11 +123,13 @@
@Test
public void onPreferenceChange_setCharging_shouldEnableCharging() {
- when(mUsbManager.isFunctionEnabled(mValues[0])).thenReturn(true);
- doNothing().when(mController).setCurrentFunction(anyString(), anyBoolean());
+ when(mUsbManagerPassThrough.getCurrentFunctions()).thenReturn(
+ UsbManagerExtras.usbFunctionsFromString(mValues[0]));
+ doNothing().when(mController).setCurrentFunctions(anyLong());
mController.onPreferenceChange(mPreference, mValues[0]);
- verify(mController).setCurrentFunction(mValues[0], false /* usb data unlock */);
+ verify(mController).setCurrentFunctions(
+ UsbManagerExtras.usbFunctionsFromString(mValues[0]));
}
@Test
@@ -144,28 +158,32 @@
@Test
public void onPreferenceChange_setMtp_shouldEnableMtp() {
- when(mUsbManager.isFunctionEnabled(mValues[1])).thenReturn(true);
- doNothing().when(mController).setCurrentFunction(anyString(), anyBoolean());
+ when(mUsbManagerPassThrough.getCurrentFunctions())
+ .thenReturn(UsbManagerExtras.usbFunctionsFromString(mValues[1]));
+ doNothing().when(mController).setCurrentFunctions(anyLong());
mController.onPreferenceChange(mPreference, mValues[1]);
- verify(mController).setCurrentFunction(mValues[1], true /* usb data unlock */);
+ verify(mController).setCurrentFunctions(
+ UsbManagerExtras.usbFunctionsFromString(mValues[1]));
}
@Test
public void onPreferenceChange_monkeyUser_shouldReturnFalse() {
- when(mUsbManager.isFunctionEnabled(mValues[1])).thenReturn(true);
+ when(mUsbManagerPassThrough.getCurrentFunctions())
+ .thenReturn(UsbManagerExtras.usbFunctionsFromString(mValues[1]));
ShadowUtils.setIsUserAMonkey(true);
- doNothing().when(mController).setCurrentFunction(anyString(), anyBoolean());
+ doNothing().when(mController).setCurrentFunctions(anyLong());
final boolean isHandled = mController.onPreferenceChange(mPreference, mValues[1]);
assertThat(isHandled).isFalse();
- verify(mController, never()).setCurrentFunction(any(), anyBoolean());
+ verify(mController, never()).setCurrentFunctions(anyLong());
}
@Test
public void updateState_chargingEnabled_shouldSetPreferenceToCharging() {
- when(mUsbManager.isFunctionEnabled(mValues[0])).thenReturn(true);
+ when(mUsbManagerPassThrough.getCurrentFunctions())
+ .thenReturn(UsbManagerExtras.usbFunctionsFromString(mValues[0]));
mController.updateState(mPreference);
@@ -175,7 +193,8 @@
@Test
public void updateState_RndisEnabled_shouldEnableRndis() {
- when(mUsbManager.isFunctionEnabled(mValues[3])).thenReturn(true);
+ when(mUsbManagerPassThrough.getCurrentFunctions())
+ .thenReturn(UsbManagerExtras.usbFunctionsFromString(mValues[3]));
mController.updateState(mPreference);
@@ -185,6 +204,7 @@
@Test
public void updateState_noValueSet_shouldEnableChargingAsDefault() {
+ when(mUsbManagerPassThrough.getCurrentFunctions()).thenReturn(UsbManagerExtras.NONE);
mController.updateState(mPreference);
verify(mPreference).setValue(mValues[0]);
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/DeviceModelPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/DeviceModelPreferenceControllerTest.java
index 6a5c7fa..47bcf1c 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/DeviceModelPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/DeviceModelPreferenceControllerTest.java
@@ -69,11 +69,17 @@
}
@Test
- public void isAlwaysAvailable() {
+ public void isAvailable_returnTrueIfVisible() {
assertThat(mController.isAvailable()).isTrue();
}
@Test
+ @Config(qualifiers = "mcc999")
+ public void isAvailable_returnFalseIfNotVisible() {
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
public void displayPref_shouldSetSummary() {
mController.displayPreference(mPreferenceScreen);
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java
index f30425b..0b83359 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java
@@ -16,6 +16,9 @@
package com.android.settings.deviceinfo;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
@@ -74,6 +77,20 @@
}
@Test
+ public void isAvailable_shouldBeTrueIfCallCapable() {
+ when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
+
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void isAvailable_shouldBeFalseIfNotCallCapable() {
+ when(mTelephonyManager.isVoiceCapable()).thenReturn(false);
+
+ assertFalse(mController.isAvailable());
+ }
+
+ @Test
public void displayPreference_multiSim_shouldAddSecondPreference() {
when(mTelephonyManager.getPhoneCount()).thenReturn(2);
diff --git a/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java b/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java
index 1bae729..ca42b3a 100644
--- a/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java
+++ b/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java
@@ -252,7 +252,7 @@
enforcingUsers.add(new UserManager.EnforcingUser(userId,
UserManager.RESTRICTION_SOURCE_PROFILE_OWNER));
when(mUserManager.getUserRestrictionSources(
- UserManager.DISALLOW_CONFIG_LOCATION_MODE, UserHandle.of(userId)))
+ UserManager.DISALLOW_CONFIG_LOCATION, UserHandle.of(userId)))
.thenReturn(enforcingUsers);
assertThat(mEnabler.getShareLocationEnforcedAdmin(userId) != null).isTrue();
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowConnectivityManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowConnectivityManager.java
index 742fbf8..fc19b44 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowConnectivityManager.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowConnectivityManager.java
@@ -26,6 +26,7 @@
public class ShadowConnectivityManager extends org.robolectric.shadows.ShadowConnectivityManager {
private final SparseBooleanArray mSupportedNetworkTypes = new SparseBooleanArray();
+ private boolean mTetheringSupported = false;
public void setNetworkSupported(int networkType, boolean supported) {
mSupportedNetworkTypes.put(networkType, supported);
@@ -35,4 +36,13 @@
public boolean isNetworkSupported(int networkType) {
return mSupportedNetworkTypes.get(networkType);
}
+
+ public void setTetheringSupported(boolean supported) {
+ mTetheringSupported = supported;
+ }
+
+ @Implementation
+ public boolean isTetheringSupported() {
+ return mTetheringSupported;
+ }
}
diff --git a/tests/robotests/src/com/android/settings/users/UserCapabilitiesTest.java b/tests/robotests/src/com/android/settings/users/UserCapabilitiesTest.java
new file mode 100644
index 0000000..4228ca0
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/users/UserCapabilitiesTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.users;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.UserManager;
+
+import com.android.settings.TestConfig;
+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.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class UserCapabilitiesTest {
+
+ @Mock
+ private Context mContext;
+ @Mock
+ private UserManager mUserManager;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ }
+
+ @Test
+ public void disallowUserSwitchWhenRestrictionIsSet() {
+ when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(true);
+
+ UserCapabilities userCapabilities = UserCapabilities.create(mContext);
+ userCapabilities.updateAddUserCapabilities(mContext);
+
+ assertThat(userCapabilities.mDisallowSwitchUser).isTrue();
+ }
+
+ @Test
+ public void allowUserSwitchWhenRestrictionIsNotSet() {
+ when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(false);
+
+ UserCapabilities userCapabilities = UserCapabilities.create(mContext);
+ userCapabilities.updateAddUserCapabilities(mContext);
+
+ assertThat(userCapabilities.mDisallowSwitchUser).isFalse();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java b/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java
new file mode 100644
index 0000000..e2fb6c1
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.widget;
+
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.graphics.drawable.ColorDrawable;
+import android.support.v7.preference.PreferenceCategory;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+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;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class HighlightablePreferenceGroupAdapterTest {
+
+ private static final String TEST_KEY = "key";
+
+ @Mock
+ private View mRoot;
+ @Mock
+ private PreferenceCategory mPreferenceCatetory;
+ private Context mContext;
+ private HighlightablePreferenceGroupAdapter mAdapter;
+ private PreferenceViewHolder mViewHolder;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ when(mPreferenceCatetory.getContext()).thenReturn(mContext);
+ mAdapter = new HighlightablePreferenceGroupAdapter(mPreferenceCatetory, TEST_KEY,
+ false /* highlighted*/);
+ mViewHolder = PreferenceViewHolder.createInstanceForTests(
+ View.inflate(mContext, R.layout.app_preference_item, null));
+ }
+
+ @Test
+ public void requestHighlight_hasKey_notHighlightedBefore_shouldRequest() {
+ mAdapter.requestHighlight(mRoot, mock(RecyclerView.class));
+
+ verify(mRoot).postDelayed(any(),
+ eq(HighlightablePreferenceGroupAdapter.DELAY_HIGHLIGHT_DURATION_MILLIS));
+ }
+
+ @Test
+ public void requestHighlight_noKey_highlightedBefore_noRecyclerView_shouldNotRequest() {
+ ReflectionHelpers.setField(mAdapter, "mHighlightKey", null);
+ ReflectionHelpers.setField(mAdapter, "mHighlightRequested", false);
+ mAdapter.requestHighlight(mRoot, mock(RecyclerView.class));
+
+ ReflectionHelpers.setField(mAdapter, "mHighlightKey", TEST_KEY);
+ ReflectionHelpers.setField(mAdapter, "mHighlightRequested", true);
+ mAdapter.requestHighlight(mRoot, mock(RecyclerView.class));
+
+ ReflectionHelpers.setField(mAdapter, "mHighlightKey", TEST_KEY);
+ ReflectionHelpers.setField(mAdapter, "mHighlightRequested", false);
+ mAdapter.requestHighlight(mRoot, null /* recyclerView */);
+
+ verifyZeroInteractions(mRoot);
+ }
+
+ @Test
+ public void updateBackground_notHighlightedRow_shouldNotSetHighlightedTag() {
+ ReflectionHelpers.setField(mAdapter, "mHighlightPosition", 10);
+
+ mAdapter.updateBackground(mViewHolder, 0);
+
+ assertThat(mViewHolder.itemView.getTag(R.id.preference_highlighted)).isNull();
+ }
+
+ @Test
+ public void updateBackground_highlight_shouldChangeBackgroundAndSetHighlightedTag() {
+ ReflectionHelpers.setField(mAdapter, "mHighlightPosition", 10);
+
+ mAdapter.updateBackground(mViewHolder, 10);
+ assertThat(mViewHolder.itemView.getBackground()).isInstanceOf(ColorDrawable.class);
+ assertThat(mViewHolder.itemView.getTag(R.id.preference_highlighted)).isEqualTo(true);
+ }
+
+ @Test
+ public void updateBackground_reuseHightlightedRowForNormalRow_shouldResetBackgroundAndTag() {
+ ReflectionHelpers.setField(mAdapter, "mHighlightPosition", 10);
+ mViewHolder.itemView.setTag(R.id.preference_highlighted, true);
+
+ mAdapter.updateBackground(mViewHolder, 0);
+
+ assertThat(mViewHolder.itemView.getBackground()).isNotInstanceOf(ColorDrawable.class);
+ assertThat(mViewHolder.itemView.getTag(R.id.preference_highlighted)).isEqualTo(false);
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java
index 29df539..28ab166 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java
@@ -16,9 +16,7 @@
package com.android.settings.wifi;
-import static android.provider.Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED;
import static android.provider.Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE;
-import static android.provider.Settings.Global.WIFI_WAKEUP_AVAILABLE;
import static android.provider.Settings.Global.WIFI_WAKEUP_ENABLED;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
@@ -33,7 +31,6 @@
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.testutils.shadow.SettingsShadowResources;
-import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.After;
import org.junit.Before;
@@ -59,12 +56,8 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
- mController = new WifiWakeupPreferenceController(
- mContext, mock(Lifecycle.class));
+ mController = new WifiWakeupPreferenceController(mContext);
Settings.System.putInt(mContext.getContentResolver(), WIFI_SCAN_ALWAYS_AVAILABLE, 1);
- Settings.System.putInt(mContext.getContentResolver(), NETWORK_RECOMMENDATIONS_ENABLED, 1);
- SettingsShadowResources.overrideResource(
- com.android.internal.R.integer.config_wifi_wakeup_available, 0);
}
@After
@@ -73,18 +66,6 @@
}
@Test
- public void testIsAvailable_returnsFalseWhenSettingIsNotAvailable() {
- Settings.System.putInt(mContext.getContentResolver(), WIFI_WAKEUP_AVAILABLE, 0);
- assertThat(mController.isAvailable()).isFalse();
- }
-
- @Test
- public void testIsAvailable_returnsTrueWhenSettingIsAvailable() {
- Settings.System.putInt(mContext.getContentResolver(), WIFI_WAKEUP_AVAILABLE, 1);
- assertThat(mController.isAvailable()).isTrue();
- }
-
- @Test
public void handlePreferenceTreeClick_nonMatchingKey_shouldDoNothing() {
final SwitchPreference pref = new SwitchPreference(mContext);
@@ -146,17 +127,4 @@
verify(preference).setEnabled(false);
verify(preference).setSummary(R.string.wifi_wakeup_summary_scanning_disabled);
}
-
- @Test
- public void updateState_preferenceSetUncheckedAndSetDisabledWhenScoringDisabled() {
- final SwitchPreference preference = mock(SwitchPreference.class);
- Settings.System.putInt(mContext.getContentResolver(), WIFI_WAKEUP_ENABLED, 1);
- Settings.System.putInt(mContext.getContentResolver(), NETWORK_RECOMMENDATIONS_ENABLED, 0);
-
- mController.updateState(preference);
-
- verify(preference).setChecked(true);
- verify(preference).setEnabled(false);
- verify(preference).setSummary(R.string.wifi_wakeup_summary_scoring_disabled);
- }
}
diff --git a/tests/unit/src/com/android/settings/SettingsPreferenceFragmentTest.java b/tests/unit/src/com/android/settings/SettingsPreferenceFragmentTest.java
deleted file mode 100644
index 0e12e79..0000000
--- a/tests/unit/src/com/android/settings/SettingsPreferenceFragmentTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package com.android.settings;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceGroupAdapter;
-
-import com.android.settings.accessibility.AccessibilitySettings;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class SettingsPreferenceFragmentTest {
-
- private Instrumentation mInstrumentation;
- private Context mTargetContext;
-
- @Before
- public void setUp() throws Exception {
- mInstrumentation = InstrumentationRegistry.getInstrumentation();
- mTargetContext = mInstrumentation.getTargetContext();
- }
-
- @Test
- public void testHighlightCaptions() throws InterruptedException {
- final String prefKey = "captioning_preference_screen";
- Bundle args = new Bundle();
- args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, prefKey);
-
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setClass(mTargetContext, SubSettings.class);
- intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT,
- "com.android.settings.accessibility.AccessibilitySettings");
- intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
-
- SettingsActivity activity = (SettingsActivity) mInstrumentation.startActivitySync(intent);
- AccessibilitySettings fragment = (AccessibilitySettings)
- activity.getFragmentManager().getFragments().get(0);
-
- // Allow time for highlight from post-delay.
- Thread.sleep(SettingsPreferenceFragment.DELAY_HIGHLIGHT_DURATION_MILLIS);
- if (!fragment.mPreferenceHighlighted) {
- Thread.sleep(SettingsPreferenceFragment.DELAY_HIGHLIGHT_DURATION_MILLIS);
- }
-
- int prefPosition = -1;
- PreferenceGroupAdapter adapter = (PreferenceGroupAdapter)
- fragment.getListView().getAdapter();
- for (int n = 0, count = adapter.getItemCount(); n < count; n++) {
- final Preference preference = adapter.getItem(n);
- final String preferenceKey = preference.getKey();
- if (preferenceKey.equals(prefKey)) {
- prefPosition = n;
- break;
- }
- }
-
- assertThat(fragment.mAdapter.initialHighlightedPosition).isEqualTo(prefPosition);
- }
-}