Add handling for account tiles for specific account type.

- List individual account instead of account type under User & account
  screen.

- Add handling to move account tiles with specific account type from
  top level account dashboard to inside the corresponding account
  preference.

- Rename settings.accounts.AccountPreference to
  settings.accounts.AccountTypePreference to make it less confused
  with settings.AccountPreference

Bug: 31801423
Test: make RunSettingsRoboTests
Change-Id: Iebe70a3c4230e8d979344f142a5c2a60945e552e
This commit is contained in:
Doris Ling
2016-11-22 16:37:06 -08:00
parent 737ae83a66
commit 20d4b041f7
15 changed files with 560 additions and 57 deletions

View File

@@ -0,0 +1,123 @@
/*
* 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.
*/
package com.android.settings.accounts;
import android.accounts.Account;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.PreferenceController;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.drawer.Tile;
import java.util.ArrayList;
import java.util.List;
public class AccountDetailDashboardFragment extends DashboardFragment {
private static final String TAG = "AccountDetailDashboard";
private static final String METADATA_IA_ACCOUNT = "com.android.settings.ia.account";
public static final String KEY_ACCOUNT = "account";
public static final String KEY_ACCOUNT_TYPE = "account_type";
public static final String KEY_ACCOUNT_LABEL = "account_label";
public static final String KEY_ACCOUNT_TITLE_RES = "account_title_res";
private String mAccountLabel;
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
String mAccountType;
private AccountSyncPreferenceController mAccountSynController;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Bundle args = getArguments();
final Activity activity = getActivity();
UserHandle userHandle = Utils.getSecureTargetUser(activity.getActivityToken(),
(UserManager) getSystemService(Context.USER_SERVICE), args,
activity.getIntent().getExtras());
Account account = null;
if (args != null) {
if (args.containsKey(KEY_ACCOUNT)) {
account = args.getParcelable(KEY_ACCOUNT);
}
if (args.containsKey(KEY_ACCOUNT_LABEL)) {
mAccountLabel = args.getString(KEY_ACCOUNT_LABEL);
}
if (args.containsKey(KEY_ACCOUNT_TYPE)) {
mAccountType = args.getString(KEY_ACCOUNT_TYPE);
}
}
mAccountSynController.init(account, userHandle);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (mAccountLabel != null) {
getActivity().setTitle(mAccountLabel);
}
}
@Override
public int getMetricsCategory() {
return MetricsEvent.ACCOUNT;
}
@Override
protected String getCategoryKey() {
return CategoryKey.CATEGORY_ACCOUNT;
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.account_type_settings;
}
@Override
protected List<PreferenceController> getPreferenceControllers(Context context) {
final List<PreferenceController> controllers = new ArrayList<>();
mAccountSynController = new AccountSyncPreferenceController(context);
controllers.add(mAccountSynController);
return controllers;
}
@Override
protected boolean displayTile(Tile tile) {
if (mAccountType == null) {
return false;
}
final Bundle metadata = tile.metaData;
if (metadata == null) {
return false;
}
return mAccountType.equals(metadata.getString(METADATA_IA_ACCOUNT));
}
}

View File

