Merge changes I2d087f34,Ia2b91315

* changes:
  Filter out unimportant battery tips from slice card.
  Revert "Remove battery saver condition."
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/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/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/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 bc050f8..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] -->
@@ -10064,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/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/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/wifi/dpp/WifiDppAddDeviceFragment.java b/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java
index 8fa58f3..9264ad9 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java
@@ -28,7 +28,6 @@
 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;
@@ -41,7 +40,7 @@
     private static final String TAG = "WifiDppAddDeviceFragment";
 
     private ImageView mWifiApPictureView;
-    private TextView mChooseDifferentNetwork;
+    private Button mChooseDifferentNetwork;
     private Button mButtonLeft;
     private Button mButtonRight;
 
@@ -109,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);
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
index 2f59e18..45d753c 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
@@ -64,6 +64,7 @@
 
     // 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;
@@ -71,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;
@@ -80,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;
@@ -368,4 +378,11 @@
             }
         }
     };
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+       outState.putBoolean(KEY_IS_CONFIGURATOR_MODE, mIsConfiguratorMode);
+
+       super.onSaveInstanceState(outState);
+    }
 }
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);
+        }
+    }
 }