Loading api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -2903,6 +2903,7 @@ package android.accounts { method public android.accounts.AccountManagerFuture<android.os.Bundle> confirmCredentials(android.accounts.Account, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler); method public android.accounts.AccountManagerFuture<android.os.Bundle> editProperties(java.lang.String, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler); method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler); method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSessionAsUser(android.os.Bundle, android.app.Activity, android.os.UserHandle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler); method public static android.accounts.AccountManager get(android.content.Context); method public android.accounts.Account[] getAccounts(); method public android.accounts.Account[] getAccountsByType(java.lang.String); core/java/android/accounts/AccountManager.java +66 −5 Original line number Diff line number Diff line Loading @@ -592,6 +592,7 @@ public class AccountManager { if (accountType == null) throw new IllegalArgumentException("accountType is null"); if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); return new Future2Task<String>(handler, callback) { @Override public void doWork() throws RemoteException { mService.getAuthTokenLabel(mResponse, accountType, authTokenType); } Loading Loading @@ -637,9 +638,11 @@ public class AccountManager { if (account == null) throw new IllegalArgumentException("account is null"); if (features == null) throw new IllegalArgumentException("features is null"); return new Future2Task<Boolean>(handler, callback) { @Override public void doWork() throws RemoteException { mService.hasFeatures(mResponse, account, features, mContext.getOpPackageName()); } @Override public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException { if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) { throw new AuthenticatorException("no result in response"); Loading Loading @@ -689,10 +692,12 @@ public class AccountManager { AccountManagerCallback<Account[]> callback, Handler handler) { if (type == null) throw new IllegalArgumentException("type is null"); return new Future2Task<Account[]>(handler, callback) { @Override public void doWork() throws RemoteException { mService.getAccountsByFeatures(mResponse, type, features, mContext.getOpPackageName()); } @Override public Account[] bundleToResult(Bundle bundle) throws AuthenticatorException { if (!bundle.containsKey(KEY_ACCOUNTS)) { throw new AuthenticatorException("no result in response"); Loading Loading @@ -971,6 +976,7 @@ public class AccountManager { if (userHandle == null) throw new IllegalArgumentException("userHandle is null"); return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { mService.removeAccountAsUser(mResponse, account, activity != null, userHandle.getIdentifier()); Loading Loading @@ -1295,6 +1301,7 @@ public class AccountManager { } optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName()); return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { mService.getAuthToken(mResponse, account, authTokenType, false /* notifyOnAuthFailure */, true /* expectActivityLaunch */, Loading Loading @@ -1463,6 +1470,7 @@ public class AccountManager { } optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName()); return new AmsTask(null, handler, callback) { @Override public void doWork() throws RemoteException { mService.getAuthToken(mResponse, account, authTokenType, notifyAuthFailure, false /* expectActivityLaunch */, optionsIn); Loading Loading @@ -1532,6 +1540,7 @@ public class AccountManager { optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName()); return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { mService.addAccount(mResponse, accountType, authTokenType, requiredFeatures, activity != null, optionsIn); Loading @@ -1556,6 +1565,7 @@ public class AccountManager { optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName()); return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { mService.addAccountAsUser(mResponse, accountType, authTokenType, requiredFeatures, activity != null, optionsIn, userHandle.getIdentifier()); Loading Loading @@ -1732,6 +1742,7 @@ public class AccountManager { if (account == null) throw new IllegalArgumentException("account is null"); final int userId = userHandle.getIdentifier(); return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { mService.confirmCredentialsAsUser(mResponse, account, options, activity != null, userId); Loading Loading @@ -1794,6 +1805,7 @@ public class AccountManager { final Handler handler) { if (account == null) throw new IllegalArgumentException("account is null"); return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { mService.updateCredentials(mResponse, account, authTokenType, activity != null, options); Loading Loading @@ -1847,6 +1859,7 @@ public class AccountManager { final Handler handler) { if (accountType == null) throw new IllegalArgumentException("accountType is null"); return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { mService.editProperties(mResponse, accountType, activity != null); } Loading Loading @@ -1886,6 +1899,7 @@ public class AccountManager { final AccountManagerFuture<Bundle> future) { handler = handler == null ? mMainHandler : handler; handler.post(new Runnable() { @Override public void run() { callback.run(future); } Loading @@ -1900,6 +1914,7 @@ public class AccountManager { System.arraycopy(accounts, 0, accountsCopy, 0, accountsCopy.length); handler = (handler == null) ? mMainHandler : handler; handler.post(new Runnable() { @Override public void run() { try { listener.onAccountsUpdated(accountsCopy); Loading @@ -1919,6 +1934,7 @@ public class AccountManager { final Activity mActivity; public AmsTask(Activity activity, Handler handler, AccountManagerCallback<Bundle> callback) { super(new Callable<Bundle>() { @Override public Bundle call() throws Exception { throw new IllegalStateException("this should never be called"); } Loading @@ -1939,6 +1955,7 @@ public class AccountManager { return this; } @Override protected void set(Bundle bundle) { // TODO: somehow a null is being set as the result of the Future. Log this // case to help debug where this is occurring. When this bug is fixed this Loading Loading @@ -1989,16 +2006,19 @@ public class AccountManager { throw new OperationCanceledException(); } @Override public Bundle getResult() throws OperationCanceledException, IOException, AuthenticatorException { return internalGetResult(null, null); } @Override public Bundle getResult(long timeout, TimeUnit unit) throws OperationCanceledException, IOException, AuthenticatorException { return internalGetResult(timeout, unit); } @Override protected void done() { if (mCallback != null) { postToHandler(mHandler, mCallback, this); Loading @@ -2007,6 +2027,7 @@ public class AccountManager { /** Handles the responses from the AccountManager */ private class Response extends IAccountManagerResponse.Stub { @Override public void onResult(Bundle bundle) { Intent intent = bundle.getParcelable(KEY_INTENT); if (intent != null && mActivity != null) { Loading @@ -2026,6 +2047,7 @@ public class AccountManager { } } @Override public void onError(int code, String message) { if (code == ERROR_CODE_CANCELED || code == ERROR_CODE_USER_RESTRICTED || code == ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE) { Loading @@ -2046,6 +2068,7 @@ public class AccountManager { public BaseFutureTask(Handler handler) { super(new Callable<T>() { @Override public T call() throws Exception { throw new IllegalStateException("this should never be called"); } Loading @@ -2072,6 +2095,7 @@ public class AccountManager { } protected class Response extends IAccountManagerResponse.Stub { @Override public void onResult(Bundle bundle) { try { T result = bundleToResult(bundle); Loading @@ -2088,6 +2112,7 @@ public class AccountManager { onError(ERROR_CODE_INVALID_RESPONSE, "no result in response"); } @Override public void onError(int code, String message) { if (code == ERROR_CODE_CANCELED || code == ERROR_CODE_USER_RESTRICTED || code == ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE) { Loading @@ -2109,9 +2134,11 @@ public class AccountManager { mCallback = callback; } @Override protected void done() { if (mCallback != null) { postRunnableToHandler(new Runnable() { @Override public void run() { mCallback.run(Future2Task.this); } Loading Loading @@ -2162,11 +2189,13 @@ public class AccountManager { throw new OperationCanceledException(); } @Override public T getResult() throws OperationCanceledException, IOException, AuthenticatorException { return internalGetResult(null, null); } @Override public T getResult(long timeout, TimeUnit unit) throws OperationCanceledException, IOException, AuthenticatorException { return internalGetResult(timeout, unit); Loading Loading @@ -2218,9 +2247,11 @@ public class AccountManager { final AccountManagerCallback<Bundle> mMyCallback; private volatile int mNumAccounts = 0; @Override public void doWork() throws RemoteException { getAccountsByTypeAndFeatures(mAccountType, mFeatures, new AccountManagerCallback<Account[]>() { @Override public void run(AccountManagerFuture<Account[]> future) { Account[] accounts; try { Loading Loading @@ -2271,6 +2302,7 @@ public class AccountManager { if (mActivity != null) { IAccountManagerResponse chooseResponse = new IAccountManagerResponse.Stub() { @Override public void onResult(Bundle value) throws RemoteException { Account account = new Account( value.getString(KEY_ACCOUNT_NAME), Loading @@ -2279,6 +2311,7 @@ public class AccountManager { mActivity, mMyCallback, mHandler); } @Override public void onError(int errorCode, String errorMessage) throws RemoteException { mResponse.onError(errorCode, errorMessage); Loading Loading @@ -2311,6 +2344,7 @@ public class AccountManager { }}, mHandler); } @Override public void run(AccountManagerFuture<Bundle> future) { try { final Bundle result = future.getResult(); Loading Loading @@ -2531,6 +2565,7 @@ public class AccountManager { * in mAccountsUpdatedListeners. */ private final BroadcastReceiver mAccountsChangedBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(final Context context, final Intent intent) { final Account[] accounts = getAccounts(); // send the result to the listeners Loading Loading @@ -2851,6 +2886,25 @@ public class AccountManager { final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) { return finishSessionAsUser( sessionBundle, activity, Process.myUserHandle(), callback, handler); } /** * @see #finishSession * @hide */ @SystemApi public AccountManagerFuture<Bundle> finishSessionAsUser( final Bundle sessionBundle, final Activity activity, final UserHandle userHandle, AccountManagerCallback<Bundle> callback, Handler handler) { if (sessionBundle == null) { throw new IllegalArgumentException("sessionBundle is null"); } Loading @@ -2862,7 +2916,12 @@ public class AccountManager { return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { mService.finishSession(mResponse, sessionBundle, activity != null, appInfo); mService.finishSessionAsUser( mResponse, sessionBundle, activity != null, appInfo, userHandle.getIdentifier()); } }.start(); } Loading Loading @@ -2898,12 +2957,14 @@ public class AccountManager { } return new Future2Task<Boolean>(handler, callback) { @Override public void doWork() throws RemoteException { mService.isCredentialsUpdateSuggested( mResponse, account, statusToken); } @Override public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException { if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) { throw new AuthenticatorException("no result in response"); Loading core/java/android/accounts/IAccountManager.aidl +3 −3 Original line number Diff line number Diff line Loading @@ -92,9 +92,9 @@ interface IAccountManager { void startUpdateCredentialsSession(in IAccountManagerResponse response, in Account account, String authTokenType, boolean expectActivityLaunch, in Bundle options); /* Finish session started by startAddAccountSession(...) or startUpdateCredentialsSession(...) */ void finishSession(in IAccountManagerResponse response, in Bundle sessionBundle, boolean expectActivityLaunch, in Bundle appInfo); /* Finish session started by startAddAccountSession(...) or startUpdateCredentialsSession(...) for user */ void finishSessionAsUser(in IAccountManagerResponse response, in Bundle sessionBundle, boolean expectActivityLaunch, in Bundle appInfo, int userId); /* Check if an account exists on any user on the device. */ boolean someUserHasAccount(in Account account); Loading services/core/java/com/android/server/accounts/AccountManagerService.java +25 −14 Original line number Diff line number Diff line Loading @@ -2486,16 +2486,20 @@ public class AccountManagerService } @Override public void finishSession(IAccountManagerResponse response, public void finishSessionAsUser(IAccountManagerResponse response, @NonNull Bundle sessionBundle, boolean expectActivityLaunch, Bundle appInfo) { Bundle appInfo, int userId) { int callingUid = Binder.getCallingUid(); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "finishSession: response "+ response + ", expectActivityLaunch " + expectActivityLaunch + ", caller's uid " + Binder.getCallingUid() + ", pid " + Binder.getCallingPid()); + ", caller's uid " + callingUid + ", caller's user id " + UserHandle.getCallingUserId() + ", pid " + Binder.getCallingPid() + ", for user id " + userId); } if (response == null) { throw new IllegalArgumentException("response is null"); Loading @@ -2507,17 +2511,24 @@ public class AccountManagerService throw new IllegalArgumentException("sessionBundle is empty"); } final int uid = Binder.getCallingUid(); // Only allow the system process to finish session for other users if (isCrossUser(callingUid, userId)) { throw new SecurityException( String.format( "User %s trying to finish session for %s without cross user permission", UserHandle.getCallingUserId(), userId)); } // Only allow system to finish session if (!isSystemUid(uid)) { if (!isSystemUid(callingUid)) { String msg = String.format( "uid %s cannot finish session.", uid); "uid %s cannot finish session because it's not system uid.", callingUid); throw new SecurityException(msg); } final int userId = UserHandle.getUserId(uid); if (!canUserModifyAccounts(userId, uid)) { if (!canUserModifyAccounts(userId, callingUid)) { sendErrorResponse(response, AccountManager.ERROR_CODE_USER_RESTRICTED, "User is not allowed to add an account!"); Loading Loading @@ -2559,7 +2570,7 @@ public class AccountManagerService } // Add info that may be used by add account or update credentials flow. decryptedBundle.putInt(AccountManager.KEY_CALLER_UID, uid); decryptedBundle.putInt(AccountManager.KEY_CALLER_UID, callingUid); decryptedBundle.putInt(AccountManager.KEY_CALLER_PID, pid); } catch (GeneralSecurityException e) { if (Log.isLoggable(TAG, Log.DEBUG)) { Loading @@ -2572,7 +2583,7 @@ public class AccountManagerService return; } if (!canUserModifyAccountsForType(userId, accountType, uid)) { if (!canUserModifyAccountsForType(userId, accountType, callingUid)) { sendErrorResponse( response, AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE, Loading @@ -2589,7 +2600,7 @@ public class AccountManagerService accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_SESSION_FINISH, TABLE_ACCOUNTS, uid); callingUid); new Session( accounts, response, Loading Loading
api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -2903,6 +2903,7 @@ package android.accounts { method public android.accounts.AccountManagerFuture<android.os.Bundle> confirmCredentials(android.accounts.Account, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler); method public android.accounts.AccountManagerFuture<android.os.Bundle> editProperties(java.lang.String, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler); method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler); method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSessionAsUser(android.os.Bundle, android.app.Activity, android.os.UserHandle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler); method public static android.accounts.AccountManager get(android.content.Context); method public android.accounts.Account[] getAccounts(); method public android.accounts.Account[] getAccountsByType(java.lang.String);
core/java/android/accounts/AccountManager.java +66 −5 Original line number Diff line number Diff line Loading @@ -592,6 +592,7 @@ public class AccountManager { if (accountType == null) throw new IllegalArgumentException("accountType is null"); if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); return new Future2Task<String>(handler, callback) { @Override public void doWork() throws RemoteException { mService.getAuthTokenLabel(mResponse, accountType, authTokenType); } Loading Loading @@ -637,9 +638,11 @@ public class AccountManager { if (account == null) throw new IllegalArgumentException("account is null"); if (features == null) throw new IllegalArgumentException("features is null"); return new Future2Task<Boolean>(handler, callback) { @Override public void doWork() throws RemoteException { mService.hasFeatures(mResponse, account, features, mContext.getOpPackageName()); } @Override public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException { if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) { throw new AuthenticatorException("no result in response"); Loading Loading @@ -689,10 +692,12 @@ public class AccountManager { AccountManagerCallback<Account[]> callback, Handler handler) { if (type == null) throw new IllegalArgumentException("type is null"); return new Future2Task<Account[]>(handler, callback) { @Override public void doWork() throws RemoteException { mService.getAccountsByFeatures(mResponse, type, features, mContext.getOpPackageName()); } @Override public Account[] bundleToResult(Bundle bundle) throws AuthenticatorException { if (!bundle.containsKey(KEY_ACCOUNTS)) { throw new AuthenticatorException("no result in response"); Loading Loading @@ -971,6 +976,7 @@ public class AccountManager { if (userHandle == null) throw new IllegalArgumentException("userHandle is null"); return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { mService.removeAccountAsUser(mResponse, account, activity != null, userHandle.getIdentifier()); Loading Loading @@ -1295,6 +1301,7 @@ public class AccountManager { } optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName()); return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { mService.getAuthToken(mResponse, account, authTokenType, false /* notifyOnAuthFailure */, true /* expectActivityLaunch */, Loading Loading @@ -1463,6 +1470,7 @@ public class AccountManager { } optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName()); return new AmsTask(null, handler, callback) { @Override public void doWork() throws RemoteException { mService.getAuthToken(mResponse, account, authTokenType, notifyAuthFailure, false /* expectActivityLaunch */, optionsIn); Loading Loading @@ -1532,6 +1540,7 @@ public class AccountManager { optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName()); return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { mService.addAccount(mResponse, accountType, authTokenType, requiredFeatures, activity != null, optionsIn); Loading @@ -1556,6 +1565,7 @@ public class AccountManager { optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName()); return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { mService.addAccountAsUser(mResponse, accountType, authTokenType, requiredFeatures, activity != null, optionsIn, userHandle.getIdentifier()); Loading Loading @@ -1732,6 +1742,7 @@ public class AccountManager { if (account == null) throw new IllegalArgumentException("account is null"); final int userId = userHandle.getIdentifier(); return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { mService.confirmCredentialsAsUser(mResponse, account, options, activity != null, userId); Loading Loading @@ -1794,6 +1805,7 @@ public class AccountManager { final Handler handler) { if (account == null) throw new IllegalArgumentException("account is null"); return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { mService.updateCredentials(mResponse, account, authTokenType, activity != null, options); Loading Loading @@ -1847,6 +1859,7 @@ public class AccountManager { final Handler handler) { if (accountType == null) throw new IllegalArgumentException("accountType is null"); return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { mService.editProperties(mResponse, accountType, activity != null); } Loading Loading @@ -1886,6 +1899,7 @@ public class AccountManager { final AccountManagerFuture<Bundle> future) { handler = handler == null ? mMainHandler : handler; handler.post(new Runnable() { @Override public void run() { callback.run(future); } Loading @@ -1900,6 +1914,7 @@ public class AccountManager { System.arraycopy(accounts, 0, accountsCopy, 0, accountsCopy.length); handler = (handler == null) ? mMainHandler : handler; handler.post(new Runnable() { @Override public void run() { try { listener.onAccountsUpdated(accountsCopy); Loading @@ -1919,6 +1934,7 @@ public class AccountManager { final Activity mActivity; public AmsTask(Activity activity, Handler handler, AccountManagerCallback<Bundle> callback) { super(new Callable<Bundle>() { @Override public Bundle call() throws Exception { throw new IllegalStateException("this should never be called"); } Loading @@ -1939,6 +1955,7 @@ public class AccountManager { return this; } @Override protected void set(Bundle bundle) { // TODO: somehow a null is being set as the result of the Future. Log this // case to help debug where this is occurring. When this bug is fixed this Loading Loading @@ -1989,16 +2006,19 @@ public class AccountManager { throw new OperationCanceledException(); } @Override public Bundle getResult() throws OperationCanceledException, IOException, AuthenticatorException { return internalGetResult(null, null); } @Override public Bundle getResult(long timeout, TimeUnit unit) throws OperationCanceledException, IOException, AuthenticatorException { return internalGetResult(timeout, unit); } @Override protected void done() { if (mCallback != null) { postToHandler(mHandler, mCallback, this); Loading @@ -2007,6 +2027,7 @@ public class AccountManager { /** Handles the responses from the AccountManager */ private class Response extends IAccountManagerResponse.Stub { @Override public void onResult(Bundle bundle) { Intent intent = bundle.getParcelable(KEY_INTENT); if (intent != null && mActivity != null) { Loading @@ -2026,6 +2047,7 @@ public class AccountManager { } } @Override public void onError(int code, String message) { if (code == ERROR_CODE_CANCELED || code == ERROR_CODE_USER_RESTRICTED || code == ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE) { Loading @@ -2046,6 +2068,7 @@ public class AccountManager { public BaseFutureTask(Handler handler) { super(new Callable<T>() { @Override public T call() throws Exception { throw new IllegalStateException("this should never be called"); } Loading @@ -2072,6 +2095,7 @@ public class AccountManager { } protected class Response extends IAccountManagerResponse.Stub { @Override public void onResult(Bundle bundle) { try { T result = bundleToResult(bundle); Loading @@ -2088,6 +2112,7 @@ public class AccountManager { onError(ERROR_CODE_INVALID_RESPONSE, "no result in response"); } @Override public void onError(int code, String message) { if (code == ERROR_CODE_CANCELED || code == ERROR_CODE_USER_RESTRICTED || code == ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE) { Loading @@ -2109,9 +2134,11 @@ public class AccountManager { mCallback = callback; } @Override protected void done() { if (mCallback != null) { postRunnableToHandler(new Runnable() { @Override public void run() { mCallback.run(Future2Task.this); } Loading Loading @@ -2162,11 +2189,13 @@ public class AccountManager { throw new OperationCanceledException(); } @Override public T getResult() throws OperationCanceledException, IOException, AuthenticatorException { return internalGetResult(null, null); } @Override public T getResult(long timeout, TimeUnit unit) throws OperationCanceledException, IOException, AuthenticatorException { return internalGetResult(timeout, unit); Loading Loading @@ -2218,9 +2247,11 @@ public class AccountManager { final AccountManagerCallback<Bundle> mMyCallback; private volatile int mNumAccounts = 0; @Override public void doWork() throws RemoteException { getAccountsByTypeAndFeatures(mAccountType, mFeatures, new AccountManagerCallback<Account[]>() { @Override public void run(AccountManagerFuture<Account[]> future) { Account[] accounts; try { Loading Loading @@ -2271,6 +2302,7 @@ public class AccountManager { if (mActivity != null) { IAccountManagerResponse chooseResponse = new IAccountManagerResponse.Stub() { @Override public void onResult(Bundle value) throws RemoteException { Account account = new Account( value.getString(KEY_ACCOUNT_NAME), Loading @@ -2279,6 +2311,7 @@ public class AccountManager { mActivity, mMyCallback, mHandler); } @Override public void onError(int errorCode, String errorMessage) throws RemoteException { mResponse.onError(errorCode, errorMessage); Loading Loading @@ -2311,6 +2344,7 @@ public class AccountManager { }}, mHandler); } @Override public void run(AccountManagerFuture<Bundle> future) { try { final Bundle result = future.getResult(); Loading Loading @@ -2531,6 +2565,7 @@ public class AccountManager { * in mAccountsUpdatedListeners. */ private final BroadcastReceiver mAccountsChangedBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(final Context context, final Intent intent) { final Account[] accounts = getAccounts(); // send the result to the listeners Loading Loading @@ -2851,6 +2886,25 @@ public class AccountManager { final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) { return finishSessionAsUser( sessionBundle, activity, Process.myUserHandle(), callback, handler); } /** * @see #finishSession * @hide */ @SystemApi public AccountManagerFuture<Bundle> finishSessionAsUser( final Bundle sessionBundle, final Activity activity, final UserHandle userHandle, AccountManagerCallback<Bundle> callback, Handler handler) { if (sessionBundle == null) { throw new IllegalArgumentException("sessionBundle is null"); } Loading @@ -2862,7 +2916,12 @@ public class AccountManager { return new AmsTask(activity, handler, callback) { @Override public void doWork() throws RemoteException { mService.finishSession(mResponse, sessionBundle, activity != null, appInfo); mService.finishSessionAsUser( mResponse, sessionBundle, activity != null, appInfo, userHandle.getIdentifier()); } }.start(); } Loading Loading @@ -2898,12 +2957,14 @@ public class AccountManager { } return new Future2Task<Boolean>(handler, callback) { @Override public void doWork() throws RemoteException { mService.isCredentialsUpdateSuggested( mResponse, account, statusToken); } @Override public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException { if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) { throw new AuthenticatorException("no result in response"); Loading
core/java/android/accounts/IAccountManager.aidl +3 −3 Original line number Diff line number Diff line Loading @@ -92,9 +92,9 @@ interface IAccountManager { void startUpdateCredentialsSession(in IAccountManagerResponse response, in Account account, String authTokenType, boolean expectActivityLaunch, in Bundle options); /* Finish session started by startAddAccountSession(...) or startUpdateCredentialsSession(...) */ void finishSession(in IAccountManagerResponse response, in Bundle sessionBundle, boolean expectActivityLaunch, in Bundle appInfo); /* Finish session started by startAddAccountSession(...) or startUpdateCredentialsSession(...) for user */ void finishSessionAsUser(in IAccountManagerResponse response, in Bundle sessionBundle, boolean expectActivityLaunch, in Bundle appInfo, int userId); /* Check if an account exists on any user on the device. */ boolean someUserHasAccount(in Account account); Loading
services/core/java/com/android/server/accounts/AccountManagerService.java +25 −14 Original line number Diff line number Diff line Loading @@ -2486,16 +2486,20 @@ public class AccountManagerService } @Override public void finishSession(IAccountManagerResponse response, public void finishSessionAsUser(IAccountManagerResponse response, @NonNull Bundle sessionBundle, boolean expectActivityLaunch, Bundle appInfo) { Bundle appInfo, int userId) { int callingUid = Binder.getCallingUid(); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "finishSession: response "+ response + ", expectActivityLaunch " + expectActivityLaunch + ", caller's uid " + Binder.getCallingUid() + ", pid " + Binder.getCallingPid()); + ", caller's uid " + callingUid + ", caller's user id " + UserHandle.getCallingUserId() + ", pid " + Binder.getCallingPid() + ", for user id " + userId); } if (response == null) { throw new IllegalArgumentException("response is null"); Loading @@ -2507,17 +2511,24 @@ public class AccountManagerService throw new IllegalArgumentException("sessionBundle is empty"); } final int uid = Binder.getCallingUid(); // Only allow the system process to finish session for other users if (isCrossUser(callingUid, userId)) { throw new SecurityException( String.format( "User %s trying to finish session for %s without cross user permission", UserHandle.getCallingUserId(), userId)); } // Only allow system to finish session if (!isSystemUid(uid)) { if (!isSystemUid(callingUid)) { String msg = String.format( "uid %s cannot finish session.", uid); "uid %s cannot finish session because it's not system uid.", callingUid); throw new SecurityException(msg); } final int userId = UserHandle.getUserId(uid); if (!canUserModifyAccounts(userId, uid)) { if (!canUserModifyAccounts(userId, callingUid)) { sendErrorResponse(response, AccountManager.ERROR_CODE_USER_RESTRICTED, "User is not allowed to add an account!"); Loading Loading @@ -2559,7 +2570,7 @@ public class AccountManagerService } // Add info that may be used by add account or update credentials flow. decryptedBundle.putInt(AccountManager.KEY_CALLER_UID, uid); decryptedBundle.putInt(AccountManager.KEY_CALLER_UID, callingUid); decryptedBundle.putInt(AccountManager.KEY_CALLER_PID, pid); } catch (GeneralSecurityException e) { if (Log.isLoggable(TAG, Log.DEBUG)) { Loading @@ -2572,7 +2583,7 @@ public class AccountManagerService return; } if (!canUserModifyAccountsForType(userId, accountType, uid)) { if (!canUserModifyAccountsForType(userId, accountType, callingUid)) { sendErrorResponse( response, AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE, Loading @@ -2589,7 +2600,7 @@ public class AccountManagerService accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_SESSION_FINISH, TABLE_ACCOUNTS, uid); callingUid); new Session( accounts, response, Loading