Getting an Auth Token from accountmanager using a CountdownLatch

1.5k views Asked by At

I am trying to get the Authentication Token from an account in Android before I make my request to the server. I Am trying to control the flow with a CountdownLatch so that it waits until:

  • a) A timeout (10s)
  • b) We get the token

    private CountDownLatch tokenLatch = new CountDownLatch(1);
    final long tokenTimeoutSeconds = 10;
    AccountManager manager = AccountManager.get(mContext);
    Account userAccount = getCurrentAccount();
    // Get the auth token
    if (userAccount != null) {
        AccountManagerFuture<Bundle> future = manager.getAuthToken(userAccount, AccountUtility.AUTHTOKEN_TYPE_FULL_ACCESS, true, new AccountManagerCallback<Bundle>() {
            @Override
            public void run(AccountManagerFuture<Bundle> future) {
                try {
                    Bundle bundle = future.getResult();
                    currentAuthToken = bundle.get(AccountManager.KEY_AUTHTOKEN).toString();
                    tokenLatch.countDown();
                } catch (Exception e) {
                    Log.e(LOG_TAG, "Problem getting auth token!", e);
                }
            }
        }, null);
    
        try {
            tokenLatch.await(tokenTimeoutSeconds, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Log.e(LOG_TAG, "Interupted while getting auth token!", e);
        }
    

Context is passed:

mContext = ...  getApplicationContext();

Right now it exits before either of those two cases. It does, however, always reach the AccountManagerCallback after all other processes are finished. Strange. I am most definitely doing something wrong. Thanks for the helperooni!

1

There are 1 answers

0
Bob Snyder On BEST ANSWER

This explanation presumes the posted code is running on the main thread. Because the Handler parameter in the call to getAuthToken() is null, the callback will also run on the main thread. This is a deadlock situation. After calling getAuthToken() the main thread blocks on the latch await(). The callback cannot run because the main thread is blocked. The latch never counts down to zero because the callback can't run.

The code posted at this blog offers an example of how an auth token can be obtained on the main thread without blocking.