am 8ba13bcb: DO NOT MERGE - Backport RLZ code to GB:   - Cache RLZ parameter   - Set RLZ parameter for address bar searches   - Add broadcast receiver to handle RLZ updates   - Update RLZ parameters in home page and bookmarks Bug: 4436761

* commit '8ba13bcb1ad5ab8b439fcc53d158bdafa327a2e8':
  DO NOT MERGE - Backport RLZ code to GB:   - Cache RLZ parameter   - Set RLZ parameter for address bar searches   - Add broadcast receiver to handle RLZ updates   - Update RLZ parameters in home page and bookmarks Bug: 4436761
diff --git a/res/layout/history_item.xml b/res/layout/history_item.xml
index 4522a75..a0b031a 100644
--- a/res/layout/history_item.xml
+++ b/res/layout/history_item.xml
@@ -19,10 +19,7 @@
         android:layout_height="wrap_content"
         android:minHeight="?android:attr/listPreferredItemHeight"
         android:orientation="horizontal"
-        android:paddingRight="6dip"
         android:paddingLeft="6dip"
-        android:paddingTop="5dip"
-        android:paddingBottom="5dip"
         android:gravity="center_vertical"
         >
     <ImageView android:id="@+id/favicon"
@@ -58,7 +55,8 @@
     </LinearLayout>
     <CheckBox android:id="@+id/star"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
+            android:layout_height="fill_parent"
+            android:paddingRight="6dip"
             android:focusable="false"
             android:button="@android:drawable/btn_star"
             />
diff --git a/res/values/all_search_engines.xml b/res/values/all_search_engines.xml
index 08cf763..c8880c4 100644
--- a/res/values/all_search_engines.xml
+++ b/res/values/all_search_engines.xml
@@ -157,7 +157,7 @@
     <item></item>
   </string-array>
   <string-array name="ask_es" translatable="false">
-    <item>Ask.com Espa&#x00f1a;</item>
+    <item>Ask.com Espa&#x00f1;a</item>
     <item>es.ask.com</item>
     <item>http://es.ask.com/favicon.ico</item>
     <item>http://es.ask.com/web?q={searchTerms}</item>
@@ -357,7 +357,7 @@
     <item>http://api.bing.com/osjson.aspx?query={searchTerms}&amp;language={language}</item>
   </string-array>
   <string-array name="yahoo_es" translatable="false">
-    <item>Yahoo! Espa&#x00f1a;</item>
+    <item>Yahoo! Espa&#x00f1;a</item>
     <item>es.yahoo.com</item>
     <item>http://es.search.yahoo.com/favicon.ico</item>
     <item>http://es.search.yahoo.com/search?ei={inputEncoding}&amp;fr=crmas&amp;p={searchTerms}</item>
diff --git a/src/com/android/browser/AddBookmarkPage.java b/src/com/android/browser/AddBookmarkPage.java
index 1104d5e..594f985 100644
--- a/src/com/android/browser/AddBookmarkPage.java
+++ b/src/com/android/browser/AddBookmarkPage.java
@@ -18,6 +18,7 @@
 
 import android.app.Activity;
 import android.content.ContentResolver;
+import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
 import android.database.Cursor;
