Merge "Persist token across activity lifecycle"
diff --git a/Android.mk b/Android.mk
index c99e30c..e385b34 100644
--- a/Android.mk
+++ b/Android.mk
@@ -23,6 +23,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_STATIC_ANDROID_LIBRARIES := \
+    androidx-constraintlayout_constraintlayout \
     androidx.slice_slice-builders \
     androidx.slice_slice-core \
     androidx.slice_slice-view \
@@ -40,6 +41,7 @@
     ims-common
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
+    androidx-constraintlayout_constraintlayout-solver \
     androidx.lifecycle_lifecycle-runtime \
     androidx.lifecycle_lifecycle-extensions \
     guava \
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 1caebbb..69a67ad 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2007,9 +2007,8 @@
             </intent-filter>
         </activity>
 
-        <!-- TODO: Is this needed? -->
         <activity android:name="BandMode"
-                  android:theme="@android:style/Theme.DeviceDefault.Light.Dialog.Alert"
+                  android:label="@string/band_mode_title"
                   android:process="com.android.phone">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/res/drawable/ic_battery_saver_accent_24dp.xml b/res/drawable/ic_battery_saver_accent_24dp.xml
new file mode 100644
index 0000000..c8def54
--- /dev/null
+++ b/res/drawable/ic_battery_saver_accent_24dp.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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/colorAccent">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M15,14l-2,0l0,2l-2,0l0,-2l-2,0l0,-2l2,0l0,-2l2,0l0,2l2,0z"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M16.2,22.5H7.8c-1.3,0 -2.3,-1 -2.3,-2.3V5.8c0,-1.3 1,-2.3 2.3,-2.3h0.7v-2h7v2h0.7c1.3,0 2.3,1.1 2.3,2.3v14.3C18.5,21.5 17.5,22.5 16.2,22.5zM7.8,5.5c-0.2,0 -0.3,0.2 -0.3,0.3v14.3c0,0.2 0.2,0.3 0.3,0.3h8.3c0.2,0 0.3,-0.1 0.3,-0.3V5.8c0,-0.2 -0.1,-0.3 -0.3,-0.3h-2.7v-2h-3v2H7.8z"/>
+</vector>
diff --git a/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml
index 21df686..4eed0f6 100644
--- a/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml
+++ b/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml
@@ -19,29 +19,40 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/root"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
+    android:layout_height="match_parent">
 
-    <include layout="@layout/wifi_dpp_fragment_header"/>
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
 
-    <com.android.settings.wifi.qrcode.QrPreviewLayout
-        android:layout_width="@dimen/qrcode_preview_size"
-        android:layout_height="@dimen/qrcode_preview_size"
-        android:layout_gravity="center">
-        <TextureView
-            android:id="@+id/preview_view"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"/>
-        <com.android.settings.wifi.qrcode.QrDecorateView
-            android:id="@+id/decorate_view"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"/>
-    </com.android.settings.wifi.qrcode.QrPreviewLayout>
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="vertical"
+            android:gravity="center_horizontal">
 
-    <TextView android:id="@+id/error_message"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"/>
+            <include layout="@layout/wifi_dpp_fragment_header"/>
+
+            <com.android.settings.wifi.qrcode.QrPreviewLayout
+                android:layout_width="@dimen/qrcode_preview_size"
+                android:layout_height="@dimen/qrcode_preview_size">
+                <TextureView
+                    android:id="@+id/preview_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"/>
+                <com.android.settings.wifi.qrcode.QrDecorateView
+                    android:id="@+id/decorate_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"/>
+            </com.android.settings.wifi.qrcode.QrPreviewLayout>
+
+            <TextView android:id="@+id/error_message"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"/>
+
+        </LinearLayout>
+
+    </ScrollView>
 
 </LinearLayout>
 
diff --git a/res/layout/band_mode.xml b/res/layout/band_mode.xml
index ddbc7ae..b43dd1d 100644
--- a/res/layout/band_mode.xml
+++ b/res/layout/band_mode.xml
@@ -19,7 +19,7 @@
               android:padding="4dip"
               android:gravity="center_horizontal"
               android:layout_width="match_parent"
-              android:layout_height="match_parent">
+              android:layout_height="wrap_content">
 
     <ListView android:id="@+id/band"
               android:layout_width="match_parent"
diff --git a/res/layout/homepage_dismissal_view.xml b/res/layout/homepage_dismissal_view.xml
index e31d436..7d1abf3 100644
--- a/res/layout/homepage_dismissal_view.xml
+++ b/res/layout/homepage_dismissal_view.xml
@@ -20,6 +20,7 @@
     android:id="@+id/dismissal_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:background="@color/homepage_card_dismissal_background"
     android:orientation="vertical">
 
     <TextView
diff --git a/res/layout/homepage_slice_half_tile.xml b/res/layout/homepage_slice_half_tile.xml
index 7de9eb6..46f3cda 100644
--- a/res/layout/homepage_slice_half_tile.xml
+++ b/res/layout/homepage_slice_half_tile.xml
@@ -24,12 +24,12 @@
     <ViewFlipper
         android:id="@+id/view_flipper"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content">
+        android:layout_height="match_parent">
 
         <LinearLayout
             android:id="@+id/content"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
+            android:layout_height="match_parent"
             android:paddingStart="@dimen/homepage_card_padding_start"
             android:paddingEnd="@dimen/homepage_card_padding_end"
             android:paddingTop="@dimen/homepage_half_card_padding_top"
diff --git a/res/layout/time_zone_search_item.xml b/res/layout/time_zone_search_item.xml
index bb75226..8d059a8 100644
--- a/res/layout/time_zone_search_item.xml
+++ b/res/layout/time_zone_search_item.xml
@@ -63,7 +63,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:singleLine="true"
-            android:textAppearance="@style/Preference_TextAppearanceMaterialSubhead"
+            android:textAppearance="?android:attr/textAppearanceListItem"
             android:ellipsize="marquee" />
 
         <RelativeLayout
diff --git a/res/layout/wifi_dpp_activity.xml b/res/layout/wifi_dpp_activity.xml
index 48f2b65..cb82f66 100644
--- a/res/layout/wifi_dpp_activity.xml
+++ b/res/layout/wifi_dpp_activity.xml
@@ -15,7 +15,7 @@
      limitations under the License.
 -->
 
-<ScrollView
+<LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/root"
     android:layout_width="match_parent"
@@ -27,4 +27,4 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"/>
 
-</ScrollView>
+</LinearLayout>
diff --git a/res/layout/wifi_dpp_add_device_fragment.xml b/res/layout/wifi_dpp_add_device_fragment.xml
index 5e70396..2d1ce5b 100644
--- a/res/layout/wifi_dpp_add_device_fragment.xml
+++ b/res/layout/wifi_dpp_add_device_fragment.xml
@@ -15,31 +15,49 @@
      limitations under the License.
 -->
 
-<LinearLayout
+<androidx.constraintlayout.widget.ConstraintLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/root"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
+    android:layout_height="match_parent">
 
-    <include layout="@layout/wifi_dpp_fragment_header"/>
-
-    <ImageView
-        android:id="@+id/wifi_ap_picture_view"
+    <ScrollView
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"/>
+        android:layout_height="match_parent">
 
-    <TextView
-        android:id="@+id/choose_different_network"
-        android:layout_width="wrap_content"
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="center_horizontal"
+            android:orientation="vertical">
+
+            <include layout="@layout/wifi_dpp_fragment_header"/>
+
+            <ImageView
+                android:id="@+id/wifi_ap_picture_view"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                app:layout_constraintTop_toBottomOf="@+id/header"/>
+
+            <Button
+                android:id="@+id/choose_different_network"
+                style="@style/SuwGlifButton.Secondary"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                app:layout_constraintTop_toBottomOf="@+id/wifi_ap_picture_view"
+                android:layout_marginTop="8dp"
+                android:text="@string/wifi_dpp_choose_different_network"/>
+
+        </LinearLayout>
+
+    </ScrollView>
+
+    <include
+        layout="@layout/wifi_dpp_fragment_footer"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:layout_marginTop="8dp"
-        android:text="@string/wifi_dpp_choose_different_network"/>
+        app:layout_constraintBottom_toBottomOf="parent"/>
 
-    <include layout="@layout/wifi_dpp_fragment_footer"
-        android:gravity="center|bottom"/>
-
-</LinearLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>
 
diff --git a/res/layout/wifi_dpp_choose_saved_wifi_network_fragment.xml b/res/layout/wifi_dpp_choose_saved_wifi_network_fragment.xml
index a65cf3e..c3fccd0 100644
--- a/res/layout/wifi_dpp_choose_saved_wifi_network_fragment.xml
+++ b/res/layout/wifi_dpp_choose_saved_wifi_network_fragment.xml
@@ -15,21 +15,39 @@
      limitations under the License.
 -->
 
-<LinearLayout
+<androidx.constraintlayout.widget.ConstraintLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/root"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
+    android:layout_height="match_parent">
 
-    <include layout="@layout/wifi_dpp_fragment_header"/>
-
-    <ListView android:id="@+id/saved_wifi_network_list"
+    <ScrollView
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"/>
+        android:layout_height="match_parent">
 
-    <include layout="@layout/wifi_dpp_fragment_footer"
-        android:gravity="center|bottom"/>
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="center_horizontal"
+            android:orientation="vertical">
 
-</LinearLayout>
+            <include layout="@layout/wifi_dpp_fragment_header"/>
+
+            <ListView android:id="@+id/saved_wifi_network_list"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                app:layout_constraintTop_toBottomOf="@+id/header"/>
+
+        </LinearLayout>
+
+    </ScrollView>
+
+    <include
+        layout="@layout/wifi_dpp_fragment_footer"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_constraintBottom_toBottomOf="parent"/>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
 
diff --git a/res/layout/wifi_dpp_fragment_footer.xml b/res/layout/wifi_dpp_fragment_footer.xml
index 98c6485..36ec1d7 100644
--- a/res/layout/wifi_dpp_fragment_footer.xml
+++ b/res/layout/wifi_dpp_fragment_footer.xml
@@ -18,16 +18,15 @@
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="horizontal">
+    android:layout_height="wrap_content"
+    style="@style/SuwGlifButtonBar">
 
     <Button
         android:id="@+id/button_left"
+        style="@style/SuwGlifButton.Secondary"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_gravity="bottom|start"
-        android:text="left"
-        style="?android:attr/borderlessButtonStyle"/>
+        android:layout_gravity="start"/>
 
     <Space
         android:layout_width="0dp"
@@ -36,9 +35,9 @@
 
     <Button
         android:id="@+id/button_right"
+        style="@style/SuwGlifButton.Primary"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_gravity="bottom|end"
-        android:text="right"/>
+        android:layout_gravity="end"/>
 
 </LinearLayout>
diff --git a/res/layout/wifi_dpp_qrcode_generator_fragment.xml b/res/layout/wifi_dpp_qrcode_generator_fragment.xml
index c7c258b..2617aea 100644
--- a/res/layout/wifi_dpp_qrcode_generator_fragment.xml
+++ b/res/layout/wifi_dpp_qrcode_generator_fragment.xml
@@ -22,14 +22,27 @@
     android:layout_height="match_parent"
     android:orientation="vertical">
 
-    <include layout="@layout/wifi_dpp_fragment_header"/>
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
 
-    <ImageView
-        android:id="@+id/qrcode_view"
-        android:layout_width="@dimen/qrcode_size"
-        android:layout_height="@dimen/qrcode_size"
-        android:src="@android:color/transparent"
-        android:layout_gravity="center"/>
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="center_horizontal"
+            android:orientation="vertical">
+
+            <include layout="@layout/wifi_dpp_fragment_header"/>
+
+            <ImageView
+                android:id="@+id/qrcode_view"
+                android:layout_width="@dimen/qrcode_size"
+                android:layout_height="@dimen/qrcode_size"
+                android:src="@android:color/transparent"/>
+
+        </LinearLayout>
+
+    </ScrollView>
 
 </LinearLayout>
 
diff --git a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
index f09fc69..c5e416b 100644
--- a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
+++ b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
@@ -19,35 +19,45 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/root"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
+    android:layout_height="match_parent">
 
-    <include layout="@layout/wifi_dpp_fragment_header"/>
-
-    <com.android.settings.wifi.qrcode.QrPreviewLayout
+    <ScrollView
         android:layout_width="match_parent"
         android:layout_height="match_parent">
-        <TextureView
-            android:id="@+id/preview_view"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"/>
-        <com.android.settings.wifi.qrcode.QrDecorateView
-            android:id="@+id/decorate_view"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"/>
-    </com.android.settings.wifi.qrcode.QrPreviewLayout>
 
