Merge "p2p: do P2P factory reset for Network Reset"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 98adebb..eb3be0e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -922,14 +922,6 @@
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="com.android.settings.SHORTCUT" />
             </intent-filter>
-            <intent-filter>
-                <action android:name="com.android.settings.action.SETTINGS" />
-            </intent-filter>
-            <meta-data android:name="com.android.settings.order" android:value="20"/>
-            <meta-data android:name="com.android.settings.category"
-                       android:value="com.android.settings.category.ia.homepage" />
-            <meta-data android:name="com.android.settings.title"
-                       android:resource="@string/about_settings" />
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                        android:value="com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment" />
             <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
diff --git a/res/layout/homepage_condition_full_tile.xml b/res/layout/homepage_condition_full_tile.xml
index 1b68e76..415defc 100644
--- a/res/layout/homepage_condition_full_tile.xml
+++ b/res/layout/homepage_condition_full_tile.xml
@@ -24,9 +24,11 @@
     <LinearLayout
         android:id="@+id/content"
         android:layout_width="match_parent"
-        android:layout_height="@dimen/homepage_condition_full_card_height"
+        android:layout_height="wrap_content"
         android:paddingStart="@dimen/homepage_card_padding_start"
         android:paddingEnd="@dimen/homepage_card_padding_end"
+        android:paddingTop="@dimen/homepage_condition_full_card_padding_top"
+        android:paddingBottom="@dimen/homepage_condition_full_card_padding_bottom"
         android:orientation="horizontal"
         android:gravity="center_vertical">
 
@@ -59,13 +61,7 @@
 
         </LinearLayout>
 
-        <View
-            android:id="@+id/divider"
-            android:layout_width="@dimen/homepage_condition_full_card_divider_width"
-            android:layout_height="match_parent"
-            android:layout_marginTop="@dimen/homepage_condition_full_card_divider_padding_top"
-            android:layout_marginBottom="@dimen/homepage_condition_full_card_divider_padding_bottom"
-            android:background="?android:attr/dividerVertical" />
+        <include layout="@layout/vertical_divider"/>
 
         <Button
             android:id="@+id/first_action"
diff --git a/res/layout/homepage_condition_half_tile.xml b/res/layout/homepage_condition_half_tile.xml
index 10b38a4..0b7eec7 100644
--- a/res/layout/homepage_condition_half_tile.xml
+++ b/res/layout/homepage_condition_half_tile.xml
@@ -40,6 +40,8 @@
             android:id="@android:id/title"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:maxLines="1"
+            android:ellipsize="end"
             android:layout_marginTop="@dimen/homepage_condition_half_card_title_margin_top"
             android:layout_marginBottom="@dimen/homepage_condition_card_title_margin_bottom"
             style="@style/TextAppearance.ConditionCardTitle"/>
@@ -48,6 +50,9 @@
             android:id="@android:id/summary"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:maxLines="1"
+            android:ellipsize="end"
+            android:layout_marginBottom="@dimen/homepage_condition_half_card_summary_margin_bottom"
             style="@style/TextAppearance.ConditionCardSummary"/>
 
         <include layout="@layout/horizontal_divider"/>
diff --git a/res/layout/vertical_divider.xml b/res/layout/vertical_divider.xml
new file mode 100644
index 0000000..4f1cc43
--- /dev/null
+++ b/res/layout/vertical_divider.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<View
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/divider"
+    android:layout_width="@dimen/vertical_divider_width"
+    android:layout_height="match_parent"
+    android:background="?android:attr/dividerVertical"/>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 8432fe1..caaea90 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -333,6 +333,9 @@
     <dimen name="horizontal_divider_margin_bottom">8dp</dimen>
     <dimen name="horizontal_divider_height">.75dp</dimen>
 
+    <!-- Vertical divider size -->
+    <dimen name="vertical_divider_width">.75dp</dimen>
+
     <!-- Signal icon in NetworkSelectSetting -->
     <dimen name="signal_strength_icon_size">24dp</dimen>
 
@@ -341,11 +344,10 @@
     <dimen name="homepage_condition_half_card_height">150dp</dimen>
     <dimen name="homepage_condition_half_card_padding_top">12dp</dimen>
     <dimen name="homepage_condition_half_card_title_margin_top">12dp</dimen>
-    <dimen name="homepage_condition_full_card_height">72dp</dimen>
+    <dimen name="homepage_condition_half_card_summary_margin_bottom">12dp</dimen>
     <dimen name="homepage_condition_full_card_padding_start">24dp</dimen>
     <dimen name="homepage_condition_full_card_padding_end">24dp</dimen>
-    <dimen name="homepage_condition_full_card_divider_width">.75dp</dimen>
-    <dimen name="homepage_condition_full_card_divider_padding_top">12dp</dimen>
-    <dimen name="homepage_condition_full_card_divider_padding_bottom">12dp</dimen>
+    <dimen name="homepage_condition_full_card_padding_top">12dp</dimen>
+    <dimen name="homepage_condition_full_card_padding_bottom">12dp</dimen>
 
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9a2576b..f30c63d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -678,7 +678,7 @@
     <!-- check box to allow data usage when roaming [CHAR LIMIT=41] -->
     <string name="allow_data_usage_title">Allow data usage when roaming</string>
     <!-- mobile network settings screen, setting check box title -->
-    <string name="roaming">Data roaming</string>
+    <string name="roaming">Roaming</string>
     <!-- mobile network settings screen, setting option summary text when check box is selected -->
     <string name="roaming_enable">Connect to data services when roaming</string>
     <!-- mobile network settings screen, setting option summary text when check box is clear -->
@@ -9964,6 +9964,13 @@
     <!-- 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 updated graphics driver [CHAR LIMIT=100] -->
+    <string name="updated_gfx_driver_dev_opt_in_app">Select app to use updated graphics driver</string>
+    <!-- UI debug setting: no app selected to use updated GPU driver [CHAR LIMIT=100] -->
+    <string name="updated_gfx_driver_dev_opt_in_app_not_set">No selected app to use updated graphics driver</string>
+    <!-- UI debug setting: app selected to use updated graphics driver [CHAR LIMIT=NONE] -->
+    <string name="updated_gfx_driver_dev_opt_in_app_set">Opt in application: <xliff:g id="app_name" example="com.company.app">%1$s</xliff:g></string>
+
     <!-- Slices Strings -->
 
     <!-- Summary text on a card explaining that a setting does not exist / is not supported on the device [CHAR_LIMIT=NONE]-->
@@ -10243,6 +10250,8 @@
     <string name="mobile_data_usage_title">App data usage</string>
     <!-- Summary to show the current network mode is invalid. [CHAR LIMIT=NONE]-->
     <string name="mobile_network_mode_error">Invalid Network Mode <xliff:g id="networkModeId" example="0">%1$d</xliff:g>. Ignore.</string>
+    <!-- Title for Apn settings in mobile network settings [CHAR LIMIT=60] -->
+    <string name="mobile_network_apn_title">Access Point Names</string>
 
     <!-- Available networks screen, summary when button disallowed due to permanent automatic mode [CHAR LIMIT=NONE] -->
     <string name="manual_mode_disallowed_summary">Unavailable when connected to <xliff:g id="carrier" example="verizon">%1$s</xliff:g></string>
@@ -10264,4 +10273,9 @@
     </plurals>
     <!-- Title for no connected devices in connected device slice. [CHAR LIMIT=NONE] -->
     <string name="no_connected_devices">No connected devices</string>
+
+    <!-- UI debug setting: force desktop mode [CHAR LIMIT=50] -->
+    <string name="force_desktop_mode">Force desktop mode</string>
+    <!-- UI debug setting: force desktop mode summary [CHAR LIMIT=NONE] -->
+    <string name="force_desktop_mode_summary">Force experimental desktop mode on secondary displays</string>
 </resources>
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 6528cf7..a35ad1b 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -422,6 +422,10 @@
         <Preference android:key="angle_enabled_app"
             android:title="@string/angle_enabled_app" />
 
+        <Preference android:key="updated_gfx_driver_dev_opt_in_app"
+            android:summary="@string/updated_gfx_driver_dev_opt_in_app_summary"
+            android:title="@string/updated_gfx_driver_dev_opt_in_app" />
+
     </PreferenceCategory>
 
     <PreferenceCategory
@@ -510,6 +514,11 @@
             android:title="@string/enable_freeform_support"
             android:summary="@string/enable_freeform_support_summary" />
 
+        <SwitchPreference
+            android:key="force_desktop_mode_on_external_displays"
+            android:title="@string/force_desktop_mode"
+            android:summary="@string/force_desktop_mode_summary" />
+
         <Preference
             android:key="reset_shortcut_manager_throttling"
             android:title="@string/reset_shortcut_manager_throttling" />