@@ -26,6 +26,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
@@ -47,6 +48,7 @@ import com.android.settings.core.PreferenceController;
import com.android.settings.core.lifecycle.LifecycleObserver;
import com.android.settings.core.lifecycle.events.OnPause;
import com.android.settings.core.lifecycle.events.OnResume;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.Index;
import com.android.settings.search.SearchIndexableRaw;
@@ -86,6 +88,7 @@ public class AccountPreferenceController extends PreferenceController
private boolean mIAEnabled;
private int mAccountProfileOrder = ORDER_ACCOUNT_PROFILES;
private AccountRestrictionHelper mHelper;
private DashboardFeatureProvider mDashboardFeatureProvider;
/**
* Holds data related to the accounts belonging to one profile.
@@ -132,8 +135,9 @@ public class AccountPreferenceController extends PreferenceController
if (mAuthorities != null) {
mAuthoritiesCount = mAuthorities.length;
}
mIAEnabled = FeatureFactory.getFactory(mContext).getDashboardFeatureProvider(mContext)
.isEnabled();
mDashboardFeatureProvider =
FeatureFactory.getFactory(mContext).getDashboardFeatureProvider(mContext);
mIAEnabled = mDashboardFeatureProvider.isEnabled();
mHelper = helper;
}
@@ -250,11 +254,6 @@ public class AccountPreferenceController extends PreferenceController
}
private void updateUi() {
if (!mIAEnabled) {
// Load the preferences from an XML resource
mParent.addPreferencesFromResource(R.xml.account_settings);
}
if (!isAvailable()) {
// This should not happen
Log.e(TAG, "We should not be showing settings for a managed profile");
@@ -264,6 +263,11 @@ public class AccountPreferenceController extends PreferenceController
return;
}
if (!mIAEnabled) {
// Load the preferences from an XML resource
mParent.addPreferencesFromResource(R.xml.account_settings);
}
if (mUm.isLinkedUser()) {
// Restricted user or similar
UserInfo userInfo = mUm.getUserInfo(UserHandle.myUserId());
@@ -400,7 +404,7 @@ public class AccountPreferenceController extends PreferenceController
private void updateAccountTypes(ProfileData profileData) {
profileData.preferenceGroup.removeAll();
if (profileData.userInfo.isEnabled()) {
final ArrayList<AccountPreference> preferences = getAccountTypePreferences(
final ArrayList<AccountTypePreference> preferences = getAccountTypePreferences(
profileData.authenticatorHelper, profileData.userInfo.getUserHandle());
final int count = preferences.size();
for (int i = 0; i < count; i++) {
@@ -430,11 +434,11 @@ public class AccountPreferenceController extends PreferenceController
}
}
private ArrayList<AccountPreference> getAccountTypePreferences(AuthenticatorHelper helper,
private ArrayList<AccountTypePreference> getAccountTypePreferences(AuthenticatorHelper helper,
UserHandle userHandle) {
final String[] accountTypes = helper.getEnabledAccountTypes();
final ArrayList<AccountPreference> accountTypePreferences =
new ArrayList<AccountPreference>(accountTypes.length);
final ArrayList<AccountTypePreference> accountTypePreferences =
new ArrayList<AccountTypePreference>(accountTypes.length);
for (int i = 0; i < accountTypes.length; i++) {
final String accountType = accountTypes[i];
@@ -453,17 +457,40 @@ public class AccountPreferenceController extends PreferenceController
.getAccountsByTypeAsUser(accountType, userHandle);
final boolean skipToAccount = accounts.length == 1
&& !helper.hasAccountPreferences(accountType);
final Drawable icon = helper.getDrawableForType(mContext, accountType);
final Context prefContext = mParent.getPreferenceManager().getContext();
if (skipToAccount) {
if (mIAEnabled) {
// Add a preference row for each individual account
for (Account account : accounts) {
final ArrayList<String> auths =
helper.getAuthoritiesForAccountType(account.type);
if (!AccountRestrictionHelper.showAccount(mAuthorities, auths)) {
continue;
}
final Bundle fragmentArguments = new Bundle();
fragmentArguments.putParcelable(AccountDetailDashboardFragment.KEY_ACCOUNT,
account);
fragmentArguments.putString(AccountDetailDashboardFragment.KEY_ACCOUNT_TYPE,
accountType);
fragmentArguments.putString(AccountDetailDashboardFragment.KEY_ACCOUNT_LABEL,
label.toString());
fragmentArguments.putInt(AccountDetailDashboardFragment.KEY_ACCOUNT_TITLE_RES,
titleResId);
fragmentArguments.putParcelable(EXTRA_USER, userHandle);
accountTypePreferences.add(new AccountTypePreference(
prefContext, account.name, titleResPackageName, titleResId, label,
AccountDetailDashboardFragment.class.getName(), fragmentArguments, icon));
}
} else if (skipToAccount) {
final Bundle fragmentArguments = new Bundle();
fragmentArguments.putParcelable(AccountSyncSettings.ACCOUNT_KEY,
accounts[0]);
fragmentArguments.putParcelable(EXTRA_USER, userHandle);
accountTypePreferences.add(new AccountPreference(
mParent.getPreferenceManager().getContext(), label, titleResPackageName,
titleResId, AccountSyncSettings.class.getName(), fragmentArguments,
helper.getDrawableForType(mContext, accountType)));
accountTypePreferences.add(new AccountTypePreference(
prefContext, label, titleResPackageName,
titleResId, AccountSyncSettings.class.getName(), fragmentArguments, icon));
} else {
final Bundle fragmentArguments = new Bundle();
fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType);
@@ -471,18 +498,23 @@ public class AccountPreferenceController extends PreferenceController
label.toString());
fragmentArguments.putParcelable(EXTRA_USER, userHandle);
accountTypePreferences.add(new AccountPreference(
mParent.getPreferenceManager().getContext(), label, titleResPackageName,
titleResId, ManageAccountsSettings.class.getName(), fragmentArguments,
helper.getDrawableForType(mContext, accountType)));
accountTypePreferences.add(new AccountTypePreference(
prefContext, label, titleResPackageName,
titleResId, ManageAccountsSettings.class.getName(), fragmentArguments, icon));
}
helper.preloadDrawableForType(mContext, accountType);
}
// Sort by label
Collections.sort(accountTypePreferences, new Comparator<AccountPreference>() {
Collections.sort(accountTypePreferences, new Comparator<AccountTypePreference>() {
@Override
public int compare(AccountPreference t1, AccountPreference t2) {
return t1.getitle().toString().compareTo(t2.getitle().toString());
public int compare(AccountTypePreference t1, AccountTypePreference t2) {
int result = 0;
if (mIAEnabled) {
result = t1.getSummary().toString().compareTo(t2.getSummary().toString());
}
return result != 0
? result : t1.getTitle().toString().compareTo(t2.getTitle().toString());
}
});
return accountTypePreferences;

View File

@@ -20,6 +20,7 @@ import android.content.Context;
import com.android.settings.AccessiblePreferenceCategory;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreference;
import java.util.ArrayList;
public class AccountRestrictionHelper {
@@ -55,4 +56,22 @@ public class AccountRestrictionHelper {
return new AccessiblePreferenceCategory(context);
}
/**
* Checks if the account should be shown based on the required authorities for the account type
* @param authorities given authority that is passed as activity extra
* @param auths list of authorities for particular account type
* @return true if the activity has the required authority to show the account
*/
public static boolean showAccount(String[] authorities, ArrayList<String> auths) {
boolean showAccount = true;
if (authorities != null && auths != null) {
showAccount = false;
for (String requestedAuthority : authorities) {
if (auths.contains(requestedAuthority)) {
return true;
}
}
}
return showAccount;
}
}

