Add tablayout for work/personal profile

- Add Tablayout in ProfileSelectFragment
- Add AccountWorkProfileDashboardFragment inherited from
ProfileSelectFragment
- Add ProfileFragmentBridge to convert AccountDashboardFragment
to AccountProfileSelectFragment
- Use flag settings_work_profile to guard the new fragment

Bug: 141601408
Test: Settings->developer options->feature flags->
turn settings_work_profile on/off, then go to settings->account
to see if UI is changed.

Change-Id: Ifb32c22cdeab69c51517664081cacf4a401c46a1
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 9270a5a..4d813d5 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -35,6 +35,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.text.TextUtils;
+import android.util.FeatureFlagUtils;
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
@@ -52,11 +53,13 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.settings.Settings.WifiSettingsActivity;
 import com.android.settings.applications.manageapplications.ManageApplications;
+import com.android.settings.core.FeatureFlags;
 import com.android.settings.core.OnActivityResultListener;
 import com.android.settings.core.SettingsBaseActivity;
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.core.gateway.SettingsGateway;
 import com.android.settings.dashboard.DashboardFeatureProvider;
+import com.android.settings.dashboard.profileselector.ProfileFragmentBridge;
 import com.android.settings.homepage.TopLevelSettings;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.wfd.WifiDisplaySettings;
@@ -565,7 +568,15 @@
             throw new IllegalArgumentException("Invalid fragment for this activity: "
                     + fragmentName);
         }
-        Fragment f = Fragment.instantiate(this, fragmentName, args);
+        Fragment f = null;
+        if (FeatureFlagUtils.isEnabled(this, FeatureFlags.PERSONAL_WORK_PROFILE)
+                && UserManager.get(this).getUserProfiles().size() > 1
+                && ProfileFragmentBridge.FRAGMENT_MAP.get(fragmentName) != null) {
+            f = Fragment.instantiate(this, ProfileFragmentBridge.FRAGMENT_MAP.get(fragmentName),
+                    args);
+        } else {
+            f = Fragment.instantiate(this, fragmentName, args);
+        }
         FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
         transaction.replace(R.id.main_content, f);
         if (titleResId > 0) {
diff --git a/src/com/android/settings/accounts/AccountDashboardFragment.java b/src/com/android/settings/accounts/AccountDashboardFragment.java
index 83f071a..46c08ab 100644
--- a/src/com/android/settings/accounts/AccountDashboardFragment.java
+++ b/src/com/android/settings/accounts/AccountDashboardFragment.java
@@ -23,6 +23,7 @@
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.users.AutoSyncDataPreferenceController;
 import com.android.settings.users.AutoSyncPersonalDataPreferenceController;
@@ -70,7 +71,8 @@
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
 
         final AccountPreferenceController accountPrefController =
-                new AccountPreferenceController(context, parent, authorities);
+                new AccountPreferenceController(context, parent, authorities,
+                        ProfileSelectFragment.ALL);
         if (parent != null) {
             parent.getSettingsLifecycle().addObserver(accountPrefController);
         }
diff --git a/src/com/android/settings/accounts/AccountPersonalDashboardFragment.java b/src/com/android/settings/accounts/AccountPersonalDashboardFragment.java
new file mode 100644
index 0000000..ac426a2
--- /dev/null
+++ b/src/com/android/settings/accounts/AccountPersonalDashboardFragment.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accounts;
+
+import static android.provider.Settings.EXTRA_AUTHORITIES;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
+import com.android.settings.users.AutoSyncDataPreferenceController;
+import com.android.settings.users.AutoSyncPersonalDataPreferenceController;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.search.SearchIndexable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Account Setting page for personal profile.
+ */
+@SearchIndexable
+public class AccountPersonalDashboardFragment extends DashboardFragment {
+
+    private static final String TAG = "AccountPersonalFrag";
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.ACCOUNT;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.accounts_personal_dashboard_settings;
+    }
+
+    @Override
+    public int getHelpResource() {
+        return R.string.help_url_user_and_account_dashboard;
+    }
+
+    @Override
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        final String[] authorities = getIntent().getStringArrayExtra(EXTRA_AUTHORITIES);
+        return buildPreferenceControllers(context, this /* parent */, authorities);
+    }
+
+    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
+            SettingsPreferenceFragment parent, String[] authorities) {
+        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+
+        final AccountPreferenceController accountPrefController =
+                new AccountPreferenceController(context, parent, authorities,
+                        ProfileSelectFragment.PERSONAL);
+        if (parent != null) {
+            parent.getSettingsLifecycle().addObserver(accountPrefController);
+        }
+        controllers.add(accountPrefController);
+        controllers.add(new AutoSyncDataPreferenceController(context, parent));
+        controllers.add(new AutoSyncPersonalDataPreferenceController(context, parent));
+        return controllers;
+    }
+
+    // TODO: b/141601408. After featureFlag settings_work_profile is launched, unmark this
+//    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+//            new BaseSearchIndexProvider(R.xml.accounts_personal_dashboard_settings) {
+//
+//                @Override
+//                public List<AbstractPreferenceController> createPreferenceControllers(
+//                        Context context) {
+//                    return buildPreferenceControllers(
+//                            context, null /* parent */, null /* authorities*/);
+//                }
+//            };
+}
diff --git a/src/com/android/settings/accounts/AccountPreferenceController.java b/src/com/android/settings/accounts/AccountPreferenceController.java
index 5c930e2..8e3e702 100644
--- a/src/com/android/settings/accounts/AccountPreferenceController.java
+++ b/src/com/android/settings/accounts/AccountPreferenceController.java
@@ -53,8 +53,8 @@
 import com.android.settings.Utils;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
 import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.search.SearchIndexableRaw;
 import com.android.settingslib.RestrictedPreference;
 import com.android.settingslib.accounts.AuthenticatorHelper;
 import com.android.settingslib.core.AbstractPreferenceController;