-    <TextView
-        android:id="@+id/error_message"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:layout_marginTop="8dp"
-        android:text="@string/wifi_dpp_could_not_detect_valid_qr_code"
-        android:visibility="invisible"
-        android:textColor="?android:attr/colorError"/>
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="vertical"
+            android:gravity="center_horizontal">
+
+            <include layout="@layout/wifi_dpp_fragment_header"/>
+
+            <com.android.settings.wifi.qrcode.QrPreviewLayout
+                android:layout_width="match_parent"
+                android:layout_height="match_parent">
+                <TextureView
+                    android:id="@+id/preview_view"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"/>
+                <com.android.settings.wifi.qrcode.QrDecorateView
+                    android:id="@+id/decorate_view"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"/>
+            </com.android.settings.wifi.qrcode.QrPreviewLayout>
+
+            <TextView
+                android:id="@+id/error_message"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="8dp"
+                android:text="@string/wifi_dpp_could_not_detect_valid_qr_code"
+                android:visibility="invisible"
+                android:textColor="?android:attr/colorError"/>
+
+        </LinearLayout>
+
+    </ScrollView>
 
 </LinearLayout>
 
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
index f864e03..cdbeada 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -23,5 +23,6 @@
   <color name="homepage_support_background">#3F5FBD</color>
   <!-- 80% black for status bar of homepage -->
   <color name="homepage_status_bar_color">#cc000000</color>
+  <color name="homepage_card_dismissal_background">@*android:color/material_grey_800</color>
 </resources>
 
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 5539d68..a1381c3 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -104,6 +104,7 @@
     <color name="homepage_about_background">#9FA8DA</color>
     <color name="homepage_privacy_background">#5E97F6</color>
     <color name="homepage_card_stroke_color">#1f000000</color>
+    <color name="homepage_card_dismissal_background">@*android:color/material_grey_50</color>
     <!-- End of dashboard/homepage icon background colors -->
 
     <color name="switchbar_text_color">@android:color/white</color>
diff --git a/res/values/config.xml b/res/values/config.xml
index 82e185c..8efa6b2 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -171,4 +171,7 @@
 
     <!-- ComponentName to launch a vendor-specific enrollment activity if available -->
     <string name="config_face_enroll" translatable="false"></string>
+
+    <!-- Max allowed value for screen timeout, in milliseconds -->
+    <integer name="max_lock_after_timeout_ms">1800000</integer>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 61b6c14..9698dcb 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5828,9 +5828,6 @@
          Used in SetupWizard for XLarge screen [CHAR LIMIT=20] -->
     <string name="wifi_setup_detail">Network details</string>
 
-    <!-- Do not translate. This is a stub which will be removed soon. -->
-    <string name="time_zone_auto_stub" translatable="false">Select Time Zone</string>
-
     <!-- Content description of the enabled sync icon for accessibility. [CHAR LIMIT=NONE] -->
     <string name="accessibility_sync_enabled">Sync enabled</string>
     <!-- Content description of the disabled sync icon for accessibility. [CHAR LIMIT=NONE] -->
@@ -7142,8 +7139,8 @@
     <!-- Sound: Other sounds: Title for the option enabling touch sounds for screen locking sounds. [CHAR LIMIT=30] -->
     <string name="screen_locking_sounds_title">Screen locking sounds</string>
 
-    <!-- Sound: Other sounds: Title for the option enabling charging sounds. [CHAR LIMIT=30] -->
-    <string name="charging_sounds_title">Charging sounds</string>
+    <!-- Sound: Other sounds: Title for the option enabling charging sounds and vibration. [CHAR LIMIT=30] -->
+    <string name="charging_sounds_title">Charging sounds and vibration</string>
 
     <!-- Sound: Other sounds: Title for the option enabling docking sounds. [CHAR LIMIT=30] -->
     <string name="docking_sounds_title">Docking sounds</string>
@@ -9094,6 +9091,12 @@
     <!-- Summary of condition that do not disturb is on [CHAR LIMIT=36] -->
     <string name="condition_zen_summary">Impacts what you hear and see</string>
 
+    <!-- Title of condition that battery saver is on [CHAR LIMIT=30] -->
+    <string name="condition_battery_title">Battery Saver is on</string>
+
+    <!-- Summary of condition that battery saver is on [CHAR LIMIT=NONE] -->
+    <string name="condition_battery_summary">Features restricted</string>
+
     <!-- Title of condition that cellular data is off [CHAR LIMIT=50] -->
     <string name="condition_cellular_title">Mobile data is off</string>
 
@@ -10058,17 +10061,24 @@
     <!-- UI debug setting: ANGLE enabled app has been set [CHAR LIMIT=NONE] -->
     <string name="angle_enabled_app_set">ANGLE enabled application: <xliff:g id="app_name" example="com.company.app">%1$s</xliff:g></string>
 
-    <!-- UI debug setting: select an app to use Game Update Package [CHAR LIMIT=100] -->
-    <string name="gup_dev_opt_in_app">Use Game Update Package</string>
-    <!-- UI debug setting: no app selected to use Game Update Package [CHAR LIMIT=100] -->
-    <string name="gup_dev_opt_in_app_not_set">No selected app</string>
-    <!-- UI debug setting: app selected to use Game Update Package [CHAR LIMIT=NONE] -->
-    <string name="gup_dev_opt_in_app_set"><xliff:g id="app_name" example="com.company.app">%1$s</xliff:g></string>
-
     <!-- Title for Game Update Packages dashboard where developers can configure apps to use GUP or not [CHAR LIMIT=50] -->
     <string name="gup_dashboard_title">Game Update Packages Preferences</string>
     <!-- Summary for Game Update Packages dashboard [CHAR LIMIT=50] -->
     <string name="gup_dashboard_summary">Modify Game Update Packages settings</string>
+    <!-- Title for Game Update Packages preference [CHAR LIMIT=50] -->
+    <string name="gup_app_preference_title">Select Graphics Driver</string>
+    <!-- The default value for Game Update Packages preference [CHAR LIMIT=50] -->
+    <string name="gup_app_preference_default">Default</string>
+    <!-- The gup value for Game Update Packages preference [CHAR LIMIT=50] -->
+    <string name="gup_app_preference_gup">Game Update Packages</string>
+    <!-- The native value for Game Update Packages preference [CHAR LIMIT=50] -->
+    <string name="gup_app_preference_native">Native Graphics Driver</string>
+    <!-- All the values for Game Update Packages preference [CHAR LIMIT=50] -->
+    <string-array name="gup_app_preference_values">
+        <item>@string/gup_app_preference_default</item>
+        <item>@string/gup_app_preference_gup</item>
+        <item>@string/gup_app_preference_native</item>
+    </string-array>
 
     <!-- Slices Strings -->
 
diff --git a/res/xml/date_time_prefs.xml b/res/xml/date_time_prefs.xml
index edda1ba..e8af64c 100644
--- a/res/xml/date_time_prefs.xml
+++ b/res/xml/date_time_prefs.xml
@@ -58,7 +58,7 @@
         <com.android.settingslib.RestrictedPreference
             android:fragment="com.android.settings.datetime.timezone.TimeZoneSettings"
             android:key="timezone"
-            android:title="@string/date_time_set_timezone"
+            android:title="@string/date_time_set_timezone_title"
             android:summary="@string/summary_placeholder"
             settings:userRestriction="no_config_date_time" />
     </PreferenceCategory>
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 2eedca5..a5e26f6 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -195,7 +195,8 @@
             android:key="gup_dashboard"
             android:title="@string/gup_dashboard_title"
             android:summary="@string/gup_dashboard_summary"
-            android:fragment="com.android.settings.development.gup.GupDashboard" />
+            android:fragment="com.android.settings.development.gup.GupDashboard"
+            settings:searchable="false" />
 
     </PreferenceCategory>
 
@@ -430,11 +431,6 @@
             android:summary="%s"
             android:title="@string/simulate_color_space" />
 
-        <Preference
-            android:title="@string/gup_dev_opt_in_app"
-            android:key="gup_dev_opt_in_app"
-            android:summary="@string/gup_dev_opt_in_app_summary" />
-
     </PreferenceCategory>
 
     <PreferenceCategory
diff --git a/res/xml/gup_settings.xml b/res/xml/gup_settings.xml
index 6344adb..43ba39b 100644
--- a/res/xml/gup_settings.xml
+++ b/res/xml/gup_settings.xml
@@ -17,4 +17,14 @@
 
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:title="@string/gup_dashboard_title" />
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:key="gup_settings"
+    android:title="@string/gup_dashboard_title">
+
+    <PreferenceCategory
+        android:key="gup_category"
+        android:title="@string/gup_app_preference_title"
+        settings:controller="com.android.settings.development.gup.GupPreferenceController">
+    </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/res/xml/privacy_dashboard_settings.xml b/res/xml/privacy_dashboard_settings.xml
index 79e2e71..a580f5f 100644
--- a/res/xml/privacy_dashboard_settings.xml
+++ b/res/xml/privacy_dashboard_settings.xml
@@ -19,7 +19,8 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="privacy_dashboard_page"
-    android:title="@string/privacy_dashboard_title">
+    android:title="@string/privacy_dashboard_title"
+    settings:initialExpandedChildrenCount="3">
 
     <!-- App permissions -->
     <Preference
@@ -30,13 +31,6 @@
         <intent android:action="android.intent.action.MANAGE_PERMISSIONS"/>
     </Preference>
 
-    <!-- On lock screen notifications -->
-    <com.android.settings.RestrictedListPreference
-        android:key="privacy_lock_screen_notifications"
-        android:title="@string/lock_screen_notifications_title"
-        android:summary="@string/summary_placeholder"
-        settings:searchable="false"/>
-
     <!-- Show passwords -->
     <SwitchPreference
         android:key="show_password"
@@ -44,6 +38,13 @@
         android:summary="@string/show_password_summary"
         settings:controller="com.android.settings.security.ShowPasswordPreferenceController"/>
 
+    <!-- On lock screen notifications -->
+    <com.android.settings.RestrictedListPreference
+        android:key="privacy_lock_screen_notifications"
+        android:title="@string/lock_screen_notifications_title"
+        android:summary="@string/summary_placeholder"
+        settings:searchable="false"/>
+
     <!-- Privacy Service -->
     <PreferenceCategory
         android:key="privacy_services"/>
diff --git a/src/com/android/settings/BandMode.java b/src/com/android/settings/BandMode.java
index 5be82f6..bae8860 100644
--- a/src/com/android/settings/BandMode.java
+++ b/src/com/android/settings/BandMode.java
@@ -73,13 +73,8 @@
         super.onCreate(icicle);
 
         requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
-
         setContentView(R.layout.band_mode);
 
-        setTitle(getString(R.string.band_mode_title));
-        getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT,
-                                    WindowManager.LayoutParams.WRAP_CONTENT);
-
         mPhone = PhoneFactory.getDefaultPhone();
 
         mBandList = (ListView) findViewById(R.id.band);
diff --git a/src/com/android/settings/development/DevelopmentOptionsActivityRequestCodes.java b/src/com/android/settings/development/DevelopmentOptionsActivityRequestCodes.java
index a67aac4..564f2c3 100644
--- a/src/com/android/settings/development/DevelopmentOptionsActivityRequestCodes.java
+++ b/src/com/android/settings/development/DevelopmentOptionsActivityRequestCodes.java
@@ -31,6 +31,4 @@
     int REQUEST_CODE_ANGLE_DRIVER_PKGS = 4;
 
     int REQUEST_CODE_ANGLE_DRIVER_VALUES = 5;
-
-    int REQUEST_CODE_GUP_DEV_OPT_IN_APPS = 6;
 }
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 5990320..725a195 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -423,7 +423,6 @@
         controllers.add(new SelectDebugAppPreferenceController(context, fragment));
         controllers.add(new WaitForDebuggerPreferenceController(context));
         controllers.add(new EnableGpuDebugLayersPreferenceController(context));
-        controllers.add(new GameUpdatePackageDevOptInPreferenceController(context, fragment));
         controllers.add(new VerifyAppsOverUsbPreferenceController(context));
         controllers.add(new LogdSizePreferenceController(context));
         controllers.add(new LogPersistPreferenceController(context, fragment, lifecycle));
