diff options
-rw-r--r-- | api/current.xml | 19 | ||||
-rw-r--r-- | core/java/android/accounts/AccountManager.java | 41 | ||||
-rw-r--r-- | core/java/android/accounts/AccountManagerService.java | 58 | ||||
-rw-r--r-- | core/java/android/accounts/IAccountManager.aidl | 2 |
4 files changed, 120 insertions, 0 deletions
diff --git a/api/current.xml b/api/current.xml index f3e614a..113b9e0 100644 --- a/api/current.xml +++ b/api/current.xml @@ -14690,6 +14690,25 @@ <parameter name="value" type="java.lang.String"> </parameter> </method> +<method name="testHasFeatures" + return="android.accounts.AccountManagerFuture<java.lang.Boolean>" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="account" type="android.accounts.Account"> +</parameter> +<parameter name="features" type="java.lang.String[]"> +</parameter> +<parameter name="callback" type="android.accounts.AccountManagerCallback<java.lang.Boolean>"> +</parameter> +<parameter name="handler" type="android.os.Handler"> +</parameter> +</method> <method name="updateCredentials" return="android.accounts.AccountManagerFuture<android.os.Bundle>" abstract="false" diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index 9765496..3bbfce8 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -230,6 +230,47 @@ public class AccountManager { } /** + * Tests that the given account has the specified features. If this account does not exist + * then this call returns false. + * <p> + * This call returns immediately but runs asynchronously and the result is accessed via the + * {@link AccountManagerFuture} that is returned. This future is also passed as the sole + * parameter to the {@link AccountManagerCallback}. If the caller wished to use this + * method asynchronously then they will generally pass in a callback object that will get + * invoked with the {@link AccountManagerFuture}. If they wish to use it synchronously then + * they will generally pass null for the callback and instead call + * {@link android.accounts.AccountManagerFuture#getResult()} on this method's return value, + * which will then block until the request completes. + * <p> + * Requires that the caller has permission {@link android.Manifest.permission#GET_ACCOUNTS}. + * + * @param account The {@link Account} to test + * @param features the features for which to test + * @param callback A callback to invoke when the request completes. If null then + * no callback is invoked. + * @param handler The {@link Handler} to use to invoke the callback. If null then the + * main thread's {@link Handler} is used. + * @return an {@link AccountManagerFuture} that represents the future result of the call. + * The future result is a {@link Boolean} that is true if the account exists and has the + * specified features. + */ + public AccountManagerFuture<Boolean> testHasFeatures(final Account account, + final String[] features, + AccountManagerCallback<Boolean> callback, Handler handler) { + return new Future2Task<Boolean>(handler, callback) { + public void doWork() throws RemoteException { + mService.testHasFeatures(mResponse, account, features); + } + 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(); + } + + /** * Add an account to the AccountManager's set of known accounts. * <p> * Requires that the caller has permission diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java index d5a9b02..f5166c2 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -449,6 +449,64 @@ public class AccountManagerService return db.insert(TABLE_EXTRAS, EXTRAS_KEY, values); } + public void testHasFeatures(IAccountManagerResponse response, + Account account, String[] features) { + checkReadAccountsPermission(); + long identityToken = clearCallingIdentity(); + try { + new TestFeaturesSession(response, account, features).bind(); + } finally { + restoreCallingIdentity(identityToken); + } + } + + private class TestFeaturesSession extends Session { + private final String[] mFeatures; + private final Account mAccount; + + public TestFeaturesSession(IAccountManagerResponse response, + Account account, String[] features) { + super(response, account.type, false /* expectActivityLaunch */); + mFeatures = features; + mAccount = account; + } + + public void run() throws RemoteException { + try { + mAuthenticator.hasFeatures(this, mAccount, mFeatures); + } catch (RemoteException e) { + onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "remote exception"); + } + } + + public void onResult(Bundle result) { + IAccountManagerResponse response = getResponseAndClose(); + if (response != null) { + try { + if (result == null) { + onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle"); + return; + } + final Bundle newResult = new Bundle(); + newResult.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, + result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)); + response.onResult(newResult); + } catch (RemoteException e) { + // if the caller is dead then there is no one to care about remote exceptions + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "failure while notifying response", e); + } + } + } + } + + protected String toDebugString(long now) { + return super.toDebugString(now) + ", testHasFeatures" + + ", " + mAccount + + ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null); + } + } + public void removeAccount(IAccountManagerResponse response, Account account) { checkManageAccountsPermission(); long identityToken = clearCallingIdentity(); diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl index 0e318c0..cbd26ee 100644 --- a/core/java/android/accounts/IAccountManager.aidl +++ b/core/java/android/accounts/IAccountManager.aidl @@ -31,6 +31,8 @@ interface IAccountManager { String getUserData(in Account account, String key); AuthenticatorDescription[] getAuthenticatorTypes(); Account[] getAccounts(String accountType); + void testHasFeatures(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); void removeAccount(in IAccountManagerResponse response, in Account account); |