AccountManager: add isCredentialsUpdateSuggested API.
Change-Id: I27e0db0345f3431b796a944740dab767b45f7871
This commit is contained in:
@@ -2860,6 +2860,7 @@ package android.accounts {
|
||||
method public abstract java.lang.String getAuthTokenLabel(java.lang.String);
|
||||
method public final android.os.IBinder getIBinder();
|
||||
method public abstract android.os.Bundle hasFeatures(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, java.lang.String[]) throws android.accounts.NetworkErrorException;
|
||||
method public android.os.Bundle isCredentialsUpdateSuggested(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, java.lang.String) throws android.accounts.NetworkErrorException;
|
||||
method public android.os.Bundle startAddAccountSession(android.accounts.AccountAuthenticatorResponse, java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle) throws android.accounts.NetworkErrorException;
|
||||
method public android.os.Bundle startUpdateCredentialsSession(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, java.lang.String, android.os.Bundle) throws android.accounts.NetworkErrorException;
|
||||
method public abstract android.os.Bundle updateCredentials(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, java.lang.String, android.os.Bundle) throws android.accounts.NetworkErrorException;
|
||||
@@ -2915,6 +2916,7 @@ package android.accounts {
|
||||
method public java.lang.String getUserData(android.accounts.Account, java.lang.String);
|
||||
method public android.accounts.AccountManagerFuture<java.lang.Boolean> hasFeatures(android.accounts.Account, java.lang.String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
|
||||
method public void invalidateAuthToken(java.lang.String, java.lang.String);
|
||||
method public android.accounts.AccountManagerFuture<java.lang.Boolean> isCredentialsUpdateSuggested(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
|
||||
method public static deprecated android.content.Intent newChooseAccountIntent(android.accounts.Account, java.util.ArrayList<android.accounts.Account>, java.lang.String[], boolean, java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle);
|
||||
method public static android.content.Intent newChooseAccountIntent(android.accounts.Account, java.util.List<android.accounts.Account>, java.lang.String[], java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle);
|
||||
method public boolean notifyAccountAuthenticated(android.accounts.Account);
|
||||
|
||||
@@ -16,16 +16,16 @@
|
||||
|
||||
package android.accounts;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.text.TextUtils;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.Manifest;
|
||||
import android.annotation.SystemApi;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -436,6 +436,7 @@ public abstract class AbstractAccountAuthenticator {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishSession(
|
||||
IAccountAuthenticatorResponse response,
|
||||
String accountType,
|
||||
@@ -461,6 +462,24 @@ public abstract class AbstractAccountAuthenticator {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isCredentialsUpdateSuggested(
|
||||
IAccountAuthenticatorResponse response,
|
||||
Account account,
|
||||
String statusToken) throws RemoteException {
|
||||
checkBinderPermission();
|
||||
try {
|
||||
final Bundle result = AbstractAccountAuthenticator.this
|
||||
.isCredentialsUpdateSuggested(
|
||||
new AccountAuthenticatorResponse(response), account, statusToken);
|
||||
if (result != null) {
|
||||
response.onResult(result);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
handleException(response, "isCredentialsUpdateSuggested", account.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleException(IAccountAuthenticatorResponse response, String method,
|
||||
@@ -873,7 +892,8 @@ public abstract class AbstractAccountAuthenticator {
|
||||
* <li>{@link AccountManager#KEY_ERROR_CODE} and
|
||||
* {@link AccountManager#KEY_ERROR_MESSAGE} to indicate an error
|
||||
* </ul>
|
||||
* @throws NetworkErrorException
|
||||
* @throws NetworkErrorException if the authenticator could not honor the request due to a
|
||||
* network error
|
||||
* @see #startAddAccountSession and #startUpdateCredentialsSession
|
||||
* @hide
|
||||
*/
|
||||
@@ -944,4 +964,32 @@ public abstract class AbstractAccountAuthenticator {
|
||||
// Otherwise, session bundle was created by startAddAccountSession default implementation.
|
||||
return addAccount(response, accountType, authTokenType, requiredFeatures, sessionOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if update of the account credentials is suggested.
|
||||
*
|
||||
* @param response to send the result back to the AccountManager, will never be null.
|
||||
* @param account the account to check, will never be null
|
||||
* @param statusToken a String of token to check if update of credentials is suggested.
|
||||
* @return a Bundle result or null if the result is to be returned via the response. The result
|
||||
* will contain either:
|
||||
* <ul>
|
||||
* <li>{@link AccountManager#KEY_BOOLEAN_RESULT}, true if update of account's
|
||||
* credentials is suggested, false otherwise
|
||||
* <li>{@link AccountManager#KEY_ERROR_CODE} and
|
||||
* {@link AccountManager#KEY_ERROR_MESSAGE} to indicate an error
|
||||
* </ul>
|
||||
* @throws NetworkErrorException if the authenticator could not honor the request due to a
|
||||
* network error
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public Bundle isCredentialsUpdateSuggested(
|
||||
final AccountAuthenticatorResponse response,
|
||||
Account account,
|
||||
String statusToken) throws NetworkErrorException {
|
||||
Bundle result = new Bundle();
|
||||
result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.accounts;
|
||||
|
||||
import static android.Manifest.permission.GET_ACCOUNTS;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.Size;
|
||||
@@ -54,8 +56,6 @@ import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import static android.Manifest.permission.GET_ACCOUNTS;
|
||||
|
||||
/**
|
||||
* This class provides access to a centralized registry of the user's
|
||||
* online accounts. The user enters credentials (username and password) once
|
||||
@@ -2866,4 +2866,50 @@ public class AccountManager {
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether {@link #updateCredentials} or {@link #startUpdateCredentialsSession} should be
|
||||
* called with respect to the specified account.
|
||||
* <p>
|
||||
* This method may be called from any thread, but the returned {@link AccountManagerFuture} must
|
||||
* not be used on the main thread.
|
||||
*
|
||||
* @param account The {@link Account} to be checked whether {@link #updateCredentials} or
|
||||
* {@link #startUpdateCredentialsSession} should be called
|
||||
* @param statusToken a String of token to check account staus
|
||||
* @param callback Callback to invoke when the request completes, null for no callback
|
||||
* @param handler {@link Handler} identifying the callback thread, null for the main thread
|
||||
* @return An {@link AccountManagerFuture} which resolves to a Boolean, true if the credentials
|
||||
* of the account should be updated.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public AccountManagerFuture<Boolean> isCredentialsUpdateSuggested(
|
||||
final Account account,
|
||||
final String statusToken,
|
||||
AccountManagerCallback<Boolean> callback,
|
||||
Handler handler) {
|
||||
if (account == null) {
|
||||
throw new IllegalArgumentException("account is null");
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(statusToken)) {
|
||||
throw new IllegalArgumentException("status token is empty");
|
||||
}
|
||||
|
||||
return new Future2Task<Boolean>(handler, callback) {
|
||||
public void doWork() throws RemoteException {
|
||||
mService.isCredentialsUpdateSuggested(
|
||||
mResponse,
|
||||
account,
|
||||
statusToken);
|
||||
}
|
||||
public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
|
||||
if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
|
||||
throw new AuthenticatorException("no result in response");
|
||||
}
|
||||
return bundle.getBoolean(KEY_BOOLEAN_RESULT);
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,4 +104,10 @@ oneway interface IAccountAuthenticator {
|
||||
*/
|
||||
void finishSession(in IAccountAuthenticatorResponse response, String accountType,
|
||||
in Bundle sessionBundle);
|
||||
|
||||
/**
|
||||
* Checks if the credentials of the provided account should be updated.
|
||||
*/
|
||||
void isCredentialsUpdateSuggested(in IAccountAuthenticatorResponse response, in Account account,
|
||||
String statusToken);
|
||||
}
|
||||
|
||||
@@ -98,4 +98,8 @@ interface IAccountManager {
|
||||
|
||||
/* Check if an account exists on any user on the device. */
|
||||
boolean someUserHasAccount(in Account account);
|
||||
|
||||
/* Check if credentials update is suggested */
|
||||
void isCredentialsUpdateSuggested(in IAccountManagerResponse response, in Account account,
|
||||
String statusToken);
|
||||
}
|
||||
|
||||
@@ -176,6 +176,7 @@ public class AccountManagerService
|
||||
private static final String[] ACCOUNT_TYPE_COUNT_PROJECTION =
|
||||
new String[] { ACCOUNTS_TYPE, ACCOUNTS_TYPE_COUNT};
|
||||
private static final Intent ACCOUNTS_CHANGED_INTENT;
|
||||
|
||||
static {
|
||||
ACCOUNTS_CHANGED_INTENT = new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION);
|
||||
ACCOUNTS_CHANGED_INTENT.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
|
||||
@@ -2491,7 +2492,7 @@ public class AccountManagerService
|
||||
Bundle appInfo) {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
Log.v(TAG,
|
||||
"finishSession: response "+ response
|
||||
"finishSession: response " + response
|
||||
+ ", expectActivityLaunch " + expectActivityLaunch
|
||||
+ ", caller's uid " + Binder.getCallingUid()
|
||||
+ ", pid " + Binder.getCallingPid());
|
||||
@@ -2777,6 +2778,99 @@ public class AccountManagerService
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isCredentialsUpdateSuggested(
|
||||
IAccountManagerResponse response,
|
||||
final Account account,
|
||||
final String statusToken) {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
Log.v(TAG,
|
||||
"isCredentialsUpdateSuggested: " + account + ", response " + response
|
||||
+ ", caller's uid " + Binder.getCallingUid()
|
||||
+ ", pid " + Binder.getCallingPid());
|
||||
}
|
||||
if (response == null) {
|
||||
throw new IllegalArgumentException("response is null");
|
||||
}
|
||||
if (account == null) {
|
||||
throw new IllegalArgumentException("account is null");
|
||||
}
|
||||
if (TextUtils.isEmpty(statusToken)) {
|
||||
throw new IllegalArgumentException("status token is empty");
|
||||
}
|
||||
|
||||
int uid = Binder.getCallingUid();
|
||||
// Only allow system to start session
|
||||
if (!isSystemUid(uid)) {
|
||||
String msg = String.format(
|
||||
"uid %s cannot stat add account session.",
|
||||
uid);
|
||||
throw new SecurityException(msg);
|
||||
}
|
||||
|
||||
int usrId = UserHandle.getCallingUserId();
|
||||
long identityToken = clearCallingIdentity();
|
||||
try {
|
||||
UserAccounts accounts = getUserAccounts(usrId);
|
||||
new Session(accounts, response, account.type, false /* expectActivityLaunch */,
|
||||
false /* stripAuthTokenFromResult */, account.name,
|
||||
false /* authDetailsRequired */) {
|
||||
@Override
|
||||
protected String toDebugString(long now) {
|
||||
return super.toDebugString(now) + ", isCredentialsUpdateSuggested"
|
||||
+ ", " + account;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() throws RemoteException {
|
||||
mAuthenticator.isCredentialsUpdateSuggested(this, account, statusToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResult(Bundle result) {
|
||||
IAccountManagerResponse response = getResponseAndClose();
|
||||
if (response == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
sendErrorResponse(
|
||||
response,
|
||||
AccountManager.ERROR_CODE_INVALID_RESPONSE,
|
||||
"null bundle");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response "
|
||||
+ response);
|
||||
}
|
||||
// Check to see if an error occurred. We know if an error occurred because all
|
||||
// error codes are greater than 0.
|
||||
if ((result.getInt(AccountManager.KEY_ERROR_CODE, -1) > 0)) {
|
||||
sendErrorResponse(response,
|
||||
result.getInt(AccountManager.KEY_ERROR_CODE),
|
||||
result.getString(AccountManager.KEY_ERROR_MESSAGE));
|
||||
return;
|
||||
}
|
||||
if (!result.containsKey(AccountManager.KEY_BOOLEAN_RESULT)) {
|
||||
sendErrorResponse(
|
||||
response,
|
||||
AccountManager.ERROR_CODE_INVALID_RESPONSE,
|
||||
"no result in response");
|
||||
return;
|
||||
}
|
||||
final Bundle newResult = new Bundle();
|
||||
newResult.putBoolean(AccountManager.KEY_BOOLEAN_RESULT,
|
||||
result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false));
|
||||
sendResponse(response, newResult);
|
||||
}
|
||||
}.bind();
|
||||
} finally {
|
||||
restoreCallingIdentity(identityToken);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editProperties(IAccountManagerResponse response, final String accountType,
|
||||
final boolean expectActivityLaunch) {
|
||||
|
||||
Reference in New Issue
Block a user