diff options
| author | Patrick Scott <phanna@android.com> | 2011-02-04 09:27:26 -0500 |
|---|---|---|
| committer | Patrick Scott <phanna@android.com> | 2011-02-04 13:22:01 -0500 |
| commit | 7d50a9364107c21e3358e1dbc51a06359a5287fb (patch) | |
| tree | 77912ffefe7bfd6fbcccf956adfba8e39fe592ff /src/com | |
| parent | 18793490c4a4fe1a9979218c7b3f2c88bc04e128 (diff) | |
| download | packages_apps_Browser-7d50a9364107c21e3358e1dbc51a06359a5287fb.tar.gz packages_apps_Browser-7d50a9364107c21e3358e1dbc51a06359a5287fb.tar.bz2 packages_apps_Browser-7d50a9364107c21e3358e1dbc51a06359a5287fb.zip | |
Clear session cookies before attempting pre-login.
If ClientLogin issues session cookies, we do not want to clear them immediately
after getting them from login. If we are not going to restore tabs, go ahead
and clear the cookies before attempting pre-login. Keep track of the tab to
restore so that we don't need to figure it out again. Requires a change in
frameworks/base that exposes the CookieManager api.
If we receive a 403 from IssueTokenAuth, inval the auth tokens and try again.
Bug: 3421214
Change-Id: I5dd4cc0eba365a20a731ac43dd2571ef6274eaa9
Diffstat (limited to 'src/com')
| -rw-r--r-- | src/com/android/browser/BrowserActivity.java | 7 | ||||
| -rw-r--r-- | src/com/android/browser/Controller.java | 31 | ||||
| -rw-r--r-- | src/com/android/browser/GoogleAccountLogin.java | 37 | ||||
| -rw-r--r-- | src/com/android/browser/TabControl.java | 165 |
4 files changed, 147 insertions, 93 deletions
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java index ec096731d..899a7c29e 100644 --- a/src/com/android/browser/BrowserActivity.java +++ b/src/com/android/browser/BrowserActivity.java @@ -111,12 +111,7 @@ public class BrowserActivity extends Activity { 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 07e1ef97e..74a66b16f 100644 --- a/src/com/android/browser/Controller.java +++ b/src/com/android/browser/Controller.java @@ -251,7 +251,7 @@ public class Controller 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 @@ public class Controller 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. + // 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 @@ public class Controller 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 f019b52a6..eaf45ea23 100644 --- a/src/com/android/browser/GoogleAccountLogin.java +++ b/src/com/android/browser/GoogleAccountLogin.java @@ -46,7 +46,7 @@ import android.webkit.WebViewClient; 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 @@ public class GoogleAccountLogin extends Thread implements 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 @@ public class GoogleAccountLogin extends Thread implements ed.apply(); } - // Thread + // Runnable @Override public void run() { String url = ISSUE_AUTH_TOKEN_URL.buildUpon() @@ -128,10 +129,22 @@ public class GoogleAccountLogin extends Thread implements 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 @@ public class GoogleAccountLogin extends Thread implements }); } + 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 @@ public class GoogleAccountLogin extends Thread implements break; case 2: mLsid = id; - this.start(); + new Thread(this).start(); break; } } catch (Exception e) { @@ -280,6 +302,11 @@ public class GoogleAccountLogin extends Thread implements 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 050ad9493..af9928a4c 100644 --- a/src/com/android/browser/TabControl.java +++ b/src/com/android/browser/TabControl.java @@ -287,7 +287,42 @@ class TabControl { } /** + * 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 @@ class TabControl { * @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); - - // 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; - } - } - } - if (currentTab < 0) { - return false; - } + void restoreState(Bundle inState, int currentTab, + boolean restoreIncognitoTabs, boolean restoreAll) { + if (currentTab == -1) { + return; + } - // 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); + // 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 { + // 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; } /** |
