diff options
5 files changed, 67 insertions, 16 deletions
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index 0df2949..6d9bb1d 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -28,6 +28,8 @@ import android.os.Looper; import android.os.RemoteException; import android.os.Parcelable; import android.os.Build; +import android.os.Process; +import android.os.UserHandle; import android.util.Log; import android.text.TextUtils; @@ -42,7 +44,6 @@ import java.util.concurrent.TimeUnit; import java.util.HashMap; import java.util.Map; -import com.google.android.collect.Lists; import com.google.android.collect.Maps; /** @@ -396,8 +397,13 @@ public class AccountManager { * (never null) if no accounts of the specified type have been added. */ public Account[] getAccountsByType(String type) { + return getAccountsByTypeAsUser(type, Process.myUserHandle()); + } + + /** @hide Same as {@link #getAccountsByType(String)} but for a specific user. */ + public Account[] getAccountsByTypeAsUser(String type, UserHandle userHandle) { try { - return mService.getAccounts(type); + return mService.getAccountsAsUser(type, userHandle.getIdentifier()); } catch (RemoteException e) { // won't ever happen throw new RuntimeException(e); @@ -1175,10 +1181,26 @@ public class AccountManager { final Activity activity, final AccountManagerCallback<Bundle> callback, final Handler handler) { + return confirmCredentialsAsUser(account, options, activity, callback, handler, + Process.myUserHandle()); + } + + /** + * @hide + * Same as {@link #confirmCredentials(Account, Bundle, Activity, AccountManagerCallback, Handler)} + * but for the specified user. + */ + public AccountManagerFuture<Bundle> confirmCredentialsAsUser(final Account account, + final Bundle options, + final Activity activity, + final AccountManagerCallback<Bundle> callback, + final Handler handler, UserHandle userHandle) { if (account == null) throw new IllegalArgumentException("account is null"); + final int userId = userHandle.getIdentifier(); return new AmsTask(activity, handler, callback) { public void doWork() throws RemoteException { - mService.confirmCredentials(mResponse, account, options, activity != null); + mService.confirmCredentialsAsUser(mResponse, account, options, activity != null, + userId); } }.start(); } diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java index 03e0c0f..2b1a2b2 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -1297,8 +1297,17 @@ public class AccountManagerService } } - public void confirmCredentials(IAccountManagerResponse response, - final Account account, final Bundle options, final boolean expectActivityLaunch) { + @Override + public void confirmCredentialsAsUser(IAccountManagerResponse response, + final Account account, final Bundle options, final boolean expectActivityLaunch, + int userId) { + // Only allow the system process to read accounts of other users + if (userId != UserHandle.getCallingUserId() + && Binder.getCallingUid() != android.os.Process.myUid()) { + throw new SecurityException("User " + UserHandle.getCallingUserId() + + " trying to confirm account credentials for " + userId); + } + if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "confirmCredentials: " + account + ", response " + response @@ -1309,7 +1318,7 @@ public class AccountManagerService if (response == null) throw new IllegalArgumentException("response is null"); if (account == null) throw new IllegalArgumentException("account is null"); checkManageAccountsPermission(); - UserAccounts accounts = getUserAccountsForCaller(); + UserAccounts accounts = getUserAccounts(userId); long identityToken = clearCallingIdentity(); try { new Session(accounts, response, account.type, expectActivityLaunch, @@ -1548,14 +1557,22 @@ public class AccountManagerService return runningAccounts.toArray(accountsArray); } - public Account[] getAccounts(String type) { + @Override + public Account[] getAccountsAsUser(String type, int userId) { + // Only allow the system process to read accounts of other users + if (userId != UserHandle.getCallingUserId() + && Binder.getCallingUid() != android.os.Process.myUid()) { + throw new SecurityException("User " + UserHandle.getCallingUserId() + + " trying to get account for " + userId); + } + if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "getAccounts: accountType " + type + ", caller's uid " + Binder.getCallingUid() + ", pid " + Binder.getCallingPid()); } checkReadAccountsPermission(); - UserAccounts accounts = getUserAccountsForCaller(); + UserAccounts accounts = getUserAccounts(userId); long identityToken = clearCallingIdentity(); try { synchronized (accounts.cacheLock) { @@ -1566,6 +1583,11 @@ public class AccountManagerService } } + @Override + public Account[] getAccounts(String type) { + return getAccountsAsUser(type, UserHandle.getCallingUserId()); + } + public void getAccountsByFeatures(IAccountManagerResponse response, String type, String[] features) { if (Log.isLoggable(TAG, Log.VERBOSE)) { diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl index 6007321..dbb4924 100644 --- a/core/java/android/accounts/IAccountManager.aidl +++ b/core/java/android/accounts/IAccountManager.aidl @@ -31,6 +31,7 @@ interface IAccountManager { String getUserData(in Account account, String key); AuthenticatorDescription[] getAuthenticatorTypes(); Account[] getAccounts(String accountType); + Account[] getAccountsAsUser(String accountType, int userId); void hasFeatures(in IAccountManagerResponse response, in Account account, in String[] features); void getAccountsByFeatures(in IAccountManagerResponse response, String accountType, in String[] features); boolean addAccount(in Account account, String password, in Bundle extras); @@ -53,8 +54,8 @@ interface IAccountManager { String authTokenType, boolean expectActivityLaunch, in Bundle options); void editProperties(in IAccountManagerResponse response, String accountType, boolean expectActivityLaunch); - void confirmCredentials(in IAccountManagerResponse response, in Account account, - in Bundle options, boolean expectActivityLaunch); + void confirmCredentialsAsUser(in IAccountManagerResponse response, in Account account, + in Bundle options, boolean expectActivityLaunch, int userId); void getAuthTokenLabel(in IAccountManagerResponse response, String accountType, String authTokenType); } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java index 9c87755..c487ddf 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java @@ -27,6 +27,7 @@ import android.content.Context; import android.content.Intent; import android.graphics.Rect; import android.os.Bundle; +import android.os.UserHandle; import android.text.Editable; import android.text.InputFilter; import android.text.LoginFilter; @@ -175,7 +176,8 @@ public class KeyguardAccountView extends LinearLayout implements KeyguardSecurit Intent intent = new Intent(); intent.setClassName(LOCK_PATTERN_PACKAGE, LOCK_PATTERN_CLASS); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mContext.startActivity(intent); + mContext.startActivityAsUser(intent, + new UserHandle(mLockPatternUtils.getCurrentUser())); mCallback.reportSuccessfulUnlockAttempt(); // dismiss keyguard @@ -220,7 +222,8 @@ public class KeyguardAccountView extends LinearLayout implements KeyguardSecurit * find a single best match. */ private Account findIntendedAccount(String username) { - Account[] accounts = AccountManager.get(mContext).getAccountsByType("com.google"); + Account[] accounts = AccountManager.get(mContext).getAccountsByTypeAsUser("com.google", + new UserHandle(mLockPatternUtils.getCurrentUser())); // Try to figure out which account they meant if they // typed only the username (and not the domain), or got @@ -267,7 +270,7 @@ public class KeyguardAccountView extends LinearLayout implements KeyguardSecurit getProgressDialog().show(); Bundle options = new Bundle(); options.putString(AccountManager.KEY_PASSWORD, password); - AccountManager.get(mContext).confirmCredentials(account, options, null /* activity */, + AccountManager.get(mContext).confirmCredentialsAsUser(account, options, null /* activity */, new AccountManagerCallback<Bundle>() { public void run(AccountManagerFuture<Bundle> future) { try { @@ -289,7 +292,7 @@ public class KeyguardAccountView extends LinearLayout implements KeyguardSecurit }); } } - }, null /* handler */); + }, null /* handler */, new UserHandle(mLockPatternUtils.getCurrentUser())); } private Dialog getProgressDialog() { diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java index 82cb44b..52768d2 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java @@ -26,6 +26,7 @@ import android.graphics.Rect; import android.os.Bundle; import android.os.CountDownTimer; import android.os.SystemClock; +import android.os.UserHandle; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; @@ -287,7 +288,8 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit private AccountAnalyzer(AccountManager accountManager) { mAccountManager = accountManager; - mAccounts = accountManager.getAccountsByType("com.google"); + mAccounts = accountManager.getAccountsByTypeAsUser("com.google", + new UserHandle(mLockPatternUtils.getCurrentUser())); } private void next() { @@ -298,7 +300,8 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit } // lookup the confirmCredentials intent for the current account - mAccountManager.confirmCredentials(mAccounts[mAccountIndex], null, null, this, null); + mAccountManager.confirmCredentialsAsUser(mAccounts[mAccountIndex], null, null, this, + null, new UserHandle(mLockPatternUtils.getCurrentUser())); } public void start() { |