diff --git a/src/com/android/settings/development/GameUpdatePackageDevOptInPreferenceController.java b/src/com/android/settings/development/GameUpdatePackageDevOptInPreferenceController.java
deleted file mode 100644
index 2d29505..0000000
--- a/src/com/android/settings/development/GameUpdatePackageDevOptInPreferenceController.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import static com.android.settings.development.DevelopmentOptionsActivityRequestCodes
-        .REQUEST_CODE_GUP_DEV_OPT_IN_APPS;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.provider.Settings;
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
-
-import com.android.settings.R;
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.development.DeveloperOptionsPreferenceController;
-
-// TODO(b/119221883): Need to override isAvailable() to return false when updatable graphics driver is not supported.
-public class GameUpdatePackageDevOptInPreferenceController
-        extends DeveloperOptionsPreferenceController
-        implements PreferenceControllerMixin, OnActivityResultListener {
-
-    private static final String GUP_DEV_OPT_IN_APP_KEY = "gup_dev_opt_in_app";
-
-    private final DevelopmentSettingsDashboardFragment mFragment;
-    private final PackageManager mPackageManager;
-
-    public GameUpdatePackageDevOptInPreferenceController(Context context,
-            DevelopmentSettingsDashboardFragment fragment) {
-        super(context);
-        mFragment = fragment;
-        mPackageManager = mContext.getPackageManager();
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return GUP_DEV_OPT_IN_APP_KEY;
-    }
-
-    @Override
-    public boolean handlePreferenceTreeClick(Preference preference) {
-        if (GUP_DEV_OPT_IN_APP_KEY.equals(preference.getKey())) {
-            // pass it on to settings
-            final Intent intent = getActivityStartIntent();
-            mFragment.startActivityForResult(intent, REQUEST_CODE_GUP_DEV_OPT_IN_APPS);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void updateState(Preference preference) {
-        updatePreferenceSummary();
-    }
-
-    @Override
-    public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (requestCode != REQUEST_CODE_GUP_DEV_OPT_IN_APPS
-                || resultCode != Activity.RESULT_OK) {
-            return false;
-        }
-        Settings.Global.putString(mContext.getContentResolver(),
-                Settings.Global.GUP_DEV_OPT_IN_APPS, data.getAction());
-        updatePreferenceSummary();
-        return true;
-    }
-
-    @Override
-    protected void onDeveloperOptionsSwitchDisabled() {
-        super.onDeveloperOptionsSwitchDisabled();
-        mPreference.setSummary(mContext.getResources().getString(
-                R.string.gup_dev_opt_in_app_not_set));
-    }
-
-    @VisibleForTesting
-    Intent getActivityStartIntent() {
-        Intent intent = new Intent(mContext, AppPicker.class);
-        intent.putExtra(AppPicker.EXTRA_NON_SYSTEM, true /* value */);
-        return intent;
-    }
-
-    private void updatePreferenceSummary() {
-        final String optInApp = Settings.Global.getString(
-                mContext.getContentResolver(), Settings.Global.GUP_DEV_OPT_IN_APPS);
-        if (optInApp != null && !optInApp.isEmpty()) {
-            mPreference.setSummary(mContext.getResources().getString(
-                    R.string.gup_dev_opt_in_app_set, getAppLabel(optInApp)));
-        } else {
-            mPreference.setSummary(mContext.getResources().getString(
-                    R.string.gup_dev_opt_in_app_not_set));
-        }
-    }
-
-    private String getAppLabel(String applicationPackageName) {
-        try {
-            final ApplicationInfo ai = mPackageManager.getApplicationInfo(applicationPackageName,
-                    PackageManager.GET_DISABLED_COMPONENTS);
-            final CharSequence lab = mPackageManager.getApplicationLabel(ai);
-            return lab != null ? lab.toString() : applicationPackageName;
-        } catch (PackageManager.NameNotFoundException e) {
-            return applicationPackageName;
-        }
-    }
-}
diff --git a/src/com/android/settings/development/featureflags/FeatureFlagPersistent.java b/src/com/android/settings/development/featureflags/FeatureFlagPersistent.java
index d27af64..33de9c3 100644
--- a/src/com/android/settings/development/featureflags/FeatureFlagPersistent.java
+++ b/src/com/android/settings/development/featureflags/FeatureFlagPersistent.java
@@ -37,6 +37,7 @@
     static {
         PERSISTENT_FLAGS = new HashSet<>();
         PERSISTENT_FLAGS.add(FeatureFlags.HEARING_AID_SETTINGS);
+        PERSISTENT_FLAGS.add(FeatureFlags.NETWORK_INTERNET_V2);
     }
 
     public static boolean isEnabled(Context context, String feature) {
diff --git a/src/com/android/settings/development/gup/GupDashboard.java b/src/com/android/settings/development/gup/GupDashboard.java
index 674a0a9..31f01dd 100644
--- a/src/com/android/settings/development/gup/GupDashboard.java
+++ b/src/com/android/settings/development/gup/GupDashboard.java
@@ -17,14 +17,22 @@
 package com.android.settings.development.gup;
 
 import android.content.Context;
+import android.provider.SearchIndexableResource;
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.development.DevelopmentSettingsEnabler;
+import com.android.settingslib.search.SearchIndexable;
 
+import java.util.ArrayList;
 import java.util.List;
 
+@SearchIndexable
 public class GupDashboard extends DashboardFragment {
     private static final String TAG = "GupDashboard";
 
@@ -47,4 +55,22 @@
     public int getHelpResource() {
         return 0;
     }
+
+    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider() {
+                @Override
+                public List<SearchIndexableResource> getXmlResourcesToIndex(
+                        Context context, boolean enabled) {
+                    final List<SearchIndexableResource> result = new ArrayList<>();
+                    final SearchIndexableResource sir = new SearchIndexableResource(context);
+                    sir.xmlResId = R.xml.gup_settings;
+                    result.add(sir);
+                    return result;
+                }
+
+                @Override
+                protected boolean isPageSearchEnabled(Context context) {
+                    return DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(context);
+                }
+            };
 }
diff --git a/src/com/android/settings/development/gup/GupPreferenceController.java b/src/com/android/settings/development/gup/GupPreferenceController.java
new file mode 100644
index 0000000..7623144
--- /dev/null
+++ b/src/com/android/settings/development/gup/GupPreferenceController.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.development.gup;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.provider.Settings;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceGroup;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.development.DevelopmentSettingsEnabler;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class GupPreferenceController
+        extends BasePreferenceController implements Preference.OnPreferenceChangeListener {
+    private final CharSequence[] mEntryList;
+    private final String mPreferenceTitle;
+    private final String mPreferenceDefault;
+    private final String mPreferenceGup;
+    private final String mPreferenceNative;
+
+    private final List<AppInfo> mAppInfos;
+    private final Set<String> mDevOptInApps;
+    private final Set<String> mDevOptOutApps;
+
+    public GupPreferenceController(Context context, String key) {
+        super(context, key);
+
+        final Resources resources = context.getResources();
+        mEntryList = resources.getStringArray(R.array.gup_app_preference_values);
+        mPreferenceTitle = resources.getString(R.string.gup_app_preference_title);
+        mPreferenceDefault = resources.getString(R.string.gup_app_preference_default);
+        mPreferenceGup = resources.getString(R.string.gup_app_preference_gup);
+        mPreferenceNative = resources.getString(R.string.gup_app_preference_native);
+
+        // TODO: Move this task to background if there's potential ANR/Jank.
+        // Update the UI when all the app infos are ready.
+        mAppInfos = getAppInfos(context);
+
+        final ContentResolver contentResolver = context.getContentResolver();
+        mDevOptInApps =
+                getGlobalSettingsString(contentResolver, Settings.Global.GUP_DEV_OPT_IN_APPS);
+        mDevOptOutApps =
+                getGlobalSettingsString(contentResolver, Settings.Global.GUP_DEV_OPT_OUT_APPS);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)
+                ? AVAILABLE
+                : DISABLED_DEPENDENT_SETTING;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        final PreferenceGroup preferenceGroup =
+                (PreferenceGroup) screen.findPreference(getPreferenceKey());
+        if (preferenceGroup == null) {
+            return;
+        }
+
+        for (AppInfo appInfo : mAppInfos) {
+            preferenceGroup.addPreference(
+                    createListPreference(appInfo.info.packageName, appInfo.label));
+        }
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        final ListPreference listPref = (ListPreference) preference;
+        final String value = newValue.toString();
+        final String packageName = preference.getKey();
+
+        // When user choose a new preference, update both Sets for
+        // opt-in and opt-out apps. Then set the new summary text.
+        if (value.equals(mPreferenceNative)) {
+            mDevOptInApps.remove(packageName);
+            mDevOptOutApps.add(packageName);
+            listPref.setSummary(mPreferenceNative);
+        } else if (value.equals(mPreferenceGup)) {
+            mDevOptInApps.add(packageName);
+            mDevOptOutApps.remove(packageName);
+            listPref.setSummary(mPreferenceGup);
+        } else {
+            mDevOptInApps.remove(packageName);
+            mDevOptOutApps.remove(packageName);
+            listPref.setSummary(mPreferenceDefault);
+        }
+
+        // Push the updated Sets for opt-in and opt-out apps to
+        // corresponding Settings.Global.GUP_DEV_OPT_(IN|OUT)_APPS
+        Settings.Global.putString(mContext.getContentResolver(),
+                Settings.Global.GUP_DEV_OPT_IN_APPS, String.join(",", mDevOptInApps));
+        Settings.Global.putString(mContext.getContentResolver(),
+                Settings.Global.GUP_DEV_OPT_OUT_APPS, String.join(",", mDevOptOutApps));
+
+        return true;
+    }
+
+    // AppInfo class to achieve loading the application label only once
+    class AppInfo {
+        AppInfo(PackageManager packageManager, ApplicationInfo applicationInfo) {
+            info = applicationInfo;
+            label = packageManager.getApplicationLabel(applicationInfo).toString();
+        }
+        final ApplicationInfo info;
+        final String label;
+    }
+
+    // List of non-system packages that are installed for the current user.
+    private List<AppInfo> getAppInfos(Context context) {
+        final PackageManager packageManager = context.getPackageManager();
+        final List<ApplicationInfo> applicationInfos =
+                packageManager.getInstalledApplications(0 /* flags */);
+
+        final List<AppInfo> appInfos = new ArrayList<>();
+        for (ApplicationInfo applicationInfo : applicationInfos) {
+            if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+                appInfos.add(new AppInfo(packageManager, applicationInfo));
+            }
+        }
+
+        Collections.sort(appInfos, appInfoComparator);
+
+        return appInfos;
+    }
+
+    // Parse the raw comma separated package names into a String Set
+    private Set<String> getGlobalSettingsString(ContentResolver contentResolver, String name) {
+        final String settingsValue = Settings.Global.getString(contentResolver, name);
+        if (settingsValue == null) {
+            return new HashSet<>();
+        }
+
+        final Set<String> valueSet = new HashSet<>(Arrays.asList(settingsValue.split(",")));
+        valueSet.remove("");
+
+        return valueSet;
+    }
+
+    private final Comparator<AppInfo> appInfoComparator = new Comparator<AppInfo>() {
+        public final int compare(AppInfo a, AppInfo b) {
+            return Collator.getInstance().compare(a.label, b.label);
+        }
+    };
+
+    @VisibleForTesting
+    protected ListPreference createListPreference(String packageName, String appName) {
+        final ListPreference listPreference = new ListPreference(mContext);
+
+        listPreference.setKey(packageName);
+        listPreference.setTitle(appName);
+        listPreference.setDialogTitle(mPreferenceTitle);
+        listPreference.setEntries(mEntryList);
+        listPreference.setEntryValues(mEntryList);
+
+        // Initialize preference default and summary with the opt in/out choices
+        // from Settings.Global.GUP_DEV_OPT_(IN|OUT)_APPS
+        if (mDevOptOutApps.contains(packageName)) {
+            listPreference.setValue(mPreferenceNative);
+            listPreference.setSummary(mPreferenceNative);
+        } else if (mDevOptInApps.contains(packageName)) {
+            listPreference.setValue(mPreferenceGup);
+            listPreference.setSummary(mPreferenceGup);
+        } else {
+            listPreference.setValue(mPreferenceDefault);
+            listPreference.setSummary(mPreferenceDefault);
+        }
+
+        listPreference.setOnPreferenceChangeListener(this);
+
+        return listPreference;
+    }
+}
diff --git a/src/com/android/settings/display/TimeoutListPreference.java b/src/com/android/settings/display/TimeoutListPreference.java
index f9a731d..5ed427f 100644
--- a/src/com/android/settings/display/TimeoutListPreference.java
+++ b/src/com/android/settings/display/TimeoutListPreference.java
@@ -26,6 +26,7 @@
 import android.util.Log;
 import android.view.View;
 
+import androidx.annotation.VisibleForTesting;
 import androidx.appcompat.app.AlertDialog.Builder;
 
 import com.android.settings.R;
@@ -33,18 +34,18 @@
 import com.android.settingslib.RestrictedLockUtils;
 
 import java.util.ArrayList;
+import java.util.List;
 
 
 public class TimeoutListPreference extends RestrictedListPreference {
     private static final String TAG = "TimeoutListPreference";
     private EnforcedAdmin mAdmin;
-    private final CharSequence[] mInitialEntries;
-    private final CharSequence[] mInitialValues;
+    private CharSequence[] mInitialEntries;
+    private CharSequence[] mInitialValues;
 
     public TimeoutListPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
-        mInitialEntries = getEntries();
-        mInitialValues = getEntryValues();
+        updateInitialValues();
     }
 
     @Override
@@ -65,13 +66,8 @@
         if (mAdmin != null) {
             View footerView = dialog.findViewById(R.id.admin_disabled_other_options);
             footerView.findViewById(R.id.admin_more_details_link).setOnClickListener(
-                    new View.OnClickListener() {
-                        @Override
-                        public void onClick(View view) {
-                            RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
-                                    getContext(), mAdmin);
-                        }
-                    });
+                    view -> RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
+                            getContext(), mAdmin));
         }
     }
 
