Merge "Fix accessibility description on master clear" into nyc-dev
diff --git a/res/layout/trusted_credential.xml b/res/layout/trusted_credential.xml
index dae9424..ea13939 100644
--- a/res/layout/trusted_credential.xml
+++ b/res/layout/trusted_credential.xml
@@ -19,6 +19,8 @@
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:background="?android:attr/selectableItemBackground"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:paddingTop="15dip"
android:paddingBottom="15dip">
diff --git a/res/layout/trusted_credential_list_container.xml b/res/layout/trusted_credential_list_container.xml
new file mode 100644
index 0000000..78e7ab7
--- /dev/null
+++ b/res/layout/trusted_credential_list_container.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:visibility="gone">
+ <LinearLayout
+ android:id="@+id/header_view"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:clickable="true"
+ android:background="?android:attr/selectableItemBackground"
+ android:visibility="gone">
+
+ <View
+ android:id="@+id/header_divider"
+ android:layout_width="match_parent"
+ android:layout_height="2dp"
+ android:background="?android:attr/listDivider"
+ android:visibility="gone"/>
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:orientation="horizontal"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+ <ImageView
+ android:id="@+id/group_indicator"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ <FrameLayout
+ android:id="@+id/header_content_container"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
+ </LinearLayout>
+ </LinearLayout>
+ <ListView
+ android:id="@+id/cert_list"
+ style="@style/TrustedCredentialsList">
+ </ListView>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/trusted_credentials.xml b/res/layout/trusted_credentials.xml
index 6be0ba2..e52310e 100644
--- a/res/layout/trusted_credentials.xml
+++ b/res/layout/trusted_credentials.xml
@@ -49,25 +49,26 @@
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:visibility="gone" />
- <ListView
- android:id="@+id/system_list"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:scrollbarStyle="outsideOverlay"
+ <LinearLayout
+ android:id="@+id/system_content"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:visibility="gone">
- </ListView>
- <ExpandableListView
- android:id="@+id/system_expandable_list"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:scrollbarStyle="outsideOverlay"
- android:visibility="gone">
- </ExpandableListView>
+ <include
+ android:id="@+id/system_personal_container"
+ layout="@layout/trusted_credential_list_container"/>
+ <include
+ android:id="@+id/system_work_container"
+ layout="@layout/trusted_credential_list_container"/>
+
+ <ExpandableListView
+ android:id="@+id/system_expandable_list"
+ style="@style/TrustedCredentialsList"
+ android:visibility="gone">
+ </ExpandableListView>
+ </LinearLayout>
</FrameLayout>
@@ -85,25 +86,27 @@
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:visibility="gone" />
- <ListView
- android:id="@+id/user_list"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:scrollbarStyle="outsideOverlay"
+ <LinearLayout
+ android:id="@+id/user_content"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:visibility="gone">
- </ListView>
- <ExpandableListView
- android:id="@+id/user_expandable_list"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:scrollbarStyle="outsideOverlay"
- android:visibility="gone">
- </ExpandableListView>
+ <include
+ android:id="@+id/user_personal_container"
+ layout="@layout/trusted_credential_list_container"/>
+
+ <include
+ android:id="@+id/user_work_container"
+ layout="@layout/trusted_credential_list_container"/>
+
+ <ExpandableListView
+ android:id="@+id/user_expandable_list"
+ style="@style/TrustedCredentialsList"
+ android:visibility="gone">
+ </ExpandableListView>
+ </LinearLayout>
</FrameLayout>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 45d2c11..1cd5fbb 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -146,6 +146,12 @@
<style name="SettingsPreferenceHeaderList" parent="@*android:style/PreferenceHeaderList">
</style>
+ <style name="TrustedCredentialsList">
+ <item name="android:layout_width">fill_parent</item>
+ <item name="android:layout_height">fill_parent</item>
+ <item name="android:scrollbarStyle">outsideOverlay</item>
+ </style>
+
<style name="PreferenceFragmentStyle" parent="@*android:style/PreferenceFragment.Material">
<item name="android:layout">@layout/preference_list_fragment</item>
</style>
diff --git a/src/com/android/settings/TrustedCredentialsSettings.java b/src/com/android/settings/TrustedCredentialsSettings.java
index e371229..e7ab406 100644
--- a/src/com/android/settings/TrustedCredentialsSettings.java
+++ b/src/com/android/settings/TrustedCredentialsSettings.java
@@ -25,6 +25,9 @@
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;
@@ -36,6 +39,7 @@
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;
@@ -43,6 +47,9 @@
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;
@@ -58,8 +65,8 @@
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
+import java.util.Set;
public class TrustedCredentialsSettings extends OptionsMenuFragment
implements TrustedCredentialsDialogBuilder.DelegateInterface {
@@ -82,36 +89,44 @@
private enum Tab {
SYSTEM("system",
- R.string.trusted_credentials_system_tab,
- R.id.system_tab,
- R.id.system_progress,
- R.id.system_list,
- R.id.system_expandable_list,
+ R.string.trusted_credentials_system_tab,
+ R.id.system_tab,
+ R.id.system_progress,
+ R.id.system_personal_container,
+ R.id.system_work_container,
+ R.id.system_expandable_list,
+ R.id.system_content,
true),
USER("user",
- R.string.trusted_credentials_user_tab,
- R.id.user_tab,
- R.id.user_progress,
- R.id.user_list,
- R.id.user_expandable_list,
- false);
+ R.string.trusted_credentials_user_tab,
+ R.id.user_tab,
+ R.id.user_progress,
+ R.id.user_personal_container,
+ R.id.user_work_container,
+ R.id.user_expandable_list,
+ R.id.user_content,
+ false);
private final String mTag;
private final int mLabel;
private final int mView;
private final int mProgress;
- private final int mList;
+ private final int mPersonalList;
+ private final int mWorkList;
private final int mExpandableList;
+ private final int mContentView;
private final boolean mSwitch;
- private Tab(String tag, int label, int view, int progress, int list, int expandableList,
- boolean withSwitch) {
+ private Tab(String tag, int label, int view, int progress, int personalList, int workList,
+ int expandableList, int contentView, boolean withSwitch) {
mTag = tag;
mLabel = label;
mView = view;
mProgress = progress;
- mList = list;
+ mPersonalList = personalList;
+ mWorkList = workList;
mExpandableList = expandableList;
+ mContentView = contentView;
mSwitch = withSwitch;
}
@@ -134,25 +149,12 @@
}
throw new AssertionError();
}
- private void postOperationUpdate(boolean ok, CertHolder certHolder) {
- if (ok) {
- if (certHolder.mTab.mSwitch) {
- certHolder.mDeleted = !certHolder.mDeleted;
- } else {
- certHolder.mAdapter.remove(certHolder);
- }
- certHolder.mAdapter.notifyDataSetChanged();
- } else {
- // bail, reload to reset to known state
- certHolder.mAdapter.load();
- }
- }
}
private TabHost mTabHost;
+ private ArrayList<GroupAdapter> mGroupAdapters = new ArrayList<>(2);
private AliasOperation mAliasOperation;
- private HashMap<Tab, AdapterData.AliasLoader>
- mAliasLoaders = new HashMap<Tab, AdapterData.AliasLoader>(2);
+ private Set<AdapterData.AliasLoader> mAliasLoaders = new ArraySet<AdapterData.AliasLoader>(2);
private final SparseArray<KeyChainConnection>
mKeyChainConnectionByProfileId = new SparseArray<KeyChainConnection>();
@@ -164,18 +166,8 @@
if (Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(action) ||
Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action) ||
Intent.ACTION_MANAGED_PROFILE_UNLOCKED.equals(action)) {
- // Reload all alias
- final ExpandableListView systemView = (ExpandableListView) mTabHost
- .findViewById(Tab.SYSTEM.mExpandableList);
- if (systemView != null) {
- ((TrustedCertificateExpandableAdapter) systemView.getExpandableListAdapter())
- .load();
- }
- final ExpandableListView userView = (ExpandableListView) mTabHost
- .findViewById(Tab.USER.mExpandableList);
- if (userView != null) {
- ((TrustedCertificateExpandableAdapter) userView.getExpandableListAdapter())
- .load();
+ for (GroupAdapter adapter : mGroupAdapters) {
+ adapter.load();
}
}
}
@@ -214,9 +206,11 @@
@Override
public void onDestroy() {
getActivity().unregisterReceiver(mWorkProfileChangedReceiver);
- for (AdapterData.AliasLoader aliasLoader : mAliasLoaders.values()) {
+ for (AdapterData.AliasLoader aliasLoader : mAliasLoaders) {
aliasLoader.cancel(true);
}
+ mAliasLoaders.clear();
+ mGroupAdapters.clear();
if (mAliasOperation != null) {
mAliasOperation.cancel(true);
mAliasOperation = null;
@@ -239,52 +233,31 @@
.setContent(tab.mView);
mTabHost.addTab(systemSpec);
- if (mUserManager.getUserProfiles().size() > 1) {
- ExpandableListView lv = (ExpandableListView) mTabHost.findViewById(tab.mExpandableList);
- final TrustedCertificateExpandableAdapter adapter =
- new TrustedCertificateExpandableAdapter(tab);
- lv.setAdapter(adapter);
- lv.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
- @Override
- public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition,
- long id) {
- final UserHandle groupUser = adapter.getGroup(groupPosition);
- final int groupUserId = groupUser.getIdentifier();
- if (mUserManager.isQuietModeEnabled(groupUser)) {
- final Intent intent = UnlaunchableAppActivity.createInQuietModeDialogIntent(
- groupUserId);
- getActivity().startActivity(intent);
- return true;
- } else if (!mUserManager.isUserUnlocked(groupUser)) {
- final LockPatternUtils lockPatternUtils = new LockPatternUtils(
- getActivity());
- if (lockPatternUtils.isSeparateProfileChallengeEnabled(groupUserId)) {
- startWorkChallenge(groupUserId);
- return true;
- }
- }
- return false;
- }
+ final int profilesSize = mUserManager.getUserProfiles().size();
+ final GroupAdapter groupAdapter = new GroupAdapter(tab);
+ mGroupAdapters.add(groupAdapter);
- });
- lv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
- @Override
- public boolean onChildClick(ExpandableListView parent, View v,
- int groupPosition, int childPosition, long id) {
- showCertDialog(adapter.getChild(groupPosition, childPosition));
- return true;
- }
- });
- } else {
- ListView lv = (ListView) mTabHost.findViewById(tab.mList);
- final TrustedCertificateAdapter adapter = new TrustedCertificateAdapter(tab);
- lv.setAdapter(adapter);
- lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override public void onItemClick(AdapterView<?> parent, View view,
- int pos, long id) {
- showCertDialog(adapter.getItem(pos));
- }
- });
+ if (profilesSize == 1) {
+ final ChildAdapter adapter = groupAdapter.getChildAdapter(0);
+ adapter.setContainerViewId(tab.mPersonalList);
+ adapter.prepare();
+ } else if (profilesSize == 2) {
+ final int workIndex = groupAdapter.getUserInfoByGroup(1).isManagedProfile() ? 1 : 0;
+ final int personalIndex = workIndex == 1 ? 0 : 1;
+
+ final ChildAdapter personalAdapter = groupAdapter.getChildAdapter(personalIndex);
+ personalAdapter.setContainerViewId(tab.mPersonalList);
+ personalAdapter.showHeader(true);
+ personalAdapter.prepare();
+
+ final ChildAdapter workAdapter = groupAdapter.getChildAdapter(workIndex);
+ workAdapter.setContainerViewId(tab.mWorkList);
+ workAdapter.showHeader(true);
+ workAdapter.showDivider(true);
+ workAdapter.prepare();
+ } else if (profilesSize >= 3) {
+ groupAdapter.setExpandableListView(
+ (ExpandableListView) mTabHost.findViewById(tab.mExpandableList));
}
}
@@ -300,46 +273,18 @@
}
/**
- * Common interface for adapters of both expandable and non-expandable certificate lists.
- */
- private interface TrustedCertificateAdapterCommons {
- /**
- * Remove a certificate from the list.
- * @param certHolder the certificate to be removed.
- */
- void remove(CertHolder certHolder);
- /**
- * Notify the adapter that the underlying data set has changed.
- */
- void notifyDataSetChanged();
- /**
- * Load the certificates.
- */
- void load();
- /**
- * Gets the identifier of the list view the adapter is connected to.
- * @param tab the tab on which the list view resides.
- * @return identifier of the list view.
- */
- int getListViewId(Tab tab);
- }
-
- /**
* Adapter for expandable list view of certificates. Groups in the view correspond to profiles
* whereas children correspond to certificates.
*/
- private class TrustedCertificateExpandableAdapter extends BaseExpandableListAdapter implements
- TrustedCertificateAdapterCommons {
- private AdapterData mData;
+ private class GroupAdapter extends BaseExpandableListAdapter implements
+ ExpandableListView.OnGroupClickListener, ExpandableListView.OnChildClickListener {
+ private final AdapterData mData;
- private TrustedCertificateExpandableAdapter(Tab tab) {
+ private GroupAdapter(Tab tab) {
mData = new AdapterData(tab, this);
load();
}
- @Override
- public void remove(CertHolder certHolder) {
- mData.remove(certHolder);
- }
+
@Override
public int getGroupCount() {
return mData.mCertHoldersByUserId.size();
@@ -358,12 +303,18 @@
}
@Override
public CertHolder getChild(int groupPosition, int childPosition) {
- return mData.mCertHoldersByUserId.valueAt(groupPosition).get(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;
@@ -382,9 +333,7 @@
}
final TextView title = (TextView) convertView.findViewById(android.R.id.title);
- final UserHandle profile = getGroup(groupPosition);
- final UserInfo userInfo = mUserManager.getUserInfo(profile.getIdentifier());
- if (userInfo.isManagedProfile()) {
+ if (getUserInfoByGroup(groupPosition).isManagedProfile()) {
title.setText(R.string.category_work);
} else {
title.setText(R.string.category_personal);
@@ -403,50 +352,227 @@
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();
}
- @Override
- public int getListViewId(Tab tab) {
- return tab.mExpandableList;
- }
- }
- private class TrustedCertificateAdapter extends BaseAdapter implements
- TrustedCertificateAdapterCommons {
- private final AdapterData mData;
- private TrustedCertificateAdapter(Tab tab) {
- mData = new AdapterData(tab, this);
- load();
- }
- @Override
public void remove(CertHolder certHolder) {
mData.remove(certHolder);
}
- @Override
- public int getListViewId(Tab tab) {
- return tab.mList;
+
+ public void setExpandableListView(ExpandableListView lv) {
+ lv.setAdapter(this);
+ lv.setOnGroupClickListener(this);
+ lv.setOnChildClickListener(this);
+ lv.setVisibility(View.VISIBLE);
}
- @Override
- public void load() {
- mData.new AliasLoader().execute();
+
+ public ChildAdapter getChildAdapter(int groupPosition) {
+ return new ChildAdapter(this, groupPosition);
}
- @Override public int getCount() {
- List<CertHolder> certHolders = mData.mCertHoldersByUserId.valueAt(0);
- if (certHolders != null) {
- return certHolders.size();
+
+ public boolean checkGroupExpandableAndStartWarningActivity(int groupPosition) {
+ final UserHandle groupUser = getGroup(groupPosition);
+ final int groupUserId = groupUser.getIdentifier();
+ if (mUserManager.isQuietModeEnabled(groupUser)) {
+ final Intent intent = UnlaunchableAppActivity.createInQuietModeDialogIntent(
+ groupUserId);
+ getActivity().startActivity(intent);
+ return false;
+ } else if (!mUserManager.isUserUnlocked(groupUser)) {
+ final LockPatternUtils lockPatternUtils = new LockPatternUtils(
+ getActivity());
+ if (lockPatternUtils.isSeparateProfileChallengeEnabled(groupUserId)) {
+ startWorkChallenge(groupUserId);
+ return false;
+ }
}
- return 0;
+ return true;
+ }
+
+ private View getViewForCertificate(CertHolder certHolder, Tab mTab, View convertView,
+ ViewGroup parent) {
+ ViewHolder holder;
+ if (convertView == null) {
+ LayoutInflater inflater = LayoutInflater.from(getActivity());
+ convertView = inflater.inflate(R.layout.trusted_credential, parent, false);
+ holder = new ViewHolder();
+ 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);
+ convertView.setTag(holder);
+ } 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);
+ }
+ 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_LAYOUT_PARAMS = new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+ private final LinearLayout.LayoutParams SHOW_LAYOUT_PARAMS = new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.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 mData.mCertHoldersByUserId.valueAt(0).get(position);
+ return mParent.getChild(mGroupPosition, position);
}
@Override public long getItemId(int position) {
- return position;
+ return mParent.getChildId(mGroupPosition, position);
}
- @Override public View getView(int position, View view, ViewGroup parent) {
- return getViewForCertificate(getItem(position), mData.mTab, view, parent);
+ @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 setContainerViewId(int viewId) {
+ mContainerView = (LinearLayout) mTabHost.findViewById(viewId);
+ mContainerView.setVisibility(View.VISIBLE);
+
+ mListView = (ListView) mContainerView.findViewById(R.id.cert_list);
+ mListView.setAdapter(this);
+ mListView.setOnItemClickListener(this);
+
+ 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 prepare() {
+ mIsListExpanded = checkGroupExpandableAndStartWarningActivity();
+ refreshViews();
+ }
+
+ private boolean checkGroupExpandableAndStartWarningActivity() {
+ return mParent.checkGroupExpandableAndStartWarningActivity(mGroupPosition);
+ }
+
+ private void refreshViews() {
+ mIndicatorView.setImageState(mIsListExpanded ? GROUP_EXPANDED_STATE_SET
+ : EMPTY_STATE_SET, false);
+ mListView.setVisibility(mIsListExpanded ? View.VISIBLE : View.GONE);
+ mContainerView.setLayoutParams(mIsListExpanded ? SHOW_LAYOUT_PARAMS
+ : HIDE_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;
}
}
@@ -454,21 +580,25 @@
private final SparseArray<List<CertHolder>> mCertHoldersByUserId =
new SparseArray<List<CertHolder>>();
private final Tab mTab;
- private final TrustedCertificateAdapterCommons mAdapter;
+ private final GroupAdapter mAdapter;
- private AdapterData(Tab tab, TrustedCertificateAdapterCommons adapter) {
+ 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 mList;
+ private View mContentView;
private Context mContext;
public AliasLoader() {
mContext = getActivity();
- mAliasLoaders.put(mTab, this);
+ mAliasLoaders.add(this);
+ List<UserHandle> profiles = mUserManager.getUserProfiles();
+ for (UserHandle profile : profiles) {
+ mCertHoldersByUserId.put(profile.getIdentifier(), new ArrayList<CertHolder>());
+ }
}
private boolean shouldSkipProfile(UserHandle userHandle) {
@@ -479,9 +609,9 @@
@Override protected void onPreExecute() {
View content = mTabHost.getTabContentView();
mProgressBar = (ProgressBar) content.findViewById(mTab.mProgress);
- mList = content.findViewById(mAdapter.getListViewId(mTab));
+ mContentView = content.findViewById(mTab.mContentView);
mProgressBar.setVisibility(View.VISIBLE);
- mList.setVisibility(View.GONE);
+ mContentView.setVisibility(View.GONE);
}
@Override protected SparseArray<List<CertHolder>> doInBackground(Void... params) {
SparseArray<List<CertHolder>> certHoldersByProfile =
@@ -565,9 +695,9 @@
}
mAdapter.notifyDataSetChanged();
mProgressBar.setVisibility(View.GONE);
- mList.setVisibility(View.VISIBLE);
+ mContentView.setVisibility(View.VISIBLE);
mProgressBar.setProgress(0);
- mAliasLoaders.remove(mTab);
+ mAliasLoaders.remove(this);
showTrustAllCaDialogIfNeeded();
}
@@ -615,7 +745,7 @@
/* package */ static class CertHolder implements Comparable<CertHolder> {
public int mProfileId;
private final IKeyChainService mService;
- private final TrustedCertificateAdapterCommons mAdapter;
+ private final GroupAdapter mAdapter;
private final Tab mTab;
private final String mAlias;
private final X509Certificate mX509Cert;
@@ -626,7 +756,7 @@
private boolean mDeleted;
private CertHolder(IKeyChainService service,
- TrustedCertificateAdapterCommons adapter,
+ GroupAdapter adapter,
Tab tab,
String alias,
X509Certificate x509Cert,
@@ -706,40 +836,6 @@
}
}
- private View getViewForCertificate(CertHolder certHolder, Tab mTab, View convertView,
- ViewGroup parent) {
- ViewHolder holder;
- if (convertView == null) {
- LayoutInflater inflater = LayoutInflater.from(getActivity());
- convertView = inflater.inflate(R.layout.trusted_credential, parent, false);
- holder = new ViewHolder();
- 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);
- convertView.setTag(holder);
- } 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);
- }
- return convertView;
- }
-
- private static class ViewHolder {
- private TextView mSubjectPrimaryView;
- private TextView mSubjectSecondaryView;
- private Switch mSwitch;
- }
private boolean isTrustAllCaCertModeInProgress() {
return mTrustAllCaUserId != UserHandle.USER_NULL;
@@ -824,7 +920,17 @@
@Override
protected void onPostExecute(Boolean ok) {
- mCertHolder.mTab.postOperationUpdate(ok, mCertHolder);
+ 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;
}
}