View File

@@ -0,0 +1,69 @@
/*
* 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.
*/
package com.android.settings.accounts;
import static android.content.Intent.EXTRA_USER;
import android.accounts.Account;
import android.content.Context;
import android.os.Bundle;
import android.os.UserHandle;
import android.support.v7.preference.Preference;
import com.android.settings.Utils;
import com.android.settings.core.PreferenceController;
public class AccountSyncPreferenceController extends PreferenceController {
private static final String TAG = "AccountSyncController";
private static final String KEY_ACCOUNT_SYNC = "account_sync";
private Account mAccount;
private UserHandle mUserHandle;
public AccountSyncPreferenceController(Context context) {
super(context);
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!KEY_ACCOUNT_SYNC.equals(preference.getKey())) {
return false;
}
final Bundle args = new Bundle();
args.putParcelable(AccountSyncSettings.ACCOUNT_KEY, mAccount);
args.putParcelable(EXTRA_USER, mUserHandle);
Utils.startWithFragment(mContext, AccountSyncSettings.class.getName(), args, null, 0, -1,
mAccount.name);
return true;
}
@Override
public String getPreferenceKey() {
return KEY_ACCOUNT_SYNC;
}
public void init(Account account, UserHandle userHandle) {
mAccount = account;
mUserHandle = userHandle;
}
}

