diff --git a/res/layout/preference_expand_divider.xml b/res/layout/preference_expand_divider.xml
index ce3d2e7..9b76688 100644
--- a/res/layout/preference_expand_divider.xml
+++ b/res/layout/preference_expand_divider.xml
@@ -34,7 +34,6 @@
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:paddingEnd="4dp"
-        android:singleLine="true"
         android:textAlignment="viewStart"
         style="@style/PreferenceCategoryTitleTextStyle"/>
 
diff --git a/res/layout/trusted_credentials.xml b/res/layout/trusted_credentials.xml
index 31f5f40..3663a79 100644
--- a/res/layout/trusted_credentials.xml
+++ b/res/layout/trusted_credentials.xml
@@ -13,78 +13,26 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<TabHost
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
+    <ProgressBar
+        android:id="@+id/progress"
+        style="?android:attr/progressBarStyleHorizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:visibility="gone"/>
+
     <LinearLayout
+        android:id="@+id/content"
         android:orientation="vertical"
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent">
-
-        <TabWidget
-            android:id="@android:id/tabs"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content" />
-
-        <FrameLayout
-            android:id="@android:id/tabcontent"
-            android:layout_width="fill_parent"
-            android:layout_height="fill_parent">
-
-            <FrameLayout
-                android:id="@+id/system_tab"
-                android:layout_width="fill_parent"
-                android:layout_height="fill_parent">
-
-                <ProgressBar
-                    android:id="@+id/system_progress"
-                    style="?android:attr/progressBarStyleHorizontal"
-                    android:layout_width="fill_parent"
-                    android:layout_height="wrap_content"
-                    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-                    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-                    android:visibility="gone" />
-
-                <LinearLayout
-                    android:id="@+id/system_content"
-                    android:orientation="vertical"
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent"
-                    android:visibility="gone"
-                    android:animateLayoutChanges="true">
-                </LinearLayout>
-
-            </FrameLayout>
-
-            <FrameLayout
-                android:id="@+id/user_tab"
-                android:layout_width="fill_parent"
-                android:layout_height="fill_parent">
-
-                <ProgressBar
-                    android:id="@+id/user_progress"
-                    style="?android:attr/progressBarStyleLarge"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-                    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-                    android:visibility="gone" />
-
-                <LinearLayout
-                    android:id="@+id/user_content"
-                    android:orientation="vertical"
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent"
-                    android:visibility="gone"
-                    android:animateLayoutChanges="true">
-                </LinearLayout>
-
-            </FrameLayout>
-
-        </FrameLayout>
-
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone">
     </LinearLayout>
 
-</TabHost>
+</FrameLayout>
\ No newline at end of file
diff --git a/src/com/android/settings/TrustedCredentialsDialogBuilder.java b/src/com/android/settings/TrustedCredentialsDialogBuilder.java
index 806da92..0dc8c25 100644
--- a/src/com/android/settings/TrustedCredentialsDialogBuilder.java
+++ b/src/com/android/settings/TrustedCredentialsDialogBuilder.java
@@ -34,7 +34,7 @@
 import androidx.appcompat.app.AlertDialog;
 
 import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.TrustedCredentialsSettings.CertHolder;
+import com.android.settings.TrustedCredentialsFragment.CertHolder;
 import com.android.settingslib.RestrictedLockUtils;
 
 import java.security.cert.X509Certificate;