@@ -89,8 +85,8 @@
             maxTimeout = Long.MAX_VALUE;
         }
 
-        ArrayList<CharSequence> revisedEntries = new ArrayList<CharSequence>();
-        ArrayList<CharSequence> revisedValues = new ArrayList<CharSequence>();
+        final ArrayList<CharSequence> revisedEntries = new ArrayList<>();
+        final ArrayList<CharSequence> revisedValues = new ArrayList<>();
         for (int i = 0; i < mInitialValues.length; ++i) {
             long timeout = Long.parseLong(mInitialValues[i].toString());
             if (timeout <= maxTimeout) {
@@ -101,7 +97,7 @@
 
         // If there are no possible options for the user, then set this preference as disabled
         // by admin, otherwise remove the padlock in case it was set earlier.
-        if (revisedValues.size() == 0) {
+        if (revisedValues.isEmpty()) {
             setDisabledByAdmin(admin);
             return;
         } else {
@@ -117,7 +113,7 @@
                 setValue(String.valueOf(userPreference));
             } else if (revisedValues.size() > 0
                     && Long.parseLong(revisedValues.get(revisedValues.size() - 1).toString())
-                            == maxTimeout) {
+                    == maxTimeout) {
                 // If the last one happens to be the same as the max timeout, select that
                 setValue(String.valueOf(maxTimeout));
             } else {
@@ -128,4 +124,36 @@
             }
         }
     }
+
+    @VisibleForTesting
+    void updateInitialValues() {
+        // Read default list of candidate values.
+        final CharSequence[] entries = getEntries();
+        final CharSequence[] values = getEntryValues();
+        // Filter out values based on config
+        final List<CharSequence> revisedEntries = new ArrayList<>();
+        final List<CharSequence> revisedValues = new ArrayList<>();
+        final long maxTimeout = getContext().getResources().getInteger(
+                R.integer.max_lock_after_timeout_ms);
+        if (entries == null || values == null) {
+            return;
+        }
+        Log.d(TAG, "max timeout: " + maxTimeout);
+        for (int i = 0; i < values.length; ++i) {
+            long timeout = Long.parseLong(values[i].toString());
+            if (timeout <= maxTimeout) {
+                Log.d(TAG, "keeping timeout: " + values[i]);
+                revisedEntries.add(entries[i]);
+                revisedValues.add(values[i]);
+            } else {
+                Log.d(TAG, "Dropping timeout: " + values[i]);
+            }
+        }
+
+        // Store final candidates in initial value lists.
+        mInitialEntries = revisedEntries.toArray(new CharSequence[0]);
+        setEntries(mInitialEntries);
+        mInitialValues = revisedValues.toArray(new CharSequence[0]);
+        setEntryValues(mInitialValues);
+    }
 }
diff --git a/src/com/android/settings/display/TimeoutPreferenceController.java b/src/com/android/settings/display/TimeoutPreferenceController.java
index 60b7e24..c1c5069 100644
--- a/src/com/android/settings/display/TimeoutPreferenceController.java
+++ b/src/com/android/settings/display/TimeoutPreferenceController.java
@@ -13,8 +13,6 @@
  */
 package com.android.settings.display;
 
-import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
-
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.os.UserHandle;
@@ -60,7 +58,7 @@
     public void updateState(Preference preference) {
         final TimeoutListPreference timeoutListPreference = (TimeoutListPreference) preference;
         final long currentTimeout = Settings.System.getLong(mContext.getContentResolver(),
-                SCREEN_OFF_TIMEOUT, FALLBACK_SCREEN_TIMEOUT_VALUE);
+                Settings.System.SCREEN_OFF_TIMEOUT, FALLBACK_SCREEN_TIMEOUT_VALUE);
         timeoutListPreference.setValue(String.valueOf(currentTimeout));
         final DevicePolicyManager dpm =
                 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
@@ -86,7 +84,8 @@
     public boolean onPreferenceChange(Preference preference, Object newValue) {
         try {
             int value = Integer.parseInt((String) newValue);
-            Settings.System.putInt(mContext.getContentResolver(), SCREEN_OFF_TIMEOUT, value);
+            Settings.System.putInt(mContext.getContentResolver(),
+                    Settings.System.SCREEN_OFF_TIMEOUT, value);
             updateTimeoutPreferenceDescription((TimeoutListPreference) preference, value);
         } catch (NumberFormatException e) {
             Log.e(TAG, "could not persist screen timeout setting", e);
@@ -94,7 +93,7 @@
         return true;
     }
 
-    public static CharSequence getTimeoutDescription(
+    private static CharSequence getTimeoutDescription(
             long currentTimeout, CharSequence[] entries, CharSequence[] values) {
         if (currentTimeout < 0 || entries == null || values == null
                 || values.length != entries.length) {
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/BatterySaverConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/BatterySaverConditionController.java
new file mode 100644
index 0000000..bce7c5d
--- /dev/null
+++ b/src/com/android/settings/homepage/contextualcards/conditional/BatterySaverConditionController.java
@@ -0,0 +1,108 @@
+/*
+ * 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.contextualcards.conditional;
+
+import android.content.Context;
+import android.os.PowerManager;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.fuelgauge.BatterySaverReceiver;
+import com.android.settings.fuelgauge.batterysaver.BatterySaverSettings;
+import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settingslib.fuelgauge.BatterySaverUtils;
+
+import java.util.Objects;
+
+public class BatterySaverConditionController implements ConditionalCardController,
+        BatterySaverReceiver.BatterySaverListener {
+    static final int ID = Objects.hash("BatterySaverConditionController");
+
+    private final Context mAppContext;
+    private final ConditionManager mConditionManager;
+    private final BatterySaverReceiver mReceiver;
+    private final PowerManager mPowerManager;
+
+    public BatterySaverConditionController(Context appContext, ConditionManager conditionManager) {
+        mAppContext = appContext;
+        mConditionManager = conditionManager;
+        mPowerManager = appContext.getSystemService(PowerManager.class);
+        mReceiver = new BatterySaverReceiver(appContext);
+        mReceiver.setBatterySaverListener(this);
+    }
+
+    @Override
+    public long getId() {
+        return ID;
+    }
+
+    @Override
+    public boolean isDisplayable() {
+        return mPowerManager.isPowerSaveMode();
+    }
+
+    @Override
+    public void onPrimaryClick(Context context) {
+        new SubSettingLauncher(context)
+                .setDestination(BatterySaverSettings.class.getName())
+                .setSourceMetricsCategory(MetricsProto.MetricsEvent.DASHBOARD_SUMMARY)
+                .setTitleRes(R.string.battery_saver)
+                .launch();
+    }
+
+    @Override
+    public void onActionClick() {
+        BatterySaverUtils.setPowerSaveMode(mAppContext, false,
+                /*needFirstTimeWarning*/ false);
+    }
+
+    @Override
+    public ContextualCard buildContextualCard() {
+        return new ConditionalContextualCard.Builder()
+                .setConditionId(ID)
+                .setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_BATTERY_SAVER)
+                .setActionText(mAppContext.getText(R.string.condition_turn_off))
+                .setName(mAppContext.getPackageName() + "/"
+                        + mAppContext.getText(R.string.condition_battery_title))
+                .setTitleText(mAppContext.getText(R.string.condition_battery_title).toString())
+                .setSummaryText(mAppContext.getText(R.string.condition_battery_summary).toString())
+                .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_battery_saver_accent_24dp))
+                .setIsHalfWidth(true)
+                .build();
+    }
+
+    @Override
+    public void startMonitoringStateChange() {
+        mReceiver.setListening(true);
+    }
+
+    @Override
+    public void stopMonitoringStateChange() {
+        mReceiver.setListening(false);
+    }
+
+    @Override
+    public void onPowerSaveModeChanged() {
+        mConditionManager.onConditionChanged();
+    }
+
+    @Override
+    public void onBatteryChanged(boolean pluggedIn) {
+
+    }
+}
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/ConditionManager.java b/src/com/android/settings/homepage/contextualcards/conditional/ConditionManager.java
index 39f4903..c741b98 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/ConditionManager.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/ConditionManager.java
@@ -154,6 +154,7 @@
         mCardControllers.add(new AirplaneModeConditionController(mAppContext, this /* manager */));
         mCardControllers.add(
                 new BackgroundDataConditionController(mAppContext, this /* manager */));
+        mCardControllers.add(new BatterySaverConditionController(mAppContext, this /* manager */));
         mCardControllers.add(new CellularDataConditionController(mAppContext, this /* manager */));
         mCardControllers.add(new DndConditionCardController(mAppContext, this /* manager */));
         mCardControllers.add(new HotspotConditionController(mAppContext, this /* manager */));
diff --git a/src/com/android/settings/homepage/contextualcards/deviceinfo/BatterySlice.java b/src/com/android/settings/homepage/contextualcards/deviceinfo/BatteryInfoSlice.java
similarity index 96%
rename from src/com/android/settings/homepage/contextualcards/deviceinfo/BatterySlice.java
rename to src/com/android/settings/homepage/contextualcards/deviceinfo/BatteryInfoSlice.java
index 5271e12..41095a4 100644
--- a/src/com/android/settings/homepage/contextualcards/deviceinfo/BatterySlice.java
+++ b/src/com/android/settings/homepage/contextualcards/deviceinfo/BatteryInfoSlice.java
@@ -42,15 +42,15 @@
 /**
  * Utility class to build a Battery Slice, and handle all associated actions.
  */