diff --git a/res/xml/gsm_umts_options.xml b/res/xml/gsm_umts_options.xml
deleted file mode 100644
index cf56595..0000000
--- a/res/xml/gsm_umts_options.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2008 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
-    <!--We want separate APN setting from reset of settings because-->
-    <!--we want user to change it with caution.-->
-    <PreferenceCategory
-        android:key="category_gsm_apn_key"
-        android:layout="@layout/preference_category_no_label">
-
-        <com.android.settingslib.RestrictedPreference
-            android:key="button_gsm_apn_key"
-            android:title="@string/apn_settings"
-            android:persistent="false" />
-    </PreferenceCategory>
-
-    <PreferenceScreen
-        android:key="carrier_settings_key"
-        android:title="@string/carrier_settings_title">
-        <!-- b/114749736, create a preference controller to build intent -->
-    </PreferenceScreen>
-
-</PreferenceScreen>
diff --git a/res/xml/mobile_network_settings.xml b/res/xml/mobile_network_settings.xml
index 0478664..cc914ad 100644
--- a/res/xml/mobile_network_settings.xml
+++ b/res/xml/mobile_network_settings.xml
@@ -138,7 +138,7 @@
     <com.android.settingslib.RestrictedPreference
         android:key="telephony_apn_key"
         android:persistent="false"
-        android:title="@string/apn_settings"
+        android:title="@string/mobile_network_apn_title"
         settings:allowDividerAbove="true"
         settings:controller="com.android.settings.network.telephony.ApnPreferenceController"/>
 
diff --git a/res/xml/print_job_settings.xml b/res/xml/print_job_settings.xml
index 32a80a7..877cd62 100644
--- a/res/xml/print_job_settings.xml
+++ b/res/xml/print_job_settings.xml
@@ -19,13 +19,16 @@
         android:title="@string/print_print_job">
 
     <Preference
-            android:key="print_job_preference">
+            android:key="print_job_preference"
+            android:title="@string/print_print_job"
+            settings:controller="com.android.settings.print.PrintJobPreferenceController">
     </Preference>
 
     <Preference
             android:key="print_job_message_preference"
             android:layout="@layout/print_job_summary"
-            android:selectable="false">
+            android:selectable="false"
+            settings:controller="com.android.settings.print.PrintJobMessagePreferenceController">
     </Preference>
 
 </PreferenceScreen>
diff --git a/res/xml/top_level_settings.xml b/res/xml/top_level_settings.xml
index b5930e4..69c4bb8 100644
--- a/res/xml/top_level_settings.xml
+++ b/res/xml/top_level_settings.xml
@@ -125,6 +125,15 @@
         android:fragment="com.android.settings.system.SystemDashboardFragment"/>
 
     <Preference
+        android:key="top_level_about_device"
+        android:title="@string/about_settings"
+        android:summary="@string/summary_placeholder"
+        android:icon="@drawable/ic_homepage_about"
+        android:order="20"
+        android:fragment="com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment"
+        settings:controller="com.android.settings.deviceinfo.aboutphone.TopLevelAboutDevicePreferenceController"/>
+
+    <Preference
         android:key="top_level_support"
         android:summary="@string/support_summary"
         android:title="@string/page_tab_title_support"
diff --git a/src/com/android/settings/accounts/AccountFeatureProvider.java b/src/com/android/settings/accounts/AccountFeatureProvider.java
index 9829ca6..fd65095 100644
--- a/src/com/android/settings/accounts/AccountFeatureProvider.java
+++ b/src/com/android/settings/accounts/AccountFeatureProvider.java
@@ -18,8 +18,10 @@
 
 import android.accounts.Account;
 import android.content.Context;
+import android.content.Intent;
 
 public interface AccountFeatureProvider {
     String getAccountType();
     Account[] getAccounts(Context context);
+    Intent getAccountSettingsDeeplinkIntent();
 }
diff --git a/src/com/android/settings/accounts/AccountFeatureProviderImpl.java b/src/com/android/settings/accounts/AccountFeatureProviderImpl.java
index 90b581b..2e0f432 100644
--- a/src/com/android/settings/accounts/AccountFeatureProviderImpl.java
+++ b/src/com/android/settings/accounts/AccountFeatureProviderImpl.java
@@ -2,6 +2,7 @@
 
 import android.accounts.Account;
 import android.content.Context;
+import android.content.Intent;
 
 public class AccountFeatureProviderImpl implements AccountFeatureProvider {
     @Override
@@ -13,4 +14,9 @@
     public Account[] getAccounts(Context context) {
         return new Account[0];
     }
+
+    @Override
+    public Intent getAccountSettingsDeeplinkIntent() {
+        return null;
+    }
 }
diff --git a/src/com/android/settings/accounts/AvatarViewMixin.java b/src/com/android/settings/accounts/AvatarViewMixin.java
index 6dcf312..78750b1 100644
--- a/src/com/android/settings/accounts/AvatarViewMixin.java
+++ b/src/com/android/settings/accounts/AvatarViewMixin.java
@@ -17,18 +17,30 @@
 package com.android.settings.accounts;
 
 import android.accounts.Account;
+import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.TextUtils;
 import android.util.Log;
 import android.widget.ImageView;
 
 import androidx.annotation.VisibleForTesting;
 import androidx.lifecycle.Lifecycle;
 import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.MutableLiveData;
 import androidx.lifecycle.OnLifecycleEvent;
 
 import com.android.settings.R;
 import com.android.settings.homepage.SettingsHomepageActivity;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.utils.ThreadUtils;
+
+import java.util.List;
 
 /**
  * Avatar related work to the onStart method of registered observable classes
@@ -37,12 +49,39 @@
 public class AvatarViewMixin implements LifecycleObserver {
     private static final String TAG = "AvatarViewMixin";
 
+    @VisibleForTesting
+    static final Intent INTENT_GET_ACCOUNT_DATA =
+            new Intent("android.content.action.SETTINGS_ACCOUNT_DATA");
+
+    private static final String METHOD_GET_ACCOUNT_AVATAR = "getAccountAvatar";
+    private static final String KEY_AVATAR_BITMAP = "account_avatar";
+    private static final int REQUEST_CODE = 1013;
+
     private final Context mContext;
     private final ImageView mAvatarView;
+    private final MutableLiveData<Bitmap> mAvatarImage;
 
-    public AvatarViewMixin(Context context, ImageView avatarView) {
-        mContext = context.getApplicationContext();
+    public AvatarViewMixin(SettingsHomepageActivity activity, ImageView avatarView) {
+        mContext = activity.getApplicationContext();
         mAvatarView = avatarView;
+        mAvatarView.setOnClickListener(v -> {
+            if (hasAccount()) {
+                //TODO(b/117509285) launch the new page of the MeCard
+            } else {
+                final Intent intent = FeatureFactory.getFactory(mContext)
+                        .getAccountFeatureProvider()
+                        .getAccountSettingsDeeplinkIntent();
+
+                if (intent != null) {
+                    activity.startActivityForResult(intent, REQUEST_CODE);
+                }
+            }
+        });
+
+        mAvatarImage = new MutableLiveData<>();
+        mAvatarImage.observe(activity, bitmap -> {
+            avatarView.setImageBitmap(bitmap);
+        });
     }
 
     @OnLifecycleEvent(Lifecycle.Event.ON_START)
@@ -52,7 +91,7 @@
             return;
         }
         if (hasAccount()) {
-            //TODO(b/117509285): To migrate account icon on search bar
+            loadAvatar();
         } else {
             mAvatarView.setImageResource(R.drawable.ic_account_circle_24dp);
         }
@@ -64,4 +103,34 @@
                 mContext).getAccountFeatureProvider().getAccounts(mContext);
         return (accounts != null) && (accounts.length > 0);
     }
+
+    private void loadAvatar() {
+        final String authority = queryProviderAuthority();
+        if (TextUtils.isEmpty(authority)) {
+            return;
+        }
+
+        ThreadUtils.postOnBackgroundThread(() -> {
+            final Uri uri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+                    .authority(authority)
+                    .build();
+            final Bundle bundle = mContext.getContentResolver().call(uri,
+                    METHOD_GET_ACCOUNT_AVATAR, null /* arg */, null /* extras */);
+            final Bitmap bitmap = bundle.getParcelable(KEY_AVATAR_BITMAP);
+            mAvatarImage.postValue(bitmap);
+        });
+    }
+
+    @VisibleForTesting
+    String queryProviderAuthority() {
+        final List<ResolveInfo> providers =
+                mContext.getPackageManager().queryIntentContentProviders(INTENT_GET_ACCOUNT_DATA,
+                        PackageManager.MATCH_SYSTEM_ONLY);
+        if (providers.size() == 1) {
+            return providers.get(0).providerInfo.authority;
+        } else {
+            Log.w(TAG, "The size of the provider is " + providers.size());
+            return null;
+        }
+    }
 }
