Merge "Revert "call getName() from CachedBluetoothDevice, not CachedBluetoothDeviceManager""
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0c1ce65..71840b1 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -124,7 +124,7 @@
android:value="true" />
</activity>
- <activity android:name=".SettingsHomepageActivity"
+ <activity android:name=".homepage.SettingsHomepageActivity"
android:taskAffinity="com.android.settings.root"
android:label="@string/settings_label_launcher"
android:theme="@style/Theme.Settings.Home"
@@ -136,7 +136,7 @@
android:taskAffinity="com.android.settings.root"
android:label="@string/settings_label_launcher"
android:launchMode="singleTask"
- android:targetActivity=".SettingsHomepageActivity">
+ android:targetActivity=".homepage.SettingsHomepageActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
@@ -1128,12 +1128,12 @@
</intent-filter>
</activity-alias>
- <activity android:name=".applications.InstalledAppOpenByDefaultPage"
+ <activity android:name=".applications.InstalledAppOpenByDefaultActivity"
android:label="@string/application_info_label"
- android:permission="android.permission.OPEN_APPLICATION_DETAILS_OPEN_BY_DEFAULT_PAGE"
+ android:permission="android.permission.OPEN_APP_OPEN_BY_DEFAULT_SETTINGS"
android:exported="true">
<intent-filter android:priority="1">
- <action android:name="android.settings.APPLICATION_DETAILS_SETTINGS_OPEN_BY_DEFAULT_PAGE" />
+ <action android:name="com.android.settings.APP_OPEN_BY_DEFAULT_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="package" />
</intent-filter>
@@ -2709,8 +2709,7 @@
<activity
android:name="Settings$WifiCallingSettingsActivity"
android:label="@string/wifi_calling_settings_title"
- android:taskAffinity="com.android.settings"
- android:parentActivityName="Settings">
+ android:taskAffinity="com.android.settings">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.settings.WIFI_CALLING_SETTINGS" />
diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index d72aaa8..4b36b50 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -37,22 +37,6 @@
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=" app:barPredictionColor="@color/material_empty_color_light""
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="res/layout/battery_history_chart.xml"
- line="38"
- column="9"/>
- </issue>
-
- <issue
- id="HardCodedColor"
- severity="Error"
- message="Avoid using hardcoded color"
- category="Correctness"
- priority="4"
- summary="Using hardcoded color"
- explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" android:textColor="@color/bluetooth_dialog_text_color" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -2425,7 +2409,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rXC/strings.xml"
- line="2559"
+ line="2524"
column="168"/>
</issue>
@@ -2441,7 +2425,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rAU/strings.xml"
- line="2560"
+ line="2525"
column="64"/>
</issue>
@@ -2457,7 +2441,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rCA/strings.xml"
- line="2560"
+ line="2525"
column="64"/>
</issue>
@@ -2473,7 +2457,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rGB/strings.xml"
- line="2560"
+ line="2525"
column="64"/>
</issue>
@@ -2489,7 +2473,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rIN/strings.xml"
- line="2560"
+ line="2525"
column="64"/>
</issue>
@@ -2505,7 +2489,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/strings.xml"
- line="5898"
+ line="5865"
column="36"/>
</issue>
@@ -2709,6 +2693,22 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" <item name="android:navigationBarDividerColor">#1f000000</item>"
+ errorLine2=" ^">
+ <location
+ file="res/values/themes.xml"
+ line="175"
+ column="56"/>
+ </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
diff --git a/res/color/bottom_navigation_colors.xml b/res/color/bottom_navigation_colors.xml
new file mode 100644
index 0000000..659ef50
--- /dev/null
+++ b/res/color/bottom_navigation_colors.xml
@@ -0,0 +1,25 @@
+<?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:state_checked="true"
+ android:color="?android:attr/colorAccent" />
+ <item
+ android:state_checked="false"
+ android:color="?android:attr/textColorPrimary" />
+</selector>
\ No newline at end of file
diff --git a/res/drawable-nodpi/gesture_ambient_reach b/res/drawable-nodpi/gesture_ambient_reach
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/res/drawable-nodpi/gesture_ambient_reach
diff --git a/res/drawable/ic_list_24dp.xml b/res/drawable/ic_list_24dp.xml
deleted file mode 100644
index 03f4af0..0000000
--- a/res/drawable/ic_list_24dp.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:fillColor="?android:attr/colorAccent"
- android:pathData="M4,13L4,13c0.55,0 1,-0.45 1,-1v0c0,-0.55 -0.45,-1 -1,-1h0c-0.55,0 -1,0.45 -1,1v0C3,12.55 3.45,13 4,13zM4,17L4,17c0.55,0 1,-0.45 1,-1v0c0,-0.55 -0.45,-1 -1,-1h0c-0.55,0 -1,0.45 -1,1v0C3,16.55 3.45,17 4,17zM4,9L4,9c0.55,0 1,-0.45 1,-1v0c0,-0.55 -0.45,-1 -1,-1h0C3.45,7 3,7.45 3,8v0C3,8.55 3.45,9 4,9zM7,13h14v-2H7V13zM7,17h14v-2H7V17zM7,7v2h14V7H7z"/>
-</vector>
diff --git a/res/drawable/ic_settings_all.xml b/res/drawable/ic_settings_all.xml
new file mode 100644
index 0000000..03958ab
--- /dev/null
+++ b/res/drawable/ic_settings_all.xml
@@ -0,0 +1,26 @@
+<!--
+ Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M3,12L3,3h9,9v9,9L12,21 3,21ZM19,12L19,5L12,5 5,5v7,7h7,7zM7,16c0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1zM11,16c0,-0.55 1.35,-1 3,-1 1.65,0 3,0.45 3,1 0,0.55 -1.35,1 -3,1 -1.65,0 -3,-0.45 -3,-1zM7,12c0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1zM11,12c0,-0.55 1.35,-1 3,-1 1.65,0 3,0.45 3,1 0,0.55 -1.35,1 -3,1 -1.65,0 -3,-0.45 -3,-1zM7,8C7,7.45 7.45,7 8,7 8.55,7 9,7.45 9,8 9,8.55 8.55,9 8,9 7.45,9 7,8.55 7,8ZM11,8c0,-0.55 1.35,-1 3,-1 1.65,0 3,0.45 3,1 0,0.55 -1.35,1 -3,1 -1.65,0 -3,-0.45 -3,-1z"
+ android:fillColor="#000000"/>
+</vector>
+
diff --git a/res/drawable/ic_settings_personal.xml b/res/drawable/ic_settings_personal.xml
new file mode 100644
index 0000000..5139405
--- /dev/null
+++ b/res/drawable/ic_settings_personal.xml
@@ -0,0 +1,28 @@
+<!--
+ Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M13.85,22.24h-3.7c-0.74,0 -1.36,-0.54 -1.45,-1.27l-0.27,-1.89c-0.27,-0.14 -0.53,-0.29 -0.79,-0.46l-1.8,0.72c-0.7,0.26 -1.47,-0.03 -1.81,-0.65L2.2,15.52c-0.35,-0.66 -0.2,-1.44 0.36,-1.88l1.53,-1.19c-0.01,-0.15 -0.02,-0.3 -0.02,-0.46c0,-0.15 0.01,-0.31 0.02,-0.46l-1.52,-1.19C1.98,9.89 1.83,9.09 2.2,8.47l1.85,-3.19c0.34,-0.62 1.11,-0.9 1.79,-0.63l1.81,0.73C7.91,5.2 8.17,5.05 8.43,4.91L8.7,3.01c0.09,-0.7 0.71,-1.25 1.44,-1.25h3.7c0.74,0 1.36,0.54 1.45,1.27l0.27,1.89c0.27,0.14 0.53,0.29 0.79,0.46l1.8,-0.72c0.71,-0.26 1.48,0.03 1.82,0.65l1.84,3.18c0.36,0.66 0.2,1.44 -0.36,1.88l-1.52,1.19c0.01,0.15 0.02,0.3 0.02,0.46s-0.01,0.31 -0.02,0.46l1.52,1.19c0.56,0.45 0.72,1.23 0.37,1.86l-1.86,3.22c-0.34,0.62 -1.11,0.9 -1.8,0.63l-1.8,-0.72c-0.26,0.17 -0.52,0.32 -0.78,0.46l-0.27,1.91C15.21,21.7 14.59,22.24 13.85,22.24zM13.32,20.72c0,0.01 0,0.01 0,0.02V20.72zM10.68,20.69v0.02C10.69,20.72 10.69,20.7 10.68,20.69zM10.62,20.24h2.76l0.37,-2.55l0.53,-0.22c0.44,-0.18 0.88,-0.44 1.34,-0.78l0.45,-0.34l2.38,0.96l1.38,-2.4l-2.03,-1.58l0.07,-0.56c0.03,-0.26 0.06,-0.51 0.06,-0.78c0,-0.27 -0.03,-0.53 -0.06,-0.78l-0.07,-0.56l2.03,-1.58l-1.39,-2.4l-2.39,0.96L15.6,7.28c-0.42,-0.32 -0.87,-0.58 -1.33,-0.77L13.75,6.3l-0.37,-2.55h-2.76L10.25,6.3L9.72,6.51C9.28,6.69 8.84,6.94 8.38,7.3L7.93,7.62L5.55,6.67L4.16,9.06l2.03,1.58L6.12,11.2c-0.03,0.26 -0.06,0.53 -0.06,0.79s0.02,0.53 0.06,0.78l0.07,0.56l-2.03,1.58l1.38,2.4l2.39,-0.96l0.45,0.35c0.43,0.33 0.86,0.58 1.33,0.77l0.53,0.22L10.62,20.24zM18.22,17.72c0,0.01 -0.01,0.02 -0.01,0.03L18.22,17.72zM5.77,17.7l0.01,0.02C5.78,17.72 5.77,17.7 5.77,17.7zM3.93,9.47L3.93,9.47L3.93,9.47zM18.22,6.26c0,0.01 0.01,0.02 0.01,0.02L18.22,6.26zM5.79,6.24L5.78,6.26C5.78,6.26 5.79,6.26 5.79,6.24zM13.31,3.27c0,0.01 0,0.01 0,0.02V3.27zM10.69,3.25v0.02C10.69,3.26 10.69,3.26 10.69,3.25z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M13.56,10.44l-1.56,-3.44l-1.56,3.44l-3.44,1.56l3.44,1.56l1.56,3.44l1.56,-3.44l3.44,-1.56z"/>
+</vector>
diff --git a/res/layout/homepage_condition_tile.xml b/res/layout/homepage_condition_tile.xml
new file mode 100644
index 0000000..50ef3c2
--- /dev/null
+++ b/res/layout/homepage_condition_tile.xml
@@ -0,0 +1,29 @@
+<!--
+ 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.
+-->
+
+<androidx.cardview.widget.CardView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ style="@style/SuggestionConditionStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:cardUseCompatPadding="true"
+ app:cardElevation="@dimen/condition_card_elevation"
+ app:cardCornerRadius="@dimen/suggestion_card_corner_radius">
+
+ <include layout="@layout/condition_tile"/>
+
+</androidx.cardview.widget.CardView>
diff --git a/res/layout/master_clear.xml b/res/layout/master_clear.xml
index 9f89961..921347e 100644
--- a/res/layout/master_clear.xml
+++ b/res/layout/master_clear.xml
@@ -23,8 +23,8 @@
android:id="@+id/master_clear_scrollview"
android:layout_width="match_parent"
android:layout_height="0dip"
- android:layout_marginStart="@dimen/preference_no_icon_padding_start"
- android:layout_marginEnd="12dp"
+ android:layout_marginStart="@dimen/reset_master_clear_margin_start"
+ android:layout_marginEnd="@dimen/reset_master_clear_margin_end"
android:layout_marginTop="12dp"
android:layout_weight="1">
<LinearLayout
diff --git a/res/layout/reset_network.xml b/res/layout/reset_network.xml
index 1850bb2..7eb5d2a 100644
--- a/res/layout/reset_network.xml
+++ b/res/layout/reset_network.xml
@@ -23,8 +23,8 @@
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dip"
- android:layout_marginStart="@dimen/preference_no_icon_padding_start"
- android:layout_marginEnd="12dp"
+ android:layout_marginStart="@dimen/reset_network_margin_start"
+ android:layout_marginEnd="@dimen/reset_network_margin_end"
android:layout_marginTop="12dp"
android:layout_weight="1">
diff --git a/res/layout/screen_pinning_instructions.xml b/res/layout/screen_pinning_instructions.xml
index 80fec3c..fea5ed8 100644
--- a/res/layout/screen_pinning_instructions.xml
+++ b/res/layout/screen_pinning_instructions.xml
@@ -31,8 +31,8 @@
android:paddingTop="@dimen/screen_pinning_textview_padding"
android:text="@string/screen_pinning_description"
android:textAppearance="@style/TextAppearance.Medium"
- android:paddingStart="@dimen/screen_margin_sides"
- android:paddingEnd="@dimen/screen_margin_sides"
+ android:paddingStart="@dimen/screen_pinning_padding_start"
+ android:paddingEnd="@dimen/screen_pinning_padding_end"
/>
</ScrollView>
diff --git a/res/layout/settings_homepage.xml b/res/layout/settings_homepage.xml
index f1555ee..035e8b4 100644
--- a/res/layout/settings_homepage.xml
+++ b/res/layout/settings_homepage.xml
@@ -15,62 +15,8 @@
limitations under the License.
-->
-<androidx.coordinatorlayout.widget.CoordinatorLayout
+<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/card_container"
android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/card_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
-
- <RelativeLayout
- android:id="@+id/bottom_sheet"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="?android:attr/windowBackground"
- android:minHeight="@dimen/homepage_bottomsheet_height"
- app:layout_behavior="@string/bottom_sheet_behavior"
- app:behavior_peekHeight="@dimen/homepage_bottomsheet_height">
-
- <androidx.coordinatorlayout.widget.CoordinatorLayout
- android:id="@+id/bottom_area"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <com.google.android.material.floatingactionbutton.FloatingActionButton
- android:id="@+id/search_fab"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/ic_search_floating_24dp"
- app:backgroundTint="@android:color/white"
- app:layout_anchor="@id/bar"/>
-
- <com.google.android.material.bottomappbar.BottomAppBar
- android:id="@+id/bar"
- android:layout_width="match_parent"
- android:layout_height="@dimen/homepage_bottombar_height"
- android:layout_alignParentTop="true"
- android:layout_marginTop="@dimen/homepage_bottombar_top_margin"
- android:clickable="true"
- app:fabAttached="true"
- app:fabAlignmentMode="end"
- app:fabCradleDiameter="@dimen/homepage_bottombar_fab_cradle"
- app:navigationIcon="@drawable/ic_list_24dp"
- style="@style/Widget.MaterialComponents.BottomAppBar"/>
- </androidx.coordinatorlayout.widget.CoordinatorLayout>
-
- <include layout="@layout/search_bar"
- android:visibility="invisible"/>
-
- <FrameLayout
- android:id="@+id/bottom_sheet_fragment"
- android:layout_below="@id/bottom_area"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
-
- </RelativeLayout>
-
-</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
+ android:layout_height="wrap_content" />
diff --git a/res/layout/settings_homepage_container.xml b/res/layout/settings_homepage_container.xml
index 84511f2..b35b4ce 100644
--- a/res/layout/settings_homepage_container.xml
+++ b/res/layout/settings_homepage_container.xml
@@ -15,8 +15,38 @@
limitations under the License.
-->
-<FrameLayout
+<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@id/main_content"
- android:layout_height="match_parent"
- android:layout_width="match_parent"/>
\ No newline at end of file
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <com.google.android.material.bottomnavigation.BottomNavigationView
+ android:id="@+id/bottom_nav"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="0dp"
+ android:layout_marginStart="0dp"
+ android:background="?android:attr/windowBackground"
+ android:layout_alignParentBottom="true"
+ app:itemIconTint="@color/bottom_navigation_colors"
+ app:itemTextColor="@color/bottom_navigation_colors"
+ app:menu="@menu/home_bottom_navigation" />
+
+ <FrameLayout
+ android:id="@id/main_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_above="@+id/bottom_nav" />
+
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
+ android:id="@+id/search_fab"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_search_24dp"
+ android:layout_margin="24dp"
+ android:layout_above="@id/bottom_nav"
+ android:layout_alignParentRight="true"
+ app:backgroundTint="?android:attr/colorAccent"
+ app:tint="@android:color/white" />
+</RelativeLayout>
\ No newline at end of file
diff --git a/res/menu/home_bottom_navigation.xml b/res/menu/home_bottom_navigation.xml
new file mode 100644
index 0000000..c58efd7
--- /dev/null
+++ b/res/menu/home_bottom_navigation.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/homepage_personal_settings"
+ android:icon="@drawable/ic_settings_personal"
+ android:title="@string/homepage_personal_settings" />
+ <item
+ android:id="@+id/homepage_all_settings"
+ android:icon="@drawable/ic_settings_all"
+ android:title="@string/homepage_all_settings" />
+</menu>
diff --git a/res/raw/gesture_ambient_reach.mp4 b/res/raw/gesture_ambient_reach.mp4
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/res/raw/gesture_ambient_reach.mp4
diff --git a/res/values-sw600dp-land/dimens.xml b/res/values-sw600dp-land/dimens.xml
index d5ea762..afdcd0e 100755
--- a/res/values-sw600dp-land/dimens.xml
+++ b/res/values-sw600dp-land/dimens.xml
@@ -29,4 +29,8 @@
<dimen name="confirm_credentials_top_padding">20dp</dimen>
<dimen name="confirm_credentials_top_margin">24dp</dimen>
+
+ <!-- Padding for screen pinning -->
+ <dimen name="screen_pinning_padding_start">128dp</dimen>
+ <dimen name="screen_pinning_padding_end">128dp</dimen>
</resources>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index 273225e..241471c 100755
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -62,4 +62,8 @@
<dimen name="confirm_credentials_top_padding">48dp</dimen>
<dimen name="confirm_credentials_side_margin">0dp</dimen>
<dimen name="confirm_credentials_top_margin">64dp</dimen>
+
+ <!-- Padding for screen pinning -->
+ <dimen name="screen_pinning_padding_start">40dp</dimen>
+ <dimen name="screen_pinning_padding_end">40dp</dimen>
</resources>
diff --git a/res/values-xlarge/dimens.xml b/res/values-xlarge/dimens.xml
index b6b4591..df9d56f 100755
--- a/res/values-xlarge/dimens.xml
+++ b/res/values-xlarge/dimens.xml
@@ -18,4 +18,8 @@
<dimen name="screen_margin_sides">128dip</dimen>
<dimen name="datetime_margin_top">154dip</dimen>
<dimen name="datetime_margin_bottom">96dip</dimen>
+
+ <!-- Padding for screen pinning -->
+ <dimen name="screen_pinning_padding_start">128dp</dimen>
+ <dimen name="screen_pinning_padding_end">128dp</dimen>
</resources>
diff --git a/res/values/bools.xml b/res/values/bools.xml
index f1abe9d..8bd11c7 100644
--- a/res/values/bools.xml
+++ b/res/values/bools.xml
@@ -174,6 +174,9 @@
<!-- Whether wifi_mac_address should be shown or not. -->
<bool name="config_show_wifi_mac_address">true</bool>
- <!-- Whether to disable "Uninstall Updates" menu item for System apps or not.. -->
+ <!-- Whether to disable "Uninstall Updates" menu item for System apps or not. -->
<bool name="config_disable_uninstall_update">false</bool>
+
+ <!-- Whether or not extra preview panels should be used for screen zoom setting. -->
+ <bool name="config_enable_extra_screen_zoom_preview">true</bool>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index acb895b..16d9f96 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -297,6 +297,16 @@
<dimen name="battery_meter_width">66dp</dimen>
<dimen name="battery_meter_height">100dp</dimen>
+ <!-- Margin for the reset screens -->
+ <dimen name="reset_network_margin_start">72dp</dimen>
+ <dimen name="reset_network_margin_end">12dp</dimen>
+ <dimen name="reset_master_clear_margin_start">72dp</dimen>
+ <dimen name="reset_master_clear_margin_end">12dp</dimen>
+
+ <!-- Padding for screen pinning -->
+ <dimen name="screen_pinning_padding_start">64dp</dimen>
+ <dimen name="screen_pinning_padding_end">64dp</dimen>
+
<!-- Suggestion/condition header padding -->
<dimen name="suggestion_condition_header_padding_collapsed">10dp</dimen>
<dimen name="suggestion_condition_header_padding_expanded">5dp</dimen>
@@ -312,6 +322,9 @@
<dimen name="suggestion_card_button_top_margin">16dp</dimen>
<dimen name="suggestion_card_button_bottom_margin">18dp</dimen>
+ <!-- Condition cards size and padding -->
+ <dimen name="condition_card_elevation">2dp</dimen>
+
<!-- Padding for the reset screens -->
<dimen name="reset_checkbox_padding_end">8dp</dimen>
<dimen name="reset_checkbox_title_padding_top">12dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 53abd54..c99d7ad 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -8193,7 +8193,7 @@
<string name="encrypt_talkback_dialog_message_password">When you enter your password to start this device, accessibility services like <xliff:g id="service" example="TalkBack">%1$s</xliff:g> won\u2019t yet be available.</string>
<!-- [CHAR LIMIT=NONE] Dialog body explaining that the app just selected by the user will not work after a reboot until until after the user enters their credentials, such as a PIN or password. -->
- <string name="direct_boot_unaware_dialog_message">Note: After a reboot, this app can\'t start until you unlock your phone</string>
+ <string name="direct_boot_unaware_dialog_message">Note: If you restart your phone and have a screen lock set, this app can\'t start until you unlock your phone</string>
<!-- Title and summary for SIM Status -->
<string name="imei_information_title">IMEI information</string>
@@ -8948,8 +8948,6 @@
<string name="disabled_by_policy_title_camera">Camera not allowed</string>
<!-- Title for dialog displayed to tell user that screenshots are disabled by an admin [CHAR LIMIT=50] -->
<string name="disabled_by_policy_title_screen_capture">Screenshot not allowed</string>
- <!-- Title for dialog displayed to tell user that turning off backups is disallowed by an admin [CHAR LIMIT=50] -->
- <string name="disabled_by_policy_title_turn_off_backups">Can’t turn off backups</string>
<!-- Title for dialog displayed to tell user that the app was suspended by an admin [CHAR LIMIT=50] -->
<string name="disabled_by_policy_title_suspend_packages">Can’t open this app</string>
<!-- Shown when the user tries to change a settings locked by an admin [CHAR LIMIT=200] -->
@@ -9459,11 +9457,11 @@
<!-- [CHAR LIMIT=60] Name of dev option called "System UI demo mode" -->
<string name="demo_mode">System UI demo mode</string>
- <!-- [CHAR LIMIT=60] Name of dev option that changes the UI Mode -->
- <string name="dark_ui_mode">Night mode</string>
+ <!-- [CHAR LIMIT=60] Name of setting that changes the UI to dark -->
+ <string name="dark_ui_mode">Dark mode</string>
<!-- [CHAR LIMIT=60] Name of dev option that changes the color of the UI -->
- <string name="dark_ui_mode_title">Set Night mode</string>
+ <string name="dark_ui_mode_title">Set Dark mode</string>
<!-- [CHAR LIMIT=60] Name of dev option to enable extra quick settings tiles -->
<string name="quick_settings_developer_tiles">Quick settings developer tiles</string>
@@ -9471,9 +9469,6 @@
<!-- [CHAR LIMIT=25] Title of developer tile to toggle winscope trace -->
<string name="winscope_trace_quick_settings_title">Winscope Trace</string>
- <!-- Template for formatting country and language. eg Canada - French [CHAR LIMIT=NONE]-->
- <string name="support_country_format"><xliff:g id="country" example="Canada">%1$s</xliff:g> - <xliff:g id="language" example="French">%2$s</xliff:g></string>
-
<!-- [CHAR LIMIT=60] Title of work profile setting page -->
<string name="managed_profile_settings_title">Work profile settings</string>
<!-- [CHAR LIMIT=60] The preference title for enabling cross-profile remote contact search -->
@@ -9584,19 +9579,10 @@
<!-- Summary text for ambient display (device) [CHAR LIMIT=NONE]-->
<string name="ambient_display_pickup_summary" product="device">To check time, notifications, and other info, pick up your device.</string>
- <!-- Preference and settings suggestion title text for reach gesture (phone) [CHAR LIMIT=60]-->
- <string name="ambient_display_reach_title" product="default">Reach to check phone</string>
- <!-- Preference and settings suggestion title text for reach gesture (tablet) [CHAR LIMIT=60]-->
- <string name="ambient_display_reach_title" product="tablet">Reach to check tablet</string>
- <!-- Preference and settings suggestion title text for reach gesture (device) [CHAR LIMIT=60]-->
- <string name="ambient_display_reach_title" product="device">Reach to check device</string>
-
- <!-- Summary text for ambient display (phone) [CHAR LIMIT=NONE]-->
- <string name="ambient_display_reach_summary" product="default">To check time, notifications, and other info, reach for your phone.</string>
- <!-- Summary text for ambient display (tablet) [CHAR LIMIT=NONE]-->
- <string name="ambient_display_reach_summary" product="tablet">To check time, notifications, and other info, reach for your tablet.</string>
- <!-- Summary text for ambient display (device) [CHAR LIMIT=NONE]-->
- <string name="ambient_display_reach_summary" product="device">To check time, notifications, and other info, reach for your device.</string>
+ <!-- Preference and settings suggestion title text for reach gesture [CHAR LIMIT=60]-->
+ <string name="ambient_display_reach_title">Reach gesture</string>
+ <!-- Summary text for ambient display [CHAR LIMIT=NONE]-->
+ <string name="ambient_display_reach_summary" product="default"></string>
<!-- Title text for swiping downwards on fingerprint sensor for notifications [CHAR LIMIT=80]-->
<string name="fingerprint_swipe_for_notifications_title">Swipe fingerprint for notifications</string>
@@ -9761,8 +9747,6 @@
<item quantity="one"><xliff:g id="count">%d</xliff:g> attempt</item>
<item quantity="other"><xliff:g id="count">%d</xliff:g> attempts</item>
</plurals>
- <!-- List item in a work device's settings. This text lets the user know that their IT administrator requires their device's data to be backed up. The user can't change this setting. [CHAR LIMIT=NONE] -->
- <string name="enterprise_privacy_backups_enabled">This device\'s data is being backed up</string>
<!-- Message indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=NONE] -->
<string name="do_disclosure_generic">This device is managed by your organization.</string>
<!-- Message indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=NONE] -->
@@ -10078,4 +10062,10 @@
<!-- UI debug setting: Enable High Refresh Rate virtual panel [CHAR LIMIT=50] -->
<string name="high_frequency_display_device_summary">Enable Virtual High Frequency Panel</string>
+ <!-- Homepage bottom menu. Title for display all Settings [CHAR LIMIT=30] -->
+ <string name="homepage_all_settings">All Settings</string>
+
+ <!-- Homepage bottom menu. Title for display personalized Settings [CHAR LIMIT=30] -->
+ <string name="homepage_personal_settings">Your Settings</string>
+
</resources>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 7fd0dcc..4bd6f52 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -167,6 +167,7 @@
<style name="Theme.Settings.Home" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Color names copied from frameworks/base/core/res/res/values/themes_device_defaults.xml -->
+ <!-- TODO (b/113964702) : fix theme color -->
<item name="colorPrimary">@*android:color/primary_device_default_settings_light</item>
<item name="colorPrimaryDark">@*android:color/primary_dark_device_default_settings_light</item>
<item name="colorAccent">@*android:color/accent_device_default_light</item>
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index 95dba41..a76bef7 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -47,7 +47,7 @@
android:title="@string/display_category_title">
<Preference
- android:fragment="com.android.settings.accessibility.ToggleFontSizePreferenceFragment"
+ android:fragment="com.android.settings.display.ToggleFontSizePreferenceFragment"
android:key="font_size_preference_screen"
android:title="@string/title_font_size"
settings:searchable="false"/>
diff --git a/res/xml/accessibility_settings_for_setup_wizard.xml b/res/xml/accessibility_settings_for_setup_wizard.xml
index c1141ab..738bb8e 100644
--- a/res/xml/accessibility_settings_for_setup_wizard.xml
+++ b/res/xml/accessibility_settings_for_setup_wizard.xml
@@ -33,7 +33,7 @@
<Preference
android:fragment=
- "com.android.settings.accessibility.FontSizePreferenceFragmentForSetupWizard"
+ "com.android.settings.display.FontSizePreferenceFragmentForSetupWizard"
android:key="font_size_preference"
android:title="@string/title_font_size"
android:summary="@string/short_summary_font_size" />
diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml
index 54769cf..db4e7d8 100644
--- a/res/xml/display_settings.xml
+++ b/res/xml/display_settings.xml
@@ -83,7 +83,7 @@
<Preference
android:key="font_size"
android:title="@string/title_font_size"
- android:fragment="com.android.settings.accessibility.ToggleFontSizePreferenceFragment"
+ android:fragment="com.android.settings.display.ToggleFontSizePreferenceFragment"
settings:controller="com.android.settings.display.FontSizePreferenceController" />
<com.android.settings.display.ScreenZoomPreference
diff --git a/res/xml/enterprise_privacy_settings.xml b/res/xml/enterprise_privacy_settings.xml
index 0aa1415..4fa50e7 100644
--- a/res/xml/enterprise_privacy_settings.xml
+++ b/res/xml/enterprise_privacy_settings.xml
@@ -83,9 +83,6 @@
<Preference android:key="ca_certs_managed_profile"
android:title="@string/enterprise_privacy_ca_certs_work"
android:selectable="false"/>
- <Preference android:key="backups_enabled"
- android:title="@string/enterprise_privacy_backups_enabled"
- android:selectable="false"/>
</PreferenceCategory>
<PreferenceCategory android:key="device_access_category"
diff --git a/res/xml/gestures.xml b/res/xml/gestures.xml
index 9f69102..aa99446 100644
--- a/res/xml/gestures.xml
+++ b/res/xml/gestures.xml
@@ -28,6 +28,12 @@
settings:controller="com.android.settings.gestures.AssistGestureSettingsPreferenceController" />
<Preference
+ android:key="gesture_reach_summary"
+ android:title="@string/ambient_display_reach_title"
+ android:fragment="com.android.settings.gestures.ReachGestureSettings"
+ settings:controller="com.android.settings.gestures.ReachGesturePreferenceController" />
+
+ <Preference
android:key="gesture_swipe_down_fingerprint_input_summary"
android:title="@string/fingerprint_swipe_for_notifications_title"
android:fragment="com.android.settings.gestures.SwipeToNotificationSettings"
diff --git a/res/xml/my_device_info.xml b/res/xml/my_device_info.xml
index 957ba81..535f61a 100644
--- a/res/xml/my_device_info.xml
+++ b/res/xml/my_device_info.xml
@@ -72,10 +72,18 @@
<intent android:action="android.settings.SHOW_REGULATORY_INFO"/>
</Preference>
+ <!-- Safety & regulatory manual -->
+ <Preference
+ android:key="safety_info"
+ android:order="7"
+ android:title="@string/safety_and_regulatory_info">
+ <intent android:action="android.settings.SHOW_SAFETY_AND_REGULATORY_INFO"/>
+ </Preference>
+
<!-- SIM status -->
<Preference
android:key="sim_status"
- android:order="7"
+ android:order="8"
android:title="@string/sim_status_title"
settings:keywords="@string/keywords_sim_status"
android:summary="@string/summary_placeholder"
@@ -142,14 +150,6 @@
android:summary="@string/summary_placeholder"
android:selectable="false" />
- <!-- Safety & regulatory manual -->
- <Preference
- android:key="safety_info"
- android:order="39"
- android:title="@string/safety_and_regulatory_info">
- <intent android:action="android.settings.SHOW_SAFETY_AND_REGULATORY_INFO"/>
- </Preference>
-
<!-- Manual -->
<Preference
android:key="manual"
diff --git a/res/xml/reach_gesture_settings.xml b/res/xml/reach_gesture_settings.xml
index 1acc364..e933e15 100644
--- a/res/xml/reach_gesture_settings.xml
+++ b/res/xml/reach_gesture_settings.xml
@@ -23,8 +23,8 @@
<com.android.settings.widget.VideoPreference
android:key="gesture_reach_video"
- app:animation="@raw/gesture_ambient_lift"
- app:preview="@drawable/gesture_ambient_lift" />
+ app:animation="@raw/gesture_ambient_reach"
+ app:preview="@drawable/gesture_ambient_reach" />
<SwitchPreference
android:key="gesture_reach"
diff --git a/src/com/android/settings/CredentialStorage.java b/src/com/android/settings/CredentialStorage.java
index c553e34..319d599 100644
--- a/src/com/android/settings/CredentialStorage.java
+++ b/src/com/android/settings/CredentialStorage.java
@@ -106,6 +106,7 @@
private static final int CONFIRM_CLEAR_SYSTEM_CREDENTIAL_REQUEST = 2;
private final KeyStore mKeyStore = KeyStore.getInstance();
+ private LockPatternUtils mUtils;
/**
* When non-null, the bundle containing credentials to install.
@@ -113,6 +114,12 @@
private Bundle mInstallBundle;
@Override
+ protected void onCreate(Bundle savedState) {
+ super.onCreate(savedState);
+ mUtils = new LockPatternUtils(this);
+ }
+
+ @Override
protected void onResume() {
super.onResume();
@@ -160,7 +167,7 @@
return;
}
case UNLOCKED: {
- if (isActivePasswordQualityInsufficient()) {
+ if (!mUtils.isSecure(UserHandle.myUserId())) {
final ConfigureKeyGuardDialog dialog = new ConfigureKeyGuardDialog();
dialog.show(getSupportFragmentManager(), ConfigureKeyGuardDialog.TAG);
return;
@@ -179,7 +186,7 @@
* case after unlocking with an old-style password).
*/
private void ensureKeyGuard() {
- if (isActivePasswordQualityInsufficient()) {
+ if (!mUtils.isSecure(UserHandle.myUserId())) {
// key guard not setup, doing so will initialize keystore
final ConfigureKeyGuardDialog dialog = new ConfigureKeyGuardDialog();
dialog.show(getSupportFragmentManager(), ConfigureKeyGuardDialog.TAG);
@@ -194,16 +201,6 @@
finish();
}
- /**
- * Returns true if the currently set key guard violates our minimum quality requirements.
- */
- private boolean isActivePasswordQualityInsufficient() {
- final int credentialOwner =
- UserManager.get(this).getCredentialOwnerProfile(UserHandle.myUserId());
- final int quality = new LockPatternUtils(this).getActivePasswordQuality(credentialOwner);
- return (quality >= MIN_PASSWORD_QUALITY);
- }
-
private boolean isHardwareBackedKey(byte[] keyData) {
try {
final ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(keyData));
@@ -350,7 +347,7 @@
protected Boolean doInBackground(Void... unused) {
// Clear all the users credentials could have been installed in for this user.
- new LockPatternUtils(CredentialStorage.this).resetKeyStore(UserHandle.myUserId());
+ mUtils.resetKeyStore(UserHandle.myUserId());
try {
final KeyChainConnection keyChainConnection = KeyChain.bind(CredentialStorage.this);
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
index 6c084ab..c8ec448 100644
--- a/src/com/android/settings/MasterClear.java
+++ b/src/com/android/settings/MasterClear.java
@@ -62,6 +62,7 @@
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.password.ConfirmLockPattern;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import java.util.List;
@@ -499,11 +500,12 @@
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final Context context = getContext();
- final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(context,
+ final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(context,
UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId());
final UserManager um = UserManager.get(context);
- final boolean disallow = !um.isAdminUser() || RestrictedLockUtils.hasBaseUserRestriction(
- context, UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId());
+ final boolean disallow = !um.isAdminUser() || RestrictedLockUtilsInternal
+ .hasBaseUserRestriction(context, UserManager.DISALLOW_FACTORY_RESET,
+ UserHandle.myUserId());
if (disallow && !Utils.isDemoUser(context)) {
return inflater.inflate(R.layout.master_clear_disallowed_screen, null);
} else if (admin != null) {
diff --git a/src/com/android/settings/MasterClearConfirm.java b/src/com/android/settings/MasterClearConfirm.java
index 0ea7250..cfd20eb 100644
--- a/src/com/android/settings/MasterClearConfirm.java
+++ b/src/com/android/settings/MasterClearConfirm.java
@@ -38,6 +38,7 @@
import com.android.settings.core.InstrumentedFragment;
import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
/**
* Confirm and execute a reset of the device to a clean "just out of the box"
@@ -146,9 +147,9 @@
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(
+ final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
getActivity(), UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId());
- if (RestrictedLockUtils.hasBaseUserRestriction(getActivity(),
+ if (RestrictedLockUtilsInternal.hasBaseUserRestriction(getActivity(),
UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId())) {
return inflater.inflate(R.layout.master_clear_disallowed_screen, null);
} else if (admin != null) {
diff --git a/src/com/android/settings/ResetNetwork.java b/src/com/android/settings/ResetNetwork.java
index 22e5716..c1eca16 100644
--- a/src/com/android/settings/ResetNetwork.java
+++ b/src/com/android/settings/ResetNetwork.java
@@ -50,6 +50,7 @@
import com.android.settings.password.ConfirmLockPattern;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import java.util.ArrayList;
import java.util.List;
@@ -240,9 +241,9 @@
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final UserManager um = UserManager.get(getActivity());
- final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(
+ final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
getActivity(), UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId());
- if (!um.isAdminUser() || RestrictedLockUtils.hasBaseUserRestriction(getActivity(),
+ if (!um.isAdminUser() || RestrictedLockUtilsInternal.hasBaseUserRestriction(getActivity(),
UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId())) {
return inflater.inflate(R.layout.network_reset_disallowed_screen, null);
} else if (admin != null) {
diff --git a/src/com/android/settings/ResetNetworkConfirm.java b/src/com/android/settings/ResetNetworkConfirm.java
index e3bd8f1..2044af5 100644
--- a/src/com/android/settings/ResetNetworkConfirm.java
+++ b/src/com/android/settings/ResetNetworkConfirm.java
@@ -50,6 +50,7 @@
import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper;
import com.android.settings.network.ApnSettings;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
/**
* Confirm and execute a reset of the network settings to a clean "just out of the box"
@@ -204,9 +205,9 @@
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(
+ final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
getActivity(), UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId());
- if (RestrictedLockUtils.hasBaseUserRestriction(getActivity(),
+ if (RestrictedLockUtilsInternal.hasBaseUserRestriction(getActivity(),
UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId())) {
return inflater.inflate(R.layout.network_reset_disallowed_screen, null);
} else if (admin != null) {
diff --git a/src/com/android/settings/RestrictedCheckBox.java b/src/com/android/settings/RestrictedCheckBox.java
index 2d45880..828c443 100644
--- a/src/com/android/settings/RestrictedCheckBox.java
+++ b/src/com/android/settings/RestrictedCheckBox.java
@@ -24,6 +24,7 @@
import android.widget.CheckBox;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
/**
* A checkbox that can be restricted by device policy, in which case it shows a dialog explaining
@@ -57,7 +58,8 @@
mEnforcedAdmin = admin;
if (mDisabledByAdmin != disabled) {
mDisabledByAdmin = disabled;
- RestrictedLockUtils.setTextViewAsDisabledByAdmin(mContext, this, mDisabledByAdmin);
+ RestrictedLockUtilsInternal.setTextViewAsDisabledByAdmin(mContext, this,
+ mDisabledByAdmin);
if (mDisabledByAdmin) {
getButtonDrawable().setColorFilter(mContext.getColor(R.color.disabled_text_color),
PorterDuff.Mode.MULTIPLY);
diff --git a/src/com/android/settings/RestrictedRadioButton.java b/src/com/android/settings/RestrictedRadioButton.java
index 7efba4f..20c2872 100644
--- a/src/com/android/settings/RestrictedRadioButton.java
+++ b/src/com/android/settings/RestrictedRadioButton.java
@@ -25,6 +25,7 @@
import android.widget.TextView;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
public class RestrictedRadioButton extends RadioButton {
private Context mContext;
@@ -63,7 +64,7 @@
mEnforcedAdmin = admin;
if (mDisabledByAdmin != disabled) {
mDisabledByAdmin = disabled;
- RestrictedLockUtils.setTextViewAsDisabledByAdmin(mContext,
+ RestrictedLockUtilsInternal.setTextViewAsDisabledByAdmin(mContext,
(TextView) this, mDisabledByAdmin);
if (mDisabledByAdmin) {
getButtonDrawable().setColorFilter(mContext.getColor(R.color.disabled_text_color),
diff --git a/src/com/android/settings/RestrictedSettingsFragment.java b/src/com/android/settings/RestrictedSettingsFragment.java
index 7fab528..df438d5 100644
--- a/src/com/android/settings/RestrictedSettingsFragment.java
+++ b/src/com/android/settings/RestrictedSettingsFragment.java
@@ -37,6 +37,7 @@
import com.android.settings.dashboard.RestrictedDashboardFragment;
import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
/**
* Base class for settings screens that should be pin protected when in restricted mode or
@@ -219,7 +220,7 @@
}
public EnforcedAdmin getRestrictionEnforcedAdmin() {
- mEnforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(getActivity(),
+ mEnforcedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(getActivity(),
mRestrictionKey, UserHandle.myUserId());
if (mEnforcedAdmin != null && mEnforcedAdmin.userId == UserHandle.USER_NULL) {
mEnforcedAdmin.userId = UserHandle.myUserId();
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 4ca1c2c..ffce321 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -62,6 +62,8 @@
import com.android.settings.core.gateway.SettingsGateway;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.DashboardSummary;
+import com.android.settings.homepage.SettingsHomepageActivity;
+import com.android.settings.homepage.TopLevelSettings;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.DeviceIndexFeatureProvider;
import com.android.settings.wfd.WifiDisplaySettings;
@@ -403,8 +405,13 @@
// Show search icon as up affordance if we are displaying the main Dashboard
mInitialTitleResId = R.string.dashboard_title;
- switchToFragment(DashboardSummary.class.getName(), null /* args */, false, false,
- mInitialTitleResId, mInitialTitle, false);
+ if (SettingsHomepageActivity.isDynamicHomepageEnabled(this)) {
+ switchToFragment(TopLevelSettings.class.getName(), null /* args */, false, false,
+ mInitialTitleResId, mInitialTitle, false);
+ } else {
+ switchToFragment(DashboardSummary.class.getName(), null /* args */, false, false,
+ mInitialTitleResId, mInitialTitle, false);
+ }
}
}
diff --git a/src/com/android/settings/SettingsHomepageActivity.java b/src/com/android/settings/SettingsHomepageActivity.java
deleted file mode 100644
index 6e583c7..0000000
--- a/src/com/android/settings/SettingsHomepageActivity.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.FeatureFlagUtils;
-
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentActivity;
-import androidx.fragment.app.FragmentManager;
-
-import com.android.settings.core.FeatureFlags;
-import com.android.settings.core.SettingsBaseActivity;
-import com.android.settings.homepage.HomepageFragment;
-
-public class SettingsHomepageActivity extends SettingsBaseActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- if (!isDynamicHomepageEnabled(this)) {
- final Intent settings = new Intent();
- settings.setAction("android.settings.SETTINGS");
- startActivity(settings);
- finish();
- return;
- }
- setContentView(R.layout.settings_homepage_container);
- if (savedInstanceState == null) {
- switchToFragment(this, R.id.main_content, HomepageFragment.class.getName());
- }
- }
-
- public static boolean isDynamicHomepageEnabled(Context context) {
- return FeatureFlagUtils.isEnabled(context, FeatureFlags.DYNAMIC_HOMEPAGE);
- }
-
- /**
- * Switch to a specific Fragment
- */
- public static void switchToFragment(FragmentActivity activity, int id, String fragmentName) {
- final Fragment f = Fragment.instantiate(activity, fragmentName, null /* args */);
-
- FragmentManager manager = activity.getSupportFragmentManager();
- manager.beginTransaction().replace(id, f).commitAllowingStateLoss();
- manager.executePendingTransactions();
- }
-}
\ No newline at end of file
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index 4197e2f..87a3511 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -541,10 +541,6 @@
private DialogInterface.OnCancelListener mOnCancelListener;
private DialogInterface.OnDismissListener mOnDismissListener;
- public SettingsDialogFragment() {
- /* do nothing */
- }
-
public SettingsDialogFragment(DialogCreatable fragment, int dialogId) {
super(fragment, dialogId);
if (!(fragment instanceof Fragment)) {
diff --git a/src/com/android/settings/TetherSettings.java b/src/com/android/settings/TetherSettings.java
index 02f9cc5..d32e387 100644
--- a/src/com/android/settings/TetherSettings.java
+++ b/src/com/android/settings/TetherSettings.java
@@ -423,9 +423,6 @@
startTethering(TETHERING_BLUETOOTH);
} else {
mCm.stopTethering(TETHERING_BLUETOOTH);
- // No ACTION_TETHER_STATE_CHANGED is fired or bluetooth unless a device is
- // connected. Need to update state manually.
- updateState();
}
}
diff --git a/src/com/android/settings/UserCredentialsSettings.java b/src/com/android/settings/UserCredentialsSettings.java
index abd8641..b1f9fe7 100644
--- a/src/com/android/settings/UserCredentialsSettings.java
+++ b/src/com/android/settings/UserCredentialsSettings.java
@@ -53,6 +53,7 @@
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import java.security.UnrecoverableKeyException;
import java.util.ArrayList;
@@ -137,11 +138,12 @@
final String restriction = UserManager.DISALLOW_CONFIG_CREDENTIALS;
final int myUserId = UserHandle.myUserId();
- if (!RestrictedLockUtils.hasBaseUserRestriction(getContext(), restriction, myUserId)) {
+ if (!RestrictedLockUtilsInternal.hasBaseUserRestriction(getContext(), restriction,
+ myUserId)) {
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
@Override public void onClick(DialogInterface dialog, int id) {
- final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(
- getContext(), restriction, myUserId);
+ final EnforcedAdmin admin = RestrictedLockUtilsInternal
+ .checkIfRestrictionEnforced(getContext(), restriction, myUserId);
if (admin != null) {
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
admin);
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index 5744703..9a8ef54 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -55,9 +55,10 @@
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
+import com.android.settings.display.ToggleFontSizePreferenceFragment;
import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.accessibility.AccessibilityUtils;
import com.android.settingslib.search.SearchIndexable;
@@ -584,7 +585,7 @@
permittedServices == null || permittedServices.contains(packageName);
if (!serviceAllowed && !serviceEnabled) {
final EnforcedAdmin admin =
- RestrictedLockUtils.checkIfAccessibilityServiceDisallowed(
+ RestrictedLockUtilsInternal.checkIfAccessibilityServiceDisallowed(
getActivity(), packageName, UserHandle.myUserId());
if (admin != null) {
preference.setDisabledByAdmin(admin);
diff --git a/src/com/android/settings/accounts/AccountRestrictionHelper.java b/src/com/android/settings/accounts/AccountRestrictionHelper.java
index 5fa83b3..05b27aa 100644
--- a/src/com/android/settings/accounts/AccountRestrictionHelper.java
+++ b/src/com/android/settings/accounts/AccountRestrictionHelper.java
@@ -19,7 +19,7 @@
import android.content.Context;
import com.android.settings.AccessiblePreferenceCategory;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import java.util.ArrayList;
@@ -51,7 +51,8 @@
}
public boolean hasBaseUserRestriction(String userRestriction, @UserIdInt int userId) {
- return RestrictedLockUtils.hasBaseUserRestriction(mContext, userRestriction, userId);
+ return RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext, userRestriction,
+ userId);
}
public AccessiblePreferenceCategory createAccessiblePreferenceCategory(Context context) {
diff --git a/src/com/android/settings/accounts/ChooseAccountPreferenceController.java b/src/com/android/settings/accounts/ChooseAccountPreferenceController.java
index 5ac5bc0..a217f01 100644
--- a/src/com/android/settings/accounts/ChooseAccountPreferenceController.java
+++ b/src/com/android/settings/accounts/ChooseAccountPreferenceController.java
@@ -39,6 +39,7 @@
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.google.android.collect.Maps;
@@ -167,7 +168,7 @@
// There's only one provider that matches. If it is disabled by admin show the
// support dialog otherwise run it.
final RestrictedLockUtils.EnforcedAdmin admin =
- RestrictedLockUtils.checkIfAccountManagementDisabled(
+ RestrictedLockUtilsInternal.checkIfAccountManagementDisabled(
context, mProviderList.get(0).getType(), mUserHandle.getIdentifier());
if (admin != null) {
mActivity.setResult(RESULT_CANCELED,
diff --git a/src/com/android/settings/accounts/ContactSearchPreferenceController.java b/src/com/android/settings/accounts/ContactSearchPreferenceController.java
index e0ddf24..8b94ba1 100644
--- a/src/com/android/settings/accounts/ContactSearchPreferenceController.java
+++ b/src/com/android/settings/accounts/ContactSearchPreferenceController.java
@@ -24,6 +24,7 @@
import com.android.settings.core.BasePreferenceController;
import com.android.settings.slices.SliceData;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedSwitchPreference;
public class ContactSearchPreferenceController extends BasePreferenceController implements
@@ -52,7 +53,7 @@
pref.setChecked(isChecked());
if (mManagedUser != null) {
final RestrictedLockUtils.EnforcedAdmin enforcedAdmin =
- RestrictedLockUtils.checkIfRemoteContactSearchDisallowed(
+ RestrictedLockUtilsInternal.checkIfRemoteContactSearchDisallowed(
mContext, mManagedUser.getIdentifier());
pref.setDisabledByAdmin(enforcedAdmin);
}
diff --git a/src/com/android/settings/accounts/ProviderPreference.java b/src/com/android/settings/accounts/ProviderPreference.java
index 1143f8d..b39f561 100644
--- a/src/com/android/settings/accounts/ProviderPreference.java
+++ b/src/com/android/settings/accounts/ProviderPreference.java
@@ -21,7 +21,7 @@
import android.content.Context;
import android.graphics.drawable.Drawable;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
/**
@@ -47,7 +47,7 @@
}
public void checkAccountManagementAndSetDisabled(int userId) {
- EnforcedAdmin admin = RestrictedLockUtils.checkIfAccountManagementDisabled(
+ EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfAccountManagementDisabled(
getContext(), getAccountType(), userId);
setDisabledByAdmin(admin);
}
diff --git a/src/com/android/settings/accounts/RemoveAccountPreferenceController.java b/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
index 7753f81..2494664 100644
--- a/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
+++ b/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
@@ -44,6 +44,7 @@
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.core.AbstractPreferenceController;
import java.io.IOException;
@@ -84,8 +85,8 @@
@Override
public void onClick(View v) {
if (mUserHandle != null) {
- final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
- UserManager.DISALLOW_MODIFY_ACCOUNTS, mUserHandle.getIdentifier());
+ final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
+ mContext, UserManager.DISALLOW_MODIFY_ACCOUNTS, mUserHandle.getIdentifier());
if (admin != null) {
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, admin);
return;
diff --git a/src/com/android/settings/applications/AppInfoBase.java b/src/com/android/settings/applications/AppInfoBase.java
index 815d0ed..fd870d6 100644
--- a/src/com/android/settings/applications/AppInfoBase.java
+++ b/src/com/android/settings/applications/AppInfoBase.java
@@ -48,7 +48,7 @@
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
@@ -107,10 +107,10 @@
@Override
public void onResume() {
super.onResume();
- mAppsControlDisallowedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(getActivity(),
- UserManager.DISALLOW_APPS_CONTROL, mUserId);
- mAppsControlDisallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(getActivity(),
- UserManager.DISALLOW_APPS_CONTROL, mUserId);
+ mAppsControlDisallowedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
+ getActivity(), UserManager.DISALLOW_APPS_CONTROL, mUserId);
+ mAppsControlDisallowedBySystem = RestrictedLockUtilsInternal.hasBaseUserRestriction(
+ getActivity(), UserManager.DISALLOW_APPS_CONTROL, mUserId);
if (!refreshUi()) {
setIntentAndFinish(true, true);
diff --git a/src/com/android/settings/applications/InstalledAppOpenByDefaultPage.java b/src/com/android/settings/applications/InstalledAppOpenByDefaultActivity.java
similarity index 93%
rename from src/com/android/settings/applications/InstalledAppOpenByDefaultPage.java
rename to src/com/android/settings/applications/InstalledAppOpenByDefaultActivity.java
index 40eef25..cd30d79 100644
--- a/src/com/android/settings/applications/InstalledAppOpenByDefaultPage.java
+++ b/src/com/android/settings/applications/InstalledAppOpenByDefaultActivity.java
@@ -20,7 +20,7 @@
import com.android.settings.SettingsActivity;
-public class InstalledAppOpenByDefaultPage extends SettingsActivity {
+public class InstalledAppOpenByDefaultActivity extends SettingsActivity {
@Override
public Intent getIntent() {
diff --git a/src/com/android/settings/applications/appinfo/AppButtonsPreferenceController.java b/src/com/android/settings/applications/appinfo/AppButtonsPreferenceController.java
index d6dfe64..12c4d9d 100644
--- a/src/com/android/settings/applications/appinfo/AppButtonsPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppButtonsPreferenceController.java
@@ -55,6 +55,7 @@
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.ActionButtonPreference;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -181,10 +182,10 @@
@Override
public void onResume() {
if (isAvailable() && !mFinishing) {
- mAppsControlDisallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(mActivity,
- UserManager.DISALLOW_APPS_CONTROL, mUserId);
- mAppsControlDisallowedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(mActivity,
- UserManager.DISALLOW_APPS_CONTROL, mUserId);
+ mAppsControlDisallowedBySystem = RestrictedLockUtilsInternal.hasBaseUserRestriction(
+ mActivity, UserManager.DISALLOW_APPS_CONTROL, mUserId);
+ mAppsControlDisallowedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
+ mActivity, UserManager.DISALLOW_APPS_CONTROL, mUserId);
if (!refreshUi()) {
setIntentAndFinish(true);
@@ -214,10 +215,11 @@
return;
}
RestrictedLockUtils.EnforcedAdmin admin =
- RestrictedLockUtils.checkIfUninstallBlocked(mActivity,
+ RestrictedLockUtilsInternal.checkIfUninstallBlocked(mActivity,
packageName, mUserId);
boolean uninstallBlockedBySystem = mAppsControlDisallowedBySystem ||
- RestrictedLockUtils.hasBaseUserRestriction(mActivity, packageName, mUserId);
+ RestrictedLockUtilsInternal.hasBaseUserRestriction(mActivity, packageName,
+ mUserId);
if (admin != null && !uninstallBlockedBySystem) {
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mActivity, admin);
} else if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
index 422c305..7b9cc79 100755
--- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
+++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
@@ -50,7 +50,7 @@
.PictureInPictureDetailPreferenceController;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.DashboardFragment;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
@@ -185,17 +185,23 @@
mDpm = (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
mUserManager = (UserManager) activity.getSystemService(Context.USER_SERVICE);
mPm = activity.getPackageManager();
-
if (!ensurePackageInfoAvailable(activity)) {
return;
}
-
startListeningToPackageRemove();
setHasOptionsMenu(true);
}
@Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ if (!ensurePackageInfoAvailable(getActivity())) {
+ return;
+ }
+ super.onCreatePreferences(savedInstanceState, rootKey);
+ }
+
+ @Override
public void onDestroy() {
stopListeningToPackageRemove();
super.onDestroy();
@@ -210,10 +216,10 @@
public void onResume() {
super.onResume();
final Activity activity = getActivity();
- mAppsControlDisallowedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(activity,
- UserManager.DISALLOW_APPS_CONTROL, mUserId);
- mAppsControlDisallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(activity,
- UserManager.DISALLOW_APPS_CONTROL, mUserId);
+ mAppsControlDisallowedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
+ activity, UserManager.DISALLOW_APPS_CONTROL, mUserId);
+ mAppsControlDisallowedBySystem = RestrictedLockUtilsInternal.hasBaseUserRestriction(
+ activity, UserManager.DISALLOW_APPS_CONTROL, mUserId);
if (!refreshUi()) {
setIntentAndFinish(true, true);
@@ -338,7 +344,7 @@
&& !mAppsControlDisallowedBySystem
&& !uninstallUpdateDisabled);
if (uninstallUpdatesItem.isVisible()) {
- RestrictedLockUtils.setMenuItemAsDisabledByAdmin(getActivity(),
+ RestrictedLockUtilsInternal.setMenuItemAsDisabledByAdmin(getActivity(),
uninstallUpdatesItem, mAppsControlDisallowedAdmin);
}
}
diff --git a/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceController.java
index ec6ea8c..9e76ff5 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceController.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceController.java
@@ -111,7 +111,7 @@
final List<ResolveInfo> candidates = new ArrayList<>();
// Resolve that intent and check that the handleAllWebDataURI boolean is set
final List<ResolveInfo> list = packageManager.queryIntentActivitiesAsUser(
- BROWSE_PROBE, PackageManager.MATCH_ALL, userId);
+ BROWSE_PROBE, 0 /* flags */, userId);
if (list != null) {
final Set<String> addedPackages = new ArraySet<>();
for (ResolveInfo info : list) {
@@ -181,13 +181,12 @@
* Whether or not the pkg is the default browser
*/
public boolean isBrowserDefault(String pkg, int userId) {
- String defaultPackage = mPackageManager.getDefaultBrowserPackageNameAsUser(userId);
+ final String defaultPackage = mPackageManager.getDefaultBrowserPackageNameAsUser(userId);
if (defaultPackage != null) {
return defaultPackage.equals(pkg);
}
- final List<ResolveInfo> list = mPackageManager.queryIntentActivitiesAsUser(BROWSE_PROBE,
- PackageManager.MATCH_ALL, userId);
+ final List<ResolveInfo> list = getCandidates(mPackageManager, userId);
// There is only 1 app, it must be the default browser.
return list != null && list.size() == 1;
}
diff --git a/src/com/android/settings/applications/manageapplications/ApplicationViewHolder.java b/src/com/android/settings/applications/manageapplications/ApplicationViewHolder.java
index 021a953..e46f294 100644
--- a/src/com/android/settings/applications/manageapplications/ApplicationViewHolder.java
+++ b/src/com/android/settings/applications/manageapplications/ApplicationViewHolder.java
@@ -73,8 +73,8 @@
static View newView(ViewGroup parent, boolean twoTarget) {
ViewGroup view = (ViewGroup) LayoutInflater.from(parent.getContext())
.inflate(R.layout.preference_app, parent, false);
+ final ViewGroup widgetFrame = view.findViewById(android.R.id.widget_frame);
if (twoTarget) {
- final ViewGroup widgetFrame = view.findViewById(android.R.id.widget_frame);
if (widgetFrame != null) {
LayoutInflater.from(parent.getContext())
.inflate(R.layout.preference_widget_master_switch, widgetFrame, true);
@@ -84,6 +84,8 @@
// second to last, before widget frame
view.addView(divider, view.getChildCount() - 1);
}
+ } else if (widgetFrame != null) {
+ widgetFrame.setVisibility(View.GONE);
}
return view;
}
diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java
index 553680f..7c05bab 100644
--- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java
+++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java
@@ -67,6 +67,7 @@
import com.android.settings.users.UserDialogs;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import org.xmlpull.v1.XmlPullParserException;
@@ -645,12 +646,12 @@
private EnforcedAdmin getAdminEnforcingCantRemoveProfile() {
// Removing a managed profile is disallowed if DISALLOW_REMOVE_MANAGED_PROFILE
// is set in the parent rather than the user itself.
- return RestrictedLockUtils.checkIfRestrictionEnforced(this,
+ return RestrictedLockUtilsInternal.checkIfRestrictionEnforced(this,
UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, getParentUserId());
}
private boolean hasBaseCantRemoveProfileRestriction() {
- return RestrictedLockUtils.hasBaseUserRestriction(this,
+ return RestrictedLockUtilsInternal.hasBaseUserRestriction(this,
UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, getParentUserId());
}
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
index cd04b22..c718dde 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
@@ -28,7 +28,7 @@
import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricEnrollIntroduction;
import com.android.settings.password.ChooseLockSettingsHelper;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.setupwizardlib.span.LinkSpan;
public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
@@ -45,7 +45,7 @@
@Override
protected boolean isDisabledByAdmin() {
- return RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
+ return RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
this, DevicePolicyManager.KEYGUARD_DISABLE_FACE, mUserId) != null;
}
diff --git a/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java b/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java
index 9a14660..cd27dbb 100644
--- a/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java
@@ -46,7 +46,7 @@
@Override
protected boolean hasEnrolledBiometrics() {
- return mFaceManager.hasEnrolledFaces(mUserId);
+ return mFaceManager.hasEnrolledTemplates(mUserId);
}
@Override
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
index 41bf86f..241545d 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
@@ -31,7 +31,7 @@
import com.android.settings.biometrics.BiometricEnrollIntroduction;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settingslib.HelpUtils;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.setupwizardlib.span.LinkSpan;
public class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction {
@@ -48,7 +48,7 @@
@Override
protected boolean isDisabledByAdmin() {
- return RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
+ return RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
this, DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT, mUserId) != null;
}
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
index b7c5506..c3bd043 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
@@ -58,6 +58,7 @@
import com.android.settingslib.HelpUtils;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.TwoTargetPreference;
import com.android.settingslib.widget.FooterPreference;
@@ -319,7 +320,7 @@
}
final FooterPreference pref = mFooterPreferenceMixin.createFooterPreference();
- final EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
+ final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
activity, DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT, mUserId);
final AnnotationSpan.LinkInfo adminLinkInfo = new AnnotationSpan.LinkInfo(
ANNOTATION_ADMIN_DETAILS, (view) -> {
diff --git a/src/com/android/settings/bluetooth/RestrictionUtils.java b/src/com/android/settings/bluetooth/RestrictionUtils.java
index 9c0c481..21b00cd 100644
--- a/src/com/android/settings/bluetooth/RestrictionUtils.java
+++ b/src/com/android/settings/bluetooth/RestrictionUtils.java
@@ -19,8 +19,8 @@
import android.content.Context;
import android.os.UserHandle;
-import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedLockUtilsInternal;
/**
* A utility class to aid testing.
@@ -36,7 +36,7 @@
* API.
*/
public EnforcedAdmin checkIfRestrictionEnforced(Context context, String restriction) {
- return RestrictedLockUtils.checkIfRestrictionEnforced(
+ return RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
context, restriction, UserHandle.myUserId());
}
diff --git a/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java b/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java
index 4b717e0..936a4c0 100644
--- a/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java
+++ b/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java
@@ -17,7 +17,6 @@
package com.android.settings.connecteddevice.usb;
import android.content.Context;
-import android.os.Bundle;
import android.provider.SearchIndexableResource;
import androidx.annotation.VisibleForTesting;
@@ -71,15 +70,6 @@
}
@Override
- public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
- super.onCreatePreferences(savedInstanceState, rootKey);
- }
-
- public boolean isConnected() {
- return mUsbReceiver.isConnected();
- }
-
- @Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
mUsbBackend = new UsbBackend(context);
mControllers = createControllerList(context, mUsbBackend, this);
diff --git a/src/com/android/settings/core/FeatureFlags.java b/src/com/android/settings/core/FeatureFlags.java
index 08b4e82..0fe37e9 100644
--- a/src/com/android/settings/core/FeatureFlags.java
+++ b/src/com/android/settings/core/FeatureFlags.java
@@ -20,10 +20,10 @@
* This class keeps track of all feature flags in Settings.
*/
public class FeatureFlags {
- public static final String BATTERY_DISPLAY_APP_LIST = "settings_battery_display_app_list";
public static final String BLUETOOTH_WHILE_DRIVING = "settings_bluetooth_while_driving";
public static final String AUDIO_SWITCHER_SETTINGS = "settings_audio_switcher";
public static final String DYNAMIC_HOMEPAGE = "settings_dynamic_homepage";
public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
public static final String MOBILE_NETWORK_V2 = "settings_mobile_network_v2";
+ public static final String DATA_USAGE_V2 = "settings_data_usage_v2";
}
diff --git a/src/com/android/settings/dashboard/RestrictedDashboardFragment.java b/src/com/android/settings/dashboard/RestrictedDashboardFragment.java
index ab4127a..ca30247 100644
--- a/src/com/android/settings/dashboard/RestrictedDashboardFragment.java
+++ b/src/com/android/settings/dashboard/RestrictedDashboardFragment.java
@@ -36,7 +36,7 @@
import com.android.settings.R;
import com.android.settings.RestrictedSettingsFragment;
import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
/**
* Base class for settings screens that should be pin protected when in restricted mode or
@@ -213,7 +213,7 @@
}
public EnforcedAdmin getRestrictionEnforcedAdmin() {
- mEnforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(getActivity(),
+ mEnforcedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(getActivity(),
mRestrictionKey, UserHandle.myUserId());
if (mEnforcedAdmin != null && mEnforcedAdmin.userId == UserHandle.USER_NULL) {
mEnforcedAdmin.userId = UserHandle.myUserId();
diff --git a/src/com/android/settings/datausage/AppDataUsage.java b/src/com/android/settings/datausage/AppDataUsage.java
index ff89a11..fcb6b72 100644
--- a/src/com/android/settings/datausage/AppDataUsage.java
+++ b/src/com/android/settings/datausage/AppDataUsage.java
@@ -40,6 +40,7 @@
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.preference.Preference;
+import androidx.preference.Preference.OnPreferenceChangeListener;
import androidx.preference.PreferenceCategory;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -47,15 +48,15 @@
import com.android.settings.applications.AppInfoBase;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.AppItem;
-import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.net.ChartData;
import com.android.settingslib.net.ChartDataLoaderCompat;
import com.android.settingslib.net.UidDetail;
import com.android.settingslib.net.UidDetailProvider;
-public class AppDataUsage extends DataUsageBase implements Preference.OnPreferenceChangeListener,
+public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceChangeListener,
DataSaverBackend.Listener {
private static final String TAG = "AppDataUsage";
@@ -137,7 +138,6 @@
addUid(mAppItem.uids.keyAt(i));
}
}
- addPreferencesFromResource(R.xml.app_data_usage);
mTotalUsage = findPreference(KEY_TOTAL_USAGE);
mForegroundUsage = findPreference(KEY_FOREGROUND_USAGE);
@@ -258,13 +258,23 @@
return super.onPreferenceTreeClick(preference);
}
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.app_data_usage;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
@VisibleForTesting
void updatePrefs() {
updatePrefs(getAppRestrictBackground(), getUnrestrictData());
}
private void updatePrefs(boolean restrictBackground, boolean unrestrictData) {
- final EnforcedAdmin admin = RestrictedLockUtils.checkIfMeteredDataRestricted(
+ final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfMeteredDataRestricted(
getContext(), mPackageName, UserHandle.getUserId(mAppItem.key));
if (mRestrictBackground != null) {
mRestrictBackground.setChecked(!restrictBackground);
diff --git a/src/com/android/settings/datausage/BillingCycleSettings.java b/src/com/android/settings/datausage/BillingCycleSettings.java
index de71572..2d96fe9 100644
--- a/src/com/android/settings/datausage/BillingCycleSettings.java
+++ b/src/com/android/settings/datausage/BillingCycleSettings.java
@@ -52,7 +52,7 @@
import java.util.List;
@SearchIndexable
-public class BillingCycleSettings extends DataUsageBase implements
+public class BillingCycleSettings extends DataUsageBaseFragment implements
Preference.OnPreferenceChangeListener, DataUsageEditController {
private static final String TAG = "BillingCycleSettings";
@@ -105,7 +105,6 @@
Bundle args = getArguments();
mNetworkTemplate = args.getParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE);
- addPreferencesFromResource(R.xml.billing_cycle);
mBillingCycle = findPreference(KEY_BILLING_CYCLE);
mEnableDataWarning = (SwitchPreference) findPreference(KEY_SET_DATA_WARNING);
mEnableDataWarning.setOnPreferenceChangeListener(this);
@@ -191,6 +190,16 @@
return MetricsEvent.BILLING_CYCLE;
}
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.billing_cycle;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
@VisibleForTesting
void setPolicyLimitBytes(long limitBytes) {
if (LOGD) Log.d(TAG, "setPolicyLimitBytes()");
diff --git a/src/com/android/settings/datausage/DataUsageBase.java b/src/com/android/settings/datausage/DataUsageBase.java
deleted file mode 100644
index c5df0bb..0000000
--- a/src/com/android/settings/datausage/DataUsageBase.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.settings.datausage;
-
-import android.content.Context;
-import android.net.INetworkStatsService;
-import android.net.NetworkPolicy;
-import android.net.NetworkPolicyManager;
-import android.os.Bundle;
-import android.os.INetworkManagementService;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.UserManager;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settingslib.NetworkPolicyEditor;
-
-/**
- * @deprecated please use {@link DataUsageBaseFragment} instead.
- */
-@Deprecated
-public abstract class DataUsageBase extends SettingsPreferenceFragment {
- private static final String TAG = "DataUsageBase";
- private static final String ETHERNET = "ethernet";
-
- protected final TemplatePreference.NetworkServices services =
- new TemplatePreference.NetworkServices();
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- final Context context = getActivity();
-
- services.mNetworkService = INetworkManagementService.Stub.asInterface(
- ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
- services.mStatsService = INetworkStatsService.Stub.asInterface(
- ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
- services.mPolicyManager = NetworkPolicyManager.from(context);
-
- services.mPolicyEditor = new NetworkPolicyEditor(services.mPolicyManager);
-
- services.mTelephonyManager = TelephonyManager.from(context);
- services.mSubscriptionManager = SubscriptionManager.from(context);
- services.mUserManager = UserManager.get(context);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- services.mPolicyEditor.read();
- }
-
- protected boolean isAdmin() {
- return services.mUserManager.isAdminUser();
- }
-
- protected boolean isMobileDataAvailable(int subId) {
- return services.mSubscriptionManager.getActiveSubscriptionInfo(subId) != null;
- }
-
- protected boolean isNetworkPolicyModifiable(NetworkPolicy policy, int subId) {
- return policy != null && isBandwidthControlEnabled() && services.mUserManager.isAdminUser()
- && isDataEnabled(subId);
- }
-
- private boolean isDataEnabled(int subId) {
- if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
- return true;
- }
- return services.mTelephonyManager.getDataEnabled(subId);
- }
-
- protected boolean isBandwidthControlEnabled() {
- try {
- return services.mNetworkService.isBandwidthControlEnabled();
- } catch (RemoteException e) {
- Log.w(TAG, "problem talking with INetworkManagementService: ", e);
- return false;
- }
- }
-}
diff --git a/src/com/android/settings/datausage/DataUsageList.java b/src/com/android/settings/datausage/DataUsageList.java
index 755eee3..057cdd7 100644
--- a/src/com/android/settings/datausage/DataUsageList.java
+++ b/src/com/android/settings/datausage/DataUsageList.java
@@ -75,13 +75,18 @@
/**
* Panel showing data usage history across various networks, including options
* to inspect based on usage cycle and control through {@link NetworkPolicy}.
+
+ * Deprecated in favor of {@link DataUsageListV2}
+ *
+ * @deprecated
*/
-public class DataUsageList extends DataUsageBase {
+@Deprecated
+public class DataUsageList extends DataUsageBaseFragment {
public static final String EXTRA_SUB_ID = "sub_id";
public static final String EXTRA_NETWORK_TEMPLATE = "network_template";
- private static final String TAG = "DataUsage";
+ private static final String TAG = "DataUsageList";
private static final boolean LOGD = false;
private static final String KEY_USAGE_AMOUNT = "usage_amount";
@@ -140,7 +145,6 @@
mUidDetailProvider = new UidDetailProvider(context);
- addPreferencesFromResource(R.xml.data_usage_list);
mUsageAmount = findPreference(KEY_USAGE_AMOUNT);
mChart = (ChartDataUsagePreference) findPreference(KEY_CHART_DATA);
mApps = (PreferenceGroup) findPreference(KEY_APPS_GROUP);
@@ -235,6 +239,16 @@
super.onDestroy();
}
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.data_usage_list;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
void processArgument() {
final Bundle args = getArguments();
if (args != null) {
diff --git a/src/com/android/settings/datausage/DataUsageListV2.java b/src/com/android/settings/datausage/DataUsageListV2.java
new file mode 100644
index 0000000..fd20e23
--- /dev/null
+++ b/src/com/android/settings/datausage/DataUsageListV2.java
@@ -0,0 +1,615 @@
+/*
+ * 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.datausage;
+
+import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
+import static android.net.TrafficStats.UID_REMOVED;
+import static android.net.TrafficStats.UID_TETHERING;
+import static android.telephony.TelephonyManager.SIM_STATE_READY;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.UserInfo;
+import android.graphics.Color;
+import android.net.ConnectivityManager;
+import android.net.INetworkStatsSession;
+import android.net.NetworkPolicy;
+import android.net.NetworkStats;
+import android.net.NetworkStatsHistory;
+import android.net.NetworkTemplate;
+import android.net.TrafficStats;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.format.DateUtils;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ImageView;
+import android.widget.Spinner;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.loader.app.LoaderManager.LoaderCallbacks;
+import androidx.loader.content.Loader;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceGroup;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.datausage.CycleAdapter.SpinnerInterface;
+import com.android.settings.widget.LoadingViewController;
+import com.android.settingslib.AppItem;
+import com.android.settingslib.net.ChartData;
+import com.android.settingslib.net.ChartDataLoaderCompat;
+import com.android.settingslib.net.SummaryForAllUidLoaderCompat;
+import com.android.settingslib.net.UidDetailProvider;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Panel showing data usage history across various networks, including options
+ * to inspect based on usage cycle and control through {@link NetworkPolicy}.
+ */
+public class DataUsageListV2 extends DataUsageBaseFragment {
+
+ public static final String EXTRA_SUB_ID = "sub_id";
+ public static final String EXTRA_NETWORK_TEMPLATE = "network_template";
+
+ private static final String TAG = "DataUsageListV2";
+ private static final boolean LOGD = false;
+
+ private static final String KEY_USAGE_AMOUNT = "usage_amount";
+ private static final String KEY_CHART_DATA = "chart_data";
+ private static final String KEY_APPS_GROUP = "apps_group";
+
+ private static final int LOADER_CHART_DATA = 2;
+ private static final int LOADER_SUMMARY = 3;
+
+ private final CellDataPreference.DataStateListener mDataStateListener =
+ new CellDataPreference.DataStateListener() {
+ @Override
+ public void onChange(boolean selfChange) {
+ updatePolicy();
+ }
+ };
+
+ private INetworkStatsSession mStatsSession;
+ private ChartDataUsagePreference mChart;
+
+ @VisibleForTesting
+ NetworkTemplate mTemplate;
+ @VisibleForTesting
+ int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ private ChartData mChartData;
+
+ private LoadingViewController mLoadingViewController;
+ private UidDetailProvider mUidDetailProvider;
+ private CycleAdapter mCycleAdapter;
+ private Spinner mCycleSpinner;
+ private Preference mUsageAmount;
+ private PreferenceGroup mApps;
+ private View mHeader;
+
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.DATA_USAGE_LIST;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ final Context context = getActivity();
+
+ if (!isBandwidthControlEnabled()) {
+ Log.w(TAG, "No bandwidth control; leaving");
+ getActivity().finish();
+ }
+
+ try {
+ mStatsSession = services.mStatsService.openSession();
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+
+ mUidDetailProvider = new UidDetailProvider(context);
+
+ mUsageAmount = findPreference(KEY_USAGE_AMOUNT);
+ mChart = (ChartDataUsagePreference) findPreference(KEY_CHART_DATA);
+ mApps = (PreferenceGroup) findPreference(KEY_APPS_GROUP);
+ processArgument();
+ }
+
+ @Override
+ public void onViewCreated(View v, Bundle savedInstanceState) {
+ super.onViewCreated(v, savedInstanceState);
+
+ mHeader = setPinnedHeaderView(R.layout.apps_filter_spinner);
+ mHeader.findViewById(R.id.filter_settings).setOnClickListener(btn -> {
+ final Bundle args = new Bundle();
+ args.putParcelable(DataUsageListV2.EXTRA_NETWORK_TEMPLATE, mTemplate);
+ new SubSettingLauncher(getContext())
+ .setDestination(BillingCycleSettings.class.getName())
+ .setTitleRes(R.string.billing_cycle)
+ .setSourceMetricsCategory(getMetricsCategory())
+ .setArguments(args)
+ .launch();
+ });
+ mCycleSpinner = mHeader.findViewById(R.id.filter_spinner);
+ mCycleAdapter = new CycleAdapter(mCycleSpinner.getContext(), new SpinnerInterface() {
+ @Override
+ public void setAdapter(CycleAdapter cycleAdapter) {
+ mCycleSpinner.setAdapter(cycleAdapter);
+ }
+
+ @Override
+ public void setOnItemSelectedListener(OnItemSelectedListener listener) {
+ mCycleSpinner.setOnItemSelectedListener(listener);
+ }
+
+ @Override
+ public Object getSelectedItem() {
+ return mCycleSpinner.getSelectedItem();
+ }
+
+ @Override
+ public void setSelection(int position) {
+ mCycleSpinner.setSelection(position);
+ }
+ }, mCycleListener, true);
+
+ mLoadingViewController = new LoadingViewController(
+ getView().findViewById(R.id.loading_container), getListView());
+ mLoadingViewController.showLoadingViewDelayed();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mDataStateListener.setListener(true, mSubId, getContext());
+ updateBody();
+
+ // kick off background task to update stats
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ try {
+ // wait a few seconds before kicking off
+ Thread.sleep(2 * DateUtils.SECOND_IN_MILLIS);
+ services.mStatsService.forceUpdate();
+ } catch (InterruptedException e) {
+ } catch (RemoteException e) {
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void result) {
+ if (isAdded()) {
+ updateBody();
+ }
+ }
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mDataStateListener.setListener(false, mSubId, getContext());
+ }
+
+ @Override
+ public void onDestroy() {
+ mUidDetailProvider.clearCache();
+ mUidDetailProvider = null;
+
+ TrafficStats.closeQuietly(mStatsSession);
+
+ super.onDestroy();
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.data_usage_list;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ void processArgument() {
+ final Bundle args = getArguments();
+ if (args != null) {
+ mSubId = args.getInt(EXTRA_SUB_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ mTemplate = args.getParcelable(EXTRA_NETWORK_TEMPLATE);
+ }
+ if (mTemplate == null && mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ final Intent intent = getIntent();
+ mSubId = intent.getIntExtra(Settings.EXTRA_SUB_ID,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ mTemplate = intent.getParcelableExtra(Settings.EXTRA_NETWORK_TEMPLATE);
+ }
+ }
+
+ /**
+ * Update body content based on current tab. Loads
+ * {@link NetworkStatsHistory} and {@link NetworkPolicy} from system, and
+ * binds them to visible controls.
+ */
+ private void updateBody() {
+ if (!isAdded()) return;
+
+ final Context context = getActivity();
+
+ // kick off loader for network history
+ // TODO: consider chaining two loaders together instead of reloading
+ // network history when showing app detail.
+ getLoaderManager().restartLoader(LOADER_CHART_DATA,
+ ChartDataLoaderCompat.buildArgs(mTemplate, null), mChartDataCallbacks);
+
+ // detail mode can change visible menus, invalidate
+ getActivity().invalidateOptionsMenu();
+
+ int seriesColor = context.getColor(R.color.sim_noitification);
+ if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ final SubscriptionInfo sir = services.mSubscriptionManager
+ .getActiveSubscriptionInfo(mSubId);
+
+ if (sir != null) {
+ seriesColor = sir.getIconTint();
+ }
+ }
+
+ final int secondaryColor = Color.argb(127, Color.red(seriesColor), Color.green(seriesColor),
+ Color.blue(seriesColor));
+ mChart.setColors(seriesColor, secondaryColor);
+ }
+
+ /**
+ * Update chart sweeps and cycle list to reflect {@link NetworkPolicy} for
+ * current {@link #mTemplate}.
+ */
+ private void updatePolicy() {
+ final NetworkPolicy policy = services.mPolicyEditor.getPolicy(mTemplate);
+ final View configureButton = mHeader.findViewById(R.id.filter_settings);
+ //SUB SELECT
+ if (isNetworkPolicyModifiable(policy, mSubId) && isMobileDataAvailable(mSubId)) {
+ mChart.setNetworkPolicy(policy);
+ configureButton.setVisibility(View.VISIBLE);
+ ((ImageView) configureButton).setColorFilter(android.R.color.white);
+ } else {
+ // controls are disabled; don't bind warning/limit sweeps
+ mChart.setNetworkPolicy(null);
+ configureButton.setVisibility(View.GONE);
+ }
+
+ // generate cycle list based on policy and available history
+ if (mCycleAdapter.updateCycleList(policy, mChartData)) {
+ updateDetailData();
+ }
+ }
+
+ /**
+ * Update details based on {@link #mChart} inspection range depending on
+ * current mode. Updates {@link #mAdapter} with sorted list
+ * of applications data usage.
+ */
+ private void updateDetailData() {
+ if (LOGD) Log.d(TAG, "updateDetailData()");
+
+ final long start = mChart.getInspectStart();
+ final long end = mChart.getInspectEnd();
+ final long now = System.currentTimeMillis();
+
+ final Context context = getActivity();
+
+ NetworkStatsHistory.Entry entry = null;
+ if (mChartData != null) {
+ entry = mChartData.network.getValues(start, end, now, null);
+ }
+
+ // kick off loader for detailed stats
+ getLoaderManager().restartLoader(LOADER_SUMMARY,
+ SummaryForAllUidLoaderCompat.buildArgs(mTemplate, start, end), mSummaryCallbacks);
+
+ final long totalBytes = entry != null ? entry.rxBytes + entry.txBytes : 0;
+ final CharSequence totalPhrase = DataUsageUtils.formatDataUsage(context, totalBytes);
+ mUsageAmount.setTitle(getString(R.string.data_used_template, totalPhrase));
+ }
+
+ /**
+ * Bind the given {@link NetworkStats}, or {@code null} to clear list.
+ */
+ public void bindStats(NetworkStats stats, int[] restrictedUids) {
+ ArrayList<AppItem> items = new ArrayList<>();
+ long largest = 0;
+
+ final int currentUserId = ActivityManager.getCurrentUser();
+ UserManager userManager = UserManager.get(getContext());
+ final List<UserHandle> profiles = userManager.getUserProfiles();
+ final SparseArray<AppItem> knownItems = new SparseArray<AppItem>();
+
+ NetworkStats.Entry entry = null;
+ final int size = stats != null ? stats.size() : 0;
+ for (int i = 0; i < size; i++) {
+ entry = stats.getValues(i, entry);
+
+ // Decide how to collapse items together
+ final int uid = entry.uid;
+
+ final int collapseKey;
+ final int category;
+ final int userId = UserHandle.getUserId(uid);
+ if (UserHandle.isApp(uid)) {
+ if (profiles.contains(new UserHandle(userId))) {
+ if (userId != currentUserId) {
+ // Add to a managed user item.
+ final int managedKey = UidDetailProvider.buildKeyForUser(userId);
+ largest = accumulate(managedKey, knownItems, entry, AppItem.CATEGORY_USER,
+ items, largest);
+ }
+ // Add to app item.
+ collapseKey = uid;
+ category = AppItem.CATEGORY_APP;
+ } else {
+ // If it is a removed user add it to the removed users' key
+ final UserInfo info = userManager.getUserInfo(userId);
+ if (info == null) {
+ collapseKey = UID_REMOVED;
+ category = AppItem.CATEGORY_APP;
+ } else {
+ // Add to other user item.
+ collapseKey = UidDetailProvider.buildKeyForUser(userId);
+ category = AppItem.CATEGORY_USER;
+ }
+ }
+ } else if (uid == UID_REMOVED || uid == UID_TETHERING) {
+ collapseKey = uid;
+ category = AppItem.CATEGORY_APP;
+ } else {
+ collapseKey = android.os.Process.SYSTEM_UID;
+ category = AppItem.CATEGORY_APP;
+ }
+ largest = accumulate(collapseKey, knownItems, entry, category, items, largest);
+ }
+
+ final int restrictedUidsMax = restrictedUids.length;
+ for (int i = 0; i < restrictedUidsMax; ++i) {
+ final int uid = restrictedUids[i];
+ // Only splice in restricted state for current user or managed users
+ if (!profiles.contains(new UserHandle(UserHandle.getUserId(uid)))) {
+ continue;
+ }
+
+ AppItem item = knownItems.get(uid);
+ if (item == null) {
+ item = new AppItem(uid);
+ item.total = -1;
+ items.add(item);
+ knownItems.put(item.key, item);
+ }
+ item.restricted = true;
+ }
+
+ Collections.sort(items);
+ mApps.removeAll();
+ for (int i = 0; i < items.size(); i++) {
+ final int percentTotal = largest != 0 ? (int) (items.get(i).total * 100 / largest) : 0;
+ AppDataUsagePreference preference = new AppDataUsagePreference(getContext(),
+ items.get(i), percentTotal, mUidDetailProvider);
+ preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ AppDataUsagePreference pref = (AppDataUsagePreference) preference;
+ AppItem item = pref.getItem();
+ startAppDataUsage(item);
+ return true;
+ }
+ });
+ mApps.addPreference(preference);
+ }
+ }
+
+ private void startAppDataUsage(AppItem item) {
+ final Bundle args = new Bundle();
+ args.putParcelable(AppDataUsage.ARG_APP_ITEM, item);
+ args.putParcelable(AppDataUsage.ARG_NETWORK_TEMPLATE, mTemplate);
+
+ new SubSettingLauncher(getContext())
+ .setDestination(AppDataUsage.class.getName())
+ .setTitleRes(R.string.app_data_usage)
+ .setArguments(args)
+ .setSourceMetricsCategory(getMetricsCategory())
+ .launch();
+ }
+
+ /**
+ * Accumulate data usage of a network stats entry for the item mapped by the collapse key.
+ * Creates the item if needed.
+ *
+ * @param collapseKey the collapse key used to map the item.
+ * @param knownItems collection of known (already existing) items.
+ * @param entry the network stats entry to extract data usage from.
+ * @param itemCategory the item is categorized on the list view by this category. Must be
+ */
+ private static long accumulate(int collapseKey, final SparseArray<AppItem> knownItems,
+ NetworkStats.Entry entry, int itemCategory, ArrayList<AppItem> items, long largest) {
+ final int uid = entry.uid;
+ AppItem item = knownItems.get(collapseKey);
+ if (item == null) {
+ item = new AppItem(collapseKey);
+ item.category = itemCategory;
+ items.add(item);
+ knownItems.put(item.key, item);
+ }
+ item.addUid(uid);
+ item.total += entry.rxBytes + entry.txBytes;
+ return Math.max(largest, item.total);
+ }
+
+ /**
+ * Test if device has a mobile data radio with SIM in ready state.
+ */
+ public static boolean hasReadyMobileRadio(Context context) {
+ if (DataUsageUtils.TEST_RADIOS) {
+ return SystemProperties.get(DataUsageUtils.TEST_RADIOS_PROP).contains("mobile");
+ }
+
+ final ConnectivityManager conn = ConnectivityManager.from(context);
+ final TelephonyManager tele = TelephonyManager.from(context);
+
+ final List<SubscriptionInfo> subInfoList =
+ SubscriptionManager.from(context).getActiveSubscriptionInfoList();
+ // No activated Subscriptions
+ if (subInfoList == null) {
+ if (LOGD) Log.d(TAG, "hasReadyMobileRadio: subInfoList=null");
+ return false;
+ }
+ // require both supported network and ready SIM
+ boolean isReady = true;
+ for (SubscriptionInfo subInfo : subInfoList) {
+ isReady = isReady & tele.getSimState(subInfo.getSimSlotIndex()) == SIM_STATE_READY;
+ if (LOGD) Log.d(TAG, "hasReadyMobileRadio: subInfo=" + subInfo);
+ }
+ boolean retVal = conn.isNetworkSupported(TYPE_MOBILE) && isReady;
+ if (LOGD) {
+ Log.d(TAG, "hasReadyMobileRadio:"
+ + " conn.isNetworkSupported(TYPE_MOBILE)="
+ + conn.isNetworkSupported(TYPE_MOBILE)
+ + " isReady=" + isReady);
+ }
+ return retVal;
+ }
+
+ /*
+ * TODO: consider adding to TelephonyManager or SubscriptionManager.
+ */
+ public static boolean hasReadyMobileRadio(Context context, int subId) {
+ if (DataUsageUtils.TEST_RADIOS) {
+ return SystemProperties.get(DataUsageUtils.TEST_RADIOS_PROP).contains("mobile");
+ }
+
+ final ConnectivityManager conn = ConnectivityManager.from(context);
+ final TelephonyManager tele = TelephonyManager.from(context);
+ final int slotId = SubscriptionManager.getSlotIndex(subId);
+ final boolean isReady = tele.getSimState(slotId) == SIM_STATE_READY;
+
+ boolean retVal = conn.isNetworkSupported(TYPE_MOBILE) && isReady;
+ if (LOGD) {
+ Log.d(TAG, "hasReadyMobileRadio: subId=" + subId
+ + " conn.isNetworkSupported(TYPE_MOBILE)="
+ + conn.isNetworkSupported(TYPE_MOBILE)
+ + " isReady=" + isReady);
+ }
+ return retVal;
+ }
+
+ private OnItemSelectedListener mCycleListener = new OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ final CycleAdapter.CycleItem cycle = (CycleAdapter.CycleItem)
+ mCycleSpinner.getSelectedItem();
+
+ if (LOGD) {
+ Log.d(TAG, "showing cycle " + cycle + ", start=" + cycle.start + ", end="
+ + cycle.end + "]");
+ }
+
+ // update chart to show selected cycle, and update detail data
+ // to match updated sweep bounds.
+ mChart.setVisibleRange(cycle.start, cycle.end);
+
+ updateDetailData();
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ // ignored
+ }
+ };
+
+ private final LoaderCallbacks<ChartData> mChartDataCallbacks = new LoaderCallbacks<
+ ChartData>() {
+ @Override
+ public Loader<ChartData> onCreateLoader(int id, Bundle args) {
+ return new ChartDataLoaderCompat(getActivity(), mStatsSession, args);
+ }
+
+ @Override
+ public void onLoadFinished(Loader<ChartData> loader, ChartData data) {
+ mLoadingViewController.showContent(false /* animate */);
+ mChartData = data;
+ mChart.setNetworkStats(mChartData.network);
+
+ // calculate policy cycles based on available data
+ updatePolicy();
+ }
+
+ @Override
+ public void onLoaderReset(Loader<ChartData> loader) {
+ mChartData = null;
+ mChart.setNetworkStats(null);
+ }
+ };
+
+ private final LoaderCallbacks<NetworkStats> mSummaryCallbacks = new LoaderCallbacks<
+ NetworkStats>() {
+ @Override
+ public Loader<NetworkStats> onCreateLoader(int id, Bundle args) {
+ return new SummaryForAllUidLoaderCompat(getActivity(), mStatsSession, args);
+ }
+
+ @Override
+ public void onLoadFinished(Loader<NetworkStats> loader, NetworkStats data) {
+ final int[] restrictedUids = services.mPolicyManager.getUidsWithPolicy(
+ POLICY_REJECT_METERED_BACKGROUND);
+ bindStats(data, restrictedUids);
+ updateEmptyVisible();
+ }
+
+ @Override
+ public void onLoaderReset(Loader<NetworkStats> loader) {
+ bindStats(null, new int[0]);
+ updateEmptyVisible();
+ }
+
+ private void updateEmptyVisible() {
+ if ((mApps.getPreferenceCount() != 0) !=
+ (getPreferenceScreen().getPreferenceCount() != 0)) {
+ if (mApps.getPreferenceCount() != 0) {
+ getPreferenceScreen().addPreference(mUsageAmount);
+ getPreferenceScreen().addPreference(mApps);
+ } else {
+ getPreferenceScreen().removeAll();
+ }
+ }
+ }
+ };
+}
diff --git a/src/com/android/settings/datausage/DataUsagePreference.java b/src/com/android/settings/datausage/DataUsagePreference.java
index fd5c44e..cdec619 100644
--- a/src/com/android/settings/datausage/DataUsagePreference.java
+++ b/src/com/android/settings/datausage/DataUsagePreference.java
@@ -20,6 +20,7 @@
import android.net.NetworkTemplate;
import android.os.Bundle;
import android.util.AttributeSet;
+import android.util.FeatureFlagUtils;
import androidx.annotation.VisibleForTesting;
import androidx.core.content.res.TypedArrayUtils;
@@ -27,6 +28,7 @@
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
+import com.android.settings.core.FeatureFlags;
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.net.DataUsageController;
@@ -75,12 +77,22 @@
@Override
public Intent getIntent() {
final Bundle args = new Bundle();
- args.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE, mTemplate);
- args.putInt(DataUsageList.EXTRA_SUB_ID, mSubId);
- final SubSettingLauncher launcher = new SubSettingLauncher(getContext())
+ final SubSettingLauncher launcher;
+ if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.DATA_USAGE_V2)) {
+ args.putParcelable(DataUsageListV2.EXTRA_NETWORK_TEMPLATE, mTemplate);
+ args.putInt(DataUsageListV2.EXTRA_SUB_ID, mSubId);
+ launcher = new SubSettingLauncher(getContext())
+ .setArguments(args)
+ .setDestination(DataUsageListV2.class.getName())
+ .setSourceMetricsCategory(MetricsProto.MetricsEvent.VIEW_UNKNOWN);
+ } else {
+ args.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE, mTemplate);
+ args.putInt(DataUsageList.EXTRA_SUB_ID, mSubId);
+ launcher = new SubSettingLauncher(getContext())
.setArguments(args)
.setDestination(DataUsageList.class.getName())
.setSourceMetricsCategory(MetricsProto.MetricsEvent.VIEW_UNKNOWN);
+ }
if (mTemplate.isMatchRuleMobile()) {
launcher.setTitleRes(R.string.app_cellular_data_usage);
} else {
diff --git a/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java b/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java
index 2fefe01..824c102 100644
--- a/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java
+++ b/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java
@@ -13,7 +13,7 @@
*/
package com.android.settings.datausage;
-import static com.android.settingslib.RestrictedLockUtils.checkIfMeteredDataRestricted;
+import static com.android.settingslib.RestrictedLockUtilsInternal.checkIfMeteredDataRestricted;
import android.content.Context;
import android.os.UserHandle;
diff --git a/src/com/android/settings/datausage/UnrestrictedDataAccessPreferenceController.java b/src/com/android/settings/datausage/UnrestrictedDataAccessPreferenceController.java
index e47c7f8..efc20f0 100644
--- a/src/com/android/settings/datausage/UnrestrictedDataAccessPreferenceController.java
+++ b/src/com/android/settings/datausage/UnrestrictedDataAccessPreferenceController.java
@@ -13,7 +13,7 @@
*/
package com.android.settings.datausage;
-import static com.android.settingslib.RestrictedLockUtils.checkIfMeteredDataRestricted;
+import static com.android.settingslib.RestrictedLockUtilsInternal.checkIfMeteredDataRestricted;
import android.app.Application;
import android.content.Context;
diff --git a/src/com/android/settings/datetime/AutoTimePreferenceController.java b/src/com/android/settings/datetime/AutoTimePreferenceController.java
index 3916ef2..bf6ecb4 100644
--- a/src/com/android/settings/datetime/AutoTimePreferenceController.java
+++ b/src/com/android/settings/datetime/AutoTimePreferenceController.java
@@ -23,6 +23,7 @@
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -74,6 +75,6 @@
}
private RestrictedLockUtils.EnforcedAdmin getEnforcedAdminProperty() {
- return RestrictedLockUtils.checkIfAutoTimeRequired(mContext);
+ return RestrictedLockUtilsInternal.checkIfAutoTimeRequired(mContext);
}
}
diff --git a/src/com/android/settings/development/StayAwakePreferenceController.java b/src/com/android/settings/development/StayAwakePreferenceController.java
index 7d67b9e..4091537 100644
--- a/src/com/android/settings/development/StayAwakePreferenceController.java
+++ b/src/com/android/settings/development/StayAwakePreferenceController.java
@@ -30,6 +30,7 @@
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -130,7 +131,7 @@
// will lock... in this case we can't allow the user to turn
// on "stay awake when plugged in" because that would defeat the
// restriction.
- return RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(mContext);
+ return RestrictedLockUtilsInternal.checkIfMaximumTimeToLockIsSet(mContext);
}
@VisibleForTesting
diff --git a/src/com/android/settings/development/VerifyAppsOverUsbPreferenceController.java b/src/com/android/settings/development/VerifyAppsOverUsbPreferenceController.java
index 29653a0..20b8f1f 100644
--- a/src/com/android/settings/development/VerifyAppsOverUsbPreferenceController.java
+++ b/src/com/android/settings/development/VerifyAppsOverUsbPreferenceController.java
@@ -28,8 +28,8 @@
import androidx.preference.Preference;
import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
@@ -57,7 +57,8 @@
class RestrictedLockUtilsDelegate {
public EnforcedAdmin checkIfRestrictionEnforced(
Context context, String userRestriction, int userId) {
- return RestrictedLockUtils.checkIfRestrictionEnforced(context, userRestriction, userId);
+ return RestrictedLockUtilsInternal.checkIfRestrictionEnforced(context, userRestriction,
+ userId);
}
}
diff --git a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
index f6ef632..6256e23 100644
--- a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
@@ -40,6 +40,7 @@
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -104,9 +105,9 @@
@Override
public void onResume() {
- mDebuggingFeaturesDisallowedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(
+ mDebuggingFeaturesDisallowedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
mContext, UserManager.DISALLOW_DEBUGGING_FEATURES, UserHandle.myUserId());
- mDebuggingFeaturesDisallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(
+ mDebuggingFeaturesDisallowedBySystem = RestrictedLockUtilsInternal.hasBaseUserRestriction(
mContext, UserManager.DISALLOW_DEBUGGING_FEATURES, UserHandle.myUserId());
mDevHitCountdown = DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)
? -1 : TAPS_TO_BE_A_DEVELOPER;
diff --git a/src/com/android/settings/deviceinfo/DeviceNamePreferenceController.java b/src/com/android/settings/deviceinfo/DeviceNamePreferenceController.java
index 2720979..0d7b1d3 100644
--- a/src/com/android/settings/deviceinfo/DeviceNamePreferenceController.java
+++ b/src/com/android/settings/deviceinfo/DeviceNamePreferenceController.java
@@ -39,10 +39,10 @@
public class DeviceNamePreferenceController extends BasePreferenceController
implements ValidatedEditTextPreference.Validator,
- Preference.OnPreferenceChangeListener,
- LifecycleObserver,
- OnSaveInstanceState,
- OnCreate {
+ Preference.OnPreferenceChangeListener,
+ LifecycleObserver,
+ OnSaveInstanceState,
+ OnCreate {
private static final String PREF_KEY = "device_name";
public static final int DEVICE_NAME_SET_WARNING_ID = 1;
private static final String KEY_PENDING_DEVICE_NAME = "key_pending_device_name";
@@ -116,9 +116,11 @@
return mWifiDeviceNameTextValidator.isTextValid(deviceName);
}
- public void confirmDeviceName() {
- if (mPendingDeviceName != null) {
+ public void updateDeviceName(boolean update) {
+ if (update && mPendingDeviceName != null) {
setDeviceName(mPendingDeviceName);
+ } else {
+ mPreference.setText(getSummary().toString());
}
}
@@ -153,7 +155,8 @@
* For more information, see {@link com.android.settings.bluetooth.BluetoothNameDialogFragment}.
*/
private static final String getFilteredBluetoothString(final String deviceName) {
- CharSequence filteredSequence = new BluetoothLengthDeviceNameFilter().filter(deviceName, 0, deviceName.length(),
+ CharSequence filteredSequence = new BluetoothLengthDeviceNameFilter().filter(deviceName, 0,
+ deviceName.length(),
new SpannedString(""),
0, 0);
// null -> use the original
diff --git a/src/com/android/settings/deviceinfo/StorageSettings.java b/src/com/android/settings/deviceinfo/StorageSettings.java
index 415af58..58188f1 100644
--- a/src/com/android/settings/deviceinfo/StorageSettings.java
+++ b/src/com/android/settings/deviceinfo/StorageSettings.java
@@ -56,6 +56,7 @@
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.deviceinfo.PrivateStorageInfo;
import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
import com.android.settingslib.search.SearchIndexable;
@@ -460,10 +461,11 @@
* @return {@code true} iff a intent was shown.
*/
private boolean wasAdminSupportIntentShown(@NonNull String restriction) {
- EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(
- getActivity(), restriction, UserHandle.myUserId());
+ EnforcedAdmin admin = RestrictedLockUtilsInternal
+ .checkIfRestrictionEnforced(getActivity(), restriction,
+ UserHandle.myUserId());
boolean hasBaseUserRestriction =
- RestrictedLockUtils.hasBaseUserRestriction(
+ RestrictedLockUtilsInternal.hasBaseUserRestriction(
getActivity(), restriction, UserHandle.myUserId());
if (admin != null && !hasBaseUserRestriction) {
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getActivity(),
diff --git a/src/com/android/settings/deviceinfo/aboutphone/DeviceNameWarningDialog.java b/src/com/android/settings/deviceinfo/aboutphone/DeviceNameWarningDialog.java
index 5633c11..a6b1dec 100644
--- a/src/com/android/settings/deviceinfo/aboutphone/DeviceNameWarningDialog.java
+++ b/src/com/android/settings/deviceinfo/aboutphone/DeviceNameWarningDialog.java
@@ -66,7 +66,9 @@
public void onClick(DialogInterface dialog, int which) {
final MyDeviceInfoFragment host = (MyDeviceInfoFragment) getTargetFragment();
if (which == DialogInterface.BUTTON_POSITIVE) {
- host.onSetDeviceNameConfirm();
+ host.onSetDeviceNameConfirm(true);
+ } else {
+ host.onSetDeviceNameConfirm(false);
}
}
}
diff --git a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
index 3de46e01..5503ea9 100644
--- a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
+++ b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
@@ -178,9 +178,9 @@
DeviceNameWarningDialog.show(this);
}
- public void onSetDeviceNameConfirm() {
+ public void onSetDeviceNameConfirm(boolean confirm) {
final DeviceNamePreferenceController controller = use(DeviceNamePreferenceController.class);
- controller.confirmDeviceName();
+ controller.updateDeviceName(confirm);
}
private static class SummaryProvider implements SummaryLoader.SummaryProvider {
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDialogController.java b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDialogController.java
index 17415cc..8c29f7b 100644
--- a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDialogController.java
+++ b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDialogController.java
@@ -29,6 +29,7 @@
import com.android.settings.R;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
public class FirmwareVersionDialogController implements View.OnClickListener {
@@ -105,9 +106,9 @@
@VisibleForTesting
void initializeAdminPermissions() {
- mFunDisallowedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(
+ mFunDisallowedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
mContext, UserManager.DISALLOW_FUN, UserHandle.myUserId());
- mFunDisallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(
+ mFunDisallowedBySystem = RestrictedLockUtilsInternal.hasBaseUserRestriction(
mContext, UserManager.DISALLOW_FUN, UserHandle.myUserId());
}
}
diff --git a/src/com/android/settings/display/FontSizePreferenceController.java b/src/com/android/settings/display/FontSizePreferenceController.java
index a55d577..680e378 100644
--- a/src/com/android/settings/display/FontSizePreferenceController.java
+++ b/src/com/android/settings/display/FontSizePreferenceController.java
@@ -18,7 +18,6 @@
import android.provider.Settings;
import com.android.settings.R;
-import com.android.settings.accessibility.ToggleFontSizePreferenceFragment;
import com.android.settings.core.BasePreferenceController;
public class FontSizePreferenceController extends BasePreferenceController {
diff --git a/src/com/android/settings/accessibility/FontSizePreferenceFragmentForSetupWizard.java b/src/com/android/settings/display/FontSizePreferenceFragmentForSetupWizard.java
similarity index 92%
rename from src/com/android/settings/accessibility/FontSizePreferenceFragmentForSetupWizard.java
rename to src/com/android/settings/display/FontSizePreferenceFragmentForSetupWizard.java
index 8dfb2b4..703ec9c 100644
--- a/src/com/android/settings/accessibility/FontSizePreferenceFragmentForSetupWizard.java
+++ b/src/com/android/settings/display/FontSizePreferenceFragmentForSetupWizard.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.accessibility;
+package com.android.settings.display;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
diff --git a/src/com/android/settings/PreviewPagerAdapter.java b/src/com/android/settings/display/PreviewPagerAdapter.java
similarity index 82%
rename from src/com/android/settings/PreviewPagerAdapter.java
rename to src/com/android/settings/display/PreviewPagerAdapter.java
index 8d83cb4..4d5b47a 100644
--- a/src/com/android/settings/PreviewPagerAdapter.java
+++ b/src/com/android/settings/display/PreviewPagerAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.settings;
+package com.android.settings.display;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
@@ -32,6 +32,8 @@
import androidx.viewpager.widget.PagerAdapter;
+import com.android.settings.support.actionbar.HelpResourceProvider;
+
/**
* A PagerAdapter used by PreviewSeekBarPreferenceFragment that for showing multiple preview screen
* regarding a single setting and allowing the user to swipe across them.
@@ -76,16 +78,12 @@
final Context configContext = context.createConfigurationContext(configurations[j]);
configContext.getTheme().setTo(context.getTheme());
- final LayoutInflater configInflater = LayoutInflater.from(configContext);
final ViewStub sampleViewStub = new ViewStub(configContext);
sampleViewStub.setLayoutResource(previewSampleResIds[i]);
final int fi = i, fj = j;
- sampleViewStub.setOnInflateListener(new OnInflateListener() {
- @Override
- public void onInflate(ViewStub stub, View inflated) {
- inflated.setVisibility(stub.getVisibility());
- mViewStubInflated[fi][fj] = true;
- }
+ sampleViewStub.setOnInflateListener((stub, inflated) -> {
+ inflated.setVisibility(stub.getVisibility());
+ mViewStubInflated[fi][fj] = true;
});
mPreviewFrames[p].addView(sampleViewStub);
@@ -94,7 +92,7 @@
}
@Override
- public void destroyItem (ViewGroup container, int position, Object object) {
+ public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
@@ -164,29 +162,29 @@
if (visibility == View.VISIBLE) {
// Fade in animation.
view.animate()
- .alpha(alpha)
- .setInterpolator(FADE_IN_INTERPOLATOR)
- .setDuration(CROSS_FADE_DURATION_MS)
- .setListener(new PreviewFrameAnimatorListener())
- .withStartAction(new Runnable() {
- @Override
- public void run() {
- view.setVisibility(visibility);
- }
- });
+ .alpha(alpha)
+ .setInterpolator(FADE_IN_INTERPOLATOR)
+ .setDuration(CROSS_FADE_DURATION_MS)
+ .setListener(new PreviewFrameAnimatorListener())
+ .withStartAction(new Runnable() {
+ @Override
+ public void run() {
+ view.setVisibility(visibility);
+ }
+ });
} else {
// Fade out animation.
view.animate()
- .alpha(alpha)
- .setInterpolator(FADE_OUT_INTERPOLATOR)
- .setDuration(CROSS_FADE_DURATION_MS)
- .setListener(new PreviewFrameAnimatorListener())
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- view.setVisibility(visibility);
- }
- });
+ .alpha(alpha)
+ .setInterpolator(FADE_OUT_INTERPOLATOR)
+ .setDuration(CROSS_FADE_DURATION_MS)
+ .setListener(new PreviewFrameAnimatorListener())
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ view.setVisibility(visibility);
+ }
+ });
}
}
}
diff --git a/src/com/android/settings/PreviewSeekBarPreferenceFragment.java b/src/com/android/settings/display/PreviewSeekBarPreferenceFragment.java
similarity index 79%
rename from src/com/android/settings/PreviewSeekBarPreferenceFragment.java
rename to src/com/android/settings/display/PreviewSeekBarPreferenceFragment.java
index 164648f..bb9e3d7 100644
--- a/src/com/android/settings/PreviewSeekBarPreferenceFragment.java
+++ b/src/com/android/settings/display/PreviewSeekBarPreferenceFragment.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Android Open Source Project
+ * 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.
@@ -14,14 +14,13 @@
* limitations under the License.
*/
-package com.android.settings;
+package com.android.settings.display;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.widget.SeekBar;
@@ -31,6 +30,8 @@
import androidx.viewpager.widget.ViewPager;
import androidx.viewpager.widget.ViewPager.OnPageChangeListener;
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.widget.DotsPageIndicator;
import com.android.settings.widget.LabeledSeekBar;
@@ -48,12 +49,6 @@
/** Index of the entry corresponding to current value of the settings. */
protected int mCurrentIndex;
- /** Resource id of the layout for this preference fragment. */
- protected int mActivityLayoutResId;
-
- /** Resource id of the layout that defines the contents inside preview screen. */
- protected int[] mPreviewSampleResIds;
-
private ViewPager mPreviewPager;
private PreviewPagerAdapter mPreviewPagerAdapter;
private DotsPageIndicator mPageIndicator;
@@ -82,12 +77,7 @@
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
if (mPreviewPagerAdapter.isAnimating()) {
- mPreviewPagerAdapter.setAnimationEndAction(new Runnable() {
- @Override
- public void run() {
- commit();
- }
- });
+ mPreviewPagerAdapter.setAnimationEndAction(() -> commit());
} else {
commit();
}
@@ -102,39 +92,33 @@
final ViewGroup listContainer = root.findViewById(android.R.id.list_container);
listContainer.removeAllViews();
- final View content = inflater.inflate(mActivityLayoutResId, listContainer, false);
+ final View content = inflater.inflate(getActivityLayoutResId(), listContainer, false);
listContainer.addView(content);
- mLabel = (TextView) content.findViewById(R.id.current_label);
+ mLabel = content.findViewById(R.id.current_label);
// The maximum SeekBar value always needs to be non-zero. If there's
// only one available value, we'll handle this by disabling the
// seek bar.
final int max = Math.max(1, mEntries.length - 1);
- mSeekBar = (LabeledSeekBar) content.findViewById(R.id.seek_bar);
+ mSeekBar = content.findViewById(R.id.seek_bar);
mSeekBar.setLabels(mEntries);
mSeekBar.setMax(max);
mSmaller = content.findViewById(R.id.smaller);
- mSmaller.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- final int progress = mSeekBar.getProgress();
- if (progress > 0) {
- mSeekBar.setProgress(progress - 1, true);
- }
+ mSmaller.setOnClickListener(v -> {
+ final int progress = mSeekBar.getProgress();
+ if (progress > 0) {
+ mSeekBar.setProgress(progress - 1, true);
}
});
mLarger = content.findViewById(R.id.larger);
- mLarger.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- final int progress = mSeekBar.getProgress();
- if (progress < mSeekBar.getMax()) {
- mSeekBar.setProgress(progress + 1, true);
- }
+ mLarger.setOnClickListener(v -> {
+ final int progress = mSeekBar.getProgress();
+ if (progress < mSeekBar.getMax()) {
+ mSeekBar.setProgress(progress + 1, true);
}
});
@@ -152,15 +136,16 @@
configurations[i] = createConfig(origConfig, i);
}
- mPreviewPager = (ViewPager) content.findViewById(R.id.preview_pager);
+ final int[] previews = getPreviewSampleResIds();
+ mPreviewPager = content.findViewById(R.id.preview_pager);
mPreviewPagerAdapter = new PreviewPagerAdapter(context, isLayoutRtl,
- mPreviewSampleResIds, configurations);
+ previews, configurations);
mPreviewPager.setAdapter(mPreviewPagerAdapter);
- mPreviewPager.setCurrentItem(isLayoutRtl ? mPreviewSampleResIds.length - 1 : 0);
+ mPreviewPager.setCurrentItem(isLayoutRtl ? previews.length - 1 : 0);
mPreviewPager.addOnPageChangeListener(mPreviewPageChangeListener);
- mPageIndicator = (DotsPageIndicator) content.findViewById(R.id.page_indicator);
- if (mPreviewSampleResIds.length > 1) {
+ mPageIndicator = content.findViewById(R.id.page_indicator);
+ if (previews.length > 1) {
mPageIndicator.setViewPager(mPreviewPager);
mPageIndicator.setVisibility(View.VISIBLE);
mPageIndicator.setOnPageChangeListener(mPageIndicatorPageChangeListener);
@@ -187,6 +172,12 @@
mSeekBar.setOnSeekBarChangeListener(null);
}
+ /** Resource id of the layout for this preference fragment. */
+ protected abstract int getActivityLayoutResId();
+
+ /** Resource id of the layout that defines the contents inside preview screen. */
+ protected abstract int[] getPreviewSampleResIds();
+
/**
* Creates new configuration based on the current position of the SeekBar.
*/
@@ -210,8 +201,8 @@
private void setPagerIndicatorContentDescription(int position) {
mPageIndicator.setContentDescription(
- getPrefContext().getString(R.string.preview_page_indicator_content_description,
- position + 1, mPreviewSampleResIds.length));
+ getString(R.string.preview_page_indicator_content_description,
+ position + 1, getPreviewSampleResIds().length));
}
private OnPageChangeListener mPreviewPageChangeListener = new OnPageChangeListener() {
diff --git a/src/com/android/settings/display/ScreenZoomPreferenceFragmentForSetupWizard.java b/src/com/android/settings/display/ScreenZoomPreferenceFragmentForSetupWizard.java
index 82cb58d..e02579f 100644
--- a/src/com/android/settings/display/ScreenZoomPreferenceFragmentForSetupWizard.java
+++ b/src/com/android/settings/display/ScreenZoomPreferenceFragmentForSetupWizard.java
@@ -18,8 +18,7 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-public class ScreenZoomPreferenceFragmentForSetupWizard
- extends ScreenZoomSettings {
+public class ScreenZoomPreferenceFragmentForSetupWizard extends ScreenZoomSettings {
@Override
public int getMetricsCategory() {
diff --git a/src/com/android/settings/display/ScreenZoomSettings.java b/src/com/android/settings/display/ScreenZoomSettings.java
index dbb6353..37ac046 100644
--- a/src/com/android/settings/display/ScreenZoomSettings.java
+++ b/src/com/android/settings/display/ScreenZoomSettings.java
@@ -24,9 +24,9 @@
import android.view.Display;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.PreviewSeekBarPreferenceFragment;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
import com.android.settingslib.display.DisplayDensityUtils;
import com.android.settingslib.search.SearchIndexable;
@@ -44,16 +44,25 @@
private int[] mValues;
@Override
+ protected int getActivityLayoutResId() {
+ return R.layout.screen_zoom_activity;
+ }
+
+ @Override
+ protected int[] getPreviewSampleResIds() {
+ return getContext().getResources().getBoolean(
+ R.bool.config_enable_extra_screen_zoom_preview)
+ ? new int[]{
+ R.layout.screen_zoom_preview_1,
+ R.layout.screen_zoom_preview_2,
+ R.layout.screen_zoom_preview_settings}
+ : new int[]{R.layout.screen_zoom_preview_1};
+ }
+
+ @Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mActivityLayoutResId = R.layout.screen_zoom_activity;
-
- // This should be replaced once the final preview sample screen is in place.
- mPreviewSampleResIds = new int[] {R.layout.screen_zoom_preview_1,
- R.layout.screen_zoom_preview_2,
- R.layout.screen_zoom_preview_settings};
-
final DisplayDensityUtils density = new DisplayDensityUtils(getContext());
final int initialIndex = density.getCurrentIndex();
@@ -62,8 +71,8 @@
// connect to the window manager service. Just use the current
// density and don't let the user change anything.
final int densityDpi = getResources().getDisplayMetrics().densityDpi;
- mValues = new int[] {densityDpi};
- mEntries = new String[] {getString(DisplayDensityUtils.SUMMARY_DEFAULT)};
+ mValues = new int[]{densityDpi};
+ mEntries = new String[]{getString(DisplayDensityUtils.SUMMARY_DEFAULT)};
mInitialIndex = 0;
mDefaultDensity = densityDpi;
} else {
@@ -108,7 +117,7 @@
}
/** Index provider used to expose this fragment in search. */
- public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableRaw> getRawDataToIndex(Context context,
diff --git a/src/com/android/settings/display/TimeoutPreferenceController.java b/src/com/android/settings/display/TimeoutPreferenceController.java
index c068168..60b7e24 100644
--- a/src/com/android/settings/display/TimeoutPreferenceController.java
+++ b/src/com/android/settings/display/TimeoutPreferenceController.java
@@ -28,6 +28,7 @@
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.core.AbstractPreferenceController;
public class TimeoutPreferenceController extends AbstractPreferenceController implements
@@ -65,7 +66,7 @@
(DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
if (dpm != null) {
final RestrictedLockUtils.EnforcedAdmin admin =
- RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(mContext);
+ RestrictedLockUtilsInternal.checkIfMaximumTimeToLockIsSet(mContext);
final long maxTimeout =
dpm.getMaximumTimeToLock(null /* admin */, UserHandle.myUserId());
timeoutListPreference.removeUnusableTimeouts(maxTimeout, admin);
@@ -73,7 +74,7 @@
updateTimeoutPreferenceDescription(timeoutListPreference,
Long.parseLong(timeoutListPreference.getValue()));
- final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(
+ final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
mContext, UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT,
UserHandle.myUserId());
if (admin != null) {
diff --git a/src/com/android/settings/accessibility/ToggleFontSizePreferenceFragment.java b/src/com/android/settings/display/ToggleFontSizePreferenceFragment.java
similarity index 91%
rename from src/com/android/settings/accessibility/ToggleFontSizePreferenceFragment.java
rename to src/com/android/settings/display/ToggleFontSizePreferenceFragment.java
index c3100ee..4f118d5 100644
--- a/src/com/android/settings/accessibility/ToggleFontSizePreferenceFragment.java
+++ b/src/com/android/settings/display/ToggleFontSizePreferenceFragment.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.accessibility;
+package com.android.settings.display;
import android.annotation.Nullable;
import android.content.ContentResolver;
@@ -25,7 +25,6 @@
import android.provider.Settings;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.PreviewSeekBarPreferenceFragment;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
@@ -44,13 +43,20 @@
private float[] mValues;
@Override
+ protected int getActivityLayoutResId() {
+ return R.layout.font_size_activity;
+ }
+
+ @Override
+ protected int[] getPreviewSampleResIds() {
+ return new int[]{R.layout.font_size_preview};
+ }
+
+ @Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mActivityLayoutResId = R.layout.font_size_activity;
- mPreviewSampleResIds = new int[] {R.layout.font_size_preview};
-
- Resources res = getContext().getResources();
+ final Resources res = getContext().getResources();
final ContentResolver resolver = getContext().getContentResolver();
// Mark the appropriate item in the preferences list.
mEntries = res.getStringArray(R.array.entries_font_size);
diff --git a/src/com/android/settings/display/WallpaperPreferenceController.java b/src/com/android/settings/display/WallpaperPreferenceController.java
index 8e29004..ff3be12 100644
--- a/src/com/android/settings/display/WallpaperPreferenceController.java
+++ b/src/com/android/settings/display/WallpaperPreferenceController.java
@@ -28,7 +28,7 @@
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -80,7 +80,7 @@
final String restriction = DISALLOW_SET_WALLPAPER;
if (pref != null) {
pref.setDisabledByAdmin(null);
- if (RestrictedLockUtils.hasBaseUserRestriction(mContext,
+ if (RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext,
restriction, UserHandle.myUserId())) {
pref.setEnabled(false);
} else {
diff --git a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java
index 52bd4f5..ac1939c 100644
--- a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java
+++ b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java
@@ -41,6 +41,7 @@
import com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminAdd;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import java.util.Objects;
@@ -94,7 +95,7 @@
if (admin == null) {
return;
}
- if (!RestrictedLockUtils.isAdminInCurrentUserOrProfile(mActivity, admin)
+ if (!RestrictedLockUtilsInternal.isAdminInCurrentUserOrProfile(mActivity, admin)
|| !RestrictedLockUtils.isCurrentUserOrProfile(mActivity, userId)) {
admin = null;
} else {
@@ -136,9 +137,6 @@
case DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE:
titleView.setText(R.string.disabled_by_policy_title_screen_capture);
break;
- case DevicePolicyManager.POLICY_MANDATORY_BACKUPS:
- titleView.setText(R.string.disabled_by_policy_title_turn_off_backups);
- break;
case DevicePolicyManager.POLICY_SUSPEND_PACKAGES:
titleView.setText(R.string.disabled_by_policy_title_suspend_packages);
break;
@@ -156,7 +154,7 @@
}
final DevicePolicyManager dpm = (DevicePolicyManager) activity.getSystemService(
Context.DEVICE_POLICY_SERVICE);
- if (!RestrictedLockUtils.isAdminInCurrentUserOrProfile(activity,
+ if (!RestrictedLockUtilsInternal.isAdminInCurrentUserOrProfile(activity,
enforcedAdmin.component) || !RestrictedLockUtils.isCurrentUserOrProfile(
activity, enforcedAdmin.userId)) {
enforcedAdmin.component = null;
diff --git a/src/com/android/settings/enterprise/BackupsEnabledPreferenceController.java b/src/com/android/settings/enterprise/BackupsEnabledPreferenceController.java
deleted file mode 100644
index b24f8dc..0000000
--- a/src/com/android/settings/enterprise/BackupsEnabledPreferenceController.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.android.settings.enterprise;
-
-import android.content.Context;
-
-import com.android.settings.core.BasePreferenceController;
-import com.android.settings.overlay.FeatureFactory;
-
-public class BackupsEnabledPreferenceController extends BasePreferenceController {
-
- private static final String KEY_BACKUPS_ENABLED = "backups_enabled";
- private final EnterprisePrivacyFeatureProvider mFeatureProvider;
-
- public BackupsEnabledPreferenceController(Context context) {
- super(context, KEY_BACKUPS_ENABLED);
- mFeatureProvider = FeatureFactory.getFactory(context)
- .getEnterprisePrivacyFeatureProvider(context);
- }
-
- @Override
- public int getAvailabilityStatus() {
- return mFeatureProvider.areBackupsMandatory() ? AVAILABLE : DISABLED_FOR_USER;
- }
-}
-
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java
index 51d125d..048782e 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java
@@ -124,9 +124,4 @@
* profile (if any).
*/
int getNumberOfActiveDeviceAdminsForCurrentUserAndManagedProfile();
-
- /*
- * Returns whether backups are mandatory.
- */
- boolean areBackupsMandatory();
}
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
index 5505683..4085988 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
@@ -234,11 +234,6 @@
return activeAdmins;
}
- @Override
- public boolean areBackupsMandatory() {
- return null != mDpm.getMandatoryBackupTransport();
- }
-
protected static class EnterprisePrivacySpan extends ClickableSpan {
private final Context mContext;
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacySettings.java b/src/com/android/settings/enterprise/EnterprisePrivacySettings.java
index f04c421..dab1395 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacySettings.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacySettings.java
@@ -84,7 +84,6 @@
exposureChangesCategoryControllers.add(new CaCertsCurrentUserPreferenceController(context));
exposureChangesCategoryControllers.add(new CaCertsManagedProfilePreferenceController(
context));
- exposureChangesCategoryControllers.add(new BackupsEnabledPreferenceController(context));
controllers.addAll(exposureChangesCategoryControllers);
controllers.add(new PreferenceCategoryController(context, "exposure_changes_category")
.setChildren(exposureChangesCategoryControllers));
diff --git a/src/com/android/settings/fuelgauge/PowerGaugePreference.java b/src/com/android/settings/fuelgauge/PowerGaugePreference.java
index a2ceb67..7c21774 100644
--- a/src/com/android/settings/fuelgauge/PowerGaugePreference.java
+++ b/src/com/android/settings/fuelgauge/PowerGaugePreference.java
@@ -58,7 +58,9 @@
private PowerGaugePreference(Context context, AttributeSet attrs, Drawable icon,
CharSequence contentDescription, BatteryEntry info) {
super(context, attrs);
- setIcon(icon != null ? icon : new ColorDrawable(0));
+ if (icon != null) {
+ setIcon(icon);
+ }
setWidgetLayoutResource(R.layout.preference_widget_summary);
mInfo = info;
mContentDescription = contentDescription;
diff --git a/src/com/android/settings/homepage/CardContentLoader.java b/src/com/android/settings/homepage/CardContentLoader.java
index 4e1e33e..9805ae3 100644
--- a/src/com/android/settings/homepage/CardContentLoader.java
+++ b/src/com/android/settings/homepage/CardContentLoader.java
@@ -17,46 +17,52 @@
package com.android.settings.homepage;
import android.content.Context;
+import android.database.Cursor;
-import androidx.annotation.Nullable;
+import androidx.annotation.NonNull;
import com.android.settingslib.utils.AsyncLoaderCompat;
+import java.util.ArrayList;
import java.util.List;
-//TODO(b/112521307): Implement this to make it work with the card database.
-public class CardContentLoader {
+public class CardContentLoader extends AsyncLoaderCompat<List<ContextualCard>> {
+ static final int CARD_CONTENT_LOADER_ID = 1;
- private static final String TAG = "CardContentLoader";
-
- private CardContentLoaderListener mListener;
+ private Context mContext;
public interface CardContentLoaderListener {
- void onFinishCardLoading(List<HomepageCard> homepageCards);
+ void onFinishCardLoading(List<ContextualCard> contextualCards);
}
- public CardContentLoader() {
+ CardContentLoader(Context context) {
+ super(context);
+ mContext = context.getApplicationContext();
}
- void setListener(CardContentLoaderListener listener) {
- mListener = listener;
+ @Override
+ protected void onDiscardResult(List<ContextualCard> result) {
+
}
- private static class CardLoader extends AsyncLoaderCompat<List<HomepageCard>> {
-
- public CardLoader(Context context) {
- super(context);
+ @NonNull
+ @Override
+ public List<ContextualCard> loadInBackground() {
+ final List<ContextualCard> result = new ArrayList<>();
+ try (Cursor cursor = CardDatabaseHelper.getInstance(mContext).getContextualCards()) {
+ if (cursor.getCount() == 0) {
+ //TODO(b/113372471): Load Default static cards and return 3 static cards
+ return result;
+ }
+ for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
+ final ContextualCard card = new ContextualCard(cursor);
+ if (card.isCustomCard()) {
+ //TODO(b/114688391): Load and generate custom card,then add into list
+ } else {
+ result.add(card);
+ }
+ }
}
-
- @Override
- protected void onDiscardResult(List<HomepageCard> result) {
-
- }
-
- @Nullable
- @Override
- public List<HomepageCard> loadInBackground() {
- return null;
- }
+ return result;
}
}
diff --git a/src/com/android/settings/homepage/CardContentProvider.java b/src/com/android/settings/homepage/CardContentProvider.java
index 640a00b..7b08756 100644
--- a/src/com/android/settings/homepage/CardContentProvider.java
+++ b/src/com/android/settings/homepage/CardContentProvider.java
@@ -61,23 +61,38 @@
@Override
public Uri insert(Uri uri, ContentValues values) {
+ final ContentValues[] cvs = {values};
+ bulkInsert(uri, cvs);
+ return uri;
+ }
+
+ @Override
+ public int bulkInsert(Uri uri, ContentValues[] values) {
final StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
+ int numInserted = 0;
+ final SQLiteDatabase database = mDBHelper.getWritableDatabase();
+
try {
maybeEnableStrictMode();
- final SQLiteDatabase database = mDBHelper.getWritableDatabase();
final String table = getTableFromMatch(uri);
- final long ret = database.insert(table, null, values);
- if (ret != -1) {
- getContext().getContentResolver().notifyChange(uri, null);
- } else {
- Log.e(TAG, "The CardContentProvider insertion failed! Plase check SQLiteDatabase's "
- + "message.");
+ database.beginTransaction();
+ for (ContentValues value : values) {
+ long ret = database.insert(table, null, value);
+ if (ret != -1L) {
+ numInserted++;
+ } else {
+ Log.e(TAG, "The row " + value.getAsString(CardDatabaseHelper.CardColumns.NAME)
+ + " insertion failed! Please check your data.");
+ }
}
+ database.setTransactionSuccessful();
+ getContext().getContentResolver().notifyChange(uri, null);
} finally {
+ database.endTransaction();
StrictMode.setThreadPolicy(oldPolicy);
}
- return uri;
+ return numInserted;
}
@Override
diff --git a/src/com/android/settings/homepage/CardDatabaseHelper.java b/src/com/android/settings/homepage/CardDatabaseHelper.java
index 382b71f..b53479e 100644
--- a/src/com/android/settings/homepage/CardDatabaseHelper.java
+++ b/src/com/android/settings/homepage/CardDatabaseHelper.java
@@ -17,6 +17,7 @@
package com.android.settings.homepage;
import android.content.Context;
+import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
@@ -190,4 +191,12 @@
}
return sCardDatabaseHelper;
}
+
+ Cursor getContextualCards() {
+ final SQLiteDatabase db = this.getReadableDatabase();
+ Cursor cursor = db.query(CARD_TABLE, null /* columns */, null /* selection */,
+ null /* selectionArgs */, null /* groupBy */, null /* having */,
+ null /* orderBy */);
+ return cursor;
+ }
}
diff --git a/src/com/android/settings/homepage/HomepageCard.java b/src/com/android/settings/homepage/ContextualCard.java
similarity index 69%
rename from src/com/android/settings/homepage/HomepageCard.java
rename to src/com/android/settings/homepage/ContextualCard.java
index 588c758..5bd265b 100644
--- a/src/com/android/settings/homepage/HomepageCard.java
+++ b/src/com/android/settings/homepage/ContextualCard.java
@@ -17,6 +17,7 @@
package com.android.settings.homepage;
import android.annotation.IntDef;
+import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.TextUtils;
@@ -25,17 +26,17 @@
import java.lang.annotation.RetentionPolicy;
/**
- * Data class representing a {@link HomepageCard}.
+ * Data class representing a {@link ContextualCard}.
*/
-public class HomepageCard {
+public class ContextualCard {
/**
- * Flags indicating the type of the HomepageCard.
+ * Flags indicating the type of the ContextualCard.
*/
- @IntDef({CardType.INVALID, CardType.SLICE, CardType.SUGGESTION, CardType.CONDITIONAL})
+ @IntDef({CardType.DEFAULT, CardType.SLICE, CardType.SUGGESTION, CardType.CONDITIONAL})
@Retention(RetentionPolicy.SOURCE)
public @interface CardType {
- int INVALID = -1;
+ int DEFAULT = 0;
int SLICE = 1;
int SUGGESTION = 2;
int CONDITIONAL = 3;
@@ -58,86 +59,90 @@
private final int mIconResId;
private final int mCardAction;
private final long mExpireTimeMS;
- private final Drawable mIconDrawable;
private final boolean mIsHalfWidth;
+ private final Drawable mIconDrawable;
String getName() {
return mName;
}
- int getCardType() {
+ public int getCardType() {
return mCardType;
}
- double getRankingScore() {
+ public double getRankingScore() {
return mRankingScore;
}
- String getTextSliceUri() {
+ public String getTextSliceUri() {
return mSliceUri;
}
- Uri getSliceUri() {
+ public Uri getSliceUri() {
return Uri.parse(mSliceUri);
}
- int getCategory() {
+ public int getCategory() {
return mCategory;
}
- String getLocalizedToLocale() {
+ public String getLocalizedToLocale() {
return mLocalizedToLocale;
}
- String getPackageName() {
+ public String getPackageName() {
return mPackageName;
}
- String getAppVersion() {
+ public String getAppVersion() {
return mAppVersion;
}
- String getTitleResName() {
+ public String getTitleResName() {
return mTitleResName;
}
- String getTitleText() {
+ public String getTitleText() {
return mTitleText;
}
- String getSummaryResName() {
+ public String getSummaryResName() {
return mSummaryResName;
}
- String getSummaryText() {
+ public String getSummaryText() {
return mSummaryText;
}
- String getIconResName() {
+ public String getIconResName() {
return mIconResName;
}
- int getIconResId() {
+ public int getIconResId() {
return mIconResId;
}
- int getCardAction() {
+ public int getCardAction() {
return mCardAction;
}
- long getExpireTimeMS() {
+ public long getExpireTimeMS() {
return mExpireTimeMS;
}
- Drawable getIconDrawable() {
+ public Drawable getIconDrawable() {
return mIconDrawable;
}
- boolean isHalfWidth() {
+ public boolean isHalfWidth() {
return mIsHalfWidth;
}
- HomepageCard(Builder builder) {
+ boolean isCustomCard() {
+ return TextUtils.isEmpty(mSliceUri);
+ }
+
+ public ContextualCard(Builder builder) {
mName = builder.mName;
mCardType = builder.mCardType;
mRankingScore = builder.mRankingScore;
@@ -158,6 +163,31 @@
mIsHalfWidth = builder.mIsHalfWidth;
}
+ ContextualCard(Cursor c) {
+ mName = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.NAME));
+ mCardType = c.getInt(c.getColumnIndex(CardDatabaseHelper.CardColumns.TYPE));
+ mRankingScore = c.getDouble(c.getColumnIndex(CardDatabaseHelper.CardColumns.SCORE));
+ mSliceUri = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.SLICE_URI));
+ mCategory = c.getInt(c.getColumnIndex(CardDatabaseHelper.CardColumns.CATEGORY));
+ mLocalizedToLocale = c.getString(
+ c.getColumnIndex(CardDatabaseHelper.CardColumns.LOCALIZED_TO_LOCALE));
+ mPackageName = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.PACKAGE_NAME));
+ mAppVersion = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.APP_VERSION));
+ mTitleResName = c.getString(
+ c.getColumnIndex(CardDatabaseHelper.CardColumns.TITLE_RES_NAME));
+ mTitleText = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.TITLE_TEXT));
+ mSummaryResName = c.getString(
+ c.getColumnIndex(CardDatabaseHelper.CardColumns.SUMMARY_RES_NAME));
+ mSummaryText = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.SUMMARY_TEXT));
+ mIconResName = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.ICON_RES_NAME));
+ mIconResId = c.getInt(c.getColumnIndex(CardDatabaseHelper.CardColumns.ICON_RES_ID));
+ mCardAction = c.getInt(c.getColumnIndex(CardDatabaseHelper.CardColumns.CARD_ACTION));
+ mExpireTimeMS = c.getLong(c.getColumnIndex(CardDatabaseHelper.CardColumns.EXPIRE_TIME_MS));
+ mIsHalfWidth = (c.getInt(
+ c.getColumnIndex(CardDatabaseHelper.CardColumns.SUPPORT_HALF_WIDTH)) == 1);
+ mIconDrawable = null;
+ }
+
@Override
public int hashCode() {
return mName.hashCode();
@@ -171,15 +201,15 @@
if (this == obj) {
return true;
}
- if (!(obj instanceof HomepageCard)) {
+ if (!(obj instanceof ContextualCard)) {
return false;
}
- final HomepageCard that = (HomepageCard) obj;
+ final ContextualCard that = (ContextualCard) obj;
return TextUtils.equals(mName, that.mName);
}
- static class Builder {
+ public static class Builder {
private String mName;
private int mCardType;
private double mRankingScore;
@@ -289,8 +319,8 @@
return this;
}
- public HomepageCard build() {
- return new HomepageCard(this);
+ public ContextualCard build() {
+ return new ContextualCard(this);
}
}
}
diff --git a/src/com/android/settings/homepage/ContextualCardController.java b/src/com/android/settings/homepage/ContextualCardController.java
new file mode 100644
index 0000000..e47f70c
--- /dev/null
+++ b/src/com/android/settings/homepage/ContextualCardController.java
@@ -0,0 +1,32 @@
+/*
+ * 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.homepage;
+
+/**
+ * Data controller for {@link ContextualCard}.
+ */
+public interface ContextualCardController {
+
+ @ContextualCard.CardType
+ int getCardType();
+
+ void onPrimaryClick(ContextualCard card);
+
+ void onActionClick(ContextualCard card);
+
+ void setCardUpdateListener(ContextualCardUpdateListener listener);
+}
diff --git a/src/com/android/settings/homepage/ContextualCardLookupTable.java b/src/com/android/settings/homepage/ContextualCardLookupTable.java
new file mode 100644
index 0000000..e70b700
--- /dev/null
+++ b/src/com/android/settings/homepage/ContextualCardLookupTable.java
@@ -0,0 +1,75 @@
+/*
+ * 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.homepage;
+
+import com.android.settings.homepage.ContextualCard.CardType;
+import com.android.settings.homepage.conditional.ConditionContextualCardController;
+import com.android.settings.homepage.conditional.ConditionContextualCardRenderer;
+
+import java.util.Set;
+import java.util.TreeSet;
+
+public class ContextualCardLookupTable {
+
+ static class ControllerRendererMapping implements Comparable<ControllerRendererMapping> {
+ @CardType
+ private final int mCardType;
+ private final Class<? extends ContextualCardController> mControllerClass;
+ private final Class<? extends ContextualCardRenderer> mRendererClass;
+
+ private ControllerRendererMapping(@CardType int cardType,
+ Class<? extends ContextualCardController> controllerClass,
+ Class<? extends ContextualCardRenderer> rendererClass) {
+ mCardType = cardType;
+ mControllerClass = controllerClass;
+ mRendererClass = rendererClass;
+ }
+
+ @Override
+ public int compareTo(ControllerRendererMapping other) {
+ return Integer.compare(this.mCardType, other.mCardType);
+ }
+ }
+
+ private static final Set<ControllerRendererMapping> LOOKUP_TABLE =
+ new TreeSet<ControllerRendererMapping>() {{
+ add(new ControllerRendererMapping(CardType.CONDITIONAL,
+ ConditionContextualCardController.class,
+ ConditionContextualCardRenderer.class));
+ }};
+
+ public static Class<? extends ContextualCardController> getCardControllerClass(
+ @CardType int cardType) {
+ for (ControllerRendererMapping mapping : LOOKUP_TABLE) {
+ if (mapping.mCardType == cardType) {
+ return mapping.mControllerClass;
+ }
+ }
+ return null;
+ }
+
+ //TODO(b/112578070): Implement multi renderer cases.
+ public static Class<? extends ContextualCardRenderer> getCardRendererClasses(
+ @CardType int cardType) {
+ for (ControllerRendererMapping mapping : LOOKUP_TABLE) {
+ if (mapping.mCardType == cardType) {
+ return mapping.mRendererClass;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/com/android/settings/homepage/ContextualCardManager.java b/src/com/android/settings/homepage/ContextualCardManager.java
new file mode 100644
index 0000000..87b048e
--- /dev/null
+++ b/src/com/android/settings/homepage/ContextualCardManager.java
@@ -0,0 +1,197 @@
+/*
+ * 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.homepage;
+
+import static com.android.settings.homepage.CardContentLoader.CARD_CONTENT_LOADER_ID;
+
+import static java.util.stream.Collectors.groupingBy;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.widget.BaseAdapter;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.loader.app.LoaderManager;
+import androidx.loader.content.Loader;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * This is a centralized manager of multiple {@link ContextualCardController}.
+ *
+ * {@link ContextualCardManager} first loads data from {@link CardContentLoader} and gets back a
+ * list of {@link ContextualCard}. All subclasses of {@link ContextualCardController} are loaded
+ * here, which will then trigger the {@link ContextualCardController} to load its data and listen to
+ * corresponding changes. When every single {@link ContextualCardController} updates its data, the
+ * data will be passed here, then going through some sorting mechanisms. The
+ * {@link ContextualCardController} will end up building a list of {@link ContextualCard} for
+ * {@link ContextualCardsAdapter} and {@link BaseAdapter#notifyDataSetChanged()} will be called to
+ * get the page refreshed.
+ */
+public class ContextualCardManager implements CardContentLoader.CardContentLoaderListener,
+ ContextualCardUpdateListener {
+
+ private static final String TAG = "ContextualCardManager";
+ //The list for Settings Custom Card
+ @ContextualCard.CardType
+ private static final int[] SETTINGS_CARDS = {ContextualCard.CardType.CONDITIONAL};
+
+ private final Context mContext;
+ private final ControllerRendererPool mControllerRendererPool;
+ private final Lifecycle mLifecycle;
+ private final List<ContextualCard> mContextualCards;
+ private final List<LifecycleObserver> mLifecycleObservers;
+
+ private ContextualCardUpdateListener mListener;
+
+ public ContextualCardManager(Context context, @NonNull Lifecycle lifecycle) {
+ mContext = context;
+ mLifecycle = lifecycle;
+ mContextualCards = new ArrayList<>();
+ mLifecycleObservers = new ArrayList<>();
+ mControllerRendererPool = new ControllerRendererPool();
+ //for data provided by Settings
+ for (int cardType : SETTINGS_CARDS) {
+ setupController(cardType);
+ }
+ }
+
+ void loadContextualCards(PersonalSettingsFragment fragment) {
+ final CardContentLoaderCallbacks cardContentLoaderCallbacks =
+ new CardContentLoaderCallbacks(mContext);
+ cardContentLoaderCallbacks.setListener(this);
+ LoaderManager.getInstance(fragment).initLoader(CARD_CONTENT_LOADER_ID, null /* bundle */,
+ cardContentLoaderCallbacks);
+ }
+
+ private void loadCardControllers() {
+ for (ContextualCard card : mContextualCards) {
+ setupController(card.getCardType());
+ }
+ }
+
+ private void setupController(int cardType) {
+ final ContextualCardController controller = mControllerRendererPool.getController(mContext,
+ cardType);
+ if (controller == null) {
+ Log.w(TAG, "Cannot find ContextualCardController for type " + cardType);
+ return;
+ }
+ controller.setCardUpdateListener(this);
+ if (controller instanceof LifecycleObserver && !mLifecycleObservers.contains(controller)) {
+ mLifecycleObservers.add((LifecycleObserver) controller);
+ mLifecycle.addObserver((LifecycleObserver) controller);
+ }
+ }
+
+ //TODO(b/111822376): implement sorting mechanism.
+ private void sortCards(List<ContextualCard> cards) {
+ //take mContextualCards as the source and do the ranking based on the rule.
+ }
+
+ @Override
+ public void onContextualCardUpdated(Map<Integer, List<ContextualCard>> updateList) {
+ //TODO(b/112245748): Should implement a DiffCallback.
+ //Keep the old list for comparison.
+ final List<ContextualCard> prevCards = mContextualCards;
+
+ final Set<Integer> cardTypes = updateList.keySet();
+ //Remove the existing data that matches the certain cardType before inserting new data.
+ final List<ContextualCard> cardsToKeep = mContextualCards
+ .stream()
+ .filter(card -> !cardTypes.contains(card.getCardType()))
+ .collect(Collectors.toList());
+ final List<ContextualCard> allCards = new ArrayList<>();
+ allCards.addAll(cardsToKeep);
+ allCards.addAll(
+ updateList.values().stream().flatMap(List::stream).collect(Collectors.toList()));
+
+ sortCards(allCards);
+ //replace with the new data
+ mContextualCards.clear();
+ mContextualCards.addAll(allCards);
+
+ loadCardControllers();
+
+ if (mListener != null) {
+ final Map<Integer, List<ContextualCard>> cardsToUpdate = new ArrayMap<>();
+ cardsToUpdate.put(ContextualCard.CardType.DEFAULT, mContextualCards);
+ mListener.onContextualCardUpdated(cardsToUpdate);
+ }
+ }
+
+ @Override
+ public void onFinishCardLoading(List<ContextualCard> cards) {
+ onContextualCardUpdated(cards.stream().collect(groupingBy(ContextualCard::getCardType)));
+ }
+
+ void setListener(ContextualCardUpdateListener listener) {
+ mListener = listener;
+ }
+
+ public ControllerRendererPool getControllerRendererPool() {
+ return mControllerRendererPool;
+ }
+
+ static class CardContentLoaderCallbacks implements
+ LoaderManager.LoaderCallbacks<List<ContextualCard>> {
+
+ private Context mContext;
+ private CardContentLoader.CardContentLoaderListener mListener;
+
+ CardContentLoaderCallbacks(Context context) {
+ mContext = context.getApplicationContext();
+ }
+
+ protected void setListener(CardContentLoader.CardContentLoaderListener listener) {
+ mListener = listener;
+ }
+
+ @NonNull
+ @Override
+ public Loader<List<ContextualCard>> onCreateLoader(int id, @Nullable Bundle bundle) {
+ if (id == CARD_CONTENT_LOADER_ID) {
+ return new CardContentLoader(mContext);
+ } else {
+ throw new IllegalArgumentException("Unknown loader id: " + id);
+ }
+ }
+
+ @Override
+ public void onLoadFinished(@NonNull Loader<List<ContextualCard>> loader,
+ List<ContextualCard> contextualCards) {
+ if (mListener != null) {
+ mListener.onFinishCardLoading(contextualCards);
+ }
+ }
+
+ @Override
+ public void onLoaderReset(@NonNull Loader<List<ContextualCard>> loader) {
+
+ }
+ }
+}
diff --git a/src/com/android/settings/homepage/HomepageCardRenderer.java b/src/com/android/settings/homepage/ContextualCardRenderer.java
similarity index 68%
rename from src/com/android/settings/homepage/HomepageCardRenderer.java
rename to src/com/android/settings/homepage/ContextualCardRenderer.java
index ffa54e3..315c09d 100644
--- a/src/com/android/settings/homepage/HomepageCardRenderer.java
+++ b/src/com/android/settings/homepage/ContextualCardRenderer.java
@@ -21,9 +21,9 @@
import androidx.recyclerview.widget.RecyclerView;
/**
- * UI renderer for {@link HomepageCard}.
+ * UI renderer for {@link ContextualCard}.
*/
-public interface HomepageCardRenderer {
+public interface ContextualCardRenderer {
/**
* The layout type of the controller.
@@ -31,16 +31,16 @@
int getViewType();
/**
- * When {@link HomepageAdapter} calls {@link HomepageAdapter#onCreateViewHolder(ViewGroup,
- * int)}, this method will be called to retrieve the corresponding
+ * When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onCreateViewHolder},
+ * this method will be called to retrieve the corresponding
* {@link androidx.recyclerview.widget.RecyclerView.ViewHolder}.
*/
RecyclerView.ViewHolder createViewHolder(View view);
/**
- * When {@link HomepageAdapter} calls {@link HomepageAdapter#onBindViewHolder(RecyclerView
- * .ViewHolder, int)}, this method will be called to bind data to the
+ * When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onBindViewHolder},
+ * this method will be called to bind data to the
* {@link androidx.recyclerview.widget.RecyclerView.ViewHolder}.
*/
- void bindView(RecyclerView.ViewHolder holder, HomepageCard card);
+ void bindView(RecyclerView.ViewHolder holder, ContextualCard card);
}
\ No newline at end of file
diff --git a/src/com/android/settings/homepage/ContextualCardUpdateListener.java b/src/com/android/settings/homepage/ContextualCardUpdateListener.java
new file mode 100644
index 0000000..60dd3a7
--- /dev/null
+++ b/src/com/android/settings/homepage/ContextualCardUpdateListener.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.homepage;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * When {@link ContextualCardController} detects changes, it will notify the listeners registered.
+ */
+public interface ContextualCardUpdateListener {
+
+ /**
+ * Called when a set of cards are updated.
+ *
+ * @param cards A map of updates grouped by {@link ContextualCard.CardType}. Values can be
+ * null, which means all cards from corresponding {@link
+ * ContextualCard.CardType} are removed.
+ */
+ void onContextualCardUpdated(Map<Integer, List<ContextualCard>> cards);
+}
\ No newline at end of file
diff --git a/src/com/android/settings/homepage/ContextualCardsAdapter.java b/src/com/android/settings/homepage/ContextualCardsAdapter.java
new file mode 100644
index 0000000..9ab8893
--- /dev/null
+++ b/src/com/android/settings/homepage/ContextualCardsAdapter.java
@@ -0,0 +1,117 @@
+/*
+ * 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.homepage;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class ContextualCardsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
+ implements ContextualCardUpdateListener {
+ static final int SPAN_COUNT = 2;
+
+ private static final String TAG = "ContextualCardsAdapter";
+ private static final int HALF_WIDTH = 1;
+ private static final int FULL_WIDTH = 2;
+
+ private final Context mContext;
+ private final ControllerRendererPool mControllerRendererPool;
+ private final List<ContextualCard> mContextualCards;
+
+ public ContextualCardsAdapter(Context context, ContextualCardManager manager) {
+ mContext = context;
+ mContextualCards = new ArrayList<>();
+ mControllerRendererPool = manager.getControllerRendererPool();
+ setHasStableIds(true);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return mContextualCards.get(position).hashCode();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return mContextualCards.get(position).getCardType();
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int cardType) {
+ final ContextualCardRenderer renderer = mControllerRendererPool.getRenderer(mContext,
+ cardType);
+ final int viewType = renderer.getViewType();
+ final View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
+
+ return renderer.createViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ final int cardType = mContextualCards.get(position).getCardType();
+ final ContextualCardRenderer renderer = mControllerRendererPool.getRenderer(mContext,
+ cardType);
+
+ renderer.bindView(holder, mContextualCards.get(position));
+ }
+
+ @Override
+ public int getItemCount() {
+ return mContextualCards.size();
+ }
+
+ @Override
+ public void onAttachedToRecyclerView(RecyclerView recyclerView) {
+ super.onAttachedToRecyclerView(recyclerView);
+ final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
+ if (layoutManager instanceof GridLayoutManager) {
+ final GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
+ gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
+ @Override
+ public int getSpanSize(int position) {
+ final ContextualCard card = mContextualCards.get(position);
+ //TODO(b/114009676): may use another field to make decision. still under review.
+ if (card.isHalfWidth()) {
+ return HALF_WIDTH;
+ }
+ return FULL_WIDTH;
+ }
+ });
+ }
+ }
+
+ @Override
+ public void onContextualCardUpdated(Map<Integer, List<ContextualCard>> cards) {
+ final List<ContextualCard> contextualCards = cards.get(ContextualCard.CardType.DEFAULT);
+ //TODO(b/112245748): Should implement a DiffCallback so we can use notifyItemChanged()
+ // instead.
+ if (contextualCards == null) {
+ mContextualCards.clear();
+ } else {
+ mContextualCards.clear();
+ mContextualCards.addAll(contextualCards);
+ }
+ notifyDataSetChanged();
+ }
+}
diff --git a/src/com/android/settings/homepage/ControllerRendererPool.java b/src/com/android/settings/homepage/ControllerRendererPool.java
index b2ac9ec..1e4b37c 100644
--- a/src/com/android/settings/homepage/ControllerRendererPool.java
+++ b/src/com/android/settings/homepage/ControllerRendererPool.java
@@ -21,78 +21,78 @@
import androidx.collection.ArraySet;
+import com.android.settings.homepage.conditional.ConditionContextualCardController;
+import com.android.settings.homepage.conditional.ConditionContextualCardRenderer;
+
import java.util.Set;
/**
- * This is a fragment scoped singleton holding a set of {@link HomepageCardController} and
- * {@link HomepageCardRenderer}.
+ * This is a fragment scoped singleton holding a set of {@link ContextualCardController} and
+ * {@link ContextualCardRenderer}.
*/
public class ControllerRendererPool {
private static final String TAG = "ControllerRendererPool";
- private final Set<HomepageCardController> mControllers;
- private final Set<HomepageCardRenderer> mRenderers;
+ private final Set<ContextualCardController> mControllers;
+ private final Set<ContextualCardRenderer> mRenderers;
public ControllerRendererPool() {
mControllers = new ArraySet<>();
mRenderers = new ArraySet<>();
}
- public <T extends HomepageCardController> T getController(Context context,
- @HomepageCard.CardType int cardType) {
- final Class<? extends HomepageCardController> clz =
- HomepageCardLookupTable.getCardControllerClass(cardType);
- for (HomepageCardController controller : mControllers) {
+ public <T extends ContextualCardController> T getController(Context context,
+ @ContextualCard.CardType int cardType) {
+ final Class<? extends ContextualCardController> clz =
+ ContextualCardLookupTable.getCardControllerClass(cardType);
+ for (ContextualCardController controller : mControllers) {
if (controller.getClass() == clz) {
Log.d(TAG, "Controller is already there.");
return (T) controller;
}
}
- final HomepageCardController controller = createCardController(context, clz);
+ final ContextualCardController controller = createCardController(context, clz);
if (controller != null) {
mControllers.add(controller);
}
return (T) controller;
}
- public Set<HomepageCardController> getControllers() {
+ public Set<ContextualCardController> getControllers() {
return mControllers;
}
- public HomepageCardRenderer getRenderer(Context context, @HomepageCard.CardType int cardType) {
- final Class<? extends HomepageCardRenderer> clz =
- HomepageCardLookupTable.getCardRendererClasses(cardType);
- for (HomepageCardRenderer renderer : mRenderers) {
+ public ContextualCardRenderer getRenderer(Context context, @ContextualCard.CardType int cardType) {
+ final Class<? extends ContextualCardRenderer> clz =
+ ContextualCardLookupTable.getCardRendererClasses(cardType);
+ for (ContextualCardRenderer renderer : mRenderers) {
if (renderer.getClass() == clz) {
Log.d(TAG, "Renderer is already there.");
return renderer;
}
}
- final HomepageCardRenderer renderer = createCardRenderer(context, clz);
+ final ContextualCardRenderer renderer = createCardRenderer(context, clz);
if (renderer != null) {
mRenderers.add(renderer);
}
return renderer;
}
- private HomepageCardController createCardController(Context context,
- Class<? extends HomepageCardController> clz) {
- /*
- if (ConditionHomepageCardController.class == clz) {
- return new ConditionHomepageCardController(context);
+ private ContextualCardController createCardController(Context context,
+ Class<? extends ContextualCardController> clz) {
+ if (ConditionContextualCardController.class == clz) {
+ return new ConditionContextualCardController(context);
}
- */
return null;
}
- private HomepageCardRenderer createCardRenderer(Context context, Class<?> clz) {
- //if (ConditionHomepageCardRenderer.class == clz) {
- // return new ConditionHomepageCardRenderer(context, this /*controllerRendererPool*/);
- //}
-
+ private ContextualCardRenderer createCardRenderer(Context context, Class<?> clz) {
+ if (ConditionContextualCardRenderer.class == clz) {
+ return new ConditionContextualCardRenderer(context, this /*controllerRendererPool*/);
+ }
return null;
}
diff --git a/src/com/android/settings/homepage/HomepageAdapter.java b/src/com/android/settings/homepage/HomepageAdapter.java
deleted file mode 100644
index 9ff5260..0000000
--- a/src/com/android/settings/homepage/HomepageAdapter.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.homepage;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.recyclerview.widget.RecyclerView;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class HomepageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements
- HomepageCardUpdateListener {
-
- private static final String TAG = "HomepageAdapter";
-
- private final Context mContext;
- private final ControllerRendererPool mControllerRendererPool;
-
- private List<HomepageCard> mHomepageCards;
- private RecyclerView mRecyclerView;
-
- public HomepageAdapter(Context context, HomepageManager manager) {
- mContext = context;
- mHomepageCards = new ArrayList<>();
- mControllerRendererPool = manager.getControllerRendererPool();
- setHasStableIds(true);
- }
-
- @Override
- public long getItemId(int position) {
- return mHomepageCards.get(position).hashCode();
- }
-
- @Override
- public int getItemViewType(int position) {
- return mHomepageCards.get(position).getCardType();
- }
-
- @Override
- public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int cardType) {
- final HomepageCardRenderer renderer = mControllerRendererPool.getRenderer(mContext,
- cardType);
- final int viewType = renderer.getViewType();
- final View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
-
- return renderer.createViewHolder(view);
- }
-
- @Override
- public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
- final int cardType = mHomepageCards.get(position).getCardType();
- final HomepageCardRenderer renderer = mControllerRendererPool.getRenderer(mContext,
- cardType);
-
- renderer.bindView(holder, mHomepageCards.get(position));
- }
-
- @Override
- public int getItemCount() {
- return mHomepageCards.size();
- }
-
- @Override
- public void onAttachedToRecyclerView(RecyclerView recyclerView) {
- super.onAttachedToRecyclerView(recyclerView);
- mRecyclerView = recyclerView;
- }
-
- @Override
- public void onHomepageCardUpdated(int cardType, List<HomepageCard> homepageCards) {
- //TODO(b/112245748): Should implement a DiffCallback so we can use notifyItemChanged()
- // instead.
- if (homepageCards == null) {
- mHomepageCards.clear();
- } else {
- mHomepageCards = homepageCards;
- }
- notifyDataSetChanged();
- }
-}
diff --git a/src/com/android/settings/homepage/HomepageCardController.java b/src/com/android/settings/homepage/HomepageCardController.java
deleted file mode 100644
index 10fc158..0000000
--- a/src/com/android/settings/homepage/HomepageCardController.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.homepage;
-
-import java.util.List;
-
-//TODO(b/111821137): add test cases
-
-/**
- * Data controller for {@link HomepageCard}.
- */
-public interface HomepageCardController {
-
- @HomepageCard.CardType
- int getCardType();
-
- /**
- * When data is updated or changed, the new data should be passed to HomepageManager for list
- * updating.
- */
- void onDataUpdated(List<HomepageCard> cardList);
-
- void onPrimaryClick(HomepageCard card);
-
- void onActionClick(HomepageCard card);
-
- void setHomepageCardUpdateListener(HomepageCardUpdateListener listener);
-}
diff --git a/src/com/android/settings/homepage/HomepageCardLookupTable.java b/src/com/android/settings/homepage/HomepageCardLookupTable.java
deleted file mode 100644
index ae3f08b..0000000
--- a/src/com/android/settings/homepage/HomepageCardLookupTable.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.homepage;
-
-import com.android.settings.homepage.HomepageCard.CardType;
-
-import java.util.Set;
-import java.util.TreeSet;
-
-public class HomepageCardLookupTable {
-
- static class HomepageMapping implements Comparable<HomepageMapping> {
- @CardType
- private final int mCardType;
- private final Class<? extends HomepageCardController> mControllerClass;
- private final Class<? extends HomepageCardRenderer> mRendererClass;
-
- private HomepageMapping(@CardType int cardType,
- Class<? extends HomepageCardController> controllerClass,
- Class<? extends HomepageCardRenderer> rendererClass) {
- mCardType = cardType;
- mControllerClass = controllerClass;
- mRendererClass = rendererClass;
- }
-
- @Override
- public int compareTo(HomepageMapping other) {
- return Integer.compare(this.mCardType, other.mCardType);
- }
- }
-
- private static final Set<HomepageMapping> LOOKUP_TABLE = new TreeSet<HomepageMapping>() {
- //add(new HomepageMapping(CardType.CONDITIONAL, ConditionHomepageCardController.class,
- // ConditionHomepageCardRenderer.class));
- };
-
- public static Class<? extends HomepageCardController> getCardControllerClass(
- @CardType int cardType) {
- for (HomepageMapping mapping : LOOKUP_TABLE) {
- if (mapping.mCardType == cardType) {
- return mapping.mControllerClass;
- }
- }
- return null;
- }
-
- //TODO(b/112578070): Implement multi renderer cases.
- public static Class<? extends HomepageCardRenderer> getCardRendererClasses(
- @CardType int cardType) {
- for (HomepageMapping mapping : LOOKUP_TABLE) {
- if (mapping.mCardType == cardType) {
- return mapping.mRendererClass;
- }
- }
- return null;
- }
-}
diff --git a/src/com/android/settings/homepage/HomepageCardUpdateListener.java b/src/com/android/settings/homepage/HomepageCardUpdateListener.java
deleted file mode 100644
index a44ba2b..0000000
--- a/src/com/android/settings/homepage/HomepageCardUpdateListener.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.homepage;
-
-import java.util.List;
-
-/**
- * When {@link HomepageCardController} detects changes, it will notify the listeners registered. In
- * our case, {@link HomepageManager} gets noticed.
- *
- * After the list of {@link HomepageCard} gets updated in{@link HomepageManager},
- * {@link HomepageManager} will notify the listeners registered, {@link HomepageAdapter} in this
- * case.
- */
-interface HomepageCardUpdateListener {
- void onHomepageCardUpdated(int cardType, List<HomepageCard> updateList);
-}
\ No newline at end of file
diff --git a/src/com/android/settings/homepage/HomepageFragment.java b/src/com/android/settings/homepage/HomepageFragment.java
deleted file mode 100644
index 402725e..0000000
--- a/src/com/android/settings/homepage/HomepageFragment.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.homepage;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Toolbar;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.SettingsHomepageActivity;
-import com.android.settings.Utils;
-import com.android.settings.core.InstrumentedFragment;
-import com.android.settings.dashboard.DashboardSummary;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.search.SearchFeatureProvider;
-
-import com.google.android.material.bottomsheet.BottomSheetBehavior;
-import com.google.android.material.floatingactionbutton.FloatingActionButton;
-
-public class HomepageFragment extends InstrumentedFragment {
-
- private static final String TAG = "HomepageFragment";
- private static final String SAVE_BOTTOMBAR_STATE = "bottombar_state";
- private static final String SAVE_BOTTOM_FRAGMENT_LOADED = "bottom_fragment_loaded";
-
- private RecyclerView mCardsContainer;
- private HomepageAdapter mHomepageAdapter;
- private LinearLayoutManager mLayoutManager;
-
- private FloatingActionButton mSearchButton;
- private BottomSheetBehavior mBottomSheetBehavior;
- private View mBottomBar;
- private View mSearchBar;
- private boolean mBottomFragmentLoaded;
- private HomepageManager mHomepageManager;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mHomepageManager = new HomepageManager(getContext(), getSettingsLifecycle());
- mHomepageManager.startCardContentLoading();
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- final View rootView = inflater.inflate(R.layout.settings_homepage,
- container, false);
- mCardsContainer = (RecyclerView) rootView.findViewById(R.id.card_container);
- //TODO(b/111822407): May have to swap to GridLayoutManager
- mLayoutManager = new LinearLayoutManager(getActivity());
- mCardsContainer.setLayoutManager(mLayoutManager);
- mHomepageAdapter = new HomepageAdapter(getContext(), mHomepageManager);
- mCardsContainer.setAdapter(mHomepageAdapter);
- mHomepageManager.setListener(mHomepageAdapter);
-
- return rootView;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- setupBottomBar();
- setupSearchBar();
- if (savedInstanceState != null) {
- final int bottombarState = savedInstanceState.getInt(SAVE_BOTTOMBAR_STATE);
- mBottomFragmentLoaded = savedInstanceState.getBoolean(SAVE_BOTTOM_FRAGMENT_LOADED);
- mBottomSheetBehavior.setState(bottombarState);
- setBarState(bottombarState);
- }
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
-
- if (mBottomSheetBehavior != null) {
- outState.putInt(SAVE_BOTTOMBAR_STATE, mBottomSheetBehavior.getState());
- outState.putBoolean(SAVE_BOTTOM_FRAGMENT_LOADED, mBottomFragmentLoaded);
- }
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.SETTINGS_HOMEPAGE;
- }
-
- private void setupBottomBar() {
- final Activity activity = getActivity();
-
- mSearchButton = activity.findViewById(R.id.search_fab);
- mSearchButton.setOnClickListener(v -> {
- final Intent intent = SearchFeatureProvider.SEARCH_UI_INTENT;
- intent.setPackage(FeatureFactory.getFactory(activity)
- .getSearchFeatureProvider().getSettingsIntelligencePkgName());
- startActivityForResult(intent, 0 /* requestCode */);
- });
- mBottomSheetBehavior = BottomSheetBehavior.from(activity.findViewById(R.id.bottom_sheet));
- mSearchBar = activity.findViewById(R.id.search_bar_container);
- mBottomBar = activity.findViewById(R.id.bar);
- mBottomBar.setOnClickListener(v -> {
- mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
- });
-
- final int screenWidthpx = getResources().getDisplayMetrics().widthPixels;
- final Toolbar searchActionBar = activity.findViewById(R.id.search_action_bar);
- searchActionBar.setNavigationIcon(R.drawable.ic_search_floating_24dp);
-
- mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
- @Override
- public void onStateChanged(@NonNull View bottomSheet, int newState) {
- if (!mBottomFragmentLoaded) {
- // TODO(b/110405144): Switch to {@link TopLevelSettings} when it's ready.
- SettingsHomepageActivity.switchToFragment(getActivity(),
- R.id.bottom_sheet_fragment, DashboardSummary.class.getName());
- mBottomFragmentLoaded = true;
- }
- setBarState(newState);
- }
-
- @Override
- public void onSlide(@NonNull View bottomSheet, float slideOffset) {
- mBottomBar.setAlpha(1 - slideOffset);
- mSearchButton.setAlpha(1 - slideOffset);
- mSearchBar.setAlpha(slideOffset);
- mSearchBar.setPadding((int) (screenWidthpx * (1 - slideOffset)), 0, 0, 0);
- }
- });
- }
-
- private void setBarState(int bottomSheetState) {
- if (bottomSheetState == BottomSheetBehavior.STATE_EXPANDED) {
- mBottomBar.setVisibility(View.INVISIBLE);
- mSearchBar.setVisibility(View.VISIBLE);
- mSearchButton.setVisibility(View.GONE);
- } else if (bottomSheetState == BottomSheetBehavior.STATE_COLLAPSED) {
- mBottomBar.setVisibility(View.VISIBLE);
- mSearchBar.setVisibility(View.INVISIBLE);
- mSearchButton.setVisibility(View.VISIBLE);
- } else if (bottomSheetState == BottomSheetBehavior.STATE_SETTLING) {
- mBottomBar.setVisibility(View.VISIBLE);
- mSearchBar.setVisibility(View.VISIBLE);
- mSearchButton.setVisibility(View.VISIBLE);
- }
- }
-
- //TODO(110767984), copied from settingsActivity. We have to merge them
- private void setupSearchBar() {
- final Activity activity = getActivity();
- final Toolbar toolbar = activity.findViewById(R.id.search_action_bar);
- FeatureFactory.getFactory(activity).getSearchFeatureProvider()
- .initSearchToolbar(activity, toolbar);
- activity.setActionBar(toolbar);
-
- // Please forgive me for what I am about to do.
- //
- // Need to make the navigation icon non-clickable so that the entire card is clickable
- // and goes to the search UI. Also set the background to null so there's no ripple.
- final View navView = toolbar.getNavigationView();
- navView.setClickable(false);
- navView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
- navView.setBackground(null);
-
- final ActionBar actionBar = activity.getActionBar();
- if (actionBar != null) {
- boolean deviceProvisioned = Utils.isDeviceProvisioned(activity);
- actionBar.setDisplayHomeAsUpEnabled(deviceProvisioned);
- actionBar.setHomeButtonEnabled(deviceProvisioned);
- actionBar.setDisplayShowTitleEnabled(false);
- }
- }
-}
diff --git a/src/com/android/settings/homepage/HomepageManager.java b/src/com/android/settings/homepage/HomepageManager.java
deleted file mode 100644
index 61d7ce7..0000000
--- a/src/com/android/settings/homepage/HomepageManager.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.homepage;
-
-import android.content.Context;
-import android.widget.BaseAdapter;
-
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This is a centralized manager of multiple {@link HomepageCardController}.
- *
- * {@link HomepageManager} first loads data from {@link CardContentLoader} and gets back a list of
- * {@link HomepageCard}. All subclasses of {@link HomepageCardController} are loaded here, which
- * will then trigger the {@link HomepageCardController} to load its data and listen to
- * corresponding changes. When every single {@link HomepageCardController} updates its data, the
- * data will be passed here, then going through some sorting mechanisms. The
- * {@link HomepageCardController} will end up building a list of {@link HomepageCard} for {@link
- * HomepageAdapter} and {@link BaseAdapter#notifyDataSetChanged()} will be called to get the page
- * refreshed.
- */
-public class HomepageManager implements CardContentLoader.CardContentLoaderListener,
- HomepageCardUpdateListener {
-
- private static final String TAG = "HomepageManager";
- //The list for Settings Custom Card
- @HomepageCard.CardType
- private static final int[] SETTINGS_CARDS = {HomepageCard.CardType.CONDITIONAL};
-
- private final Context mContext;
- private final ControllerRendererPool mControllerRendererPool;
- private final Lifecycle mLifecycle;
-
- private List<HomepageCard> mHomepageCards;
- private HomepageCardUpdateListener mListener;
-
-
- public HomepageManager(Context context, Lifecycle lifecycle) {
- mContext = context;
- mLifecycle = lifecycle;
- mHomepageCards = new ArrayList<>();
- mControllerRendererPool = new ControllerRendererPool();
- }
-
- void startCardContentLoading() {
- final CardContentLoader cardContentLoader = new CardContentLoader();
- cardContentLoader.setListener(this);
- }
-
- private void loadCardControllers() {
- if (mHomepageCards != null) {
- for (HomepageCard card : mHomepageCards) {
- setupController(card.getCardType());
- }
- }
-
- //for data provided by Settings
- for (int cardType : SETTINGS_CARDS) {
- setupController(cardType);
- }
- }
-
- private void setupController(int cardType) {
- final HomepageCardController controller = mControllerRendererPool.getController(mContext,
- cardType);
- if (controller != null) {
- controller.setHomepageCardUpdateListener(this);
- if (controller instanceof LifecycleObserver) {
- if (mLifecycle != null) {
- mLifecycle.addObserver((LifecycleObserver) controller);
- }
- }
- }
- }
-
- //TODO(b/111822376): implement sorting mechanism.
- private void sortCards() {
- //take mHomepageCards as the source and do the ranking based on the rule.
- }
-
- @Override
- public void onHomepageCardUpdated(int cardType, List<HomepageCard> updateList) {
- //TODO(b/112245748): Should implement a DiffCallback.
- //Keep the old list for comparison.
- final List<HomepageCard> prevCards = mHomepageCards;
-
- //Remove the existing data that matches the certain cardType so as to insert the new data.
- for (int i = mHomepageCards.size() - 1; i >= 0; i--) {
- if (mHomepageCards.get(i).getCardType() == cardType) {
- mHomepageCards.remove(i);
- }
- }
-
- //Append the new data
- mHomepageCards.addAll(updateList);
-
- sortCards();
-
- if (mListener != null) {
- mListener.onHomepageCardUpdated(HomepageCard.CardType.INVALID, mHomepageCards);
- }
- }
-
- @Override
- public void onFinishCardLoading(List<HomepageCard> homepageCards) {
- mHomepageCards = homepageCards;
-
- //Force card sorting here in case CardControllers of custom view have nothing to update
- // for the first launch.
- sortCards();
-
- loadCardControllers();
- }
-
- void setListener(HomepageCardUpdateListener listener) {
- mListener = listener;
- }
-
- public ControllerRendererPool getControllerRendererPool() {
- return mControllerRendererPool;
- }
-}
diff --git a/src/com/android/settings/homepage/PersonalSettingsFragment.java b/src/com/android/settings/homepage/PersonalSettingsFragment.java
new file mode 100644
index 0000000..4a0041e
--- /dev/null
+++ b/src/com/android/settings/homepage/PersonalSettingsFragment.java
@@ -0,0 +1,68 @@
+/*
+ * 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.homepage;
+
+import static com.android.settings.homepage.ContextualCardsAdapter.SPAN_COUNT;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+import com.android.settings.core.InstrumentedFragment;
+
+public class PersonalSettingsFragment extends InstrumentedFragment {
+
+ private static final String TAG = "PersonalSettingsFragment";
+
+ private RecyclerView mCardsContainer;
+ private GridLayoutManager mLayoutManager;
+ private ContextualCardsAdapter mContextualCardsAdapter;
+ private ContextualCardManager mContextualCardManager;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContextualCardManager = new ContextualCardManager(getContext(), getSettingsLifecycle());
+ mContextualCardManager.loadContextualCards(this);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ final View rootView = inflater.inflate(R.layout.settings_homepage, container, false);
+ mCardsContainer = rootView.findViewById(R.id.card_container);
+ mLayoutManager = new GridLayoutManager(getActivity(), SPAN_COUNT,
+ GridLayoutManager.VERTICAL, false /* reverseLayout */);
+ mCardsContainer.setLayoutManager(mLayoutManager);
+ mContextualCardsAdapter = new ContextualCardsAdapter(getContext(), mContextualCardManager);
+ mCardsContainer.setAdapter(mContextualCardsAdapter);
+ mContextualCardManager.setListener(mContextualCardsAdapter);
+
+ return rootView;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.SETTINGS_HOMEPAGE;
+ }
+}
diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
new file mode 100644
index 0000000..35b45a4
--- /dev/null
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -0,0 +1,106 @@
+/*
+ * 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.homepage;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.FeatureFlagUtils;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+
+import com.android.settings.R;
+import com.android.settings.core.FeatureFlags;
+import com.android.settings.core.SettingsBaseActivity;
+import com.android.settings.overlay.FeatureFactory;
+
+import com.google.android.material.bottomnavigation.BottomNavigationView;
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+
+public class SettingsHomepageActivity extends SettingsBaseActivity {
+
+ @VisibleForTesting
+ static final String PERSONAL_SETTINGS_TAG = "personal_settings";
+ private static final String ALL_SETTINGS_TAG = "all_settings";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (!isDynamicHomepageEnabled(this)) {
+ final Intent settings = new Intent();
+ settings.setAction("android.settings.SETTINGS");
+ startActivity(settings);
+ finish();
+ return;
+ }
+
+ setContentView(R.layout.settings_homepage_container);
+
+ final FloatingActionButton searchButton = findViewById(R.id.search_fab);
+ FeatureFactory.getFactory(this).getSearchFeatureProvider()
+ .initSearchToolbar(this, searchButton);
+
+ final BottomNavigationView navigation = findViewById(R.id.bottom_nav);
+ navigation.setOnNavigationItemSelectedListener(item -> {
+ switch (item.getItemId()) {
+ case R.id.homepage_personal_settings:
+ switchFragment(new PersonalSettingsFragment(), PERSONAL_SETTINGS_TAG,
+ ALL_SETTINGS_TAG);
+ return true;
+
+ case R.id.homepage_all_settings:
+ switchFragment(new TopLevelSettings(), ALL_SETTINGS_TAG,
+ PERSONAL_SETTINGS_TAG);
+ return true;
+ }
+ return false;
+ });
+
+ if (savedInstanceState == null) {
+ // savedInstanceState is null, this is first load.
+ // Default to open contextual cards.
+ switchFragment(new PersonalSettingsFragment(), PERSONAL_SETTINGS_TAG,
+ ALL_SETTINGS_TAG);
+ }
+ }
+
+ public static boolean isDynamicHomepageEnabled(Context context) {
+ return FeatureFlagUtils.isEnabled(context, FeatureFlags.DYNAMIC_HOMEPAGE);
+ }
+
+ private void switchFragment(Fragment fragment, String showFragmentTag, String hideFragmentTag) {
+ final FragmentManager fragmentManager = getSupportFragmentManager();
+ final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+
+ final Fragment hideFragment = fragmentManager.findFragmentByTag(hideFragmentTag);
+ if (hideFragment != null) {
+ fragmentTransaction.hide(hideFragment);
+ }
+
+ Fragment showFragment = fragmentManager.findFragmentByTag(showFragmentTag);
+ if (showFragment == null) {
+ fragmentTransaction.add(R.id.main_content, fragment, showFragmentTag);
+ } else {
+ fragmentTransaction.show(showFragment);
+ }
+ fragmentTransaction.commit();
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java b/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java
new file mode 100644
index 0000000..fbbab14
--- /dev/null
+++ b/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java
@@ -0,0 +1,110 @@
+/*
+ * 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.homepage.conditional;
+
+import android.content.Context;
+import android.util.ArrayMap;
+
+import com.android.settings.homepage.ContextualCard;
+import com.android.settings.homepage.ContextualCardController;
+import com.android.settings.homepage.ContextualCardUpdateListener;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This controller triggers the loading of conditional cards and monitors state changes to
+ * update the homepage.
+ */
+public class ConditionContextualCardController implements ContextualCardController,
+ ConditionListener, LifecycleObserver, OnStart, OnStop {
+
+ private final Context mContext;
+ private final ConditionManager mConditionManager;
+
+ private ContextualCardUpdateListener mListener;
+
+ public ConditionContextualCardController(Context context) {
+ mContext = context;
+ mConditionManager = new ConditionManager(context.getApplicationContext(), this);
+ mConditionManager.startMonitoringStateChange();
+ }
+
+ @Override
+ public void setCardUpdateListener(ContextualCardUpdateListener listener) {
+ mListener = listener;
+ }
+
+ @Override
+ public int getCardType() {
+ return ContextualCard.CardType.CONDITIONAL;
+ }
+
+ @Override
+ public void onStart() {
+ mConditionManager.startMonitoringStateChange();
+ }
+
+ @Override
+ public void onStop() {
+ mConditionManager.stopMonitoringStateChange();
+ }
+
+ @Override
+ public void onPrimaryClick(ContextualCard contextualCard) {
+ final ConditionalContextualCard card = (ConditionalContextualCard) contextualCard;
+ mConditionManager.onPrimaryClick(mContext, card.getConditionId());
+ }
+
+ @Override
+ public void onActionClick(ContextualCard contextualCard) {
+ final ConditionalContextualCard card = (ConditionalContextualCard) contextualCard;
+ mConditionManager.onActionClick(card.getConditionId());
+ }
+
+ @Override
+ public void onConditionsChanged() {
+ final List<ContextualCard> conditionCards = new ArrayList<>();
+ final List<ConditionalCard> conditionList = mConditionManager.getDisplayableCards();
+
+ for (ConditionalCard condition : conditionList) {
+ final ContextualCard conditionCard =
+ new ConditionalContextualCard.Builder()
+ .setConditionId(condition.getId())
+ .setMetricsConstant(condition.getMetricsConstant())
+ .setActionText(condition.getActionText())
+ .setName(mContext.getPackageName() + "/"
+ + condition.getTitle().toString())
+ .setTitleText(condition.getTitle().toString())
+ .setSummaryText(condition.getSummary().toString())
+ .setIconDrawable(condition.getIcon())
+ .build();
+
+ conditionCards.add(conditionCard);
+ }
+
+ if (mListener != null) {
+ final Map<Integer, List<ContextualCard>> conditionalCards = new ArrayMap<>();
+ conditionalCards.put(ContextualCard.CardType.CONDITIONAL, conditionCards);
+ mListener.onContextualCardUpdated(conditionalCards);
+ }
+ }
+}
diff --git a/src/com/android/settings/homepage/conditional/ConditionContextualCardRenderer.java b/src/com/android/settings/homepage/conditional/ConditionContextualCardRenderer.java
new file mode 100644
index 0000000..69988ae
--- /dev/null
+++ b/src/com/android/settings/homepage/conditional/ConditionContextualCardRenderer.java
@@ -0,0 +1,137 @@
+/*
+ * 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.homepage.conditional;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.homepage.ContextualCard;
+import com.android.settings.homepage.ControllerRendererPool;
+import com.android.settings.homepage.ContextualCardRenderer;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+
+/**
+ * Card renderer for {@link ConditionalContextualCard}.
+ */
+public class ConditionContextualCardRenderer implements ContextualCardRenderer {
+
+ private final Context mContext;
+ private final ControllerRendererPool mControllerRendererPool;
+
+ public ConditionContextualCardRenderer(Context context,
+ ControllerRendererPool controllerRendererPool) {
+ mContext = context;
+ mControllerRendererPool = controllerRendererPool;
+ }
+
+ @Override
+ public int getViewType() {
+ return R.layout.homepage_condition_tile;
+ }
+
+ @Override
+ public RecyclerView.ViewHolder createViewHolder(View view) {
+ return new ConditionalCardHolder(view);
+ }
+
+ @Override
+ public void bindView(RecyclerView.ViewHolder holder, ContextualCard contextualCard) {
+ final ConditionalCardHolder view = (ConditionalCardHolder) holder;
+ final ConditionalContextualCard card = (ConditionalContextualCard) contextualCard;
+ final MetricsFeatureProvider metricsFeatureProvider = FeatureFactory.getFactory(
+ mContext).getMetricsFeatureProvider();
+
+ metricsFeatureProvider.visible(mContext, MetricsProto.MetricsEvent.SETTINGS_HOMEPAGE,
+ card.getMetricsConstant());
+ initializePrimaryClick(view, card, metricsFeatureProvider);
+ initializeView(view, card);
+ initializeActionButton(view, card, metricsFeatureProvider);
+ }
+
+ private void initializePrimaryClick(ConditionalCardHolder view, ConditionalContextualCard card,
+ MetricsFeatureProvider metricsFeatureProvider) {
+ view.itemView.findViewById(R.id.content).setOnClickListener(
+ v -> {
+ metricsFeatureProvider.action(mContext,
+ MetricsProto.MetricsEvent.ACTION_SETTINGS_CONDITION_CLICK,
+ card.getMetricsConstant());
+ mControllerRendererPool.getController(mContext,
+ card.getCardType()).onPrimaryClick(card);
+ });
+ }
+
+ private void initializeView(ConditionalCardHolder view, ConditionalContextualCard card) {
+ view.icon.setImageDrawable(card.getIconDrawable());
+ view.title.setText(card.getTitleText());
+ view.summary.setText(card.getSummaryText());
+
+ setViewVisibility(view.itemView, R.id.divider, false);
+ }
+
+ private void initializeActionButton(ConditionalCardHolder view, ConditionalContextualCard card,
+ MetricsFeatureProvider metricsFeatureProvider) {
+ final CharSequence action = card.getActionText();
+ final boolean hasButtons = !TextUtils.isEmpty(action);
+ setViewVisibility(view.itemView, R.id.buttonBar, hasButtons);
+
+ final Button button = view.itemView.findViewById(R.id.first_action);
+ if (hasButtons) {
+ button.setVisibility(View.VISIBLE);
+ button.setText(action);
+ button.setOnClickListener(v -> {
+ final Context viewContext = v.getContext();
+ metricsFeatureProvider.action(
+ viewContext, MetricsProto.MetricsEvent.ACTION_SETTINGS_CONDITION_BUTTON,
+ card.getMetricsConstant());
+ mControllerRendererPool.getController(mContext, card.getCardType()).onActionClick(
+ card);
+ });
+ } else {
+ button.setVisibility(View.GONE);
+ }
+ }
+
+ private void setViewVisibility(View containerView, int viewId, boolean visible) {
+ View view = containerView.findViewById(viewId);
+ if (view != null) {
+ view.setVisibility(visible ? View.VISIBLE : View.GONE);
+ }
+ }
+
+ public static class ConditionalCardHolder extends RecyclerView.ViewHolder {
+
+ public final ImageView icon;
+ public final TextView title;
+ public final TextView summary;
+
+ public ConditionalCardHolder(View itemView) {
+ super(itemView);
+ icon = itemView.findViewById(android.R.id.icon);
+ title = itemView.findViewById(android.R.id.title);
+ summary = itemView.findViewById(android.R.id.summary);
+ }
+ }
+}
diff --git a/src/com/android/settings/homepage/conditional/ConditionalContextualCard.java b/src/com/android/settings/homepage/conditional/ConditionalContextualCard.java
new file mode 100644
index 0000000..828f90b
--- /dev/null
+++ b/src/com/android/settings/homepage/conditional/ConditionalContextualCard.java
@@ -0,0 +1,91 @@
+/*
+ * 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.homepage.conditional;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.settings.homepage.ContextualCard;
+
+/**
+ * Data class representing a conditional {@link ContextualCard}.
+ *
+ * Use this class to store additional attributes on top of {@link ContextualCard} for
+ * {@link ConditionalCard}.
+ */
+public class ConditionalContextualCard extends ContextualCard {
+
+ private final long mConditionId;
+ private final int mMetricsConstant;
+ private final CharSequence mActionText;
+
+ private ConditionalContextualCard(Builder builder) {
+ super(builder);
+
+ mConditionId = builder.mConditionId;
+ mMetricsConstant = builder.mMetricsConstant;
+ mActionText = builder.mActionText;
+ }
+
+ @Override
+ public int getCardType() {
+ return CardType.CONDITIONAL;
+ }
+
+ public long getConditionId() {
+ return mConditionId;
+ }
+
+ public int getMetricsConstant() {
+ return mMetricsConstant;
+ }
+
+ public CharSequence getActionText() {
+ return mActionText;
+ }
+
+ public static class Builder extends ContextualCard.Builder {
+
+ private long mConditionId;
+ private int mMetricsConstant;
+ private CharSequence mActionText;
+
+ public Builder setConditionId(long id) {
+ mConditionId = id;
+ return this;
+ }
+
+ public Builder setMetricsConstant(int metricsConstant) {
+ mMetricsConstant = metricsConstant;
+ return this;
+ }
+
+ public Builder setActionText(CharSequence actionText) {
+ mActionText = actionText;
+ return this;
+ }
+
+ @Override
+ public Builder setCardType(int cardType) {
+ throw new IllegalArgumentException(
+ "Cannot change card type for " + getClass().getName());
+ }
+
+ public ConditionalContextualCard build() {
+ return new ConditionalContextualCard(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/homepage/conditional/HotspotConditionCard.java b/src/com/android/settings/homepage/conditional/HotspotConditionCard.java
index a6ff224..fd99693 100644
--- a/src/com/android/settings/homepage/conditional/HotspotConditionCard.java
+++ b/src/com/android/settings/homepage/conditional/HotspotConditionCard.java
@@ -23,7 +23,7 @@
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
public class HotspotConditionCard implements ConditionalCard {
@@ -42,7 +42,7 @@
@Override
public CharSequence getActionText() {
- if (RestrictedLockUtils.hasBaseUserRestriction(mAppContext,
+ if (RestrictedLockUtilsInternal.hasBaseUserRestriction(mAppContext,
UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.myUserId())) {
return null;
}
diff --git a/src/com/android/settings/homepage/conditional/HotspotConditionController.java b/src/com/android/settings/homepage/conditional/HotspotConditionController.java
index 4271136..5ff7f23 100644
--- a/src/com/android/settings/homepage/conditional/HotspotConditionController.java
+++ b/src/com/android/settings/homepage/conditional/HotspotConditionController.java
@@ -31,6 +31,7 @@
import com.android.settings.TetherSettings;
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import java.util.Objects;
@@ -75,7 +76,7 @@
@Override
public void onActionClick() {
final RestrictedLockUtils.EnforcedAdmin admin =
- RestrictedLockUtils.checkIfRestrictionEnforced(
+ RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
mAppContext, UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.myUserId());
if (admin != null) {
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mAppContext, admin);
diff --git a/src/com/android/settings/location/LocationEnabler.java b/src/com/android/settings/location/LocationEnabler.java
index 65de6e2..20c2280 100644
--- a/src/com/android/settings/location/LocationEnabler.java
+++ b/src/com/android/settings/location/LocationEnabler.java
@@ -13,7 +13,7 @@
*/
package com.android.settings.location;
-import static com.android.settingslib.RestrictedLockUtils.checkIfRestrictionEnforced;
+import static com.android.settingslib.RestrictedLockUtilsInternal.checkIfRestrictionEnforced;
import static com.android.settingslib.Utils.updateLocationEnabled;
import static com.android.settingslib.Utils.updateLocationMode;
@@ -32,6 +32,7 @@
import com.android.settings.Utils;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnPause;
@@ -168,14 +169,14 @@
mContext, UserManager.DISALLOW_SHARE_LOCATION, userId);
if (admin == null) {
- admin = RestrictedLockUtils.checkIfRestrictionEnforced(
+ admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
mContext, UserManager.DISALLOW_CONFIG_LOCATION, userId);
}
return admin;
}
boolean hasShareLocationRestriction(int userId) {
- return RestrictedLockUtils.hasBaseUserRestriction(
+ return RestrictedLockUtilsInternal.hasBaseUserRestriction(
mContext, UserManager.DISALLOW_SHARE_LOCATION, userId);
}
diff --git a/src/com/android/settings/network/MobileNetworkPreferenceController.java b/src/com/android/settings/network/MobileNetworkPreferenceController.java
index ece4294..4230c67 100644
--- a/src/com/android/settings/network/MobileNetworkPreferenceController.java
+++ b/src/com/android/settings/network/MobileNetworkPreferenceController.java
@@ -36,7 +36,7 @@
import com.android.settings.core.FeatureFlags;
import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.Utils;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -84,7 +84,7 @@
public boolean isUserRestricted() {
return mIsSecondaryUser ||
- RestrictedLockUtils.hasBaseUserRestriction(
+ RestrictedLockUtilsInternal.hasBaseUserRestriction(
mContext,
DISALLOW_CONFIG_MOBILE_NETWORKS,
myUserId());
diff --git a/src/com/android/settings/network/MobilePlanPreferenceController.java b/src/com/android/settings/network/MobilePlanPreferenceController.java
index 1db6b2e..dc41708 100644
--- a/src/com/android/settings/network/MobilePlanPreferenceController.java
+++ b/src/com/android/settings/network/MobilePlanPreferenceController.java
@@ -20,7 +20,7 @@
import static android.os.UserHandle.myUserId;
import static android.os.UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS;
-import static com.android.settingslib.RestrictedLockUtils.hasBaseUserRestriction;
+import static com.android.settingslib.RestrictedLockUtilsInternal.hasBaseUserRestriction;
import android.content.ActivityNotFoundException;
import android.content.Context;
diff --git a/src/com/android/settings/network/NetworkDashboardFragment.java b/src/com/android/settings/network/NetworkDashboardFragment.java
index a2a2450..0279cfa 100644
--- a/src/com/android/settings/network/NetworkDashboardFragment.java
+++ b/src/com/android/settings/network/NetworkDashboardFragment.java
@@ -15,12 +15,15 @@
*/
package com.android.settings.network;
+import static android.provider.Settings.ACTION_DATA_USAGE_SETTINGS;
import static com.android.settings.network.MobilePlanPreferenceController
.MANAGE_MOBILE_PLAN_DIALOG_ID;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
import android.icu.text.ListFormatter;
import android.provider.SearchIndexableResource;
import android.text.BidiFormatter;
@@ -45,6 +48,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.function.BooleanSupplier;
import java.util.List;
@SearchIndexable
@@ -158,24 +162,32 @@
private final WifiMasterSwitchPreferenceController mWifiPreferenceController;
private final MobileNetworkPreferenceController mMobileNetworkPreferenceController;
private final TetherPreferenceController mTetherPreferenceController;
+ private final BooleanSupplier mHasDataUsageActivity;
public SummaryProvider(Context context, SummaryLoader summaryLoader) {
this(context, summaryLoader,
new WifiMasterSwitchPreferenceController(context, null),
new MobileNetworkPreferenceController(context),
- new TetherPreferenceController(context, null /* lifecycle */));
+ new TetherPreferenceController(context, null /* lifecycle */),
+ () -> {
+ final Intent intent = new Intent(ACTION_DATA_USAGE_SETTINGS);
+ final PackageManager pm = context.getPackageManager();
+ return intent.resolveActivity(pm) != null;
+ });
}
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
SummaryProvider(Context context, SummaryLoader summaryLoader,
WifiMasterSwitchPreferenceController wifiPreferenceController,
MobileNetworkPreferenceController mobileNetworkPreferenceController,
- TetherPreferenceController tetherPreferenceController) {
+ TetherPreferenceController tetherPreferenceController,
+ BooleanSupplier hasDataUsageActivity) {
mContext = context;
mSummaryLoader = summaryLoader;
mWifiPreferenceController = wifiPreferenceController;
mMobileNetworkPreferenceController = mobileNetworkPreferenceController;
mTetherPreferenceController = tetherPreferenceController;
+ mHasDataUsageActivity = hasDataUsageActivity;
}
@@ -198,7 +210,7 @@
if (mMobileNetworkPreferenceController.isAvailable() && !TextUtils.isEmpty(mobileSummary)) {
summaries.add(mobileSummary);
}
- if (!TextUtils.isEmpty(dataUsageSummary)) {
+ if (!TextUtils.isEmpty(dataUsageSummary) && mHasDataUsageActivity.getAsBoolean()) {
summaries.add(dataUsageSummary);
}
if (mTetherPreferenceController.isAvailable() && !TextUtils.isEmpty(hotspotSummary)) {
diff --git a/src/com/android/settings/network/NetworkResetRestrictionChecker.java b/src/com/android/settings/network/NetworkResetRestrictionChecker.java
index bb1fde7..46227f9 100644
--- a/src/com/android/settings/network/NetworkResetRestrictionChecker.java
+++ b/src/com/android/settings/network/NetworkResetRestrictionChecker.java
@@ -22,7 +22,7 @@
import androidx.annotation.VisibleForTesting;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
public class NetworkResetRestrictionChecker {
@@ -36,13 +36,13 @@
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
boolean hasUserBaseRestriction() {
- return RestrictedLockUtils.hasBaseUserRestriction(mContext,
+ return RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext,
UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId());
}
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
boolean isRestrictionEnforcedByAdmin() {
- return RestrictedLockUtils.checkIfRestrictionEnforced(
+ return RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
mContext, UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId()) != null;
}
diff --git a/src/com/android/settings/network/TetherPreferenceController.java b/src/com/android/settings/network/TetherPreferenceController.java
index f9a03d9..0d4a6a6 100644
--- a/src/com/android/settings/network/TetherPreferenceController.java
+++ b/src/com/android/settings/network/TetherPreferenceController.java
@@ -17,7 +17,7 @@
import static android.os.UserManager.DISALLOW_CONFIG_TETHERING;
-import static com.android.settingslib.RestrictedLockUtils.checkIfRestrictionEnforced;
+import static com.android.settingslib.RestrictedLockUtilsInternal.checkIfRestrictionEnforced;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothPan;
diff --git a/src/com/android/settings/network/VpnPreferenceController.java b/src/com/android/settings/network/VpnPreferenceController.java
index 8ecd796..62589d5 100644
--- a/src/com/android/settings/network/VpnPreferenceController.java
+++ b/src/com/android/settings/network/VpnPreferenceController.java
@@ -40,7 +40,7 @@
import com.android.internal.net.VpnConfig;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnPause;
@@ -92,7 +92,7 @@
@Override
public boolean isAvailable() {
- return !RestrictedLockUtils.hasBaseUserRestriction(mContext,
+ return !RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext,
UserManager.DISALLOW_CONFIG_VPN, UserHandle.myUserId());
}
diff --git a/src/com/android/settings/nfc/AndroidBeam.java b/src/com/android/settings/nfc/AndroidBeam.java
index efa6041..2b7f872 100644
--- a/src/com/android/settings/nfc/AndroidBeam.java
+++ b/src/com/android/settings/nfc/AndroidBeam.java
@@ -38,7 +38,7 @@
import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper;
import com.android.settings.widget.SwitchBar;
import com.android.settingslib.HelpUtils;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
public class AndroidBeam extends InstrumentedFragment
implements SwitchBar.OnSwitchChangeListener {
@@ -68,10 +68,10 @@
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(
+ final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
getActivity(), UserManager.DISALLOW_OUTGOING_BEAM, UserHandle.myUserId());
final UserManager um = UserManager.get(getActivity());
- mBeamDisallowedByBase = RestrictedLockUtils.hasBaseUserRestriction(getActivity(),
+ mBeamDisallowedByBase = RestrictedLockUtilsInternal.hasBaseUserRestriction(getActivity(),
UserManager.DISALLOW_OUTGOING_BEAM, UserHandle.myUserId());
if (!mBeamDisallowedByBase && admin != null) {
new ActionDisabledByAdminDialogHelper(getActivity())
diff --git a/src/com/android/settings/nfc/AndroidBeamEnabler.java b/src/com/android/settings/nfc/AndroidBeamEnabler.java
index 1808775..4dda2fd 100644
--- a/src/com/android/settings/nfc/AndroidBeamEnabler.java
+++ b/src/com/android/settings/nfc/AndroidBeamEnabler.java
@@ -22,7 +22,7 @@
import android.os.UserManager;
import com.android.settings.R;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
/**
@@ -36,7 +36,7 @@
public AndroidBeamEnabler(Context context, RestrictedPreference preference) {
super(context);
mPreference = preference;
- mBeamDisallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(context,
+ mBeamDisallowedBySystem = RestrictedLockUtilsInternal.hasBaseUserRestriction(context,
UserManager.DISALLOW_OUTGOING_BEAM, UserHandle.myUserId());
if (!isNfcAvailable()) {
// NFC is not supported
diff --git a/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java b/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
index d708edf..1563bc4 100644
--- a/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
+++ b/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
@@ -41,6 +41,7 @@
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnPause;
@@ -246,7 +247,7 @@
private void setRestrictedIfNotificationFeaturesDisabled(CharSequence entry,
CharSequence entryValue, int keyguardNotificationFeatures) {
RestrictedLockUtils.EnforcedAdmin admin =
- RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
+ RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
mContext, keyguardNotificationFeatures, UserHandle.myUserId());
if (admin != null && mLockscreen != null) {
RestrictedListPreference.RestrictedItem item =
@@ -255,7 +256,7 @@
}
if (mProfileUserId != UserHandle.USER_NULL) {
RestrictedLockUtils.EnforcedAdmin profileAdmin =
- RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
+ RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
mContext, keyguardNotificationFeatures, mProfileUserId);
if (profileAdmin != null && mLockscreenProfile != null) {
RestrictedListPreference.RestrictedItem item =
diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java
index 01f1228..03b4ec3 100644
--- a/src/com/android/settings/notification/NotificationBackend.java
+++ b/src/com/android/settings/notification/NotificationBackend.java
@@ -78,6 +78,12 @@
return row;
}
+ public boolean isBlockable(Context context, ApplicationInfo info) {
+ final boolean blocked = getNotificationsBanned(info.packageName, info.uid);
+ final boolean systemApp = isSystemApp(context, info);
+ return !systemApp || (systemApp && blocked);
+ }
+
public AppRow loadAppRow(Context context, PackageManager pm, PackageInfo app) {
final AppRow row = loadAppRow(context, pm, app.applicationInfo);
recordCanBeBlocked(context, pm, app, row);
diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java
index a645c4b..ed0b123 100644
--- a/src/com/android/settings/notification/NotificationSettingsBase.java
+++ b/src/com/android/settings/notification/NotificationSettingsBase.java
@@ -51,7 +51,7 @@
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.widget.MasterCheckBoxPreference;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import java.util.ArrayList;
import java.util.Comparator;
@@ -112,19 +112,22 @@
mPkgInfo = findPackageInfo(mPkg, mUid);
- mUserId = UserHandle.getUserId(mUid);
- mSuspendedAppsAdmin = RestrictedLockUtils.checkIfApplicationIsSuspended(
- mContext, mPkg, mUserId);
+ if (mPkgInfo != null) {
+ mUserId = UserHandle.getUserId(mUid);
+ mSuspendedAppsAdmin = RestrictedLockUtilsInternal.checkIfApplicationIsSuspended(
+ mContext, mPkg, mUserId);
- loadChannel();
- loadAppRow();
- loadChannelGroup();
- collectConfigActivities();
- getSettingsLifecycle().addObserver(use(HeaderPreferenceController.class));
+ loadChannel();
+ loadAppRow();
+ loadChannelGroup();
+ collectConfigActivities();
- for (NotificationPreferenceController controller : mControllers) {
- controller.onResume(mAppRow, mChannel, mChannelGroup, mSuspendedAppsAdmin);
+ getSettingsLifecycle().addObserver(use(HeaderPreferenceController.class));
+
+ for (NotificationPreferenceController controller : mControllers) {
+ controller.onResume(mAppRow, mChannel, mChannelGroup, mSuspendedAppsAdmin);
+ }
}
}
diff --git a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
index a027aec..bbc01f5 100644
--- a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
+++ b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
@@ -82,17 +82,6 @@
private Preference mSeeAllPref;
private Preference mDivider;
- static {
- SKIP_SYSTEM_PACKAGES.addAll(Arrays.asList(
- "android",
- "com.android.phone",
- "com.android.settings",
- "com.android.systemui",
- "com.android.providers.calendar",
- "com.android.providers.media"
- ));
- }
-
public RecentNotifyingAppsPreferenceController(Context context, NotificationBackend backend,
Application app, Fragment host) {
this(context, backend, app == null ? null : ApplicationsState.getInstance(app), host);
@@ -226,6 +215,7 @@
.setSourceMetricsCategory(
MetricsProto.MetricsEvent.MANAGE_APPLICATIONS_NOTIFICATIONS)
.toIntent());
+ pref.setEnabled(mNotificationBackend.isBlockable(mContext, appEntry.info));
pref.setOnPreferenceChangeListener((preference, newValue) -> {
boolean blocked = !(Boolean) newValue;
mNotificationBackend.setNotificationsEnabledForPackage(
@@ -272,10 +262,6 @@
* Whether or not the app should be included in recent list.
*/
private boolean shouldIncludePkgInRecents(String pkgName) {
- if (SKIP_SYSTEM_PACKAGES.contains(pkgName)) {
- Log.d(TAG, "System package, skipping " + pkgName);
- return false;
- }
final Intent launchIntent = new Intent().addCategory(Intent.CATEGORY_LAUNCHER)
.setPackage(pkgName);
diff --git a/src/com/android/settings/notification/RedactionInterstitial.java b/src/com/android/settings/notification/RedactionInterstitial.java
index 517c041..32dc52d 100644
--- a/src/com/android/settings/notification/RedactionInterstitial.java
+++ b/src/com/android/settings/notification/RedactionInterstitial.java
@@ -47,6 +47,7 @@
import com.android.settings.SetupWizardUtils;
import com.android.settings.Utils;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
public class RedactionInterstitial extends SettingsActivity {
@@ -160,7 +161,7 @@
private void checkNotificationFeaturesAndSetDisabled(RestrictedRadioButton button,
int keyguardNotifications) {
- EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
+ EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
getActivity(), keyguardNotifications, mUserId);
button.setDisabledByAdmin(admin);
}
diff --git a/src/com/android/settings/notification/VisibilityPreferenceController.java b/src/com/android/settings/notification/VisibilityPreferenceController.java
index 578a6c3..fe036e9 100644
--- a/src/com/android/settings/notification/VisibilityPreferenceController.java
+++ b/src/com/android/settings/notification/VisibilityPreferenceController.java
@@ -33,6 +33,7 @@
import com.android.settings.RestrictedListPreference;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import java.util.ArrayList;
@@ -128,7 +129,7 @@
private void setRestrictedIfNotificationFeaturesDisabled(RestrictedListPreference pref,
CharSequence entry, CharSequence entryValue, int keyguardNotificationFeatures) {
RestrictedLockUtils.EnforcedAdmin admin =
- RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
+ RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
mContext, keyguardNotificationFeatures, mAppRow.userId);
if (admin != null) {
RestrictedListPreference.RestrictedItem item =
diff --git a/src/com/android/settings/overlay/SupportFeatureProvider.java b/src/com/android/settings/overlay/SupportFeatureProvider.java
index a9b66d6..b22b458 100644
--- a/src/com/android/settings/overlay/SupportFeatureProvider.java
+++ b/src/com/android/settings/overlay/SupportFeatureProvider.java
@@ -16,55 +16,17 @@
package com.android.settings.overlay;
-import android.accounts.Account;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
import android.app.Activity;
-import android.content.Context;
-
-import com.android.settings.support.SupportPhone;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
/**
* Feature provider for support tab.
*/
public interface SupportFeatureProvider {
- @IntDef({SupportType.EMAIL, SupportType.PHONE, SupportType.CHAT})
- @Retention(RetentionPolicy.SOURCE)
- @interface SupportType {
- int EMAIL = 1;
- int PHONE = 2;
- int CHAT = 3;
- }
-
/**
- * Refreshes all operation rules.
- */
- void refreshOperationRules();
-
- /**
- * Returns the current country code if it has a operation config, otherwise returns null.
- */
- String getCurrentCountryCodeIfHasConfig(@SupportType int type);
-
- /**
- * Returns a support phone for specified country.
- */
- SupportPhone getSupportPhones(String countryCode, boolean isTollfree);
-
- /**
- * Returns array of {@link Account} that's eligible for support options.
- */
- @NonNull
- Account[] getSupportEligibleAccounts(Context context);
-
- /**
- * Starts support v2, invokes the support home page. Will no-op if support v2 is not enabled.
+ * Starts support, invokes the support home page.
*
* @param activity Calling activity.
*/
- void startSupportV2(Activity activity);
+ void startSupport(Activity activity);
}
diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java
index 6edacda..df2d3cd 100644
--- a/src/com/android/settings/password/ChooseLockGeneric.java
+++ b/src/com/android/settings/password/ChooseLockGeneric.java
@@ -64,8 +64,8 @@
import com.android.settings.biometrics.fingerprint.FingerprintEnrollFindSensor;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.search.SearchFeatureProvider;
-import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import java.util.List;
@@ -562,7 +562,7 @@
final PreferenceScreen entries = getPreferenceScreen();
int adminEnforcedQuality = mDPM.getPasswordQuality(null, mUserId);
- EnforcedAdmin enforcedAdmin = RestrictedLockUtils.checkIfPasswordQualityIsSet(
+ EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal.checkIfPasswordQualityIsSet(
getActivity(), mUserId);
for (ScreenLockType lock : ScreenLockType.values()) {
@@ -813,7 +813,7 @@
// TODO: figure out how to eliminate duplicated code. It's a bit hard due to the async-ness
private void removeAllFaceForUserAndFinish(final int userId, RemovalTracker tracker) {
if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
- if (mFaceManager.hasEnrolledFaces(userId)) {
+ if (mFaceManager.hasEnrolledTemplates(userId)) {
mFaceManager.setActiveUser(userId);
Face face = new Face(null, 0, 0);
mFaceManager.remove(face, userId,
diff --git a/src/com/android/settings/password/SetNewPasswordController.java b/src/com/android/settings/password/SetNewPasswordController.java
index f3bcedc..d5641cd 100644
--- a/src/com/android/settings/password/SetNewPasswordController.java
+++ b/src/com/android/settings/password/SetNewPasswordController.java
@@ -115,7 +115,7 @@
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)
&& mFaceManager != null
&& mFaceManager.isHardwareDetected()
- && !mFaceManager.hasEnrolledFaces(mTargetUserId)
+ && !mFaceManager.hasEnrolledTemplates(mTargetUserId)
&& !isFaceDisabledByAdmin()) {
extras = getFaceChooseLockExtras();
} else if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)
diff --git a/src/com/android/settings/search/SearchFeatureProvider.java b/src/com/android/settings/search/SearchFeatureProvider.java
index 6744a7b..c19ccef 100644
--- a/src/com/android/settings/search/SearchFeatureProvider.java
+++ b/src/com/android/settings/search/SearchFeatureProvider.java
@@ -21,7 +21,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.widget.Toolbar;
+import android.view.View;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.search.SearchIndexableResources;
@@ -55,11 +55,11 @@
/**
* Initializes the search toolbar.
*/
- default void initSearchToolbar(Activity activity, Toolbar toolbar) {
- if (activity == null || toolbar == null) {
+ default void initSearchToolbar(Activity activity, View view) {
+ if (activity == null || view == null) {
return;
}
- toolbar.setOnClickListener(tb -> {
+ view.setOnClickListener(tb -> {
final Intent intent = SEARCH_UI_INTENT;
intent.setPackage(getSettingsIntelligencePkgName());
diff --git a/src/com/android/settings/security/ChangeScreenLockPreferenceController.java b/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
index ae857ce..a58c528 100644
--- a/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
+++ b/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
@@ -36,6 +36,7 @@
import com.android.settings.security.screenlock.ScreenLockSettings;
import com.android.settings.widget.GearPreference;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -170,7 +171,7 @@
* DO or PO installed in the user may disallow to change password.
*/
void disableIfPasswordQualityManaged(int userId) {
- final RestrictedLockUtils.EnforcedAdmin admin = RestrictedLockUtils
+ final RestrictedLockUtils.EnforcedAdmin admin = RestrictedLockUtilsInternal
.checkIfPasswordQualityIsSet(mContext, userId);
final DevicePolicyManager dpm = (DevicePolicyManager) mContext
.getSystemService(Context.DEVICE_POLICY_SERVICE);
diff --git a/src/com/android/settings/security/LockUnificationPreferenceController.java b/src/com/android/settings/security/LockUnificationPreferenceController.java
index 71be0ae..1aebe24 100644
--- a/src/com/android/settings/security/LockUnificationPreferenceController.java
+++ b/src/com/android/settings/security/LockUnificationPreferenceController.java
@@ -39,7 +39,7 @@
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.password.ChooseLockSettingsHelper;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -136,8 +136,9 @@
mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileUserId);
mUnifyProfile.setChecked(!separate);
if (separate) {
- mUnifyProfile.setDisabledByAdmin(RestrictedLockUtils.checkIfRestrictionEnforced(
- mContext, UserManager.DISALLOW_UNIFIED_PASSWORD, mProfileUserId));
+ mUnifyProfile.setDisabledByAdmin(RestrictedLockUtilsInternal
+ .checkIfRestrictionEnforced(mContext, UserManager.DISALLOW_UNIFIED_PASSWORD,
+ mProfileUserId));
}
}
}
diff --git a/src/com/android/settings/security/OwnerInfoPreferenceController.java b/src/com/android/settings/security/OwnerInfoPreferenceController.java
index 226e887..f7a20ba 100644
--- a/src/com/android/settings/security/OwnerInfoPreferenceController.java
+++ b/src/com/android/settings/security/OwnerInfoPreferenceController.java
@@ -27,8 +27,8 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.users.OwnerInfoSettings;
-import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -140,6 +140,6 @@
@VisibleForTesting
EnforcedAdmin getDeviceOwner() {
- return RestrictedLockUtils.getDeviceOwner(mContext);
+ return RestrictedLockUtilsInternal.getDeviceOwner(mContext);
}
}
diff --git a/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceController.java b/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceController.java
index a003d3b..999c945 100644
--- a/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceController.java
+++ b/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceController.java
@@ -34,6 +34,7 @@
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.security.trustagent.TrustAgentManager;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.core.AbstractPreferenceController;
public class LockAfterTimeoutPreferenceController extends AbstractPreferenceController
@@ -106,7 +107,7 @@
preference.setValue(String.valueOf(currentTimeout));
if (mDPM != null) {
final RestrictedLockUtils.EnforcedAdmin admin =
- RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(mContext);
+ RestrictedLockUtilsInternal.checkIfMaximumTimeToLockIsSet(mContext);
final long adminTimeout =
mDPM.getMaximumTimeToLock(null /* admin */, UserHandle.myUserId());
final long displayTimeout = Math.max(0,
diff --git a/src/com/android/settings/security/trustagent/TrustAgentManager.java b/src/com/android/settings/security/trustagent/TrustAgentManager.java
index feac9fa..e039db8 100644
--- a/src/com/android/settings/security/trustagent/TrustAgentManager.java
+++ b/src/com/android/settings/security/trustagent/TrustAgentManager.java
@@ -39,6 +39,7 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -113,7 +114,7 @@
final List<ResolveInfo> resolveInfos = pm.queryIntentServices(TRUST_AGENT_INTENT,
PackageManager.GET_META_DATA);
final List<ComponentName> enabledTrustAgents = utils.getEnabledTrustAgents(myUserId);
- final RestrictedLockUtils.EnforcedAdmin admin = RestrictedLockUtils
+ final RestrictedLockUtils.EnforcedAdmin admin = RestrictedLockUtilsInternal
.checkIfKeyguardFeaturesDisabled(
context, DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS, myUserId);
diff --git a/src/com/android/settings/security/trustagent/TrustAgentsPreferenceController.java b/src/com/android/settings/security/trustagent/TrustAgentsPreferenceController.java
index 5088d31..4268839 100644
--- a/src/com/android/settings/security/trustagent/TrustAgentsPreferenceController.java
+++ b/src/com/android/settings/security/trustagent/TrustAgentsPreferenceController.java
@@ -40,7 +40,7 @@
import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.security.SecurityFeatureProvider;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
@@ -97,8 +97,8 @@
loadActiveAgents();
removeUselessExistingPreferences();
- final EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(mContext,
- DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS, UserHandle.myUserId());
+ final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
+ mContext, DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS, UserHandle.myUserId());
for (TrustAgentInfo agent : mAvailableAgents.values()) {
final ComponentName componentName = agent.getComponentName();
diff --git a/src/com/android/settings/support/SupportDashboardActivity.java b/src/com/android/settings/support/SupportDashboardActivity.java
index ed7e76c..245810a 100644
--- a/src/com/android/settings/support/SupportDashboardActivity.java
+++ b/src/com/android/settings/support/SupportDashboardActivity.java
@@ -43,9 +43,9 @@
SupportFeatureProvider supportFeatureProvider = FeatureFactory.getFactory(this)
.getSupportFeatureProvider(this);
- // try to launch support v2 if we have the feature provider
+ // try to launch support if we have the feature provider
if (supportFeatureProvider != null) {
- supportFeatureProvider.startSupportV2(this);
+ supportFeatureProvider.startSupport(this);
finish();
}
}
diff --git a/src/com/android/settings/support/SupportPhone.java b/src/com/android/settings/support/SupportPhone.java
deleted file mode 100644
index d27dca5..0000000
--- a/src/com/android/settings/support/SupportPhone.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.support;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import java.text.ParseException;
-
-/**
- * Data model for a support phone number.
- */
-public final class SupportPhone implements Parcelable {
-
- public final String language;
- public final String number;
- public final boolean isTollFree;
-
- public SupportPhone(String config) throws ParseException {
- // Config follows this format: language:[tollfree|tolled]:number
- final String[] tokens = config.split(":");
- if (tokens.length != 3) {
- throw new ParseException("Phone config is invalid " + config, 0);
- }
- language = tokens[0];
- isTollFree = TextUtils.equals(tokens[1], "tollfree");
- number = tokens[2];
- }
-
- protected SupportPhone(Parcel in) {
- language = in.readString();
- number = in.readString();
- isTollFree = in.readInt() != 0;
- }
-
- public Intent getDialIntent() {
- return new Intent(Intent.ACTION_DIAL)
- .setData(new Uri.Builder()
- .scheme("tel")
- .appendPath(number)
- .build());
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(language);
- dest.writeString(number);
- dest.writeInt(isTollFree ? 1 : 0);
- }
-
- public static final Creator<SupportPhone> CREATOR = new Creator<SupportPhone>() {
- @Override
- public SupportPhone createFromParcel(Parcel in) {
- return new SupportPhone(in);
- }
-
- @Override
- public SupportPhone[] newArray(int size) {
- return new SupportPhone[size];
- }
- };
-}
diff --git a/src/com/android/settings/users/EditUserPhotoController.java b/src/com/android/settings/users/EditUserPhotoController.java
index f7d7e86..3253f79 100644
--- a/src/com/android/settings/users/EditUserPhotoController.java
+++ b/src/com/android/settings/users/EditUserPhotoController.java
@@ -53,6 +53,7 @@
import com.android.settings.R;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.drawable.CircleFramedDrawable;
import libcore.io.Streams;
@@ -419,9 +420,9 @@
mAction = action;
final int myUserId = UserHandle.myUserId();
- mAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(context,
+ mAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(context,
restriction, myUserId);
- mIsRestrictedByBase = RestrictedLockUtils.hasBaseUserRestriction(mContext,
+ mIsRestrictedByBase = RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext,
restriction, myUserId);
}
diff --git a/src/com/android/settings/users/UserCapabilities.java b/src/com/android/settings/users/UserCapabilities.java
index b9a2228..473c9c5 100644
--- a/src/com/android/settings/users/UserCapabilities.java
+++ b/src/com/android/settings/users/UserCapabilities.java
@@ -25,6 +25,7 @@
import com.android.settings.Utils;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
public class UserCapabilities {
boolean mEnabled = true;
@@ -67,9 +68,9 @@
public void updateAddUserCapabilities(Context context) {
final UserManager userManager =
(UserManager) context.getSystemService(Context.USER_SERVICE);
- mEnforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(context,
+ mEnforcedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(context,
UserManager.DISALLOW_ADD_USER, UserHandle.myUserId());
- final boolean hasBaseUserRestriction = RestrictedLockUtils.hasBaseUserRestriction(
+ final boolean hasBaseUserRestriction = RestrictedLockUtilsInternal.hasBaseUserRestriction(
context, UserManager.DISALLOW_ADD_USER, UserHandle.myUserId());
mDisallowAddUserSetByAdmin = mEnforcedAdmin != null && !hasBaseUserRestriction;
mDisallowAddUser = (mEnforcedAdmin != null || hasBaseUserRestriction);
diff --git a/src/com/android/settings/users/UserDetailsSettings.java b/src/com/android/settings/users/UserDetailsSettings.java
index 65868e9..99d3ca4 100644
--- a/src/com/android/settings/users/UserDetailsSettings.java
+++ b/src/com/android/settings/users/UserDetailsSettings.java
@@ -31,7 +31,7 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import java.util.List;
@@ -105,7 +105,7 @@
mPhonePref.setChecked(
!mDefaultGuestRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS));
}
- if (RestrictedLockUtils.hasBaseUserRestriction(context,
+ if (RestrictedLockUtilsInternal.hasBaseUserRestriction(context,
UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId())) {
removePreference(KEY_REMOVE_USER);
}
diff --git a/src/com/android/settings/users/UserPreference.java b/src/com/android/settings/users/UserPreference.java
index bcc0167..d87d78e 100644
--- a/src/com/android/settings/users/UserPreference.java
+++ b/src/com/android/settings/users/UserPreference.java
@@ -28,7 +28,7 @@
import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import java.util.Comparator;
@@ -142,7 +142,7 @@
private boolean canDeleteUser() {
return mDeleteClickListener != null
- && !RestrictedLockUtils.hasBaseUserRestriction(getContext(),
+ && !RestrictedLockUtilsInternal.hasBaseUserRestriction(getContext(),
UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId());
}
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 89e9a67..6e3174d 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -72,6 +72,7 @@
import com.android.settings.widget.SwitchBarController;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.drawable.CircleFramedDrawable;
import com.android.settingslib.search.SearchIndexable;
@@ -912,7 +913,7 @@
if (mUserCaps.mDisallowAddUser) {
pref.setDisabledByAdmin(mUserCaps.mEnforcedAdmin);
} else if (mUserCaps.mDisallowSwitchUser) {
- pref.setDisabledByAdmin(RestrictedLockUtils.getDeviceOwner(context));
+ pref.setDisabledByAdmin(RestrictedLockUtilsInternal.getDeviceOwner(context));
} else {
pref.setDisabledByAdmin(null);
}
@@ -963,7 +964,8 @@
mAddUserWhenLockedPreferenceController.getPreferenceKey());
mAddUserWhenLockedPreferenceController.updateState(addUserOnLockScreen);
mMultiUserFooterPreferenceController.updateState(null /* preference */);
- mAddUser.setVisible(mUserCaps.mUserSwitcherEnabled);
+ mAddUser.setVisible(mUserCaps.mCanAddUser && Utils.isDeviceProvisioned(context)
+ && mUserCaps.mUserSwitcherEnabled);
mUserListCategory.setVisible(mUserCaps.mUserSwitcherEnabled);
if (!mUserCaps.mUserSwitcherEnabled) {
return;
@@ -1090,7 +1092,7 @@
switch (v.getId()) {
case UserPreference.DELETE_ID:
final EnforcedAdmin removeDisallowedAdmin =
- RestrictedLockUtils.checkIfRestrictionEnforced(getContext(),
+ RestrictedLockUtilsInternal.checkIfRestrictionEnforced(getContext(),
UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId());
if (removeDisallowedAdmin != null) {
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
diff --git a/src/com/android/settings/utils/ManagedServiceSettings.java b/src/com/android/settings/utils/ManagedServiceSettings.java
index 6ee5e8e..e5dfb06 100644
--- a/src/com/android/settings/utils/ManagedServiceSettings.java
+++ b/src/com/android/settings/utils/ManagedServiceSettings.java
@@ -32,11 +32,6 @@
import android.util.Log;
import android.view.View;
-import androidx.appcompat.app.AlertDialog;
-import androidx.fragment.app.Fragment;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.SwitchPreference;
-
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.Utils;
@@ -47,6 +42,11 @@
import java.util.List;
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
public abstract class ManagedServiceSettings extends EmptyTextSettings {
private static final String TAG = "ManagedServiceSettings";
private final Config mConfig;
@@ -117,12 +117,12 @@
CharSequence title = null;
try {
title = mPm.getApplicationInfoAsUser(
- service.packageName, 0, getCurrentUser(managedProfileId)).loadLabel(mPm);
+ service.packageName, 0, UserHandle.myUserId()).loadLabel(mPm);
} catch (PackageManager.NameNotFoundException e) {
// unlikely, as we are iterating over live services.
Log.e(TAG, "can't find package name", e);
}
- final String finalTitle = title.toString();
+ final CharSequence finalTitle = title;
final String summary = service.loadLabel(mPm).toString();
final SwitchPreference pref = new AppSwitchPreference(getPrefContext());
pref.setPersistent(false);
@@ -143,7 +143,11 @@
}
pref.setOnPreferenceChangeListener((preference, newValue) -> {
final boolean enable = (boolean) newValue;
- return setEnabled(cn, finalTitle, enable);
+ if (finalTitle != null) {
+ return setEnabled(cn, finalTitle.toString(), enable);
+ } else {
+ return setEnabled(cn, null, enable);
+ }
});
pref.setKey(cn.flattenToString());
screen.addPreference(pref);
diff --git a/src/com/android/settings/vpn2/VpnSettings.java b/src/com/android/settings/vpn2/VpnSettings.java
index dafa7ec..ed36da8 100644
--- a/src/com/android/settings/vpn2/VpnSettings.java
+++ b/src/com/android/settings/vpn2/VpnSettings.java
@@ -63,7 +63,7 @@
import com.android.settings.RestrictedSettingsFragment;
import com.android.settings.widget.GearPreference;
import com.android.settings.widget.GearPreference.OnGearClickListener;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.google.android.collect.Lists;
@@ -143,7 +143,7 @@
// Disable all actions if VPN configuration has been disallowed
for (int i = 0; i < menu.size(); i++) {
if (isUiRestrictedByOnlyAdmin()) {
- RestrictedLockUtils.setMenuItemAsDisabledByAdmin(getPrefContext(),
+ RestrictedLockUtilsInternal.setMenuItemAsDisabledByAdmin(getPrefContext(),
menu.getItem(i), getRestrictionEnforcedAdmin());
} else {
menu.getItem(i).setEnabled(!mUnavailable);
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index de67c10..2e6611f 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -465,8 +465,7 @@
} else {
enabled = ipAndProxyFieldsAreValid();
}
- if (mEapCaCertSpinner != null
- && mView.findViewById(R.id.l_ca_cert).getVisibility() != View.GONE) {
+ if (mAccessPointSecurity == AccessPoint.SECURITY_EAP) {
String caCertSelection = (String) mEapCaCertSpinner.getSelectedItem();
if (caCertSelection.equals(mUnspecifiedCertString)) {
// Disallow submit if the user has not selected a CA certificate for an EAP network
@@ -482,10 +481,8 @@
enabled = false;
}
}
- if (mEapUserCertSpinner != null
- && mView.findViewById(R.id.l_user_cert).getVisibility() != View.GONE
- && ((String) mEapUserCertSpinner.getSelectedItem())
- .equals(mUnspecifiedCertString)) {
+ if (mAccessPointSecurity == AccessPoint.SECURITY_EAP
+ && mEapUserCertSpinner.getSelectedItem().equals(mUnspecifiedCertString)) {
// Disallow submit if the user has not selected a user certificate for an EAP network
// configuration.
enabled = false;
diff --git a/src/com/android/settings/wifi/WifiDialog.java b/src/com/android/settings/wifi/WifiDialog.java
index f1df7e4..2b8fb2d 100644
--- a/src/com/android/settings/wifi/WifiDialog.java
+++ b/src/com/android/settings/wifi/WifiDialog.java
@@ -26,6 +26,7 @@
import com.android.settings.R;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.wifi.AccessPoint;
public class WifiDialog extends AlertDialog implements WifiConfigUiBase,
@@ -117,7 +118,7 @@
case BUTTON_FORGET:
if (WifiUtils.isNetworkLockedDown(getContext(), mAccessPoint.getConfig())) {
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
- RestrictedLockUtils.getDeviceOwner(getContext()));
+ RestrictedLockUtilsInternal.getDeviceOwner(getContext()));
return;
}
mListener.onForget(this);
diff --git a/src/com/android/settings/wifi/WifiEnabler.java b/src/com/android/settings/wifi/WifiEnabler.java
index 8efefc3..60480c2 100644
--- a/src/com/android/settings/wifi/WifiEnabler.java
+++ b/src/com/android/settings/wifi/WifiEnabler.java
@@ -35,8 +35,8 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.widget.SwitchWidgetController;
-import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.WirelessUtils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -162,12 +162,12 @@
mSwitchWidget.setEnabled(true);
}
- if (RestrictedLockUtils.hasBaseUserRestriction(mContext,
+ if (RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext,
UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.myUserId())) {
mSwitchWidget.setEnabled(false);
} else {
- final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
- UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.myUserId());
+ final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
+ mContext, UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.myUserId());
mSwitchWidget.setDisabledByAdmin(admin);
}
}
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index d23cf46..12ca26a 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -67,6 +67,7 @@
import com.android.settings.widget.SwitchBarController;
import com.android.settings.wifi.details.WifiNetworkDetailsFragment;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.wifi.AccessPoint;
import com.android.settingslib.wifi.AccessPoint.AccessPointListener;
@@ -578,7 +579,7 @@
WifiConfiguration config = accessPoint.getConfig();
if (WifiUtils.isNetworkLockedDown(getActivity(), config) && accessPoint.isActive()) {
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getActivity(),
- RestrictedLockUtils.getDeviceOwner(getActivity()));
+ RestrictedLockUtilsInternal.getDeviceOwner(getActivity()));
return;
}
}
diff --git a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
index d114e06..c29ad60 100644
--- a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
+++ b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
@@ -35,6 +35,7 @@
import com.android.settings.wifi.WifiConfigUiBase;
import com.android.settings.wifi.WifiDialog;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.wifi.AccessPoint;
@@ -108,7 +109,7 @@
case Menu.FIRST:
if (!mWifiDetailPreferenceController.canModifyNetwork()) {
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
- RestrictedLockUtils.getDeviceOwner(getContext()));
+ RestrictedLockUtilsInternal.getDeviceOwner(getContext()));
} else {
showDialog(WIFI_DIALOG_ID);
}
diff --git a/tests/robotests/assets/grandfather_not_implementing_index_provider b/tests/robotests/assets/grandfather_not_implementing_index_provider
index 1a7b289..1ed50c9 100644
--- a/tests/robotests/assets/grandfather_not_implementing_index_provider
+++ b/tests/robotests/assets/grandfather_not_implementing_index_provider
@@ -29,6 +29,7 @@
com.android.settings.bluetooth.DevicePickerFragment
com.android.settings.datausage.AppDataUsage
com.android.settings.datausage.DataUsageList
+com.android.settings.datausage.DataUsageListV2
com.android.settings.datetime.timezone.TimeZoneSettings
com.android.settings.deviceinfo.PrivateVolumeSettings
com.android.settings.deviceinfo.PublicVolumeSettings
diff --git a/tests/robotests/assets/grandfather_not_in_search_index_provider_registry b/tests/robotests/assets/grandfather_not_in_search_index_provider_registry
index af663f4..64e0a01 100644
--- a/tests/robotests/assets/grandfather_not_in_search_index_provider_registry
+++ b/tests/robotests/assets/grandfather_not_in_search_index_provider_registry
@@ -1,3 +1,3 @@
-com.android.settings.accessibility.FontSizePreferenceFragmentForSetupWizard
+com.android.settings.display.FontSizePreferenceFragmentForSetupWizard
com.android.settings.display.ScreenZoomPreferenceFragmentForSetupWizard
com.android.settings.search.FakeSettingsFragment
diff --git a/tests/robotests/config/robolectric.properties b/tests/robotests/config/robolectric.properties
index d213eec..aae2779 100644
--- a/tests/robotests/config/robolectric.properties
+++ b/tests/robotests/config/robolectric.properties
@@ -1,3 +1,6 @@
manifest=packages/apps/Settings/AndroidManifest.xml
sdk=NEWEST_SDK
-shadows=com.android.settings.testutils.shadow.ShadowThreadUtils
\ No newline at end of file
+
+shadows=\
+ com.android.settings.testutils.shadow.ShadowThreadUtils,\
+ com.android.settingslib.testutils.shadow.ShadowXmlUtils
diff --git a/tests/robotests/res/values-mcc999/config.xml b/tests/robotests/res/values-mcc999/config.xml
index 2488882..6347d79 100644
--- a/tests/robotests/res/values-mcc999/config.xml
+++ b/tests/robotests/res/values-mcc999/config.xml
@@ -63,6 +63,9 @@
<bool name="config_disable_uninstall_update">true</bool>
<bool name="config_show_device_name">false</bool>
+ <!-- Whether or not extra preview panels should be used for screen zoom setting. -->
+ <bool name="config_enable_extra_screen_zoom_preview">false</bool>
+
<!-- List of a11y components on the device allowed to be enabled by Settings Slices -->
<string-array name="config_settings_slices_accessibility_components" translatable="false">
<item>fake_package/fake_service</item>
@@ -72,5 +75,4 @@
<string-array name="slice_whitelist_package_names" translatable="false">
<item>com.android.settings.slice_whitelist_package</item>
</string-array>
-
</resources>
diff --git a/tests/robotests/res/values/themes.xml b/tests/robotests/res/values/themes.xml
index 9a247f6..d3ba69f 100644
--- a/tests/robotests/res/values/themes.xml
+++ b/tests/robotests/res/values/themes.xml
@@ -6,5 +6,14 @@
<!-- Override the main app's style for ActionPrimaryButton to get around lack of new style
support in robolectric -->
- <style name="ActionPrimaryButton" parent="android:Widget.DeviceDefault.Button" />
+ <style name="ActionPrimaryButton" parent="android:Widget.DeviceDefault.Button"/>
+
+ <!-- Test version of Theme.Settings.Home. Needed to build homepage activity in Robolectric -->
+ <style name="Theme.Settings.Home" parent="Theme.AppCompat.DayNight.NoActionBar">
+ <item name="colorPrimary">#ffffff</item>
+ <item name="colorPrimaryDark">#ffffff</item>
+ <item name="colorAccent">#ffffff</item>
+ <item name="preferenceTheme">@style/PreferenceTheme</item>
+ <item name="android:windowLightStatusBar">true</item>
+ </style>
</resources>
diff --git a/tests/robotests/src/com/android/settings/SettingsActivityTest.java b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
index 723978f..409512e 100644
--- a/tests/robotests/src/com/android/settings/SettingsActivityTest.java
+++ b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
@@ -73,10 +73,11 @@
Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 0);
final Intent intent = new Intent(mContext, Settings.class);
final SettingsActivity activity =
- Robolectric.buildActivity(SettingsActivity.class, intent).create(Bundle.EMPTY).get();
+ Robolectric.buildActivity(SettingsActivity.class, intent).create(
+ Bundle.EMPTY).get();
assertThat(activity.findViewById(R.id.search_bar).getVisibility())
- .isEqualTo(View.INVISIBLE);
+ .isEqualTo(View.INVISIBLE);
}
@Test
@@ -84,7 +85,8 @@
Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 1);
final Intent intent = new Intent(mContext, Settings.class);
final SettingsActivity activity =
- Robolectric.buildActivity(SettingsActivity.class, intent).create(Bundle.EMPTY).get();
+ Robolectric.buildActivity(SettingsActivity.class, intent).create(
+ Bundle.EMPTY).get();
assertThat(activity.findViewById(R.id.search_bar).getVisibility()).isEqualTo(View.VISIBLE);
}
@@ -92,6 +94,7 @@
@Test
public void launchSettingFragment_nullExtraShowFragment_shouldNotCrash() {
when(mActivity.getSupportFragmentManager()).thenReturn(mFragmentManager);
+ doReturn(mContext.getContentResolver()).when(mActivity).getContentResolver();
when(mFragmentManager.beginTransaction()).thenReturn(mock(FragmentTransaction.class));
doReturn(RuntimeEnvironment.application.getClassLoader()).when(mActivity).getClassLoader();
diff --git a/tests/robotests/src/com/android/settings/accounts/ChooseAccountPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/ChooseAccountPreferenceControllerTest.java
index 2fa233c..22c2cdb 100644
--- a/tests/robotests/src/com/android/settings/accounts/ChooseAccountPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/ChooseAccountPreferenceControllerTest.java
@@ -41,7 +41,7 @@
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowAccountManager;
import com.android.settings.testutils.shadow.ShadowContentResolver;
-import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
+import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
import org.junit.After;
import org.junit.Before;
@@ -54,7 +54,7 @@
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class,
- ShadowRestrictedLockUtils.class})
+ ShadowRestrictedLockUtilsInternal.class})
public class ChooseAccountPreferenceControllerTest {
private Context mContext;
@@ -77,7 +77,7 @@
public void tearDown() {
ShadowContentResolver.reset();
ShadowAccountManager.resetAuthenticator();
- ShadowRestrictedLockUtils.clearDisabledTypes();
+ ShadowRestrictedLockUtilsInternal.clearDisabledTypes();
}
@Test
@@ -115,9 +115,9 @@
true /* supportsUploading */)};
ShadowContentResolver.setSyncAdapterTypes(syncAdapters);
- ShadowRestrictedLockUtils.setHasSystemFeature(true);
- ShadowRestrictedLockUtils.setDevicePolicyManager(mock(DevicePolicyManager.class));
- ShadowRestrictedLockUtils.setDisabledTypes(new String[] {"test_type"});
+ ShadowRestrictedLockUtilsInternal.setHasSystemFeature(true);
+ ShadowRestrictedLockUtilsInternal.setDevicePolicyManager(mock(DevicePolicyManager.class));
+ ShadowRestrictedLockUtilsInternal.setDisabledTypes(new String[] {"test_type"});
doReturn("label").when(mController).getLabelForType(anyString());
@@ -140,9 +140,9 @@
true /* supportsUploading */)};
ShadowContentResolver.setSyncAdapterTypes(syncAdapters);
- ShadowRestrictedLockUtils.setHasSystemFeature(true);
- ShadowRestrictedLockUtils.setDevicePolicyManager(mock(DevicePolicyManager.class));
- ShadowRestrictedLockUtils.setDisabledTypes(new String[] {"com.acct1"});
+ ShadowRestrictedLockUtilsInternal.setHasSystemFeature(true);
+ ShadowRestrictedLockUtilsInternal.setDevicePolicyManager(mock(DevicePolicyManager.class));
+ ShadowRestrictedLockUtilsInternal.setDisabledTypes(new String[] {"com.acct1"});
doReturn("label").when(mController).getLabelForType(anyString());
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 b6bb9b5..539e75f 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
@@ -170,7 +170,7 @@
}
@Test
- public void launchFragment_hasNoPackageInfo_shouldFinish() {
+ public void ensurePackageInfoAvailable_hasNoPackageInfo_shouldFinish() {
ReflectionHelpers.setField(mFragment, "mPackageInfo", null);
assertThat(mFragment.ensurePackageInfoAvailable(mActivity)).isFalse();
@@ -178,7 +178,7 @@
}
@Test
- public void launchFragment_hasPackageInfo_shouldReturnTrue() {
+ public void ensurePackageInfoAvailable_hasPackageInfo_shouldReturnTrue() {
final PackageInfo packageInfo = mock(PackageInfo.class);
ReflectionHelpers.setField(mFragment, "mPackageInfo", packageInfo);
@@ -187,6 +187,16 @@
}
@Test
+ public void createPreference_hasNoPackageInfo_shouldSkip() {
+ ReflectionHelpers.setField(mFragment, "mPackageInfo", null);
+
+ mFragment.onCreatePreferences(new Bundle(), "root_key");
+
+ verify(mActivity).finishAndRemoveTask();
+ verify(mFragment, never()).getPreferenceScreen();
+ }
+
+ @Test
public void packageSizeChange_isOtherPackage_shouldNotRefreshUi() {
ReflectionHelpers.setField(mFragment, "mPackageName", PACKAGE_NAME);
mFragment.onPackageSizeChanged("Not_" + PACKAGE_NAME);
diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java
index 0ef1cf3..4a482d0 100644
--- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java
@@ -18,9 +18,9 @@
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@@ -133,8 +133,11 @@
@Test
public void isBrowserDefault_onlyApp_shouldReturnTrue() {
when(mPackageManager.getDefaultBrowserPackageNameAsUser(anyInt())).thenReturn(null);
+ final List<ResolveInfo> resolveInfos = new ArrayList<>();
+ final String PACKAGE_ONE = "pkg";
+ resolveInfos.add(createResolveInfo(PACKAGE_ONE));
when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
- .thenReturn(Collections.singletonList(new ResolveInfo()));
+ .thenReturn(resolveInfos);
assertThat(mController.isBrowserDefault("pkg", 0)).isTrue();
}
@@ -161,6 +164,15 @@
assertThat(defaultBrowserInfo.size()).isEqualTo(2);
}
+ @Test
+ public void getCandidates_shouldQueryActivityWithFlagsEquals0() {
+
+ mController.getCandidates(mPackageManager, 0 /* userId */);
+
+ verify(mPackageManager).queryIntentActivitiesAsUser(
+ any(Intent.class), eq(0) /* flags */, eq(0) /* userId */);
+ }
+
private ResolveInfo createResolveInfo(String packageName) {
final ResolveInfo info = new ResolveInfo();
info.handleAllWebDataURI = true;
diff --git a/tests/robotests/src/com/android/settings/biometrics/face/FaceStatusPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/biometrics/face/FaceStatusPreferenceControllerTest.java
index d223099..9907da0 100644
--- a/tests/robotests/src/com/android/settings/biometrics/face/FaceStatusPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/biometrics/face/FaceStatusPreferenceControllerTest.java
@@ -121,7 +121,7 @@
when(mFaceManager.isHardwareDetected()).thenReturn(true);
when(mFaceManager.getEnrolledFaces(anyInt()))
.thenReturn(Collections.singletonList(mock(Face.class)));
- when(mFaceManager.hasEnrolledFaces(anyInt()))
+ when(mFaceManager.hasEnrolledTemplates(anyInt()))
.thenReturn(true);
mController.updateState(mPreference);
diff --git a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
index 261fac3..01fa32f 100644
--- a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
@@ -40,7 +40,7 @@
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
-import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
+import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.AppItem;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
@@ -58,7 +58,7 @@
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(shadows = {ShadowEntityHeaderController.class, ShadowRestrictedLockUtils.class})
+@Config(shadows = {ShadowEntityHeaderController.class, ShadowRestrictedLockUtilsInternal.class})
public class AppDataUsageTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
@@ -163,7 +163,7 @@
ReflectionHelpers.setField(mFragment, "mDataSaverBackend", dataSaverBackend);
ReflectionHelpers.setField(mFragment.services, "mPolicyManager", networkPolicyManager);
- ShadowRestrictedLockUtils.setRestricted(true);
+ ShadowRestrictedLockUtilsInternal.setRestricted(true);
doReturn(NetworkPolicyManager.POLICY_NONE).when(networkPolicyManager)
.getUidPolicy(testUid);
diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java
index 0140d6f..acd00fd 100644
--- a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java
@@ -31,10 +31,12 @@
import android.provider.Settings;
import androidx.fragment.app.FragmentActivity;
+import androidx.preference.PreferenceManager;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.NetworkPolicyEditor;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
import org.junit.Before;
import org.junit.Test;
@@ -68,7 +70,11 @@
@Test
public void resumePause_shouldListenUnlistenDataStateChange() {
- mDataUsageList.onAttach(mContext);
+ ReflectionHelpers.setField(
+ mDataUsageList, "mVisibilityLoggerMixin", mock(VisibilityLoggerMixin.class));
+ ReflectionHelpers.setField(
+ mDataUsageList, "mPreferenceManager", mock(PreferenceManager.class));
+
mDataUsageList.onResume();
verify(mListener).setListener(true, mDataUsageList.mSubId, mContext);
diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageListV2Test.java b/tests/robotests/src/com/android/settings/datausage/DataUsageListV2Test.java
new file mode 100644
index 0000000..9eb8003
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/datausage/DataUsageListV2Test.java
@@ -0,0 +1,114 @@
+/*
+ * 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.datausage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.NetworkTemplate;
+import android.os.Bundle;
+import android.provider.Settings;
+
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.NetworkPolicyEditor;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.util.ReflectionHelpers;
+
+import androidx.fragment.app.FragmentActivity;
+import androidx.preference.PreferenceManager;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class DataUsageListV2Test {
+
+ @Mock
+ private CellDataPreference.DataStateListener mListener;
+ @Mock
+ private TemplatePreference.NetworkServices mNetworkServices;
+ @Mock
+ private Context mContext;
+ private DataUsageListV2 mDataUsageList;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ FakeFeatureFactory.setupForTest();
+ mNetworkServices.mPolicyEditor = mock(NetworkPolicyEditor.class);
+ mDataUsageList = spy(DataUsageListV2.class);
+
+ doReturn(mContext).when(mDataUsageList).getContext();
+ ReflectionHelpers.setField(mDataUsageList, "mDataStateListener", mListener);
+ ReflectionHelpers.setField(mDataUsageList, "services", mNetworkServices);
+ }
+
+ @Test
+ public void resumePause_shouldListenUnlistenDataStateChange() {
+ ReflectionHelpers.setField(
+ mDataUsageList, "mVisibilityLoggerMixin", mock(VisibilityLoggerMixin.class));
+ ReflectionHelpers.setField(
+ mDataUsageList, "mPreferenceManager", mock(PreferenceManager.class));
+
+ mDataUsageList.onResume();
+
+ verify(mListener).setListener(true, mDataUsageList.mSubId, mContext);
+
+ mDataUsageList.onPause();
+
+ verify(mListener).setListener(false, mDataUsageList.mSubId, mContext);
+ }
+
+ @Test
+ public void processArgument_shouldGetTemplateFromArgument() {
+ final Bundle args = new Bundle();
+ args.putParcelable(DataUsageListV2.EXTRA_NETWORK_TEMPLATE, mock(NetworkTemplate.class));
+ args.putInt(DataUsageListV2.EXTRA_SUB_ID, 3);
+ mDataUsageList.setArguments(args);
+
+ mDataUsageList.processArgument();
+
+ assertThat(mDataUsageList.mTemplate).isNotNull();
+ assertThat(mDataUsageList.mSubId).isEqualTo(3);
+ }
+
+ @Test
+ public void processArgument_fromIntent_shouldGetTemplateFromIntent() {
+ final FragmentActivity activity = mock(FragmentActivity.class);
+ final Intent intent = new Intent();
+ intent.putExtra(Settings.EXTRA_NETWORK_TEMPLATE, mock(NetworkTemplate.class));
+ intent.putExtra(Settings.EXTRA_SUB_ID, 3);
+ when(activity.getIntent()).thenReturn(intent);
+ doReturn(activity).when(mDataUsageList).getActivity();
+
+ mDataUsageList.processArgument();
+
+ assertThat(mDataUsageList.mTemplate).isNotNull();
+ assertThat(mDataUsageList.mSubId).isEqualTo(3);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/datausage/UnrestrictedDataAccessPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/datausage/UnrestrictedDataAccessPreferenceControllerTest.java
index b357630..983b96d 100644
--- a/tests/robotests/src/com/android/settings/datausage/UnrestrictedDataAccessPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/UnrestrictedDataAccessPreferenceControllerTest.java
@@ -43,6 +43,7 @@
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
+import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
@@ -61,6 +62,7 @@
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = {
ShadowRestrictedLockUtils.class,
+ ShadowRestrictedLockUtilsInternal.class,
UnrestrictedDataAccessPreferenceControllerTest.ShadowAppStateBaseBridge.class
})
public class UnrestrictedDataAccessPreferenceControllerTest {
@@ -127,7 +129,7 @@
final String testPkg1 = "com.example.one";
final String testPkg2 = "com.example.two";
- ShadowRestrictedLockUtils.setRestrictedPkgs(testPkg2);
+ ShadowRestrictedLockUtilsInternal.setRestrictedPkgs(testPkg2);
doAnswer((invocation) -> {
final UnrestrictedDataAccessPreference preference = invocation.getArgument(0);
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/DeviceNamePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/DeviceNamePreferenceControllerTest.java
index 4ee7f41..8662c7f 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/DeviceNamePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/DeviceNamePreferenceControllerTest.java
@@ -114,7 +114,7 @@
@Test
public void setDeviceName_preferenceUpdatedWhenDeviceNameUpdated() {
- forceAcceptDeviceName();
+ acceptDeviceName(true);
mController.displayPreference(mScreen);
mController.onPreferenceChange(mPreference, TESTING_STRING);
@@ -123,7 +123,7 @@
@Test
public void setDeviceName_bluetoothNameUpdatedWhenDeviceNameUpdated() {
- forceAcceptDeviceName();
+ acceptDeviceName(true);
mController.displayPreference(mScreen);
mController.onPreferenceChange(mPreference, TESTING_STRING);
@@ -132,7 +132,7 @@
@Test
public void setDeviceName_wifiTetherNameUpdatedWhenDeviceNameUpdated() {
- forceAcceptDeviceName();
+ acceptDeviceName(true);
mController.displayPreference(mScreen);
mController.onPreferenceChange(mPreference, TESTING_STRING);
@@ -150,21 +150,39 @@
@Test
public void setDeviceName_ignoresIfCancelPressed() {
- forceAcceptDeviceName();
+ acceptDeviceName(true);
mController.displayPreference(mScreen);
mController.onPreferenceChange(mPreference, TESTING_STRING);
assertThat(mBluetoothAdapter.getName()).isEqualTo(TESTING_STRING);
}
- private void forceAcceptDeviceName() {
+ @Test
+ public void setDeviceName_okInDeviceNameWarningDialog_shouldChangePreferenceText() {
+ acceptDeviceName(true);
+ mController.displayPreference(mScreen);
+ mController.onPreferenceChange(mPreference, TESTING_STRING);
+
+ assertThat(mPreference.getSummary()).isEqualTo(TESTING_STRING);
+ }
+
+ @Test
+ public void setDeviceName_cancelInDeviceNameWarningDialog_shouldNotChangePreferenceText() {
+ acceptDeviceName(false);
+ mController.displayPreference(mScreen);
+ mController.onPreferenceChange(mPreference, TESTING_STRING);
+
+ assertThat(mPreference.getSummary()).isNotEqualTo(TESTING_STRING);
+ assertThat(mPreference.getText()).isEqualTo(mPreference.getSummary());
+ }
+
+ private void acceptDeviceName(boolean accept) {
mController.setHost(
new DeviceNamePreferenceController.DeviceNamePreferenceHost() {
@Override
public void showDeviceNameWarningDialog(String deviceName) {
- mController.confirmDeviceName();
+ mController.updateDeviceName(accept);
}
});
}
-
}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/deviceinfo/DeviceNameWarningDialogTest.java b/tests/robotests/src/com/android/settings/deviceinfo/deviceinfo/DeviceNameWarningDialogTest.java
index e28e6ec..9e1400b 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/deviceinfo/DeviceNameWarningDialogTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/deviceinfo/DeviceNameWarningDialogTest.java
@@ -30,7 +30,7 @@
fragmentController.create().start().resume();
fragment.onClick(null, DialogInterface.BUTTON_POSITIVE);
- verify(deviceInfoFragment).onSetDeviceNameConfirm();
+ verify(deviceInfoFragment).onSetDeviceNameConfirm(true);
}
@Test
@@ -43,6 +43,6 @@
fragmentController.create().start().resume();
fragment.onClick(null, DialogInterface.BUTTON_NEGATIVE);
- verify(deviceInfoFragment, never()).onSetDeviceNameConfirm();
+ verify(deviceInfoFragment).onSetDeviceNameConfirm(false);
}
}
diff --git a/tests/robotests/src/com/android/settings/display/ScreenZoomSettingsTest.java b/tests/robotests/src/com/android/settings/display/ScreenZoomSettingsTest.java
new file mode 100644
index 0000000..0822076
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/display/ScreenZoomSettingsTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.display;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class ScreenZoomSettingsTest {
+
+ private ScreenZoomSettings mSettings;
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ mSettings = spy(new ScreenZoomSettings());
+ doReturn(mContext).when(mSettings).getContext();
+ }
+
+ @Test
+ public void getPreviewSampleResIds_default_return3Previews() {
+ assertThat(mSettings.getPreviewSampleResIds()).hasLength(3);
+ }
+
+ @Test
+ @Config(qualifiers = "mcc999")
+ public void getPreviewSampleResIds_extraPreviewDisabled_return1Preview() {
+ assertThat(mSettings.getPreviewSampleResIds()).hasLength(1);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/display/TimeoutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/TimeoutPreferenceControllerTest.java
index e0a504a..f6f0d7f 100644
--- a/tests/robotests/src/com/android/settings/display/TimeoutPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/TimeoutPreferenceControllerTest.java
@@ -34,7 +34,7 @@
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
-import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
+import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import org.junit.After;
@@ -78,7 +78,7 @@
@After
public void tearDown() {
- ShadowRestrictedLockUtils.reset();
+ ShadowRestrictedLockUtilsInternal.reset();
}
@Test
@@ -139,13 +139,13 @@
}
@Test
- @Config(shadows = ShadowRestrictedLockUtils.class)
+ @Config(shadows = ShadowRestrictedLockUtilsInternal.class)
public void updateState_selectedTimeoutLargerThanAdminMax_shouldSetSummaryToUpdatedPrefValue() {
final int profileUserId = UserHandle.myUserId();
final long allowedTimeout = 480000L; // 8 minutes
when(mUserManager.getProfiles(profileUserId)).thenReturn(Collections.emptyList());
ShadowDevicePolicyManager.getShadow().setMaximumTimeToLock(profileUserId, allowedTimeout);
- ShadowRestrictedLockUtils.setMaximumTimeToLockIsSet(true);
+ ShadowRestrictedLockUtilsInternal.setMaximumTimeToLockIsSet(true);
final CharSequence[] timeouts = {"15000", "30000", "60000", "120000", "300000", "600000"};
final CharSequence[] summaries = {"15s", "30s", "1m", "2m", "5m", "10m"};
// set current timeout to be 10 minutes, which is longer than the allowed 8 minutes
diff --git a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java
index 5321c10..9b138a6 100644
--- a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java
@@ -124,10 +124,6 @@
assertEquals(Shadows.shadowOf(textView).innerText(),
mActivity.getString(R.string.disabled_by_policy_title_screen_capture));
- mHelper.setAdminSupportTitle(view, DevicePolicyManager.POLICY_MANDATORY_BACKUPS);
- assertEquals(Shadows.shadowOf(textView).innerText(),
- mActivity.getString(R.string.disabled_by_policy_title_turn_off_backups));
-
mHelper.setAdminSupportTitle(view, DevicePolicyManager.POLICY_SUSPEND_PACKAGES);
assertEquals(Shadows.shadowOf(textView).innerText(),
mActivity.getString(R.string.disabled_by_policy_title_suspend_packages));
diff --git a/tests/robotests/src/com/android/settings/enterprise/BackupsEnabledPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/BackupsEnabledPreferenceControllerTest.java
deleted file mode 100644
index 4e6db05..0000000
--- a/tests/robotests/src/com/android/settings/enterprise/BackupsEnabledPreferenceControllerTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.enterprise;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-
-import androidx.preference.Preference;
-
-import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-public class BackupsEnabledPreferenceControllerTest {
-
- private static final String KEY_BACKUPS_ENABLED = "backups_enabled";
-
- private Context mContext;
- private FakeFeatureFactory mFeatureFactory;
-
- private BackupsEnabledPreferenceController mController;
-
- @Before
- public void setUp() {
- mContext = RuntimeEnvironment.application;
- mFeatureFactory = FakeFeatureFactory.setupForTest();
- mController = new BackupsEnabledPreferenceController(mContext);
- }
-
- @Test
- public void testIsAvailable() {
- when(mFeatureFactory.enterprisePrivacyFeatureProvider.areBackupsMandatory())
- .thenReturn(false);
- assertThat(mController.isAvailable()).isFalse();
-
- when(mFeatureFactory.enterprisePrivacyFeatureProvider.areBackupsMandatory())
- .thenReturn(true);
- assertThat(mController.isAvailable()).isTrue();
- }
-
- @Test
- public void testHandlePreferenceTreeClick() {
- assertThat(mController.handlePreferenceTreeClick(new Preference(mContext, null, 0, 0)))
- .isFalse();
- }
-
- @Test
- public void testGetPreferenceKey() {
- assertThat(mController.getPreferenceKey()).isEqualTo(KEY_BACKUPS_ENABLED);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
index a7bd329..92c420a 100644
--- a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
@@ -346,15 +346,6 @@
.isEqualTo(3);
}
- @Test
- public void testAreBackupsMandatory() {
- assertThat(mProvider.areBackupsMandatory()).isFalse();
- ComponentName transportComponent = new ComponentName("test", "test");
- when(mDevicePolicyManager.getMandatoryBackupTransport())
- .thenReturn(transportComponent);
- assertThat(mProvider.areBackupsMandatory()).isTrue();
- }
-
private void resetAndInitializePackageManager() {
reset(mPackageManager);
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN))
diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java
index d37738d..f1d03c7 100644
--- a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java
@@ -99,7 +99,7 @@
private void verifyPreferenceControllers(List<AbstractPreferenceController> controllers) {
assertThat(controllers).isNotNull();
- assertThat(controllers.size()).isEqualTo(18);
+ assertThat(controllers.size()).isEqualTo(17);
int position = 0;
assertThat(controllers.get(position++)).isInstanceOf(NetworkLogsPreferenceController.class);
assertThat(controllers.get(position++)).isInstanceOf(BugReportsPreferenceController.class);
@@ -127,8 +127,6 @@
assertThat(controllers.get(position++)).isInstanceOf(
CaCertsManagedProfilePreferenceController.class);
assertThat(controllers.get(position++)).isInstanceOf(
- BackupsEnabledPreferenceController.class);
- assertThat(controllers.get(position++)).isInstanceOf(
PreferenceCategoryController.class);
assertThat(controllers.get(position++)).isInstanceOf(
FailedPasswordWipeCurrentUserPreferenceController.class);
diff --git a/tests/robotests/src/com/android/settings/homepage/CardContentProviderTest.java b/tests/robotests/src/com/android/settings/homepage/CardContentProviderTest.java
index eec87b0..84955e2 100644
--- a/tests/robotests/src/com/android/settings/homepage/CardContentProviderTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/CardContentProviderTest.java
@@ -72,16 +72,25 @@
@Test
public void cardData_insert() {
- final int cnt_before_instert = getRowCount();
- mResolver.insert(mUri, insertOneRow());
- final int cnt_after_instert = getRowCount();
+ final int rowsBeforeInsert = getRowCount();
+ mResolver.insert(mUri, generateOneRow());
+ final int rowsAfterInsert = getRowCount();
- assertThat(cnt_after_instert - cnt_before_instert).isEqualTo(1);
+ assertThat(rowsAfterInsert - rowsBeforeInsert).isEqualTo(1);
+ }
+
+ @Test
+ public void cardData_bulkInsert_twoRows() {
+ final int rowsBeforeInsert = getRowCount();
+ mResolver.bulkInsert(mUri, generateTwoRows());
+ final int rowsAfterInsert = getRowCount();
+
+ assertThat(rowsAfterInsert - rowsBeforeInsert).isEqualTo(2);
}
@Test
public void cardData_query() {
- mResolver.insert(mUri, insertOneRow());
+ mResolver.insert(mUri, generateOneRow());
final int count = getRowCount();
assertThat(count).isGreaterThan(0);
@@ -89,24 +98,24 @@
@Test
public void cardData_delete() {
- mResolver.insert(mUri, insertOneRow());
- final int del_count = mResolver.delete(mUri, null, null);
+ mResolver.insert(mUri, generateOneRow());
+ final int delCount = mResolver.delete(mUri, null, null);
- assertThat(del_count).isGreaterThan(0);
+ assertThat(delCount).isGreaterThan(0);
}
@Test
public void cardData_update() {
- mResolver.insert(mUri, insertOneRow());
+ mResolver.insert(mUri, generateOneRow());
final double updatingScore = 0.87;
final ContentValues values = new ContentValues();
values.put(CardDatabaseHelper.CardColumns.SCORE, updatingScore);
final String strWhere = CardDatabaseHelper.CardColumns.NAME + "=?";
final String[] selectionArgs = {"auto_rotate"};
- final int update_count = mResolver.update(mUri, values, strWhere, selectionArgs);
+ final int updateCount = mResolver.update(mUri, values, strWhere, selectionArgs);
- assertThat(update_count).isGreaterThan(0);
+ assertThat(updateCount).isGreaterThan(0);
final String[] columns = {CardDatabaseHelper.CardColumns.SCORE};
final Cursor cr = mResolver.query(mUri, columns, strWhere, selectionArgs, null);
@@ -122,7 +131,7 @@
ShadowThreadUtils.setIsMainThread(true);
ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true);
- mProvider.insert(mUri, insertOneRow());
+ mProvider.insert(mUri, generateOneRow());
verify(mProvider).enableStrictMode();
}
@@ -164,7 +173,7 @@
ShadowThreadUtils.setIsMainThread(false);
ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true);
- mProvider.insert(mUri, insertOneRow());
+ mProvider.insert(mUri, generateOneRow());
verify(mProvider, never()).enableStrictMode();
}
@@ -217,10 +226,10 @@
mProvider.getTableFromMatch(invalid_Uri);
}
- private ContentValues insertOneRow() {
+ private ContentValues generateOneRow() {
final ContentValues values = new ContentValues();
values.put(CardDatabaseHelper.CardColumns.NAME, "auto_rotate");
- values.put(CardDatabaseHelper.CardColumns.TYPE, 0);
+ values.put(CardDatabaseHelper.CardColumns.TYPE, 1);
values.put(CardDatabaseHelper.CardColumns.SCORE, 0.9);
values.put(CardDatabaseHelper.CardColumns.SLICE_URI,
"content://com.android.settings.slices/action/auto_rotate");
@@ -231,6 +240,24 @@
return values;
}
+ private ContentValues[] generateTwoRows() {
+ final ContentValues[] twoRows = new ContentValues[2];
+ twoRows[0] = generateOneRow();
+
+ final ContentValues values = new ContentValues();
+ values.put(CardDatabaseHelper.CardColumns.NAME, "toggle_airplane");
+ values.put(CardDatabaseHelper.CardColumns.TYPE, 1);
+ values.put(CardDatabaseHelper.CardColumns.SCORE, 0.95);
+ values.put(CardDatabaseHelper.CardColumns.SLICE_URI,
+ "content://com.android.settings.slices/action/toggle_airplane");
+ values.put(CardDatabaseHelper.CardColumns.CATEGORY, 2);
+ values.put(CardDatabaseHelper.CardColumns.PACKAGE_NAME, "com.android.settings");
+ values.put(CardDatabaseHelper.CardColumns.APP_VERSION, "1.0.0");
+ twoRows[1] = values;
+
+ return twoRows;
+ }
+
private int getRowCount() {
final Cursor cr = mResolver.query(mUri, null, null, null);
final int count = cr.getCount();
diff --git a/tests/robotests/src/com/android/settings/homepage/ConditionalContextualCardTest.java b/tests/robotests/src/com/android/settings/homepage/ConditionalContextualCardTest.java
new file mode 100644
index 0000000..ced8b06
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/ConditionalContextualCardTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.homepage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.settings.homepage.conditional.ConditionalContextualCard;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class ConditionalContextualCardTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void newInstance_changeCardType_shouldCrash() {
+ new ConditionalContextualCard.Builder()
+ .setCardType(ContextualCard.CardType.SUGGESTION)
+ .build();
+ }
+
+ @Test
+ public void getCardType_shouldAlwaysBeConditional() {
+ assertThat(new ConditionalContextualCard.Builder().build().getCardType())
+ .isEqualTo(ContextualCard.CardType.CONDITIONAL);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
new file mode 100644
index 0000000..4b237a0
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.homepage;
+
+import static com.android.settings.homepage.SettingsHomepageActivity.PERSONAL_SETTINGS_TAG;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.util.FeatureFlagUtils;
+
+import androidx.fragment.app.Fragment;
+
+import com.android.settings.core.FeatureFlags;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class SettingsHomepageActivityTest {
+
+ private Context mContext;
+ private SettingsHomepageActivity mActivity;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ FeatureFlagUtils.setEnabled(mContext, FeatureFlags.DYNAMIC_HOMEPAGE, true);
+ }
+
+ @Test
+ public void launchHomepage_shouldOpenPersonalSettings() {
+ mActivity = Robolectric.setupActivity(SettingsHomepageActivity.class);
+ final Fragment fragment = mActivity.getSupportFragmentManager()
+ .findFragmentByTag(PERSONAL_SETTINGS_TAG);
+
+ assertThat(fragment).isInstanceOf(PersonalSettingsFragment.class);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardControllerTest.java b/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardControllerTest.java
new file mode 100644
index 0000000..a59a3bc
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardControllerTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.homepage.conditional;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+
+import com.android.settings.R;
+import com.android.settings.homepage.ContextualCardUpdateListener;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class ConditionContextualCardControllerTest {
+
+ @Mock
+ private ConditionManager mConditionManager;
+ @Mock
+ private ContextualCardUpdateListener mListener;
+ private Context mContext;
+ private ConditionContextualCardController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ mController = spy(new ConditionContextualCardController(mContext));
+ ReflectionHelpers.setField(mController, "mConditionManager", mConditionManager);
+ }
+
+ @Test
+ public void onStart_shouldStartMonitoring() {
+ mController.onStart();
+
+ verify(mConditionManager).startMonitoringStateChange();
+ }
+
+ @Test
+ public void onStop_shouldStopMonitoring() {
+ mController.onStop();
+
+ verify(mConditionManager).stopMonitoringStateChange();
+ }
+
+ @Test
+ public void onConditionsChanged_listenerIsSet_shouldUpdateData() {
+ final FakeConditionalCard fakeConditionalCard = new FakeConditionalCard(mContext);
+ final List<ConditionalCard> conditionalCards = new ArrayList<>();
+ conditionalCards.add(fakeConditionalCard);
+ when(mConditionManager.getDisplayableCards()).thenReturn(conditionalCards);
+ mController.setCardUpdateListener(mListener);
+
+ mController.onConditionsChanged();
+
+ verify(mListener).onContextualCardUpdated(any());
+ }
+
+ @Test
+ public void onConditionsChanged_listenerNotSet_shouldNotUpdateData() {
+ final FakeConditionalCard fakeConditionalCard = new FakeConditionalCard(mContext);
+ final List<ConditionalCard> conditionalCards = new ArrayList<>();
+ conditionalCards.add(fakeConditionalCard);
+ when(mConditionManager.getDisplayableCards()).thenReturn(conditionalCards);
+
+ mController.onConditionsChanged();
+
+ verify(mListener, never()).onContextualCardUpdated(any());
+ }
+
+ private class FakeConditionalCard implements ConditionalCard {
+
+ private final Context mContext;
+
+ public FakeConditionalCard(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public long getId() {
+ return 100;
+ }
+
+ @Override
+ public CharSequence getActionText() {
+ return "action_text_test";
+ }
+
+ @Override
+ public int getMetricsConstant() {
+ return 1;
+ }
+
+ @Override
+ public Drawable getIcon() {
+ return mContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp);
+ }
+
+ @Override
+ public CharSequence getTitle() {
+ return "title_text_test";
+ }
+
+ @Override
+ public CharSequence getSummary() {
+ return "summary_text_test";
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardRendererTest.java
new file mode 100644
index 0000000..dc56a7f
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardRendererTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.homepage.conditional;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.settings.R;
+import com.android.settings.homepage.ContextualCard;
+import com.android.settings.homepage.ControllerRendererPool;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class ConditionContextualCardRendererTest {
+
+ @Mock
+ private ControllerRendererPool mControllerRendererPool;
+ @Mock
+ private ConditionContextualCardController mController;
+ private Context mContext;
+ private ConditionContextualCardRenderer mRenderer;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ mRenderer = new ConditionContextualCardRenderer(mContext, mControllerRendererPool);
+ }
+
+ @Test
+ public void bindView_shouldSetListener() {
+ final int viewType = mRenderer.getViewType();
+ final RecyclerView recyclerView = new RecyclerView(mContext);
+ recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
+ final View view = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
+ final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view);
+ final View card = view.findViewById(R.id.content);
+ when(mControllerRendererPool.getController(mContext,
+ ContextualCard.CardType.CONDITIONAL)).thenReturn(mController);
+
+ mRenderer.bindView(viewHolder, buildConditionContextualCard());
+
+ assertThat(card).isNotNull();
+ assertThat(card.hasOnClickListeners()).isTrue();
+ }
+
+ @Test
+ public void viewClick_shouldInvokeControllerPrimaryClick() {
+ final int viewType = mRenderer.getViewType();
+ final RecyclerView recyclerView = new RecyclerView(mContext);
+ recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
+ final View view = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
+ final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view);
+ final View card = view.findViewById(R.id.content);
+ when(mControllerRendererPool.getController(mContext,
+ ContextualCard.CardType.CONDITIONAL)).thenReturn(mController);
+
+ mRenderer.bindView(viewHolder, buildConditionContextualCard());
+
+ assertThat(card).isNotNull();
+ card.performClick();
+
+ verify(mController).onPrimaryClick(any(ContextualCard.class));
+ }
+
+ private ContextualCard buildConditionContextualCard() {
+ return new ConditionalContextualCard.Builder()
+ .setConditionId(123)
+ .setMetricsConstant(1)
+ .setActionText("test_action")
+ .setName("test_name")
+ .setTitleText("test_title")
+ .setSummaryText("test_summary")
+ .setIconDrawable(mContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
+ .setIsHalfWidth(true)
+ .build();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java
index d6f86f9..469a537 100644
--- a/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java
@@ -79,7 +79,7 @@
final SummaryLoader.SummaryProvider provider =
new NetworkDashboardFragment.SummaryProvider(mContext, summaryLoader,
wifiPreferenceController, mobileNetworkPreferenceController,
- tetherPreferenceController);
+ tetherPreferenceController, () -> true);
provider.setListening(false);
@@ -107,7 +107,7 @@
final SummaryLoader.SummaryProvider provider =
new NetworkDashboardFragment.SummaryProvider(mContext, summaryLoader,
wifiPreferenceController, mobileNetworkPreferenceController,
- tetherPreferenceController);
+ tetherPreferenceController, () -> true);
provider.setListening(false);
@@ -121,4 +121,34 @@
verify(summaryLoader).setSummary(provider, "Wi\u2011Fi and data usage");
}
+
+ @Test
+ public void summaryProviderSetListening_noDataUsageActivity_shouldReturnNoDataUsageSummary() {
+ final WifiMasterSwitchPreferenceController wifiPreferenceController =
+ mock(WifiMasterSwitchPreferenceController.class);
+ final MobileNetworkPreferenceController mobileNetworkPreferenceController =
+ mock(MobileNetworkPreferenceController.class);
+ final TetherPreferenceController tetherPreferenceController =
+ mock(TetherPreferenceController.class);
+
+ final SummaryLoader summaryLoader = mock(SummaryLoader.class);
+ final SummaryLoader.SummaryProvider provider =
+ new NetworkDashboardFragment.SummaryProvider(mContext, summaryLoader,
+ wifiPreferenceController, mobileNetworkPreferenceController,
+ tetherPreferenceController, () -> false);
+
+ provider.setListening(false);
+
+ verifyZeroInteractions(summaryLoader);
+
+ when(wifiPreferenceController.isAvailable()).thenReturn(true);
+ when(mobileNetworkPreferenceController.isAvailable()).thenReturn(true);
+ when(tetherPreferenceController.isAvailable()).thenReturn(true);
+
+ provider.setListening(true);
+
+ verify(summaryLoader).setSummary(provider, "Wi\u2011Fi, mobile, and hotspot");
+ }
+
+
}
diff --git a/tests/robotests/src/com/android/settings/network/TopLevelNetworkEntryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/TopLevelNetworkEntryPreferenceControllerTest.java
index 22aaf2a..004e352 100644
--- a/tests/robotests/src/com/android/settings/network/TopLevelNetworkEntryPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/TopLevelNetworkEntryPreferenceControllerTest.java
@@ -23,7 +23,7 @@
import android.content.Context;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
+import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
import com.android.settings.wifi.WifiMasterSwitchPreferenceController;
import org.junit.Before;
@@ -36,7 +36,7 @@
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(shadows = ShadowRestrictedLockUtils.class)
+@Config(shadows = ShadowRestrictedLockUtilsInternal.class)
public class TopLevelNetworkEntryPreferenceControllerTest {
@Mock
diff --git a/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java
index e3fc843..bf2c132 100644
--- a/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java
@@ -31,7 +31,7 @@
import androidx.preference.PreferenceScreen;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import org.junit.Before;
@@ -69,7 +69,7 @@
when(mContext.getApplicationContext()).thenReturn(mContext);
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
when(mContext.getSystemService(Context.NFC_SERVICE)).thenReturn(mManager);
- when(RestrictedLockUtils.hasBaseUserRestriction(mContext,
+ when(RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext,
UserManager.DISALLOW_OUTGOING_BEAM, UserHandle.myUserId())).thenReturn(false);
when(NfcAdapter.getDefaultAdapter(mContext)).thenReturn(mNfcAdapter);
@@ -104,7 +104,7 @@
public void isBeamEnable_disAllowBeam_shouldReturnFalse() {
when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_OFF);
- when(RestrictedLockUtils.hasBaseUserRestriction(mContext,
+ when(RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext,
UserManager.DISALLOW_OUTGOING_BEAM, UserHandle.myUserId())).thenReturn(true);
mAndroidBeamController.displayPreference(mScreen);
diff --git a/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java
index cbc51a9..e222b20 100644
--- a/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java
@@ -189,9 +189,8 @@
mController.displayPreference(mScreen);
verify(mCategory).setTitle(R.string.recent_notifications);
- // Only add app1. app2 is skipped because of the package name, app3 skipped because
- // it's invalid app.
- verify(mCategory, times(1)).addPreference(any(Preference.class));
+ // Only add app1 & app2. app3 skipped because it's invalid app.
+ verify(mCategory, times(2)).addPreference(any(Preference.class));
verify(mSeeAllPref).setSummary(null);
verify(mSeeAllPref).setIcon(R.drawable.ic_chevron_right_24dp);
@@ -247,35 +246,6 @@
}
@Test
- public void display_hasRecentButNoneDisplayable_showAppInfo() {
- final List<NotifyingApp> apps = new ArrayList<>();
- final NotifyingApp app1 = new NotifyingApp()
- .setPackage("com.android.phone")
- .setLastNotified(System.currentTimeMillis());
- final NotifyingApp app2 = new NotifyingApp()
- .setPackage("com.android.settings")
- .setLastNotified(System.currentTimeMillis());
- apps.add(app1);
- apps.add(app2);
-
- // app1, app2 are not displayable
- when(mAppState.getEntry(app1.getPackage(), UserHandle.myUserId()))
- .thenReturn(mock(ApplicationsState.AppEntry.class));
- when(mAppState.getEntry(app2.getPackage(), UserHandle.myUserId()))
- .thenReturn(mock(ApplicationsState.AppEntry.class));
- when(mPackageManager.resolveActivity(any(Intent.class), anyInt())).thenReturn(
- new ResolveInfo());
- when(mBackend.getRecentApps()).thenReturn(apps);
-
- mController.displayPreference(mScreen);
-
- verify(mCategory, never()).addPreference(any(Preference.class));
- verify(mCategory).setTitle(null);
- verify(mSeeAllPref).setTitle(R.string.notifications_title);
- verify(mSeeAllPref).setIcon(null);
- }
-
- @Test
public void display_showRecents_formatSummary() {
final List<NotifyingApp> apps = new ArrayList<>();
final NotifyingApp app1 = new NotifyingApp()
diff --git a/tests/robotests/src/com/android/settings/notification/RedactionInterstitialTest.java b/tests/robotests/src/com/android/settings/notification/RedactionInterstitialTest.java
index 5b337de..b62495c 100644
--- a/tests/robotests/src/com/android/settings/notification/RedactionInterstitialTest.java
+++ b/tests/robotests/src/com/android/settings/notification/RedactionInterstitialTest.java
@@ -22,7 +22,7 @@
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.SettingsShadowResourcesImpl;
-import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
+import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settings.testutils.shadow.ShadowUtils;
@@ -39,7 +39,7 @@
SettingsShadowResourcesImpl.class,
SettingsShadowResources.SettingsShadowTheme.class,
ShadowUtils.class,
- ShadowRestrictedLockUtils.class,
+ ShadowRestrictedLockUtilsInternal.class,
ShadowUserManager.class,
})
public class RedactionInterstitialTest {
@@ -49,7 +49,7 @@
@After
public void tearDown() {
ShadowUserManager.getShadow().reset();
- ShadowRestrictedLockUtils.reset();
+ ShadowRestrictedLockUtilsInternal.reset();
}
@Test
@@ -85,7 +85,7 @@
@Test
public void primaryUserUnredactedRestrictionTest() {
setupSettings(1 /* show */, 1 /* showUnredacted */);
- ShadowRestrictedLockUtils.setKeyguardDisabledFeatures(
+ ShadowRestrictedLockUtilsInternal.setKeyguardDisabledFeatures(
KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
setupActivity();
@@ -97,7 +97,7 @@
@Test
public void primaryUserNotificationRestrictionTest() {
setupSettings(1 /* show */, 1 /* showUnredacted */);
- ShadowRestrictedLockUtils.setKeyguardDisabledFeatures(
+ ShadowRestrictedLockUtilsInternal.setKeyguardDisabledFeatures(
KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
setupActivity();
@@ -121,7 +121,7 @@
public void managedProfileUnredactedRestrictionTest() {
setupSettings(1 /* show */, 1 /* showUnredacted */);
ShadowUserManager.getShadow().addManagedProfile(UserHandle.myUserId());
- ShadowRestrictedLockUtils.setKeyguardDisabledFeatures(
+ ShadowRestrictedLockUtilsInternal.setKeyguardDisabledFeatures(
KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
setupActivity();
diff --git a/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java b/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java
index fa1c0f7..af77ad8 100644
--- a/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java
+++ b/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java
@@ -113,7 +113,7 @@
// GIVEN the device supports face.
when(mFaceManager.isHardwareDetected()).thenReturn(true);
// GIVEN there are no enrolled face.
- when(mFaceManager.hasEnrolledFaces(CURRENT_USER_ID)).thenReturn(false);
+ when(mFaceManager.hasEnrolledTemplates(CURRENT_USER_ID)).thenReturn(false);
// GIVEN DPC does not disallow face for keyguard usage.
when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(ComponentName.class)))
.thenReturn(0);
@@ -180,7 +180,7 @@
// GIVEN the device does NOT support face.
when(mFaceManager.isHardwareDetected()).thenReturn(false);
// GIVEN there are no enrolled face.
- when(mFaceManager.hasEnrolledFaces(CURRENT_USER_ID)).thenReturn(false);
+ when(mFaceManager.hasEnrolledTemplates(CURRENT_USER_ID)).thenReturn(false);
// GIVEN DPC does not disallow face for keyguard usage.
when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(ComponentName.class)))
.thenReturn(0);
@@ -218,7 +218,7 @@
// GIVEN the device supports face.
when(mFaceManager.isHardwareDetected()).thenReturn(true);
// GIVEN there are no enrolled face.
- when(mFaceManager.hasEnrolledFaces(CURRENT_USER_ID)).thenReturn(true);
+ when(mFaceManager.hasEnrolledTemplates(CURRENT_USER_ID)).thenReturn(true);
// GIVEN DPC does not disallow face for keyguard usage.
when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(ComponentName.class)))
.thenReturn(0);
@@ -256,7 +256,7 @@
// GIVEN the device supports face.
when(mFaceManager.isHardwareDetected()).thenReturn(true);
// GIVEN there is an enrolled face.
- when(mFaceManager.hasEnrolledFaces(CURRENT_USER_ID)).thenReturn(true);
+ when(mFaceManager.hasEnrolledTemplates(CURRENT_USER_ID)).thenReturn(true);
// GIVEN DPC disallows face for keyguard usage.
when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(ComponentName.class)))
.thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FACE);
diff --git a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentsPreferenceControllerTest.java
index f4d7a32..ede6a8f 100644
--- a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentsPreferenceControllerTest.java
@@ -35,7 +35,7 @@
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
-import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
+import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedSwitchPreference;
import org.junit.After;
@@ -55,7 +55,7 @@
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = {
ShadowLockPatternUtils.class,
- ShadowRestrictedLockUtils.class,
+ ShadowRestrictedLockUtilsInternal.class,
ShadowDevicePolicyManager.class,
ShadowApplicationPackageManager.class,
TrustAgentsPreferenceControllerTest.ShadowTrustAgentManager.class
@@ -145,7 +145,7 @@
@Test
public void onStart_hasUnrestrictedTrustAgent_shouldAddThreeChangeablePreferences() {
- ShadowRestrictedLockUtils.setKeyguardDisabledFeatures(0);
+ ShadowRestrictedLockUtilsInternal.setKeyguardDisabledFeatures(0);
final List<ResolveInfo> availableAgents = createFakeAvailableAgents();
for (ResolveInfo rInfo : availableAgents) {
ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
@@ -170,7 +170,7 @@
ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
}
mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
- ShadowRestrictedLockUtils.setKeyguardDisabledFeatures(
+ ShadowRestrictedLockUtilsInternal.setKeyguardDisabledFeatures(
DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS);
mController.displayPreference(mPreferenceScreen);
diff --git a/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java b/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
index ad808fc..87f0a37 100644
--- a/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
+++ b/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
@@ -76,6 +76,8 @@
paths.add(new ResourcePath(null,
Fs.fromURL(new URL("file:frameworks/base/packages/SettingsLib/res")), null));
paths.add(new ResourcePath(null,
+ Fs.fromURL(new URL("file:frameworks/base/packages/SettingsLib/HelpUtils/res/")), null));
+ paths.add(new ResourcePath(null,
Fs.fromURL(new URL("file:frameworks/base/core/res/res")), null));
paths.add(new ResourcePath(null,
Fs.fromURL(new URL("file:frameworks/opt/setupwizard/library/main/res")), null));
@@ -86,6 +88,8 @@
paths.add(new ResourcePath(null,
Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.appcompat_appcompat-nodeps/android_common/aar/res/")), null));
paths.add(new ResourcePath(null,
+ Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/extras/material-design-x/com.google.android.material_material-nodeps/android_common/aar/res/")), null));
+ paths.add(new ResourcePath(null,
Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.cardview_cardview-nodeps/android_common/aar/res")), null));
} catch (MalformedURLException e) {
throw new RuntimeException("SettingsRobolectricTestRunner failure", e);
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtils.java
index d1cedec..c054656 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtils.java
@@ -15,99 +15,24 @@
*/
package com.android.settings.testutils.shadow;
-import android.annotation.UserIdInt;
-import android.app.admin.DevicePolicyManager;
import android.content.Context;
-import com.android.internal.util.ArrayUtils;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
-import org.robolectric.annotation.Resetter;
@Implements(RestrictedLockUtils.class)
public class ShadowRestrictedLockUtils {
- private static boolean sIsRestricted;
private static boolean sAdminSupportDetailsIntentLaunched;
- private static boolean sHasSystemFeature;
- private static boolean sMaximumTimeToLockIsSet;
- private static String[] sRestrictedPkgs;
- private static DevicePolicyManager sDevicePolicyManager;
- private static String[] sDisabledTypes;
- private static int sKeyguardDisabledFeatures;
-
- @Resetter
- public static void reset() {
- sIsRestricted = false;
- sRestrictedPkgs = null;
- sAdminSupportDetailsIntentLaunched = false;
- sKeyguardDisabledFeatures = 0;
- sDisabledTypes = new String[0];
- sMaximumTimeToLockIsSet = false;
- }
-
- @Implementation
- public static EnforcedAdmin checkIfMeteredDataRestricted(Context context,
- String packageName, int userId) {
- if (sIsRestricted) {
- return new EnforcedAdmin();
- }
- if (ArrayUtils.contains(sRestrictedPkgs, packageName)) {
- return new EnforcedAdmin();
- }
- return null;
- }
@Implementation
public static void sendShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin) {
sAdminSupportDetailsIntentLaunched = true;
}
- @Implementation
- public static EnforcedAdmin checkIfAccountManagementDisabled(Context context,
- String accountType, int userId) {
- if (accountType == null) {
- return null;
- }
- if (!sHasSystemFeature || sDevicePolicyManager == null) {
- return null;
- }
- boolean isAccountTypeDisabled = false;
- if (ArrayUtils.contains(sDisabledTypes, accountType)) {
- isAccountTypeDisabled = true;
- }
- if (!isAccountTypeDisabled) {
- return null;
- }
- return new EnforcedAdmin();
- }
-
- @Implementation
- public static EnforcedAdmin checkIfKeyguardFeaturesDisabled(Context context,
- int features, final @UserIdInt int userId) {
- return (sKeyguardDisabledFeatures & features) == 0 ? null : new EnforcedAdmin();
- }
-
- @Implementation
- public static boolean hasBaseUserRestriction(Context context,
- String userRestriction, int userId) {
- return sIsRestricted;
- }
-
- @Implementation
- public static EnforcedAdmin checkIfRestrictionEnforced(Context context,
- String userRestriction, int userId) {
- return sIsRestricted ? new EnforcedAdmin() : null;
- }
-
- @Implementation
- public static EnforcedAdmin checkIfMaximumTimeToLockIsSet(Context context) {
- return sMaximumTimeToLockIsSet ? new EnforcedAdmin() : null;
- }
-
public static boolean hasAdminSupportDetailsIntentLaunched() {
return sAdminSupportDetailsIntentLaunched;
}
@@ -116,36 +41,5 @@
sAdminSupportDetailsIntentLaunched = false;
}
- public static void setRestricted(boolean restricted) {
- sIsRestricted = restricted;
- }
-
- public static void setRestrictedPkgs(String... pkgs) {
- sRestrictedPkgs = pkgs;
- }
-
- public static void setHasSystemFeature(boolean hasSystemFeature) {
- sHasSystemFeature = hasSystemFeature;
- }
-
- public static void setDevicePolicyManager(DevicePolicyManager dpm) {
- sDevicePolicyManager = dpm;
- }
-
- public static void setDisabledTypes(String[] disabledTypes) {
- sDisabledTypes = disabledTypes;
- }
-
- public static void clearDisabledTypes() {
- sDisabledTypes = new String[0];
- }
-
- public static void setKeyguardDisabledFeatures(int features) {
- sKeyguardDisabledFeatures = features;
- }
-
- public static void setMaximumTimeToLockIsSet(boolean isSet) {
- sMaximumTimeToLockIsSet = isSet;
- }
}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtilsInternal.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtilsInternal.java
new file mode 100644
index 0000000..1508431
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtilsInternal.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.testutils.shadow;
+
+import android.annotation.UserIdInt;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+
+import com.android.internal.util.ArrayUtils;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedLockUtilsInternal;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+@Implements(RestrictedLockUtilsInternal.class)
+public class ShadowRestrictedLockUtilsInternal {
+
+ private static boolean sIsRestricted;
+ private static boolean sHasSystemFeature;
+ private static boolean sMaximumTimeToLockIsSet;
+ private static String[] sRestrictedPkgs;
+ private static DevicePolicyManager sDevicePolicyManager;
+ private static String[] sDisabledTypes;
+ private static int sKeyguardDisabledFeatures;
+
+ @Resetter
+ public static void reset() {
+ sIsRestricted = false;
+ sRestrictedPkgs = null;
+ sKeyguardDisabledFeatures = 0;
+ sDisabledTypes = new String[0];
+ sMaximumTimeToLockIsSet = false;
+ }
+
+ @Implementation
+ public static EnforcedAdmin checkIfMeteredDataRestricted(Context context,
+ String packageName, int userId) {
+ if (sIsRestricted) {
+ return new EnforcedAdmin();
+ }
+ if (ArrayUtils.contains(sRestrictedPkgs, packageName)) {
+ return new EnforcedAdmin();
+ }
+ return null;
+ }
+
+ @Implementation
+ public static EnforcedAdmin checkIfAccountManagementDisabled(Context context,
+ String accountType, int userId) {
+ if (accountType == null) {
+ return null;
+ }
+ if (!sHasSystemFeature || sDevicePolicyManager == null) {
+ return null;
+ }
+ boolean isAccountTypeDisabled = false;
+ if (ArrayUtils.contains(sDisabledTypes, accountType)) {
+ isAccountTypeDisabled = true;
+ }
+ if (!isAccountTypeDisabled) {
+ return null;
+ }
+ return new EnforcedAdmin();
+ }
+
+ @Implementation
+ public static EnforcedAdmin checkIfKeyguardFeaturesDisabled(Context context,
+ int features, final @UserIdInt int userId) {
+ return (sKeyguardDisabledFeatures & features) == 0 ? null : new EnforcedAdmin();
+ }
+
+ @Implementation
+ public static boolean hasBaseUserRestriction(Context context,
+ String userRestriction, int userId) {
+ return sIsRestricted;
+ }
+
+ @Implementation
+ public static EnforcedAdmin checkIfRestrictionEnforced(Context context,
+ String userRestriction, int userId) {
+ return sIsRestricted ? new EnforcedAdmin() : null;
+ }
+
+ @Implementation
+ public static EnforcedAdmin checkIfMaximumTimeToLockIsSet(Context context) {
+ return sMaximumTimeToLockIsSet ? new EnforcedAdmin() : null;
+ }
+
+ public static void setRestricted(boolean restricted) {
+ sIsRestricted = restricted;
+ }
+
+ public static void setRestrictedPkgs(String... pkgs) {
+ sRestrictedPkgs = pkgs;
+ }
+
+ public static void setHasSystemFeature(boolean hasSystemFeature) {
+ sHasSystemFeature = hasSystemFeature;
+ }
+
+ public static void setDevicePolicyManager(DevicePolicyManager dpm) {
+ sDevicePolicyManager = dpm;
+ }
+
+ public static void setDisabledTypes(String[] disabledTypes) {
+ sDisabledTypes = disabledTypes;
+ }
+
+ public static void clearDisabledTypes() {
+ sDisabledTypes = new String[0];
+ }
+
+ public static void setKeyguardDisabledFeatures(int features) {
+ sKeyguardDisabledFeatures = features;
+ }
+
+ public static void setMaximumTimeToLockIsSet(boolean isSet) {
+ sMaximumTimeToLockIsSet = isSet;
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
index 753d159..3266a7f 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
@@ -80,6 +80,15 @@
}
@Implementation
+ public int[] getProfileIds(@UserIdInt int userHandle, boolean enabledOnly) {
+ int[] ids = new int[mUserProfileInfos.size()];
+ for (int i = 0; i < mUserProfileInfos.size(); i++) {
+ ids[i] = mUserProfileInfos.get(i).id;
+ }
+ return ids;
+ }
+
+ @Implementation
public int getCredentialOwnerProfile(@UserIdInt int userHandle) {
return userHandle;
}
diff --git a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
index 41f48c6..02c279e 100644
--- a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
@@ -21,6 +21,7 @@
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -184,4 +185,58 @@
assertThat(addUser.isEnabled()).isFalse();
}
+
+ @Test
+ public void updateUserList_cannotAddUserButCanSwitchUser_shouldNotShowAddUser() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.DEVICE_PROVISIONED, 1);
+ final RestrictedPreference addUser = mock(RestrictedPreference.class);
+
+ mUserCapabilities.mCanAddUser = false;
+ mUserCapabilities.mDisallowAddUser = true;
+ mUserCapabilities.mUserSwitcherEnabled = true;
+
+ ReflectionHelpers.setField(mFragment, "mUserManager", mUserManager);
+ ReflectionHelpers.setField(mFragment, "mUserCaps", mUserCapabilities);
+ ReflectionHelpers.setField(mFragment, "mDefaultIconDrawable", mDefaultIconDrawable);
+ ReflectionHelpers.setField(mFragment, "mAddingUser", false);
+ mFragment.mMePreference = mMePreference;
+ mFragment.mUserListCategory = mock(PreferenceCategory.class);
+ mFragment.mAddUser = addUser;
+
+ doReturn(mock(PreferenceScreen.class)).when(mFragment).getPreferenceScreen();
+
+ mFragment.updateUserList();
+
+ verify(addUser, never()).setVisible(true);
+
+ }
+
+ @Test
+ public void updateUserList_canAddUserAndSwitchUser_shouldShowAddUser() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.DEVICE_PROVISIONED, 1);
+ final RestrictedPreference addUser = mock(RestrictedPreference.class);
+
+ mUserCapabilities.mCanAddUser = true;
+ mUserCapabilities.mDisallowAddUser = false;
+ mUserCapabilities.mUserSwitcherEnabled = true;
+
+ ReflectionHelpers.setField(mFragment, "mUserManager", mUserManager);
+ ReflectionHelpers.setField(mFragment, "mUserCaps", mUserCapabilities);
+ ReflectionHelpers.setField(mFragment, "mDefaultIconDrawable", mDefaultIconDrawable);
+ ReflectionHelpers.setField(mFragment, "mAddingUser", false);
+ mFragment.mMePreference = mMePreference;
+ mFragment.mUserListCategory = mock(PreferenceCategory.class);
+ mFragment.mAddUser = addUser;
+
+ doReturn(mock(PreferenceScreen.class)).when(mFragment).getPreferenceScreen();
+ doReturn("Test summary").when(mFragment).getString(anyInt(), anyInt());
+
+ mFragment.updateUserList();
+
+ verify(addUser).setVisible(true);
+
+ }
+
}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
index 5e8dd28..54be773 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
@@ -184,6 +184,22 @@
}
@Test
+ public void isSubmittable_EapToPskWithValidPassword_shouldReturnTrue() {
+ final TextView password = mView.findViewById(R.id.password);
+ final Spinner securitySpinner = mView.findViewById(R.id.security);
+ assertThat(password).isNotNull();
+ assertThat(securitySpinner).isNotNull();
+ when(mAccessPoint.isSaved()).thenReturn(true);
+
+ // Change it from EAP to PSK
+ mController.onItemSelected(securitySpinner, null, AccessPoint.SECURITY_EAP, 0);
+ mController.onItemSelected(securitySpinner, null, AccessPoint.SECURITY_PSK, 0);
+ password.setText(GOOD_PSK);
+
+ assertThat(mController.isSubmittable()).isTrue();
+ }
+
+ @Test
public void getSignalString_notReachable_shouldHaveNoSignalString() {
when(mAccessPoint.isReachable()).thenReturn(false);
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java
index 71a7298..53b3a64 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java
@@ -26,7 +26,7 @@
import android.net.wifi.WifiManager;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
+import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
import com.android.settings.widget.SwitchWidgetController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -38,7 +38,7 @@
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(shadows = ShadowRestrictedLockUtils.class)
+@Config(shadows = ShadowRestrictedLockUtilsInternal.class)
public class WifiEnablerTest {
@Mock
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java
index 06d3479..5aef036 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java
@@ -37,7 +37,7 @@
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
+import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
import com.android.settings.widget.MasterSwitchPreference;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -50,7 +50,7 @@
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(shadows = ShadowRestrictedLockUtils.class)
+@Config(shadows = ShadowRestrictedLockUtilsInternal.class)
public class WifiMasterSwitchPreferenceControllerTest {
@Mock