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
This commit is contained in:
Alexandra Gherghina
2014-06-27 12:33:42 +01:00
parent d888b543b2
commit 7d748c0267
7 changed files with 170 additions and 38 deletions

View File

@@ -16,7 +16,11 @@
package com.android.settings; package com.android.settings;
import static android.content.Intent.EXTRA_USER;
import android.annotation.Nullable;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.app.Fragment; import android.app.Fragment;
@@ -61,6 +65,7 @@ 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;
@@ -73,6 +78,7 @@ import java.util.Locale;
public final class Utils { public final class Utils {
private static final String TAG = "Settings"; private static final String TAG = "Settings";
/** /**
* Set the preference's title to the matching activity's label. * Set the preference's title to the matching activity's label.
*/ */
@@ -110,6 +116,8 @@ public final class Utils {
*/ */
private static final String META_DATA_PREFERENCE_SUMMARY = "com.android.settings.summary"; private static final String META_DATA_PREFERENCE_SUMMARY = "com.android.settings.summary";
private static final String SETTINGS_PACKAGE_NAME = "com.android.settings";
/** /**
* Finds a matching activity for a preference's intent. If a matching * Finds a matching activity for a preference's intent. If a matching
* activity is not found, it will remove the preference. * activity is not found, it will remove the preference.
@@ -613,28 +621,100 @@ public final class Utils {
} }
/** /**
* Returns the {@link UserHandle} of the profile that a settings screen should refer to. * Returns the target user for a Settings activity.
* *
* <p> This takes into account the id of the user that triggered the settings screen. * The target user can be either the current user, the user that launched this activity or
* the user contained as an extra in the arguments or intent extras.
*
* Note: This is secure in the sense that it only returns a target user different to the current
* one if the app launching this activity is the Settings app itself, running in the same user
* or in one that is in the same profile group, or if the user id is provided by the system.
*/ */
public static UserHandle getProfileToDisplay(IActivityManager am, IBinder activityToken, public static UserHandle getSecureTargetUser(IBinder activityToken,
Bundle arguments) { UserManager um, @Nullable Bundle arguments, @Nullable Bundle intentExtras) {
int currentUser = UserHandle.getCallingUserId(); UserHandle currentUser = new UserHandle(UserHandle.myUserId());
// Check to see if it was called from a different user IActivityManager am = ActivityManagerNative.getDefault();
try {
String launchedFromPackage = am.getLaunchedFromPackage(activityToken);
boolean launchedFromSettingsApp = SETTINGS_PACKAGE_NAME.equals(launchedFromPackage);
UserHandle launchedFromUser = new UserHandle(UserHandle.getUserId(
am.getLaunchedFromUid(activityToken)));
if (launchedFromUser != null && !launchedFromUser.equals(currentUser)) {
// Check it's secure
if (isProfileOf(um, launchedFromUser)) {
return launchedFromUser;
}
}
UserHandle extrasUser = intentExtras != null
? (UserHandle) intentExtras.getParcelable(EXTRA_USER) : null;
if (extrasUser != null && !extrasUser.equals(currentUser)) {
// Check it's secure
if (launchedFromSettingsApp && isProfileOf(um, extrasUser)) {
return extrasUser;
}
}
UserHandle argumentsUser = arguments != null
? (UserHandle) arguments.getParcelable(EXTRA_USER) : null;
if (argumentsUser != null && !argumentsUser.equals(currentUser)) {
// Check it's secure
if (launchedFromSettingsApp && isProfileOf(um, argumentsUser)) {
return argumentsUser;
}
}
} catch (RemoteException e) {
// Should not happen
Log.v(TAG, "Could not talk to activity manager.", e);
}
return currentUser;
}
/**
* Returns the target user for a Settings activity.
*
* The target user can be either the current user, the user that launched this activity or
* the user contained as an extra in the arguments or intent extras.
*
* You should use {@link #getSecureTargetUser(IBinder, UserManager, Bundle, Bundle)} if
* possible.
*
* @see #getInsecureTargetUser(IBinder, Bundle, Bundle)
*/
public static UserHandle getInsecureTargetUser(IBinder activityToken, @Nullable Bundle arguments,
@Nullable Bundle intentExtras) {
UserHandle currentUser = new UserHandle(UserHandle.myUserId());
IActivityManager am = ActivityManagerNative.getDefault();
try { try {
int launchedFromUser = UserHandle.getUserId(am.getLaunchedFromUid(activityToken)); UserHandle launchedFromUser = new UserHandle(UserHandle.getUserId(
if (launchedFromUser != currentUser) { am.getLaunchedFromUid(activityToken)));
// This is a forwarded intent if (launchedFromUser != null && !launchedFromUser.equals(currentUser)) {
return new UserHandle(launchedFromUser); return launchedFromUser;
}
UserHandle extrasUser = intentExtras != null
? (UserHandle) intentExtras.getParcelable(EXTRA_USER) : null;
if (extrasUser != null && !extrasUser.equals(currentUser)) {
return extrasUser;
}
UserHandle argumentsUser = arguments != null
? (UserHandle) arguments.getParcelable(EXTRA_USER) : null;
if (argumentsUser != null && !argumentsUser.equals(currentUser)) {
return argumentsUser;
} }
} catch (RemoteException e) { } catch (RemoteException e) {
// Should not happen // Should not happen
Log.v(TAG, "Could not get launching user."); Log.v(TAG, "Could not talk to activity manager.", e);
return null;
} }
// TODO: Check fragment arguments. See: http://b/15466880 return currentUser;
}
// Default to current profile /**
return new UserHandle(currentUser); * Returns true if the user provided is in the same profiles group as the current user.
*/
private static boolean isProfileOf(UserManager um, UserHandle otherUser) {
if (um == null || otherUser == null) return false;
return (UserHandle.myUserId() == otherUser.getIdentifier())
|| um.getUserProfiles().contains(otherUser);
} }
/** /**

View File

@@ -1,4 +1,5 @@
/* /*
* Copyright (C) 2008 The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * 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.accounts.AuthenticatorDescription;
import android.app.Activity; import android.app.Activity;
import android.app.ActivityManagerNative; import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.SyncAdapterType; import android.content.SyncAdapterType;
@@ -68,9 +70,10 @@ class AccountPreferenceBase extends SettingsPreferenceFragment
public void onCreate(Bundle icicle) { public void onCreate(Bundle icicle) {
super.onCreate(icicle); super.onCreate(icicle);
mUm = (UserManager) getSystemService(Context.USER_SERVICE); mUm = (UserManager) getSystemService(Context.USER_SERVICE);
mUserHandle = Utils.getProfileToDisplay(ActivityManagerNative.getDefault(), final Activity activity = getActivity();
getActivity().getActivityToken(), icicle); mUserHandle = Utils.getSecureTargetUser(activity.getActivityToken(), mUm, getArguments(),
mAuthenticatorHelper = new AuthenticatorHelper(getActivity(), mUserHandle, mUm, this); 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, // correct text colors. Control colors will still be wrong,
// but there's not much we can do about it since we can't // but there's not much we can do about it since we can't
// reference local color resources. // reference local color resources.
final Context targetCtx = getActivity().createPackageContext( final Context targetCtx = getActivity().createPackageContextAsUser(
desc.packageName, 0); desc.packageName, 0, mUserHandle);
final Theme baseTheme = getResources().newTheme(); final Theme baseTheme = getResources().newTheme();
baseTheme.applyStyle(com.android.settings.R.style.Theme_SettingsBase, true); baseTheme.applyStyle(com.android.settings.R.style.Theme_SettingsBase, true);
final Context themedCtx = new ContextThemeWrapper(targetCtx, 0); final Context themedCtx = new ContextThemeWrapper(targetCtx, 0);

View File

@@ -16,14 +16,13 @@
package com.android.settings.accounts; 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.content.BroadcastReceiver; 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.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.UserHandle;
@@ -39,13 +38,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 static android.content.Intent.EXTRA_USER;
/** /**
* 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.
*
* 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 public class AccountSettings extends SettingsPreferenceFragment
implements AuthenticatorHelper.OnAccountsUpdateListener, implements AuthenticatorHelper.OnAccountsUpdateListener,
@@ -146,7 +149,7 @@ public class AccountSettings extends SettingsPreferenceFragment
} }
final ProfileData profileData = new ProfileData(); final ProfileData profileData = new ProfileData();
profileData.preferenceGroup = (PreferenceGroup) findPreference(categoryKey); profileData.preferenceGroup = (PreferenceGroup) findPreference(categoryKey);
if (mUm.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) { if (mUm.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, userHandle)) {
removePreference(addAccountKey); removePreference(addAccountKey);
} else { } else {
profileData.addAccountPreference = findPreference(addAccountKey); profileData.addAccountPreference = findPreference(addAccountKey);
@@ -189,7 +192,7 @@ public class AccountSettings extends SettingsPreferenceFragment
private void updateAccountTypes(ProfileData profileData) { private void updateAccountTypes(ProfileData profileData) {
profileData.preferenceGroup.removeAll(); profileData.preferenceGroup.removeAll();
final ArrayList<AccountPreference> preferences = getAccountTypePreferences( final ArrayList<AccountPreference> preferences = getAccountTypePreferences(
profileData.authenticatorHelper); profileData.authenticatorHelper, profileData.userHandle);
final int count = preferences.size(); final int count = preferences.size();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
profileData.preferenceGroup.addPreference(preferences.get(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 String[] accountTypes = helper.getEnabledAccountTypes();
final ArrayList<AccountPreference> accountTypePreferences = final ArrayList<AccountPreference> accountTypePreferences =
new ArrayList<AccountPreference>(accountTypes.length); new ArrayList<AccountPreference>(accountTypes.length);
@@ -212,7 +216,7 @@ public class AccountSettings extends SettingsPreferenceFragment
} }
final Account[] accounts = AccountManager.get(getActivity()) final Account[] accounts = AccountManager.get(getActivity())
.getAccountsByType(accountType); .getAccountsByTypeAsUser(accountType, userHandle);
final boolean skipToAccount = accounts.length == 1 final boolean skipToAccount = accounts.length == 1
&& !helper.hasAccountPreferences(accountType); && !helper.hasAccountPreferences(accountType);
@@ -220,6 +224,7 @@ public class AccountSettings extends SettingsPreferenceFragment
final Bundle fragmentArguments = new Bundle(); final Bundle fragmentArguments = new Bundle();
fragmentArguments.putParcelable(AccountSyncSettings.ACCOUNT_KEY, fragmentArguments.putParcelable(AccountSyncSettings.ACCOUNT_KEY,
accounts[0]); accounts[0]);
fragmentArguments.putParcelable(EXTRA_USER, userHandle);
accountTypePreferences.add(new AccountPreference(getActivity(), label, accountTypePreferences.add(new AccountPreference(getActivity(), label,
AccountSyncSettings.class.getName(), fragmentArguments, 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_TYPE, accountType);
fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_LABEL, fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_LABEL,
label.toString()); label.toString());
fragmentArguments.putParcelable(EXTRA_USER, userHandle);
accountTypePreferences.add(new AccountPreference(getActivity(), label, accountTypePreferences.add(new AccountPreference(getActivity(), label,
ManageAccountsSettings.class.getName(), fragmentArguments, ManageAccountsSettings.class.getName(), fragmentArguments,
@@ -254,7 +260,7 @@ public class AccountSettings extends SettingsPreferenceFragment
ProfileData profileData = mProfiles.valueAt(i); ProfileData profileData = mProfiles.valueAt(i);
if (preference == profileData.addAccountPreference) { if (preference == profileData.addAccountPreference) {
Intent intent = new Intent(ADD_ACCOUNT_ACTION); Intent intent = new Intent(ADD_ACCOUNT_ACTION);
intent.putExtra(Intent.EXTRA_USER_HANDLE, profileData.userHandle); intent.putExtra(EXTRA_USER, profileData.userHandle);
startActivity(intent); startActivity(intent);
return true; return true;
} }

View File

@@ -90,6 +90,8 @@ public class AccountSyncSettings extends AccountPreferenceBase {
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { 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()) AccountManager.get(AccountSyncSettings.this.getActivity())
.removeAccount(mAccount, .removeAccount(mAccount,
new AccountManagerCallback<Boolean>() { new AccountManagerCallback<Boolean>() {

View File

@@ -22,22 +22,25 @@ 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.Activity;
import android.app.ActivityManagerNative;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
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.Log;
import android.widget.Toast; import android.widget.Toast;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Settings;
import com.android.settings.Utils; import com.android.settings.Utils;
import java.io.IOException; 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} * 1) When the other Activities launch this Activity, it launches {@link ChooseAccountActivity}
* without showing anything. * 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 * 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 * 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. * 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 { public class AddAccountSettings extends Activity {
/** /**
@@ -90,6 +96,7 @@ public class AddAccountSettings extends Activity {
addAccountOptions.putParcelable(KEY_CALLER_IDENTITY, mPendingIntent); addAccountOptions.putParcelable(KEY_CALLER_IDENTITY, mPendingIntent);
addAccountOptions.putBoolean(EXTRA_HAS_MULTIPLE_USERS, addAccountOptions.putBoolean(EXTRA_HAS_MULTIPLE_USERS,
Utils.hasMultipleUsers(AddAccountSettings.this)); Utils.hasMultipleUsers(AddAccountSettings.this));
addAccountOptions.putParcelable(EXTRA_USER, mUserHandle);
intent.putExtras(addAccountOptions); intent.putExtras(addAccountOptions);
startActivityForResult(intent, ADD_ACCOUNT_REQUEST); startActivityForResult(intent, ADD_ACCOUNT_REQUEST);
} else { } else {
@@ -116,6 +123,7 @@ public class AddAccountSettings extends Activity {
}; };
private boolean mAddAccountCalled = false; private boolean mAddAccountCalled = false;
private UserHandle mUserHandle;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@@ -127,7 +135,9 @@ public class AddAccountSettings extends Activity {
} }
final UserManager um = (UserManager) getSystemService(Context.USER_SERVICE); 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. // We aren't allowed to add an account.
Toast.makeText(this, R.string.user_cannot_add_accounts_message, Toast.LENGTH_LONG) Toast.makeText(this, R.string.user_cannot_add_accounts_message, Toast.LENGTH_LONG)
.show(); .show();
@@ -150,6 +160,7 @@ public class AddAccountSettings extends Activity {
if (accountTypes != null) { if (accountTypes != null) {
intent.putExtra(AccountPreferenceBase.ACCOUNT_TYPES_FILTER_KEY, accountTypes); intent.putExtra(AccountPreferenceBase.ACCOUNT_TYPES_FILTER_KEY, accountTypes);
} }
intent.putExtra(EXTRA_USER, mUserHandle);
startActivityForResult(intent, CHOOSE_ACCOUNT_REQUEST); startActivityForResult(intent, CHOOSE_ACCOUNT_REQUEST);
} }
@@ -188,6 +199,14 @@ public class AddAccountSettings extends Activity {
mPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(), 0); mPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(), 0);
addAccountOptions.putParcelable(KEY_CALLER_IDENTITY, mPendingIntent); addAccountOptions.putParcelable(KEY_CALLER_IDENTITY, mPendingIntent);
addAccountOptions.putBoolean(EXTRA_HAS_MULTIPLE_USERS, Utils.hasMultipleUsers(this)); 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( AccountManager.get(this).addAccount(
accountType, accountType,
null, /* authTokenType */ null, /* authTokenType */

View File

@@ -18,6 +18,7 @@ package com.android.settings.accounts;
import android.accounts.AccountManager; import android.accounts.AccountManager;
import android.accounts.AuthenticatorDescription; import android.accounts.AuthenticatorDescription;
import android.app.ActivityManagerNative;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@@ -26,13 +27,18 @@ 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.Bundle; import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceActivity; import android.preference.PreferenceActivity;
import android.preference.PreferenceGroup; import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen; import android.preference.PreferenceScreen;
import android.util.Log; import android.util.Log;
import com.android.internal.util.CharSequences; import com.android.internal.util.CharSequences;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils;
import com.google.android.collect.Maps; import com.google.android.collect.Maps;
import java.util.ArrayList; import java.util.ArrayList;
@@ -41,8 +47,13 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import static android.content.Intent.EXTRA_USER;
/** /**
* Activity asking a user to select an account to be set up. * 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 { public class ChooseAccountActivity extends PreferenceActivity {
@@ -55,6 +66,9 @@ public class ChooseAccountActivity extends PreferenceActivity {
private HashMap<String, ArrayList<String>> mAccountTypeToAuthorities = null; private HashMap<String, ArrayList<String>> mAccountTypeToAuthorities = null;
private Map<String, AuthenticatorDescription> mTypeToAuthDescription private Map<String, AuthenticatorDescription> mTypeToAuthDescription
= new HashMap<String, AuthenticatorDescription>(); = 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 static class ProviderEntry implements Comparable<ProviderEntry> {
private final CharSequence name; private final CharSequence name;
@@ -92,6 +106,9 @@ public class ChooseAccountActivity extends PreferenceActivity {
} }
} }
mAddAccountGroup = getPreferenceScreen(); mAddAccountGroup = getPreferenceScreen();
mUm = UserManager.get(this);
mUserHandle = Utils.getSecureTargetUser(getActivityToken(), mUm, null /* arguments */,
getIntent().getExtras());
updateAuthDescriptions(); updateAuthDescriptions();
} }
@@ -100,7 +117,8 @@ public class ChooseAccountActivity extends PreferenceActivity {
* and update any UI that depends on AuthenticatorDescriptions in onAuthDescriptionsUpdated(). * and update any UI that depends on AuthenticatorDescriptions in onAuthDescriptionsUpdated().
*/ */
private void updateAuthDescriptions() { private void updateAuthDescriptions() {
mAuthDescs = AccountManager.get(this).getAuthenticatorTypes(); mAuthDescs = AccountManager.get(this).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]);
} }
@@ -168,7 +186,8 @@ public class ChooseAccountActivity extends PreferenceActivity {
public ArrayList<String> getAuthoritiesForAccountType(String type) { public ArrayList<String> getAuthoritiesForAccountType(String type) {
if (mAccountTypeToAuthorities == null) { if (mAccountTypeToAuthorities == null) {
mAccountTypeToAuthorities = Maps.newHashMap(); mAccountTypeToAuthorities = Maps.newHashMap();
SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypes(); SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypesAsUser(
mUserHandle.getIdentifier());
for (int i = 0, n = syncAdapters.length; i < n; i++) { for (int i = 0, n = syncAdapters.length; i < n; i++) {
final SyncAdapterType sa = syncAdapters[i]; final SyncAdapterType sa = syncAdapters[i];
ArrayList<String> authorities = mAccountTypeToAuthorities.get(sa.accountType); ArrayList<String> authorities = mAccountTypeToAuthorities.get(sa.accountType);
@@ -196,8 +215,9 @@ public class ChooseAccountActivity extends PreferenceActivity {
if (mTypeToAuthDescription.containsKey(accountType)) { if (mTypeToAuthDescription.containsKey(accountType)) {
try { try {
AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType); AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
Context authContext = createPackageContext(desc.packageName, 0); Context authContext = createPackageContextAsUser(desc.packageName, 0, mUserHandle);
icon = authContext.getResources().getDrawable(desc.iconId); icon = mUm.getBadgedDrawableForUser(
authContext.getResources().getDrawable(desc.iconId), mUserHandle);
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
// TODO: place holder icon for missing account icons? // TODO: place holder icon for missing account icons?
Log.w(TAG, "No icon name for account type " + accountType); Log.w(TAG, "No icon name for account type " + accountType);
@@ -219,7 +239,7 @@ public class ChooseAccountActivity extends PreferenceActivity {
if (mTypeToAuthDescription.containsKey(accountType)) { if (mTypeToAuthDescription.containsKey(accountType)) {
try { try {
AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType); AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
Context authContext = createPackageContext(desc.packageName, 0); Context authContext = createPackageContextAsUser(desc.packageName, 0, mUserHandle);
label = authContext.getResources().getText(desc.labelId); label = authContext.getResources().getText(desc.labelId);
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "No label name for account type " + accountType); Log.w(TAG, "No label name for account type " + accountType);
@@ -245,6 +265,7 @@ public class ChooseAccountActivity extends PreferenceActivity {
private void finishWithAccountType(String accountType) { private void finishWithAccountType(String accountType) {
Intent intent = new Intent(); Intent intent = new Intent();
intent.putExtra(AddAccountSettings.EXTRA_SELECTED_ACCOUNT, accountType); intent.putExtra(AddAccountSettings.EXTRA_SELECTED_ACCOUNT, accountType);
intent.putExtra(EXTRA_USER, mUserHandle);
setResult(RESULT_OK, intent); setResult(RESULT_OK, intent);
finish(); finish();
} }

View File

@@ -54,8 +54,9 @@ public class MessageAccessSettings extends SettingsPreferenceFragment
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mUserHandle = Utils.getProfileToDisplay(ActivityManagerNative.getDefault(),
getActivity().getActivityToken(), savedInstanceState); // TODO: Define behavior for managed profile. See: http://b/16287773
mUserHandle = new UserHandle(UserHandle.myUserId());
addPreferencesFromResource(R.xml.bluetooth_message_access); addPreferencesFromResource(R.xml.bluetooth_message_access);
} }