Add work account settings.
Bug: 15467756 Change-Id: I13b5a0bb3967611d0d24b575bfc15d9bfaad4cfa
This commit is contained in:
@@ -127,7 +127,8 @@ public class SettingsActivity extends Activity
|
|||||||
PreferenceFragment.OnPreferenceStartFragmentCallback,
|
PreferenceFragment.OnPreferenceStartFragmentCallback,
|
||||||
ButtonBarHandler, OnAccountsUpdateListener, FragmentManager.OnBackStackChangedListener,
|
ButtonBarHandler, OnAccountsUpdateListener, FragmentManager.OnBackStackChangedListener,
|
||||||
SearchView.OnQueryTextListener, SearchView.OnCloseListener,
|
SearchView.OnQueryTextListener, SearchView.OnCloseListener,
|
||||||
MenuItem.OnActionExpandListener {
|
MenuItem.OnActionExpandListener,
|
||||||
|
AuthenticatorHelper.OnAccountsUpdateListener {
|
||||||
|
|
||||||
private static final String LOG_TAG = "Settings";
|
private static final String LOG_TAG = "Settings";
|
||||||
|
|
||||||
@@ -466,10 +467,13 @@ public class SettingsActivity extends Activity
|
|||||||
if (intent.hasExtra(EXTRA_UI_OPTIONS)) {
|
if (intent.hasExtra(EXTRA_UI_OPTIONS)) {
|
||||||
getWindow().setUiOptions(intent.getIntExtra(EXTRA_UI_OPTIONS, 0));
|
getWindow().setUiOptions(intent.getIntExtra(EXTRA_UI_OPTIONS, 0));
|
||||||
}
|
}
|
||||||
|
// TODO: Delete accounts tile once we have the new screen working
|
||||||
mAuthenticatorHelper = new AuthenticatorHelper();
|
// See: http://b/15815948
|
||||||
|
final UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
|
||||||
|
mAuthenticatorHelper = new AuthenticatorHelper(
|
||||||
|
this, UserHandle.getCallingUserHandle(), um, this);
|
||||||
mAuthenticatorHelper.updateAuthDescriptions(this);
|
mAuthenticatorHelper.updateAuthDescriptions(this);
|
||||||
mAuthenticatorHelper.onAccountsUpdated(this, null);
|
mAuthenticatorHelper.onAccountsUpdated(null);
|
||||||
|
|
||||||
mDevelopmentPreferences = getSharedPreferences(DevelopmentSettings.PREF_FILE,
|
mDevelopmentPreferences = getSharedPreferences(DevelopmentSettings.PREF_FILE,
|
||||||
Context.MODE_PRIVATE);
|
Context.MODE_PRIVATE);
|
||||||
@@ -1263,7 +1267,11 @@ public class SettingsActivity extends Activity
|
|||||||
public void onAccountsUpdated(Account[] accounts) {
|
public void onAccountsUpdated(Account[] accounts) {
|
||||||
// TODO: watch for package upgrades to invalidate cache; see 7206643
|
// TODO: watch for package upgrades to invalidate cache; see 7206643
|
||||||
mAuthenticatorHelper.updateAuthDescriptions(this);
|
mAuthenticatorHelper.updateAuthDescriptions(this);
|
||||||
mAuthenticatorHelper.onAccountsUpdated(this, accounts);
|
invalidateCategories();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAccountsUpdate(UserHandle userHandle) {
|
||||||
invalidateCategories();
|
invalidateCategories();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -56,12 +56,14 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.TabWidget;
|
import android.widget.TabWidget;
|
||||||
|
|
||||||
import com.android.settings.dashboard.DashboardCategory;
|
import com.android.settings.dashboard.DashboardCategory;
|
||||||
import com.android.settings.dashboard.DashboardTile;
|
import com.android.settings.dashboard.DashboardTile;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@@ -579,4 +581,31 @@ public final class Utils {
|
|||||||
intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_AS_SHORTCUT, isShortcut);
|
intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_AS_SHORTCUT, isShortcut);
|
||||||
return intent;
|
return intent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the managed profile of the current user or null if none found.
|
||||||
|
*/
|
||||||
|
public static UserHandle getManagedProfile(UserManager userManager) {
|
||||||
|
List<UserHandle> userProfiles = userManager.getUserProfiles();
|
||||||
|
final int count = userProfiles.size();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
final UserHandle profile = userProfiles.get(i);
|
||||||
|
if (profile.getIdentifier() == userManager.getUserHandle()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final UserInfo userInfo = userManager.getUserInfo(profile.getIdentifier());
|
||||||
|
if (userInfo.isManagedProfile()) {
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the current profile is a managed one.
|
||||||
|
*/
|
||||||
|
public static boolean isManagedProfile(UserManager userManager) {
|
||||||
|
UserInfo currentUser = userManager.getUserInfo(userManager.getUserHandle());
|
||||||
|
return currentUser.isManagedProfile();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,19 +16,9 @@
|
|||||||
|
|
||||||
package com.android.settings.accounts;
|
package com.android.settings.accounts;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.android.settings.SettingsPreferenceFragment;
|
|
||||||
|
|
||||||
import com.google.android.collect.Maps;
|
import com.google.android.collect.Maps;
|
||||||
|
|
||||||
import android.accounts.Account;
|
|
||||||
import android.accounts.AccountManager;
|
|
||||||
import android.accounts.AuthenticatorDescription;
|
import android.accounts.AuthenticatorDescription;
|
||||||
import android.accounts.OnAccountsUpdateListener;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -40,28 +30,47 @@ import android.content.res.Resources.Theme;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
import android.os.UserManager;
|
||||||
import android.preference.PreferenceScreen;
|
import android.preference.PreferenceScreen;
|
||||||
import android.text.format.DateFormat;
|
import android.text.format.DateFormat;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.ContextThemeWrapper;
|
import android.view.ContextThemeWrapper;
|
||||||
|
|
||||||
|
import com.android.settings.SettingsPreferenceFragment;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
class AccountPreferenceBase extends SettingsPreferenceFragment
|
class AccountPreferenceBase extends SettingsPreferenceFragment
|
||||||
implements OnAccountsUpdateListener {
|
implements AuthenticatorHelper.OnAccountsUpdateListener {
|
||||||
|
|
||||||
protected static final String TAG = "AccountSettings";
|
protected static final String TAG = "AccountSettings";
|
||||||
public static final String AUTHORITIES_FILTER_KEY = "authorities";
|
public static final String AUTHORITIES_FILTER_KEY = "authorities";
|
||||||
public static final String ACCOUNT_TYPES_FILTER_KEY = "account_types";
|
public static final String ACCOUNT_TYPES_FILTER_KEY = "account_types";
|
||||||
private final Handler mHandler = new Handler();
|
private final Handler mHandler = new Handler();
|
||||||
|
private UserManager mUm;
|
||||||
private Object mStatusChangeListenerHandle;
|
private Object mStatusChangeListenerHandle;
|
||||||
private HashMap<String, ArrayList<String>> mAccountTypeToAuthorities = null;
|
private HashMap<String, ArrayList<String>> mAccountTypeToAuthorities = null;
|
||||||
private AuthenticatorHelper mAuthenticatorHelper = new AuthenticatorHelper();
|
protected AuthenticatorHelper mAuthenticatorHelper;
|
||||||
private java.text.DateFormat mDateFormat;
|
private java.text.DateFormat mDateFormat;
|
||||||
private java.text.DateFormat mTimeFormat;
|
private java.text.DateFormat mTimeFormat;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle icicle) {
|
||||||
|
super.onCreate(icicle);
|
||||||
|
// TODO: This needs to handle different users, get the user id from the intent
|
||||||
|
mUm = (UserManager) getSystemService(Context.USER_SERVICE);
|
||||||
|
mAuthenticatorHelper = new AuthenticatorHelper(
|
||||||
|
getActivity(), UserHandle.getCallingUserHandle(), mUm, this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overload to handle account updates.
|
* Overload to handle account updates.
|
||||||
*/
|
*/
|
||||||
public void onAccountsUpdated(Account[] accounts) {
|
@Override
|
||||||
|
public void onAccountsUpdate(UserHandle userHandle) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,11 +19,17 @@ package com.android.settings.accounts;
|
|||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.accounts.AccountManager;
|
import android.accounts.AccountManager;
|
||||||
import android.accounts.OnAccountsUpdateListener;
|
import android.accounts.OnAccountsUpdateListener;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.content.pm.UserInfo;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.SparseArray;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.Preference.OnPreferenceClickListener;
|
import android.preference.Preference.OnPreferenceClickListener;
|
||||||
import android.preference.PreferenceGroup;
|
import android.preference.PreferenceGroup;
|
||||||
@@ -33,16 +39,17 @@ import com.android.settings.SettingsPreferenceFragment;
|
|||||||
import com.android.settings.Utils;
|
import com.android.settings.Utils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings screen for the account types on the device.
|
* Settings screen for the account types on the device.
|
||||||
* This shows all account types available for personal and work profiles.
|
* This shows all account types available for personal and work profiles.
|
||||||
*/
|
*/
|
||||||
public class AccountSettings extends SettingsPreferenceFragment
|
public class AccountSettings extends SettingsPreferenceFragment
|
||||||
implements OnAccountsUpdateListener, OnPreferenceClickListener {
|
implements AuthenticatorHelper.OnAccountsUpdateListener,
|
||||||
|
OnPreferenceClickListener {
|
||||||
public static final String TAG = "AccountSettings";
|
public static final String TAG = "AccountSettings";
|
||||||
|
|
||||||
private static final String KEY_ACCOUNT = "account";
|
private static final String KEY_ACCOUNT = "account";
|
||||||
@@ -51,128 +58,183 @@ public class AccountSettings extends SettingsPreferenceFragment
|
|||||||
private static final String KEY_CATEGORY_PERSONAL = "account_personal";
|
private static final String KEY_CATEGORY_PERSONAL = "account_personal";
|
||||||
private static final String KEY_ADD_ACCOUNT_PERSONAL = "add_account_personal";
|
private static final String KEY_ADD_ACCOUNT_PERSONAL = "add_account_personal";
|
||||||
private static final String KEY_CATEGORY_WORK = "account_work";
|
private static final String KEY_CATEGORY_WORK = "account_work";
|
||||||
|
private static final String KEY_ADD_ACCOUNT_WORK = "add_account_work";
|
||||||
|
|
||||||
private AuthenticatorHelper mAuthenticatorHelper;
|
private static final String ADD_ACCOUNT_ACTION = "android.settings.ADD_ACCOUNT_SETTINGS";
|
||||||
private boolean mListeningToAccountUpdates;
|
|
||||||
|
|
||||||
private PreferenceGroup mAccountTypesForUser;
|
|
||||||
private Preference mAddAccountForUser;
|
|
||||||
|
|
||||||
private UserManager mUm;
|
private UserManager mUm;
|
||||||
|
private SparseArray<ProfileData> mProfiles;
|
||||||
|
private ManagedProfileBroadcastReceiver mManagedProfileBroadcastReceiver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds data related to the accounts belonging to one profile.
|
||||||
|
*/
|
||||||
|
private static class ProfileData {
|
||||||
|
/**
|
||||||
|
* The preference that displays the accounts.
|
||||||
|
*/
|
||||||
|
public PreferenceGroup preferenceGroup;
|
||||||
|
/**
|
||||||
|
* The preference that displays the add account button.
|
||||||
|
*/
|
||||||
|
public Preference addAccountPreference;
|
||||||
|
/**
|
||||||
|
* The user handle of the user that these accounts belong to.
|
||||||
|
*/
|
||||||
|
public UserHandle userHandle;
|
||||||
|
/**
|
||||||
|
* The {@link AuthenticatorHelper} that holds accounts data for this profile.
|
||||||
|
*/
|
||||||
|
public AuthenticatorHelper authenticatorHelper;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
mUm = (UserManager) getSystemService(Context.USER_SERVICE);
|
mUm = (UserManager) getSystemService(Context.USER_SERVICE);
|
||||||
|
mProfiles = new SparseArray<ProfileData>(2);
|
||||||
|
updateUi();
|
||||||
|
}
|
||||||
|
|
||||||
mAuthenticatorHelper = new AuthenticatorHelper();
|
void updateUi() {
|
||||||
mAuthenticatorHelper.updateAuthDescriptions(getActivity());
|
|
||||||
mAuthenticatorHelper.onAccountsUpdated(getActivity(), null);
|
|
||||||
|
|
||||||
// Load the preferences from an XML resource
|
// Load the preferences from an XML resource
|
||||||
addPreferencesFromResource(R.xml.account_settings);
|
addPreferencesFromResource(R.xml.account_settings);
|
||||||
|
|
||||||
if(mUm.isLinkedUser()) {
|
if(mUm.isLinkedUser()) {
|
||||||
// Restricted user or similar
|
// Restricted user or similar
|
||||||
// TODO: Do we disallow modifying accounts for restricted profiles?
|
updateSingleProfileUi();
|
||||||
mAccountTypesForUser = (PreferenceGroup) findPreference(KEY_ACCOUNT);
|
|
||||||
if (mUm.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) {
|
|
||||||
removePreference(KEY_ADD_ACCOUNT);
|
|
||||||
} else {
|
} else {
|
||||||
mAddAccountForUser = findPreference(KEY_ADD_ACCOUNT);
|
if (Utils.isManagedProfile(mUm)) {
|
||||||
mAddAccountForUser.setOnPreferenceClickListener(this);
|
// This should not happen
|
||||||
|
Log.w(TAG, "We should not be showing settings for a managed profile");
|
||||||
|
updateSingleProfileUi();
|
||||||
}
|
}
|
||||||
removePreference(KEY_CATEGORY_PERSONAL);
|
final UserHandle currentProfile = UserHandle.getCallingUserHandle();
|
||||||
removePreference(KEY_CATEGORY_WORK);
|
final UserHandle managedProfile = Utils.getManagedProfile(mUm);
|
||||||
|
if (managedProfile == null) {
|
||||||
|
updateSingleProfileUi();
|
||||||
} else {
|
} else {
|
||||||
mAccountTypesForUser = (PreferenceGroup) findPreference(KEY_CATEGORY_PERSONAL);
|
updateProfileUi(currentProfile,
|
||||||
mAddAccountForUser = findPreference(KEY_ADD_ACCOUNT_PERSONAL);
|
KEY_CATEGORY_PERSONAL, KEY_ADD_ACCOUNT_PERSONAL, new ArrayList<String>());
|
||||||
mAddAccountForUser.setOnPreferenceClickListener(this);
|
final ArrayList<String> unusedPreferences = new ArrayList<String>(1);
|
||||||
|
unusedPreferences.add(KEY_ADD_ACCOUNT);
|
||||||
|
updateProfileUi(managedProfile,
|
||||||
|
KEY_CATEGORY_WORK, KEY_ADD_ACCOUNT_WORK, unusedPreferences);
|
||||||
|
mManagedProfileBroadcastReceiver = new ManagedProfileBroadcastReceiver();
|
||||||
|
mManagedProfileBroadcastReceiver.register(getActivity());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final int count = mProfiles.size();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
updateAccountTypes(mProfiles.valueAt(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Show the work accounts also
|
private void updateSingleProfileUi() {
|
||||||
// TODO: Handle the case where there is only one account
|
final ArrayList<String> unusedPreferences = new ArrayList<String>(2);
|
||||||
removePreference(KEY_CATEGORY_WORK);
|
unusedPreferences.add(KEY_CATEGORY_PERSONAL);
|
||||||
removePreference(KEY_ADD_ACCOUNT);
|
unusedPreferences.add(KEY_CATEGORY_WORK);
|
||||||
|
updateProfileUi(UserHandle.getCallingUserHandle(), KEY_ACCOUNT, KEY_ADD_ACCOUNT,
|
||||||
|
unusedPreferences);
|
||||||
}
|
}
|
||||||
updateAccountTypes(mAccountTypesForUser);
|
|
||||||
|
private void updateProfileUi(UserHandle userHandle, String categoryKey, String addAccountKey,
|
||||||
|
ArrayList<String> unusedPreferences) {
|
||||||
|
final int count = unusedPreferences.size();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
removePreference(unusedPreferences.get(i));
|
||||||
|
}
|
||||||
|
final ProfileData profileData = new ProfileData();
|
||||||
|
profileData.preferenceGroup = (PreferenceGroup) findPreference(categoryKey);
|
||||||
|
if (mUm.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) {
|
||||||
|
removePreference(addAccountKey);
|
||||||
|
} else {
|
||||||
|
profileData.addAccountPreference = findPreference(addAccountKey);
|
||||||
|
profileData.addAccountPreference.setOnPreferenceClickListener(this);
|
||||||
|
}
|
||||||
|
profileData.userHandle = userHandle;
|
||||||
|
profileData.authenticatorHelper = new AuthenticatorHelper(
|
||||||
|
getActivity(), userHandle, mUm, this);
|
||||||
|
mProfiles.put(userHandle.getIdentifier(), profileData);
|
||||||
|
|
||||||
|
profileData.authenticatorHelper.listenToAccountUpdates();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
stopListeningToAccountUpdates();
|
cleanUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanUp() {
|
||||||
|
if (mManagedProfileBroadcastReceiver != null) {
|
||||||
|
mManagedProfileBroadcastReceiver.unregister(getActivity());
|
||||||
|
}
|
||||||
|
final int count = mProfiles.size();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
mProfiles.valueAt(i).authenticatorHelper.stopListeningToAccountUpdates();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAccountsUpdated(Account[] accounts) {
|
public void onAccountsUpdate(UserHandle userHandle) {
|
||||||
// TODO: watch for package upgrades to invalidate cache; see 7206643
|
final ProfileData profileData = mProfiles.get(userHandle.getIdentifier());
|
||||||
mAuthenticatorHelper.updateAuthDescriptions(getActivity());
|
if (profileData != null) {
|
||||||
mAuthenticatorHelper.onAccountsUpdated(getActivity(), accounts);
|
updateAccountTypes(profileData);
|
||||||
listenToAccountUpdates();
|
} else {
|
||||||
updateAccountTypes(mAccountTypesForUser);
|
Log.w(TAG, "Missing Settings screen for: " + userHandle.getIdentifier());
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPreferenceClick(Preference preference) {
|
|
||||||
// Check the preference
|
|
||||||
if (preference == mAddAccountForUser) {
|
|
||||||
Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
|
|
||||||
startActivity(intent);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateAccountTypes(PreferenceGroup preferenceGroup) {
|
|
||||||
preferenceGroup.removeAll();
|
|
||||||
preferenceGroup.setOrderingAsAdded(true);
|
|
||||||
for (AccountPreference preference : getAccountTypePreferences()) {
|
|
||||||
preferenceGroup.addPreference(preference);
|
|
||||||
}
|
|
||||||
if (mAddAccountForUser != null) {
|
|
||||||
preferenceGroup.addPreference(mAddAccountForUser);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<AccountPreference> getAccountTypePreferences() {
|
private void updateAccountTypes(ProfileData profileData) {
|
||||||
String[] accountTypes = mAuthenticatorHelper.getEnabledAccountTypes();
|
profileData.preferenceGroup.removeAll();
|
||||||
List<AccountPreference> accountTypePreferences =
|
final ArrayList<AccountPreference> preferences = getAccountTypePreferences(
|
||||||
|
profileData.authenticatorHelper);
|
||||||
|
final int count = preferences.size();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
profileData.preferenceGroup.addPreference(preferences.get(i));
|
||||||
|
}
|
||||||
|
if (profileData.addAccountPreference != null) {
|
||||||
|
profileData.preferenceGroup.addPreference(profileData.addAccountPreference);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<AccountPreference> getAccountTypePreferences(AuthenticatorHelper helper) {
|
||||||
|
final String[] accountTypes = helper.getEnabledAccountTypes();
|
||||||
|
final ArrayList<AccountPreference> accountTypePreferences =
|
||||||
new ArrayList<AccountPreference>(accountTypes.length);
|
new ArrayList<AccountPreference>(accountTypes.length);
|
||||||
for (String accountType : accountTypes) {
|
|
||||||
CharSequence label = mAuthenticatorHelper.getLabelForType(getActivity(), accountType);
|
for (int i = 0; i < accountTypes.length; i++) {
|
||||||
|
final String accountType = accountTypes[i];
|
||||||
|
final CharSequence label = helper.getLabelForType(getActivity(), accountType);
|
||||||
if (label == null) {
|
if (label == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Account[] accounts = AccountManager.get(getActivity()).getAccountsByType(accountType);
|
final Account[] accounts = AccountManager.get(getActivity())
|
||||||
boolean skipToAccount = accounts.length == 1
|
.getAccountsByType(accountType);
|
||||||
&& !mAuthenticatorHelper.hasAccountPreferences(accountType);
|
final boolean skipToAccount = accounts.length == 1
|
||||||
|
&& !helper.hasAccountPreferences(accountType);
|
||||||
|
|
||||||
if (skipToAccount) {
|
if (skipToAccount) {
|
||||||
Bundle fragmentArguments = new Bundle();
|
final Bundle fragmentArguments = new Bundle();
|
||||||
fragmentArguments.putParcelable(AccountSyncSettings.ACCOUNT_KEY,
|
fragmentArguments.putParcelable(AccountSyncSettings.ACCOUNT_KEY,
|
||||||
accounts[0]);
|
accounts[0]);
|
||||||
|
|
||||||
accountTypePreferences.add(new AccountPreference(
|
accountTypePreferences.add(new AccountPreference(getActivity(), label,
|
||||||
getActivity(),
|
AccountSyncSettings.class.getName(), fragmentArguments,
|
||||||
label,
|
helper.getDrawableForType(getActivity(), accountType)));
|
||||||
accountType,
|
|
||||||
AccountSyncSettings.class.getName(),
|
|
||||||
fragmentArguments));
|
|
||||||
} else {
|
} else {
|
||||||
Bundle fragmentArguments = new Bundle();
|
final Bundle fragmentArguments = new Bundle();
|
||||||
fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType);
|
fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType);
|
||||||
fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_LABEL,
|
fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_LABEL,
|
||||||
label.toString());
|
label.toString());
|
||||||
|
|
||||||
accountTypePreferences.add(new AccountPreference(
|
accountTypePreferences.add(new AccountPreference(getActivity(), label,
|
||||||
getActivity(),
|
ManageAccountsSettings.class.getName(), fragmentArguments,
|
||||||
label,
|
helper.getDrawableForType(getActivity(), accountType)));
|
||||||
accountType,
|
|
||||||
ManageAccountsSettings.class.getName(),
|
|
||||||
fragmentArguments));
|
|
||||||
}
|
}
|
||||||
mAuthenticatorHelper.preloadDrawableForType(getActivity(), accountType);
|
helper.preloadDrawableForType(getActivity(), accountType);
|
||||||
}
|
}
|
||||||
// Sort by label
|
// Sort by label
|
||||||
Collections.sort(accountTypePreferences, new Comparator<AccountPreference>() {
|
Collections.sort(accountTypePreferences, new Comparator<AccountPreference>() {
|
||||||
@@ -184,18 +246,20 @@ public class AccountSettings extends SettingsPreferenceFragment
|
|||||||
return accountTypePreferences;
|
return accountTypePreferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void listenToAccountUpdates() {
|
@Override
|
||||||
if (!mListeningToAccountUpdates) {
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
AccountManager.get(getActivity()).addOnAccountsUpdatedListener(this, null, true);
|
// Check the preference
|
||||||
mListeningToAccountUpdates = true;
|
final int count = mProfiles.size();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
ProfileData profileData = mProfiles.valueAt(i);
|
||||||
|
if (preference == profileData.addAccountPreference) {
|
||||||
|
Intent intent = new Intent(ADD_ACCOUNT_ACTION);
|
||||||
|
intent.putExtra(Intent.EXTRA_USER_HANDLE, profileData.userHandle);
|
||||||
|
startActivity(intent);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
private void stopListeningToAccountUpdates() {
|
|
||||||
if (mListeningToAccountUpdates) {
|
|
||||||
AccountManager.get(getActivity()).removeOnAccountsUpdatedListener(this);
|
|
||||||
mListeningToAccountUpdates = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AccountPreference extends Preference implements OnPreferenceClickListener {
|
private class AccountPreference extends Preference implements OnPreferenceClickListener {
|
||||||
@@ -218,18 +282,16 @@ public class AccountSettings extends SettingsPreferenceFragment
|
|||||||
*/
|
*/
|
||||||
private final Bundle mFragmentArguments;
|
private final Bundle mFragmentArguments;
|
||||||
|
|
||||||
|
public AccountPreference(Context context, CharSequence title, String fragment,
|
||||||
public AccountPreference(Context context, CharSequence title,
|
Bundle fragmentArguments, Drawable icon) {
|
||||||
String accountType, String fragment, Bundle fragmentArguments) {
|
|
||||||
super(context);
|
super(context);
|
||||||
mTitle = title;
|
mTitle = title;
|
||||||
mFragment = fragment;
|
mFragment = fragment;
|
||||||
mFragmentArguments = fragmentArguments;
|
mFragmentArguments = fragmentArguments;
|
||||||
setWidgetLayoutResource(R.layout.account_type_preference);
|
setWidgetLayoutResource(R.layout.account_type_preference);
|
||||||
|
|
||||||
Drawable drawable = mAuthenticatorHelper.getDrawableForType(context, accountType);
|
|
||||||
setTitle(title);
|
setTitle(title);
|
||||||
setIcon(drawable);
|
setIcon(icon);
|
||||||
|
|
||||||
setOnPreferenceClickListener(this);
|
setOnPreferenceClickListener(this);
|
||||||
}
|
}
|
||||||
@@ -244,6 +306,39 @@ public class AccountSettings extends SettingsPreferenceFragment
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ManagedProfileBroadcastReceiver extends BroadcastReceiver {
|
||||||
|
private boolean listeningToManagedProfileEvents;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
if (intent.getAction().equals(Intent.ACTION_MANAGED_PROFILE_REMOVED)
|
||||||
|
|| intent.getAction().equals(Intent.ACTION_MANAGED_PROFILE_ADDED)) {
|
||||||
|
Log.v(TAG, "Received broadcast: " + intent.getAction());
|
||||||
|
cleanUp();
|
||||||
|
updateUi();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log.w(TAG, "Cannot handle received broadcast: " + intent.getAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register(Context context) {
|
||||||
|
if (!listeningToManagedProfileEvents) {
|
||||||
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
|
intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
|
||||||
|
intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
|
||||||
|
context.registerReceiver(this, intentFilter);
|
||||||
|
listeningToManagedProfileEvents = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unregister(Context context) {
|
||||||
|
if (listeningToManagedProfileEvents) {
|
||||||
|
context.unregisterReceiver(this);
|
||||||
|
listeningToManagedProfileEvents = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// TODO Implement a {@link SearchIndexProvider} to allow Indexing and Search of account types
|
// TODO Implement a {@link SearchIndexProvider} to allow Indexing and Search of account types
|
||||||
// See http://b/15403806
|
// See http://b/15403806
|
||||||
}
|
}
|
||||||
|
@@ -16,13 +16,15 @@
|
|||||||
|
|
||||||
package com.android.settings.accounts;
|
package com.android.settings.accounts;
|
||||||
|
|
||||||
|
import com.google.android.collect.Lists;
|
||||||
|
import com.google.android.collect.Maps;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.accounts.AccountManager;
|
import android.accounts.AccountManager;
|
||||||
import android.accounts.AccountManagerCallback;
|
import android.accounts.AccountManagerCallback;
|
||||||
import android.accounts.AccountManagerFuture;
|
import android.accounts.AccountManagerFuture;
|
||||||
import android.accounts.AuthenticatorException;
|
import android.accounts.AuthenticatorException;
|
||||||
import android.accounts.OperationCanceledException;
|
import android.accounts.OperationCanceledException;
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
@@ -34,6 +36,7 @@ import android.content.SyncStatusInfo;
|
|||||||
import android.content.pm.ProviderInfo;
|
import android.content.pm.ProviderInfo;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceScreen;
|
import android.preference.PreferenceScreen;
|
||||||
@@ -51,8 +54,6 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.Utils;
|
import com.android.settings.Utils;
|
||||||
import com.google.android.collect.Lists;
|
|
||||||
import com.google.android.collect.Maps;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -193,10 +194,9 @@ public class AccountSyncSettings extends AccountPreferenceBase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
final Activity activity = getActivity();
|
mAuthenticatorHelper.listenToAccountUpdates();
|
||||||
AccountManager.get(activity).addOnAccountsUpdatedListener(this, null, false);
|
|
||||||
updateAuthDescriptions();
|
updateAuthDescriptions();
|
||||||
onAccountsUpdated(AccountManager.get(activity).getAccounts());
|
onAccountsUpdate(UserHandle.getCallingUserHandle());
|
||||||
|
|
||||||
super.onResume();
|
super.onResume();
|
||||||
}
|
}
|
||||||
@@ -204,7 +204,7 @@ public class AccountSyncSettings extends AccountPreferenceBase {
|
|||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
AccountManager.get(getActivity()).removeOnAccountsUpdatedListener(this);
|
mAuthenticatorHelper.stopListeningToAccountUpdates();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSyncStateCheckBox(Account account, String authority) {
|
private void addSyncStateCheckBox(Account account, String authority) {
|
||||||
@@ -436,10 +436,10 @@ public class AccountSyncSettings extends AccountPreferenceBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAccountsUpdated(Account[] accounts) {
|
public void onAccountsUpdate(final UserHandle userHandle) {
|
||||||
super.onAccountsUpdated(accounts);
|
super.onAccountsUpdate(userHandle);
|
||||||
mAccounts = accounts;
|
mAccounts = AccountManager.get(getActivity()).getAccounts();
|
||||||
updateAccountCheckboxes(accounts);
|
updateAccountCheckboxes(mAccounts);
|
||||||
onSyncStateUpdated();
|
onSyncStateUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,27 +19,58 @@ package com.android.settings.accounts;
|
|||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.accounts.AccountManager;
|
import android.accounts.AccountManager;
|
||||||
import android.accounts.AuthenticatorDescription;
|
import android.accounts.AuthenticatorDescription;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
import android.os.UserManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class AuthenticatorHelper {
|
/**
|
||||||
|
* Helper class for monitoring accounts on the device for a given user.
|
||||||
|
*
|
||||||
|
* Classes using this helper should implement {@link OnAccountsUpdateListener}.
|
||||||
|
* {@link OnAccountsUpdateListener#onAccountsUpdate(UserHandle)} will then be
|
||||||
|
* called once accounts get updated. For setting up listening for account
|
||||||
|
* updates, {@link #listenToAccountUpdates()} and
|
||||||
|
* {@link #stopListeningToAccountUpdates()} should be used.
|
||||||
|
*/
|
||||||
|
final public class AuthenticatorHelper extends BroadcastReceiver {
|
||||||
private static final String TAG = "AuthenticatorHelper";
|
private static final String TAG = "AuthenticatorHelper";
|
||||||
|
|
||||||
private Map<String, AuthenticatorDescription> mTypeToAuthDescription
|
private Map<String, AuthenticatorDescription> mTypeToAuthDescription
|
||||||
= new HashMap<String, AuthenticatorDescription>();
|
= new HashMap<String, AuthenticatorDescription>();
|
||||||
private AuthenticatorDescription[] mAuthDescs;
|
private AuthenticatorDescription[] mAuthDescs;
|
||||||
private ArrayList<String> mEnabledAccountTypes = new ArrayList<String>();
|
private ArrayList<String> mEnabledAccountTypes = new ArrayList<String>();
|
||||||
private Map<String, Drawable> mAccTypeIconCache = new HashMap<String, Drawable>();
|
private Map<String, Drawable> mAccTypeIconCache = new HashMap<String, Drawable>();
|
||||||
|
|
||||||
public AuthenticatorHelper() {
|
private final UserHandle mUserHandle;
|
||||||
|
private final UserManager mUm;
|
||||||
|
private final Context mContext;
|
||||||
|
private final OnAccountsUpdateListener mListener;
|
||||||
|
private boolean mListeningToAccountUpdates;
|
||||||
|
|
||||||
|
public interface OnAccountsUpdateListener {
|
||||||
|
void onAccountsUpdate(UserHandle userHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthenticatorHelper(Context context, UserHandle userHandle, UserManager userManager,
|
||||||
|
OnAccountsUpdateListener listener) {
|
||||||
|
mContext = context;
|
||||||
|
mUm = userManager;
|
||||||
|
mUserHandle = userHandle;
|
||||||
|
mListener = listener;
|
||||||
|
// This guarantees that the helper is ready to use once constructed
|
||||||
|
onAccountsUpdated(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getEnabledAccountTypes() {
|
public String[] getEnabledAccountTypes() {
|
||||||
@@ -72,7 +103,8 @@ public class AuthenticatorHelper {
|
|||||||
try {
|
try {
|
||||||
AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
|
AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
|
||||||
Context authContext = context.createPackageContext(desc.packageName, 0);
|
Context authContext = context.createPackageContext(desc.packageName, 0);
|
||||||
icon = authContext.getResources().getDrawable(desc.iconId);
|
icon = mUm.getBadgedDrawableForUser(
|
||||||
|
authContext.getResources().getDrawable(desc.iconId), mUserHandle);
|
||||||
synchronized (mAccTypeIconCache) {
|
synchronized (mAccTypeIconCache) {
|
||||||
mAccTypeIconCache.put(accountType, icon);
|
mAccTypeIconCache.put(accountType, icon);
|
||||||
}
|
}
|
||||||
@@ -112,25 +144,13 @@ public class AuthenticatorHelper {
|
|||||||
* and update any UI that depends on AuthenticatorDescriptions in onAuthDescriptionsUpdated().
|
* and update any UI that depends on AuthenticatorDescriptions in onAuthDescriptionsUpdated().
|
||||||
*/
|
*/
|
||||||
public void updateAuthDescriptions(Context context) {
|
public void updateAuthDescriptions(Context context) {
|
||||||
mAuthDescs = AccountManager.get(context).getAuthenticatorTypes();
|
mAuthDescs = AccountManager.get(context)
|
||||||
|
.getAuthenticatorTypesAsUser(mUserHandle.getIdentifier());
|
||||||
for (int i = 0; i < mAuthDescs.length; i++) {
|
for (int i = 0; i < mAuthDescs.length; i++) {
|
||||||
mTypeToAuthDescription.put(mAuthDescs[i].type, mAuthDescs[i]);
|
mTypeToAuthDescription.put(mAuthDescs[i].type, mAuthDescs[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onAccountsUpdated(Context context, Account[] accounts) {
|
|
||||||
if (accounts == null) {
|
|
||||||
accounts = AccountManager.get(context).getAccounts();
|
|
||||||
}
|
|
||||||
mEnabledAccountTypes.clear();
|
|
||||||
mAccTypeIconCache.clear();
|
|
||||||
for (Account account: accounts) {
|
|
||||||
if (!mEnabledAccountTypes.contains(account.type)) {
|
|
||||||
mEnabledAccountTypes.add(account.type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean containsAccountType(String accountType) {
|
public boolean containsAccountType(String accountType) {
|
||||||
return mTypeToAuthDescription.containsKey(accountType);
|
return mTypeToAuthDescription.containsKey(accountType);
|
||||||
}
|
}
|
||||||
@@ -148,4 +168,50 @@ public class AuthenticatorHelper {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onAccountsUpdated(Account[] accounts) {
|
||||||
|
// TODO: Revert to non-public once no longer needed in SettingsActivity
|
||||||
|
// See http://b/15819268
|
||||||
|
updateAuthDescriptions(mContext);
|
||||||
|
if (accounts == null) {
|
||||||
|
accounts = AccountManager.get(mContext).getAccounts();
|
||||||
|
}
|
||||||
|
mEnabledAccountTypes.clear();
|
||||||
|
mAccTypeIconCache.clear();
|
||||||
|
for (int i = 0; i < accounts.length; i++) {
|
||||||
|
final Account account = accounts[i];
|
||||||
|
if (!mEnabledAccountTypes.contains(account.type)) {
|
||||||
|
mEnabledAccountTypes.add(account.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mListeningToAccountUpdates) {
|
||||||
|
mListener.onAccountsUpdate(mUserHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(final Context context, final Intent intent) {
|
||||||
|
final Account[] accounts = AccountManager.get(mContext)
|
||||||
|
.getAccountsAsUser(mUserHandle.getIdentifier());
|
||||||
|
onAccountsUpdated(accounts);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void listenToAccountUpdates() {
|
||||||
|
if (!mListeningToAccountUpdates) {
|
||||||
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
|
intentFilter.addAction(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION);
|
||||||
|
// At disk full, certain actions are blocked (such as writing the accounts to storage).
|
||||||
|
// It is useful to also listen for recovery from disk full to avoid bugs.
|
||||||
|
intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
|
||||||
|
mContext.registerReceiverAsUser(this, mUserHandle, intentFilter, null, null);
|
||||||
|
mListeningToAccountUpdates = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopListeningToAccountUpdates() {
|
||||||
|
if (mListeningToAccountUpdates) {
|
||||||
|
mContext.unregisterReceiver(this);
|
||||||
|
mListeningToAccountUpdates = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user