-public class BatterySlice implements CustomSliceable {
-    private static final String TAG = "BatterySlice";
+public class BatteryInfoSlice implements CustomSliceable {
+    private static final String TAG = "BatteryInfoSlice";
 
     private final Context mContext;
 
     private BatteryInfo mBatteryInfo;
     private boolean mIsBatteryInfoLoading;
 
-    public BatterySlice(Context context) {
+    public BatteryInfoSlice(Context context) {
         mContext = context;
     }
 
diff --git a/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSlice.java b/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSlice.java
index 531501b..c0cfb3f 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSlice.java
@@ -25,7 +25,6 @@
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.net.Uri;
-import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
 import androidx.annotation.WorkerThread;
@@ -49,6 +48,7 @@
 import com.android.settings.slices.SliceBuilderUtils;
 import com.android.settingslib.utils.ThreadUtils;
 
+import java.util.Arrays;
 import java.util.List;
 
 public class BatteryFixSlice implements CustomSliceable {
@@ -58,6 +58,11 @@
     @VisibleForTesting
     static final String KEY_CURRENT_TIPS_TYPE = "current_tip_type";
 
+    private static final List<Integer> UNIMPORTANT_BATTERY_TIPS = Arrays.asList(
+            BatteryTip.TipType.SUMMARY,
+            BatteryTip.TipType.BATTERY_SAVER
+    );
+
     private static final String TAG = "BatteryFixSlice";
 
     private final Context mContext;
@@ -78,7 +83,7 @@
                         .setAccentColor(-1);
 
         // TipType.SUMMARY is battery good
-        if (readBatteryTipAvailabilityCache(mContext) == BatteryTip.TipType.SUMMARY) {
+        if (UNIMPORTANT_BATTERY_TIPS.contains(readBatteryTipAvailabilityCache(mContext))) {
             return buildBatteryGoodSlice(sliceBuilder, true);
         }
 
@@ -91,19 +96,21 @@
         }
 
         for (BatteryTip batteryTip : batteryTips) {
-            if (batteryTip.getState() != BatteryTip.StateType.INVISIBLE) {
-                final IconCompat icon = IconCompat.createWithResource(mContext, batteryTip.getIconId());
-                final SliceAction primaryAction = SliceAction.createDeeplink(getPrimaryAction(),
-                        icon,
-                        ListBuilder.ICON_IMAGE,
-                        batteryTip.getTitle(mContext));
-                sliceBuilder.addRow(new RowBuilder()
-                        .setTitleItem(icon, ListBuilder.ICON_IMAGE)
-                        .setTitle(batteryTip.getTitle(mContext))
-                        .setSubtitle(batteryTip.getSummary(mContext))
-                        .setPrimaryAction(primaryAction));
-                break;
+            if (batteryTip.getState() == BatteryTip.StateType.INVISIBLE) {
+                continue;
             }
+            final IconCompat icon = IconCompat.createWithResource(mContext,
+                    batteryTip.getIconId());
+            final SliceAction primaryAction = SliceAction.createDeeplink(getPrimaryAction(),
+                    icon,
+                    ListBuilder.ICON_IMAGE,
+                    batteryTip.getTitle(mContext));
+            sliceBuilder.addRow(new RowBuilder()
+                    .setTitleItem(icon, ListBuilder.ICON_IMAGE)
+                    .setTitle(batteryTip.getTitle(mContext))
+                    .setSubtitle(batteryTip.getSummary(mContext))
+                    .setPrimaryAction(primaryAction));
+            break;
         }
         return sliceBuilder.build();
     }
diff --git a/src/com/android/settings/network/NetworkDashboardFragment.java b/src/com/android/settings/network/NetworkDashboardFragment.java
index 7d94bba..c2b4a2b 100644
--- a/src/com/android/settings/network/NetworkDashboardFragment.java
+++ b/src/com/android/settings/network/NetworkDashboardFragment.java
@@ -21,7 +21,6 @@
 import android.app.Dialog;
 import android.content.Context;
 import android.provider.SearchIndexableResource;
-import android.util.FeatureFlagUtils;
 import android.util.Log;
 
 import androidx.appcompat.app.AlertDialog;
@@ -31,6 +30,7 @@
 import com.android.settings.R;
 import com.android.settings.core.FeatureFlags;
 import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.development.featureflags.FeatureFlagPersistent;
 import com.android.settings.network.MobilePlanPreferenceController.MobilePlanPreferenceHost;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.wifi.WifiMasterSwitchPreferenceController;
@@ -61,7 +61,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.NETWORK_INTERNET_V2)) {
+        if (FeatureFlagPersistent.isEnabled(getContext(), FeatureFlags.NETWORK_INTERNET_V2)) {
             return R.xml.network_and_internet_v2;
         } else {
             return R.xml.network_and_internet;
@@ -72,7 +72,7 @@
     public void onAttach(Context context) {
         super.onAttach(context);
 
-        if (FeatureFlagUtils.isEnabled(context, FeatureFlags.NETWORK_INTERNET_V2)) {
+        if (FeatureFlagPersistent.isEnabled(context, FeatureFlags.NETWORK_INTERNET_V2)) {
             use(MultiNetworkHeaderController.class).init(getSettingsLifecycle());
         }
         use(AirplaneModePreferenceController.class).setFragment(this);
diff --git a/src/com/android/settings/slices/CustomSliceManager.java b/src/com/android/settings/slices/CustomSliceManager.java
index bb47df2..24ee680 100644
--- a/src/com/android/settings/slices/CustomSliceManager.java
+++ b/src/com/android/settings/slices/CustomSliceManager.java
@@ -23,7 +23,7 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.settings.flashlight.FlashlightSlice;
-import com.android.settings.homepage.contextualcards.deviceinfo.BatterySlice;
+import com.android.settings.homepage.contextualcards.deviceinfo.BatteryInfoSlice;
 import com.android.settings.homepage.contextualcards.deviceinfo.DataUsageSlice;
 import com.android.settings.homepage.contextualcards.deviceinfo.DeviceInfoSlice;
 import com.android.settings.homepage.contextualcards.deviceinfo.EmergencyInfoSlice;
@@ -106,7 +106,7 @@
 
     private void addSlices() {
         mUriMap.put(CustomSliceRegistry.BATTERY_FIX_SLICE_URI, BatteryFixSlice.class);
-        mUriMap.put(CustomSliceRegistry.BATTERY_INFO_SLICE_URI, BatterySlice.class);
+        mUriMap.put(CustomSliceRegistry.BATTERY_INFO_SLICE_URI, BatteryInfoSlice.class);
         mUriMap.put(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI, BluetoothDevicesSlice.class);
         mUriMap.put(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI, ContextualWifiSlice.class);
         mUriMap.put(CustomSliceRegistry.DATA_USAGE_SLICE_URI, DataUsageSlice.class);
diff --git a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
index 7a1bdb4..06e36e5 100644
--- a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
+++ b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
@@ -16,7 +16,6 @@
 
 package com.android.settings.wifi;
 
-import android.app.Activity;
 import android.app.Dialog;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -67,9 +66,15 @@
     /** Message sent to us to stop scanning wifi and pop up timeout dialog. */
     private static final int MESSAGE_STOP_SCAN_WIFI_LIST = 0;
 
+    /** Message sent to us to finish activity. */
+    private static final int MESSAGE_FINISH_ACTIVITY = 1;
+
     /** Spec defines there should be 5 wifi ap on the list at most. */
     private static final int MAX_NUMBER_LIST_ITEM = 5;
 
+    /** Holding time to let user be aware that selected wifi ap is connected */
+    private static final int DELAY_TIME_USER_AWARE_CONNECTED_MS = 1 * 1000;
+
     /** Delayed time to stop scanning wifi. */
     private static final int DELAY_TIME_STOP_SCAN_MS = 30 * 1000;
 
@@ -155,7 +160,9 @@
     public void onCancel(@NonNull DialogInterface dialog) {
         super.onCancel(dialog);
         // Finishes the activity when user clicks back key or outside of the dialog.
-        getActivity().finish();
+        if (getActivity() != null) {
+            getActivity().finish();
+        }
     }
 
     @Override
@@ -177,6 +184,8 @@
     @Override
     public void onDestroy() {
         super.onDestroy();
+
+        mHandler.removeMessages(MESSAGE_FINISH_ACTIVITY);
         if (mFilterWifiTracker != null) {
             mFilterWifiTracker.onDestroy();
             mFilterWifiTracker = null;
@@ -207,7 +216,10 @@
             switch (msg.what) {
                 case MESSAGE_STOP_SCAN_WIFI_LIST:
                     removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST);
-                    stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE.TIME_OUT);
+                    stopScanningAndMaybePopErrorDialog(ERROR_DIALOG_TYPE.TIME_OUT);
+                    break;
+                case MESSAGE_FINISH_ACTIVITY:
+                    stopScanningAndMaybePopErrorDialog(/* ERROR_DIALOG_TYPE */ null);
                     break;
                 default:
                     // Do nothing.
@@ -216,18 +228,29 @@
         }
     };
 
-    protected void stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE type) {
+    protected void stopScanningAndMaybePopErrorDialog(ERROR_DIALOG_TYPE type) {
         // Dismisses current dialog.
-        dismiss();
+        final Dialog dialog =  getDialog();
+        if (dialog != null && dialog.isShowing()) {
+            dismiss();
+        }
 
-        // Throws new timeout dialog.
-        final NetworkRequestErrorDialogFragment fragment = NetworkRequestErrorDialogFragment
-                .newInstance();
-        final Bundle bundle = new Bundle();
-        bundle.putSerializable(NetworkRequestErrorDialogFragment.DIALOG_TYPE, type);
-        fragment.setArguments(bundle);
-        fragment.show(getActivity().getSupportFragmentManager(),
-                NetworkRequestDialogFragment.class.getSimpleName());
+        if (type  == null) {
+            // If no error, finishes activity.
+            if (getActivity() != null) {
+                getActivity().finish();
+            }
+        } else {
+            // Throws error dialog.
+            final NetworkRequestErrorDialogFragment fragment = NetworkRequestErrorDialogFragment
+                    .newInstance();
+            final Bundle bundle = new Bundle();
+            bundle.putSerializable(NetworkRequestErrorDialogFragment.DIALOG_TYPE, type);
+            fragment.setArguments(bundle);
+            fragment.show(getActivity().getSupportFragmentManager(),
+                    NetworkRequestDialogFragment.class.getSimpleName());
+        }
+
     }
 
     @Override
@@ -284,7 +307,7 @@
 
     @Override
     public void onAbort() {
-        stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE.ABORT);
+        stopScanningAndMaybePopErrorDialog(ERROR_DIALOG_TYPE.ABORT);
     }
 
     @Override
@@ -295,10 +318,13 @@
 
     @Override
     public void onMatch(List<ScanResult> scanResults) {
-        mHandler.removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST);
-        renewAccessPointList(scanResults);
+        // Shouldn't need to renew cached list, since input result is empty.
+        if (scanResults != null && scanResults.size() > 0) {
+            mHandler.removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST);
+            renewAccessPointList(scanResults);
 
-        notifyAdapterRefresh();
+            notifyAdapterRefresh();
+        }
     }
 
     // Updates internal AccessPoint list from WifiTracker. scanResults are used to update key list
@@ -329,17 +355,24 @@
 
     @Override
     public void onUserSelectionConnectSuccess(WifiConfiguration wificonfiguration) {
-        // Dismisses current dialog and finishes Activity, since connection is success.
-        dismiss();
-        final Activity activity = getActivity();
-        if (activity != null) {
-            activity.finish();
+        // Removes the progress icon.
+        final Dialog dialog = getDialog();
+        if (dialog != null) {
+            final View view = dialog.findViewById(R.id.network_request_title_progress);
+            if (view != null) {
+                view.setVisibility(View.GONE);
+            }
         }
+
+        // Posts delay to finish self since connection is success.
+        mHandler.removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST);
+        mHandler.sendEmptyMessageDelayed(MESSAGE_FINISH_ACTIVITY,
+                DELAY_TIME_USER_AWARE_CONNECTED_MS);
     }
 
     @Override
     public void onUserSelectionConnectFailure(WifiConfiguration wificonfiguration) {
-        stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE.ABORT);
+        stopScanningAndMaybePopErrorDialog(ERROR_DIALOG_TYPE.ABORT);
     }
 
     private final class FilterWifiTracker {
diff --git a/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java b/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java
index 12814f8..9264ad9 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java
@@ -18,14 +18,16 @@
 
 import android.app.ActionBar;
 import android.app.Activity;
+import android.content.Context;
+import android.net.wifi.WifiManager;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.ProgressBar;
-import android.widget.TextView;
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
@@ -35,11 +37,42 @@
  * to the Wi-Fi network.
  */
 public class WifiDppAddDeviceFragment extends WifiDppQrCodeBaseFragment {
+    private static final String TAG = "WifiDppAddDeviceFragment";
+
     private ImageView mWifiApPictureView;
-    private TextView mChooseDifferentNetwork;
+    private Button mChooseDifferentNetwork;
     private Button mButtonLeft;
     private Button mButtonRight;
 
+    private class DppStatusCallback extends android.net.wifi.DppStatusCallback {
+        @Override
+        public void onEnrolleeSuccess(int newNetworkId) {
+            // Do nothing
+        }
+
+        @Override
+        public void onConfiguratorSuccess(int code) {
+            // Update success UI.
+            mTitle.setText(R.string.wifi_dpp_wifi_shared_with_device);
+            mSummary.setVisibility(View.INVISIBLE);
+            mButtonLeft.setText(R.string.wifi_dpp_add_another_device);
+            mButtonLeft.setOnClickListener(v -> getFragmentManager().popBackStack());
+            mButtonRight.setText(R.string.done);
+            mButtonRight.setOnClickListener(v -> getActivity().finish());
+        }
+
+        @Override
+        public void onFailure(int code) {
+            //TODO(b/122429170): Show DPP configuration error state UI
+            Log.d(TAG, "DppStatusCallback.onFailure " + code);
+        }
+
+        @Override
+        public void onProgress(int code) {
+            // Do nothing
+        }
+    }
+
     @Override
     public int getMetricsCategory() {
         return MetricsProto.MetricsEvent.SETTINGS_WIFI_DPP_CONFIGURATOR;
@@ -75,10 +108,16 @@
                 wifiNetworkConfig.getSsid()));
 
         mWifiApPictureView = view.findViewById(R.id.wifi_ap_picture_view);
+
         mChooseDifferentNetwork = view.findViewById(R.id.choose_different_network);
+        mChooseDifferentNetwork.setOnClickListener(v -> getFragmentManager().popBackStack());
+
         mButtonLeft = view.findViewById(R.id.button_left);
         mButtonLeft.setText(R.string.cancel);
-        mButtonLeft.setOnClickListener(v -> getFragmentManager().popBackStack());
+        mButtonLeft.setOnClickListener(v -> {
+            getActivity().setResult(Activity.RESULT_CANCELED);
+            getActivity().finish();
+        });
 
         mButtonRight = view.findViewById(R.id.button_right);
         mButtonRight.setText(R.string.wifi_dpp_share_wifi);
@@ -86,6 +125,11 @@
     }
 
     private void startWifiDppInitiator() {
-        //TODO(b/122331217): starts Wi-Fi DPP initiator handshake here
+        final String enrolleeUri = ((WifiDppConfiguratorActivity) getActivity()).getDppUri();
+        final int networkId =
+                ((WifiDppConfiguratorActivity) getActivity()).getWifiNetworkConfig().getNetworkId();
+        final WifiManager wifiManager = getContext().getSystemService(WifiManager.class);
+        wifiManager.startDppAsConfiguratorInitiator(enrolleeUri, networkId,
+                WifiManager.DPP_NETWORK_ROLE_STA, /* handler */ null, new DppStatusCallback());
     }
 }
diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
index 9c65d10..b08546c 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
@@ -66,11 +66,8 @@
     /** The Wi-Fi network which will be configured */
     private WifiNetworkConfig mWifiNetworkConfig;
 
-    /** The public key from Wi-Fi DPP QR code */
-    private String mPublicKey;
-
-    /** The information from Wi-Fi DPP QR code */
-    private String mInformation;
+    /** The uri from Wi-Fi DPP QR code */
+    private String mDppUri;
 
     /** The Wi-Fi DPP QR code from intent ACTION_PROCESS_WIFI_DPP_QR_CODE */
     private WifiQrCode mWifiDppQrCode;
@@ -228,12 +225,8 @@
         return mWifiNetworkConfig;
     }
 