@@ -62,6 +62,7 @@
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
+import com.android.settingslib.search.SearchIndexableRaw;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -81,8 +82,8 @@
 
     private UserManager mUm;
     private SparseArray<ProfileData> mProfiles = new SparseArray<ProfileData>();
-    private ManagedProfileBroadcastReceiver mManagedProfileBroadcastReceiver
-                = new ManagedProfileBroadcastReceiver();
+    private ManagedProfileBroadcastReceiver mManagedProfileBroadcastReceiver =
+            new ManagedProfileBroadcastReceiver();
     private Preference mProfileNotAvailablePreference;
     private String[] mAuthorities;
     private int mAuthoritiesCount = 0;
@@ -90,6 +91,7 @@
     private int mAccountProfileOrder = ORDER_ACCOUNT_PROFILES;
     private AccountRestrictionHelper mHelper;
     private MetricsFeatureProvider mMetricsFeatureProvider;
+    private @ProfileSelectFragment.ProfileType int mType;
 
     /**
      * Holds data related to the accounts belonging to one profile.
@@ -130,13 +132,14 @@
     }
 
     public AccountPreferenceController(Context context, SettingsPreferenceFragment parent,
-        String[] authorities) {
-        this(context, parent, authorities, new AccountRestrictionHelper(context));
+            String[] authorities, @ProfileSelectFragment.ProfileType int type) {
+        this(context, parent, authorities, new AccountRestrictionHelper(context), type);
     }
 
     @VisibleForTesting
     AccountPreferenceController(Context context, SettingsPreferenceFragment parent,
-        String[] authorities, AccountRestrictionHelper helper) {
+            String[] authorities, AccountRestrictionHelper helper,
+            @ProfileSelectFragment.ProfileType int type) {
         super(context);
         mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
         mAuthorities = authorities;
@@ -147,6 +150,7 @@
         final FeatureFactory featureFactory = FeatureFactory.getFactory(mContext);
         mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider();
         mHelper = helper;
+        mType = type;
     }
 
     @Override
@@ -186,7 +190,7 @@
                 }
                 if (userInfo.isManagedProfile()) {
                     if (!mHelper.hasBaseUserRestriction(DISALLOW_REMOVE_MANAGED_PROFILE,
-                        UserHandle.myUserId())) {
+                            UserHandle.myUserId())) {
                         SearchIndexableRaw data = new SearchIndexableRaw(mContext);
                         data.title = res.getString(R.string.remove_managed_profile_label);
                         data.screenTitle = screenTitle;
@@ -277,7 +281,13 @@
             List<UserInfo> profiles = mUm.getProfiles(UserHandle.myUserId());
             final int profilesCount = profiles.size();
             for (int i = 0; i < profilesCount; i++) {
-                updateProfileUi(profiles.get(i));
+                if (profiles.get(i).isManagedProfile()
+                        && (mType & ProfileSelectFragment.WORK) != 0) {
+                    updateProfileUi(profiles.get(i));
+                } else if (!profiles.get(i).isManagedProfile()
+                        && (mType & ProfileSelectFragment.PERSONAL) != 0) {
+                    updateProfileUi(profiles.get(i));
+                }
             }
         }
         cleanUpPreferences();
@@ -302,7 +312,7 @@
             if (userInfo.isEnabled()) {
                 // recreate the authentication helper to refresh the list of enabled accounts
                 data.authenticatorHelper =
-                    new AuthenticatorHelper(mContext, userInfo.getUserHandle(), this);
+                        new AuthenticatorHelper(mContext, userInfo.getUserHandle(), this);
             }
             return;
         }
@@ -310,27 +320,28 @@
         final ProfileData profileData = new ProfileData();
         profileData.userInfo = userInfo;
         AccessiblePreferenceCategory preferenceGroup =
-            mHelper.createAccessiblePreferenceCategory(mParent.getPreferenceManager().getContext());
+                mHelper.createAccessiblePreferenceCategory(
+                        mParent.getPreferenceManager().getContext());
         preferenceGroup.setOrder(mAccountProfileOrder++);
         if (isSingleProfile()) {
             preferenceGroup.setTitle(context.getString(R.string.account_for_section_header,
                     BidiFormatter.getInstance().unicodeWrap(userInfo.name)));
             preferenceGroup.setContentDescription(
-                mContext.getString(R.string.account_settings));
+                    mContext.getString(R.string.account_settings));
         } else if (userInfo.isManagedProfile()) {
             preferenceGroup.setTitle(R.string.category_work);
             String workGroupSummary = getWorkGroupSummary(context, userInfo);
             preferenceGroup.setSummary(workGroupSummary);
             preferenceGroup.setContentDescription(
-                mContext.getString(R.string.accessibility_category_work, workGroupSummary));
+                    mContext.getString(R.string.accessibility_category_work, workGroupSummary));
             profileData.removeWorkProfilePreference = newRemoveWorkProfilePreference();
             mHelper.enforceRestrictionOnPreference(profileData.removeWorkProfilePreference,
-                DISALLOW_REMOVE_MANAGED_PROFILE, UserHandle.myUserId());
+                    DISALLOW_REMOVE_MANAGED_PROFILE, UserHandle.myUserId());
             profileData.managedProfilePreference = newManagedProfileSettings();
         } else {
             preferenceGroup.setTitle(R.string.category_personal);
             preferenceGroup.setContentDescription(
-                mContext.getString(R.string.accessibility_category_personal));
+                    mContext.getString(R.string.accessibility_category_personal));
         }
         final PreferenceScreen screen = mParent.getPreferenceScreen();
         if (screen != null) {
@@ -342,14 +353,14 @@
                     userInfo.getUserHandle(), this);
             profileData.addAccountPreference = newAddAccountPreference();
             mHelper.enforceRestrictionOnPreference(profileData.addAccountPreference,
-                DISALLOW_MODIFY_ACCOUNTS, userInfo.id);
+                    DISALLOW_MODIFY_ACCOUNTS, userInfo.id);
         }
         mProfiles.put(userInfo.id, profileData);
     }
 
     private RestrictedPreference newAddAccountPreference() {
         RestrictedPreference preference =
-            new RestrictedPreference(mParent.getPreferenceManager().getContext());
+                new RestrictedPreference(mParent.getPreferenceManager().getContext());
         preference.setTitle(R.string.add_account_label);
         preference.setIcon(R.drawable.ic_add_24dp);
         preference.setOnPreferenceClickListener(this);
@@ -359,7 +370,7 @@
 
     private RestrictedPreference newRemoveWorkProfilePreference() {
         RestrictedPreference preference = new RestrictedPreference(
-            mParent.getPreferenceManager().getContext());
+                mParent.getPreferenceManager().getContext());
         preference.setTitle(R.string.remove_managed_profile_label);
         preference.setIcon(R.drawable.ic_delete);
         preference.setOnPreferenceClickListener(this);
@@ -393,7 +404,7 @@
             return;
         }
         final int count = mProfiles.size();
-        for (int i = count-1; i >= 0; i--) {
+        for (int i = count - 1; i >= 0; i--) {
             final ProfileData data = mProfiles.valueAt(i);
             if (data.pendingRemoval) {
                 screen.removePreference(data.preferenceGroup);
@@ -449,7 +460,7 @@
             }
             for (String key : preferenceToRemove.keySet()) {
                 profileData.preferenceGroup.removePreference(
-                    profileData.accountPreferences.get(key));
+                        profileData.accountPreferences.get(key));
                 profileData.accountPreferences.remove(key);
             }
         } else {
@@ -457,7 +468,7 @@
             // Put a label instead of the accounts list
             if (mProfileNotAvailablePreference == null) {
                 mProfileNotAvailablePreference =
-                    new Preference(mParent.getPreferenceManager().getContext());
+                        new Preference(mParent.getPreferenceManager().getContext());
             }
             mProfileNotAvailablePreference.setEnabled(false);
             mProfileNotAvailablePreference.setIcon(R.drawable.empty_icon);
@@ -507,26 +518,26 @@
                     continue;
                 }
                 final ArrayList<String> auths =
-                    helper.getAuthoritiesForAccountType(account.type);
+                        helper.getAuthoritiesForAccountType(account.type);
                 if (!AccountRestrictionHelper.showAccount(mAuthorities, auths)) {
                     continue;
                 }
                 final Bundle fragmentArguments = new Bundle();
                 fragmentArguments.putParcelable(AccountDetailDashboardFragment.KEY_ACCOUNT,
-                    account);
+                        account);
                 fragmentArguments.putParcelable(AccountDetailDashboardFragment.KEY_USER_HANDLE,
-                    userHandle);
+                        userHandle);
                 fragmentArguments.putString(AccountDetailDashboardFragment.KEY_ACCOUNT_TYPE,
-                    accountType);
+                        accountType);
                 fragmentArguments.putString(AccountDetailDashboardFragment.KEY_ACCOUNT_LABEL,
-                    label.toString());
+                        label.toString());
                 fragmentArguments.putInt(AccountDetailDashboardFragment.KEY_ACCOUNT_TITLE_RES,
-                    titleResId);
+                        titleResId);
                 fragmentArguments.putParcelable(EXTRA_USER, userHandle);
                 accountTypePreferences.add(new AccountTypePreference(
-                    prefContext, mMetricsFeatureProvider.getMetricsCategory(mParent),
-                    account, titleResPackageName, titleResId, label,
-                    AccountDetailDashboardFragment.class.getName(), fragmentArguments, icon));
+                        prefContext, mMetricsFeatureProvider.getMetricsCategory(mParent),
+                        account, titleResPackageName, titleResId, label,
+                        AccountDetailDashboardFragment.class.getName(), fragmentArguments, icon));
             }
             helper.preloadDrawableForType(mContext, accountType);
         }
@@ -536,7 +547,7 @@
             public int compare(AccountTypePreference t1, AccountTypePreference t2) {
                 int result = t1.getSummary().toString().compareTo(t2.getSummary().toString());
                 return result != 0
-                    ? result : t1.getTitle().toString().compareTo(t2.getTitle().toString());
+                        ? result : t1.getTitle().toString().compareTo(t2.getTitle().toString());
             }
         });
         return accountTypePreferences;
diff --git a/src/com/android/settings/accounts/AccountProfileSelectFragment.java b/src/com/android/settings/accounts/AccountProfileSelectFragment.java
new file mode 100644
index 0000000..128596d
--- /dev/null
+++ b/src/com/android/settings/accounts/AccountProfileSelectFragment.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accounts;
+import androidx.fragment.app.Fragment;
+
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
+
+/**
+ * Account Setting page for personal/managed profile.
+ */
+public class AccountProfileSelectFragment extends ProfileSelectFragment {
+
+    @Override
+    public Fragment[] getFragments() {
+        return new Fragment[] {
+                new AccountPersonalDashboardFragment(),
+                new AccountWorkProfileDashboardFragment()
+        };
+    }
+}
diff --git a/src/com/android/settings/accounts/AccountWorkProfileDashboardFragment.java b/src/com/android/settings/accounts/AccountWorkProfileDashboardFragment.java
new file mode 100644
index 0000000..e3fceb8
--- /dev/null
+++ b/src/com/android/settings/accounts/AccountWorkProfileDashboardFragment.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accounts;
+
+import static android.provider.Settings.EXTRA_AUTHORITIES;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
+import com.android.settings.users.AutoSyncDataPreferenceController;
+import com.android.settings.users.AutoSyncWorkDataPreferenceController;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.search.SearchIndexable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Account Setting page for work profile.
+ */
+@SearchIndexable
+public class AccountWorkProfileDashboardFragment extends DashboardFragment {
+
+    private static final String TAG = "AccountWorkProfileFrag";
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.ACCOUNT;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.accounts_work_dashboard_settings;
+    }
+
+    @Override
+    public int getHelpResource() {
+        return R.string.help_url_user_and_account_dashboard;
+    }
+
+    @Override
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        final String[] authorities = getIntent().getStringArrayExtra(EXTRA_AUTHORITIES);
+        return buildPreferenceControllers(context, this /* parent */, authorities);
+    }
+
+    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
+            SettingsPreferenceFragment parent, String[] authorities) {
+        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+
+        final AccountPreferenceController accountPrefController =
+                new AccountPreferenceController(context, parent, authorities,
+                        ProfileSelectFragment.WORK);
+        if (parent != null) {
+            parent.getSettingsLifecycle().addObserver(accountPrefController);
+        }
+        controllers.add(accountPrefController);
+        controllers.add(new AutoSyncDataPreferenceController(context, parent));
+        controllers.add(new AutoSyncWorkDataPreferenceController(context, parent));
+        return controllers;
+    }
+
+    // TODO: b/141601408. After featureFlag settings_work_profile is launched, unmark this
+//    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+//            new BaseSearchIndexProvider(R.xml.accounts_work_dashboard_settings) {
+//
+//                @Override
+//                public List<AbstractPreferenceController> createPreferenceControllers(
+//                        Context context) {
+//                    return buildPreferenceControllers(
+//                            context, null /* parent */, null /* authorities*/);
+//                }
+//            };
+}
diff --git a/src/com/android/settings/core/FeatureFlags.java b/src/com/android/settings/core/FeatureFlags.java
index fee9c42..8203b35 100644
--- a/src/com/android/settings/core/FeatureFlags.java
+++ b/src/com/android/settings/core/FeatureFlags.java
@@ -27,4 +27,5 @@
     public static final String NETWORK_INTERNET_V2 = "settings_network_and_internet_v2";
     public static final String WIFI_DETAILS_DATAUSAGE_HEADER =
             "settings_wifi_details_datausage_header";