diff --git a/src/com/android/settings/TrustedCredentialsFragment.java b/src/com/android/settings/TrustedCredentialsFragment.java
new file mode 100644
index 0000000..ca565a4
--- /dev/null
+++ b/src/com/android/settings/TrustedCredentialsFragment.java
@@ -0,0 +1,1030 @@
+/*
+ * Copyright (C) 2022 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;
+
+import static android.app.admin.DevicePolicyResources.Strings.Settings.PERSONAL_CATEGORY_HEADER;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_CATEGORY_HEADER;
+import static android.widget.LinearLayout.LayoutParams.MATCH_PARENT;
+import static android.widget.LinearLayout.LayoutParams.WRAP_CONTENT;
+
+import android.annotation.UiThread;
+import android.app.Activity;
+import android.app.KeyguardManager;
+import android.app.admin.DevicePolicyManager;
+import android.app.settings.SettingsEnums;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.UserInfo;
+import android.content.res.TypedArray;
+import android.database.DataSetObserver;
+import android.graphics.drawable.Drawable;
+import android.net.http.SslCertificate;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.security.IKeyChainService;
+import android.security.KeyChain;
+import android.security.KeyChain.KeyChainConnection;
+import android.util.ArraySet;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.BaseExpandableListAdapter;
+import android.widget.ExpandableListView;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.ProgressBar;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.app.UnlaunchableAppActivity;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.TrustedCredentialsSettings.Tab;
+import com.android.settings.core.InstrumentedFragment;
+
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.function.IntConsumer;
+
+/**
+ * Fragment to display trusted credentials settings for one tab.
+ */
+public class TrustedCredentialsFragment extends InstrumentedFragment
+        implements TrustedCredentialsDialogBuilder.DelegateInterface {
+
+    public static final String ARG_POSITION = "tab";
+    public static final String ARG_SHOW_NEW_FOR_USER = "ARG_SHOW_NEW_FOR_USER";
+
+    private static final String TAG = "TrustedCredentialsFragment";
+
+    private DevicePolicyManager mDevicePolicyManager;
+    private UserManager mUserManager;
+    private KeyguardManager mKeyguardManager;
+    private int mTrustAllCaUserId;
+
+    private static final String SAVED_CONFIRMED_CREDENTIAL_USERS = "ConfirmedCredentialUsers";
+    private static final String SAVED_CONFIRMING_CREDENTIAL_USER = "ConfirmingCredentialUser";
+    private static final int REQUEST_CONFIRM_CREDENTIALS = 1;
+
+    private GroupAdapter mGroupAdapter;
+    private AliasOperation mAliasOperation;
+    private ArraySet<Integer> mConfirmedCredentialUsers;
+    private int mConfirmingCredentialUser;
+    private IntConsumer mConfirmingCredentialListener;
+    private final Set<AdapterData.AliasLoader> mAliasLoaders = new ArraySet<>(2);
+    @GuardedBy("mKeyChainConnectionByProfileId")
+    private final SparseArray<KeyChainConnection>
+            mKeyChainConnectionByProfileId = new SparseArray<>();
+    private ViewGroup mFragmentView;
+
+    private final BroadcastReceiver mWorkProfileChangedReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(action)
+                    || Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action)
+                    || Intent.ACTION_MANAGED_PROFILE_UNLOCKED.equals(action)) {
+                mGroupAdapter.load();
+            }
+        }
+    };
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Activity activity = getActivity();
+        mDevicePolicyManager = activity.getSystemService(DevicePolicyManager.class);
+        mUserManager = activity.getSystemService(UserManager.class);
+        mKeyguardManager = activity.getSystemService(KeyguardManager.class);
+        mTrustAllCaUserId = activity.getIntent().getIntExtra(ARG_SHOW_NEW_FOR_USER,
+                UserHandle.USER_NULL);
+        mConfirmedCredentialUsers = new ArraySet<>(2);
+        mConfirmingCredentialUser = UserHandle.USER_NULL;
+        if (savedInstanceState != null) {
+            mConfirmingCredentialUser = savedInstanceState.getInt(SAVED_CONFIRMING_CREDENTIAL_USER,
+                    UserHandle.USER_NULL);
+            ArrayList<Integer> users = savedInstanceState.getIntegerArrayList(
+                    SAVED_CONFIRMED_CREDENTIAL_USERS);
+            if (users != null) {
+                mConfirmedCredentialUsers.addAll(users);
+            }
+        }
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
+        filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
+        filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
+        activity.registerReceiver(mWorkProfileChangedReceiver, filter);
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putIntegerArrayList(SAVED_CONFIRMED_CREDENTIAL_USERS, new ArrayList<>(
+                mConfirmedCredentialUsers));
+        outState.putInt(SAVED_CONFIRMING_CREDENTIAL_USER, mConfirmingCredentialUser);
+        mGroupAdapter.saveState(outState);
+    }
+
+    @Override
+    public View onCreateView(
+            LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
+        mFragmentView = (ViewGroup) inflater.inflate(R.layout.trusted_credentials, parent, false);
+
+        ViewGroup contentView = mFragmentView.findViewById(R.id.content);
+
+        mGroupAdapter = new GroupAdapter(
+                requireArguments().getInt(ARG_POSITION) == 0 ? Tab.SYSTEM : Tab.USER);
+        int profilesSize = mGroupAdapter.getGroupCount();
+        for (int i = 0; i < profilesSize; i++) {
+            Bundle childState = savedInstanceState == null ? null
+                    : savedInstanceState.getBundle(mGroupAdapter.getKey(i));
+            createChildView(inflater, contentView, childState, i);
+        }
+        return mFragmentView;
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.TRUSTED_CREDENTIALS;
+    }
+
+    private void createChildView(
+            LayoutInflater inflater, ViewGroup parent, Bundle childState, int i) {
+        boolean isWork = mGroupAdapter.getUserInfoByGroup(i).isManagedProfile();
+        ChildAdapter adapter = mGroupAdapter.createChildAdapter(i);
+
+        LinearLayout containerView = (LinearLayout) inflater.inflate(
+                R.layout.trusted_credential_list_container, parent, false);
+        adapter.setContainerView(containerView, childState);
+
+        int profilesSize = mGroupAdapter.getGroupCount();
+        adapter.showHeader(profilesSize > 1);
+        adapter.showDivider(isWork);
+        adapter.setExpandIfAvailable(profilesSize <= 2 || !isWork, childState);
+        if (isWork) {
+            parent.addView(containerView);
+        } else {
+            parent.addView(containerView, 0);
+        }
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mFragmentView.requestLayout();
+    }
+
+    @Override
+    public void onDestroy() {
+        getActivity().unregisterReceiver(mWorkProfileChangedReceiver);
+        for (AdapterData.AliasLoader aliasLoader : mAliasLoaders) {
+            aliasLoader.cancel(true);
+        }
+        mAliasLoaders.clear();
+        if (mAliasOperation != null) {
+            mAliasOperation.cancel(true);
+            mAliasOperation = null;
+        }
+        closeKeyChainConnections();
+        super.onDestroy();
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUEST_CONFIRM_CREDENTIALS) {
+            int userId = mConfirmingCredentialUser;
+            IntConsumer listener = mConfirmingCredentialListener;
+            // reset them before calling the listener because the listener may call back to start
+            // activity again. (though it should never happen.)
+            mConfirmingCredentialUser = UserHandle.USER_NULL;
+            mConfirmingCredentialListener = null;
+            if (resultCode == Activity.RESULT_OK) {
+                mConfirmedCredentialUsers.add(userId);
+                if (listener != null) {
+                    listener.accept(userId);
+                }
+            }
+        }
+    }
+
+    private void closeKeyChainConnections() {
+        synchronized (mKeyChainConnectionByProfileId) {
+            int n = mKeyChainConnectionByProfileId.size();
+            for (int i = 0; i < n; ++i) {
+                mKeyChainConnectionByProfileId.valueAt(i).close();
+            }
+            mKeyChainConnectionByProfileId.clear();
+        }
+    }
+
+    /**
+     * Start work challenge activity.
+     *
+     * @return true if screenlock exists
+     */
+    private boolean startConfirmCredential(int userId) {
+        Intent newIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, null, userId);
+        if (newIntent == null) {
+            return false;
+        }
+        mConfirmingCredentialUser = userId;
+        startActivityForResult(newIntent, REQUEST_CONFIRM_CREDENTIALS);
+        return true;
+    }
+
+    /**
+     * Adapter for expandable list view of certificates. Groups in the view correspond to profiles
+     * whereas children correspond to certificates.
+     */
+    private class GroupAdapter extends BaseExpandableListAdapter implements
+            ExpandableListView.OnGroupClickListener, ExpandableListView.OnChildClickListener {
+        private final AdapterData mData;
+        private final ArrayList<ChildAdapter> mChildAdapters = new ArrayList<>();
+
+        private GroupAdapter(Tab tab) {
+            mData = new AdapterData(tab, this);
+            load();
+        }
+
+        @Override
+        public int getGroupCount() {
+            return mData.mCertHoldersByUserId.size();
+        }
+
+        @Override
+        public int getChildrenCount(int groupPosition) {
+            List<CertHolder> certHolders = mData.mCertHoldersByUserId.valueAt(groupPosition);
+            if (certHolders != null) {
+                return certHolders.size();
+            }
+            return 0;
+        }
+
+        @Override
+        public UserHandle getGroup(int groupPosition) {
+            return new UserHandle(mData.mCertHoldersByUserId.keyAt(groupPosition));
+        }
+
+        @Override
+        public CertHolder getChild(int groupPosition, int childPosition) {
+            return mData.mCertHoldersByUserId.get(getUserIdByGroup(groupPosition)).get(
+                    childPosition);
+        }
+
+        @Override
+        public long getGroupId(int groupPosition) {
+            return getUserIdByGroup(groupPosition);
+        }
+
+        private int getUserIdByGroup(int groupPosition) {
+            return mData.mCertHoldersByUserId.keyAt(groupPosition);
+        }
+
+        public UserInfo getUserInfoByGroup(int groupPosition) {
+            return mUserManager.getUserInfo(getUserIdByGroup(groupPosition));
+        }
+
+        @Override
+        public long getChildId(int groupPosition, int childPosition) {
+            return childPosition;
+        }
+
+        @Override
+        public boolean hasStableIds() {
+            return false;
+        }
+
+        @Override
+        public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
+                ViewGroup parent) {
+            if (convertView == null) {
+                LayoutInflater inflater = (LayoutInflater) getActivity()
+                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+                convertView = Utils.inflateCategoryHeader(inflater, parent);
+            }
+
+            TextView title = convertView.findViewById(android.R.id.title);
+            if (getUserInfoByGroup(groupPosition).isManagedProfile()) {
+                title.setText(mDevicePolicyManager.getResources().getString(WORK_CATEGORY_HEADER,
+                        () -> getString(R.string.category_work)));
+            } else {
+                title.setText(mDevicePolicyManager.getResources().getString(
+                        PERSONAL_CATEGORY_HEADER,
+                        () -> getString(R.string.category_personal)));
+
+            }
+            title.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
+
+            return convertView;
+        }
+
+        @Override
+        public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
+                View convertView, ViewGroup parent) {
+            return getViewForCertificate(getChild(groupPosition, childPosition), mData.mTab,
+                    convertView, parent);
+        }
+
+        @Override
+        public boolean isChildSelectable(int groupPosition, int childPosition) {
+            return true;
+        }
+
+        @Override
+        public boolean onChildClick(ExpandableListView expandableListView, View view,
+                int groupPosition, int childPosition, long id) {
+            showCertDialog(getChild(groupPosition, childPosition));
+            return true;
+        }
+
+        @Override
+        public boolean onGroupClick(ExpandableListView expandableListView, View view,
+                int groupPosition, long id) {
+            return !checkGroupExpandableAndStartWarningActivity(groupPosition);
+        }
+
+        public void load() {
+            mData.new AliasLoader().execute();
+        }
+
+        public void remove(CertHolder certHolder) {
+            mData.remove(certHolder);
+        }
+
+        ChildAdapter createChildAdapter(int groupPosition) {
+            ChildAdapter childAdapter = new ChildAdapter(this, groupPosition);
+            mChildAdapters.add(childAdapter);
+            return childAdapter;
+        }
+
+        public boolean checkGroupExpandableAndStartWarningActivity(int groupPosition) {
+            return checkGroupExpandableAndStartWarningActivity(groupPosition, true);
+        }
+
+        public boolean checkGroupExpandableAndStartWarningActivity(int groupPosition,
+                boolean startActivity) {
+            UserHandle groupUser = getGroup(groupPosition);
+            int groupUserId = groupUser.getIdentifier();
+            if (mUserManager.isQuietModeEnabled(groupUser)) {
+                if (startActivity) {
+                    Intent intent =
+                            UnlaunchableAppActivity.createInQuietModeDialogIntent(groupUserId);
+                    getActivity().startActivity(intent);
+                }
+                return false;
+            } else if (!mUserManager.isUserUnlocked(groupUser)) {
+                LockPatternUtils lockPatternUtils = new LockPatternUtils(getActivity());
+                if (lockPatternUtils.isSeparateProfileChallengeEnabled(groupUserId)) {
+                    if (startActivity) {
+                        startConfirmCredential(groupUserId);
+                    }
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        private View getViewForCertificate(CertHolder certHolder, Tab mTab, View convertView,
+                ViewGroup parent) {
+            ViewHolder holder;
+            if (convertView == null) {
+                holder = new ViewHolder();
+                LayoutInflater inflater = LayoutInflater.from(getActivity());
+                convertView = inflater.inflate(R.layout.trusted_credential, parent, false);
+                convertView.setTag(holder);
+                holder.mSubjectPrimaryView =
+                        convertView.findViewById(R.id.trusted_credential_subject_primary);
+                holder.mSubjectSecondaryView =
+                        convertView.findViewById(R.id.trusted_credential_subject_secondary);
+                holder.mSwitch = convertView.findViewById(R.id.trusted_credential_status);
+                holder.mSwitch.setOnClickListener(view -> {
+                    removeOrInstallCert((CertHolder) view.getTag());
+                });
+            } else {
+                holder = (ViewHolder) convertView.getTag();
+            }
+            holder.mSubjectPrimaryView.setText(certHolder.mSubjectPrimary);
+            holder.mSubjectSecondaryView.setText(certHolder.mSubjectSecondary);
+            if (mTab.mSwitch) {
+                holder.mSwitch.setChecked(!certHolder.mDeleted);
+                holder.mSwitch.setEnabled(!mUserManager.hasUserRestriction(
+                        UserManager.DISALLOW_CONFIG_CREDENTIALS,
+                        new UserHandle(certHolder.mProfileId)));
+                holder.mSwitch.setVisibility(View.VISIBLE);
+                holder.mSwitch.setTag(certHolder);
+            }
+            return convertView;
+        }
+
+        private void saveState(Bundle outState) {
+            for (int groupPosition = 0, mChildAdaptersSize = mChildAdapters.size();
+                    groupPosition < mChildAdaptersSize; groupPosition++) {
+                ChildAdapter childAdapter = mChildAdapters.get(groupPosition);
+                outState.putBundle(getKey(groupPosition), childAdapter.saveState());
+            }
+        }
+
+        @NonNull
+        private String getKey(int groupPosition) {
+            return "Group" + getUserIdByGroup(groupPosition);
+        }
+
+        private class ViewHolder {
+            private TextView mSubjectPrimaryView;
+            private TextView mSubjectSecondaryView;
+            private Switch mSwitch;
+        }
+    }
+
+    private class ChildAdapter extends BaseAdapter implements View.OnClickListener,
+            AdapterView.OnItemClickListener {
+        private static final String KEY_CONTAINER = "Container";
+        private static final String KEY_IS_LIST_EXPANDED = "IsListExpanded";
+        private final int[] mGroupExpandedStateSet = {com.android.internal.R.attr.state_expanded};
+        private final int[] mEmptyStateSet = {};
+        private final LinearLayout.LayoutParams mHideContainerLayoutParams =
+                new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT, 0f);
+        private final LinearLayout.LayoutParams mHideListLayoutParams =
+                new LinearLayout.LayoutParams(MATCH_PARENT, 0);
+        private final LinearLayout.LayoutParams mShowLayoutParams = new LinearLayout.LayoutParams(
+                LinearLayout.LayoutParams.MATCH_PARENT, MATCH_PARENT, 1f);
+        private final GroupAdapter mParent;
+        private final int mGroupPosition;
+        /*
+         * This class doesn't hold the actual data. Events should notify parent.
+         * When notifying DataSet events in this class, events should be forwarded to mParent.
+         * i.e. this.notifyDataSetChanged -> mParent.notifyDataSetChanged -> mObserver.onChanged
+         * -> outsideObservers.onChanged() (e.g. ListView)
+         */
+        private final DataSetObserver mObserver = new DataSetObserver() {
+            @Override
+            public void onChanged() {
+                super.onChanged();
+                TrustedCredentialsFragment.ChildAdapter.super.notifyDataSetChanged();
+            }
+
+            @Override
+            public void onInvalidated() {
+                super.onInvalidated();
+                TrustedCredentialsFragment.ChildAdapter.super.notifyDataSetInvalidated();
+            }
+        };
+
+        private boolean mIsListExpanded = true;
+        private LinearLayout mContainerView;
+        private ViewGroup mHeaderView;
+        private ListView mListView;
+        private ImageView mIndicatorView;
+
+        private ChildAdapter(GroupAdapter parent, int groupPosition) {
+            mParent = parent;
+            mGroupPosition = groupPosition;
+            mParent.registerDataSetObserver(mObserver);
+        }
+
+        @Override
+        public int getCount() {
+            return mParent.getChildrenCount(mGroupPosition);
+        }
+
+        @Override
+        public CertHolder getItem(int position) {
+            return mParent.getChild(mGroupPosition, position);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return mParent.getChildId(mGroupPosition, position);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            return mParent.getChildView(mGroupPosition, position, false, convertView, parent);
+        }
+
+        // DataSet events
+        @Override
+        public void notifyDataSetChanged() {
+            // Don't call super as the parent will propagate this event back later in mObserver
+            mParent.notifyDataSetChanged();
+        }
+
+        @Override
+        public void notifyDataSetInvalidated() {
+            // Don't call super as the parent will propagate this event back later in mObserver
+            mParent.notifyDataSetInvalidated();
+        }
+
+        // View related codes
+        @Override
+        public void onClick(View view) {
+            mIsListExpanded = checkGroupExpandableAndStartWarningActivity() && !mIsListExpanded;
+            refreshViews();
+        }
+
+        @Override
+        public void onItemClick(AdapterView<?> adapterView, View view, int pos, long id) {
+            showCertDialog(getItem(pos));
+        }
+
+        public void setContainerView(LinearLayout containerView, Bundle savedState) {
+            mContainerView = containerView;
+            // Handle manually because multiple groups with same id elements.
+            mContainerView.setSaveFromParentEnabled(false);
+
+            mListView = mContainerView.findViewById(R.id.cert_list);
+            mListView.setAdapter(this);
+            mListView.setOnItemClickListener(this);
+            mListView.setItemsCanFocus(true);
+
+            mHeaderView = mContainerView.findViewById(R.id.header_view);
+            mHeaderView.setOnClickListener(this);
+
+            mIndicatorView = mHeaderView.findViewById(R.id.group_indicator);
+            mIndicatorView.setImageDrawable(getGroupIndicator());
+
+            FrameLayout headerContentContainer =
+                    mHeaderView.findViewById(R.id.header_content_container);
+            headerContentContainer.addView(
+                    mParent.getGroupView(mGroupPosition, true /* parent ignores it */, null,
+                            headerContentContainer));
+
+            if (savedState != null) {
+                SparseArray<Parcelable> containerStates =
+                        savedState.getSparseParcelableArray(KEY_CONTAINER, Parcelable.class);
+                if (containerStates != null) {
+                    mContainerView.restoreHierarchyState(containerStates);
+                }
+            }
+        }
+
+        public void showHeader(boolean showHeader) {
+            mHeaderView.setVisibility(showHeader ? View.VISIBLE : View.GONE);
+        }
+
+        public void showDivider(boolean showDivider) {
+            View dividerView = mHeaderView.findViewById(R.id.header_divider);
+            dividerView.setVisibility(showDivider ? View.VISIBLE : View.GONE);
+        }
+
+        public void setExpandIfAvailable(boolean expanded, Bundle savedState) {
+            if (savedState != null) {
+                expanded = savedState.getBoolean(KEY_IS_LIST_EXPANDED);
+            }
+            mIsListExpanded = expanded && mParent.checkGroupExpandableAndStartWarningActivity(
+                    mGroupPosition, false /* startActivity */);
+            refreshViews();
+        }
+
+        private boolean checkGroupExpandableAndStartWarningActivity() {
+            return mParent.checkGroupExpandableAndStartWarningActivity(mGroupPosition);
+        }
+
+        private void refreshViews() {
+            mIndicatorView.setImageState(mIsListExpanded ? mGroupExpandedStateSet
+                    : mEmptyStateSet, false);
+            mListView.setLayoutParams(mIsListExpanded ? mShowLayoutParams
+                    : mHideListLayoutParams);
+            mContainerView.setLayoutParams(mIsListExpanded ? mShowLayoutParams
+                    : mHideContainerLayoutParams);
+        }
+
+        // Get group indicator from styles of ExpandableListView
+        private Drawable getGroupIndicator() {
+            TypedArray a = getActivity().obtainStyledAttributes(null,
+                    com.android.internal.R.styleable.ExpandableListView,
+                    com.android.internal.R.attr.expandableListViewStyle, 0);
+            Drawable groupIndicator = a.getDrawable(
+                    com.android.internal.R.styleable.ExpandableListView_groupIndicator);
+            a.recycle();
+            return groupIndicator;
+        }
+
+        private Bundle saveState() {
+            Bundle bundle = new Bundle();
+            SparseArray<Parcelable> states = new SparseArray<>();
+            mContainerView.saveHierarchyState(states);
+            bundle.putSparseParcelableArray(KEY_CONTAINER, states);
+            bundle.putBoolean(KEY_IS_LIST_EXPANDED, mIsListExpanded);
+            return bundle;
+        }
+    }
+
+    private class AdapterData {
+        private final SparseArray<List<CertHolder>> mCertHoldersByUserId =
+                new SparseArray<>();
+        private final Tab mTab;
+        private final GroupAdapter mAdapter;
+
+        private AdapterData(Tab tab, GroupAdapter adapter) {
+            mAdapter = adapter;
+            mTab = tab;
+        }
+
+        private class AliasLoader extends AsyncTask<Void, Integer, SparseArray<List<CertHolder>>> {
+            private ProgressBar mProgressBar;
+            private View mContentView;
+            private Context mContext;
+
+            AliasLoader() {
+                mContext = getActivity();
+                mAliasLoaders.add(this);
+                List<UserHandle> profiles = mUserManager.getUserProfiles();
+                for (UserHandle profile : profiles) {
+                    mCertHoldersByUserId.put(profile.getIdentifier(), new ArrayList<>());
+                }
+            }
+
+            private boolean shouldSkipProfile(UserHandle userHandle) {
+                return mUserManager.isQuietModeEnabled(userHandle)
+                        || !mUserManager.isUserUnlocked(userHandle.getIdentifier());
+            }
+
+            @Override
+            protected void onPreExecute() {
+                mProgressBar = mFragmentView.findViewById(R.id.progress);
+                mContentView = mFragmentView.findViewById(R.id.content);
+                mProgressBar.setVisibility(View.VISIBLE);
+                mContentView.setVisibility(View.GONE);
+            }
+
+            @Override
+            protected SparseArray<List<CertHolder>> doInBackground(Void... params) {
+                SparseArray<List<CertHolder>> certHoldersByProfile =
+                        new SparseArray<>();
+                try {
+                    synchronized (mKeyChainConnectionByProfileId) {
+                        List<UserHandle> profiles = mUserManager.getUserProfiles();
+                        // First we get all aliases for all profiles in order to show progress
+                        // correctly. Otherwise this could all be in a single loop.
+                        SparseArray<List<String>> aliasesByProfileId =
+                                new SparseArray<>(profiles.size());
+                        int max = 0;
+                        int progress = 0;
+                        for (UserHandle profile : profiles) {
+                            int profileId = profile.getIdentifier();
+                            if (shouldSkipProfile(profile)) {
+                                continue;
+                            }
+                            KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext,
+                                    profile);
+                            // Saving the connection for later use on the certificate dialog.
+                            mKeyChainConnectionByProfileId.put(profileId, keyChainConnection);
+                            IKeyChainService service = keyChainConnection.getService();
+                            List<String> aliases = mTab.getAliases(service);
+                            if (isCancelled()) {
+                                return new SparseArray<>();
+                            }
+                            max += aliases.size();
+                            aliasesByProfileId.put(profileId, aliases);
+                        }
+                        for (UserHandle profile : profiles) {
+                            int profileId = profile.getIdentifier();
+                            List<String> aliases = aliasesByProfileId.get(profileId);
+                            if (isCancelled()) {
+                                return new SparseArray<>();
+                            }
+                            KeyChainConnection keyChainConnection =
+                                    mKeyChainConnectionByProfileId.get(
+                                            profileId);
+                            if (shouldSkipProfile(profile) || aliases == null
+                                    || keyChainConnection == null) {
+                                certHoldersByProfile.put(profileId, new ArrayList<>(0));
+                                continue;
+                            }
+                            IKeyChainService service = keyChainConnection.getService();
+                            List<CertHolder> certHolders = new ArrayList<>(max);
+                            for (String alias : aliases) {
+                                byte[] encodedCertificate = service.getEncodedCaCertificate(alias,
+                                        true);
+                                X509Certificate cert = KeyChain.toCertificate(encodedCertificate);
+                                certHolders.add(new CertHolder(service, mAdapter,
+                                        mTab, alias, cert, profileId));
+                                publishProgress(++progress, max);
+                            }
+                            Collections.sort(certHolders);
+                            certHoldersByProfile.put(profileId, certHolders);
+                        }
+                        return certHoldersByProfile;
+                    }
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Remote exception while loading aliases.", e);
+                    return new SparseArray<>();
+                } catch (InterruptedException e) {
+                    Log.e(TAG, "InterruptedException while loading aliases.", e);
+                    return new SparseArray<>();
+                }
+            }
+
+            @Override
+            protected void onProgressUpdate(Integer... progressAndMax) {
+                int progress = progressAndMax[0];
+                int max = progressAndMax[1];
+                if (max != mProgressBar.getMax()) {
+                    mProgressBar.setMax(max);
+                }
+                mProgressBar.setProgress(progress);
+            }
+
+            @Override
+            protected void onPostExecute(SparseArray<List<CertHolder>> certHolders) {
+                mCertHoldersByUserId.clear();
+                int n = certHolders.size();
+                for (int i = 0; i < n; ++i) {
+                    mCertHoldersByUserId.put(certHolders.keyAt(i), certHolders.valueAt(i));
+                }
+                mAdapter.notifyDataSetChanged();
+                mProgressBar.setVisibility(View.GONE);
+                mContentView.setVisibility(View.VISIBLE);
+                mProgressBar.setProgress(0);
+                mAliasLoaders.remove(this);
+                showTrustAllCaDialogIfNeeded();
+            }
+
+            private boolean isUserTabAndTrustAllCertMode() {
+                return isTrustAllCaCertModeInProgress() && mTab == Tab.USER;
+            }
+
+            @UiThread
+            private void showTrustAllCaDialogIfNeeded() {
+                if (!isUserTabAndTrustAllCertMode()) {
+                    return;
+                }
+                List<CertHolder> certHolders = mCertHoldersByUserId.get(mTrustAllCaUserId);
+                if (certHolders == null) {
+                    return;
+                }
+
+                List<CertHolder> unapprovedUserCertHolders = new ArrayList<>();
+                DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
+                for (CertHolder cert : certHolders) {
+                    if (cert != null && !dpm.isCaCertApproved(cert.mAlias, mTrustAllCaUserId)) {
+                        unapprovedUserCertHolders.add(cert);
+                    }
+                }
+
+                if (unapprovedUserCertHolders.size() == 0) {
+                    Log.w(TAG, "no cert is pending approval for user " + mTrustAllCaUserId);
+                    return;
+                }
+                showTrustAllCaDialog(unapprovedUserCertHolders);
+            }
+        }
+
+        public void remove(CertHolder certHolder) {
+            if (mCertHoldersByUserId != null) {
+                List<CertHolder> certs = mCertHoldersByUserId.get(certHolder.mProfileId);
+                if (certs != null) {
+                    certs.remove(certHolder);
+                }
+            }
+        }
+    }
+
+    /* package */ static class CertHolder implements Comparable<CertHolder> {
+        public int mProfileId;
+        private final IKeyChainService mService;
+        private final GroupAdapter mAdapter;
+        private final Tab mTab;
+        private final String mAlias;
+        private final X509Certificate mX509Cert;
+
+        private final SslCertificate mSslCert;
+        private final String mSubjectPrimary;
+        private final String mSubjectSecondary;
+        private boolean mDeleted;
+
+        private CertHolder(IKeyChainService service,
+                GroupAdapter adapter,
+                Tab tab,
+                String alias,
+                X509Certificate x509Cert,
+                int profileId) {
+            mProfileId = profileId;
+            mService = service;
+            mAdapter = adapter;
+            mTab = tab;
+            mAlias = alias;
+            mX509Cert = x509Cert;
+
+            mSslCert = new SslCertificate(x509Cert);
+
+            String cn = mSslCert.getIssuedTo().getCName();
+            String o = mSslCert.getIssuedTo().getOName();
+            String ou = mSslCert.getIssuedTo().getUName();
+            // if we have a O, use O as primary subject, secondary prefer CN over OU
+            // if we don't have an O, use CN as primary, empty secondary
+            // if we don't have O or CN, use DName as primary, empty secondary
+            if (!o.isEmpty()) {
+                if (!cn.isEmpty()) {
+                    mSubjectPrimary = o;
+                    mSubjectSecondary = cn;
+                } else {
+                    mSubjectPrimary = o;
+                    mSubjectSecondary = ou;
+                }
+            } else {
+                if (!cn.isEmpty()) {
+                    mSubjectPrimary = cn;
+                    mSubjectSecondary = "";
+                } else {
+                    mSubjectPrimary = mSslCert.getIssuedTo().getDName();
+                    mSubjectSecondary = "";
+                }
+            }
+            try {
+                mDeleted = mTab.deleted(mService, mAlias);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Remote exception while checking if alias " + mAlias + " is deleted.",
+                        e);
+                mDeleted = false;
+            }
+        }
+
+        @Override
+        public int compareTo(CertHolder o) {
+            int primary = this.mSubjectPrimary.compareToIgnoreCase(o.mSubjectPrimary);
+            if (primary != 0) {
+                return primary;
+            }
+            return this.mSubjectSecondary.compareToIgnoreCase(o.mSubjectSecondary);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof CertHolder)) {
+                return false;
+            }
+            CertHolder other = (CertHolder) o;
+            return mAlias.equals(other.mAlias);
+        }
+
+        @Override
+        public int hashCode() {
+            return mAlias.hashCode();
+        }
+
+        public int getUserId() {
+            return mProfileId;
+        }
+
+        public String getAlias() {
+            return mAlias;
+        }
+
+        public boolean isSystemCert() {
+            return mTab == Tab.SYSTEM;
+        }
+
+        public boolean isDeleted() {
+            return mDeleted;
+        }
+    }
+
+
+    private boolean isTrustAllCaCertModeInProgress() {
+        return mTrustAllCaUserId != UserHandle.USER_NULL;
+    }
+
+    private void showTrustAllCaDialog(List<CertHolder> unapprovedCertHolders) {
+        CertHolder[] arr =
+                unapprovedCertHolders.toArray(new CertHolder[unapprovedCertHolders.size()]);
+        new TrustedCredentialsDialogBuilder(getActivity(), this)
+                .setCertHolders(arr)
+                .setOnDismissListener(dialogInterface -> {
+                    // Avoid starting dialog again after Activity restart.
+                    getActivity().getIntent().removeExtra(ARG_SHOW_NEW_FOR_USER);
+                    mTrustAllCaUserId = UserHandle.USER_NULL;
+                })
+                .show();
+    }
+
+    private void showCertDialog(final CertHolder certHolder) {
+        new TrustedCredentialsDialogBuilder(getActivity(), this)
+                .setCertHolder(certHolder)
+                .show();
+    }
+
+    @Override
+    public List<X509Certificate> getX509CertsFromCertHolder(CertHolder certHolder) {
+        List<X509Certificate> certificates = null;
+        try {
+            synchronized (mKeyChainConnectionByProfileId) {
+                KeyChainConnection keyChainConnection = mKeyChainConnectionByProfileId.get(
+                        certHolder.mProfileId);
+                IKeyChainService service = keyChainConnection.getService();
+                List<String> chain = service.getCaCertificateChainAliases(certHolder.mAlias, true);
+                certificates = new ArrayList<>(chain.size());
+                for (String s : chain) {
+                    byte[] encodedCertificate = service.getEncodedCaCertificate(s, true);
+                    X509Certificate certificate = KeyChain.toCertificate(encodedCertificate);
+                    certificates.add(certificate);
+                }
+            }
+        } catch (RemoteException ex) {
+            Log.e(TAG, "RemoteException while retrieving certificate chain for root "
+                    + certHolder.mAlias, ex);
+        }
+        return certificates;
+    }
+
+    @Override
+    public void removeOrInstallCert(CertHolder certHolder) {
+        new AliasOperation(certHolder).execute();
+    }
+
+    @Override
+    public boolean startConfirmCredentialIfNotConfirmed(int userId,
+            IntConsumer onCredentialConfirmedListener) {
+        if (mConfirmedCredentialUsers.contains(userId)) {
+            // Credential has been confirmed. Don't start activity.
+            return false;
+        }
+
+        boolean result = startConfirmCredential(userId);
+        if (result) {
+            mConfirmingCredentialListener = onCredentialConfirmedListener;
+        }
+        return result;
+    }
+
+    private class AliasOperation extends AsyncTask<Void, Void, Boolean> {
+        private final CertHolder mCertHolder;
+
+        private AliasOperation(CertHolder certHolder) {
+            mCertHolder = certHolder;
+            mAliasOperation = this;
+        }
+
+        @Override
+        protected Boolean doInBackground(Void... params) {
+            try {
+                synchronized (mKeyChainConnectionByProfileId) {
+                    KeyChainConnection keyChainConnection = mKeyChainConnectionByProfileId.get(
+                            mCertHolder.mProfileId);
+                    IKeyChainService service = keyChainConnection.getService();
+                    if (mCertHolder.mDeleted) {
+                        byte[] bytes = mCertHolder.mX509Cert.getEncoded();
+                        service.installCaCertificate(bytes);
+                        return true;
+                    } else {
+                        return service.deleteCaCertificate(mCertHolder.mAlias);
+                    }
+                }
+            } catch (CertificateEncodingException | SecurityException | IllegalStateException
+                    | RemoteException e) {
+                Log.w(TAG, "Error while toggling alias " + mCertHolder.mAlias, e);
+                return false;
+            }
+        }
+
+        @Override
+        protected void onPostExecute(Boolean ok) {
+            if (ok) {
+                if (mCertHolder.mTab.mSwitch) {
+                    mCertHolder.mDeleted = !mCertHolder.mDeleted;
+                } else {
+                    mCertHolder.mAdapter.remove(mCertHolder);
+                }
+                mCertHolder.mAdapter.notifyDataSetChanged();
+            } else {
+                // bail, reload to reset to known state
+                mCertHolder.mAdapter.load();
+            }
+            mAliasOperation = null;
+        }
+    }
+}
diff --git a/src/com/android/settings/TrustedCredentialsSettings.java b/src/com/android/settings/TrustedCredentialsSettings.java
index 735cb3b..a88019e 100644
--- a/src/com/android/settings/TrustedCredentialsSettings.java
+++ b/src/com/android/settings/TrustedCredentialsSettings.java
@@ -16,121 +16,114 @@
 
 package com.android.settings;
 
