Merge "Revert "Add a new logger for StatsLog""
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e93e56d..e86917c 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>
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 49018f8..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
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/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/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 5663d1e..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));
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/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/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/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/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];
+    }
+
+}