From f1318ecbfff840702b08eab40d744dc55670610d Mon Sep 17 00:00:00 2001 From: lambroslambrou Date: Fri, 26 Sep 2014 18:12:44 -0700 Subject: [PATCH] Android Chromoting: Don't fetch auth token if there's a fetch pending. Currently, the host list is fetched from the main activity's onStart() handler. If onStart() is triggered again during the process of authentication, this could cause an infinite loop of pending requests. Review URL: https://codereview.chromium.org/607453004 Cr-Commit-Position: refs/heads/master@{#297088} --- .../org/chromium/chromoting/Chromoting.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/remoting/android/java/src/org/chromium/chromoting/Chromoting.java b/remoting/android/java/src/org/chromium/chromoting/Chromoting.java index f21efccb8eeda..be378904553fe 100644 --- a/remoting/android/java/src/org/chromium/chromoting/Chromoting.java +++ b/remoting/android/java/src/org/chromium/chromoting/Chromoting.java @@ -96,6 +96,13 @@ public class Chromoting extends Activity implements JniInterface.ConnectionListe */ boolean mTriedNewAuthToken; + /** + * Flag to track whether a call to AccountManager.getAuthToken() is currently pending. + * This avoids infinitely-nested calls in case onStart() gets triggered a second time + * while a token is being fetched. + */ + private boolean mWaitingForAuthToken = false; + /** Shows a warning explaining that a Google account is required, then closes the activity. */ private void showNoAccountsDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(this); @@ -292,16 +299,27 @@ public void onCancel(DialogInterface dialog) { } private void refreshHostList() { + if (mWaitingForAuthToken) { + return; + } + mTriedNewAuthToken = false; setHostListProgressVisible(true); // The refresh button simply makes use of the currently-chosen account. + requestAuthToken(); + } + + private void requestAuthToken() { AccountManager.get(this).getAuthToken(mAccount, TOKEN_SCOPE, null, this, this, null); + mWaitingForAuthToken = true; } @Override public void run(AccountManagerFuture future) { Log.i("auth", "User finished with auth dialogs"); + mWaitingForAuthToken = false; + Bundle result = null; String explanation = null; try { @@ -316,6 +334,7 @@ public void run(AccountManagerFuture future) { } if (result == null) { + setHostListProgressVisible(false); if (explanation != null) { Toast.makeText(this, explanation, Toast.LENGTH_LONG).show(); } @@ -387,7 +406,7 @@ public void onError(HostListLoader.Error error) { Log.w("auth", "Requesting renewal of rejected auth token"); authenticator.invalidateAuthToken(mAccount.type, mToken); mToken = null; - authenticator.getAuthToken(mAccount, TOKEN_SCOPE, null, this, this, null); + requestAuthToken(); // We're not in an error state *yet*. return;