1f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom/*
2f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom * Copyright (C) 2011 The Android Open Source Project
3f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom *
4f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
5f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom * you may not use this file except in compliance with the License.
6f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom * You may obtain a copy of the License at
7f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom *
8f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
9f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom *
10f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom * Unless required by applicable law or agreed to in writing, software
11f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
12f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom * See the License for the specific language governing permissions and
14f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom * limitations under the License.
15f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom */
16f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
17f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrompackage com.android.settings;
18f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
19f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.app.AlertDialog;
20f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.app.Dialog;
21f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.app.Fragment;
22f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.content.DialogInterface;
23f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.net.http.SslCertificate;
24f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.os.AsyncTask;
25f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.os.Bundle;
26f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.os.RemoteException;
27f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.security.IKeyChainService;
28f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.security.KeyChain;
29f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.security.KeyChain.KeyChainConnection;
30f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.view.LayoutInflater;
31f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.view.View;
32f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.view.ViewGroup;
33f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.widget.AdapterView;
34f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.widget.BaseAdapter;
35f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.widget.Button;
36f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.widget.CheckBox;
37f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.widget.FrameLayout;
38f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.widget.ListView;
39729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstromimport android.widget.ProgressBar;
40f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.widget.TabHost;
41f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport android.widget.TextView;
42f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport java.security.cert.CertificateEncodingException;
43f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport java.security.cert.X509Certificate;
44f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport java.util.ArrayList;
45f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport java.util.Collections;
46f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport java.util.List;
47f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport java.util.Set;
48f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstromimport org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore;
49f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
50ac45fb42b00f377e58f8dfd59e4807a3147cfb57Brian Carlstrompublic class TrustedCredentialsSettings extends Fragment {
51f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
52ac45fb42b00f377e58f8dfd59e4807a3147cfb57Brian Carlstrom    private static final String TAG = "TrustedCredentialsSettings";
53f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
54f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    private enum Tab {
55f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        SYSTEM("system",
56f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom               R.string.trusted_credentials_system_tab,
57f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom               R.id.system_tab,
58f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom               R.id.system_progress,
59f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom               R.id.system_list,
60f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom               true),
61f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        USER("user",
62f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom             R.string.trusted_credentials_user_tab,
63f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom             R.id.user_tab,
64f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom             R.id.user_progress,
65f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom             R.id.user_list,
66f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom             false);
67f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
68f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private final String mTag;
69f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private final int mLabel;
70f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private final int mView;
71f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private final int mProgress;
72f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private final int mList;
73f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private final boolean mCheckbox;
74f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private Tab(String tag, int label, int view, int progress, int list, boolean checkbox) {
75f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            mTag = tag;
76f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            mLabel = label;
77f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            mView = view;
78f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            mProgress = progress;
79f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            mList = list;
80f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            mCheckbox = checkbox;
81f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
82f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private Set<String> getAliases(TrustedCertificateStore store) {
83f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            switch (this) {
84f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                case SYSTEM:
85f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    return store.allSystemAliases();
86f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                case USER:
87f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    return store.userAliases();
88f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            }
89f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            throw new AssertionError();
90f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
91f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private boolean deleted(TrustedCertificateStore store, String alias) {
92f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            switch (this) {
93f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                case SYSTEM:
94f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    return !store.containsAlias(alias);
95f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                case USER:
96f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    return false;
97f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            }
98f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            throw new AssertionError();
99f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
100f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private int getButtonLabel(CertHolder certHolder) {
101f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            switch (this) {
102f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                case SYSTEM:
103f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    if (certHolder.mDeleted) {
104f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                        return R.string.trusted_credentials_enable_label;
105f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    }
106f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    return R.string.trusted_credentials_disable_label;
107f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                case USER:
108f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    return R.string.trusted_credentials_remove_label;
109f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            }
110f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            throw new AssertionError();
111f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
112f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private int getButtonConfirmation(CertHolder certHolder) {
113f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            switch (this) {
114f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                case SYSTEM:
115f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    if (certHolder.mDeleted) {
116f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                        return R.string.trusted_credentials_enable_confirmation;
117f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    }
118f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    return R.string.trusted_credentials_disable_confirmation;
119f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                case USER:
120f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    return R.string.trusted_credentials_remove_confirmation;
121f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            }
122f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            throw new AssertionError();
123f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
124f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private void postOperationUpdate(boolean ok, CertHolder certHolder) {
125f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            if (ok) {
126f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                if (certHolder.mTab.mCheckbox) {
127f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    certHolder.mDeleted = !certHolder.mDeleted;
128f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                } else {
129f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    certHolder.mAdapter.mCertHolders.remove(certHolder);
130f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                }
131f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                certHolder.mAdapter.notifyDataSetChanged();
132f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            } else {
133f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                // bail, reload to reset to known state
134f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                certHolder.mAdapter.load();
135f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            }
136f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
137f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    }
138f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
139f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    // be careful not to use this on the UI thread since it is does file operations
140f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    private final TrustedCertificateStore mStore = new TrustedCertificateStore();
141f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
142f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    private TabHost mTabHost;
143f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
144f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    @Override public View onCreateView(
145f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
146f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        mTabHost = (TabHost) inflater.inflate(R.layout.trusted_credentials, parent, false);
147f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        mTabHost.setup();
148f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        addTab(Tab.SYSTEM);
149f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        // TODO add Install button on Tab.USER to go to CertInstaller like KeyChainActivity
150f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        addTab(Tab.USER);
151f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        return mTabHost;
152f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    }
153f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
154f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    private void addTab(Tab tab) {
155f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        TabHost.TabSpec systemSpec = mTabHost.newTabSpec(tab.mTag)
156f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                .setIndicator(getActivity().getString(tab.mLabel))
157f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                .setContent(tab.mView);
158f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        mTabHost.addTab(systemSpec);
159f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
160f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        ListView lv = (ListView) mTabHost.findViewById(tab.mList);
161f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        final TrustedCertificateAdapter adapter = new TrustedCertificateAdapter(tab);
162f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        lv.setAdapter(adapter);
163f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
164f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            @Override public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
165f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                showCertDialog(adapter.getItem(pos));
166f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            }
167f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        });
168f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    }
169f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
170f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    private class TrustedCertificateAdapter extends BaseAdapter {
171f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private final List<CertHolder> mCertHolders = new ArrayList<CertHolder>();
172f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private final Tab mTab;
173f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private TrustedCertificateAdapter(Tab tab) {
174f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            mTab = tab;
175f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            load();
176f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
177f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private void load() {
178f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            new AliasLoader().execute();
179f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
180f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        @Override public int getCount() {
181f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            return mCertHolders.size();
182f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
183f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        @Override public CertHolder getItem(int position) {
184f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            return mCertHolders.get(position);
185f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
186f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        @Override public long getItemId(int position) {
187f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            return position;
188f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
189f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        @Override public View getView(int position, View view, ViewGroup parent) {
190f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            ViewHolder holder;
191f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            if (view == null) {
192f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                LayoutInflater inflater = LayoutInflater.from(getActivity());
193f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                view = inflater.inflate(R.layout.trusted_credential, parent, false);
194f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                holder = new ViewHolder();
19510cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                holder.mSubjectPrimaryView = (TextView)
19610cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                        view.findViewById(R.id.trusted_credential_subject_primary);
19710cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                holder.mSubjectSecondaryView = (TextView)
19810cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                        view.findViewById(R.id.trusted_credential_subject_secondary);
199f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                holder.mCheckBox = (CheckBox) view.findViewById(R.id.trusted_credential_status);
200f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                view.setTag(holder);
201f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            } else {
202f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                holder = (ViewHolder) view.getTag();
203f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            }
204f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            CertHolder certHolder = mCertHolders.get(position);
20510cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom            holder.mSubjectPrimaryView.setText(certHolder.mSubjectPrimary);
20610cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom            holder.mSubjectSecondaryView.setText(certHolder.mSubjectSecondary);
207f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            if (mTab.mCheckbox) {
208f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                holder.mCheckBox.setChecked(!certHolder.mDeleted);
209f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                holder.mCheckBox.setVisibility(View.VISIBLE);
210f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            }
211f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            return view;
212f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        };
213f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
214729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom        private class AliasLoader extends AsyncTask<Void, Integer, List<CertHolder>> {
215729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom            ProgressBar mProgressBar;
216729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom            View mList;
217f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            @Override protected void onPreExecute() {
218f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                View content = mTabHost.getTabContentView();
219729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom                mProgressBar = (ProgressBar) content.findViewById(mTab.mProgress);
220729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom                mList = content.findViewById(mTab.mList);
221729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom                mProgressBar.setVisibility(View.VISIBLE);
222729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom                mList.setVisibility(View.GONE);
223f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            }
224f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            @Override protected List<CertHolder> doInBackground(Void... params) {
225f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                Set<String> aliases = mTab.getAliases(mStore);
226729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom                int max = aliases.size();
227729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom                int progress = 0;
228729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom                List<CertHolder> certHolders = new ArrayList<CertHolder>(max);
229f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                for (String alias : aliases) {
230f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    X509Certificate cert = (X509Certificate) mStore.getCertificate(alias, true);
231f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    certHolders.add(new CertHolder(mStore,
232f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                                                   TrustedCertificateAdapter.this,
233f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                                                   mTab,
234f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                                                   alias,
235f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                                                   cert));
236729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom                    publishProgress(++progress, max);
237f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                }
238f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                Collections.sort(certHolders);
239f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                return certHolders;
240f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            }
241729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom            @Override protected void onProgressUpdate(Integer... progressAndMax) {
242729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom                int progress = progressAndMax[0];
243729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom                int max = progressAndMax[1];
244729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom                if (max != mProgressBar.getMax()) {
245729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom                    mProgressBar.setMax(max);
246729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom                }
247729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom                mProgressBar.setProgress(progress);
248729c6d99e21856558f3631d31537b8dca6bb2314Brian Carlstrom            }
249f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            @Override protected void onPostExecute(List<CertHolder> certHolders) {
250f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                mCertHolders.clear();
251f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                mCertHolders.addAll(certHolders);
252f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                notifyDataSetChanged();
253f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                View content = mTabHost.getTabContentView();
254945e383833c77101eb415b28bad4d1c6dfe85485Brian Carlstrom                mProgressBar.setVisibility(View.GONE);
255945e383833c77101eb415b28bad4d1c6dfe85485Brian Carlstrom                mList.setVisibility(View.VISIBLE);
256945e383833c77101eb415b28bad4d1c6dfe85485Brian Carlstrom                mProgressBar.setProgress(0);
257f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            }
258f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
259f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    }
260f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
261f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    private static class CertHolder implements Comparable<CertHolder> {
262f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private final TrustedCertificateStore mStore;
263f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private final TrustedCertificateAdapter mAdapter;
264f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private final Tab mTab;
265f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private final String mAlias;
266f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private final X509Certificate mX509Cert;
267f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
268f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private final SslCertificate mSslCert;
26910cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom        private final String mSubjectPrimary;
27010cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom        private final String mSubjectSecondary;
271f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private boolean mDeleted;
272f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
273f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private CertHolder(TrustedCertificateStore store,
274f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                           TrustedCertificateAdapter adapter,
275f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                           Tab tab,
276f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                           String alias,
277f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                           X509Certificate x509Cert) {
278f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            mStore = store;
279f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            mAdapter = adapter;
280f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            mTab = tab;
281f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            mAlias = alias;
282f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            mX509Cert = x509Cert;
283f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
284f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            mSslCert = new SslCertificate(x509Cert);
285f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
286f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            String cn = mSslCert.getIssuedTo().getCName();
287f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            String o = mSslCert.getIssuedTo().getOName();
288f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            String ou = mSslCert.getIssuedTo().getUName();
28910cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom            // if we have a O, use O as primary subject, secondary prefer CN over OU
29010cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom            // if we don't have an O, use CN as primary, empty secondary
29110cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom            // if we don't have O or CN, use DName as primary, empty secondary
292f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            if (!o.isEmpty()) {
29310cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                if (!cn.isEmpty()) {
29410cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                    mSubjectPrimary = o;
29510cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                    mSubjectSecondary = cn;
29610cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                } else {
29710cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                    mSubjectPrimary = o;
29810cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                    mSubjectSecondary = ou;
299f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                }
300f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            } else {
30110cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                if (!cn.isEmpty()) {
30210cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                    mSubjectPrimary = cn;
30310cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                    mSubjectSecondary = "";
30410cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                } else {
30510cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                    mSubjectPrimary = mSslCert.getIssuedTo().getDName();
30610cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                    mSubjectSecondary = "";
30710cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                }
308f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            }
309f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            mDeleted = mTab.deleted(mStore, mAlias);
310f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
311f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        @Override public int compareTo(CertHolder o) {
31210cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom            int primary = this.mSubjectPrimary.compareToIgnoreCase(o.mSubjectPrimary);
31310cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom            if (primary != 0) {
31410cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom                return primary;
31510cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom            }
31610cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom            return this.mSubjectSecondary.compareToIgnoreCase(o.mSubjectSecondary);
317f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
318f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        @Override public boolean equals(Object o) {
319f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            if (!(o instanceof CertHolder)) {
320f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                return false;
321f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            }
322f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            CertHolder other = (CertHolder) o;
323f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            return mAlias.equals(other.mAlias);
324f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
325f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        @Override public int hashCode() {
326f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            return mAlias.hashCode();
327f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
328f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    }
329f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
330f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    private static class ViewHolder {
33110cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom        private TextView mSubjectPrimaryView;
33210cc989346e1beda02a0dc5e0ca257734bbd21fcBrian Carlstrom        private TextView mSubjectSecondaryView;
333f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private CheckBox mCheckBox;
334f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    }
335f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
336f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    private void showCertDialog(final CertHolder certHolder) {
33791615cfa9ead46769ad3adc624b3bacb4906e4b2Brian Carlstrom        View view = certHolder.mSslCert.inflateCertificateView(getActivity());
338f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
339f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        builder.setTitle(com.android.internal.R.string.ssl_certificate);
340f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        builder.setView(view);
341f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
342f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            @Override public void onClick(DialogInterface dialog, int id) {
343f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                dialog.dismiss();
344f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            }
345f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        });
346f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        final Dialog certDialog = builder.create();
347f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
34891615cfa9ead46769ad3adc624b3bacb4906e4b2Brian Carlstrom        ViewGroup body = (ViewGroup) view.findViewById(com.android.internal.R.id.body);
34991615cfa9ead46769ad3adc624b3bacb4906e4b2Brian Carlstrom        LayoutInflater inflater = LayoutInflater.from(getActivity());
35091615cfa9ead46769ad3adc624b3bacb4906e4b2Brian Carlstrom        Button removeButton = (Button) inflater.inflate(R.layout.trusted_credential_details,
35191615cfa9ead46769ad3adc624b3bacb4906e4b2Brian Carlstrom                                                        body,
35291615cfa9ead46769ad3adc624b3bacb4906e4b2Brian Carlstrom                                                        false);
35391615cfa9ead46769ad3adc624b3bacb4906e4b2Brian Carlstrom        body.addView(removeButton);
354f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        removeButton.setText(certHolder.mTab.getButtonLabel(certHolder));
355f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        removeButton.setOnClickListener(new View.OnClickListener() {
356f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            @Override public void onClick(View v) {
357f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
358f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                builder.setMessage(certHolder.mTab.getButtonConfirmation(certHolder));
359f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                builder.setPositiveButton(
360f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                        android.R.string.yes, new DialogInterface.OnClickListener() {
361f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    @Override public void onClick(DialogInterface dialog, int id) {
362f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                        new AliasOperation(certHolder).execute();
363f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                        dialog.dismiss();
364f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                        certDialog.dismiss();
365f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    }
366f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                });
367f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                builder.setNegativeButton(
368f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                        android.R.string.no, new DialogInterface.OnClickListener() {
369f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    @Override public void onClick(DialogInterface dialog, int id) {
370f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                        dialog.cancel();
371f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    }
372f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                });
373f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                AlertDialog alert = builder.create();
374f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                alert.show();
375f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            }
376f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        });
377f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
378f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        certDialog.show();
379f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    }
380f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom
381f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    private class AliasOperation extends AsyncTask<Void, Void, Boolean> {
382f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private final CertHolder mCertHolder;
383f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        private AliasOperation(CertHolder certHolder) {
384f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            mCertHolder = certHolder;
385f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
386f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        @Override protected Boolean doInBackground(Void... params) {
387f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            try {
388f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                KeyChainConnection keyChainConnection = KeyChain.bind(getActivity());
389f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                IKeyChainService service = keyChainConnection.getService();
390f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                try {
391f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    if (mCertHolder.mDeleted) {
392f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                        byte[] bytes = mCertHolder.mX509Cert.getEncoded();
393f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                        service.installCaCertificate(bytes);
394f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                        return true;
395f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    } else {
396f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                        return service.deleteCaCertificate(mCertHolder.mAlias);
397f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    }
398f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                } finally {
399f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                    keyChainConnection.close();
400f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                }
401f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            } catch (CertificateEncodingException e) {
402f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                return false;
403f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            } catch (IllegalStateException e) {
404f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                // used by installCaCertificate to report errors
405f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                return false;
406f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            } catch (RemoteException e) {
407f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                return false;
408f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            } catch (InterruptedException e) {
409f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                Thread.currentThread().interrupt();
410f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom                return false;
411f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            }
412f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
413f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        @Override protected void onPostExecute(Boolean ok) {
414f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom            mCertHolder.mTab.postOperationUpdate(ok, mCertHolder);
415f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom        }
416f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom    }
417f6f4e303abb8b7883713b0af8484c7767e6af84dBrian Carlstrom}
418