-import static android.app.admin.DevicePolicyResources.Strings.Settings.PERSONAL_CATEGORY_HEADER;
-import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_CATEGORY_HEADER;
-import static android.widget.LinearLayout.LayoutParams.MATCH_PARENT;
-import static android.widget.LinearLayout.LayoutParams.WRAP_CONTENT;
-
-import android.animation.LayoutTransition;
-import android.annotation.UiThread;
-import android.app.Activity;
-import android.app.KeyguardManager;
-import android.app.admin.DevicePolicyManager;
 import android.app.settings.SettingsEnums;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.UserInfo;
-import android.content.res.TypedArray;
-import android.database.DataSetObserver;
-import android.graphics.drawable.Drawable;
-import android.net.http.SslCertificate;
-import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.RemoteException;
-import android.os.UserHandle;
-import android.os.UserManager;
 import android.security.IKeyChainService;
-import android.security.KeyChain;
-import android.security.KeyChain.KeyChainConnection;
-import android.util.ArraySet;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.BaseExpandableListAdapter;
-import android.widget.ExpandableListView;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.ProgressBar;
-import android.widget.Switch;
-import android.widget.TabHost;
-import android.widget.TextView;
 
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.app.UnlaunchableAppActivity;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.core.InstrumentedFragment;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.viewpager2.adapter.FragmentStateAdapter;
+import androidx.viewpager2.widget.ViewPager2;
 
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collections;
+import com.android.settings.dashboard.DashboardFragment;
+
+import com.google.android.material.tabs.TabLayout;
+import com.google.android.material.tabs.TabLayoutMediator;
+import com.google.common.collect.ImmutableList;
+
 import java.util.List;