diff --git a/src/com/android/settings/development/DesktopModePreferenceController.java b/src/com/android/settings/development/DesktopModePreferenceController.java
new file mode 100644
index 0000000..528af8a
--- /dev/null
+++ b/src/com/android/settings/development/DesktopModePreferenceController.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.development;
+
+import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
+
+import android.content.Context;
+import android.os.Build;
+import android.provider.Settings;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.SwitchPreference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.development.DeveloperOptionsPreferenceController;
+
+public class DesktopModePreferenceController extends DeveloperOptionsPreferenceController
+        implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
+
+    private static final String FORCE_DESKTOP_MODE_KEY = "force_desktop_mode_on_external_displays";
+
+    @VisibleForTesting
+    static final int SETTING_VALUE_OFF = 0;
+    @VisibleForTesting
+    static final int SETTING_VALUE_ON = 1;
+
+    public DesktopModePreferenceController(Context context) {
+        super(context);
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return FORCE_DESKTOP_MODE_KEY;
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        final boolean isEnabled = (Boolean) newValue;
+        Settings.Global.putInt(mContext.getContentResolver(),
+                DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS,
+                isEnabled ? SETTING_VALUE_ON : SETTING_VALUE_OFF);
+        return true;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+                DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, SETTING_VALUE_OFF);
+        ((SwitchPreference) mPreference).setChecked(mode != SETTING_VALUE_OFF);
+    }
+
+    @Override
+    protected void onDeveloperOptionsSwitchDisabled() {
+        super.onDeveloperOptionsSwitchDisabled();
+        Settings.Global.putInt(mContext.getContentResolver(),
+                DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, SETTING_VALUE_OFF);
+        ((SwitchPreference) mPreference).setChecked(false);
+    }
+
+    @VisibleForTesting
+    String getBuildType() {
+        return Build.TYPE;
+    }
+}
diff --git a/src/com/android/settings/development/DevelopmentOptionsActivityRequestCodes.java b/src/com/android/settings/development/DevelopmentOptionsActivityRequestCodes.java
index 6e3ec93..3532a15 100644
--- a/src/com/android/settings/development/DevelopmentOptionsActivityRequestCodes.java
+++ b/src/com/android/settings/development/DevelopmentOptionsActivityRequestCodes.java
@@ -27,4 +27,6 @@
     int REQUEST_MOCK_LOCATION_APP = 2;
 
     int REQUEST_CODE_ANGLE_ENABLED_APP = 3;
+
+    int REQUEST_CODE_UPDATED_GFX_DRIVER_DEV_OPT_IN_APP = 4;
 }
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 82c9828..0fcf6aa 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -406,6 +406,7 @@
         controllers.add(new WaitForDebuggerPreferenceController(context));
         controllers.add(new EnableGpuDebugLayersPreferenceController(context));
         controllers.add(new AngleEnabledAppPreferenceController(context, fragment));
+        controllers.add(new UpdatedGfxDriverDevOptInPreferenceController(context, fragment));
         controllers.add(new VerifyAppsOverUsbPreferenceController(context));
         controllers.add(new LogdSizePreferenceController(context));
         controllers.add(new LogPersistPreferenceController(context, fragment, lifecycle));
@@ -458,6 +459,7 @@
         controllers.add(new AllowAppsOnExternalPreferenceController(context));
         controllers.add(new ResizableActivityPreferenceController(context));
         controllers.add(new FreeformWindowsPreferenceController(context));
+        controllers.add(new DesktopModePreferenceController(context));
         controllers.add(new SmsAccessRestrictionPreferenceController(context));
         controllers.add(new ShortcutManagerThrottlingPreferenceController(context));
         controllers.add(new EnableGnssRawMeasFullTrackingPreferenceController(context));
diff --git a/src/com/android/settings/development/FreeformWindowsPreferenceController.java b/src/com/android/settings/development/FreeformWindowsPreferenceController.java
index 5b19f36..4d38480 100644
--- a/src/com/android/settings/development/FreeformWindowsPreferenceController.java
+++ b/src/com/android/settings/development/FreeformWindowsPreferenceController.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.os.Build;
 import android.provider.Settings;
-import android.text.TextUtils;
 
 import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
@@ -37,19 +36,12 @@
     static final int SETTING_VALUE_OFF = 0;
     @VisibleForTesting
     static final int SETTING_VALUE_ON = 1;
-    @VisibleForTesting
-    static final String USER_BUILD_TYPE = "user";
 
     public FreeformWindowsPreferenceController(Context context) {
         super(context);
     }
 
     @Override
-    public boolean isAvailable() {
-        return !TextUtils.equals(USER_BUILD_TYPE, getBuildType());
-    }
-
-    @Override
     public String getPreferenceKey() {
         return ENABLE_FREEFORM_SUPPORT_KEY;
     }
diff --git a/src/com/android/settings/development/UpdatedGfxDriverDevOptInPreferenceController.java b/src/com/android/settings/development/UpdatedGfxDriverDevOptInPreferenceController.java
new file mode 100644
index 0000000..ad2131e
--- /dev/null
+++ b/src/com/android/settings/development/UpdatedGfxDriverDevOptInPreferenceController.java
@@ -0,0 +1,124 @@
+/*
+ * 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_UPDATED_GFX_DRIVER_DEV_OPT_IN_APP;
+
+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 UpdatedGfxDriverDevOptInPreferenceController
+        extends DeveloperOptionsPreferenceController
+        implements PreferenceControllerMixin, OnActivityResultListener {
+
+    private static final String UPDATED_GFX_DRIVER_DEV_OPT_IN_APP_KEY =
+            "updated_gfx_driver_dev_opt_in_app";
+
+    private final DevelopmentSettingsDashboardFragment mFragment;
+    private final PackageManager mPackageManager;
+
+    public UpdatedGfxDriverDevOptInPreferenceController(Context context,
+            DevelopmentSettingsDashboardFragment fragment) {
+        super(context);
+        mFragment = fragment;
+        mPackageManager = mContext.getPackageManager();
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return UPDATED_GFX_DRIVER_DEV_OPT_IN_APP_KEY;
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        if (UPDATED_GFX_DRIVER_DEV_OPT_IN_APP_KEY.equals(preference.getKey())) {
+            // pass it on to settings
+            final Intent intent = getActivityStartIntent();
+            mFragment.startActivityForResult(intent,
+                    REQUEST_CODE_UPDATED_GFX_DRIVER_DEV_OPT_IN_APP);
+            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_UPDATED_GFX_DRIVER_DEV_OPT_IN_APP
+                || resultCode != Activity.RESULT_OK) {
+            return false;
+        }
+        Settings.Global.putString(mContext.getContentResolver(),
+                Settings.Global.UPDATED_GFX_DRIVER_DEV_OPT_IN_APP, data.getAction());
+        updatePreferenceSummary();
+        return true;
+    }
+
+    @Override
+    protected void onDeveloperOptionsSwitchDisabled() {
+        super.onDeveloperOptionsSwitchDisabled();
+        mPreference.setSummary(mContext.getResources().getString(
+                R.string.updated_gfx_driver_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 updatedGfxDriverDevOptInApp = Settings.Global.getString(
+                mContext.getContentResolver(), Settings.Global.UPDATED_GFX_DRIVER_DEV_OPT_IN_APP);
+        if (updatedGfxDriverDevOptInApp != null && !updatedGfxDriverDevOptInApp.isEmpty()) {
+            mPreference.setSummary(mContext.getResources().getString(
+                    R.string.updated_gfx_driver_dev_opt_in_app_set,
+                    getAppLabel(updatedGfxDriverDevOptInApp)));
+        } else {
+            mPreference.setSummary(mContext.getResources().getString(
+                    R.string.updated_gfx_driver_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/deviceinfo/DeviceModelPreferenceController.java b/src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java
index 25090dc..a9d0e3f 100644
--- a/src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java
@@ -79,12 +79,7 @@
     }
 
     public static String getDeviceModel() {
-        FutureTask<String> msvSuffixTask = new FutureTask<String>(new Callable<String>() {
-            @Override
-            public String call() {
-                return DeviceInfoUtils.getMsvSuffix();
-            }
-        });
+        FutureTask<String> msvSuffixTask = new FutureTask<>(() -> DeviceInfoUtils.getMsvSuffix());
 
         msvSuffixTask.run();
         try {
diff --git a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
index 37f80b7..8c6c5ae 100644
--- a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
+++ b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
@@ -181,25 +181,6 @@
         controller.updateDeviceName(confirm);
     }
 
-    private static class SummaryProvider implements SummaryLoader.SummaryProvider {
-
-        private final SummaryLoader mSummaryLoader;
-
-        public SummaryProvider(SummaryLoader summaryLoader) {
-            mSummaryLoader = summaryLoader;
-        }
-
-        @Override
-        public void setListening(boolean listening) {
-            if (listening) {
-                mSummaryLoader.setSummary(this, DeviceModelPreferenceController.getDeviceModel());
-            }
-        }
-    }
-
-    public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
-            = (activity, summaryLoader) -> new SummaryProvider(summaryLoader);
-
     /**
      * For Search.
      */
