1539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott/* 2539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott * Copyright (C) 2010 The Android Open Source Project 3539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott * 4539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott * Licensed under the Apache License, Version 2.0 (the "License"); 5539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott * you may not use this file except in compliance with the License. 6539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott * You may obtain a copy of the License at 7539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott * 8539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott * http://www.apache.org/licenses/LICENSE-2.0 9539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott * 10539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott * Unless required by applicable law or agreed to in writing, software 11539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott * distributed under the License is distributed on an "AS IS" BASIS, 12539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott * See the License for the specific language governing permissions and 14539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott * limitations under the License. 15539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott */ 16539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott 17539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scottpackage com.android.browser; 18539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott 19539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scottimport android.accounts.Account; 20539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scottimport android.accounts.AccountManager; 21539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scottimport android.accounts.AccountManagerCallback; 22539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scottimport android.accounts.AccountManagerFuture; 23539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scottimport android.app.Activity; 24cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scottimport android.app.ProgressDialog; 25539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scottimport android.content.Context; 26539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scottimport android.content.DialogInterface; 27539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scottimport android.content.DialogInterface.OnCancelListener; 28cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scottimport android.content.SharedPreferences.Editor; 29539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scottimport android.net.Uri; 300fba5d9470f3b98d5aa61ae7392164450baf73deMichael Kolbimport android.net.http.AndroidHttpClient; 31539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scottimport android.os.Bundle; 32a4af6dce2ebe6c4979524461047fcc0eb76fce84Patrick Scottimport android.util.Log; 33ef18de60e02b4b2a7227d9e9751487cc74baec36Patrick Scottimport android.webkit.CookieSyncManager; 34539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scottimport android.webkit.WebView; 35539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scottimport android.webkit.WebViewClient; 36539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott 37ba287c2673922ac51c4e4258224574411c0117e1John Reckimport org.apache.http.HttpEntity; 38ba287c2673922ac51c4e4258224574411c0117e1John Reckimport org.apache.http.HttpResponse; 39ba287c2673922ac51c4e4258224574411c0117e1John Reckimport org.apache.http.HttpStatus; 40ba287c2673922ac51c4e4258224574411c0117e1John Reckimport org.apache.http.client.methods.HttpPost; 41ba287c2673922ac51c4e4258224574411c0117e1John Reckimport org.apache.http.util.EntityUtils; 42ba287c2673922ac51c4e4258224574411c0117e1John Reck 437d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scottpublic class GoogleAccountLogin implements Runnable, 44539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott AccountManagerCallback<Bundle>, OnCancelListener { 45539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott 46a4af6dce2ebe6c4979524461047fcc0eb76fce84Patrick Scott private static final String LOGTAG = "BrowserLogin"; 47a4af6dce2ebe6c4979524461047fcc0eb76fce84Patrick Scott 48539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott // Url for issuing the uber token. 49539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott private Uri ISSUE_AUTH_TOKEN_URL = Uri.parse( 50539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott "https://www.google.com/accounts/IssueAuthToken?service=gaia&Session=false"); 51539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott // Url for signing into a particular service. 52a4af6dce2ebe6c4979524461047fcc0eb76fce84Patrick Scott private static final Uri TOKEN_AUTH_URL = Uri.parse( 53539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott "https://www.google.com/accounts/TokenAuth"); 54539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott // Google account type 55a4af6dce2ebe6c4979524461047fcc0eb76fce84Patrick Scott private static final String GOOGLE = "com.google"; 56cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott // Last auto login time 57ba287c2673922ac51c4e4258224574411c0117e1John Reck public static final String PREF_AUTOLOGIN_TIME = "last_autologin_time"; 58539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott 59539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott private final Activity mActivity; 60539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott private final Account mAccount; 61539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott private final WebView mWebView; 62539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott private Runnable mRunnable; 63cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott private ProgressDialog mProgressDialog; 64539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott 65539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott // SID and LSID retrieval process. 66539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott private String mSid; 67539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott private String mLsid; 68539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott private int mState; // {NONE(0), SID(1), LSID(2)} 697d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott private boolean mTokensInvalidated; 709bbd9314fee5f284ff254d7063c30d147fe47454Ben Murdoch private String mUserAgent; 71539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott 72d43e75adea6f394730828cbf830438e2bddaed4bPatrick Scott private GoogleAccountLogin(Activity activity, Account account, 73cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott Runnable runnable) { 74539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott mActivity = activity; 75d43e75adea6f394730828cbf830438e2bddaed4bPatrick Scott mAccount = account; 76539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott mWebView = new WebView(mActivity); 77cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott mRunnable = runnable; 789bbd9314fee5f284ff254d7063c30d147fe47454Ben Murdoch mUserAgent = mWebView.getSettings().getUserAgentString(); 79cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott 80ef18de60e02b4b2a7227d9e9751487cc74baec36Patrick Scott // XXX: Doing pre-login causes onResume to skip calling 81ef18de60e02b4b2a7227d9e9751487cc74baec36Patrick Scott // resumeWebViewTimers. So to avoid problems with timers not running, we 82ef18de60e02b4b2a7227d9e9751487cc74baec36Patrick Scott // duplicate the work here using the off-screen WebView. 83ef18de60e02b4b2a7227d9e9751487cc74baec36Patrick Scott CookieSyncManager.getInstance().startSync(); 84e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood WebViewTimersControl.getInstance().onBrowserActivityResume(mWebView); 85ef18de60e02b4b2a7227d9e9751487cc74baec36Patrick Scott 86539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott mWebView.setWebViewClient(new WebViewClient() { 87539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott @Override 88539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott public boolean shouldOverrideUrlLoading(WebView view, String url) { 89539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott return false; 90539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } 91539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott @Override 92539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott public void onPageFinished(WebView view, String url) { 93539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott done(); 94539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } 95539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott }); 96539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } 97539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott 98cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott private void saveLoginTime() { 99ba287c2673922ac51c4e4258224574411c0117e1John Reck Editor ed = BrowserSettings.getInstance().getPreferences().edit(); 100cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott ed.putLong(PREF_AUTOLOGIN_TIME, System.currentTimeMillis()); 101cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott ed.apply(); 102cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott } 103cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott 1047d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott // Runnable 105539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott @Override 106539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott public void run() { 107539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott String url = ISSUE_AUTH_TOKEN_URL.buildUpon() 108539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott .appendQueryParameter("SID", mSid) 109539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott .appendQueryParameter("LSID", mLsid) 110539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott .build().toString(); 111539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott // Intentionally not using Proxy. 1129bbd9314fee5f284ff254d7063c30d147fe47454Ben Murdoch AndroidHttpClient client = AndroidHttpClient.newInstance(mUserAgent); 113539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott HttpPost request = new HttpPost(url); 114539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott 115539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott String result = null; 116539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott try { 117539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott HttpResponse response = client.execute(request); 1187d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott int status = response.getStatusLine().getStatusCode(); 1197d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott if (status != HttpStatus.SC_OK) { 120a4af6dce2ebe6c4979524461047fcc0eb76fce84Patrick Scott Log.d(LOGTAG, "LOGIN_FAIL: Bad status from auth url " 1217d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott + status + ": " 122a4af6dce2ebe6c4979524461047fcc0eb76fce84Patrick Scott + response.getStatusLine().getReasonPhrase()); 1237d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott // Invalidate the tokens once just in case the 403 was for other 1247d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott // reasons. 1257d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott if (status == HttpStatus.SC_FORBIDDEN && !mTokensInvalidated) { 1267d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott Log.d(LOGTAG, "LOGIN_FAIL: Invalidating tokens..."); 1277d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott // Need to regenerate the auth tokens and try again. 1287d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott invalidateTokens(); 1297d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott // XXX: Do not touch any more member variables from this 1307d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott // thread as a second thread will handle the next login 1317d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott // attempt. 1327d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott return; 1337d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott } 134539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott done(); 135539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott return; 136539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } 137539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott HttpEntity entity = response.getEntity(); 138539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott if (entity == null) { 139a4af6dce2ebe6c4979524461047fcc0eb76fce84Patrick Scott Log.d(LOGTAG, "LOGIN_FAIL: Null entity in response"); 140539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott done(); 141539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott return; 142539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } 143539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott result = EntityUtils.toString(entity, "UTF-8"); 144539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } catch (Exception e) { 145a4af6dce2ebe6c4979524461047fcc0eb76fce84Patrick Scott Log.d(LOGTAG, "LOGIN_FAIL: Exception acquiring uber token " + e); 146539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott request.abort(); 147539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott done(); 148539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott return; 149539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } finally { 150539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott client.close(); 151539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } 152539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott final String newUrl = TOKEN_AUTH_URL.buildUpon() 153539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott .appendQueryParameter("source", "android-browser") 154539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott .appendQueryParameter("auth", result) 155539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott .appendQueryParameter("continue", 156539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott BrowserSettings.getFactoryResetHomeUrl(mActivity)) 157539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott .build().toString(); 158539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott mActivity.runOnUiThread(new Runnable() { 159539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott @Override public void run() { 160081caaa34ab5af0694087c3203e39be25797455aPatrick Scott // Check mRunnable in case the request has been canceled. This 161081caaa34ab5af0694087c3203e39be25797455aPatrick Scott // is most likely not necessary as run() is the only non-UI 162081caaa34ab5af0694087c3203e39be25797455aPatrick Scott // thread that calls done() but I am paranoid. 163081caaa34ab5af0694087c3203e39be25797455aPatrick Scott synchronized (GoogleAccountLogin.this) { 164081caaa34ab5af0694087c3203e39be25797455aPatrick Scott if (mRunnable == null) { 165081caaa34ab5af0694087c3203e39be25797455aPatrick Scott return; 166081caaa34ab5af0694087c3203e39be25797455aPatrick Scott } 167081caaa34ab5af0694087c3203e39be25797455aPatrick Scott mWebView.loadUrl(newUrl); 168081caaa34ab5af0694087c3203e39be25797455aPatrick Scott } 169539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } 170539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott }); 171539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } 172539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott 1737d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott private void invalidateTokens() { 1747d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott AccountManager am = AccountManager.get(mActivity); 1757d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott am.invalidateAuthToken(GOOGLE, mSid); 1767d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott am.invalidateAuthToken(GOOGLE, mLsid); 1777d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott mTokensInvalidated = true; 1787d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott mState = 1; // SID 1797d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott am.getAuthToken(mAccount, "SID", null, mActivity, this, null); 1807d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott } 1817d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott 182539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott // AccountManager callbacks. 183539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott @Override 184539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott public void run(AccountManagerFuture<Bundle> value) { 185539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott try { 186539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott String id = value.getResult().getString( 187539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott AccountManager.KEY_AUTHTOKEN); 188539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott switch (mState) { 189539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott default: 190539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott case 0: 191539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott throw new IllegalStateException( 192539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott "Impossible to get into this state"); 193539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott case 1: 194539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott mSid = id; 195539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott mState = 2; // LSID 196539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott AccountManager.get(mActivity).getAuthToken( 197539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott mAccount, "LSID", null, mActivity, this, null); 198539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott break; 199539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott case 2: 200539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott mLsid = id; 2017d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott new Thread(this).start(); 202539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott break; 203539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } 204539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } catch (Exception e) { 205a4af6dce2ebe6c4979524461047fcc0eb76fce84Patrick Scott Log.d(LOGTAG, "LOGIN_FAIL: Exception in state " + mState + " " + e); 206539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott // For all exceptions load the original signin page. 207539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott // TODO: toast login failed? 208539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott done(); 209539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } 210539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } 211539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott 212cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott // Start the login process if auto-login is enabled and the user is not 213cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott // already logged in. 214cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott public static void startLoginIfNeeded(Activity activity, 215d43e75adea6f394730828cbf830438e2bddaed4bPatrick Scott Runnable runnable) { 216d43e75adea6f394730828cbf830438e2bddaed4bPatrick Scott // Already logged in? 217ba287c2673922ac51c4e4258224574411c0117e1John Reck if (isLoggedIn()) { 218cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott runnable.run(); 219cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott return; 220cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott } 221cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott 222cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott // No account found? 223d43e75adea6f394730828cbf830438e2bddaed4bPatrick Scott Account[] accounts = getAccounts(activity); 224d43e75adea6f394730828cbf830438e2bddaed4bPatrick Scott if (accounts == null || accounts.length == 0) { 225cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott runnable.run(); 226cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott return; 227cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott } 228cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott 229cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott GoogleAccountLogin login = 230d43e75adea6f394730828cbf830438e2bddaed4bPatrick Scott new GoogleAccountLogin(activity, accounts[0], runnable); 231cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott login.startLogin(); 232cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott } 233cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott 234cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott private void startLogin() { 235ba287c2673922ac51c4e4258224574411c0117e1John Reck saveLoginTime(); 236cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott mProgressDialog = ProgressDialog.show(mActivity, 237cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott mActivity.getString(R.string.pref_autologin_title), 238cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott mActivity.getString(R.string.pref_autologin_progress, 239cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott mAccount.name), 240cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott true /* indeterminate */, 241cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott true /* cancelable */, 242cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott this); 243539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott mState = 1; // SID 244539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott AccountManager.get(mActivity).getAuthToken( 245539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott mAccount, "SID", null, mActivity, this, null); 246539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } 247539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott 248d43e75adea6f394730828cbf830438e2bddaed4bPatrick Scott private static Account[] getAccounts(Context ctx) { 249539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott return AccountManager.get(ctx).getAccountsByType(GOOGLE); 250539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } 251539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott 252d43e75adea6f394730828cbf830438e2bddaed4bPatrick Scott // Checks if we already did pre-login. 253ba287c2673922ac51c4e4258224574411c0117e1John Reck private static boolean isLoggedIn() { 254cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott // See if we last logged in less than a week ago. 255ba287c2673922ac51c4e4258224574411c0117e1John Reck long lastLogin = BrowserSettings.getInstance().getPreferences() 256ba287c2673922ac51c4e4258224574411c0117e1John Reck .getLong(PREF_AUTOLOGIN_TIME, -1); 257cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott if (lastLogin == -1) { 258cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott return false; 259cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott } 260d43e75adea6f394730828cbf830438e2bddaed4bPatrick Scott return true; 26197efb1e650b356d3fc81ff531544383362759d77Patrick Scott } 26297efb1e650b356d3fc81ff531544383362759d77Patrick Scott 263539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott // Used to indicate that the Browser should continue loading the main page. 264539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott // This can happen on success, error, or timeout. 265539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott private synchronized void done() { 266539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott if (mRunnable != null) { 267a4af6dce2ebe6c4979524461047fcc0eb76fce84Patrick Scott Log.d(LOGTAG, "Finished login attempt for " + mAccount.name); 268539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott mActivity.runOnUiThread(mRunnable); 269cd135089d54a8c003f7b0a35d88b3230f0a206b5Patrick Scott 270cf1df73719e171915eed887a5f06916158e42f04John Reck try { 271cf1df73719e171915eed887a5f06916158e42f04John Reck mProgressDialog.dismiss(); 272cf1df73719e171915eed887a5f06916158e42f04John Reck } catch (Exception e) { 273cf1df73719e171915eed887a5f06916158e42f04John Reck // TODO: Switch to a managed dialog solution (DialogFragment?) 274cf1df73719e171915eed887a5f06916158e42f04John Reck // Also refactor this class, it doesn't 275cf1df73719e171915eed887a5f06916158e42f04John Reck // play nice with the activity lifecycle, leading to issues 276cf1df73719e171915eed887a5f06916158e42f04John Reck // with the dialog it manages 277cf1df73719e171915eed887a5f06916158e42f04John Reck Log.w(LOGTAG, "Failed to dismiss mProgressDialog: " + e.getMessage()); 278cf1df73719e171915eed887a5f06916158e42f04John Reck } 279539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott mRunnable = null; 280474c927a76d4a6b12e942ba4bde3a7db18a1a332John Reck mActivity.runOnUiThread(new Runnable() { 281474c927a76d4a6b12e942ba4bde3a7db18a1a332John Reck @Override 282474c927a76d4a6b12e942ba4bde3a7db18a1a332John Reck public void run() { 283474c927a76d4a6b12e942ba4bde3a7db18a1a332John Reck mWebView.destroy(); 284474c927a76d4a6b12e942ba4bde3a7db18a1a332John Reck } 285474c927a76d4a6b12e942ba4bde3a7db18a1a332John Reck }); 286539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } 287539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } 288539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott 289539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott // Called by the progress dialog on startup. 290539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott public void onCancel(DialogInterface unused) { 291539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott done(); 292539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott } 2930fba5d9470f3b98d5aa61ae7392164450baf73deMichael Kolb 294539e2eced0f35144d7841477e5cdc2d8c521e82aPatrick Scott} 295