-import java.util.Set;
-import java.util.function.IntConsumer;
 
-public class TrustedCredentialsSettings extends InstrumentedFragment
-        implements TrustedCredentialsDialogBuilder.DelegateInterface {
-
-    public static final String ARG_SHOW_NEW_FOR_USER = "ARG_SHOW_NEW_FOR_USER";
+/**
+ * Main fragment to display trusted credentials settings.
+ */
+public class TrustedCredentialsSettings extends DashboardFragment {
 
     private static final String TAG = "TrustedCredentialsSettings";
 
-    private DevicePolicyManager mDevicePolicyManager;
-    private UserManager mUserManager;
-    private KeyguardManager mKeyguardManager;
-    private int mTrustAllCaUserId;
+    public static final String ARG_SHOW_NEW_FOR_USER = "ARG_SHOW_NEW_FOR_USER";
 
-    private static final String SAVED_CONFIRMED_CREDENTIAL_USERS = "ConfirmedCredentialUsers";
-    private static final String SAVED_CONFIRMING_CREDENTIAL_USER = "ConfirmingCredentialUser";
+    static final ImmutableList<Tab> TABS = ImmutableList.of(Tab.SYSTEM, Tab.USER);
+
     private static final String USER_ACTION = "com.android.settings.TRUSTED_CREDENTIALS_USER";
-    private static final int REQUEST_CONFIRM_CREDENTIALS = 1;
 
     @Override
     public int getMetricsCategory() {
         return SettingsEnums.TRUSTED_CREDENTIALS;
     }
 
-    private enum Tab {
-        SYSTEM("system",
-                R.string.trusted_credentials_system_tab,
-                R.id.system_tab,
-                R.id.system_progress,
-                R.id.system_content,
-                true),
-        USER("user",
-                R.string.trusted_credentials_user_tab,
-                R.id.user_tab,
-                R.id.user_progress,
-                R.id.user_content,
-                false);
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        getActivity().setTitle(R.string.trusted_credentials);
+    }
 
-        private final String mTag;
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.placeholder_preference_screen;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+        View tabContainer = view.findViewById(R.id.tab_container);
+        tabContainer.setVisibility(View.VISIBLE);
+
+        ViewPager2 viewPager = tabContainer.findViewById(R.id.view_pager);
+        viewPager.setAdapter(new FragmentAdapter(this));
+        viewPager.setUserInputEnabled(false);
+
+        Intent intent = getActivity().getIntent();
+        if (intent != null && USER_ACTION.equals(intent.getAction())) {
+            viewPager.setCurrentItem(TABS.indexOf(Tab.USER), false);
+        }
+
+        TabLayout tabLayout = tabContainer.findViewById(R.id.tabs);
+        new TabLayoutMediator(tabLayout, viewPager, false, false,
+                (tab, position) -> tab.setText(TABS.get(position).mLabel)).attach();
+    }
+
+    private static class FragmentAdapter extends FragmentStateAdapter {
+        FragmentAdapter(Fragment fragment) {
+            super(fragment);
+        }
+
+        @NonNull
+        @Override
+        public Fragment createFragment(int position) {
+            TrustedCredentialsFragment fragment = new TrustedCredentialsFragment();
+            Bundle args = new Bundle();
+            args.putInt(TrustedCredentialsFragment.ARG_POSITION, position);
+            fragment.setArguments(args);
+            return fragment;
+        }
+
+        @Override
+        public int getItemCount() {
+            return TrustedCredentialsSettings.TABS.size();
+        }
+    }
+
+    enum Tab {
+        SYSTEM(R.string.trusted_credentials_system_tab, true),
+        USER(R.string.trusted_credentials_user_tab, false);
+
         private final int mLabel;
-        private final int mView;
-        private final int mProgress;
-        private final int mContentView;
-        private final boolean mSwitch;
+        final boolean mSwitch;
 
-        private Tab(String tag, int label, int view, int progress, int contentView,
-                boolean withSwitch) {
-            mTag = tag;
+        Tab(int label, boolean withSwitch) {
             mLabel = label;
-            mView = view;
-            mProgress = progress;
-            mContentView = contentView;
             mSwitch = withSwitch;
         }
 
-        private List<String> getAliases(IKeyChainService service) throws RemoteException {
+        List<String> getAliases(IKeyChainService service) throws RemoteException {
             switch (this) {
                 case SYSTEM: {
                     return service.getSystemCaAliases().getList();
@@ -140,7 +133,8 @@
             }
             throw new AssertionError();
         }
-        private boolean deleted(IKeyChainService service, String alias) throws RemoteException {
+
+        boolean deleted(IKeyChainService service, String alias) throws RemoteException {
             switch (this) {
                 case SYSTEM:
                     return !service.containsCaAlias(alias);
@@ -150,895 +144,4 @@
             throw new AssertionError();
         }
     }
-
-    private TabHost mTabHost;
-    private ArrayList<GroupAdapter> mGroupAdapters = new ArrayList<>(2);
-    private AliasOperation mAliasOperation;
-    private ArraySet<Integer> mConfirmedCredentialUsers;
-    private int mConfirmingCredentialUser;
-    private IntConsumer mConfirmingCredentialListener;
-    private Set<AdapterData.AliasLoader> mAliasLoaders = new ArraySet<AdapterData.AliasLoader>(2);
-    @GuardedBy("mKeyChainConnectionByProfileId")
-    private final SparseArray<KeyChainConnection>
-            mKeyChainConnectionByProfileId = new SparseArray<KeyChainConnection>();
-
-    private BroadcastReceiver mWorkProfileChangedReceiver = new BroadcastReceiver() {
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(action) ||
-                    Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action) ||
-                    Intent.ACTION_MANAGED_PROFILE_UNLOCKED.equals(action)) {
-                for (GroupAdapter adapter : mGroupAdapters) {
-                    adapter.load();
-                }
-            }
-        }
-
-    };
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        final Activity activity = getActivity();
-        mDevicePolicyManager = activity.getSystemService(DevicePolicyManager.class);
-        mUserManager = (UserManager) activity.getSystemService(Context.USER_SERVICE);
-        mKeyguardManager = (KeyguardManager) activity
-                .getSystemService(Context.KEYGUARD_SERVICE);
-        mTrustAllCaUserId = activity.getIntent().getIntExtra(ARG_SHOW_NEW_FOR_USER,
-                UserHandle.USER_NULL);
-        mConfirmedCredentialUsers = new ArraySet<>(2);
-        mConfirmingCredentialUser = UserHandle.USER_NULL;
-        if (savedInstanceState != null) {
-            mConfirmingCredentialUser = savedInstanceState.getInt(SAVED_CONFIRMING_CREDENTIAL_USER,
-                    UserHandle.USER_NULL);
-            ArrayList<Integer> users = savedInstanceState.getIntegerArrayList(
-                    SAVED_CONFIRMED_CREDENTIAL_USERS);
-            if (users != null) {
-                mConfirmedCredentialUsers.addAll(users);
-            }
-        }
-
-        mConfirmingCredentialListener = null;
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
-        filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
-        filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
-        activity.registerReceiver(mWorkProfileChangedReceiver, filter);
-
-        activity.setTitle(R.string.trusted_credentials);
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        outState.putIntegerArrayList(SAVED_CONFIRMED_CREDENTIAL_USERS, new ArrayList<>(
-                mConfirmedCredentialUsers));
-        outState.putInt(SAVED_CONFIRMING_CREDENTIAL_USER, mConfirmingCredentialUser);
-    }
-
-    @Override public View onCreateView(
-            LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
-        mTabHost = (TabHost) inflater.inflate(R.layout.trusted_credentials, parent, false);
-        mTabHost.setup();
-        addTab(Tab.SYSTEM);
-        // TODO add Install button on Tab.USER to go to CertInstaller like KeyChainActivity
-        addTab(Tab.USER);
-        if (getActivity().getIntent() != null &&
-                USER_ACTION.equals(getActivity().getIntent().getAction())) {
-            mTabHost.setCurrentTabByTag(Tab.USER.mTag);
-        }
-        return mTabHost;
-    }
-    @Override
-    public void onDestroy() {
-        getActivity().unregisterReceiver(mWorkProfileChangedReceiver);
-        for (AdapterData.AliasLoader aliasLoader : mAliasLoaders) {
-            aliasLoader.cancel(true);
-        }
-        mAliasLoaders.clear();
-        mGroupAdapters.clear();
-        if (mAliasOperation != null) {
-            mAliasOperation.cancel(true);
-            mAliasOperation = null;
-        }
-        closeKeyChainConnections();
-        super.onDestroy();
-    }
-
-    @Override
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (requestCode == REQUEST_CONFIRM_CREDENTIALS) {
-            int userId = mConfirmingCredentialUser;
-            IntConsumer listener = mConfirmingCredentialListener;
-            // reset them before calling the listener because the listener may call back to start
-            // activity again. (though it should never happen.)
-            mConfirmingCredentialUser = UserHandle.USER_NULL;
-            mConfirmingCredentialListener = null;
-            if (resultCode == Activity.RESULT_OK) {
-                mConfirmedCredentialUsers.add(userId);
-                if (listener != null) {
-                    listener.accept(userId);
-                }
-            }
-        }
-    }
-
-    private void closeKeyChainConnections() {
-        synchronized (mKeyChainConnectionByProfileId) {
-            final int n = mKeyChainConnectionByProfileId.size();
-            for (int i = 0; i < n; ++i) {
-                mKeyChainConnectionByProfileId.valueAt(i).close();
-            }
-            mKeyChainConnectionByProfileId.clear();
-        }
-    }
-
-    private void addTab(Tab tab) {
-        TabHost.TabSpec systemSpec = mTabHost.newTabSpec(tab.mTag)
-                .setIndicator(getActivity().getString(tab.mLabel))
-                .setContent(tab.mView);
-        mTabHost.addTab(systemSpec);
-
-        final GroupAdapter groupAdapter = new GroupAdapter(tab);
-        mGroupAdapters.add(groupAdapter);
-        final int profilesSize = groupAdapter.getGroupCount();
-
-        // Add a transition for non-visibility events like resizing the pane.
-        final ViewGroup contentView = (ViewGroup) mTabHost.findViewById(tab.mContentView);
-        contentView.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
-
-        final LayoutInflater inflater = LayoutInflater.from(getActivity());
-        for (int i = 0; i < groupAdapter.getGroupCount(); i++) {
-            final boolean isWork = groupAdapter.getUserInfoByGroup(i).isManagedProfile();
-            final ChildAdapter adapter = groupAdapter.getChildAdapter(i);
-
-            final LinearLayout containerView = (LinearLayout) inflater
-                    .inflate(R.layout.trusted_credential_list_container, contentView, false);
-            adapter.setContainerView(containerView);
-
-            adapter.showHeader(profilesSize > 1);
-            adapter.showDivider(isWork);
-            adapter.setExpandIfAvailable(profilesSize <= 2 ? true : !isWork);
-            if (isWork) {
-                contentView.addView(containerView);
-            } else {
-                contentView.addView(containerView, 0);
-            }
-        }
-    }
-
-    /**
-     * Start work challenge activity.
-     * @return true if screenlock exists
-     */
-    private boolean startConfirmCredential(int userId) {
-        final Intent newIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, null,
-                userId);
-        if (newIntent == null) {
-            return false;
-        }
-        mConfirmingCredentialUser = userId;
-        startActivityForResult(newIntent, REQUEST_CONFIRM_CREDENTIALS);
-        return true;
-    }
-
-    /**
-     * Adapter for expandable list view of certificates. Groups in the view correspond to profiles
-     * whereas children correspond to certificates.
-     */
-    private class GroupAdapter extends BaseExpandableListAdapter implements
-            ExpandableListView.OnGroupClickListener, ExpandableListView.OnChildClickListener,
-            View.OnClickListener {
-        private final AdapterData mData;
-
-        private GroupAdapter(Tab tab) {
-            mData = new AdapterData(tab, this);
-            load();
-        }
-
-        @Override
-        public int getGroupCount() {
-            return mData.mCertHoldersByUserId.size();
-        }
-        @Override
-        public int getChildrenCount(int groupPosition) {
-            List<CertHolder> certHolders = mData.mCertHoldersByUserId.valueAt(groupPosition);
-            if (certHolders != null) {
-                return certHolders.size();
-            }
-            return 0;
-        }
-        @Override
-        public UserHandle getGroup(int groupPosition) {
-            return new UserHandle(mData.mCertHoldersByUserId.keyAt(groupPosition));
-        }
-        @Override
-        public CertHolder getChild(int groupPosition, int childPosition) {
-            return mData.mCertHoldersByUserId.get(getUserIdByGroup(groupPosition)).get(
-                    childPosition);
-        }
-        @Override
-        public long getGroupId(int groupPosition) {
-            return getUserIdByGroup(groupPosition);
-        }
-        private int getUserIdByGroup(int groupPosition) {
-            return mData.mCertHoldersByUserId.keyAt(groupPosition);
-        }
-        public UserInfo getUserInfoByGroup(int groupPosition) {
-            return mUserManager.getUserInfo(getUserIdByGroup(groupPosition));
-        }
-        @Override
-        public long getChildId(int groupPosition, int childPosition) {
-            return childPosition;
-        }
-        @Override
-        public boolean hasStableIds() {
-            return false;
-        }
-        @Override
-        public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
-                ViewGroup parent) {
-            if (convertView == null) {
-                LayoutInflater inflater = (LayoutInflater) getActivity()
-                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-                convertView = Utils.inflateCategoryHeader(inflater, parent);
-            }
-
-            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
-            if (getUserInfoByGroup(groupPosition).isManagedProfile()) {
-                title.setText(mDevicePolicyManager.getResources().getString(WORK_CATEGORY_HEADER,
-                        () -> getString(R.string.category_work)));
-            } else {
-                title.setText(mDevicePolicyManager.getResources().getString(
-                        PERSONAL_CATEGORY_HEADER,
-                        () -> getString(R.string.category_personal)));
-
-            }
-            title.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
-
-            return convertView;
-        }
-        @Override
-        public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
-                View convertView, ViewGroup parent) {
-            return getViewForCertificate(getChild(groupPosition, childPosition), mData.mTab,
-                    convertView, parent);
-        }
-        @Override
-        public boolean isChildSelectable(int groupPosition, int childPosition) {
-            return true;
-        }
-
-        @Override
-        public boolean onChildClick(ExpandableListView expandableListView, View view,
-                int groupPosition, int childPosition, long id) {
-            showCertDialog(getChild(groupPosition, childPosition));
-            return true;
-        }
-
-        /**
-         * Called when the switch on a system certificate is clicked. This will toggle whether it
-         * is trusted as a credential.
-         */
-        @Override
-        public void onClick(View view) {
-            CertHolder holder = (CertHolder) view.getTag();
-            removeOrInstallCert(holder);
-        }
-
-        @Override
-        public boolean onGroupClick(ExpandableListView expandableListView, View view,
-                int groupPosition, long id) {
-            return !checkGroupExpandableAndStartWarningActivity(groupPosition);
-        }
-
-        public void load() {
-            mData.new AliasLoader().execute();
-        }
-
-        public void remove(CertHolder certHolder) {
-            mData.remove(certHolder);
-        }
-
-        public void setExpandableListView(ExpandableListView lv) {
-            lv.setAdapter(this);
-            lv.setOnGroupClickListener(this);
-            lv.setOnChildClickListener(this);
-            lv.setVisibility(View.VISIBLE);
-        }
-
-        public ChildAdapter getChildAdapter(int groupPosition) {
-            return new ChildAdapter(this, groupPosition);
-        }
-
-        public boolean checkGroupExpandableAndStartWarningActivity(int groupPosition) {
-            return checkGroupExpandableAndStartWarningActivity(groupPosition, true);
-        }
-
-        public boolean checkGroupExpandableAndStartWarningActivity(int groupPosition,
-                boolean startActivity) {
-            final UserHandle groupUser = getGroup(groupPosition);
-            final int groupUserId = groupUser.getIdentifier();
-            if (mUserManager.isQuietModeEnabled(groupUser)) {
-                final Intent intent = UnlaunchableAppActivity.createInQuietModeDialogIntent(
-                        groupUserId);
-                if (startActivity) {
-                    getActivity().startActivity(intent);
-                }
-                return false;
-            } else if (!mUserManager.isUserUnlocked(groupUser)) {
-                final LockPatternUtils lockPatternUtils = new LockPatternUtils(
-                        getActivity());
-                if (lockPatternUtils.isSeparateProfileChallengeEnabled(groupUserId)) {
-                    if (startActivity) {
-                        startConfirmCredential(groupUserId);
-                    }
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        private View getViewForCertificate(CertHolder certHolder, Tab mTab, View convertView,
-                ViewGroup parent) {
-            ViewHolder holder;
-            if (convertView == null) {
-                holder = new ViewHolder();
-                LayoutInflater inflater = LayoutInflater.from(getActivity());
-                convertView = inflater.inflate(R.layout.trusted_credential, parent, false);
-                convertView.setTag(holder);
-                holder.mSubjectPrimaryView = (TextView)
-                        convertView.findViewById(R.id.trusted_credential_subject_primary);
-                holder.mSubjectSecondaryView = (TextView)
-                        convertView.findViewById(R.id.trusted_credential_subject_secondary);
-                holder.mSwitch = (Switch) convertView.findViewById(
-                        R.id.trusted_credential_status);
-                holder.mSwitch.setOnClickListener(this);
-            } else {
-                holder = (ViewHolder) convertView.getTag();
-            }
-            holder.mSubjectPrimaryView.setText(certHolder.mSubjectPrimary);
-            holder.mSubjectSecondaryView.setText(certHolder.mSubjectSecondary);
-            if (mTab.mSwitch) {
-                holder.mSwitch.setChecked(!certHolder.mDeleted);
-                holder.mSwitch.setEnabled(!mUserManager.hasUserRestriction(
-                        UserManager.DISALLOW_CONFIG_CREDENTIALS,
-                        new UserHandle(certHolder.mProfileId)));
-                holder.mSwitch.setVisibility(View.VISIBLE);
-                holder.mSwitch.setTag(certHolder);
-            }
-            return convertView;
-        }
-
-        private class ViewHolder {
-            private TextView mSubjectPrimaryView;
-            private TextView mSubjectSecondaryView;
-            private Switch mSwitch;
-        }
-    }
-
-    private class ChildAdapter extends BaseAdapter implements View.OnClickListener,
-            AdapterView.OnItemClickListener {
-        private final int[] GROUP_EXPANDED_STATE_SET = {com.android.internal.R.attr.state_expanded};
-        private final int[] EMPTY_STATE_SET = {};
-        private final LinearLayout.LayoutParams HIDE_CONTAINER_LAYOUT_PARAMS =
-                new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT, 0f);
-        private final LinearLayout.LayoutParams HIDE_LIST_LAYOUT_PARAMS =
-                new LinearLayout.LayoutParams(MATCH_PARENT, 0);
-        private final LinearLayout.LayoutParams SHOW_LAYOUT_PARAMS = new LinearLayout.LayoutParams(
-                LinearLayout.LayoutParams.MATCH_PARENT, MATCH_PARENT, 1f);
-        private final GroupAdapter mParent;
-        private final int mGroupPosition;
-        /*
-         * This class doesn't hold the actual data. Events should notify parent.
-         * When notifying DataSet events in this class, events should be forwarded to mParent.
-         * i.e. this.notifyDataSetChanged -> mParent.notifyDataSetChanged -> mObserver.onChanged
-         * -> outsideObservers.onChanged() (e.g. ListView)
-         */
-        private final DataSetObserver mObserver = new DataSetObserver() {
-            @Override
-            public void onChanged() {
-                super.onChanged();
-                ChildAdapter.super.notifyDataSetChanged();
-            }
-            @Override
-            public void onInvalidated() {
-                super.onInvalidated();
-                ChildAdapter.super.notifyDataSetInvalidated();
-            }
-        };
-
-        private boolean mIsListExpanded = true;
-        private LinearLayout mContainerView;
-        private ViewGroup mHeaderView;
-        private ListView mListView;
-        private ImageView mIndicatorView;
-
-        private ChildAdapter(GroupAdapter parent, int groupPosition) {
-            mParent = parent;
-            mGroupPosition = groupPosition;
-            mParent.registerDataSetObserver(mObserver);
-        }
-
-        @Override public int getCount() {
-            return mParent.getChildrenCount(mGroupPosition);
-        }
-        @Override public CertHolder getItem(int position) {
-            return mParent.getChild(mGroupPosition, position);
-        }
-        @Override public long getItemId(int position) {
-            return mParent.getChildId(mGroupPosition, position);
-        }
-        @Override public View getView(int position, View convertView, ViewGroup parent) {
-            return mParent.getChildView(mGroupPosition, position, false, convertView, parent);
-        }
-        // DataSet events
-        @Override
-        public void notifyDataSetChanged() {
-            // Don't call super as the parent will propagate this event back later in mObserver
-            mParent.notifyDataSetChanged();
-        }
-        @Override
-        public void notifyDataSetInvalidated() {
-            // Don't call super as the parent will propagate this event back later in mObserver
-            mParent.notifyDataSetInvalidated();
-        }
-
-        // View related codes
-        @Override
-        public void onClick(View view) {
-            mIsListExpanded = checkGroupExpandableAndStartWarningActivity() && !mIsListExpanded;
-            refreshViews();
-        }
-
-        @Override
-        public void onItemClick(AdapterView<?> adapterView, View view, int pos, long id) {
-            showCertDialog(getItem(pos));
-        }
-
-        public void setContainerView(LinearLayout containerView) {
-            mContainerView = containerView;
-
-            mListView = (ListView) mContainerView.findViewById(R.id.cert_list);
-            mListView.setAdapter(this);
-            mListView.setOnItemClickListener(this);
-            mListView.setItemsCanFocus(true);
-
-            mHeaderView = (ViewGroup) mContainerView.findViewById(R.id.header_view);
-            mHeaderView.setOnClickListener(this);
-
-            mIndicatorView = (ImageView) mHeaderView.findViewById(R.id.group_indicator);
-            mIndicatorView.setImageDrawable(getGroupIndicator());
-
-            FrameLayout headerContentContainer = (FrameLayout)
-                    mHeaderView.findViewById(R.id.header_content_container);
-            headerContentContainer.addView(
-                    mParent.getGroupView(mGroupPosition, true /* parent ignores it */, null,
-                            headerContentContainer));
-        }
-
-        public void showHeader(boolean showHeader) {
-            mHeaderView.setVisibility(showHeader ? View.VISIBLE : View.GONE);
-        }
-
-        public void showDivider(boolean showDivider) {
-            View dividerView = mHeaderView.findViewById(R.id.header_divider);
-            dividerView.setVisibility(showDivider ? View.VISIBLE : View.GONE );
-        }
-
-        public void setExpandIfAvailable(boolean expanded) {
-            mIsListExpanded = expanded && mParent.checkGroupExpandableAndStartWarningActivity(
-                    mGroupPosition, false /* startActivity */);
-            refreshViews();
-        }
-
-        private boolean checkGroupExpandableAndStartWarningActivity() {
-            return mParent.checkGroupExpandableAndStartWarningActivity(mGroupPosition);
-        }
-
-        private void refreshViews() {
-            mIndicatorView.setImageState(mIsListExpanded ? GROUP_EXPANDED_STATE_SET
-                    : EMPTY_STATE_SET, false);
-            mListView.setLayoutParams(mIsListExpanded ? SHOW_LAYOUT_PARAMS
-                    : HIDE_LIST_LAYOUT_PARAMS);
-            mContainerView.setLayoutParams(mIsListExpanded ? SHOW_LAYOUT_PARAMS
-                    : HIDE_CONTAINER_LAYOUT_PARAMS);
-        }
-
-        // Get group indicator from styles of ExpandableListView
-        private Drawable getGroupIndicator() {
-            final TypedArray a = getActivity().obtainStyledAttributes(null,
-                    com.android.internal.R.styleable.ExpandableListView,
-                    com.android.internal.R.attr.expandableListViewStyle, 0);
-            Drawable groupIndicator = a.getDrawable(
-                    com.android.internal.R.styleable.ExpandableListView_groupIndicator);
-            a.recycle();
-            return groupIndicator;
-        }
-    }
-
-    private class AdapterData {
-        private final SparseArray<List<CertHolder>> mCertHoldersByUserId =
-                new SparseArray<List<CertHolder>>();
-        private final Tab mTab;
-        private final GroupAdapter mAdapter;
-
-        private AdapterData(Tab tab, GroupAdapter adapter) {
-            mAdapter = adapter;
-            mTab = tab;
-        }
-
-        private class AliasLoader extends AsyncTask<Void, Integer, SparseArray<List<CertHolder>>> {
-            private ProgressBar mProgressBar;
-            private View mContentView;
-            private Context mContext;
-
-            public AliasLoader() {
-                mContext = getActivity();
-                mAliasLoaders.add(this);
-                List<UserHandle> profiles = mUserManager.getUserProfiles();
-                for (UserHandle profile : profiles) {
-                    mCertHoldersByUserId.put(profile.getIdentifier(), new ArrayList<CertHolder>());
-                }
-            }
-
-            private boolean shouldSkipProfile(UserHandle userHandle) {
-                return mUserManager.isQuietModeEnabled(userHandle)
-                        || !mUserManager.isUserUnlocked(userHandle.getIdentifier());
-            }
-
-            @Override protected void onPreExecute() {
-                View content = mTabHost.getTabContentView();
-                mProgressBar = (ProgressBar) content.findViewById(mTab.mProgress);
-                mContentView = content.findViewById(mTab.mContentView);
-                mProgressBar.setVisibility(View.VISIBLE);
-                mContentView.setVisibility(View.GONE);
-            }
-            @Override protected SparseArray<List<CertHolder>> doInBackground(Void... params) {
-                SparseArray<List<CertHolder>> certHoldersByProfile =
-                        new SparseArray<List<CertHolder>>();
-                try {
-                    synchronized(mKeyChainConnectionByProfileId) {
-                        List<UserHandle> profiles = mUserManager.getUserProfiles();
-                        final int n = profiles.size();
-                        // First we get all aliases for all profiles in order to show progress
-                        // correctly. Otherwise this could all be in a single loop.
-                        SparseArray<List<String>> aliasesByProfileId = new SparseArray<
-                                List<String>>(n);
-                        int max = 0;
-                        int progress = 0;
-                        for (int i = 0; i < n; ++i) {
-                            UserHandle profile = profiles.get(i);
-                            int profileId = profile.getIdentifier();
-                            if (shouldSkipProfile(profile)) {
-                                continue;
-                            }
-                            KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext,
-                                    profile);
-                            // Saving the connection for later use on the certificate dialog.
-                            mKeyChainConnectionByProfileId.put(profileId, keyChainConnection);
-                            IKeyChainService service = keyChainConnection.getService();
-                            List<String> aliases = mTab.getAliases(service);
-                            if (isCancelled()) {
-                                return new SparseArray<List<CertHolder>>();
-                            }
-                            max += aliases.size();
-                            aliasesByProfileId.put(profileId, aliases);
-                        }
-                        for (int i = 0; i < n; ++i) {
-                            UserHandle profile = profiles.get(i);
-                            int profileId = profile.getIdentifier();
-                            List<String> aliases = aliasesByProfileId.get(profileId);
-                            if (isCancelled()) {
-                                return new SparseArray<List<CertHolder>>();
-                            }
-                            KeyChainConnection keyChainConnection = mKeyChainConnectionByProfileId.get(
-                                    profileId);
-                            if (shouldSkipProfile(profile) || aliases == null
-                                    || keyChainConnection == null) {
-                                certHoldersByProfile.put(profileId, new ArrayList<CertHolder>(0));
-                                continue;
-                            }
-                            IKeyChainService service = keyChainConnection.getService();
-                            List<CertHolder> certHolders = new ArrayList<CertHolder>(max);
-                            final int aliasMax = aliases.size();
-                            for (int j = 0; j < aliasMax; ++j) {
-                                String alias = aliases.get(j);
-                                byte[] encodedCertificate = service.getEncodedCaCertificate(alias,
-                                        true);
-                                X509Certificate cert = KeyChain.toCertificate(encodedCertificate);
-                                certHolders.add(new CertHolder(service, mAdapter,
-                                        mTab, alias, cert, profileId));
-                                publishProgress(++progress, max);
-                            }
-                            Collections.sort(certHolders);
-                            certHoldersByProfile.put(profileId, certHolders);
-                        }
-                        return certHoldersByProfile;
-                    }
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Remote exception while loading aliases.", e);
-                    return new SparseArray<List<CertHolder>>();
-                } catch (InterruptedException e) {
-                    Log.e(TAG, "InterruptedException while loading aliases.", e);
-                    return new SparseArray<List<CertHolder>>();
-                }
-            }
-            @Override protected void onProgressUpdate(Integer... progressAndMax) {
-                int progress = progressAndMax[0];
-                int max = progressAndMax[1];
-                if (max != mProgressBar.getMax()) {
-                    mProgressBar.setMax(max);
-                }
-                mProgressBar.setProgress(progress);
-            }
-            @Override protected void onPostExecute(SparseArray<List<CertHolder>> certHolders) {
-                mCertHoldersByUserId.clear();
-                final int n = certHolders.size();
-                for (int i = 0; i < n; ++i) {
-                    mCertHoldersByUserId.put(certHolders.keyAt(i), certHolders.valueAt(i));
-                }
-                mAdapter.notifyDataSetChanged();
-                mProgressBar.setVisibility(View.GONE);
-                mContentView.setVisibility(View.VISIBLE);
-                mProgressBar.setProgress(0);
-                mAliasLoaders.remove(this);
-                showTrustAllCaDialogIfNeeded();
-            }
-
-            private boolean isUserTabAndTrustAllCertMode() {
-                return isTrustAllCaCertModeInProgress() && mTab == Tab.USER;
-            }
-
-            @UiThread
-            private void showTrustAllCaDialogIfNeeded() {
-                if (!isUserTabAndTrustAllCertMode()) {
-                    return;
-                }
-                List<CertHolder> certHolders = mCertHoldersByUserId.get(mTrustAllCaUserId);
-                if (certHolders == null) {
-                    return;
-                }
-
-                List<CertHolder> unapprovedUserCertHolders = new ArrayList<>();
-                final DevicePolicyManager dpm = mContext.getSystemService(
-                        DevicePolicyManager.class);
-                for (CertHolder cert : certHolders) {
-                    if (cert != null && !dpm.isCaCertApproved(cert.mAlias, mTrustAllCaUserId)) {
-                        unapprovedUserCertHolders.add(cert);
-                    }
-                }
-
-                if (unapprovedUserCertHolders.size() == 0) {
-                    Log.w(TAG, "no cert is pending approval for user " + mTrustAllCaUserId);
-                    return;
-                }
-                showTrustAllCaDialog(unapprovedUserCertHolders);
-            }
-        }
-
-        public void remove(CertHolder certHolder) {
-            if (mCertHoldersByUserId != null) {
-                final List<CertHolder> certs = mCertHoldersByUserId.get(certHolder.mProfileId);
-                if (certs != null) {
-                    certs.remove(certHolder);
-                }
-            }
-        }
-    }
-
-    /* package */ static class CertHolder implements Comparable<CertHolder> {
-        public int mProfileId;
-        private final IKeyChainService mService;
-        private final GroupAdapter mAdapter;
-        private final Tab mTab;
-        private final String mAlias;
-        private final X509Certificate mX509Cert;
-
-        private final SslCertificate mSslCert;
-        private final String mSubjectPrimary;
-        private final String mSubjectSecondary;
-        private boolean mDeleted;
-
-        private CertHolder(IKeyChainService service,
-                           GroupAdapter adapter,
-                           Tab tab,
-                           String alias,
-                           X509Certificate x509Cert,
-                           int profileId) {
-            mProfileId = profileId;
-            mService = service;
-            mAdapter = adapter;
-            mTab = tab;
-            mAlias = alias;
-            mX509Cert = x509Cert;
-
-            mSslCert = new SslCertificate(x509Cert);
-
-            String cn = mSslCert.getIssuedTo().getCName();
-            String o = mSslCert.getIssuedTo().getOName();
-            String ou = mSslCert.getIssuedTo().getUName();
-            // if we have a O, use O as primary subject, secondary prefer CN over OU
-            // if we don't have an O, use CN as primary, empty secondary
-            // if we don't have O or CN, use DName as primary, empty secondary
-            if (!o.isEmpty()) {
-                if (!cn.isEmpty()) {
-                    mSubjectPrimary = o;
-                    mSubjectSecondary = cn;
-                } else {
-                    mSubjectPrimary = o;
-                    mSubjectSecondary = ou;
-                }
-            } else {
-                if (!cn.isEmpty()) {
-                    mSubjectPrimary = cn;
-                    mSubjectSecondary = "";
-                } else {
-                    mSubjectPrimary = mSslCert.getIssuedTo().getDName();
-                    mSubjectSecondary = "";
-                }
-            }
-            try {
-                mDeleted = mTab.deleted(mService, mAlias);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Remote exception while checking if alias " + mAlias + " is deleted.",
-                        e);
-                mDeleted = false;
-            }
-        }
-        @Override public int compareTo(CertHolder o) {
-            int primary = this.mSubjectPrimary.compareToIgnoreCase(o.mSubjectPrimary);
-            if (primary != 0) {
-                return primary;
-            }
-            return this.mSubjectSecondary.compareToIgnoreCase(o.mSubjectSecondary);
-        }
-        @Override public boolean equals(Object o) {
-            if (!(o instanceof CertHolder)) {
-                return false;
-            }
-            CertHolder other = (CertHolder) o;
-            return mAlias.equals(other.mAlias);
-        }
-        @Override public int hashCode() {
-            return mAlias.hashCode();
-        }
-
-        public int getUserId() {
-            return mProfileId;
-        }
-
-        public String getAlias() {
-            return mAlias;
-        }
-
-        public boolean isSystemCert() {
-            return mTab == Tab.SYSTEM;
-        }
-
-        public boolean isDeleted() {
-            return mDeleted;
-        }
-    }
-
-
-    private boolean isTrustAllCaCertModeInProgress() {
-        return mTrustAllCaUserId != UserHandle.USER_NULL;
-    }
-
-    private void showTrustAllCaDialog(List<CertHolder> unapprovedCertHolders) {
-        final CertHolder[] arr = unapprovedCertHolders.toArray(
-                new CertHolder[unapprovedCertHolders.size()]);
-        new TrustedCredentialsDialogBuilder(getActivity(), this)
-                .setCertHolders(arr)
-                .setOnDismissListener(new DialogInterface.OnDismissListener() {
-                    @Override
-                    public void onDismiss(DialogInterface dialogInterface) {
-                        // Avoid starting dialog again after Activity restart.
-                        getActivity().getIntent().removeExtra(ARG_SHOW_NEW_FOR_USER);
-                        mTrustAllCaUserId = UserHandle.USER_NULL;
-                    }
-                })
-                .show();
-    }
-
-    private void showCertDialog(final CertHolder certHolder) {
-        new TrustedCredentialsDialogBuilder(getActivity(), this)
-                .setCertHolder(certHolder)
-                .show();
-    }
-
-    @Override
-    public List<X509Certificate> getX509CertsFromCertHolder(CertHolder certHolder) {
-        List<X509Certificate> certificates = null;
-        try {
-            synchronized (mKeyChainConnectionByProfileId) {
-                KeyChainConnection keyChainConnection = mKeyChainConnectionByProfileId.get(
-                        certHolder.mProfileId);
-                IKeyChainService service = keyChainConnection.getService();
-                List<String> chain = service.getCaCertificateChainAliases(certHolder.mAlias, true);
-                final int n = chain.size();
-                certificates = new ArrayList<X509Certificate>(n);
-                for (int i = 0; i < n; ++i) {
-                    byte[] encodedCertificate = service.getEncodedCaCertificate(chain.get(i), true);
-                    X509Certificate certificate = KeyChain.toCertificate(encodedCertificate);
-                    certificates.add(certificate);
-                }
-            }
-        } catch (RemoteException ex) {
-            Log.e(TAG, "RemoteException while retrieving certificate chain for root "
-                    + certHolder.mAlias, ex);
-        }
-        return certificates;
-    }
-
-    @Override
-    public void removeOrInstallCert(CertHolder certHolder) {
-        new AliasOperation(certHolder).execute();
-    }
-
-    @Override
-    public boolean startConfirmCredentialIfNotConfirmed(int userId,
-            IntConsumer onCredentialConfirmedListener) {
-        if (mConfirmedCredentialUsers.contains(userId)) {
-            // Credential has been confirmed. Don't start activity.
-            return false;
-        }
-
-        boolean result = startConfirmCredential(userId);
-        if (result) {
-            mConfirmingCredentialListener = onCredentialConfirmedListener;
-        }
-        return result;
-    }
-
-    private class AliasOperation extends AsyncTask<Void, Void, Boolean> {
-        private final CertHolder mCertHolder;
-
-        private AliasOperation(CertHolder certHolder) {
-            mCertHolder = certHolder;
-            mAliasOperation = this;
-        }
-
-        @Override
-        protected Boolean doInBackground(Void... params) {
-            try {
-                synchronized (mKeyChainConnectionByProfileId) {
-                    KeyChainConnection keyChainConnection = mKeyChainConnectionByProfileId.get(
-                            mCertHolder.mProfileId);
-                    IKeyChainService service = keyChainConnection.getService();
-                    if (mCertHolder.mDeleted) {
-                        byte[] bytes = mCertHolder.mX509Cert.getEncoded();
-                        service.installCaCertificate(bytes);
-                        return true;
-                    } else {
-                        return service.deleteCaCertificate(mCertHolder.mAlias);
-                    }
-                }
-            } catch (CertificateEncodingException | SecurityException | IllegalStateException
-                    | RemoteException e) {
-                Log.w(TAG, "Error while toggling alias " + mCertHolder.mAlias, e);
-                return false;
-            }
-        }
-
-        @Override
-        protected void onPostExecute(Boolean ok) {
-            if (ok) {
-                if (mCertHolder.mTab.mSwitch) {
-                    mCertHolder.mDeleted = !mCertHolder.mDeleted;
-                } else {
-                    mCertHolder.mAdapter.remove(mCertHolder);
-                }
-                mCertHolder.mAdapter.notifyDataSetChanged();
-            } else {
-                // bail, reload to reset to known state
-                mCertHolder.mAdapter.load();
-            }
-            mAliasOperation = null;
-        }
-    }
 }
diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
index b397e18..34edf98 100644
--- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
@@ -172,7 +172,7 @@
         launchArgs.mPackageName = entry.getDefaultPackageName();
         launchArgs.mAppLabel = entry.getLabel();
         launchArgs.mUid = entry.getUid();
-        launchArgs.mIconId = entry.iconId;
+        launchArgs.mIconId = entry.mIconId;
         launchArgs.mConsumedPower = (int) entry.getConsumedPower();
         launchArgs.mForegroundTimeMs = isValidToShowSummary ? entry.getTimeInForegroundMs() : 0;
         launchArgs.mBackgroundTimeMs = isValidToShowSummary ? entry.getTimeInBackgroundMs() : 0;
diff --git a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
index 8dbce79..8fb0d1e 100644
--- a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
@@ -127,9 +127,9 @@
                         final int userId = UserHandle.getUserId(entry.getUid());
                         final UserHandle userHandle = new UserHandle(userId);
                         pgp.setIcon(mUserManager.getBadgedIconForUser(entry.getIcon(), userHandle));
-                        pgp.setTitle(entry.name);
+                        pgp.setTitle(entry.mName);
                         if (entry.isAppEntry()) {
-                            pgp.setContentDescription(entry.name);
+                            pgp.setContentDescription(entry.mName);
                         }
                     }
                     break;