diff --git a/src/com/android/settings/deviceinfo/aboutphone/TopLevelAboutDevicePreferenceController.java b/src/com/android/settings/deviceinfo/aboutphone/TopLevelAboutDevicePreferenceController.java
new file mode 100644
index 0000000..ba28f3a
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/aboutphone/TopLevelAboutDevicePreferenceController.java
@@ -0,0 +1,39 @@
+/*
+ * 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.deviceinfo.aboutphone;
+
+import android.content.Context;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.deviceinfo.DeviceModelPreferenceController;
+
+public class TopLevelAboutDevicePreferenceController extends BasePreferenceController {
+
+    public TopLevelAboutDevicePreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        return DeviceModelPreferenceController.getDeviceModel();
+    }
+}
diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java
index 7f04bde..14a918e 100644
--- a/src/com/android/settings/password/ChooseLockGeneric.java
+++ b/src/com/android/settings/password/ChooseLockGeneric.java
@@ -264,6 +264,10 @@
             return false;
         }
 
+        protected Class<? extends ChooseLockGeneric.InternalActivity> getInternalActivityClass() {
+            return ChooseLockGeneric.InternalActivity.class;
+        }
+
         protected void addHeaderView() {
             if (mForFingerprint) {
                 setHeaderView(R.layout.choose_lock_generic_fingerprint_header);
@@ -291,7 +295,7 @@
                 return true;
             } else if (KEY_SKIP_FINGERPRINT.equals(key) || KEY_SKIP_FACE.equals(key)) {
                 Intent chooseLockGenericIntent = new Intent(getActivity(),
-                    ChooseLockGeneric.InternalActivity.class);
+                    getInternalActivityClass());
                 chooseLockGenericIntent.setAction(getIntent().getAction());
                 // Forward the target user id to  ChooseLockGeneric.
                 chooseLockGenericIntent.putExtra(Intent.EXTRA_USER_ID, mUserId);
diff --git a/src/com/android/settings/password/SetupChooseLockGeneric.java b/src/com/android/settings/password/SetupChooseLockGeneric.java
index 700cc2d..7600104 100644
--- a/src/com/android/settings/password/SetupChooseLockGeneric.java
+++ b/src/com/android/settings/password/SetupChooseLockGeneric.java
@@ -27,6 +27,7 @@
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
+import androidx.fragment.app.Fragment;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceFragmentCompat;
 import androidx.recyclerview.widget.RecyclerView;
@@ -135,6 +136,11 @@
             return true;
         }
 
+        @Override
+        protected Class<? extends ChooseLockGeneric.InternalActivity> getInternalActivityClass() {
+            return SetupChooseLockGeneric.InternalActivity.class;
+        }
+
         /***
          * Disables preferences that are less secure than required quality and shows only secure
          * screen lock options here.
@@ -207,4 +213,25 @@
             return intent;
         }
     }
+
+    public static class InternalActivity extends ChooseLockGeneric.InternalActivity {
+        @Override
+        protected boolean isValidFragment(String fragmentName) {
+            return InternalSetupChooseLockGenericFragment.class.getName().equals(fragmentName);
+        }
+
+        @Override
+        /* package */ Class<? extends Fragment> getFragmentClass() {
+            return InternalSetupChooseLockGenericFragment.class;
+        }
+
+        public static class InternalSetupChooseLockGenericFragment
+                extends ChooseLockGenericFragment {
+            @Override
+            protected boolean canRunBeforeDeviceProvisioned() {
+                return true;
+            }
+        }
+    }
+
 }
diff --git a/src/com/android/settings/print/PrintJobMessagePreferenceController.java b/src/com/android/settings/print/PrintJobMessagePreferenceController.java
new file mode 100644
index 0000000..9573e5d
--- /dev/null
+++ b/src/com/android/settings/print/PrintJobMessagePreferenceController.java
@@ -0,0 +1,47 @@
+/*
+ * 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.print;
+
+import android.content.Context;
+import android.print.PrintJob;
+import android.print.PrintJobInfo;
+import android.text.TextUtils;
+
+public class PrintJobMessagePreferenceController extends PrintJobPreferenceControllerBase {
+
+    public PrintJobMessagePreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    @Override
+    protected void updateUi() {
+        final PrintJob printJob = getPrintJob();
+
+        if (printJob == null) {
+            mFragment.finish();
+            return;
+        }
+
+        if (printJob.isCancelled() || printJob.isCompleted()) {
+            mFragment.finish();
+            return;
+        }
+
+        final PrintJobInfo info = printJob.getInfo();
+        final CharSequence status = info.getStatus(mContext.getPackageManager());
+        mPreference.setVisible(!TextUtils.isEmpty(status));
+        mPreference.setSummary(status);
+    }
+}
diff --git a/src/com/android/settings/print/PrintJobPreferenceController.java b/src/com/android/settings/print/PrintJobPreferenceController.java
new file mode 100644
index 0000000..0eff0d6
--- /dev/null
+++ b/src/com/android/settings/print/PrintJobPreferenceController.java
@@ -0,0 +1,115 @@
+/*
+ * 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.print;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.print.PrintJob;
+import android.print.PrintJobInfo;
+import android.text.format.DateUtils;
+
+import com.android.settings.R;
+
+import java.text.DateFormat;
+
+public class PrintJobPreferenceController extends PrintJobPreferenceControllerBase {
+
+    public PrintJobPreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    @Override
+    protected void updateUi() {
+        final PrintJob printJob = getPrintJob();
+
+        if (printJob == null) {
+            mFragment.finish();
+            return;
+        }
+
+        if (printJob.isCancelled() || printJob.isCompleted()) {
+            mFragment.finish();
+            return;
+        }
+
+        PrintJobInfo info = printJob.getInfo();
+
+        switch (info.getState()) {
+            case PrintJobInfo.STATE_CREATED: {
+                mPreference.setTitle(mContext.getString(
+                        R.string.print_configuring_state_title_template, info.getLabel()));
+            }
+            break;
+            case PrintJobInfo.STATE_QUEUED:
+            case PrintJobInfo.STATE_STARTED: {
+                if (!printJob.getInfo().isCancelling()) {
+                    mPreference.setTitle(mContext.getString(
+                            R.string.print_printing_state_title_template, info.getLabel()));
+                } else {
+                    mPreference.setTitle(mContext.getString(
+                            R.string.print_cancelling_state_title_template, info.getLabel()));
+                }
+            }
+            break;
+
+            case PrintJobInfo.STATE_FAILED: {
+                mPreference.setTitle(mContext.getString(
+                        R.string.print_failed_state_title_template, info.getLabel()));
+            }
+            break;
+
+            case PrintJobInfo.STATE_BLOCKED: {
+                if (!printJob.getInfo().isCancelling()) {
+                    mPreference.setTitle(mContext.getString(
+                            R.string.print_blocked_state_title_template, info.getLabel()));
+                } else {
+                    mPreference.setTitle(mContext.getString(
+                            R.string.print_cancelling_state_title_template, info.getLabel()));
+                }
+            }
+            break;
+        }
+
+        mPreference.setSummary(mContext.getString(R.string.print_job_summary,
+                info.getPrinterName(), DateUtils.formatSameDayTime(
+                        info.getCreationTime(), info.getCreationTime(), DateFormat.SHORT,
+                        DateFormat.SHORT)));
+
+        TypedArray a = mContext.obtainStyledAttributes(new int[]{
+                android.R.attr.colorControlNormal});
+        int tintColor = a.getColor(0, 0);
+        a.recycle();
+
+        switch (info.getState()) {
+            case PrintJobInfo.STATE_QUEUED:
+            case PrintJobInfo.STATE_STARTED: {
+                Drawable icon = mContext.getDrawable(com.android.internal.R.drawable.ic_print);
+                icon.setTint(tintColor);
+                mPreference.setIcon(icon);
+                break;
+            }
+
+            case PrintJobInfo.STATE_FAILED:
+            case PrintJobInfo.STATE_BLOCKED: {
+                Drawable icon = mContext.getDrawable(
+                        com.android.internal.R.drawable.ic_print_error);
+                icon.setTint(tintColor);
+                mPreference.setIcon(icon);
+                break;
+            }
+        }
+    }
+}
diff --git a/src/com/android/settings/print/PrintJobPreferenceControllerBase.java b/src/com/android/settings/print/PrintJobPreferenceControllerBase.java
new file mode 100644
index 0000000..0726a19
--- /dev/null
+++ b/src/com/android/settings/print/PrintJobPreferenceControllerBase.java
@@ -0,0 +1,99 @@
+/*
+ * 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.print;
+
+import android.content.Context;
+import android.print.PrintJob;
+import android.print.PrintJobId;
+import android.print.PrintManager;
+import android.util.Log;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+public abstract class PrintJobPreferenceControllerBase extends BasePreferenceController implements
+        LifecycleObserver, OnStart, OnStop, PrintManager.PrintJobStateChangeListener {
+    private static final String TAG = "PrintJobPrefCtrlBase";
+
+    private static final String EXTRA_PRINT_JOB_ID = "EXTRA_PRINT_JOB_ID";
+
+    private final PrintManager mPrintManager;
+    protected Preference mPreference;
+    protected PrintJobSettingsFragment mFragment;
+    protected PrintJobId mPrintJobId;
+
+    public PrintJobPreferenceControllerBase(Context context, String key) {
+        super(context, key);
+        mPrintManager = ((PrintManager) mContext.getSystemService(
+                Context.PRINT_SERVICE)).getGlobalPrintManagerForUser(mContext.getUserId());
+    }
+
+    @Override
+    public void onStart() {
+        mPrintManager.addPrintJobStateChangeListener(this);
+        updateUi();
+    }
+
+    @Override
+    public void onStop() {
+        mPrintManager.removePrintJobStateChangeListener(this);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public void onPrintJobStateChanged(PrintJobId printJobId) {
+        updateUi();
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(getPreferenceKey());
+    }
+
+    public void init(PrintJobSettingsFragment fragment) {
+        mFragment = fragment;
+        processArguments();
+    }
+
+    protected PrintJob getPrintJob() {
+        return mPrintManager.getPrintJob(mPrintJobId);
+    }
+
+    protected abstract void updateUi();
+
+    private void processArguments() {
+        String printJobId = mFragment.getArguments().getString(EXTRA_PRINT_JOB_ID);
+        if (printJobId == null) {
+            printJobId = mFragment.getActivity().getIntent().getStringExtra(EXTRA_PRINT_JOB_ID);
+
+            if (printJobId == null) {
+                Log.w(TAG, EXTRA_PRINT_JOB_ID + " not set");
+                mFragment.finish();
+                return;
+            }
+        }
+        mPrintJobId = PrintJobId.unflattenFromString(printJobId);
+    }
+}
diff --git a/src/com/android/settings/print/PrintJobSettingsFragment.java b/src/com/android/settings/print/PrintJobSettingsFragment.java
index ba0172b..1d6ff5a 100644
--- a/src/com/android/settings/print/PrintJobSettingsFragment.java
+++ b/src/com/android/settings/print/PrintJobSettingsFragment.java
@@ -17,60 +17,42 @@
 package com.android.settings.print;
 
 import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.print.PrintJob;
-import android.print.PrintJobId;
-import android.print.PrintJobInfo;
-import android.print.PrintManager;
-import android.print.PrintManager.PrintJobStateChangeListener;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.util.Log;
-import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.preference.Preference;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-
-import java.text.DateFormat;
+import com.android.settings.dashboard.DashboardFragment;
 
 /**
  * Fragment for management of a print job.
  */