View File

@@ -29,7 +29,7 @@ import com.android.settings.Utils;
import static android.content.Intent.EXTRA_USER;
public class AccountPreference extends Preference implements OnPreferenceClickListener {
public class AccountTypePreference extends Preference implements OnPreferenceClickListener {
/**
* Title of the tile that is shown to the user.
* @attr ref android.R.styleable#PreferenceHeader_title
@@ -47,6 +47,11 @@ public class AccountPreference extends Preference implements OnPreferenceClickLi
*/
private final int mTitleResId;
/**
* Summary of the tile that is shown to the user.
*/
private final CharSequence mSummary;
/**
* Full class name of the fragment to display when this tile is
* selected.
@@ -60,17 +65,26 @@ public class AccountPreference extends Preference implements OnPreferenceClickLi
*/
private final Bundle mFragmentArguments;
public AccountPreference(Context context, CharSequence title, String titleResPackageName,
public AccountTypePreference(Context context, CharSequence title, String titleResPackageName,
int titleResId, String fragment, Bundle fragmentArguments, Drawable icon) {
this(context, title, titleResPackageName, titleResId, null, fragment, fragmentArguments,
icon);
}
public AccountTypePreference(Context context, CharSequence title, String titleResPackageName,
int titleResId, CharSequence summary, String fragment, Bundle fragmentArguments,
Drawable icon) {
super(context);
mTitle = title;
mTitleResPackageName = titleResPackageName;
mTitleResId = titleResId;
mSummary = summary;
mFragment = fragment;
mFragmentArguments = fragmentArguments;
setWidgetLayoutResource(R.layout.account_type_preference);
setTitle(title);
setSummary(summary);
setIcon(icon);
setOnPreferenceClickListener(this);
@@ -97,8 +111,12 @@ public class AccountPreference extends Preference implements OnPreferenceClickLi
return false;
}
public CharSequence getitle() {
public CharSequence getTitle() {
return mTitle;
}
public CharSequence getSummary() {
return mSummary;
}
}

View File

@@ -373,18 +373,7 @@ public class ManageAccountsSettings extends AccountPreferenceBase
if (mAccountType != null && !account.type.equals(mAccountType)) continue;
final ArrayList<String> auths = getAuthoritiesForAccountType(account.type);
boolean showAccount = true;
if (mAuthorities != null && auths != null) {
showAccount = false;
for (String requestedAuthority : mAuthorities) {
if (auths.contains(requestedAuthority)) {
showAccount = true;
break;
}
}
}
if (showAccount) {
if (AccountRestrictionHelper.showAccount(mAuthorities, auths)) {
final Drawable icon = getDrawableForType(account.type);
final AccountPreference preference =
new AccountPreference(getPrefContext(), account, icon, auths, false);

View File

@@ -17,13 +17,18 @@ package com.android.settings.accounts;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.preference.Preference;
import android.util.ArraySet;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.core.PreferenceController;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.drawer.Tile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import static android.provider.Settings.EXTRA_AUTHORITIES;
@@ -31,6 +36,8 @@ import static android.provider.Settings.EXTRA_AUTHORITIES;
public class UserAndAccountDashboardFragment extends DashboardFragment {
private static final String TAG = "UserAndAccountDashboard";
private static final String METADATA_IA_ACCOUNT = "com.android.settings.ia.account";
private HashMap<String, ArraySet<Preference>> mAccountTiles = new HashMap<>();
@Override
public int getMetricsCategory() {
@@ -71,4 +78,13 @@ public class UserAndAccountDashboardFragment extends DashboardFragment {
return controllers;
}
}
@Override
protected boolean displayTile(Tile tile) {
final Bundle metadata = tile.metaData;
if (metadata != null) {
return metadata.getString(METADATA_IA_ACCOUNT) == null;
}
return true;
}
}