+    public static final String PERSONAL_WORK_PROFILE = "settings_work_profile";
 }
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileFragmentBridge.java b/src/com/android/settings/dashboard/profileselector/ProfileFragmentBridge.java
new file mode 100644
index 0000000..797782a
--- /dev/null
+++ b/src/com/android/settings/dashboard/profileselector/ProfileFragmentBridge.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.dashboard.profileselector;
+
+import android.util.ArrayMap;
+
+import com.android.settings.accounts.AccountDashboardFragment;
+import com.android.settings.accounts.AccountProfileSelectFragment;
+
+import java.util.Map;
+
+/**
+ * A registry to keep track of which page and its own profile selection page.
+ */
+public class ProfileFragmentBridge {
+
+    /**
+     * Map from parent fragment to category key. The parent fragment hosts child with
+     * category_key.
+     */
+    public static final Map<String, String> FRAGMENT_MAP;
+
+    static {
+        FRAGMENT_MAP = new ArrayMap<>();
+        FRAGMENT_MAP.put(AccountDashboardFragment.class.getName(),
+                AccountProfileSelectFragment.class.getName());
+    }
+}
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java
new file mode 100644
index 0000000..96eace8
--- /dev/null
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.dashboard.profileselector;
+
+import android.annotation.IntDef;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentStatePagerAdapter;
+import androidx.viewpager.widget.ViewPager;
+
+import com.android.settings.R;
+import com.android.settings.core.InstrumentedFragment;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Base fragment class for per profile settings.
+ */
+public abstract class ProfileSelectFragment extends InstrumentedFragment {
+
+    /**
+     * Denotes the profile type.
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({PERSONAL, WORK, ALL})
+    public @interface ProfileType {
+    }
+
+    /**
+     * It is personal work profile.
+     */
+    public static final int PERSONAL = 1;
+
+    /**
+     * It is work profile
+     */
+    public static final int WORK = 1 << 1;
+
+    /**
+     * It is personal and work profile
+     */
+    public static final int ALL = PERSONAL | WORK;
+
+    private View mContentView;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        mContentView = inflater.inflate(R.layout.profile_select_tablayout, null /* root */);
+        final ViewPager viewPager = mContentView.findViewById(R.id.view_pager);
+        viewPager.setAdapter(new ViewPagerAdapter(this));
+        return mContentView;
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return METRICS_CATEGORY_UNKNOWN;
+    }
+
+    /**
+     * Returns an array of {@link Fragment} to display in the
+     * {@link com.google.android.material.tabs.TabLayout}
+     */
+    public abstract Fragment[] getFragments();
+
+    static class ViewPagerAdapter extends FragmentStatePagerAdapter {
+
+        private final Fragment[] mChildFragments;
+        private final Context mContext;
+
+        ViewPagerAdapter(ProfileSelectFragment fragment) {
+            super(fragment.getActivity().getSupportFragmentManager());
+            mContext = fragment.getContext();
+            mChildFragments = fragment.getFragments();
+        }
+
+        @Override
+        public Fragment getItem(int position) {
+            return mChildFragments[position];
+        }
+
+        @Override
+        public int getCount() {
+            return mChildFragments.length;
+        }
+
+        @Override
+        public CharSequence getPageTitle(int position) {
+            if (position == 0) {
+                return mContext.getString(R.string.category_personal);
+            } else {
+                return mContext.getString(R.string.category_work);
+            }
+        }
+    }
+}