-public class PrintJobSettingsFragment extends SettingsPreferenceFragment {
-    private static final String LOG_TAG = PrintJobSettingsFragment.class.getSimpleName();
+public class PrintJobSettingsFragment extends DashboardFragment {
+    private static final String TAG = "PrintJobSettingsFragment";
 
     private static final int MENU_ITEM_ID_CANCEL = 1;
     private static final int MENU_ITEM_ID_RESTART = 2;
 
-    private static final String EXTRA_PRINT_JOB_ID = "EXTRA_PRINT_JOB_ID";
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.print_job_settings;
+    }
 
-    private static final String PRINT_JOB_PREFERENCE = "print_job_preference";
-    private static final String PRINT_JOB_MESSAGE_PREFERENCE = "print_job_message_preference";
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
 
-    private final PrintJobStateChangeListener mPrintJobStateChangeListener =
-            new PrintJobStateChangeListener() {
-        @Override
-        public void onPrintJobStateChanged(PrintJobId printJobId) {
-            updateUi();
-        }
-    };
-
-    private PrintManager mPrintManager;
-
-    private Preference mPrintJobPreference;
-    private Preference mMessagePreference;
-
-    private PrintJobId mPrintJobId;
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        use(PrintJobPreferenceController.class).init(this);
+        use(PrintJobMessagePreferenceController.class).init(this);
+    }
 
     @Override
     public int getMetricsCategory() {
@@ -78,53 +60,16 @@
     }
 
     @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-        View view = super.onCreateView(inflater, container, savedInstanceState);
-
-        addPreferencesFromResource(R.xml.print_job_settings);
-        mPrintJobPreference = findPreference(PRINT_JOB_PREFERENCE);
-        mMessagePreference = findPreference(PRINT_JOB_MESSAGE_PREFERENCE);
-
-        mPrintManager = ((PrintManager) getActivity().getSystemService(
-                Context.PRINT_SERVICE)).getGlobalPrintManagerForUser(
-                        getActivity().getUserId());
-
-        getActivity().getActionBar().setTitle(R.string.print_print_job);
-
-        processArguments();
-
-        setHasOptionsMenu(true);
-
-        return  view;
-    }
-
-    @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
         getListView().setEnabled(false);
     }
 
     @Override
-    public void onStart() {
-        super.onStart();
-        mPrintManager.addPrintJobStateChangeListener(
-                mPrintJobStateChangeListener);
-        updateUi();
-    }
-
-    @Override
-    public void onStop() {
-        super.onStop();
-        mPrintManager.removePrintJobStateChangeListener(
-                mPrintJobStateChangeListener);
-    }
-
-    @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         super.onCreateOptionsMenu(menu, inflater);
 
-        PrintJob printJob = getPrintJob();
+        final PrintJob printJob = use(PrintJobPreferenceController.class).getPrintJob();
         if (printJob == null) {
             return;
         }
@@ -144,7 +89,7 @@
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        PrintJob printJob = getPrintJob();
+        final PrintJob printJob = use(PrintJobPreferenceController.class).getPrintJob();
 
         if (printJob != null) {
             switch (item.getItemId()) {
@@ -164,113 +109,4 @@
 
         return super.onOptionsItemSelected(item);
     }
-
-    private void processArguments() {
-        String printJobId = getArguments().getString(EXTRA_PRINT_JOB_ID);
-        if (printJobId == null) {
-            printJobId = getIntent().getStringExtra(EXTRA_PRINT_JOB_ID);
-
-            if (printJobId == null) {
-                Log.w(LOG_TAG, EXTRA_PRINT_JOB_ID + " not set");
-                finish();
-                return;
-            }
-        }
-
-
-        mPrintJobId = PrintJobId.unflattenFromString(printJobId);
-    }
-
-    private PrintJob getPrintJob() {
-        return mPrintManager.getPrintJob(mPrintJobId);
-    }
-
-    private void updateUi() {
-        PrintJob printJob = getPrintJob();
-
-        if (printJob == null) {
-            finish();
-            return;
-        }
-
-        if (printJob.isCancelled() || printJob.isCompleted()) {
-            finish();
-            return;
-        }
-
-        PrintJobInfo info = printJob.getInfo();
-
-        switch (info.getState()) {
-            case PrintJobInfo.STATE_CREATED: {
-                mPrintJobPreference.setTitle(getString(
-                        R.string.print_configuring_state_title_template, info.getLabel()));
-            } break;
-            case PrintJobInfo.STATE_QUEUED:
-            case PrintJobInfo.STATE_STARTED: {
-                if (!printJob.getInfo().isCancelling()) {
-                    mPrintJobPreference.setTitle(getString(
-                            R.string.print_printing_state_title_template, info.getLabel()));
-                } else {
-                    mPrintJobPreference.setTitle(getString(
-                            R.string.print_cancelling_state_title_template, info.getLabel()));
-                }
-            } break;
-
-            case PrintJobInfo.STATE_FAILED: {
-                mPrintJobPreference.setTitle(getString(
-                        R.string.print_failed_state_title_template, info.getLabel()));
-            } break;
-
-            case PrintJobInfo.STATE_BLOCKED: {
-                if (!printJob.getInfo().isCancelling()) {
-                    mPrintJobPreference.setTitle(getString(
-                            R.string.print_blocked_state_title_template, info.getLabel()));
-                } else {
-                    mPrintJobPreference.setTitle(getString(
-                            R.string.print_cancelling_state_title_template, info.getLabel()));
-                }
-            } break;
-        }
-
-        mPrintJobPreference.setSummary(getString(R.string.print_job_summary,
-                info.getPrinterName(), DateUtils.formatSameDayTime(
-                        info.getCreationTime(), info.getCreationTime(), DateFormat.SHORT,
-                        DateFormat.SHORT)));
-
-        TypedArray a = getActivity().obtainStyledAttributes(new int[]{
-                android.R.attr.colorControlNormal});
-        int tintColor = a.getColor(0, 0);
-        a.recycle();
-
-        switch (info.getState()) {
-            case PrintJobInfo.STATE_QUEUED:
-            case PrintJobInfo.STATE_STARTED: {
-                Drawable icon = getActivity().getDrawable(com.android.internal.R.drawable.ic_print);
-                icon.setTint(tintColor);
-                mPrintJobPreference.setIcon(icon);
-                break;
-            }
-
-            case PrintJobInfo.STATE_FAILED:
-            case PrintJobInfo.STATE_BLOCKED: {
-                Drawable icon = getActivity().getDrawable(
-                        com.android.internal.R.drawable.ic_print_error);
-                icon.setTint(tintColor);
-                mPrintJobPreference.setIcon(icon);
-                break;
-            }
-        }
-
-        CharSequence status = info.getStatus(getPackageManager());
-        if (!TextUtils.isEmpty(status)) {
-            if (getPreferenceScreen().findPreference(PRINT_JOB_MESSAGE_PREFERENCE) == null) {
-                getPreferenceScreen().addPreference(mMessagePreference);
-            }
-            mMessagePreference.setSummary(status);
-        } else {
-            getPreferenceScreen().removePreference(mMessagePreference);
-        }
-
-        getActivity().invalidateOptionsMenu();
-    }
 }
