am f763b717: Merge "Authenticate correct user\'s account when pattern fails multiple times." into jb-mr1-dev

* commit 'f763b71756d4d810e78e368fbcd56ff8a844f62c':
  Authenticate correct user's account when pattern fails multiple times.
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index f3c6566..bcb35d5 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -28,6 +28,8 @@
 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.HashMap;
 import java.util.Map;
 
-import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 
 /**
@@ -396,8 +397,13 @@
      *     (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 @@
             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 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 @@
         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 @@
         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 @@
         }
     }
 
+    @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 @@
     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 @@
         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 3ce61d9..d552b35 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.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 @@
                     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 @@
      * 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 @@
         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 @@
                     });
                 }
             }
-        }, 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 3a82687..186d717 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
@@ -27,6 +27,7 @@
 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;
@@ -295,7 +296,8 @@
 
         private AccountAnalyzer(AccountManager accountManager) {
             mAccountManager = accountManager;
-            mAccounts = accountManager.getAccountsByType("com.google");
+            mAccounts = accountManager.getAccountsByTypeAsUser("com.google",
+                    new UserHandle(mLockPatternUtils.getCurrentUser()));
         }
 
         private void next() {
@@ -306,7 +308,8 @@
             }
 
             // 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() {