@@ -116,7 +117,9 @@
      */
     private class SaveBookmarkRunnable implements Runnable {
         private Message mMessage;
-        public SaveBookmarkRunnable(Message msg) {
+        private Context mContext;
+        public SaveBookmarkRunnable(Context ctx, Message msg) {
+            mContext = ctx;
             mMessage = msg;
         }
         public void run() {
@@ -135,7 +138,7 @@
                 final ContentResolver cr = getContentResolver();
                 Bookmarks.addBookmark(null, cr, url, title, thumbnail, true);
                 if (touchIconUrl != null) {
-                    new DownloadTouchIcon(cr, url).execute(mTouchIconUrl);
+                    new DownloadTouchIcon(mContext, cr, url).execute(mTouchIconUrl);
                 }
                 mMessage.arg1 = 1;
             } catch (IllegalStateException e) {
@@ -237,7 +240,7 @@
             Message msg = Message.obtain(mHandler, SAVE_BOOKMARK);
             msg.setData(bundle);
             // Start a new thread so as to not slow down the UI
-            Thread t = new Thread(new SaveBookmarkRunnable(msg));
+            Thread t = new Thread(new SaveBookmarkRunnable(getApplicationContext(), msg));
             t.start();
             setResult(RESULT_OK);
             LogTag.logBookmarkAdded(url, "bookmarkview");
diff --git a/src/com/android/browser/AddNewBookmark.java b/src/com/android/browser/AddNewBookmark.java
index 5308f6b..5d6a166 100644
--- a/src/com/android/browser/AddNewBookmark.java
+++ b/src/com/android/browser/AddNewBookmark.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.view.LayoutInflater;
-import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
@@ -28,9 +27,7 @@
  // FIXME: Remove BrowserBookmarkItem
 class AddNewBookmark extends LinearLayout {
 
-    private TextView    mTextView;
     private TextView    mUrlText;
-    private ImageView   mImageView;
 
     /**
      *  Instantiate a bookmark item, including a default favicon.
@@ -43,9 +40,7 @@
         setWillNotDraw(false);
         LayoutInflater factory = LayoutInflater.from(context);
         factory.inflate(R.layout.add_new_bookmark, this);
-        mTextView = (TextView) findViewById(R.id.title);
         mUrlText = (TextView) findViewById(R.id.url);
-        mImageView = (ImageView) findViewById(R.id.favicon);
     }
 
     /**
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index 793a43c..3ac2612 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -2283,36 +2283,45 @@
                             StringBuilder sb = new StringBuilder(
                                     Browser.BookmarkColumns.URL + " = ");
                             DatabaseUtils.appendEscapedSQLString(sb, url);
-                            Cursor c = mResolver.query(Browser.BOOKMARKS_URI,
-                                    Browser.HISTORY_PROJECTION,
-                                    sb.toString(),
-                                    null,
-                                    null);
-                            if (c.moveToFirst()) {
-                                // The site has been visited before, so grab the
-                                // info from the database.
-                                Bitmap favicon = null;
-                                Bitmap thumbnail = null;
-                                String linkTitle = c.getString(Browser.
-                                        HISTORY_PROJECTION_TITLE_INDEX);
-                                byte[] data = c.getBlob(Browser.
-                                        HISTORY_PROJECTION_FAVICON_INDEX);
-                                if (data != null) {
-                                    favicon = BitmapFactory.decodeByteArray(
-                                            data, 0, data.length);
+                            Cursor c = null;
+                            try {
+                                c = mResolver.query(Browser.BOOKMARKS_URI,
+                                        Browser.HISTORY_PROJECTION,
+                                        sb.toString(),
+                                        null,
+                                        null);
+                                if (c.moveToFirst()) {
+                                    // The site has been visited before, so grab the
+                                    // info from the database.
+                                    Bitmap favicon = null;
+                                    Bitmap thumbnail = null;
+                                    String linkTitle = c.getString(Browser.
+                                            HISTORY_PROJECTION_TITLE_INDEX);
+                                    byte[] data = c.getBlob(Browser.
+                                            HISTORY_PROJECTION_FAVICON_INDEX);
+                                    if (data != null) {
+                                        favicon = BitmapFactory.decodeByteArray(
+                                                data, 0, data.length);
+                                    }
+                                    data = c.getBlob(Browser.
+                                            HISTORY_PROJECTION_THUMBNAIL_INDEX);
+                                    if (data != null) {
+                                        thumbnail = BitmapFactory.decodeByteArray(
+                                                data, 0, data.length);
+                                    }
+                                    sharePage(BrowserActivity.this,
+                                            linkTitle, url, favicon, thumbnail);
+                                } else {
+                                    Browser.sendString(BrowserActivity.this, url,
+                                            getString(
+                                            R.string.choosertitle_sharevia));
                                 }
-                                data = c.getBlob(Browser.
-                                        HISTORY_PROJECTION_THUMBNAIL_INDEX);
-                                if (data != null) {
-                                    thumbnail = BitmapFactory.decodeByteArray(
-                                            data, 0, data.length);
-                                }
-                                sharePage(BrowserActivity.this,
-                                        linkTitle, url, favicon, thumbnail);
-                            } else {
-                                Browser.sendString(BrowserActivity.this, url,
-                                        getString(
-                                        R.string.choosertitle_sharevia));
+                            } finally {
+                                if (c != null) c.close();
+                            }
+                            // close the cursor after its used
+                            if (c != null) {
+                                c.close();
                             }
                             break;
                         case R.id.copy_link_context_menu_id:
diff --git a/src/com/android/browser/BrowserProvider.java b/src/com/android/browser/BrowserProvider.java
index f8574ed..72ec819 100644
--- a/src/com/android/browser/BrowserProvider.java
+++ b/src/com/android/browser/BrowserProvider.java
@@ -152,7 +152,8 @@
     // 20 -> 21 Added touch_icon
     // 21 -> 22 Remove "clientid"
     // 22 -> 23 Added user_entered
-    private static final int DATABASE_VERSION = 23;
+    // 23 -> 24 Url not allowed to be null anymore.
+    private static final int DATABASE_VERSION = 24;
 
     // Regular expression which matches http://, followed by some stuff, followed by
     // optionally a trailing slash, all matched as separate groups.
@@ -232,7 +233,7 @@
             db.execSQL("CREATE TABLE bookmarks (" +
                     "_id INTEGER PRIMARY KEY," +
                     "title TEXT," +
-                    "url TEXT," +
+                    "url TEXT NOT NULL," +
                     "visits INTEGER," +
                     "date LONG," +
                     "created LONG," +
@@ -284,6 +285,27 @@
             }
             if (oldVersion < 23) {
                 db.execSQL("ALTER TABLE bookmarks ADD COLUMN user_entered INTEGER;");
+            }
+            if (oldVersion < 24) {
+                /* SQLite does not support ALTER COLUMN, hence the lengthy code. */
+                db.execSQL("DELETE FROM bookmarks WHERE url IS NULL;");
+                db.execSQL("ALTER TABLE bookmarks RENAME TO bookmarks_temp;");
+                db.execSQL("CREATE TABLE bookmarks (" +
+                        "_id INTEGER PRIMARY KEY," +
+                        "title TEXT," +
+                        "url TEXT NOT NULL," +
+                        "visits INTEGER," +
+                        "date LONG," +
+                        "created LONG," +
+                        "description TEXT," +
+                        "bookmark INTEGER," +
+                        "favicon BLOB DEFAULT NULL," +
+                        "thumbnail BLOB DEFAULT NULL," +
+                        "touch_icon BLOB DEFAULT NULL," +
+                        "user_entered INTEGER" +
+                        ");");
+                db.execSQL("INSERT INTO bookmarks SELECT * FROM bookmarks_temp;");
+                db.execSQL("DROP TABLE bookmarks_temp;");
             } else {
                 db.execSQL("DROP TABLE IF EXISTS bookmarks");
                 db.execSQL("DROP TABLE IF EXISTS searches");
diff --git a/src/com/android/browser/DownloadTouchIcon.java b/src/com/android/browser/DownloadTouchIcon.java
index b5369ae..e8a912c 100644
--- a/src/com/android/browser/DownloadTouchIcon.java
+++ b/src/com/android/browser/DownloadTouchIcon.java
@@ -19,19 +19,23 @@
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
+import android.content.Context;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.net.http.AndroidHttpClient;
+import android.net.Proxy;
 import android.os.AsyncTask;
 import android.provider.Browser;
 import android.webkit.WebView;
 
 
 import org.apache.http.HttpEntity;
+import org.apache.http.HttpHost;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.params.HttpClientParams;
+import org.apache.http.conn.params.ConnRouteParams;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -43,10 +47,12 @@
     private final String mOriginalUrl;
     private final String mUrl;
     private final String mUserAgent;
+    private final Context mContext;
     /* package */ Tab mTab;
 
-    public DownloadTouchIcon(Tab tab, ContentResolver cr, WebView view) {
+    public DownloadTouchIcon(Tab tab, Context ctx, ContentResolver cr, WebView view) {
         mTab = tab;
+        mContext = ctx;
         mContentResolver = cr;
         // Store these in case they change.
         mOriginalUrl = view.getOriginalUrl();
@@ -54,8 +60,9 @@
         mUserAgent = view.getSettings().getUserAgentString();
     }
 
-    public DownloadTouchIcon(ContentResolver cr, String url) {
+    public DownloadTouchIcon(Context ctx, ContentResolver cr, String url) {
         mTab = null;
+        mContext = ctx;
         mContentResolver = cr;
         mOriginalUrl = null;
         mUrl = url;
@@ -71,6 +78,11 @@
 
             AndroidHttpClient client = AndroidHttpClient.newInstance(
                     mUserAgent);
+            HttpHost httpHost = Proxy.getPreferredHttpHost(mContext, url);
+            if (httpHost != null) {
+                ConnRouteParams.setDefaultProxy(client.getParams(), httpHost);
+            }
+
             HttpGet request = new HttpGet(url);
 
             // Follow redirects
diff --git a/src/com/android/browser/FetchUrlMimeType.java b/src/com/android/browser/FetchUrlMimeType.java
index 1e4debf..62d877e 100644
--- a/src/com/android/browser/FetchUrlMimeType.java
+++ b/src/com/android/browser/FetchUrlMimeType.java
@@ -17,12 +17,15 @@
 package com.android.browser;
 
 import android.content.ContentValues;
+import android.net.Proxy;
 import android.net.Uri;
 import android.net.http.AndroidHttpClient;
 
+import org.apache.http.HttpHost;
 import org.apache.http.HttpResponse;
 import org.apache.http.Header;
 import org.apache.http.client.methods.HttpHead;
+import org.apache.http.conn.params.ConnRouteParams;
 
 import java.io.IOException;
 
@@ -44,7 +47,7 @@
  * android.os.webkit.LoadListener rather than handling it here.
  *
  */
-class FetchUrlMimeType extends AsyncTask<ContentValues, String, String> {
+class FetchUrlMimeType extends AsyncTask<ContentValues, String, ContentValues> {
 
     BrowserActivity mActivity;
     ContentValues mValues;
@@ -54,7 +57,7 @@
     }
 
     @Override
-    public String doInBackground(ContentValues... values) {
+    public ContentValues doInBackground(ContentValues... values) {
         mValues = values[0];
 
         // Check to make sure we have a URI to download
@@ -67,6 +70,10 @@
         // seems ok with that.
         AndroidHttpClient client = AndroidHttpClient.newInstance(
                 mValues.getAsString(Downloads.Impl.COLUMN_USER_AGENT));
+        HttpHost httpHost = Proxy.getPreferredHttpHost(mActivity, uri);
+        if (httpHost != null) {
+            ConnRouteParams.setDefaultProxy(client.getParams(), httpHost);
+        }
         HttpHead request = new HttpHead(uri);
 
         String cookie = mValues.getAsString(Downloads.Impl.COLUMN_COOKIE_DATA);
@@ -80,7 +87,7 @@
         }
 
         HttpResponse response;
-        String mimeType = null;
+        ContentValues result = new ContentValues();
         try {
             response = client.execute(request);
             // We could get a redirect here, but if we do lets let
@@ -89,11 +96,16 @@
             if (response.getStatusLine().getStatusCode() == 200) {
                 Header header = response.getFirstHeader("Content-Type");
                 if (header != null) {
-                    mimeType = header.getValue();
+                    String mimeType = header.getValue();
                     final int semicolonIndex = mimeType.indexOf(';');
                     if (semicolonIndex != -1) {
                         mimeType = mimeType.substring(0, semicolonIndex);
                     }
+                    result.put("Content-Type", mimeType);
+                }
+                Header contentDispositionHeader = response.getFirstHeader("Content-Disposition");
+                if (contentDispositionHeader != null) {
+                    result.put("Content-Disposition", contentDispositionHeader.getValue());
                 }
             }
         } catch (IllegalArgumentException ex) {
@@ -104,11 +116,13 @@
             client.close();
         }
 
-        return mimeType;
+        return result;
     }
 
    @Override
-    public void onPostExecute(String mimeType) {
+    public void onPostExecute(ContentValues values) {
+       final String mimeType = values.getAsString("Content-Type");
+       final String contentDisposition = values.getAsString("Content-Disposition");
        if (mimeType != null) {
            String url = mValues.getAsString(Downloads.Impl.COLUMN_URI);
            if (mimeType.equalsIgnoreCase("text/plain") ||
@@ -121,7 +135,7 @@
                }
            }
            String filename = URLUtil.guessFileName(url,
-                   null, mimeType);
+                   contentDisposition, mimeType);
            mValues.put(Downloads.Impl.COLUMN_FILE_NAME_HINT, filename);
        }
 
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index af0cdf8..7019c8a 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -1042,7 +1042,7 @@
             }
             // Have only one async task at a time.
             if (mTouchIconLoader == null) {
-                mTouchIconLoader = new DownloadTouchIcon(Tab.this, cr, view);
+                mTouchIconLoader = new DownloadTouchIcon(Tab.this, mActivity, cr, view);
                 mTouchIconLoader.execute(url);
             }
         }
diff --git a/tools/get_search_engines.py b/tools/get_search_engines.py
index cd73423..8ac9b6f 100755
--- a/tools/get_search_engines.py
+++ b/tools/get_search_engines.py
@@ -87,7 +87,7 @@
     str = str.strip('"')
     str = str.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
     str = str.replace('"', '&quot;').replace('\'', '&apos;')
-    str = re.sub(r'\\x([a-fA-F0-9]+)', r'&#x\1;', str)
+    str = re.sub(r'\\x([a-fA-F0-9]{1,4})', r'&#x\1;', str)
 
     return str