diff --git a/tests/robotests/assets/grandfather_not_implementing_index_provider b/tests/robotests/assets/grandfather_not_implementing_index_provider
index f9301a2..479ffee 100644
--- a/tests/robotests/assets/grandfather_not_implementing_index_provider
+++ b/tests/robotests/assets/grandfather_not_implementing_index_provider
@@ -58,6 +58,7 @@
 com.android.settings.notification.ZenModeEventRuleSettings
 com.android.settings.notification.ZenModeScheduleRuleSettings
 com.android.settings.password.ChooseLockGeneric$ChooseLockGenericFragment
+com.android.settings.password.SetupChooseLockGeneric$InternalActivity$InternalSetupChooseLockGenericFragment
 com.android.settings.password.SetupChooseLockGeneric$SetupChooseLockGenericFragment
 com.android.settings.print.PrintJobSettingsFragment
 com.android.settings.print.PrintServiceSettingsFragment
diff --git a/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java b/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java
index b3d929c..039d2e2 100644
--- a/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java
@@ -24,6 +24,10 @@
 
 import android.accounts.Account;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
 import android.widget.ImageView;
 
 import com.android.settings.homepage.SettingsHomepageActivity;
@@ -39,38 +43,45 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowPackageManager;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 public class AvatarViewMixinTest {
     private static final String DUMMY_ACCOUNT = "test@domain.com";
     private static final String DUMMY_DOMAIN = "domain.com";
+    private static final String DUMMY_AUTHORITY = "authority.domain.com";
 
     private Context mContext;
     private ImageView mImageView;
+    private ActivityController mController;
+    private SettingsHomepageActivity mActivity;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
         mImageView = new ImageView(mContext);
+        mController = Robolectric.buildActivity(SettingsHomepageActivity.class).create();
+        mActivity = (SettingsHomepageActivity) mController.get();
     }
 
     @Test
     public void hasAccount_useDefaultAccountData_returnFalse() {
-        final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mContext, mImageView);
+        final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mActivity, mImageView);
         assertThat(avatarViewMixin.hasAccount()).isFalse();
     }
 
     @Test
     @Config(shadows = ShadowAccountFeatureProviderImpl.class)
     public void hasAccount_useShadowAccountData_returnTrue() {
-        final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mContext, mImageView);
+        final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mActivity, mImageView);
         assertThat(avatarViewMixin.hasAccount()).isTrue();
     }
 
     @Test
     public void onStart_configDisabled_doNothing() {
-        final AvatarViewMixin mixin = spy(new AvatarViewMixin(mContext, mImageView));
+        final AvatarViewMixin mixin = spy(new AvatarViewMixin(mActivity, mImageView));
         mixin.onStart();
 
         verify(mixin, never()).hasAccount();
@@ -79,19 +90,45 @@
     @Test
     @Config(qualifiers = "mcc999")
     public void onStart_useMockAvatarViewMixin_shouldBeExecuted() {
-        final AvatarViewMixin mockAvatar = spy(new AvatarViewMixin(mContext, mImageView));
+        final AvatarViewMixin mockAvatar = spy(new AvatarViewMixin(mActivity, mImageView));
 
-        final ActivityController controller = Robolectric.buildActivity(
-                SettingsHomepageActivity.class).create();
-        final SettingsHomepageActivity settingsHomepageActivity =
-                (SettingsHomepageActivity) controller.get();
-        settingsHomepageActivity.getLifecycle().addObserver(mockAvatar);
-        controller.start();
+        mActivity.getLifecycle().addObserver(mockAvatar);
+        mController.start();
 
         verify(mockAvatar).hasAccount();
     }
 
-    @Implements(AccountFeatureProviderImpl.class)
+    @Test
+    public void queryProviderAuthority_useShadowPackagteManager_returnNull() {
+        final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mActivity, mImageView);
+
+        assertThat(avatarViewMixin.queryProviderAuthority()).isNull();
+    }
+
+    @Test
+    public void queryProviderAuthority_useNewShadowPackagteManager_returnAuthority() {
+        final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mActivity, mImageView);
+        ShadowPackageManager shadowPackageManager = Shadow.extract(mContext.getPackageManager());
+        final PackageInfo accountProvider = new PackageInfo();
+        accountProvider.packageName = "test.pkg";
+        accountProvider.applicationInfo = new ApplicationInfo();
+        accountProvider.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
+        accountProvider.applicationInfo.packageName = accountProvider.packageName;
+        accountProvider.providers = new ProviderInfo[1];
+        accountProvider.providers[0] = new ProviderInfo();
+        accountProvider.providers[0].authority = DUMMY_AUTHORITY;
+        accountProvider.providers[0].packageName = accountProvider.packageName;
+        accountProvider.providers[0].name = "test.class";
+        accountProvider.providers[0].applicationInfo = accountProvider.applicationInfo;
+
+        final ResolveInfo resolveInfo = new ResolveInfo();
+        resolveInfo.providerInfo = accountProvider.providers[0];
+        shadowPackageManager.addResolveInfoForIntent(AvatarViewMixin.INTENT_GET_ACCOUNT_DATA,
+                resolveInfo);
+        assertThat(avatarViewMixin.queryProviderAuthority()).isEqualTo(DUMMY_AUTHORITY);
+    }
+
+    @Implements(value = AccountFeatureProviderImpl.class)
     public static class ShadowAccountFeatureProviderImpl {
 
         @Implementation
diff --git a/tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java
new file mode 100644
index 0000000..e6e8cb9
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.development;
+
+import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
+
+import static com.android.settings.development.DesktopModePreferenceController.SETTING_VALUE_OFF;
+import static com.android.settings.development.DesktopModePreferenceController.SETTING_VALUE_ON;
+
+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.content.Context;
+import android.provider.Settings;
+
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class DesktopModePreferenceControllerTest {
+
+    private static final String ENG_BUILD_TYPE = "eng";
+    private static final String USER_BUILD_TYPE = "user";
+
+    @Mock
+    private SwitchPreference mPreference;
+    @Mock
+    private PreferenceScreen mScreen;
+
+    private Context mContext;
+    private DesktopModePreferenceController mController;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mController = new DesktopModePreferenceController(mContext);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+        mController.displayPreference(mScreen);
+    }
+
+    @Test
+    public void isAvailable_engBuild_shouldBeTrue() {
+        mController = spy(mController);
+        doReturn(ENG_BUILD_TYPE).when(mController).getBuildType();
+
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void isAvaiable_userBuild_shouldBeTrue() {
+        mController = spy(mController);
+        doReturn(USER_BUILD_TYPE).when(mController).getBuildType();
+
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void onPreferenceChange_switchEnabled_shouldEnableFreeformWindows() {
+        mController.onPreferenceChange(mPreference, true /* new value */);
+
+        final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+                DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, -1 /* default */);
+        assertThat(mode).isEqualTo(SETTING_VALUE_ON);
+    }
+
+    @Test
+    public void onPreferenceChange_switchDisabled_shouldDisableFreeformWindows() {
+        mController.onPreferenceChange(mPreference, false /* new value */);
+
+        final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+                DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, -1 /* default */);
+        assertThat(mode).isEqualTo(SETTING_VALUE_OFF);
+    }
+
+    @Test
+    public void updateState_settingEnabled_preferenceShouldBeChecked() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, SETTING_VALUE_ON);
+
+        mController.updateState(mPreference);
+
+        verify(mPreference).setChecked(true);
+    }
+
+    @Test
+    public void updateState_settingDisabled_preferenceShouldNotBeChecked() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, SETTING_VALUE_OFF);
+
+        mController.updateState(mPreference);
+
+        verify(mPreference).setChecked(false);
+    }
+
+    @Test
+    public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() {
+        mController.onDeveloperOptionsSwitchDisabled();
+
+        final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+                DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, -1 /* default */);
+        assertThat(mode).isEqualTo(SETTING_VALUE_OFF);
+        verify(mPreference).setEnabled(false);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/development/FreeformWindowsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/FreeformWindowsPreferenceControllerTest.java
index b58f756..08fb23e 100644
--- a/tests/robotests/src/com/android/settings/development/FreeformWindowsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/FreeformWindowsPreferenceControllerTest.java
@@ -19,7 +19,6 @@
 import static com.android.settings.development.FreeformWindowsPreferenceController
         .SETTING_VALUE_OFF;
 import static com.android.settings.development.FreeformWindowsPreferenceController.SETTING_VALUE_ON;
