/*
 * Copyright (C) 2011 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.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.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.Log;
import android.util.SparseArray;
import android.util.ArraySet;
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.app.UnlaunchableAppActivity;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.internal.util.ParcelableString;
import com.android.internal.widget.LockPatternUtils;

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;

public class TrustedCredentialsSettings extends OptionsMenuFragment
        implements TrustedCredentialsDialogBuilder.DelegateInterface {

    public static final String ARG_SHOW_NEW_FOR_USER = "ARG_SHOW_NEW_FOR_USER";

    private static final String TAG = "TrustedCredentialsSettings";

    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 String USER_ACTION = "com.android.settings.TRUSTED_CREDENTIALS_USER";
    private static final int REQUEST_CONFIRM_CREDENTIALS = 1;

    @Override
    public int getMetricsCategory() {
        return MetricsEvent.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);

        private final String mTag;
        private final int mLabel;
        private final int mView;
        private final int mProgress;
        private final int mContentView;
        private final boolean mSwitch;

        private Tab(String tag, int label, int view, int progress, int contentView, boolean withSwitch) {
            mTag = tag;
            mLabel = label;
            mView = view;
            mProgress = progress;
            mContentView = contentView;
            mSwitch = withSwitch;
        }

        private List<ParcelableString> getAliases(IKeyChainService service) throws RemoteException {
            switch (this) {
                case SYSTEM: {
                    return service.getSystemCaAliases().getList();
                }
                case USER:
                    return service.getUserCaAliases().getList();
            }
            throw new AssertionError();
        }
        private boolean deleted(IKeyChainService service, String alias) throws RemoteException {
            switch (this) {
                case SYSTEM:
                    return !service.containsCaAlias(alias);
                case USER:
                    return false;
            }
            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);
    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);
        mUserManager = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
        mKeyguardManager = (KeyguardManager) getActivity()
                .getSystemService(Context.KEYGUARD_SERVICE);
        mTrustAllCaUserId = getActivity().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);
        getActivity().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);
    }

    @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() {
        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(R.string.category_work);
            } else {
                title.setText(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 {
                    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<ParcelableString>> aliasesByProfileId = new SparseArray<
                            List<ParcelableString>>(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<ParcelableString> 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<ParcelableString> 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).string;
                            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 {
            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 {
                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;
        }
    }
}
