From c73ceeed0f97cdf584bf28e1f748fed7bf48ab25 Mon Sep 17 00:00:00 2001 From: Jeff Hamilton Date: Thu, 16 Sep 2010 12:52:34 -0500 Subject: Don't crash when creating a bookmark. Bug: 3007425 Change-Id: I9c802b05952791c205fa2f7d1f0add0272bda10f --- src/com/android/browser/provider/BrowserProvider2.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/browser/provider/BrowserProvider2.java b/src/com/android/browser/provider/BrowserProvider2.java index a633941..0112343 100644 --- a/src/com/android/browser/provider/BrowserProvider2.java +++ b/src/com/android/browser/provider/BrowserProvider2.java @@ -797,7 +797,7 @@ public class BrowserProvider2 extends SQLiteContentProvider { // Extract out the image values so they can be inserted into the images table String url = values.getAsString(Bookmarks.URL); ContentValues imageValues = extractImageValues(values, url); - boolean isFolder = values.getAsBoolean(Bookmarks.IS_FOLDER); + boolean isFolder = (values.getAsInteger(Bookmarks.IS_FOLDER) != 0); if (!isFolder && imageValues != null && !TextUtils.isEmpty(url)) { db.insertOrThrow(TABLE_IMAGES, Images.FAVICON, imageValues); } -- cgit v1.1 From 603825c895f6ae943274656bc345cb5a246dae4c Mon Sep 17 00:00:00 2001 From: Ying Wang Date: Tue, 23 Nov 2010 11:17:46 -0800 Subject: Move icons to mipmap. Change-Id: If6356ccfe3ae6b791f82157488b9a78c1724cef6 --- AndroidManifest.xml | 4 ++-- res/drawable-hdpi/ic_launcher_browser.png | Bin 7531 -> 0 bytes .../ic_launcher_shortcut_browser_bookmark.png | Bin 3328 -> 0 bytes res/drawable-mdpi/ic_launcher_browser.png | Bin 4142 -> 0 bytes .../ic_launcher_shortcut_browser_bookmark.png | Bin 2160 -> 0 bytes res/layout/bookmarklistwidget.xml | 2 +- res/mipmap-hdpi/ic_launcher_browser.png | Bin 0 -> 7531 bytes .../ic_launcher_shortcut_browser_bookmark.png | Bin 0 -> 3328 bytes res/mipmap-mdpi/ic_launcher_browser.png | Bin 0 -> 4142 bytes .../ic_launcher_shortcut_browser_bookmark.png | Bin 0 -> 2160 bytes src/com/android/browser/BookmarkUtils.java | 4 ++-- 11 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 res/drawable-hdpi/ic_launcher_browser.png delete mode 100644 res/drawable-hdpi/ic_launcher_shortcut_browser_bookmark.png delete mode 100755 res/drawable-mdpi/ic_launcher_browser.png delete mode 100644 res/drawable-mdpi/ic_launcher_shortcut_browser_bookmark.png create mode 100644 res/mipmap-hdpi/ic_launcher_browser.png create mode 100644 res/mipmap-hdpi/ic_launcher_shortcut_browser_bookmark.png create mode 100755 res/mipmap-mdpi/ic_launcher_browser.png create mode 100644 res/mipmap-mdpi/ic_launcher_shortcut_browser_bookmark.png diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 9fea44a..b653461 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -39,7 +39,7 @@ @@ -147,7 +147,7 @@ + android:icon="@mipmap/ic_launcher_shortcut_browser_bookmark"> diff --git a/res/drawable-hdpi/ic_launcher_browser.png b/res/drawable-hdpi/ic_launcher_browser.png deleted file mode 100644 index 2ca92c8..0000000 Binary files a/res/drawable-hdpi/ic_launcher_browser.png and /dev/null differ diff --git a/res/drawable-hdpi/ic_launcher_shortcut_browser_bookmark.png b/res/drawable-hdpi/ic_launcher_shortcut_browser_bookmark.png deleted file mode 100644 index 7b2c680..0000000 Binary files a/res/drawable-hdpi/ic_launcher_shortcut_browser_bookmark.png and /dev/null differ diff --git a/res/drawable-mdpi/ic_launcher_browser.png b/res/drawable-mdpi/ic_launcher_browser.png deleted file mode 100755 index f9d6172..0000000 Binary files a/res/drawable-mdpi/ic_launcher_browser.png and /dev/null differ diff --git a/res/drawable-mdpi/ic_launcher_shortcut_browser_bookmark.png b/res/drawable-mdpi/ic_launcher_shortcut_browser_bookmark.png deleted file mode 100644 index aa05683..0000000 Binary files a/res/drawable-mdpi/ic_launcher_shortcut_browser_bookmark.png and /dev/null differ diff --git a/res/layout/bookmarklistwidget.xml b/res/layout/bookmarklistwidget.xml index 983854c..17aee1d 100644 --- a/res/layout/bookmarklistwidget.xml +++ b/res/layout/bookmarklistwidget.xml @@ -33,7 +33,7 @@ android:id="@+id/logo" android:layout_width="32dp" android:layout_height="32dp" - android:src="@drawable/ic_launcher_browser" /> + android:src="@mipmap/ic_launcher_browser" /> Date: Thu, 13 Jan 2011 09:54:49 -0800 Subject: Merge "Fix 3337625 to follow link to Google Images" into honeycomb --- src/com/android/browser/UrlHandler.java | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/com/android/browser/UrlHandler.java b/src/com/android/browser/UrlHandler.java index cd0afeb..f39ac4b 100644 --- a/src/com/android/browser/UrlHandler.java +++ b/src/com/android/browser/UrlHandler.java @@ -120,7 +120,7 @@ public class UrlHandler { // AsyncTask. Although we are not overriding the URL load synchronously, // we guarantee that we will handle this URL load after the task executes, // so it's safe to just return true to WebCore now to stop its own loading. - new RLZTask(siteUri, view).execute(); + new RLZTask(tab, siteUri, view).execute(); return true; } } @@ -137,9 +137,7 @@ public class UrlHandler { return true; } - if (mController.isMenuDown()) { - mController.openTab(tab, url, false); - mActivity.closeOptionsMenu(); + if (handleMenuClick(tab, url)) { return true; } @@ -198,6 +196,19 @@ public class UrlHandler { return false; } + // In case a physical keyboard is attached, handle clicks with the menu key + // depressed by opening in a new tab + boolean handleMenuClick(Tab tab, String url) + { + if (mController.isMenuDown()) { + mController.openTab(tab, url, false); + mActivity.closeOptionsMenu(); + return true; + } + + return false; + } + // Url for issuing the uber token. private final static Uri ISSUE_AUTH_TOKEN_URL = Uri.parse( "https://www.google.com/accounts/IssueAuthToken?service=gaia&Session=false"); @@ -355,10 +366,12 @@ public class UrlHandler { } private class RLZTask extends AsyncTask { + private Tab mTab; private Uri mSiteUri; private WebView mWebView; - public RLZTask(Uri uri, WebView webView) { + public RLZTask(Tab tab, Uri uri, WebView webView) { + mTab = tab; mSiteUri = uri; mWebView = webView; } @@ -383,7 +396,12 @@ public class UrlHandler { } protected void onPostExecute(String result) { - startActivityForUrl(result); + // If the Activity Manager is not invoked, load the URL directly + if (!startActivityForUrl(result)) { + if (!handleMenuClick(mTab, result)) { + mController.loadUrl(mWebView, result); + } + } } } -- cgit v1.1 From adfea63105f28befb860ad8ca179fba350423336 Mon Sep 17 00:00:00 2001 From: Patrick Scott Date: Thu, 13 Jan 2011 11:27:38 -0500 Subject: Different approach to auto signin. On startup, attempt to log the user into google sites. Show a progress dialog that the user can cancel if login takes too long. Add a new preference for toggling auto signin. This preference shows the current account and allows the user to choose the account to use. If there are no accounts, the option is disabled. The saved account is validated each time it is accessed in case the account was removed. Bug: 3278072 Change-Id: I10ce1dc57a683b2820b17ef6955577037c82f332 --- res/values/strings.xml | 13 +- res/xml/browser_preferences.xml | 216 --------------------- res/xml/privacy_security_preferences.xml | 5 + src/com/android/browser/BrowserActivity.java | 30 ++- src/com/android/browser/BrowserSettings.java | 31 +++ src/com/android/browser/GoogleAccountLogin.java | 199 +++++++++++++++++++ src/com/android/browser/UrlHandler.java | 181 ----------------- .../PrivacySecurityPreferencesFragment.java | 84 ++++++++ 8 files changed, 355 insertions(+), 404 deletions(-) delete mode 100644 res/xml/browser_preferences.xml create mode 100644 src/com/android/browser/GoogleAccountLogin.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 4464370..00a2a46 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -376,6 +376,15 @@ Set up & manage data for AutoFilled forms + + Automatic Google sign-in + + No accounts found + + Sign into Google sites automatically using %s + + Signing into Google sites using %s + AutoFill will use your profile to help you complete web forms in a single click. @@ -909,8 +918,4 @@ reached. [CHAR LIMIT=50] --> No more tabs available - - Choose an account or cancel to login - manually - diff --git a/res/xml/browser_preferences.xml b/res/xml/browser_preferences.xml deleted file mode 100644 index 1c04528..0000000 --- a/res/xml/browser_preferences.xml +++ /dev/null @@ -1,216 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/xml/privacy_security_preferences.xml b/res/xml/privacy_security_preferences.xml index 50802ca..54f3ff0 100644 --- a/res/xml/privacy_security_preferences.xml +++ b/res/xml/privacy_security_preferences.xml @@ -39,6 +39,11 @@ android:title="@string/pref_security_show_security_warning" android:summary="@string/pref_security_show_security_warning_summary" /> + + extends AsyncTask { diff --git a/src/com/android/browser/GoogleAccountLogin.java b/src/com/android/browser/GoogleAccountLogin.java new file mode 100644 index 0000000..8ff0972 --- /dev/null +++ b/src/com/android/browser/GoogleAccountLogin.java @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.browser; + +import org.apache.http.Header; +import org.apache.http.HeaderIterator; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.util.EntityUtils; + +import android.accounts.Account; +import android.accounts.AccountManager; +import android.accounts.AccountManagerCallback; +import android.accounts.AccountManagerFuture; +import android.app.Activity; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnCancelListener; +import android.net.http.AndroidHttpClient; +import android.net.Uri; +import android.os.Bundle; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +import java.util.ArrayList; + +public class GoogleAccountLogin extends Thread implements + AccountManagerCallback, OnCancelListener { + + // Url for issuing the uber token. + private Uri ISSUE_AUTH_TOKEN_URL = Uri.parse( + "https://www.google.com/accounts/IssueAuthToken?service=gaia&Session=false"); + // Url for signing into a particular service. + private final static Uri TOKEN_AUTH_URL = Uri.parse( + "https://www.google.com/accounts/TokenAuth"); + // Google account type + private final static String GOOGLE = "com.google"; + + private final Activity mActivity; + private final Account mAccount; + private final WebView mWebView; + private Runnable mRunnable; + + // SID and LSID retrieval process. + private String mSid; + private String mLsid; + private int mState; // {NONE(0), SID(1), LSID(2)} + + GoogleAccountLogin(Activity activity, String name) { + mActivity = activity; + mAccount = new Account(name, GOOGLE); + mWebView = new WebView(mActivity); + mWebView.setWebViewClient(new WebViewClient() { + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + return false; + } + @Override + public void onPageFinished(WebView view, String url) { + done(); + } + }); + } + + // Thread + @Override + public void run() { + String url = ISSUE_AUTH_TOKEN_URL.buildUpon() + .appendQueryParameter("SID", mSid) + .appendQueryParameter("LSID", mLsid) + .build().toString(); + // Intentionally not using Proxy. + AndroidHttpClient client = AndroidHttpClient.newInstance( + mWebView.getSettings().getUserAgentString()); + HttpPost request = new HttpPost(url); + + String result = null; + try { + HttpResponse response = client.execute(request); + if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + done(); + return; + } + HttpEntity entity = response.getEntity(); + if (entity == null) { + done(); + return; + } + result = EntityUtils.toString(entity, "UTF-8"); + } catch (Exception e) { + request.abort(); + done(); + return; + } finally { + client.close(); + } + final String newUrl = TOKEN_AUTH_URL.buildUpon() + .appendQueryParameter("source", "android-browser") + .appendQueryParameter("auth", result) + .appendQueryParameter("continue", + BrowserSettings.getFactoryResetHomeUrl(mActivity)) + .build().toString(); + mActivity.runOnUiThread(new Runnable() { + @Override public void run() { + mWebView.loadUrl(newUrl); + } + }); + } + + // AccountManager callbacks. + @Override + public void run(AccountManagerFuture value) { + try { + String id = value.getResult().getString( + AccountManager.KEY_AUTHTOKEN); + switch (mState) { + default: + case 0: + throw new IllegalStateException( + "Impossible to get into this state"); + case 1: + mSid = id; + mState = 2; // LSID + AccountManager.get(mActivity).getAuthToken( + mAccount, "LSID", null, mActivity, this, null); + break; + case 2: + mLsid = id; + this.start(); + break; + } + } catch (Exception e) { + // For all exceptions load the original signin page. + // TODO: toast login failed? + done(); + } + } + + public void startLogin(Runnable runnable) { + mRunnable = runnable; + mState = 1; // SID + AccountManager.get(mActivity).getAuthToken( + mAccount, "SID", null, mActivity, this, null); + } + + // Returns the account name passed in if the account exists, otherwise + // returns the default account. + public static String validateAccount(Context ctx, String name) { + Account[] accounts = getAccounts(ctx); + if (accounts.length == 0) { + return null; + } + if (name != null) { + // Make sure the account still exists. + for (Account a : accounts) { + if (a.name.equals(name)) { + return name; + } + } + } + // Return the first entry. + return accounts[0].name; + } + + public static Account[] getAccounts(Context ctx) { + return AccountManager.get(ctx).getAccountsByType(GOOGLE); + } + + // Used to indicate that the Browser should continue loading the main page. + // This can happen on success, error, or timeout. + private synchronized void done() { + if (mRunnable != null) { + mActivity.runOnUiThread(mRunnable); + mRunnable = null; + mWebView.destroy(); + } + } + + // Called by the progress dialog on startup. + public void onCancel(DialogInterface unused) { + done(); + } +} diff --git a/src/com/android/browser/UrlHandler.java b/src/com/android/browser/UrlHandler.java index f39ac4b..9e41990 100644 --- a/src/com/android/browser/UrlHandler.java +++ b/src/com/android/browser/UrlHandler.java @@ -16,29 +16,12 @@ package com.android.browser; -import org.apache.http.Header; -import org.apache.http.HeaderIterator; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.util.EntityUtils; - -import android.accounts.Account; -import android.accounts.AccountManager; -import android.accounts.AccountManagerCallback; -import android.accounts.AccountManagerFuture; import android.app.Activity; -import android.app.AlertDialog; import android.content.ActivityNotFoundException; -import android.content.DialogInterface; -import android.content.DialogInterface.OnCancelListener; -import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; -import android.net.http.AndroidHttpClient; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; @@ -125,14 +108,6 @@ public class UrlHandler { } } - // Check for service login and prompt the user for an account to use. - if (url.startsWith("https://www.google.com/accounts/ServiceLogin?") || - url.startsWith("https://www.google.com/accounts/Login?")) { - if (loginWithDeviceAccount(view, url)) { - return true; - } - } - if (startActivityForUrl(url)) { return true; } @@ -209,162 +184,6 @@ public class UrlHandler { return false; } - // Url for issuing the uber token. - private final static Uri ISSUE_AUTH_TOKEN_URL = Uri.parse( - "https://www.google.com/accounts/IssueAuthToken?service=gaia&Session=false"); - // Url for signing into a particular service. - private final static Uri TOKEN_AUTH_URL = Uri.parse( - "https://www.google.com/accounts/TokenAuth"); - - private class GoogleServiceLogin extends Thread implements - AccountManagerCallback, OnClickListener, OnCancelListener { - // For choosing the account. - private final Account[] mAccounts; - private int mCurrentAccount; // initially 0 for the first account - - // For loading the auth token urls or the original url on error. - private final WebView mWebView; - private final String mUrl; - - // SID and LSID retrieval process. - private String mSid; - private String mLsid; - private int mState; // {NONE(0), SID(1), LSID(2)} - - GoogleServiceLogin(Account[] accounts, WebView view, String url) { - mAccounts = accounts; - mWebView = view; - mUrl = url; - } - - // Thread - public void run() { - String url = ISSUE_AUTH_TOKEN_URL.buildUpon() - .appendQueryParameter("SID", mSid) - .appendQueryParameter("LSID", mLsid) - .build().toString(); - // Intentionally not using Proxy. - AndroidHttpClient client = AndroidHttpClient.newInstance( - mWebView.getSettings().getUserAgentString()); - HttpPost request = new HttpPost(url); - - String result = null; - try { - HttpResponse response = client.execute(request); - if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { - onCancel(null); - return; - } - HttpEntity entity = response.getEntity(); - if (entity == null) { - onCancel(null); - return; - } - result = EntityUtils.toString(entity, "UTF-8"); - } catch (Exception e) { - request.abort(); - onCancel(null); - } finally { - client.close(); - } - Uri parsedUri = Uri.parse(mUrl); - String service = parsedUri.getQueryParameter("service"); - String redirect = parsedUri.getQueryParameter("continue"); - final String newUrl = TOKEN_AUTH_URL.buildUpon() - .appendQueryParameter("service", service) - .appendQueryParameter("source", "android-browser") - .appendQueryParameter("auth", result) - .appendQueryParameter("continue", redirect) - .build().toString(); - mActivity.runOnUiThread(new Runnable() { - @Override public void run() { - mController.loadUrl(mWebView, newUrl); - } - }); - } - - // AccountManager callbacks. - public void run(AccountManagerFuture value) { - try { - String id = value.getResult().getString( - AccountManager.KEY_AUTHTOKEN); - switch (mState) { - default: - case 0: - throw new IllegalStateException( - "Impossible to get into this state"); - case 1: - mSid = id; - mState = 2; // LSID - AccountManager.get(mActivity).getAuthToken( - mAccounts[mCurrentAccount], "LSID", null, - mActivity, this, null); - break; - case 2: - mLsid = id; - this.start(); - break; - } - } catch (Exception e) { - // For all exceptions load the original signin page. - // TODO: toast login failed? - onCancel(null); - } - } - - // Handle picking an account and "OK." - public void onClick(DialogInterface unused, int which) { - if (which == DialogInterface.BUTTON_POSITIVE) { - // TODO: toast loading...? - Account current = mAccounts[mCurrentAccount]; - mState = 1; // SID - AccountManager.get(mActivity).getAuthToken( - mAccounts[mCurrentAccount], "SID", null, - mActivity, this, null); - } else if (which == DialogInterface.BUTTON_NEGATIVE) { - onCancel(null); - } else { - mCurrentAccount = which; - } - } - - // Handle "cancel." - public void onCancel(DialogInterface unusued) { - // load the original url to login manually. - mController.loadUrl(mWebView, mUrl); - } - } - - private boolean loginWithDeviceAccount(WebView view, String url) { - Uri parsedUri = Uri.parse(url); - if ("true".equals(parsedUri.getQueryParameter("go"))) { - return false; - } - Account[] accounts = - AccountManager.get(mActivity).getAccountsByType("com.google"); - if (accounts.length == 0) { - return false; - } - - // Populate the account list. - CharSequence[] names = new CharSequence[accounts.length]; - int i = 0; - for (Account a : accounts) { - names[i++] = a.name; - } - - GoogleServiceLogin login = new GoogleServiceLogin(accounts, view, url); - new AlertDialog.Builder(mActivity) - .setTitle(R.string.account_picker_title) - .setSingleChoiceItems(names, 0 /* first choice */, login) - .setPositiveButton(R.string.ok, login) - .setNegativeButton(R.string.cancel, login) - .setCancelable(true) - .setOnCancelListener(login) - .show(); - return true; - } - private class RLZTask extends AsyncTask { private Tab mTab; private Uri mSiteUri; diff --git a/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java b/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java index 8a5178c..20d4f42 100644 --- a/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java +++ b/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java @@ -17,26 +17,50 @@ package com.android.browser.preferences; import com.android.browser.BrowserSettings; +import com.android.browser.GoogleAccountLogin; import com.android.browser.R; +import android.accounts.Account; import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.os.Bundle; +import android.preference.CheckBoxPreference; import android.preference.Preference; import android.preference.PreferenceFragment; public class PrivacySecurityPreferencesFragment extends PreferenceFragment implements Preference.OnPreferenceChangeListener { + private BrowserSettings mSettings; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + mSettings = BrowserSettings.getInstance(); + // Load the preferences from an XML resource addPreferencesFromResource(R.xml.privacy_security_preferences); Preference e = findPreference(BrowserSettings.PREF_CLEAR_HISTORY); e.setOnPreferenceChangeListener(this); + e = findPreference(BrowserSettings.PREF_AUTOLOGIN); + e.setOnPreferenceChangeListener(this); + updateAutoLoginSummary((CheckBoxPreference) e); + } + + private void updateAutoLoginSummary(CheckBoxPreference pref) { + String account = mSettings.getAutoLoginAccount(getActivity()); + if (account == null) { + pref.setChecked(false); + pref.setEnabled(false); + pref.setSummary(R.string.pref_autologin_no_account); + } else { + pref.setSummary(getString(R.string.pref_autologin_summary, account)); + } } @Override @@ -48,8 +72,68 @@ public class PrivacySecurityPreferencesFragment extends PreferenceFragment getActivity().setResult(Activity.RESULT_OK, (new Intent()).putExtra(Intent.EXTRA_TEXT, pref.getKey())); return true; + } else if (pref.getKey().equals(BrowserSettings.PREF_AUTOLOGIN)) { + boolean val = ((Boolean) objValue).booleanValue(); + if (val) { + selectAccount((CheckBoxPreference) pref); + return false; + } + return true; } return false; } + + class AccountCallback implements OnClickListener { + private final Account[] mAccounts; + private final CheckBoxPreference mPref; + + public AccountCallback(Account[] accounts, CheckBoxPreference pref) { + mAccounts = accounts; + mPref = pref; + } + + public void onClick(DialogInterface d, int which) { + saveAutoLoginAccount(mPref, mAccounts[which].name); + d.dismiss(); + } + } + + private void saveAutoLoginAccount(CheckBoxPreference pref, String name) { + mSettings.setAutoLoginAccount(getActivity(), name); + pref.setChecked(true); + updateAutoLoginSummary(pref); + } + + private void selectAccount(CheckBoxPreference pref) { + Account[] accounts = GoogleAccountLogin.getAccounts(getActivity()); + if (accounts.length == 0) { + mSettings.setAutoLoginAccount(getActivity(), null); + updateAutoLoginSummary(pref); + return; + } else if (accounts.length == 1) { + // No need for a dialog with one account. + saveAutoLoginAccount(pref, accounts[0].name); + return; + } + + String account = mSettings.getAutoLoginAccount(getActivity()); + CharSequence[] names = new CharSequence[accounts.length]; + int i = 0; + int defaultAccount = 0; + for (Account a : accounts) { + if (a.name.equals(account)) { + defaultAccount = i; + } + names[i++] = a.name; + } + + AccountCallback callback = + new AccountCallback(accounts, pref); + new AlertDialog.Builder(getActivity()) + .setTitle(R.string.pref_autologin_title) + .setSingleChoiceItems(names, defaultAccount, callback) + .setCancelable(true) + .show(); + } } -- cgit v1.1 From 6d316d10f2db5d71f4c7dc37baba172f026aa6f5 Mon Sep 17 00:00:00 2001 From: Patrick Scott Date: Thu, 13 Jan 2011 12:06:58 -0800 Subject: Merge "Skip auto sign-in if the user is already logged in." into honeycomb --- src/com/android/browser/BrowserActivity.java | 14 ++++++++++++-- src/com/android/browser/GoogleAccountLogin.java | 19 ++++++++++++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java index 0fce014..018744d 100644 --- a/src/com/android/browser/BrowserActivity.java +++ b/src/com/android/browser/BrowserActivity.java @@ -26,6 +26,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.PixelFormat; import android.os.Bundle; +import android.os.Handler; import android.util.Log; import android.view.ActionMode; import android.view.ContextMenu; @@ -115,7 +116,8 @@ public class BrowserActivity extends Activity { } String account = settings.getAutoLoginAccount(this); - if (settings.isAutoLoginEnabled() && account != null) { + if (settings.isAutoLoginEnabled() && account != null && + !GoogleAccountLogin.isLoggedIn()) { GoogleAccountLogin login = new GoogleAccountLogin(this, account); final ProgressDialog dialog = ProgressDialog.show(this, @@ -125,9 +127,17 @@ public class BrowserActivity extends Activity { true /* cancelable */, login); final Bundle b = icicle; - final Runnable start = new Runnable() { + final Handler handler = new Handler(); + final Runnable dismiss = new Runnable() { @Override public void run() { dialog.dismiss(); + } + }; + final Runnable start = new Runnable() { + @Override public void run() { + // Post a delayed dismiss message to avoid a flash of the + // progress dialog. + handler.postDelayed(dismiss, 1000); mController.start(b, getIntent()); } }; diff --git a/src/com/android/browser/GoogleAccountLogin.java b/src/com/android/browser/GoogleAccountLogin.java index 8ff0972..04b3957 100644 --- a/src/com/android/browser/GoogleAccountLogin.java +++ b/src/com/android/browser/GoogleAccountLogin.java @@ -35,10 +35,11 @@ import android.content.DialogInterface.OnCancelListener; import android.net.http.AndroidHttpClient; import android.net.Uri; import android.os.Bundle; +import android.webkit.CookieManager; import android.webkit.WebView; import android.webkit.WebViewClient; -import java.util.ArrayList; +import java.util.StringTokenizer; public class GoogleAccountLogin extends Thread implements AccountManagerCallback, OnCancelListener { @@ -182,6 +183,22 @@ public class GoogleAccountLogin extends Thread implements return AccountManager.get(ctx).getAccountsByType(GOOGLE); } + // Checks for the presence of the SID cookie on google.com. + public static boolean isLoggedIn() { + String cookies = CookieManager.getInstance().getCookie( + "http://www.google.com"); + if (cookies != null) { + StringTokenizer tokenizer = new StringTokenizer(cookies, ";"); + while (tokenizer.hasMoreTokens()) { + String cookie = tokenizer.nextToken().trim(); + if (cookie.startsWith("SID=")) { + return true; + } + } + } + return false; + } + // Used to indicate that the Browser should continue loading the main page. // This can happen on success, error, or timeout. private synchronized void done() { -- cgit v1.1 From 430329f9e07bdeb8d3a17099b34a1c659a836f62 Mon Sep 17 00:00:00 2001 From: Patrick Scott Date: Tue, 18 Jan 2011 08:50:20 -0500 Subject: Protect access to mWebView by checking mRunnable. If the user cancels the login event, mRunnable will be reset and the WebView destroyed. Check for a null mRunnable before accessing mWebView. Bug: 3361009 Bug: 3349815 Change-Id: Idd9a2b788673d9ec95bfa083a4af7df705c22fcd --- src/com/android/browser/GoogleAccountLogin.java | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/com/android/browser/GoogleAccountLogin.java b/src/com/android/browser/GoogleAccountLogin.java index 04b3957..855c407 100644 --- a/src/com/android/browser/GoogleAccountLogin.java +++ b/src/com/android/browser/GoogleAccountLogin.java @@ -86,9 +86,17 @@ public class GoogleAccountLogin extends Thread implements .appendQueryParameter("SID", mSid) .appendQueryParameter("LSID", mLsid) .build().toString(); + // Check mRunnable to see if the request has been canceled. Otherwise + // we might access a destroyed WebView. + String ua = null; + synchronized (this) { + if (mRunnable == null) { + return; + } + ua = mWebView.getSettings().getUserAgentString(); + } // Intentionally not using Proxy. - AndroidHttpClient client = AndroidHttpClient.newInstance( - mWebView.getSettings().getUserAgentString()); + AndroidHttpClient client = AndroidHttpClient.newInstance(ua); HttpPost request = new HttpPost(url); String result = null; @@ -119,7 +127,15 @@ public class GoogleAccountLogin extends Thread implements .build().toString(); mActivity.runOnUiThread(new Runnable() { @Override public void run() { - mWebView.loadUrl(newUrl); + // Check mRunnable in case the request has been canceled. This + // is most likely not necessary as run() is the only non-UI + // thread that calls done() but I am paranoid. + synchronized (GoogleAccountLogin.this) { + if (mRunnable == null) { + return; + } + mWebView.loadUrl(newUrl); + } } }); } -- cgit v1.1 From 8235f294c9a2ed3e82352de07719a202aa392478 Mon Sep 17 00:00:00 2001 From: John Reck Date: Fri, 21 Jan 2011 14:18:37 -0800 Subject: Updated assets (app icon & default thumbnail) Bug: 3378251 Change-Id: I1ae4890b9e6fdb60e7a7dca8c4b2f77939655cbe --- res/drawable-mdpi/browser_thumbnail.png | Bin 19418 -> 25024 bytes res/drawable/browser_widget_preview.png | Bin 109140 -> 85506 bytes res/mipmap-hdpi/ic_launcher_browser.png | Bin 7531 -> 11178 bytes res/mipmap-mdpi/ic_launcher_browser.png | Bin 4142 -> 7333 bytes 4 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 res/mipmap-mdpi/ic_launcher_browser.png diff --git a/res/drawable-mdpi/browser_thumbnail.png b/res/drawable-mdpi/browser_thumbnail.png index f596131..f59bec5 100644 Binary files a/res/drawable-mdpi/browser_thumbnail.png and b/res/drawable-mdpi/browser_thumbnail.png differ diff --git a/res/drawable/browser_widget_preview.png b/res/drawable/browser_widget_preview.png index 4923978..7a2af05 100644 Binary files a/res/drawable/browser_widget_preview.png and b/res/drawable/browser_widget_preview.png differ diff --git a/res/mipmap-hdpi/ic_launcher_browser.png b/res/mipmap-hdpi/ic_launcher_browser.png index 2ca92c8..8a6c206 100644 Binary files a/res/mipmap-hdpi/ic_launcher_browser.png and b/res/mipmap-hdpi/ic_launcher_browser.png differ diff --git a/res/mipmap-mdpi/ic_launcher_browser.png b/res/mipmap-mdpi/ic_launcher_browser.png old mode 100755 new mode 100644 index f9d6172..cb473d3 Binary files a/res/mipmap-mdpi/ic_launcher_browser.png and b/res/mipmap-mdpi/ic_launcher_browser.png differ -- cgit v1.1 From 969857cef695cb2d1edf8bdf90a4a2f322bf5b9b Mon Sep 17 00:00:00 2001 From: Justin Ho Date: Fri, 21 Jan 2011 15:24:35 -0800 Subject: Updated Browser launcher icon Change-Id: Ibdc5e171bff93428f772c54d91c3fe095fad10d2 --- res/mipmap-hdpi/ic_launcher_browser.png | Bin 11178 -> 9418 bytes res/mipmap-mdpi/ic_launcher_browser.png | Bin 7333 -> 5413 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/res/mipmap-hdpi/ic_launcher_browser.png b/res/mipmap-hdpi/ic_launcher_browser.png index 8a6c206..ed7d3ce 100644 Binary files a/res/mipmap-hdpi/ic_launcher_browser.png and b/res/mipmap-hdpi/ic_launcher_browser.png differ diff --git a/res/mipmap-mdpi/ic_launcher_browser.png b/res/mipmap-mdpi/ic_launcher_browser.png index cb473d3..46ad0a0 100644 Binary files a/res/mipmap-mdpi/ic_launcher_browser.png and b/res/mipmap-mdpi/ic_launcher_browser.png differ -- cgit v1.1 From 3ef1906465a9320b8c1bc57f948f64f315ff79b4 Mon Sep 17 00:00:00 2001 From: Dave Burke Date: Tue, 8 Feb 2011 00:11:35 -0800 Subject: Fix ISE in History page (DO NOT MERGE) Corresponding change in master was https://android-git.corp.google.com/g/#change,95446 Bug: 3427773 Change-Id: Iaa7a5620285797cd6d3e15e9f5e058ca553a5951 --- src/com/android/browser/BrowserHistoryPage.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java index 777cfd4..44f358d 100644 --- a/src/com/android/browser/BrowserHistoryPage.java +++ b/src/com/android/browser/BrowserHistoryPage.java @@ -187,7 +187,8 @@ public class BrowserHistoryPage extends Fragment switch (loader.getId()) { case LOADER_HISTORY: { mAdapter.changeCursor(data); - if (mGroupList.getCheckedItemPosition() == ListView.INVALID_POSITION) { + if (!mAdapter.isEmpty() + && mGroupList.getCheckedItemPosition() == ListView.INVALID_POSITION) { selectGroup(0); } -- cgit v1.1 From 5c9dde07d60f72f1955146db64039740bf3068e2 Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Mon, 7 Feb 2011 13:18:24 -0800 Subject: Import revised translations. DO NOT MERGE Change-Id: Ie4157fa59972b091bad51d6c8d5a374f21d72110 --- res/values-es-rUS/strings.xml | 2 +- res/values-pl/strings.xml | 12 ++++++------ res/values-ru/strings.xml | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index fdeb3e4..9958b89 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -64,7 +64,7 @@ "Detener" "Actualizar" "Atrás" - "Reenviar" + "Siguiente" "Aceptar" "Cancelar" "Ubicación" diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index e34bce9..bee5c18 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -161,8 +161,8 @@ "Wszystkie zapisane hasła zostaną usunięte." "Włącz obsługę lokalizacji" "Zezwalaj witrynom na żądanie dostępu do informacji o lokalizacji" - "Wyczyść dostęp do informacji o lokalizacji" - "Usuń ustawienia dostępu do informacji o lokalizacji dla witryn" + "Wyczyść dostęp do lokalizacji" + "Anuluj ustawienia dostępu do lokalizacji dla witryn" "Wyczyść ustawienia dostępu witryn do informacji o lokalizacji" "Ustawienia zabezpieczeń" "Pamiętaj hasła" @@ -189,8 +189,8 @@ "Duże" "Powiększenie domyślne" - "Otwieraj strony w widoku ogólnym" - "Pokaż przegląd nowo otwartych stron" + "Podgląd otwartej strony" + "Po otwarciu nowa strona jest widoczna na całym ekranie" "Ustawienia zaawansowane" "Ustawienia witryn" "Ustawienia zaawansowane dla poszczególnych witryn" @@ -283,10 +283,10 @@ "Zapamiętaj ustawienie" "Ta witryna może uzyskać dostęp do informacji o Twojej lokalizacji. Zmień to ustawienie w menu Ustawienia -> Ustawienia witryn." "Ta witryna nie może uzyskać dostępu do informacji o Twojej lokalizacji. Zmień to ustawienie w menu Ustawienia -> Ustawienia witryn." - "Wyczyść dostęp do informacji o lokalizacji" + "Wyczyść dostęp do lokalizacji" "Ta witryna ma obecnie dostęp do informacji o Twojej lokalizacji" "Ta witryna nie ma obecnie dostępu do informacji o Twojej lokalizacji" - "Wyczyść dostęp do informacji o lokalizacji" + "Wyczyść dostęp do lokalizacji" "Dostęp tej witryny do informacji o lokalizacji zostanie usunięty" "Usuń dostęp" "Anuluj" diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 341dbe0..fd9d614 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -130,9 +130,9 @@ "Открывать в фоновом режиме" "Разрешить плагины" - "Всегда вкл." + "Да" "По требованию" - "Выкл." + "Нет" "Открывать новые окна позади текущего окна" "Домашняя страница" @@ -159,11 +159,11 @@ "Очистить пароли" "Удалить все сохраненные пароли" "Все сохраненные пароли будут удалены." - "Включить местоположение" - "Разрешить сайтам запрашивать доступ к данным о местоположении" - "Удалить данные доступа к местоположению" - "Удалить данные доступа к местоположению для всех сайтов" - "Удалить данные доступа к местоположению для всех сайтов" + "Доступ к геоданным" + "Разрешить сайтам запрашивать доступ к данным о вашем местоположении" + "Закрыть геоданные" + "Очистить список сайтов, имеющих доступ к данным о вашем местоположении" + "Очистить список сайтов, имеющих доступ к данным о вашем местоположении" "Настройки безопасности" "Сохранять пароли" "Сохранять имена пользователей и пароли веб-сайтов" @@ -283,7 +283,7 @@ "Запомнить настройки" "У этого сайта есть доступ к данным о вашем местоположении. Для изменения параметров доступа выберите Настройки -> Настройки веб-сайта" "У этого сайта нет доступа к данным о вашем местоположении. Для изменения параметров доступа выберите Настройки -> Настройки веб-сайта" - "Удалить данные доступа к местоположению" + "Закрыть геоданные" "Этот сайт сейчас имеет доступ к вашему местоположению" "Этот сайт в настоящее время не имеет доступа к вашему местоположению" "Удалить данные доступа к местоположению" -- cgit v1.1 From 134857d9f2bc5b1a3e9d8739436c047d0877a3ff Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Mon, 14 Feb 2011 17:22:00 -0800 Subject: Import revised translations. DO NOT MERGE Change-Id: I82ff880eecf561fc7c60cb4fa6ba848420ef1a33 --- res/values-ja/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 870aac4..862bdab 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -137,7 +137,7 @@ "現在のウィンドウの後ろに新しいウィンドウを開く" "ホームページ設定" "検索エンジンの設定" - "検索エンジンを選択します" + "検索エンジンを選択する" "現在のページを使用" "ページの自動調整" "画面に合わせてウェブページをフォーマットする" -- cgit v1.1