-    public String getPublicKey() {
-        return mPublicKey;
-    }
-
-    public String getInformation() {
-        return mInformation;
+    public String getDppUri() {
+        return mDppUri;
     }
 
     public WifiQrCode getWifiDppQrCode() {
@@ -270,17 +263,15 @@
     }
 
     @Override
-    public void onScanWifiDppSuccess(String publicKey, String information) {
-        mPublicKey = publicKey;
-        mInformation = information;
+    public void onScanWifiDppSuccess(String uri) {
+        mDppUri = uri;
 
         showAddDeviceFragment(/* addToBackStack */ true);
     }
 
     @Override
     public void onScanZxingWifiFormatSuccess(WifiNetworkConfig wifiNetworkConfig) {
-        mPublicKey = null;
-        mInformation = null;
+        mDppUri = null;
         mWifiNetworkConfig = new WifiNetworkConfig(wifiNetworkConfig);
 
         showAddDeviceFragment(/* addToBackStack */ true);
diff --git a/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java b/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java
index 584a819..8c0e1f0 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.wifi.dpp;
 
+import android.content.Context;
+import android.net.wifi.WifiConfiguration;
 import android.provider.Settings;
 import android.app.ActionBar;
 import android.app.Activity;
@@ -32,6 +34,8 @@
 import com.android.settings.core.InstrumentedActivity;
 import com.android.settings.R;
 
+import java.util.List;
+
 /**
  * To provision "this" device with specified Wi-Fi network.
  *
@@ -49,6 +53,39 @@
 
     private FragmentManager mFragmentManager;
 
+    private class DppStatusCallback extends android.net.wifi.DppStatusCallback {
+        @Override
+        public void onEnrolleeSuccess(int newNetworkId) {
+            // Connect to the new network.
+            final WifiManager wifiManager = getSystemService(WifiManager.class);
+            final List<WifiConfiguration> wifiConfigs = wifiManager.getPrivilegedConfiguredNetworks();
+            for (WifiConfiguration wifiConfig : wifiConfigs) {
+                if (wifiConfig.networkId == newNetworkId) {
+                    wifiManager.connect(wifiConfig, WifiDppEnrolleeActivity.this);
+                    return;
+                }
+            }
+            Log.e(TAG, "Invalid networkId " + newNetworkId);
+            WifiDppEnrolleeActivity.this.onFailure(WifiManager.ERROR_AUTHENTICATING);
+        }
+
+        @Override
+        public void onConfiguratorSuccess(int code) {
+            // Do nothing
+        }
+
+        @Override
+        public void onFailure(int code) {
+            //TODO(b/122429170): Show DPP enrollee error state UI
+            Log.d(TAG, "DppStatusCallback.onFailure " + code);
+        }
+
+        @Override
+        public void onProgress(int code) {
+            // Do nothing
+        }
+    }
+
     @Override
     public int getMetricsCategory() {
         return MetricsProto.MetricsEvent.SETTINGS_WIFI_DPP_ENROLLEE;
@@ -108,8 +145,9 @@
     }
 
     @Override
-    public void onScanWifiDppSuccess(String publicKey, String information) {
-        // TODO(b/1023597): starts DPP enrollee handshake here
+    public void onScanWifiDppSuccess(String uri) {
+        final WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
+        wifiManager.startDppAsEnrolleeInitiator(uri, /* handler */ null, new DppStatusCallback());
     }
 
     @Override
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
index c7c1461..45d753c 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
@@ -62,9 +62,9 @@
     private static final long SHOW_ERROR_MESSAGE_INTERVAL = 2000;
     private static final long SHOW_SUCCESS_SQUARE_INTERVAL = 1000;
 
-    // Keys for Bundle usage
-    private static final String KEY_PUBLIC_KEY = "key_public_key";
-    private static final String KEY_INFORMATION = "key_information";
+    // Key for Bundle usage
+    private static final String KEY_PUBLIC_URI = "key_public_uri";
+    private static final String KEY_IS_CONFIGURATOR_MODE = "key_is_configurator_mode";
 
     private QrCamera mCamera;
     private TextureView mTextureView;
@@ -72,7 +72,7 @@
     private TextView mErrorMessage;
 
     /** true if the fragment working for configurator, false enrollee*/
-    private final boolean mIsConfiguratorMode;
+    private boolean mIsConfiguratorMode;
 
     /** The SSID of the Wi-Fi network which the user specify to enroll */
     private String mSsid;
@@ -81,6 +81,15 @@
     private WifiQrCode mWifiQrCode;
 
     @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        if (savedInstanceState != null) {
+            mIsConfiguratorMode = savedInstanceState.getBoolean(KEY_IS_CONFIGURATOR_MODE);
+        }
+    }
+
+    @Override
     public int getMetricsCategory() {
         if (mIsConfiguratorMode) {
             return MetricsProto.MetricsEvent.SETTINGS_WIFI_DPP_CONFIGURATOR;
@@ -91,7 +100,7 @@
 
     // Container Activity must implement this interface
     public interface OnScanWifiDppSuccessListener {
-        public void onScanWifiDppSuccess(String publicKey, String information);
+        public void onScanWifiDppSuccess(String uri);
     }
     OnScanWifiDppSuccessListener mScanWifiDppSuccessListener;
 
@@ -269,7 +278,7 @@
     public void handleSuccessfulResult(String qrCode) {
         switch (mWifiQrCode.getScheme()) {
             case WifiQrCode.SCHEME_DPP:
-                handleWifiDpp(mWifiQrCode.getPublicKey(), mWifiQrCode.getInformation());
+                handleWifiDpp(qrCode);
                 break;
 
             case WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG:
@@ -281,13 +290,12 @@
         }
     }
 
-    private void handleWifiDpp(String publicKey, String information) {
+    private void handleWifiDpp(String uri) {
         destroyCamera();
         mDecorateView.setFocused(true);
 
         final Bundle bundle = new Bundle();
-        bundle.putString(KEY_PUBLIC_KEY, publicKey);
-        bundle.putString(KEY_INFORMATION, information);
+        bundle.putString(KEY_PUBLIC_URI, uri);
 
         Message message = mHandler.obtainMessage(MESSAGE_SCAN_WIFI_DPP_SUCCESS);
         message.setData(bundle);
@@ -352,10 +360,9 @@
                         return;
                     }
                     final Bundle bundle = msg.getData();
-                    final String publicKey = bundle.getString(KEY_PUBLIC_KEY);
-                    final String information = bundle.getString(KEY_INFORMATION);
+                    final String uri = bundle.getString(KEY_PUBLIC_URI);
 
-                    mScanWifiDppSuccessListener.onScanWifiDppSuccess(publicKey, information);
+                    mScanWifiDppSuccessListener.onScanWifiDppSuccess(uri);
                     break;
 
                 case MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS:
@@ -371,4 +378,11 @@
             }
         }
     };
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+       outState.putBoolean(KEY_IS_CONFIGURATOR_MODE, mIsConfiguratorMode);
+
+       super.onSaveInstanceState(outState);
+    }
 }
diff --git a/src/com/android/settings/wifi/dpp/WifiDppUtils.java b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
index 3a40e25..0205ec1 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppUtils.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
@@ -64,6 +64,9 @@
     /** The data corresponding to {@code WifiConfiguration} hiddenSSID */
     public static final String EXTRA_WIFI_HIDDEN_SSID = "hiddenSsid";
 
+    /** The data corresponding to {@code WifiConfiguration} networkId */
+    public static final String EXTRA_WIFI_NETWORK_ID = "networkId";
+
     /** @see WifiQrCode */
     public static final String EXTRA_QR_CODE = "qrCode";
 
@@ -164,6 +167,11 @@
         if (!TextUtils.isEmpty(preSharedKey)) {
             intent.putExtra(EXTRA_WIFI_PRE_SHARED_KEY, preSharedKey);
         }
+        if (wifiConfig.networkId == WifiConfiguration.INVALID_NETWORK_ID) {
+            throw new IllegalArgumentException("Invalid network ID");
+        } else {
+            intent.putExtra(EXTRA_WIFI_NETWORK_ID, wifiConfig.networkId);
+        }
 
         return intent;
     }
diff --git a/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java b/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java
index c9bfbd6..a9e88a9 100644
--- a/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java
+++ b/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java
@@ -46,13 +46,15 @@
     private String mSsid;
     private String mPreSharedKey;
     private boolean mHiddenSsid;
+    private int mNetworkId;
 
