Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb68a4fc authored by Fred Quintana's avatar Fred Quintana
Browse files

add AccountManager.testHasFeatures() to make it easy to check if a given...

add AccountManager.testHasFeatures() to make it easy to check if a given account has a set of features
parent 81787533
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -14690,6 +14690,25 @@
<parameter name="value" type="java.lang.String">
</parameter>
</method>
<method name="testHasFeatures"
 return="android.accounts.AccountManagerFuture&lt;java.lang.Boolean&gt;"
 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&lt;java.lang.Boolean&gt;">
</parameter>
<parameter name="handler" type="android.os.Handler">
</parameter>
</method>
<method name="updateCredentials"
 return="android.accounts.AccountManagerFuture&lt;android.os.Bundle&gt;"
 abstract="false"
+41 −0
Original line number Diff line number Diff line
@@ -229,6 +229,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>
+58 −0
Original line number Diff line number Diff line
@@ -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();
+2 −0
Original line number Diff line number Diff line
@@ -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);