am 7d50a936: Clear session cookies before attempting pre-login.
* commit '7d50a9364107c21e3358e1dbc51a06359a5287fb':
Clear session cookies before attempting pre-login.
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index ec09673..899a7c2 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -111,12 +111,7 @@
icicle = state;
}
- final Bundle b = icicle;
- GoogleAccountLogin.startLoginIfNeeded(this, settings, new Runnable() {
- @Override public void run() {
- mController.start(b, getIntent());
- }
- });
+ mController.start(icicle, getIntent());
}
@VisibleForTesting
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index 07e1ef9..74a66b1 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -251,7 +251,7 @@
retainIconsOnStartup();
}
- void start(Bundle icicle, Intent intent) {
+ void start(final Bundle icicle, final Intent intent) {
// Unless the last browser usage was within 24 hours, destroy any
// remaining incognito tabs.
@@ -261,17 +261,32 @@
Calendar yesterday = Calendar.getInstance();
yesterday.add(Calendar.DATE, -1);
- boolean restoreIncognitoTabs = !(lastActiveDate == null
+ final boolean restoreIncognitoTabs = !(lastActiveDate == null
|| lastActiveDate.before(yesterday)
|| lastActiveDate.after(today));
- if (!mTabControl.restoreState(icicle, restoreIncognitoTabs,
- mUi.needsRestoreAllTabs())) {
- // there is no quit on Android. But if we can't restore the state,
- // we can treat it as a new Browser, remove the old session cookies.
- // This is done async in the CookieManager.
- CookieManager.getInstance().removeSessionCookie();
+ // Find out if we will restore any state and remember the tab.
+ final int currentTab =
+ mTabControl.canRestoreState(icicle, restoreIncognitoTabs);
+ if (currentTab == -1) {
+ // Not able to restore so we go ahead and clear session cookies. We
+ // must do this before trying to login the user as we don't want to
+ // clear any session cookies set during login.
+ CookieManager.getInstance().removeSessionCookie();
+ }
+
+ GoogleAccountLogin.startLoginIfNeeded(mActivity, mSettings,
+ new Runnable() {
+ @Override public void run() {
+ start(icicle, intent, currentTab, restoreIncognitoTabs);
+ }
+ });
+ }
+
+ private void start(Bundle icicle, Intent intent, int currentTab,
+ boolean restoreIncognitoTabs) {
+ if (currentTab == -1) {
final Bundle extra = intent.getExtras();
// Create an initial tab.
// If the intent is ACTION_VIEW and data is not null, the Browser is
@@ -303,6 +318,8 @@
loadUrlDataIn(t, urlData);
}
} else {
+ mTabControl.restoreState(icicle, currentTab, restoreIncognitoTabs,
+ mUi.needsRestoreAllTabs());
mUi.updateTabs(mTabControl.getTabs());
// TabControl.restoreState() will create a new tab even if
// restoring the state fails.
diff --git a/src/com/android/browser/GoogleAccountLogin.java b/src/com/android/browser/GoogleAccountLogin.java
index f019b52..eaf45ea 100644
--- a/src/com/android/browser/GoogleAccountLogin.java
+++ b/src/com/android/browser/GoogleAccountLogin.java
@@ -46,7 +46,7 @@
import java.util.StringTokenizer;
-public class GoogleAccountLogin extends Thread implements
+public class GoogleAccountLogin implements Runnable,
AccountManagerCallback<Bundle>, OnCancelListener {
private static final String LOGTAG = "BrowserLogin";
@@ -77,6 +77,7 @@
private String mSid;
private String mLsid;
private int mState; // {NONE(0), SID(1), LSID(2)}
+ private boolean mTokensInvalidated;
private GoogleAccountLogin(Activity activity, String name,
Runnable runnable) {
@@ -105,7 +106,7 @@
ed.apply();
}
- // Thread
+ // Runnable
@Override
public void run() {
String url = ISSUE_AUTH_TOKEN_URL.buildUpon()
@@ -128,10 +129,22 @@
String result = null;
try {
HttpResponse response = client.execute(request);
- if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+ int status = response.getStatusLine().getStatusCode();
+ if (status != HttpStatus.SC_OK) {
Log.d(LOGTAG, "LOGIN_FAIL: Bad status from auth url "
- + response.getStatusLine().getStatusCode() + ": "
+ + status + ": "
+ response.getStatusLine().getReasonPhrase());
+ // Invalidate the tokens once just in case the 403 was for other
+ // reasons.
+ if (status == HttpStatus.SC_FORBIDDEN && !mTokensInvalidated) {
+ Log.d(LOGTAG, "LOGIN_FAIL: Invalidating tokens...");
+ // Need to regenerate the auth tokens and try again.
+ invalidateTokens();
+ // XXX: Do not touch any more member variables from this
+ // thread as a second thread will handle the next login
+ // attempt.
+ return;
+ }
done();
return;
}
@@ -171,6 +184,15 @@
});
}
+ private void invalidateTokens() {
+ AccountManager am = AccountManager.get(mActivity);
+ am.invalidateAuthToken(GOOGLE, mSid);
+ am.invalidateAuthToken(GOOGLE, mLsid);
+ mTokensInvalidated = true;
+ mState = 1; // SID
+ am.getAuthToken(mAccount, "SID", null, mActivity, this, null);
+ }
+
// AccountManager callbacks.
@Override
public void run(AccountManagerFuture<Bundle> value) {
@@ -190,7 +212,7 @@
break;
case 2:
mLsid = id;
- this.start();
+ new Thread(this).start();
break;
}
} catch (Exception e) {
@@ -280,6 +302,11 @@
return false;
}
+ // This will potentially block the UI thread but we have to have the
+ // most updated cookies.
+ // FIXME: Figure out how to avoid waiting to clear session cookies.
+ CookieManager.getInstance().waitForCookieOperationsToComplete();
+
// Use /a/ to grab hosted cookies as well as the base set of google.com
// cookies.
String cookies = CookieManager.getInstance().getCookie(
diff --git a/src/com/android/browser/TabControl.java b/src/com/android/browser/TabControl.java
index 050ad94..af9928a 100644
--- a/src/com/android/browser/TabControl.java
+++ b/src/com/android/browser/TabControl.java
@@ -287,7 +287,42 @@
}
/**
+ * Check if the state can be restored. If the state can be restored, the
+ * current tab index is returned. This can be passed to restoreState below
+ * in order to restore the correct tab. Otherwise, -1 is returned and the
+ * state cannot be restored.
+ */
+ int canRestoreState(Bundle inState, boolean restoreIncognitoTabs) {
+ final int numTabs = (inState == null)
+ ? - 1 : inState.getInt(Tab.NUMTABS, -1);
+ if (numTabs == -1) {
+ return -1;
+ }
+ final int oldCurrentTab = inState.getInt(Tab.CURRTAB, -1);
+
+ // Determine whether the saved current tab can be restored, and if not,
+ // which tab will take its place.
+ int currentTab = -1;
+ if (restoreIncognitoTabs ||
+ !inState.getBundle(Tab.WEBVIEW + oldCurrentTab)
+ .getBoolean(Tab.INCOGNITO)) {
+ currentTab = oldCurrentTab;
+ } else {
+ for (int i = 0; i < numTabs; i++) {
+ if (!inState.getBundle(Tab.WEBVIEW + i)
+ .getBoolean(Tab.INCOGNITO)) {
+ currentTab = i;
+ break;
+ }
+ }
+ }
+
+ return currentTab;
+ }
+
+ /**
* Restore the state of all the tabs.
+ * @param currentTab The tab index to restore.
* @param inState The saved state of all the tabs.
* @param restoreIncognitoTabs Restoring private browsing tabs
* @param restoreAll All webviews get restored, not just the current tab
@@ -295,89 +330,69 @@
* @return True if there were previous tabs that were restored. False if
* there was no saved state or restoring the state failed.
*/
- boolean restoreState(Bundle inState, boolean restoreIncognitoTabs,
- boolean restoreAll) {
- final int numTabs = (inState == null)
- ? -1 : inState.getInt(Tab.NUMTABS, -1);
- if (numTabs == -1) {
- return false;
- } else {
- final int oldCurrentTab = inState.getInt(Tab.CURRTAB, -1);
+ void restoreState(Bundle inState, int currentTab,
+ boolean restoreIncognitoTabs, boolean restoreAll) {
+ if (currentTab == -1) {
+ return;
+ }
- // Determine whether the saved current tab can be restored, and
- // if not, which tab will take its place.
- int currentTab = -1;
- if (restoreIncognitoTabs
- || !inState.getBundle(Tab.WEBVIEW + oldCurrentTab).getBoolean(Tab.INCOGNITO)) {
- currentTab = oldCurrentTab;
+ // If currentTab is valid, numTabs must be present.
+ final int numTabs = inState.getInt(Tab.NUMTABS, -1);
+
+ // Map saved tab indices to new indices, in case any incognito tabs
+ // need to not be restored.
+ HashMap<Integer, Integer> originalTabIndices = new HashMap<Integer, Integer>();
+ originalTabIndices.put(-1, -1);
+ for (int i = 0; i < numTabs; i++) {
+ Bundle state = inState.getBundle(Tab.WEBVIEW + i);
+
+ if (!restoreIncognitoTabs && state != null && state.getBoolean(Tab.INCOGNITO)) {
+ originalTabIndices.put(i, -1);
+ } else if (i == currentTab || restoreAll) {
+ Tab t = createNewTab();
+ // Me must set the current tab before restoring the state
+ // so that all the client classes are set.
+ if (i == currentTab) {
+ setCurrentTab(t);
+ }
+ if (!t.restoreState(state)) {
+ Log.w(LOGTAG, "Fail in restoreState, load home page.");
+ t.getWebView().loadUrl(BrowserSettings.getInstance()
+ .getHomePage());
+ }
+ originalTabIndices.put(i, getTabCount() - 1);
} else {
- for (int i = 0; i < numTabs; i++) {
- if (!inState.getBundle(Tab.WEBVIEW + i).getBoolean(Tab.INCOGNITO)) {
- currentTab = i;
- break;
- }
+ // Create a new tab and don't restore the state yet, add it
+ // to the tab list
+ Tab t = new Tab(mController, null, false, null, null);
+ if (state != null) {
+ t.setSavedState(state);
+ // Need to maintain the app id and original url so we
+ // can possibly reuse this tab.
+ t.setAppId(state.getString(Tab.APPID));
}
+ mTabs.add(t);
+ // added the tab to the front as they are not current
+ mTabQueue.add(0, t);
+ originalTabIndices.put(i, getTabCount() - 1);
}
- if (currentTab < 0) {
- return false;
- }
+ }
- // Map saved tab indices to new indices, in case any incognito tabs
- // need to not be restored.
- HashMap<Integer, Integer> originalTabIndices = new HashMap<Integer, Integer>();
- originalTabIndices.put(-1, -1);
- for (int i = 0; i < numTabs; i++) {
- Bundle state = inState.getBundle(Tab.WEBVIEW + i);
-
- if (!restoreIncognitoTabs && state != null && state.getBoolean(Tab.INCOGNITO)) {
- originalTabIndices.put(i, -1);
- } else if (i == currentTab || restoreAll) {
- Tab t = createNewTab();
- // Me must set the current tab before restoring the state
- // so that all the client classes are set.
- if (i == currentTab) {
- setCurrentTab(t);
- }
- if (!t.restoreState(state)) {
- Log.w(LOGTAG, "Fail in restoreState, load home page.");
- t.getWebView().loadUrl(BrowserSettings.getInstance()
- .getHomePage());
- }
- originalTabIndices.put(i, getTabCount() - 1);
- } else {
- // Create a new tab and don't restore the state yet, add it
- // to the tab list
- Tab t = new Tab(mController, null, false, null, null);
- if (state != null) {
- t.setSavedState(state);
- // Need to maintain the app id and original url so we
- // can possibly reuse this tab.
- t.setAppId(state.getString(Tab.APPID));
- }
- mTabs.add(t);
- // added the tab to the front as they are not current
- mTabQueue.add(0, t);
- originalTabIndices.put(i, getTabCount() - 1);
- }
- }
-
- // Rebuild the tree of tabs. Do this after all tabs have been
- // created/restored so that the parent tab exists.
- for (int i = 0; i < numTabs; i++) {
- final Bundle b = inState.getBundle(Tab.WEBVIEW + i);
- final Tab t = getTab(i);
- if (b != null && t != null) {
- final Integer parentIndex = originalTabIndices.get(b.getInt(Tab.PARENTTAB, -1));
- if (parentIndex != -1) {
- final Tab parent = getTab(parentIndex);
- if (parent != null) {
- parent.addChildTab(t);
- }
+ // Rebuild the tree of tabs. Do this after all tabs have been
+ // created/restored so that the parent tab exists.
+ for (int i = 0; i < numTabs; i++) {
+ final Bundle b = inState.getBundle(Tab.WEBVIEW + i);
+ final Tab t = getTab(i);
+ if (b != null && t != null) {
+ final Integer parentIndex = originalTabIndices.get(b.getInt(Tab.PARENTTAB, -1));
+ if (parentIndex != -1) {
+ final Tab parent = getTab(parentIndex);
+ if (parent != null) {
+ parent.addChildTab(t);
}
}
}
}
- return true;
}
/**