@@ -249,7 +249,7 @@
                             contentDescription, entry);
                     pref.setKey(key);
                 }
-                entry.percent = percentOfTotal;
+                entry.mPercent = percentOfTotal;
                 pref.setTitle(entry.getLabel());
                 pref.setOrder(i + 1);
                 pref.setPercent(percentOfTotal);
@@ -288,7 +288,7 @@
             final BatteryEntry entry = usageList.get(i);
             final double percentOfTotal = mBatteryUtils.calculateBatteryPercent(
                     entry.getConsumedPower(), totalPower, dischargePercentage);
-            entry.percent = percentOfTotal;
+            entry.mPercent = percentOfTotal;
         }
         return usageList;
     }
diff --git a/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java
index 249ee49..02248c9 100644
--- a/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java
@@ -508,7 +508,9 @@
             mBatteryHistoryKeys[mTrapezoidIndex * 2], mIs24HourFormat);
         final String toHour = ConvertUtils.utcToLocalTimeHour(mPrefContext,
             mBatteryHistoryKeys[(mTrapezoidIndex + 1) * 2], mIs24HourFormat);
-        return String.format("%s - %s", fromHour, toHour);
+        return mIs24HourFormat
+            ? String.format("%s–%s", fromHour, toHour)
+            : String.format("%s – %s", fromHour, toHour);
     }
 
     @VisibleForTesting