-    private WifiNetworkConfig(String security, String ssid, String preSharedKey,
-            boolean hiddenSsid) {
+    private WifiNetworkConfig(String security, String ssid, String preSharedKey, boolean hiddenSsid,
+            int networkId) {
         mSecurity = security;
         mSsid = ssid;
         mPreSharedKey = preSharedKey;
         mHiddenSsid = hiddenSsid;
+        mNetworkId = networkId;
     }
 
     public WifiNetworkConfig(WifiNetworkConfig config) {
@@ -60,6 +62,7 @@
         mSsid = config.mSsid;
         mPreSharedKey = config.mPreSharedKey;
         mHiddenSsid = config.mHiddenSsid;
+        mNetworkId = config.mNetworkId;
     }
 
     /**
@@ -82,17 +85,19 @@
         String ssid = intent.getStringExtra(WifiDppUtils.EXTRA_WIFI_SSID);
         String preSharedKey = intent.getStringExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY);
         boolean hiddenSsid = intent.getBooleanExtra(WifiDppUtils.EXTRA_WIFI_HIDDEN_SSID, false);
+        int networkId = intent.getIntExtra(WifiDppUtils.EXTRA_WIFI_NETWORK_ID,
+                WifiConfiguration.INVALID_NETWORK_ID);
 
-        return getValidConfigOrNull(security, ssid, preSharedKey, hiddenSsid);
+        return getValidConfigOrNull(security, ssid, preSharedKey, hiddenSsid, networkId);
     }
 
     public static WifiNetworkConfig getValidConfigOrNull(String security, String ssid,
-            String preSharedKey, boolean hiddenSsid) {
+            String preSharedKey, boolean hiddenSsid, int networkId) {
         if (!isValidConfig(security, ssid, preSharedKey, hiddenSsid)) {
             return null;
         }
 
-        return new WifiNetworkConfig(security, ssid, preSharedKey, hiddenSsid);
+        return new WifiNetworkConfig(security, ssid, preSharedKey, hiddenSsid, networkId);
     }
 
     public static boolean isValidConfig(WifiNetworkConfig config) {
@@ -184,6 +189,11 @@
         return mHiddenSsid;
     }
 
+    @Keep
+    public int getNetworkId() {
+        return mNetworkId;
+    }
+
     public void connect(Context context, WifiManager.ActionListener listener) {
         WifiConfiguration wifiConfiguration = getWifiConfigurationOrNull();
         if (wifiConfiguration == null) {
@@ -208,6 +218,7 @@
         final WifiConfiguration wifiConfiguration = new WifiConfiguration();
         wifiConfiguration.SSID = addQuotationIfNeeded(mSsid);
         wifiConfiguration.hiddenSSID = mHiddenSsid;
+        wifiConfiguration.networkId = mNetworkId;
 
         if (TextUtils.isEmpty(mSecurity) || SECURITY_NO_PASSWORD.equals(mSecurity)) {
             wifiConfiguration.allowedKeyManagement.set(KeyMgmt.NONE);
diff --git a/src/com/android/settings/wifi/dpp/WifiQrCode.java b/src/com/android/settings/wifi/dpp/WifiQrCode.java
index a8562bb..8eae3a4 100644
--- a/src/com/android/settings/wifi/dpp/WifiQrCode.java
+++ b/src/com/android/settings/wifi/dpp/WifiQrCode.java
@@ -17,6 +17,7 @@
 package com.android.settings.wifi.dpp;
 
 import android.content.Intent;
+import android.net.wifi.WifiConfiguration;
 import android.text.TextUtils;
 
 import androidx.annotation.Keep;
@@ -135,7 +136,7 @@
         password = removeBackSlash(password);
 
         mWifiNetworkConfig = WifiNetworkConfig.getValidConfigOrNull(security, ssid, password,
-                hiddenSsid);
+                hiddenSsid, WifiConfiguration.INVALID_NETWORK_ID);
 
         if (mWifiNetworkConfig == null) {
             throw new IllegalArgumentException("Invalid format");
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
index fb2ce97..c0a3fa7 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
@@ -53,10 +53,8 @@
         final WifiConfiguration config = mWifiManager.getWifiApConfiguration();
         if (config != null) {
             mSSID = config.SSID;
-            Log.d(TAG, "Updating SSID in Preference, " + mSSID);
         } else {
             mSSID = DEFAULT_SSID;
-            Log.d(TAG, "Updating to default SSID in Preference, " + mSSID);
         }
         ((ValidatedEditTextPreference) mPreference).setValidator(this);
         updateSsidDisplay((EditTextPreference) mPreference);
diff --git a/tests/robotests/Android.mk b/tests/robotests/Android.mk
index 01218cb..50133d9 100644
--- a/tests/robotests/Android.mk
+++ b/tests/robotests/Android.mk
@@ -25,6 +25,7 @@
 	$(SETTINGS_AOSP_PATH)/res
 
 LOCAL_STATIC_ANDROID_LIBRARIES := \
+    androidx-constraintlayout_constraintlayout \
     androidx.slice_slice-builders \
     androidx.slice_slice-core \
     androidx.slice_slice-view \
@@ -42,6 +43,7 @@
     ims-common
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
+    androidx-constraintlayout_constraintlayout-solver \
     androidx.lifecycle_lifecycle-runtime \
     androidx.lifecycle_lifecycle-extensions \
     guava \
diff --git a/tests/robotests/assets/grandfather_not_implementing_index_provider b/tests/robotests/assets/grandfather_not_implementing_index_provider
index 2622eb3..447de00 100644
--- a/tests/robotests/assets/grandfather_not_implementing_index_provider
+++ b/tests/robotests/assets/grandfather_not_implementing_index_provider
@@ -28,7 +28,6 @@
 com.android.settings.datausage.AppDataUsage
 com.android.settings.datausage.DataUsageList
 com.android.settings.datetime.timezone.TimeZoneSettings
-com.android.settings.development.gup.GupDashboard
 com.android.settings.deviceinfo.PrivateVolumeSettings
 com.android.settings.deviceinfo.PublicVolumeSettings
 com.android.settings.deviceinfo.StorageProfileFragment
diff --git a/tests/robotests/res/values-mcc999/config.xml b/tests/robotests/res/values-mcc999/config.xml
index 101a6b8..59028d3 100644
--- a/tests/robotests/res/values-mcc999/config.xml
+++ b/tests/robotests/res/values-mcc999/config.xml
@@ -88,4 +88,7 @@
 
     <!-- Email address for the homepage contextual cards feedback -->
     <string name="config_contextual_card_feedback_email" translatable="false">test@test.test</string>
+
+    <!-- Max allowed value for screen timeout, in milliseconds -->
+    <integer name="max_lock_after_timeout_ms">1700000</integer>
 </resources>
diff --git a/tests/robotests/src/com/android/settings/development/GameUpdatePackageDevOptInPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/GameUpdatePackageDevOptInPreferenceControllerTest.java
deleted file mode 100644
index 199cad6..0000000
--- a/tests/robotests/src/com/android/settings/development/GameUpdatePackageDevOptInPreferenceControllerTest.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import static com.android.settings.development.DevelopmentOptionsActivityRequestCodes.REQUEST_CODE_GUP_DEV_OPT_IN_APPS;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.provider.Settings;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.R;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class GameUpdatePackageDevOptInPreferenceControllerTest {
-
-    @Mock
-    private PreferenceScreen mPreferenceScreen;
-    @Mock
-    private DevelopmentSettingsDashboardFragment mFragment;
-
-    private Context mContext;
-    private Preference mPreference;
-    private GameUpdatePackageDevOptInPreferenceController mController;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
-        mController = spy(new GameUpdatePackageDevOptInPreferenceController(mContext, mFragment));
-        mPreference = new Preference(mContext);
-        mPreference.setKey(mController.getPreferenceKey());
-
-        when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
-            .thenReturn(mPreference);
-        mController.displayPreference(mPreferenceScreen);
-    }
-
-    @Test
-    public void handlePreferenceTreeClick_preferenceClicked_launchActivity() {
-        final Intent activityStartIntent = new Intent(mContext, AppPicker.class);
-        doReturn(activityStartIntent).when(mController).getActivityStartIntent();
-        mController.handlePreferenceTreeClick(mPreference);
-
-        verify(mFragment).startActivityForResult(activityStartIntent,
-                REQUEST_CODE_GUP_DEV_OPT_IN_APPS);
-    }
-
-    @Test
-    public void updateState_foobarAppSelected_shouldUpdateSummaryWithGUPDevOptInAppLabel() {
-        final String selectedApp = "foobar";
-        final ContentResolver contentResolver = mContext.getContentResolver();
-        Settings.Global.putString(contentResolver,
-                Settings.Global.GUP_DEV_OPT_IN_APPS, selectedApp);
-        mController.updateState(mPreference);
-
-        assertThat(mPreference.getSummary()).isEqualTo(
-                mContext.getString(R.string.gup_dev_opt_in_app_set, selectedApp));
-    }
-
-    @Test
-    public void updateState_noAppSelected_shouldUpdateSummaryWithNoAppSelected() {
-        final String selectedApp = null;
-        final ContentResolver contentResolver = mContext.getContentResolver();
-        Settings.Global.putString(contentResolver,
-                Settings.Global.GUP_DEV_OPT_IN_APPS, selectedApp);
-        mController.updateState(mPreference);
-
-        assertThat(mPreference.getSummary()).isEqualTo(
-                mContext.getString(R.string.gup_dev_opt_in_app_not_set));
-    }
-
-    @Test
-    public void onActivityResult_foobarAppSelected_shouldUpdateSummaryWithGUPDevOptInLabel() {
-        Intent activityResultIntent = new Intent(mContext, AppPicker.class);
-        final String appLabel = "foobar";
-        activityResultIntent.setAction(appLabel);
-        final boolean result = mController
-            .onActivityResult(REQUEST_CODE_GUP_DEV_OPT_IN_APPS, Activity.RESULT_OK,
-                    activityResultIntent);
-
-        assertThat(result).isTrue();
-        assertThat(mPreference.getSummary()).isEqualTo(
-                mContext.getString(R.string.gup_dev_opt_in_app_set, appLabel));
-    }
-
-    @Test
-    public void onActivityResult_badRequestCode_shouldReturnFalse() {
-        assertThat(mController.onActivityResult(
-                -1 /* requestCode */, -1 /* resultCode */, null /* intent */)).isFalse();
-    }
-
-    @Test
-    public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() {
-        mController.onDeveloperOptionsSwitchDisabled();
-
-        assertThat(mPreference.isEnabled()).isFalse();
-        assertThat(mPreference.getSummary()).isEqualTo(
-                mContext.getString(R.string.gup_dev_opt_in_app_not_set));
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/development/gup/GupPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/gup/GupPreferenceControllerTest.java
new file mode 100644
index 0000000..62e3475
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/gup/GupPreferenceControllerTest.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.development.gup;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
+import static com.android.settings.testutils.ApplicationTestUtils.buildInfo;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.provider.Settings;
+
+import androidx.preference.ListPreference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceGroup;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+
+import java.util.Arrays;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class GupPreferenceControllerTest {
+    private static final int DEFAULT = 0;
+    private static final int GUP = 1;
+    private static final int NATIVE = 2;
+    private static final String TEST_APP_NAME = "testApp";
+    private static final String TEST_PKG_NAME = "testPkg";
+
+    // Pre-installed Apps in the Mock PackageManager
+    private static final String APP_1 = "app1";
+    private static final String APP_2 = "app2";
+    private static final String APP_3 = "app3";
+
+    @Mock
+    private PackageManager mPackageManager;
+    @Mock
+    private PreferenceScreen mScreen;
+
+    private Context mContext;
+    private PreferenceGroup mGroup;
+    private PreferenceManager mPreferenceManager;
+    private ContentResolver mResolver;
+    private GupPreferenceController mController;
+    private CharSequence[] mValueList;
+    private String mDialogTitle;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        mResolver = mContext.getContentResolver();
+        mValueList = mContext.getResources().getStringArray(R.array.gup_app_preference_values);
+        mDialogTitle = mContext.getResources().getString(R.string.gup_app_preference_title);
+    }
+
+    @Test
+    public void getAvailability_developmentSettingsEnabled_available() {
+        loadDefaultConfig();
+        Settings.Global.putInt(mResolver, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+    }
+
+    @Test
+    public void getAvailability_developmentSettingsDisabled_disabledDependentSetting() {
+        loadDefaultConfig();
+        Settings.Global.putInt(mResolver, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
+    }
+
+    @Test
+    public void displayPreference_shouldAddTwoPreferencesAndSortAscendingly() {
+        mockPackageManager();
+        loadDefaultConfig();
+
+        // Only non-system app has preference
+        assertThat(mGroup.getPreferenceCount()).isEqualTo(2);
+        assertThat(mGroup.getPreference(0).getKey()).isEqualTo(APP_1);
+        assertThat(mGroup.getPreference(1).getKey()).isEqualTo(APP_3);
+    }
+
+    @Test
+    public void createPreference_configDefault_shouldSetDefaultAttributes() {
+        loadDefaultConfig();
+        final ListPreference preference =
+                mController.createListPreference(TEST_PKG_NAME, TEST_APP_NAME);
+
+        assertThat(preference.getKey()).isEqualTo(TEST_PKG_NAME);
+        assertThat(preference.getTitle()).isEqualTo(TEST_APP_NAME);
+        assertThat(preference.getDialogTitle()).isEqualTo(mDialogTitle);
+        assertThat(preference.getEntries()).isEqualTo(mValueList);
+        assertThat(preference.getEntryValues()).isEqualTo(mValueList);
+        assertThat(preference.getEntry()).isEqualTo(mValueList[DEFAULT]);
+        assertThat(preference.getValue()).isEqualTo(mValueList[DEFAULT]);
+        assertThat(preference.getSummary()).isEqualTo(mValueList[DEFAULT]);
+    }
+
+    @Test
+    public void createPreference_configGup_shouldSetGupAttributes() {
+        loadConfig(TEST_PKG_NAME, "");
+        final ListPreference preference =
+                mController.createListPreference(TEST_PKG_NAME, TEST_APP_NAME);
+
+        assertThat(preference.getKey()).isEqualTo(TEST_PKG_NAME);
+        assertThat(preference.getTitle()).isEqualTo(TEST_APP_NAME);
+        assertThat(preference.getDialogTitle()).isEqualTo(mDialogTitle);
+        assertThat(preference.getEntries()).isEqualTo(mValueList);
+        assertThat(preference.getEntryValues()).isEqualTo(mValueList);
+        assertThat(preference.getEntry()).isEqualTo(mValueList[GUP]);
+        assertThat(preference.getValue()).isEqualTo(mValueList[GUP]);
+        assertThat(preference.getSummary()).isEqualTo(mValueList[GUP]);
+    }
+
+    @Test
+    public void createPreference_configNative_shouldSetNativeAttributes() {
+        loadConfig("", TEST_PKG_NAME);
+        final ListPreference preference =
+                mController.createListPreference(TEST_PKG_NAME, TEST_APP_NAME);
+
+        assertThat(preference.getKey()).isEqualTo(TEST_PKG_NAME);
+        assertThat(preference.getTitle()).isEqualTo(TEST_APP_NAME);
+        assertThat(preference.getDialogTitle()).isEqualTo(mDialogTitle);
+        assertThat(preference.getEntries()).isEqualTo(mValueList);
+        assertThat(preference.getEntryValues()).isEqualTo(mValueList);
+        assertThat(preference.getEntry()).isEqualTo(mValueList[NATIVE]);
+        assertThat(preference.getValue()).isEqualTo(mValueList[NATIVE]);
+        assertThat(preference.getSummary()).isEqualTo(mValueList[NATIVE]);
+    }
+
+    @Test
+    public void onPreferenceChange_selectDefault_shouldUpdateAttributesAndSettingsGlobal() {
+        loadDefaultConfig();
+        final ListPreference preference =
+                mController.createListPreference(TEST_PKG_NAME, TEST_APP_NAME);
+        mController.onPreferenceChange(preference, mValueList[DEFAULT]);
+
+        assertThat(preference.getSummary()).isEqualTo(mValueList[DEFAULT]);
+        assertThat(Settings.Global.getString(mResolver, Settings.Global.GUP_DEV_OPT_IN_APPS))
+                .isEqualTo("");
+        assertThat(Settings.Global.getString(mResolver, Settings.Global.GUP_DEV_OPT_OUT_APPS))
+                .isEqualTo("");
+    }
+
+    @Test
+    public void onPreferenceChange_selectGup_shouldUpdateAttributesAndSettingsGlobal() {
+        loadDefaultConfig();
+        final ListPreference preference =
+                mController.createListPreference(TEST_PKG_NAME, TEST_APP_NAME);
+        mController.onPreferenceChange(preference, mValueList[GUP]);
+
+        assertThat(preference.getSummary()).isEqualTo(mValueList[GUP]);
+        assertThat(Settings.Global.getString(mResolver, Settings.Global.GUP_DEV_OPT_IN_APPS))
+                .isEqualTo(TEST_PKG_NAME);
+        assertThat(Settings.Global.getString(mResolver, Settings.Global.GUP_DEV_OPT_OUT_APPS))
+                .isEqualTo("");
+    }
+
+    @Test
+    public void onPreferenceChange_selectNative_shouldUpdateAttributesAndSettingsGlobal() {
+        loadDefaultConfig();
+        final ListPreference preference =
+                mController.createListPreference(TEST_PKG_NAME, TEST_APP_NAME);
+        mController.onPreferenceChange(preference, mValueList[NATIVE]);
+
+        assertThat(preference.getSummary()).isEqualTo(mValueList[NATIVE]);
+        assertThat(Settings.Global.getString(mResolver, Settings.Global.GUP_DEV_OPT_IN_APPS))
+                .isEqualTo("");
+        assertThat(Settings.Global.getString(mResolver, Settings.Global.GUP_DEV_OPT_OUT_APPS))
+                .isEqualTo(TEST_PKG_NAME);
+    }
+
+    private void mockPackageManager() {
+        final int uid = mContext.getUserId();
+        final ApplicationInfo app1 = buildInfo(uid, APP_1, 0 /* flags */, 0 /* targetSdkVersion */);
+        final ApplicationInfo app2 =
+                buildInfo(uid, APP_2, ApplicationInfo.FLAG_SYSTEM, 0 /* targetSdkVersion */);
+        final ApplicationInfo app3 = buildInfo(uid, APP_3, 0 /* flags */, 0 /* targetSdkVersion */);
+
+        when(mPackageManager.getInstalledApplications(0 /* flags */))
+                .thenReturn(Arrays.asList(app3, app2, app1));
+        when(mPackageManager.getApplicationLabel(app1)).thenReturn(APP_1);
+        when(mPackageManager.getApplicationLabel(app2)).thenReturn(APP_2);
+        when(mPackageManager.getApplicationLabel(app3)).thenReturn(APP_3);
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
+    }
+
+    private void loadDefaultConfig() { loadConfig("", ""); }
+
+    private void loadConfig(String optIn, String optOut) {
+        Settings.Global.putString(mResolver, Settings.Global.GUP_DEV_OPT_IN_APPS, optIn);
+        Settings.Global.putString(mResolver, Settings.Global.GUP_DEV_OPT_OUT_APPS, optOut);
+
+        mController = new GupPreferenceController(mContext, "testKey");
+        mGroup = spy(new PreferenceCategory(mContext));
+        final PreferenceManager preferenceManager = new PreferenceManager(mContext);
+        when(mGroup.getPreferenceManager()).thenReturn(preferenceManager);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mGroup);
+        mController.displayPreference(mScreen);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/display/TimeoutListPreferenceTest.java b/tests/robotests/src/com/android/settings/display/TimeoutListPreferenceTest.java
index 55fcdac..7b67f0f 100644
--- a/tests/robotests/src/com/android/settings/display/TimeoutListPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/display/TimeoutListPreferenceTest.java
@@ -17,11 +17,11 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Mockito.mock;
 import static org.robolectric.RuntimeEnvironment.application;
 
 import android.util.AttributeSet;
 
+import com.android.settings.R;
 import com.android.settings.testutils.shadow.ShadowUserManager;
 import com.android.settingslib.RestrictedLockUtils;
 
@@ -69,4 +69,23 @@
         // should set to largest allowed value, which is 5 minute
         assertThat(mPreference.getValue()).isEqualTo("300000");
     }
+
+    @Test
+    @Config(qualifiers = "mcc999")
+    public void newInstance_hasLowTimeoutConfig_shouldRemoveLongTimeouts() {
+        final AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
+        final TimeoutListPreference pref = new TimeoutListPreference(application, attributeSet);
+        final long maxTimeout = application.getResources().getInteger(
+                R.integer.max_lock_after_timeout_ms);
+        pref.setEntries(R.array.screen_timeout_entries);
+        pref.setEntryValues(R.array.screen_timeout_values);
+
+        pref.updateInitialValues();
+
+        final CharSequence[] values = pref.getEntryValues();
+        for (CharSequence value : values) {
+            long timeout = Long.parseLong(value.toString());
+            assertThat(timeout).isAtMost(maxTimeout);
+        }
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/BatterySaverConditionControllerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/BatterySaverConditionControllerTest.java
new file mode 100644
index 0000000..e4ca6c0
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/BatterySaverConditionControllerTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.contextualcards.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 android.content.Context;
+import android.content.IntentFilter;
+import android.os.PowerManager;
+
+import com.android.settings.fuelgauge.BatterySaverReceiver;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.Shadows;
+import org.robolectric.shadows.ShadowPowerManager;
+
+@RunWith(RobolectricTestRunner.class)
+public class BatterySaverConditionControllerTest {
+    @Mock
+    private ConditionManager mConditionManager;
+
+    private ShadowPowerManager mPowerManager;
+    private Context mContext;
+    private BatterySaverConditionController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        mPowerManager = Shadows.shadowOf(mContext.getSystemService(PowerManager.class));
+        mController = new BatterySaverConditionController(mContext, mConditionManager);
+    }
+
+    @Test
+    public void startMonitor_shouldRegisterReceiver() {
+        mController.startMonitoringStateChange();
+
+        verify(mContext).registerReceiver(any(BatterySaverReceiver.class), any(IntentFilter.class));
+    }
+
+    @Test
+    public void stopMonitor_shouldUnregisterReceiver() {
+        mController.startMonitoringStateChange();
+        mController.stopMonitoringStateChange();
+
+        verify(mContext).unregisterReceiver(any(BatterySaverReceiver.class));
+    }
+
+    @Test
+    public void isDisplayable_PowerSaverOn_true() {
+        mPowerManager.setIsPowerSaveMode(true);
+
+        assertThat(mController.isDisplayable()).isTrue();
+    }
+
+    @Test
+    public void isDisplayable_PowerSaverOff_false() {
+        mPowerManager.setIsPowerSaveMode(false);
+
+        assertThat(mController.isDisplayable()).isFalse();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/BatterySliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/BatteryInfoSliceTest.java
similarity index 84%
rename from tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/BatterySliceTest.java
rename to tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/BatteryInfoSliceTest.java
index 289a57d..ff276d6 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/BatterySliceTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/BatteryInfoSliceTest.java
@@ -40,10 +40,10 @@
 import org.robolectric.RuntimeEnvironment;
 
 @RunWith(RobolectricTestRunner.class)
-public class BatterySliceTest {
+public class BatteryInfoSliceTest {
 
     private Context mContext;
-    private BatterySlice mBatterySlice;
+    private BatteryInfoSlice mBatteryInfoSlice;
 
     @Before
     public void setUp() {
@@ -52,16 +52,16 @@
         // Set-up specs for SliceMetadata.
         SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
 
-        mBatterySlice = spy(new BatterySlice(mContext));
+        mBatteryInfoSlice = spy(new BatteryInfoSlice(mContext));
     }
 
     @Test
     public void getSlice_shouldBeCorrectSliceContent() {
-        doNothing().when(mBatterySlice).loadBatteryInfo();
-        doReturn("10%").when(mBatterySlice).getBatteryPercentString();
-        doReturn("test").when(mBatterySlice).getSummary();
+        doNothing().when(mBatteryInfoSlice).loadBatteryInfo();
+        doReturn("10%").when(mBatteryInfoSlice).getBatteryPercentString();
+        doReturn("test").when(mBatteryInfoSlice).getSummary();
 
-        final Slice slice = mBatterySlice.getSlice();
+        final Slice slice = mBatteryInfoSlice.getSlice();
 
         final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
         assertThat(metadata.getTitle()).isEqualTo(
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSliceTest.java
index ff08c6a..1c299cb 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSliceTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSliceTest.java
@@ -26,6 +26,8 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 
+import androidx.slice.Slice;
+import androidx.slice.SliceMetadata;
 import androidx.slice.SliceProvider;
 import androidx.slice.widget.SliceLiveData;
 
@@ -55,11 +57,13 @@
 public class BatteryFixSliceTest {
 
     private Context mContext;
+    private BatteryFixSlice mSlice;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
+        mSlice = new BatteryFixSlice(mContext);
 
         // Set-up specs for SliceMetadata.
         SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
@@ -71,7 +75,7 @@
     }
 
     @Test
-    public void readBatteryTipfromPref_readCorrectValue() {
+    public void readBatteryTipFromPref_readCorrectValue() {
         int target = 111;
         final SharedPreferences.Editor editor = mContext.getSharedPreferences(PREFS,
                 MODE_PRIVATE).edit();
@@ -90,7 +94,7 @@
     public void updateBatteryTipAvailabilityCache_writeCorrectValue() {
         final List<BatteryTip> tips = new ArrayList<>();
         tips.add(new LowBatteryTip(BatteryTip.StateType.INVISIBLE, false, ""));
-        tips.add(new EarlyWarningTip(BatteryTip.StateType.HANDLED, false));
+        tips.add(new EarlyWarningTip(BatteryTip.StateType.NEW, false));
         ShadowBatteryTipLoader.setBatteryTips(tips);
 
         BatteryFixSlice.updateBatteryTipAvailabilityCache(mContext);
@@ -99,6 +103,23 @@
                 BatteryTip.TipType.BATTERY_SAVER);
     }
 
+    @Test
+    @Config(shadows = {
+            ShadowBatteryStatsHelperLoader.class,
+            ShadowBatteryTipLoader.class
+    })
+    public void getSlice_unimportantSlice_shouldSkip() {
+        final List<BatteryTip> tips = new ArrayList<>();
+        tips.add(new LowBatteryTip(BatteryTip.StateType.INVISIBLE, false, ""));
+        tips.add(new EarlyWarningTip(BatteryTip.StateType.NEW, false));
+        ShadowBatteryTipLoader.setBatteryTips(tips);
+
+        BatteryFixSlice.updateBatteryTipAvailabilityCache(mContext);
+        final Slice slice = mSlice.getSlice();
+
+        assertThat(SliceMetadata.from(mContext, slice).isErrorSlice()).isTrue();
+    }
+
     @Implements(BatteryStatsHelperLoader.class)
     public static class ShadowBatteryStatsHelperLoader {
 
diff --git a/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogFragmentTest.java b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogFragmentTest.java
index e64fae7..17516e9 100644
--- a/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogFragmentTest.java
@@ -111,14 +111,17 @@
         ShadowLooper.getShadowMainLooper().runToEndOfTasks();
 
         assertThat(fakeFragment.bCalledStopAndPop).isTrue();
+        assertThat(fakeFragment.errorType).isEqualTo(ERROR_DIALOG_TYPE.TIME_OUT);
     }
 
     class FakeNetworkRequestDialogFragment extends NetworkRequestDialogFragment {
         boolean bCalledStopAndPop = false;
+        ERROR_DIALOG_TYPE errorType = null;
 
         @Override
-        public void stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE type) {
+        public void stopScanningAndMaybePopErrorDialog(ERROR_DIALOG_TYPE type) {
             bCalledStopAndPop = true;
+            errorType = type;
         }
     }
 
@@ -150,22 +153,28 @@
 
     @Test
     public void updateAccessPointList_onUserSelectionConnectSuccess_shouldCloseTheDialog() {
-        List<AccessPoint> accessPointList = createAccessPointList();
-        when(networkRequestDialogFragment.getAccessPointList()).thenReturn(accessPointList);
-        networkRequestDialogFragment.show(mActivity.getSupportFragmentManager(), null);
-        AlertDialog alertDialog = ShadowAlertDialogCompat.getLatestAlertDialog();
-        assertThat(alertDialog.isShowing()).isTrue();
+        // Assert
+        FakeNetworkRequestDialogFragment fakeFragment = new FakeNetworkRequestDialogFragment();
+        FakeNetworkRequestDialogFragment spyFakeFragment = spy(fakeFragment);
 
-        // Test if config would update list.
+        List<AccessPoint> accessPointList = createAccessPointList();
+        when(spyFakeFragment.getAccessPointList()).thenReturn(accessPointList);
+
+        spyFakeFragment.show(mActivity.getSupportFragmentManager(), null);
+
+        // Action
         WifiConfiguration config = new WifiConfiguration();
         config.SSID = "Test AP 3";
-        networkRequestDialogFragment.onUserSelectionConnectSuccess(config);
+        spyFakeFragment.onUserSelectionConnectSuccess(config);
 
-        assertThat(alertDialog.isShowing()).isFalse();
+        // Check
+        ShadowLooper.getShadowMainLooper().runToEndOfTasks();
+        assertThat(fakeFragment.bCalledStopAndPop).isTrue();
+        assertThat(fakeFragment.errorType).isNull();
     }
 
     @Test
-    public void updateAccessPointList_onUserSelectionConnectFailure_shouldCallTimeoutDialog() {
+    public void updateAccessPointList_onUserSelectionConnectFailure_shouldCallAbortDialog() {
         FakeNetworkRequestDialogFragment fakeFragment = new FakeNetworkRequestDialogFragment();
         FakeNetworkRequestDialogFragment spyFakeFragment = spy(fakeFragment);
         List<AccessPoint> accessPointList = createAccessPointList();
@@ -181,6 +190,7 @@
         fakeFragment.onUserSelectionConnectFailure(config);
 
         assertThat(fakeFragment.bCalledStopAndPop).isTrue();
+        assertThat(fakeFragment.errorType).isEqualTo(ERROR_DIALOG_TYPE.ABORT);
     }
 
     @Test