-import static com.android.settings.development.FreeformWindowsPreferenceController.USER_BUILD_TYPE;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -47,6 +46,7 @@
 public class FreeformWindowsPreferenceControllerTest {
 
     private static final String ENG_BUILD_TYPE = "eng";
+    private static final String USER_BUILD_TYPE = "user";
 
     @Mock
     private SwitchPreference mPreference;
@@ -74,11 +74,11 @@
     }
 
     @Test
-    public void isAvaiable_userBuild_shouldBeFalse() {
+    public void isAvaiable_userBuild_shouldBeTrue() {
         mController = spy(mController);
         doReturn(USER_BUILD_TYPE).when(mController).getBuildType();
 
-        assertThat(mController.isAvailable()).isFalse();
+        assertThat(mController.isAvailable()).isTrue();
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/development/UpdatedGfxDriverDevOptInPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/UpdatedGfxDriverDevOptInPreferenceControllerTest.java
new file mode 100644
index 0000000..3071912
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/UpdatedGfxDriverDevOptInPreferenceControllerTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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_UPDATED_GFX_DRIVER_DEV_OPT_IN_APP;
+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 com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class UpdatedGfxDriverDevOptInPreferenceControllerTest {
+
+    @Mock
+    private PreferenceScreen mPreferenceScreen;
+    @Mock
+    private DevelopmentSettingsDashboardFragment mFragment;
+
+    private Context mContext;
+    private Preference mPreference;
+    private UpdatedGfxDriverDevOptInPreferenceController mController;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mController = spy(new UpdatedGfxDriverDevOptInPreferenceController(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);
+        final String preferenceKey = mController.getPreferenceKey();
+        doReturn(activityStartIntent).when(mController).getActivityStartIntent();
+        mController.handlePreferenceTreeClick(mPreference);
+
+        verify(mFragment).startActivityForResult(activityStartIntent,
+                REQUEST_CODE_UPDATED_GFX_DRIVER_DEV_OPT_IN_APP);
+    }
+
+    @Test
+    public void updateState_foobarAppSelected_shouldUpdateSummaryWithUpdatedDriverDevOptInAppLabel() {
+        final String selectedApp = "foobar";
+        final ContentResolver contentResolver = mContext.getContentResolver();
+        Settings.Global.putString(contentResolver,
+                Settings.Global.UPDATED_GFX_DRIVER_DEV_OPT_IN_APP, selectedApp);
+        mController.updateState(mPreference);
+
+        assertThat(mPreference.getSummary()).isEqualTo(mContext.getString(R.string.updated_gfx_driver_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.UPDATED_GFX_DRIVER_DEV_OPT_IN_APP, selectedApp);
+        mController.updateState(mPreference);
+
+        assertThat(mPreference.getSummary()).isEqualTo(mContext.getString(R.string.updated_gfx_driver_dev_opt_in_app_not_set));
+    }
+
+    @Test
+    public void onActivityResult_foobarAppSelected_shouldUpdateSummaryWithUpdatedDriverDevOptInLabel() {
+        Intent activityResultIntent = new Intent(mContext, AppPicker.class);
+        final String appLabel = "foobar";
+        activityResultIntent.setAction(appLabel);
+        final boolean result = mController
+            .onActivityResult(REQUEST_CODE_UPDATED_GFX_DRIVER_DEV_OPT_IN_APP, Activity.RESULT_OK,
+                    activityResultIntent);
+
+        assertThat(result).isTrue();
+        assertThat(mPreference.getSummary()).isEqualTo(mContext.getString(R.string.updated_gfx_driver_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.updated_gfx_driver_dev_opt_in_app_not_set));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/deviceinfo/DeviceNameWarningDialogTest.java b/tests/robotests/src/com/android/settings/deviceinfo/aboutphone/DeviceNameWarningDialogTest.java
similarity index 72%
rename from tests/robotests/src/com/android/settings/deviceinfo/deviceinfo/DeviceNameWarningDialogTest.java
rename to tests/robotests/src/com/android/settings/deviceinfo/aboutphone/DeviceNameWarningDialogTest.java
index 0be0ac2..6ea36a0 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/deviceinfo/DeviceNameWarningDialogTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/aboutphone/DeviceNameWarningDialogTest.java
@@ -1,4 +1,20 @@
-package com.android.settings.deviceinfo.deviceinfo;
+/*
+ * 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.deviceinfo.aboutphone;
 
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -6,8 +22,6 @@
 
 import android.content.DialogInterface;
 
-import com.android.settings.deviceinfo.aboutphone.DeviceNameWarningDialog;
-import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/MyDeviceInfoFragmentTest.java b/tests/robotests/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragmentTest.java
similarity index 97%
rename from tests/robotests/src/com/android/settings/deviceinfo/MyDeviceInfoFragmentTest.java
rename to tests/robotests/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragmentTest.java
index 4a741cf..e304a1e 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/MyDeviceInfoFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragmentTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.deviceinfo;
+package com.android.settings.deviceinfo.aboutphone;
 
 import static com.android.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY;
 
@@ -35,7 +35,7 @@
 import androidx.fragment.app.FragmentActivity;
 import androidx.preference.PreferenceScreen;
 
-import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
+import com.android.settings.deviceinfo.BuildNumberPreferenceController;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/aboutphone/TopLevelAboutDevicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/aboutphone/TopLevelAboutDevicePreferenceControllerTest.java
new file mode 100644
index 0000000..ae3007c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/aboutphone/TopLevelAboutDevicePreferenceControllerTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.deviceinfo.aboutphone;
+
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.os.Build;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class TopLevelAboutDevicePreferenceControllerTest {
+
+    private Context mContext;
+    private TopLevelAboutDevicePreferenceController mController;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mController = new TopLevelAboutDevicePreferenceController(mContext, "test_key");
+    }
+
+    @Test
+    public void getAvailabilityState_shouldBeAvailable() {
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+    }
+
+    @Test
+    public void getSummary_shouldReturnDeviceModel() {
+        assertThat(mController.getSummary().toString()).isEqualTo(Build.MODEL);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/print/PrintJobMessagePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/print/PrintJobMessagePreferenceControllerTest.java
new file mode 100644
index 0000000..50dd38b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/print/PrintJobMessagePreferenceControllerTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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.print;
+
+import static androidx.lifecycle.Lifecycle.Event.ON_START;
+import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.print.PrintJob;
+import android.print.PrintJobInfo;
+import android.print.PrintManager;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class PrintJobMessagePreferenceControllerTest {
+    private static final String PREF_KEY = "print_job_message_preference";
+
+    @Mock
+    private PrintManager mPrintManager;
+    @Mock
+    private PrintJob mPrintJob;
+    @Mock
+    private PrintJobInfo mPrintJobInfo;
+    @Mock
+    private PreferenceScreen mScreen;
+
+    private Context mContext;
+    private PrintJobMessagePreferenceController mController;
+    private Preference mPreference;
+    private LifecycleOwner mLifecycleOwner;
+    private Lifecycle mLifecycle;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        mPreference = new Preference(mContext);
+        when(mContext.getSystemService(Context.PRINT_SERVICE)).thenReturn(mPrintManager);
+        when(mPrintManager.getGlobalPrintManagerForUser(anyInt())).thenReturn(mPrintManager);
+        when(mPrintManager.getPrintJob(anyObject())).thenReturn(mPrintJob);
+        when(mPrintJob.getInfo()).thenReturn(mPrintJobInfo);
+        mController = new PrintJobMessagePreferenceController(mContext, PREF_KEY);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+        mController.displayPreference(mScreen);
+        mLifecycleOwner = () -> mLifecycle;
+        mLifecycle = new Lifecycle(mLifecycleOwner);
+        mLifecycle.addObserver(mController);
+    }
+
+    @Test
+    public void onStartStop_shouldRegisterPrintStateListener() {
+        mLifecycle.handleLifecycleEvent(ON_START);
+        mLifecycle.handleLifecycleEvent(ON_STOP);
+
+        verify(mPrintManager).addPrintJobStateChangeListener(mController);
+        verify(mPrintManager).removePrintJobStateChangeListener(mController);
+    }
+
+    @Test
+    public void updateUi_visiblePreference() {
+        when(mPrintJobInfo.getStatus(anyObject())).thenReturn("TestPrint");
+        mLifecycle.handleLifecycleEvent(ON_START);
+
+        assertThat(mPreference.isVisible()).isTrue();
+
+        mLifecycle.handleLifecycleEvent(ON_STOP);
+    }
+
+    @Test
+    public void updateUi_invisiblePreference() {
+        when(mPrintJobInfo.getStatus(anyObject())).thenReturn(null);
+        mLifecycle.handleLifecycleEvent(ON_START);
+
+        assertThat(mPreference.isVisible()).isFalse();
+
+        mLifecycle.handleLifecycleEvent(ON_STOP);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/print/PrintJobPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/print/PrintJobPreferenceControllerTest.java
new file mode 100644
index 0000000..fc92eb3
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/print/PrintJobPreferenceControllerTest.java
@@ -0,0 +1,189 @@
+/*
+ * 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.print;
+
+import static androidx.lifecycle.Lifecycle.Event.ON_START;
+import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.print.PrintJob;
+import android.print.PrintJobInfo;
+import android.print.PrintManager;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class PrintJobPreferenceControllerTest {
+    private static final String PREF_KEY = "print_job_preference";
+
+    @Mock
+    private PrintManager mPrintManager;
+    @Mock
+    private PrintJob mPrintJob;
+    @Mock
+    private PrintJobInfo mPrintJobInfo;
+    @Mock
+    private PreferenceScreen mScreen;
+
+    private Context mContext;
+    private LifecycleOwner mLifecycleOwner;
+    private Lifecycle mLifecycle;
+    private PrintJobPreferenceController mController;
+    private Preference mPreference;
+    private String mTestLabel;
+
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        mPreference = new Preference(mContext);
+        mTestLabel = "PrintTest";
+        when(mContext.getSystemService(Context.PRINT_SERVICE)).thenReturn(mPrintManager);
+        when(mPrintManager.getGlobalPrintManagerForUser(anyInt())).thenReturn(mPrintManager);
+        when(mPrintManager.getPrintJob(anyObject())).thenReturn(mPrintJob);
+        when(mPrintJob.getInfo()).thenReturn(mPrintJobInfo);
+        mController = new PrintJobPreferenceController(mContext, PREF_KEY);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+        when(mPrintJobInfo.getLabel()).thenReturn(mTestLabel);
+        mController.displayPreference(mScreen);
+        mLifecycleOwner = () -> mLifecycle;
+        mLifecycle = new Lifecycle(mLifecycleOwner);
+        mLifecycle.addObserver(mController);
+    }
+
+    @Test
+    public void onStartStop_shouldRegisterPrintStateListener() {
+        mLifecycle.handleLifecycleEvent(ON_START);
+        mLifecycle.handleLifecycleEvent(ON_STOP);
+
+        verify(mPrintManager).addPrintJobStateChangeListener(mController);
+        verify(mPrintManager).removePrintJobStateChangeListener(mController);
+    }
+
+    @Test
+    public void updateUi_jobState_STATE_CREATED() {
+        when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_CREATED);
+
+        mController.onStart();
+        String title = mContext.getString(
+                R.string.print_configuring_state_title_template, mTestLabel);
+
+        assertThat(mPreference.getTitle()).isEqualTo(title);
+    }
+
+    @Test
+    public void updateUi_jobState_STATE_QUEUED() {
+        when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_QUEUED);
+
+        mController.onStart();
+        String title = mContext.getString(
+                R.string.print_printing_state_title_template, mTestLabel);
+
+        assertThat(mPreference.getTitle()).isEqualTo(title);
+    }
+
+    @Test
+    public void updateUi_jobState_STATE_STARTED() {
+        when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_STARTED);
+
+        mController.onStart();
+        String title = mContext.getString(
+                R.string.print_printing_state_title_template, mTestLabel);
+
+        assertThat(mPreference.getTitle()).isEqualTo(title);
+    }
+
+    @Test
+    public void updateUi_jobState_STATE_QUEUED_and_jobInfo_CANCELLING() {
+        when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_QUEUED);
+        when(mPrintJobInfo.isCancelling()).thenReturn(true);
+
+        mController.onStart();
+        String title = mContext.getString(
+                R.string.print_cancelling_state_title_template, mTestLabel);
+
+        assertThat(mPreference.getTitle()).isEqualTo(title);
+    }
+
+    @Test
+    public void updateUi_jobState_STATE_STARTED_and_jobInfo_CANCELLING() {
+        when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_STARTED);
+        when(mPrintJobInfo.isCancelling()).thenReturn(true);
+
+        mController.onStart();
+        String title = mContext.getString(
+                R.string.print_cancelling_state_title_template, mTestLabel);
+
+        assertThat(mPreference.getTitle()).isEqualTo(title);
+    }
+
+    @Test
+    public void updateUi_jobState_STATE_FAILED() {
+        when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_FAILED);
+
+        mController.onStart();
+        String title = mContext.getString(
+                R.string.print_failed_state_title_template, mTestLabel);
+
+        assertThat(mPreference.getTitle()).isEqualTo(title);
+    }
+
+    @Test
+    public void updateUi_jobState_STATE_BLOCKED() {
+        when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_BLOCKED);
+
+        mController.onStart();
+        String title = mContext.getString(
+                R.string.print_blocked_state_title_template, mTestLabel);
+
+        assertThat(mPreference.getTitle()).isEqualTo(title);
+    }
+
+    @Test
+    public void updateUi_jobState_STATE_BLOCKED_and_jobInfo_CANCELLING() {
+        when(mPrintJobInfo.getState()).thenReturn(PrintJobInfo.STATE_BLOCKED);
+        when(mPrintJobInfo.isCancelling()).thenReturn(true);
+
+        mController.onStart();
+        String title = mContext.getString(
+                R.string.print_cancelling_state_title_template, mTestLabel);
+
+        assertThat(mPreference.getTitle()).isEqualTo(title);
+    }
+}
diff --git a/tests/uitests/assets/search_results_list b/tests/uitests/assets/search_results_list
index a8bf6f5..6f7c513 100644
--- a/tests/uitests/assets/search_results_list
+++ b/tests/uitests/assets/search_results_list
@@ -235,6 +235,7 @@
 Force RTL layout direction;force_rtl_layout_all_locales
 Force activities to be resizable;force_resizable_activities
 Force allow apps on external;force_allow_on_external
+Force desktop mode;force_desktop_mode_on_external_displays
 Force full GNSS measurements;enable_gnss_raw_meas_full_tracking
 Free up space;storage_settings_free_space
 Games;pref_games
diff --git a/tests/unit/src/com/android/settings/password/SetupChooseLockGenericTest.java b/tests/unit/src/com/android/settings/password/SetupChooseLockGenericTest.java
new file mode 100644
index 0000000..ce3d08f
--- /dev/null
+++ b/tests/unit/src/com/android/settings/password/SetupChooseLockGenericTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.password;
+
+import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+import static android.support.test.InstrumentationRegistry.getTargetContext;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.provider.Settings;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
+import android.support.test.runner.lifecycle.Stage;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiSelector;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collection;
+
+/**
+ * Tests for {@link SetupChooseLockGenericTest}
+ *
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class SetupChooseLockGenericTest {
+
+    private UiDevice mDevice;
+    private Context mContext;
+
+    @Before
+    public void setUp() throws Exception {
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        mContext = getInstrumentation().getTargetContext();
+        Settings.Global.putInt(
+            mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0);
+    }
+
+    @After
+    public void tearDown() {
+        Settings.Global.putInt(
+            mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
+    }
+
+    @Test
+    public void clickSkipFigerprintPreference_deviceNotProvisioned_shouldBeAbleToProceed()
+            throws Throwable {
+        final Intent newPasswordIntent =
+            new Intent(getTargetContext(), SetupChooseLockGeneric.class)
+            .putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true)
+            .setAction(ACTION_SET_NEW_PASSWORD)
+            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+
+        getInstrumentation().getContext().startActivity(newPasswordIntent);
+        mDevice.waitForIdle();
+        mDevice.findObject(new UiSelector().textContains("Continue without ")).click();
+
+        final Activity activity = getCurrentActivity();
+        assertThat(activity).isInstanceOf(SetupChooseLockGeneric.InternalActivity.class);
+    }
+
+    private Activity getCurrentActivity() throws Throwable {
+        getInstrumentation().waitForIdleSync();
+        final Activity[] activity = new Activity[1];
+        getInstrumentation().runOnMainSync(() -> {
+            Collection<Activity> activities = ActivityLifecycleMonitorRegistry.getInstance()
+                    .getActivitiesInStage(Stage.RESUMED);
+            activity[0] = activities.iterator().next();
+        });
+        return activity[0];
+    }
+
+}