diff --git a/src/com/android/settings/fuelgauge/BatteryDiffEntry.java b/src/com/android/settings/fuelgauge/BatteryDiffEntry.java
index ca29cfe..5ef1110 100644
--- a/src/com/android/settings/fuelgauge/BatteryDiffEntry.java
+++ b/src/com/android/settings/fuelgauge/BatteryDiffEntry.java
@@ -171,9 +171,9 @@
         // Checks whether we have cached data or not first before fetching.
         final BatteryEntry.NameAndIcon nameAndIcon = getCache();
         if (nameAndIcon != null) {
-            mAppLabel = nameAndIcon.name;
-            mAppIcon = nameAndIcon.icon;
-            mAppIconId = nameAndIcon.iconId;
+            mAppLabel = nameAndIcon.mName;
+            mAppIcon = nameAndIcon.mIcon;
+            mAppIconId = nameAndIcon.mIconId;
         }
         final Boolean validForRestriction = sValidForRestriction.get(getKey());
         if (validForRestriction != null) {
@@ -196,8 +196,8 @@
                     BatteryEntry.getNameAndIconFromUserId(
                         mContext, (int) mBatteryHistEntry.mUserId);
                 if (nameAndIconForUser != null) {
-                    mAppIcon = nameAndIconForUser.icon;
-                    mAppLabel = nameAndIconForUser.name;
+                    mAppIcon = nameAndIconForUser.mIcon;
+                    mAppLabel = nameAndIconForUser.mName;
                     sResourceCache.put(
                         getKey(),
                         new BatteryEntry.NameAndIcon(mAppLabel, mAppIcon, /*iconId=*/ 0));
@@ -208,10 +208,10 @@
                     BatteryEntry.getNameAndIconFromPowerComponent(
                         mContext, mBatteryHistEntry.mDrainType);
                 if (nameAndIconForSystem != null) {
-                    mAppLabel = nameAndIconForSystem.name;
-                    if (nameAndIconForSystem.iconId != 0) {
-                        mAppIconId = nameAndIconForSystem.iconId;
-                        mAppIcon = mContext.getDrawable(nameAndIconForSystem.iconId);
+                    mAppLabel = nameAndIconForSystem.mName;
+                    if (nameAndIconForSystem.mIconId != 0) {
+                        mAppIconId = nameAndIconForSystem.mIconId;
+                        mAppIcon = mContext.getDrawable(nameAndIconForSystem.mIconId);
                     }
                     sResourceCache.put(
                         getKey(),
@@ -308,8 +308,8 @@
         if (packages == null || packages.length == 0) {
             final BatteryEntry.NameAndIcon nameAndIcon =
                 BatteryEntry.getNameAndIconFromUid(mContext, mAppLabel, uid);
-            mAppLabel = nameAndIcon.name;
-            mAppIcon = nameAndIcon.icon;
+            mAppLabel = nameAndIcon.mName;
+            mAppIcon = nameAndIcon.mIcon;
         }
 
         final BatteryEntry.NameAndIcon nameAndIcon =
@@ -319,13 +319,13 @@
         // Clears BatteryEntry internal cache since we will have another one.
         BatteryEntry.clearUidCache();
         if (nameAndIcon != null) {
-            mAppLabel = nameAndIcon.name;
-            mAppIcon = nameAndIcon.icon;
-            mDefaultPackageName = nameAndIcon.packageName;
+            mAppLabel = nameAndIcon.mName;
+            mAppIcon = nameAndIcon.mIcon;
+            mDefaultPackageName = nameAndIcon.mPackageName;
             if (mDefaultPackageName != null
-                    && !mDefaultPackageName.equals(nameAndIcon.packageName)) {
+                    && !mDefaultPackageName.equals(nameAndIcon.mPackageName)) {
                 Log.w(TAG, String.format("found different package: %s | %s",
-                    mDefaultPackageName, nameAndIcon.packageName));
+                    mDefaultPackageName, nameAndIcon.mPackageName));
             }
         }
     }
diff --git a/src/com/android/settings/fuelgauge/BatteryEntry.java b/src/com/android/settings/fuelgauge/BatteryEntry.java
index 5c9d071..c9acc4c 100644
--- a/src/com/android/settings/fuelgauge/BatteryEntry.java
+++ b/src/com/android/settings/fuelgauge/BatteryEntry.java
@@ -53,10 +53,10 @@
 public class BatteryEntry {
 
     public static final class NameAndIcon {
-        public final String name;
-        public final String packageName;
-        public final Drawable icon;
-        public final int iconId;
+        public final String mName;
+        public final String mPackageName;
+        public final Drawable mIcon;
+        public final int mIconId;
 
         public NameAndIcon(String name, Drawable icon, int iconId) {
             this(name, /*packageName=*/ null, icon, iconId);
@@ -64,10 +64,10 @@
 
         public NameAndIcon(
                 String name, String packageName, Drawable icon, int iconId) {
-            this.name = name;
-            this.icon = icon;
-            this.iconId = iconId;
-            this.packageName = packageName;
+            this.mName = name;
+            this.mIcon = icon;
+            this.mIconId = iconId;
+            this.mPackageName = packageName;
         }
     }
 
@@ -111,11 +111,11 @@
                 final NameAndIcon nameAndIcon =
                     BatteryEntry.loadNameAndIcon(
                         be.mContext, be.getUid(), sHandler, be,
-                        be.mDefaultPackageName, be.name, be.icon);
+                        be.mDefaultPackageName, be.mName, be.mIcon);
                 if (nameAndIcon != null) {
-                    be.icon = nameAndIcon.icon;
-                    be.name = nameAndIcon.name;
-                    be.mDefaultPackageName = nameAndIcon.packageName;
+                    be.mIcon = nameAndIcon.mIcon;
+                    be.mName = nameAndIcon.mName;
+                    be.mDefaultPackageName = nameAndIcon.mPackageName;
                 }
             }
         }
@@ -169,27 +169,27 @@
     private long mTimeInForegroundMs;
     private long mTimeInBackgroundMs;
 
-    public String name;
-    public Drawable icon;
-    public int iconId; // For passing to the detail screen.
-    public double percent;
+    public String mName;
+    public Drawable mIcon;
+    public int mIconId;
+    public double mPercent;
     private String mDefaultPackageName;
     private double mConsumedPower;
 
     static class UidToDetail {
-        String name;
-        String packageName;
-        Drawable icon;
+        String mName;
+        String mPackageName;
+        Drawable mIcon;
     }
 
     public BatteryEntry(Context context, Handler handler, UserManager um,
-            @NonNull BatteryConsumer batteryConsumer, boolean isHidden, int uid, String[] packages,
+            BatteryConsumer batteryConsumer, boolean isHidden, int uid, String[] packages,
             String packageName) {
         this(context, handler, um, batteryConsumer, isHidden, uid, packages, packageName, true);
     }
 
     public BatteryEntry(Context context, Handler handler, UserManager um,
-            @NonNull BatteryConsumer batteryConsumer, boolean isHidden, int uid, String[] packages,
+            BatteryConsumer batteryConsumer, boolean isHidden, int uid, String[] packages,
             String packageName, boolean loadDataInBackground) {
         sHandler = handler;
         mContext = context;
@@ -217,11 +217,11 @@
                 try {
                     ApplicationInfo appInfo =
                             pm.getApplicationInfo(mDefaultPackageName, 0 /* no flags */);
-                    name = pm.getApplicationLabel(appInfo).toString();
+                    mName = pm.getApplicationLabel(appInfo).toString();
                 } catch (NameNotFoundException e) {
                     Log.d(TAG, "PackageManager failed to retrieve ApplicationInfo for: "
                             + mDefaultPackageName);
-                    name = mDefaultPackageName;
+                    mName = mDefaultPackageName;
                 }
             }
             getQuickNameIconForUid(uid, packages, loadDataInBackground);
@@ -235,10 +235,10 @@
             mConsumedPower = batteryConsumer.getConsumedPower();
             final NameAndIcon nameAndIcon = getNameAndIconFromUserId(
                     context, ((UserBatteryConsumer) batteryConsumer).getUserId());
-            icon = nameAndIcon.icon;
-            name = nameAndIcon.name;
+            mIcon = nameAndIcon.mIcon;
+            mName = nameAndIcon.mName;
         } else {
-            throw new IllegalArgumentException("Unsupported battery consumer: " + batteryConsumer);
+            throw new IllegalArgumentException("Unsupported: " + batteryConsumer);
         }
     }
 
@@ -257,11 +257,12 @@
         mUsageDurationMs = usageDurationMs;
         mConsumerType = ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY;
 
-        final NameAndIcon nameAndIcon = getNameAndIconFromPowerComponent(context, powerComponentId);
-        iconId = nameAndIcon.iconId;
-        name = nameAndIcon.name;
-        if (iconId != 0) {
-            icon = context.getDrawable(iconId);
+        final NameAndIcon nameAndIcon =
+            getNameAndIconFromPowerComponent(context, powerComponentId);
+        mIconId = nameAndIcon.mIconId;
+        mName = nameAndIcon.mName;
+        if (mIconId != 0) {
+            mIcon = context.getDrawable(mIconId);
         }
     }
 
@@ -274,9 +275,9 @@
         mIsHidden = false;
         mPowerComponentId = powerComponentId;
 
-        iconId = R.drawable.ic_power_system;
-        icon = context.getDrawable(iconId);
-        name = powerComponentName;
+        mIconId = R.drawable.ic_power_system;
+        mIcon = context.getDrawable(mIconId);
+        mName = powerComponentName;
         mConsumedPower =
             powerComponentId == BatteryConsumer.POWER_COMPONENT_SCREEN
                 ? devicePowerMah
@@ -285,14 +286,11 @@
     }
 
     public Drawable getIcon() {
-        return icon;
+        return mIcon;
     }
 
-    /**
-     * Gets the application name
-     */
     public String getLabel() {
-        return name;
+        return mName;
     }
 
     @ConvertUtils.ConsumerType
@@ -317,18 +315,18 @@
         final String uidString = Integer.toString(uid);
         if (sUidCache.containsKey(uidString)) {
             UidToDetail utd = sUidCache.get(uidString);
-            mDefaultPackageName = utd.packageName;
-            name = utd.name;
-            icon = utd.icon;
+            mDefaultPackageName = utd.mPackageName;
+            mName = utd.mName;
+            mIcon = utd.mIcon;
             return;
         }
 
         if (packages == null || packages.length == 0) {
-            final NameAndIcon nameAndIcon = getNameAndIconFromUid(mContext, name, uid);
-            icon = nameAndIcon.icon;
-            name = nameAndIcon.name;
+            final NameAndIcon nameAndIcon = getNameAndIconFromUid(mContext, mName, uid);
+            mIcon = nameAndIcon.mIcon;
+            mName = nameAndIcon.mName;
         } else {
-            icon = mContext.getPackageManager().getDefaultActivityIcon();
+            mIcon = mContext.getPackageManager().getDefaultActivityIcon();
         }
 
         // Avoids post the loading icon and label in the background request.
@@ -339,9 +337,7 @@
         }
     }
 
