diff options
author | Alexandra Gherghina <alexgherghina@google.com> | 2014-06-27 12:33:42 +0100 |
---|---|---|
committer | Alexandra Gherghina <alexgherghina@google.com> | 2014-07-17 19:05:57 +0000 |
commit | 7d748c0267b7d499309464ebae168be01e136b4c (patch) | |
tree | 9c00c859437be85213a59fd1afadc4774df6020f /src/com/android/settings/accounts | |
parent | d888b543b2c188e59ea537ba4e73bf9253fbfc93 (diff) | |
download | packages_apps_Settings-7d748c0267b7d499309464ebae168be01e136b4c.zip packages_apps_Settings-7d748c0267b7d499309464ebae168be01e136b4c.tar.gz packages_apps_Settings-7d748c0267b7d499309464ebae168be01e136b4c.tar.bz2 |
Handle choosing and adding accounts for a managed profile
The user id can now be passed through the app as a fragment argument.
Bug: 15466880
Change-Id: I0e2be20551b4ec8c9226640ac74ea74115156ccd
Diffstat (limited to 'src/com/android/settings/accounts')
5 files changed, 73 insertions, 22 deletions
diff --git a/src/com/android/settings/accounts/AccountPreferenceBase.java b/src/com/android/settings/accounts/AccountPreferenceBase.java index 6125adc..cfe2cb2 100644 --- a/src/com/android/settings/accounts/AccountPreferenceBase.java +++ b/src/com/android/settings/accounts/AccountPreferenceBase.java @@ -1,4 +1,5 @@ /* + * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,6 +22,7 @@ import com.google.android.collect.Maps; import android.accounts.AuthenticatorDescription; import android.app.Activity; import android.app.ActivityManagerNative; +import android.app.IActivityManager; import android.content.ContentResolver; import android.content.Context; import android.content.SyncAdapterType; @@ -68,9 +70,10 @@ class AccountPreferenceBase extends SettingsPreferenceFragment public void onCreate(Bundle icicle) { super.onCreate(icicle); mUm = (UserManager) getSystemService(Context.USER_SERVICE); - mUserHandle = Utils.getProfileToDisplay(ActivityManagerNative.getDefault(), - getActivity().getActivityToken(), icicle); - mAuthenticatorHelper = new AuthenticatorHelper(getActivity(), mUserHandle, mUm, this); + final Activity activity = getActivity(); + mUserHandle = Utils.getSecureTargetUser(activity.getActivityToken(), mUm, getArguments(), + activity.getIntent().getExtras()); + mAuthenticatorHelper = new AuthenticatorHelper(activity, mUserHandle, mUm, this); } /** @@ -172,8 +175,8 @@ class AccountPreferenceBase extends SettingsPreferenceFragment // correct text colors. Control colors will still be wrong, // but there's not much we can do about it since we can't // reference local color resources. - final Context targetCtx = getActivity().createPackageContext( - desc.packageName, 0); + final Context targetCtx = getActivity().createPackageContextAsUser( + desc.packageName, 0, mUserHandle); final Theme baseTheme = getResources().newTheme(); baseTheme.applyStyle(com.android.settings.R.style.Theme_SettingsBase, true); final Context themedCtx = new ContextThemeWrapper(targetCtx, 0); diff --git a/src/com/android/settings/accounts/AccountSettings.java b/src/com/android/settings/accounts/AccountSettings.java index e60bed9..13878d7 100644 --- a/src/com/android/settings/accounts/AccountSettings.java +++ b/src/com/android/settings/accounts/AccountSettings.java @@ -16,14 +16,13 @@ package com.android.settings.accounts; + import android.accounts.Account; import android.accounts.AccountManager; -import android.accounts.OnAccountsUpdateListener; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.UserInfo; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.UserHandle; @@ -39,13 +38,17 @@ import com.android.settings.SettingsPreferenceFragment; import com.android.settings.Utils; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Comparator; +import static android.content.Intent.EXTRA_USER; + /** * Settings screen for the account types on the device. * This shows all account types available for personal and work profiles. + * + * An extra {@link UserHandle} can be specified in the intent as {@link EXTRA_USER}, if the user for + * which the action needs to be performed is different to the one the Settings App will run in. */ public class AccountSettings extends SettingsPreferenceFragment implements AuthenticatorHelper.OnAccountsUpdateListener, @@ -146,7 +149,7 @@ public class AccountSettings extends SettingsPreferenceFragment } final ProfileData profileData = new ProfileData(); profileData.preferenceGroup = (PreferenceGroup) findPreference(categoryKey); - if (mUm.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) { + if (mUm.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, userHandle)) { removePreference(addAccountKey); } else { profileData.addAccountPreference = findPreference(addAccountKey); @@ -189,7 +192,7 @@ public class AccountSettings extends SettingsPreferenceFragment private void updateAccountTypes(ProfileData profileData) { profileData.preferenceGroup.removeAll(); final ArrayList<AccountPreference> preferences = getAccountTypePreferences( - profileData.authenticatorHelper); + profileData.authenticatorHelper, profileData.userHandle); final int count = preferences.size(); for (int i = 0; i < count; i++) { profileData.preferenceGroup.addPreference(preferences.get(i)); @@ -199,7 +202,8 @@ public class AccountSettings extends SettingsPreferenceFragment } } - private ArrayList<AccountPreference> getAccountTypePreferences(AuthenticatorHelper helper) { + private ArrayList<AccountPreference> getAccountTypePreferences(AuthenticatorHelper helper, + UserHandle userHandle) { final String[] accountTypes = helper.getEnabledAccountTypes(); final ArrayList<AccountPreference> accountTypePreferences = new ArrayList<AccountPreference>(accountTypes.length); @@ -212,7 +216,7 @@ public class AccountSettings extends SettingsPreferenceFragment } final Account[] accounts = AccountManager.get(getActivity()) - .getAccountsByType(accountType); + .getAccountsByTypeAsUser(accountType, userHandle); final boolean skipToAccount = accounts.length == 1 && !helper.hasAccountPreferences(accountType); @@ -220,6 +224,7 @@ public class AccountSettings extends SettingsPreferenceFragment final Bundle fragmentArguments = new Bundle(); fragmentArguments.putParcelable(AccountSyncSettings.ACCOUNT_KEY, accounts[0]); + fragmentArguments.putParcelable(EXTRA_USER, userHandle); accountTypePreferences.add(new AccountPreference(getActivity(), label, AccountSyncSettings.class.getName(), fragmentArguments, @@ -229,6 +234,7 @@ public class AccountSettings extends SettingsPreferenceFragment fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType); fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_LABEL, label.toString()); + fragmentArguments.putParcelable(EXTRA_USER, userHandle); accountTypePreferences.add(new AccountPreference(getActivity(), label, ManageAccountsSettings.class.getName(), fragmentArguments, @@ -254,7 +260,7 @@ public class AccountSettings extends SettingsPreferenceFragment ProfileData profileData = mProfiles.valueAt(i); if (preference == profileData.addAccountPreference) { Intent intent = new Intent(ADD_ACCOUNT_ACTION); - intent.putExtra(Intent.EXTRA_USER_HANDLE, profileData.userHandle); + intent.putExtra(EXTRA_USER, profileData.userHandle); startActivity(intent); return true; } diff --git a/src/com/android/settings/accounts/AccountSyncSettings.java b/src/com/android/settings/accounts/AccountSyncSettings.java index 458adca..1bde8a3 100644 --- a/src/com/android/settings/accounts/AccountSyncSettings.java +++ b/src/com/android/settings/accounts/AccountSyncSettings.java @@ -90,6 +90,8 @@ public class AccountSyncSettings extends AccountPreferenceBase { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + // TODO: We need an API to remove an account from a different user. + // See: http://b/15466880 AccountManager.get(AccountSyncSettings.this.getActivity()) .removeAccount(mAccount, new AccountManagerCallback<Boolean>() { diff --git a/src/com/android/settings/accounts/AddAccountSettings.java b/src/com/android/settings/accounts/AddAccountSettings.java index 34b6c8d..0af0260 100644 --- a/src/com/android/settings/accounts/AddAccountSettings.java +++ b/src/com/android/settings/accounts/AddAccountSettings.java @@ -22,22 +22,25 @@ import android.accounts.AccountManagerFuture; import android.accounts.AuthenticatorException; import android.accounts.OperationCanceledException; import android.app.Activity; +import android.app.ActivityManagerNative; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.os.UserHandle; import android.os.UserManager; import android.util.Log; import android.widget.Toast; import com.android.settings.R; -import com.android.settings.Settings; import com.android.settings.Utils; import java.io.IOException; +import static android.content.Intent.EXTRA_USER; + /** - * Entry point Actiivty for account setup. Works as follows + * Entry point Activity for account setup. Works as follows * * 1) When the other Activities launch this Activity, it launches {@link ChooseAccountActivity} * without showing anything. @@ -50,6 +53,9 @@ import java.io.IOException; * currently delegate the work to the other Activity. When we let this Activity do that work, users * would see the list of account types when leaving this Activity, since the UI is already ready * when returning from each account setup, which doesn't look good. + * + * An extra {@link UserHandle} can be specified in the intent as {@link EXTRA_USER}, if the user for + * which the action needs to be performed is different to the one the Settings App will run in. */ public class AddAccountSettings extends Activity { /** @@ -90,6 +96,7 @@ public class AddAccountSettings extends Activity { addAccountOptions.putParcelable(KEY_CALLER_IDENTITY, mPendingIntent); addAccountOptions.putBoolean(EXTRA_HAS_MULTIPLE_USERS, Utils.hasMultipleUsers(AddAccountSettings.this)); + addAccountOptions.putParcelable(EXTRA_USER, mUserHandle); intent.putExtras(addAccountOptions); startActivityForResult(intent, ADD_ACCOUNT_REQUEST); } else { @@ -116,6 +123,7 @@ public class AddAccountSettings extends Activity { }; private boolean mAddAccountCalled = false; + private UserHandle mUserHandle; @Override public void onCreate(Bundle savedInstanceState) { @@ -127,7 +135,9 @@ public class AddAccountSettings extends Activity { } final UserManager um = (UserManager) getSystemService(Context.USER_SERVICE); - if (um.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) { + mUserHandle = Utils.getSecureTargetUser(getActivityToken(), um, null /* arguments */, + getIntent().getExtras()); + if (um.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, mUserHandle)) { // We aren't allowed to add an account. Toast.makeText(this, R.string.user_cannot_add_accounts_message, Toast.LENGTH_LONG) .show(); @@ -150,6 +160,7 @@ public class AddAccountSettings extends Activity { if (accountTypes != null) { intent.putExtra(AccountPreferenceBase.ACCOUNT_TYPES_FILTER_KEY, accountTypes); } + intent.putExtra(EXTRA_USER, mUserHandle); startActivityForResult(intent, CHOOSE_ACCOUNT_REQUEST); } @@ -188,6 +199,14 @@ public class AddAccountSettings extends Activity { mPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(), 0); addAccountOptions.putParcelable(KEY_CALLER_IDENTITY, mPendingIntent); addAccountOptions.putBoolean(EXTRA_HAS_MULTIPLE_USERS, Utils.hasMultipleUsers(this)); + // TODO: We need an API to add an account to a different user. See: http://b/15466880 + int userId = mUserHandle.getIdentifier(); + int callingUserId = UserHandle.getCallingUserId(); + if (userId != callingUserId) { + Log.w(TAG, "Cannot add an account for user " + userId + " from " + callingUserId + "."); + finish(); + return; + } AccountManager.get(this).addAccount( accountType, null, /* authTokenType */ diff --git a/src/com/android/settings/accounts/ChooseAccountActivity.java b/src/com/android/settings/accounts/ChooseAccountActivity.java index 631fe47..7c0dbdb 100644 --- a/src/com/android/settings/accounts/ChooseAccountActivity.java +++ b/src/com/android/settings/accounts/ChooseAccountActivity.java @@ -18,6 +18,7 @@ package com.android.settings.accounts; import android.accounts.AccountManager; import android.accounts.AuthenticatorDescription; +import android.app.ActivityManagerNative; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; @@ -26,13 +27,18 @@ import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.os.UserHandle; +import android.os.UserManager; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceGroup; import android.preference.PreferenceScreen; import android.util.Log; + import com.android.internal.util.CharSequences; import com.android.settings.R; +import com.android.settings.Utils; + import com.google.android.collect.Maps; import java.util.ArrayList; @@ -41,8 +47,13 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import static android.content.Intent.EXTRA_USER; + /** * Activity asking a user to select an account to be set up. + * + * An extra {@link UserHandle} can be specified in the intent as {@link EXTRA_USER}, if the user for + * which the action needs to be performed is different to the one the Settings App will run in. */ public class ChooseAccountActivity extends PreferenceActivity { @@ -55,7 +66,10 @@ public class ChooseAccountActivity extends PreferenceActivity { private HashMap<String, ArrayList<String>> mAccountTypeToAuthorities = null; private Map<String, AuthenticatorDescription> mTypeToAuthDescription = new HashMap<String, AuthenticatorDescription>(); - + // The UserHandle of the user we are choosing an account for + private UserHandle mUserHandle; + private UserManager mUm; + private static class ProviderEntry implements Comparable<ProviderEntry> { private final CharSequence name; private final String type; @@ -92,6 +106,9 @@ public class ChooseAccountActivity extends PreferenceActivity { } } mAddAccountGroup = getPreferenceScreen(); + mUm = UserManager.get(this); + mUserHandle = Utils.getSecureTargetUser(getActivityToken(), mUm, null /* arguments */, + getIntent().getExtras()); updateAuthDescriptions(); } @@ -100,7 +117,8 @@ public class ChooseAccountActivity extends PreferenceActivity { * and update any UI that depends on AuthenticatorDescriptions in onAuthDescriptionsUpdated(). */ private void updateAuthDescriptions() { - mAuthDescs = AccountManager.get(this).getAuthenticatorTypes(); + mAuthDescs = AccountManager.get(this).getAuthenticatorTypesAsUser( + mUserHandle.getIdentifier()); for (int i = 0; i < mAuthDescs.length; i++) { mTypeToAuthDescription.put(mAuthDescs[i].type, mAuthDescs[i]); } @@ -168,7 +186,8 @@ public class ChooseAccountActivity extends PreferenceActivity { public ArrayList<String> getAuthoritiesForAccountType(String type) { if (mAccountTypeToAuthorities == null) { mAccountTypeToAuthorities = Maps.newHashMap(); - SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypes(); + SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypesAsUser( + mUserHandle.getIdentifier()); for (int i = 0, n = syncAdapters.length; i < n; i++) { final SyncAdapterType sa = syncAdapters[i]; ArrayList<String> authorities = mAccountTypeToAuthorities.get(sa.accountType); @@ -196,8 +215,9 @@ public class ChooseAccountActivity extends PreferenceActivity { if (mTypeToAuthDescription.containsKey(accountType)) { try { AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType); - Context authContext = createPackageContext(desc.packageName, 0); - icon = authContext.getResources().getDrawable(desc.iconId); + Context authContext = createPackageContextAsUser(desc.packageName, 0, mUserHandle); + icon = mUm.getBadgedDrawableForUser( + authContext.getResources().getDrawable(desc.iconId), mUserHandle); } catch (PackageManager.NameNotFoundException e) { // TODO: place holder icon for missing account icons? Log.w(TAG, "No icon name for account type " + accountType); @@ -219,7 +239,7 @@ public class ChooseAccountActivity extends PreferenceActivity { if (mTypeToAuthDescription.containsKey(accountType)) { try { AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType); - Context authContext = createPackageContext(desc.packageName, 0); + Context authContext = createPackageContextAsUser(desc.packageName, 0, mUserHandle); label = authContext.getResources().getText(desc.labelId); } catch (PackageManager.NameNotFoundException e) { Log.w(TAG, "No label name for account type " + accountType); @@ -245,6 +265,7 @@ public class ChooseAccountActivity extends PreferenceActivity { private void finishWithAccountType(String accountType) { Intent intent = new Intent(); intent.putExtra(AddAccountSettings.EXTRA_SELECTED_ACCOUNT, accountType); + intent.putExtra(EXTRA_USER, mUserHandle); setResult(RESULT_OK, intent); finish(); } |