-    /**
-     * Loads the app label and icon image and stores into the cache.
-     */
+    /** Loads the app label and icon image and stores into the cache. */
     public static NameAndIcon loadNameAndIcon(
             Context context,
             int uid,
@@ -400,7 +396,7 @@
                 // Look for an official name for this UID.
                 for (String pkgName : packages) {
                     try {
-                        final PackageInfo pi = ipm.getPackageInfo(pkgName, 0 /* no flags */, userId);
+                        final PackageInfo pi = ipm.getPackageInfo(pkgName, 0, userId);
                         if (pi == null) {
                             Log.d(TAG, "Retrieving null package info for package "
                                     + pkgName + ", user " + userId);
@@ -432,9 +428,9 @@
         }
 
         UidToDetail utd = new UidToDetail();
-        utd.name = name;
-        utd.icon = icon;
-        utd.packageName = defaultPackageName;
+        utd.mName = name;
+        utd.mIcon = icon;
+        utd.mPackageName = defaultPackageName;
 
         sUidCache.put(uidString, utd);
         if (handler != null) {
@@ -443,9 +439,7 @@
         return new NameAndIcon(name, defaultPackageName, icon, /*iconId=*/ 0);
     }
 
-    /**
-     * Returns a string that uniquely identifies this battery consumer.
-     */
+    /** Returns a string that uniquely identifies this battery consumer. */
     public String getKey() {
         if (mBatteryConsumer instanceof UidBatteryConsumer) {
             return Integer.toString(mUid);
@@ -456,23 +450,17 @@
         }
     }
 
-    /**
-     * Returns true if the entry is hidden from the battery usage summary list.
-     */
+    /** Returns true if the entry is hidden from the battery usage summary list. */
     public boolean isHidden() {
         return mIsHidden;
     }
 
-    /**
-     * Returns true if this entry describes an app (UID)
-     */
+    /** Returns true if this entry describes an app (UID). */
     public boolean isAppEntry() {
         return mBatteryConsumer instanceof UidBatteryConsumer;
     }
 
-    /**
-     * Returns true if this entry describes a User.
-     */
+    /** Returns true if this entry describes a User. */
     public boolean isUserEntry() {
         if (mBatteryConsumer instanceof UserBatteryConsumer) {
             return true;
@@ -495,9 +483,7 @@
         return mUid;
     }
 
-    /**
-     * Returns foreground foreground time (in milliseconds) that is attributed to this entry.
-     */
+    /** Returns foreground foreground time/ms that is attributed to this entry. */
     public long getTimeInForegroundMs() {
         if (mBatteryConsumer instanceof UidBatteryConsumer) {
             return mTimeInForegroundMs;
@@ -506,9 +492,7 @@
         }
     }
 
-    /**
-     * Returns background activity time (in milliseconds) that is attributed to this entry.
-     */
+    /** Returns background activity time/ms that is attributed to this entry. */
     public long getTimeInBackgroundMs() {
         if (mBatteryConsumer instanceof UidBatteryConsumer) {
             return mTimeInBackgroundMs;
@@ -542,9 +526,7 @@
         }
     }
 
-    /**
-     * Gets name and icon resource from UserBatteryConsumer userId.
-     */
+    /** Gets name and icon resource from UserBatteryConsumer userId. */
     public static NameAndIcon getNameAndIconFromUserId(
             Context context, final int userId) {
         UserManager um = context.getSystemService(UserManager.class);
@@ -562,9 +544,7 @@
         return new NameAndIcon(name, icon, 0 /* iconId */);
     }
 
-    /**
-     * Gets name and icon resource from UidBatteryConsumer uid.
-     */
+    /** Gets name and icon resource from UidBatteryConsumer uid. */
     public static NameAndIcon getNameAndIconFromUid(
             Context context, String name, final int uid) {
         Drawable icon = context.getDrawable(R.drawable.ic_power_system);
@@ -579,9 +559,7 @@
         return new NameAndIcon(name, icon, 0 /* iconId */);
     }
 
-    /**
-     * Gets name and icon resource from BatteryConsumer power component ID.
-     */
+    /** Gets name and icon resource from BatteryConsumer power component ID. */
     public static NameAndIcon getNameAndIconFromPowerComponent(
             Context context, @BatteryConsumer.PowerComponent int powerComponentId) {
         String name;
@@ -625,8 +603,9 @@
                 iconId = R.drawable.ic_settings_phone_idle;
                 break;
             default:
-                name = DebugUtils.constantToString(BatteryConsumer.class, "POWER_COMPONENT_",
-                        powerComponentId);
+                Log.w(TAG, "unknown attribute:" + DebugUtils.constantToString(
+                        BatteryConsumer.class, "POWER_COMPONENT_", powerComponentId));
+                name = null;
                 iconId = R.drawable.ic_power_system;
                 break;
         }
diff --git a/src/com/android/settings/fuelgauge/ConvertUtils.java b/src/com/android/settings/fuelgauge/ConvertUtils.java
index 946c910..696147b 100644
--- a/src/com/android/settings/fuelgauge/ConvertUtils.java
+++ b/src/com/android/settings/fuelgauge/ConvertUtils.java
@@ -101,7 +101,7 @@
             values.put(BatteryHistEntry.KEY_CONSUME_POWER,
                 Double.valueOf(entry.getConsumedPower()));
             values.put(BatteryHistEntry.KEY_PERCENT_OF_TOTAL,
-                Double.valueOf(entry.percent));
+                Double.valueOf(entry.mPercent));
             values.put(BatteryHistEntry.KEY_FOREGROUND_USAGE_TIME,
                 Long.valueOf(entry.getTimeInForegroundMs()));
             values.put(BatteryHistEntry.KEY_BACKGROUND_USAGE_TIME,
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
index a10d323..aaa1487 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
@@ -181,7 +181,7 @@
         when(mBatteryEntry.getLabel()).thenReturn(APP_LABEL);
         when(mBatteryEntry.getTimeInBackgroundMs()).thenReturn(BACKGROUND_TIME_MS);
         when(mBatteryEntry.getTimeInForegroundMs()).thenReturn(FOREGROUND_TIME_MS);
-        mBatteryEntry.iconId = ICON_ID;
+        mBatteryEntry.mIconId = ICON_ID;
 
         mFragment.mHeaderPreference = mHeaderPreference;
         mFragment.mState = mState;
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryDiffEntryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryDiffEntryTest.java
index 13ce29e..710d065 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryDiffEntryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryDiffEntryTest.java
@@ -140,8 +140,8 @@
         // Verifies the app label in the cache.
         final BatteryEntry.NameAndIcon nameAndIcon =
             BatteryDiffEntry.sResourceCache.get(entry.getKey());
-        assertThat(nameAndIcon.name).isEqualTo(expectedName);
-        assertThat(nameAndIcon.iconId).isEqualTo(R.drawable.ic_settings_aod);
+        assertThat(nameAndIcon.mName).isEqualTo(expectedName);
+        assertThat(nameAndIcon.mIconId).isEqualTo(R.drawable.ic_settings_aod);
         // Verifies the restrictable flag in the cache.
         assertThat(entry.mValidForRestriction).isTrue();
         assertThat(BatteryDiffEntry.sValidForRestriction.get(entry.getKey())).isTrue();
@@ -166,8 +166,8 @@
         // Verifies the app label in the cache.
         final BatteryEntry.NameAndIcon nameAndIcon =
             BatteryDiffEntry.sResourceCache.get(entry.getKey());
-        assertThat(nameAndIcon.name).isEqualTo(expectedName);
-        assertThat(nameAndIcon.iconId).isEqualTo(0);
+        assertThat(nameAndIcon.mName).isEqualTo(expectedName);
+        assertThat(nameAndIcon.mIconId).isEqualTo(0);
         // Verifies the restrictable flag in the cache.
         assertThat(entry.mValidForRestriction).isTrue();
         assertThat(BatteryDiffEntry.sValidForRestriction.get(entry.getKey())).isTrue();
@@ -195,7 +195,7 @@
         // Verifies the app label in the cache.
         final BatteryEntry.NameAndIcon nameAndIcon =
             BatteryDiffEntry.sResourceCache.get(entry.getKey());
-        assertThat(nameAndIcon.name).isEqualTo(expectedAppLabel);
+        assertThat(nameAndIcon.mName).isEqualTo(expectedAppLabel);
         // Verifies the restrictable flag in the cache.
         assertThat(entry.mValidForRestriction).isFalse();
         assertThat(BatteryDiffEntry.sValidForRestriction.get(entry.getKey())).isFalse();
@@ -215,7 +215,7 @@
         // Verifies the app label in the cache.
         final BatteryEntry.NameAndIcon nameAndIcon =
             BatteryDiffEntry.sResourceCache.get(entry.getKey());
-        assertThat(nameAndIcon.name).isEqualTo(expectedAppLabel);
+        assertThat(nameAndIcon.mName).isEqualTo(expectedAppLabel);
     }
 
     @Test
@@ -274,7 +274,7 @@
         // Verifies the app label in the cache.
         final BatteryEntry.NameAndIcon nameAndIcon =
             BatteryDiffEntry.sResourceCache.get(entry.getKey());
-        assertThat(nameAndIcon.icon).isEqualTo(mockDrawable);
+        assertThat(nameAndIcon.mIcon).isEqualTo(mockDrawable);
     }
 
     @Test
@@ -309,7 +309,7 @@
         // Verifies the cache is updated into the new drawable.
         final BatteryEntry.NameAndIcon nameAndIcon =
             BatteryDiffEntry.sResourceCache.get(entry2.getKey());
-        assertThat(nameAndIcon.icon).isEqualTo(mockDrawable2);
+        assertThat(nameAndIcon.mIcon).isEqualTo(mockDrawable2);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
index c1b1761..966bc70 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
@@ -158,8 +158,8 @@
         final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application,
                 BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY, 200, 100, 1000);
 
-        assertThat(entry.iconId).isEqualTo(R.drawable.ic_settings_aod);
-        assertThat(entry.name).isEqualTo("Ambient display");
+        assertThat(entry.mIconId).isEqualTo(R.drawable.ic_settings_aod);
+        assertThat(entry.mName).isEqualTo("Ambient display");
     }
 
     @Test
@@ -167,8 +167,8 @@
         final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application,
                 BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 42, "ABC", 200, 100);
 
-        assertThat(entry.iconId).isEqualTo(R.drawable.ic_power_system);
-        assertThat(entry.name).isEqualTo("ABC");
+        assertThat(entry.mIconId).isEqualTo(R.drawable.ic_power_system);
+        assertThat(entry.mName).isEqualTo("ABC");
     }
 
     @Test
@@ -261,16 +261,16 @@
 
         final NameAndIcon nameAndIcon = BatteryEntry.getNameAndIconFromUserId(
                 mContext, userId);
-        assertThat(nameAndIcon.name).isEqualTo(getString(
+        assertThat(nameAndIcon.mName).isEqualTo(getString(
                 R.string.running_process_item_removed_user_label));
-        assertThat(nameAndIcon.icon).isNull();
+        assertThat(nameAndIcon.mIcon).isNull();
     }
 
     @Test
     public void getNameAndIconFromUid_rerturnExpectedName() {
         final NameAndIcon nameAndIcon = BatteryEntry.getNameAndIconFromUid(
                 mContext, /* name */ null, /* uid */ 0);
-        assertThat(nameAndIcon.name).isEqualTo(getString(R.string.process_kernel_label));
+        assertThat(nameAndIcon.mName).isEqualTo(getString(R.string.process_kernel_label));
 
         assertNameAndIcon("mediaserver", R.string.process_mediaserver_label);
         assertNameAndIcon("dex2oat32", R.string.process_dex2oat_label);
@@ -312,14 +312,14 @@
     private void assertNameAndIcon(String name, int stringId) {
         final NameAndIcon nameAndIcon = BatteryEntry.getNameAndIconFromUid(
                 mContext, name, /* uid */ 1000);
-        assertThat(nameAndIcon.name).isEqualTo(getString(stringId));
+        assertThat(nameAndIcon.mName).isEqualTo(getString(stringId));
     }
 
     private void assertNameAndIcon(int powerComponentId, int stringId, int iconId) {
         final NameAndIcon nameAndIcon = BatteryEntry.getNameAndIconFromPowerComponent(
                 mContext, powerComponentId);
-        assertThat(nameAndIcon.name).isEqualTo(getString(stringId));
-        assertThat(nameAndIcon.iconId).isEqualTo(iconId);
+        assertThat(nameAndIcon.mName).isEqualTo(getString(stringId));
+        assertThat(nameAndIcon.mIconId).isEqualTo(iconId);
     }
 
     private String getString(int stringId) {
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHistEntryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHistEntryTest.java
index ca3109c..3acb8f3 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHistEntryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHistEntryTest.java
@@ -57,7 +57,7 @@
         when(mockBatteryEntry.isHidden()).thenReturn(true);
         when(mBatteryUsageStats.getConsumedPower()).thenReturn(5.1);
         when(mockBatteryEntry.getConsumedPower()).thenReturn(1.1);
-        mockBatteryEntry.percent = 0.3;
+        mockBatteryEntry.mPercent = 0.3;
         when(mockBatteryEntry.getTimeInForegroundMs()).thenReturn(1234L);
         when(mockBatteryEntry.getTimeInBackgroundMs()).thenReturn(5689L);
         when(mockBatteryEntry.getPowerComponentId()).thenReturn(expectedType);
@@ -76,7 +76,7 @@
         assertBatteryHistEntry(
             new BatteryHistEntry(values),
             /*drainType=*/ expectedType,
-            /*percentOfTotal=*/ mockBatteryEntry.percent);
+            /*percentOfTotal=*/ mockBatteryEntry.mPercent);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java
index ff0f25c..42483d0 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java
@@ -77,7 +77,7 @@
         when(mockBatteryEntry.isHidden()).thenReturn(true);
         when(mBatteryUsageStats.getConsumedPower()).thenReturn(5.1);
         when(mockBatteryEntry.getConsumedPower()).thenReturn(1.1);
-        mockBatteryEntry.percent = 0.3;
+        mockBatteryEntry.mPercent = 0.3;
         when(mockBatteryEntry.getTimeInForegroundMs()).thenReturn(1234L);
         when(mockBatteryEntry.getTimeInBackgroundMs()).thenReturn(5689L);
         when(mockBatteryEntry.getPowerComponentId()).thenReturn(expectedType);
