Merge "Adds a cancel button to ShortcutActivity dialog"
diff --git a/res/layout/autofill_settings_fragment.xml b/res/layout/autofill_settings_fragment.xml
index b0e0f53..ca74e9a 100644
--- a/res/layout/autofill_settings_fragment.xml
+++ b/res/layout/autofill_settings_fragment.xml
@@ -16,8 +16,7 @@
 
 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:fillViewport="true">
+    android:layout_height="match_parent">
 
     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
@@ -27,8 +26,8 @@
     <TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:textAppearance="?android:attr/textAppearanceLarge"
-        android:text="@string/pref_autofill_profile_editor" />
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:text="@string/autofill_profile_editor_heading" />
 
     <View
         android:layout_height="20dip"
@@ -37,52 +36,47 @@
     <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_weight="1"
         android:shrinkColumns="1"
         android:stretchColumns="1">
-        <TableRow
-            android:layout_height="match_parent"
-            android:layout_weight="1">
+        <TableRow>
             <TextView
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:gravity="center_vertical"
-                android:padding="10dip"
+                android:layout_margin="2dip"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:text="@string/autofill_profile_editor_name" />
             <EditText android:id="@+id/autofill_profile_editor_name_edit"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:padding="10dip"
+                android:gravity="center_vertical"
+                android:layout_margin="2dip"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:inputType="textPersonName|textCapWords"
                 android:singleLine="true" />
         </TableRow>
-        <TableRow
-            android:layout_height="match_parent"
-            android:layout_weight="1">
+        <TableRow>
             <TextView
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:gravity="center_vertical"
-                android:padding="10dip"
+                android:layout_margin="2dip"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:text="@string/autofill_profile_editor_company_name" />
             <EditText android:id="@+id/autofill_profile_editor_company_name_edit"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:padding="10dip"
+                android:gravity="center_vertical"
+                android:layout_margin="2dip"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:inputType="textCapWords"
                 android:singleLine="true" />
         </TableRow>
-        <TableRow
-            android:layout_height="match_parent"
-            android:layout_weight="1">
+        <TableRow>
             <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:padding="10dip"
+                android:layout_margin="2dip"
                 android:orientation="vertical">
                 <TextView
                     android:layout_width="wrap_content"
@@ -98,20 +92,17 @@
                     android:text="@string/autofill_profile_editor_address_line_1_hint" />
             </LinearLayout>
             <EditText android:id="@+id/autofill_profile_editor_address_line_1_edit"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:padding="10dip"
+                android:gravity="center_vertical"
+                android:layout_margin="2dip"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:inputType="textCapWords"
                 android:singleLine="true" />
         </TableRow>
-        <TableRow
-            android:layout_height="match_parent"
-            android:layout_weight="1">
+        <TableRow>
             <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:padding="10dip"
+                android:layout_margin="2dip"
                 android:orientation="vertical">
                 <TextView
                     android:layout_width="wrap_content"
@@ -129,115 +120,110 @@
             <EditText android:id="@+id/autofill_profile_editor_address_line_2_edit"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:padding="10dip"
+                android:gravity="bottom"
+                android:layout_margin="2dip"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:inputType="textCapWords"
                 android:singleLine="true" />
         </TableRow>
-        <TableRow
-            android:layout_height="match_parent"
-            android:layout_weight="1">
+        <TableRow>
             <TextView
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:gravity="center_vertical"
-                android:padding="10dip"
+                android:layout_margin="2dip"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:text="@string/autofill_profile_editor_city" />
             <EditText android:id="@+id/autofill_profile_editor_city_edit"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:padding="10dip"
+                android:gravity="center_vertical"
+                android:layout_margin="2dip"
                 android:inputType="textCapWords"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:singleLine="true" />
         </TableRow>
-        <TableRow
-            android:layout_height="match_parent"
-            android:layout_weight="1">
+        <TableRow>
             <TextView
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:gravity="center_vertical"
-                android:padding="10dip"
+                android:layout_margin="2dip"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:text="@string/autofill_profile_editor_state" />
             <EditText android:id="@+id/autofill_profile_editor_state_edit"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:padding="10dip"
+                android:gravity="center_vertical"
+                android:layout_margin="2dip"
                 android:inputType="textCapWords"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:singleLine="true" />
         </TableRow>
-        <TableRow
-            android:layout_height="match_parent"
-            android:layout_weight="1">
+        <TableRow>
             <TextView
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:gravity="center_vertical"
-                android:padding="10dip"
+                android:layout_margin="2dip"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:text="@string/autofill_profile_editor_zip_code" />
             <EditText android:id="@+id/autofill_profile_editor_zip_code_edit"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:padding="10dip"
+                android:gravity="center_vertical"
+                android:layout_margin="2dip"
                 android:inputType="textCapCharacters"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:singleLine="true" />
         </TableRow>
-       <TableRow
-            android:layout_height="match_parent"
-            android:layout_weight="1">
+        <TableRow>
             <TextView
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:gravity="center_vertical"
-                android:padding="10dip"
+                android:layout_margin="2dip"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:text="@string/autofill_profile_editor_country" />
             <EditText android:id="@+id/autofill_profile_editor_country_edit"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:padding="10dip"
+                android:gravity="center_vertical"
+                android:layout_margin="2dip"
                 android:inputType="textCapWords"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:singleLine="true" />
         </TableRow>
-        <TableRow
-            android:layout_height="match_parent"
-            android:layout_weight="1">
+        <TableRow>
             <TextView
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:gravity="center_vertical"
-                android:padding="10dip"
+                android:layout_margin="2dip"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:text="@string/autofill_profile_editor_phone_number" />
             <EditText android:id="@+id/autofill_profile_editor_phone_number_edit"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:padding="10dip"
+                android:gravity="center_vertical"
+                android:layout_margin="2dip"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:singleLine="true"
                 android:phoneNumber="true" />
         </TableRow>
-        <TableRow
-            android:layout_height="match_parent"
-            android:layout_weight="1">
+        <TableRow>
             <TextView
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:gravity="center_vertical"
-                android:padding="10dip"
+                android:layout_margin="2dip"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:text="@string/autofill_profile_editor_email_address" />
             <EditText android:id="@+id/autofill_profile_editor_email_address_edit"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:padding="10dip"
+                android:gravity="center_vertical"
+                android:layout_margin="2dip"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:inputType="textEmailAddress"
                 android:singleLine="true" />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b1c04dc..c6adaef 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -370,6 +370,8 @@
     <!-- Summary for the AutoFill Settings preference [CHAR-LIMIT=none] -->
     <string name="pref_autofill_profile_editor_summary">Set up &amp; manage data for AutoFilled forms</string>
 
+    <!-- Heading for the AutoFill profile editor to tell the user what AutoFill does and why they should fill out the profile. [CHAR-LIMIT=None] -->
+    <string name="autofill_profile_editor_heading">AutoFill will use your profile to help you complete web forms in a single click.</string>
     <!-- String for the user's full name in the AutoFill profile editor. [CHAR-LIMIT=32] -->
     <string name="autofill_profile_editor_name">Full name:</string>
     <!-- String for the user's e-mail address in the AutoFill profile editor. [CHAR-LIMIT=32] -->
@@ -402,7 +404,7 @@
     <!-- Toast message displayed when the profile has been successfully deleted [CHAR-LIMIT=none] -->
     <string name="autofill_profile_successful_delete">Profile deleted</string>
     <!-- Button text to delete all the AutoFill profile data [CHAR-LIMIT=20] -->
-    <string name="autofill_profile_editor_delete_profile">Delete profile data</string>
+    <string name="autofill_profile_editor_delete_profile">Delete profile</string>
 
     <!-- Text on a dialog shown to the user when they are prompted to set up the autofill feature [CHAR-LIMIT=NONE] -->
     <string name="autofill_setup_dialog_message">Browser can automatically complete web forms like this one. Would you like to set up your profile?</string>
diff --git a/src/com/android/browser/AddBookmarkPage.java b/src/com/android/browser/AddBookmarkPage.java
index 24a8cd5..2bfcbb4 100644
--- a/src/com/android/browser/AddBookmarkPage.java
+++ b/src/com/android/browser/AddBookmarkPage.java
@@ -339,11 +339,16 @@
                         BrowserContract.Bookmarks.TITLE,
                         BrowserContract.Bookmarks.IS_FOLDER
                 };
+                String where = BrowserContract.Bookmarks.IS_FOLDER + " != 0";
+                if (mEditingFolder) {
+                    where += " AND " + BrowserContract.Bookmarks._ID + " != "
+                            + mMap.getLong(BrowserContract.Bookmarks._ID);
+                }
                 return new CursorLoader(this,
                         BrowserContract.Bookmarks.buildFolderUri(
                         mCurrentFolder),
                         projection,
-                        BrowserContract.Bookmarks.IS_FOLDER + " != 0",
+                        where,
                         null,
                         null);
             default:
@@ -452,6 +457,7 @@
         }
     }
 
+    @Override
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         if (DEBUG_CRASH) {
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java
index b39cb43..b9ccd72 100644
--- a/src/com/android/browser/BaseUi.java
+++ b/src/com/android/browser/BaseUi.java
@@ -349,7 +349,6 @@
             // Request focus on the top window.
             mTabBar.onSetActiveTab(tab);
         }
-        bookmarkedStatusHasChanged(tab);
         resetTitleIconAndProgress(tab);
         updateLockIconToLatest(tab);
         tab.getTopWindow().requestFocus();
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index a2caf90..e433e29 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -33,6 +33,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
+import android.database.ContentObserver;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteException;
@@ -191,6 +192,9 @@
     private boolean mLoadStopped;
 
     private Handler mHandler;
+    // Checks to see when the bookmarks database has changed, and updates the
+    // Tabs' notion of whether they represent bookmarked sites.
+    private ContentObserver mBookmarksObserver;
 
     private static class ClearThumbnails extends AsyncTask<File, Void, Void> {
         @Override
@@ -221,6 +225,18 @@
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
 
         startHandler();
+        mBookmarksObserver = new ContentObserver(mHandler) {
+            @Override
+            public void onChange(boolean selfChange) {
+                int size = mTabControl.getTabCount();
+                for (int i = 0; i < size; i++) {
+                    mTabControl.getTab(i).updateBookmarkedStatus();
+                }
+            }
+
+        };
+        browser.getContentResolver().registerContentObserver(
+                BrowserContract.Bookmarks.CONTENT_URI, true, mBookmarksObserver);
 
         mNetworkHandler = new NetworkStateHandler(mActivity, this);
         // Start watching the default geolocation permissions
@@ -668,6 +684,7 @@
             dismissSubWindow(t);
             removeTab(t);
         }
+        mActivity.getContentResolver().unregisterContentObserver(mBookmarksObserver);
         // Destroy all the tabs
         mTabControl.destroy();
         WebIconDatabase.getInstance().close();
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index 3e79edb..5b536f8 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -503,39 +503,7 @@
             // finally update the UI in the activity if it is in the foreground
             mWebViewController.onPageStarted(Tab.this, view, url, favicon);
 
-            final String urlInQuestion = url;
-            if (mBookmarkAsyncTask != null) {
-                mBookmarkAsyncTask.cancel(true);
-            }
-            mBookmarkAsyncTask = new AsyncTask<Void, Void, Boolean>() {
-                @Override
-                protected Boolean doInBackground(Void... unused) {
-                    // Check to see if the site is bookmarked
-                    Cursor cursor = null;
-                    try {
-                        cursor = mActivity.getContentResolver().query(
-                                BrowserContract.Bookmarks.CONTENT_URI,
-                                new String[] { BrowserContract.Bookmarks.URL },
-                                BrowserContract.Bookmarks.URL + " == ?",
-                                new String[] { urlInQuestion },
-                                null);
-                        return cursor.moveToFirst();
-                    } catch (SQLiteException e) {
-                        Log.e(LOGTAG, "Error checking for bookmark: " + e);
-                        return false;
-                    } finally {
-                        if (cursor != null) cursor.close();
-                    }
-                }
-                @Override
-                protected void onPostExecute(Boolean isBookmarked) {
-                    if (this == mBookmarkAsyncTask) {
-                        mIsBookmarkedSite = isBookmarked;
-                        mWebViewController.bookmarkedStatusHasChanged(Tab.this);
-                    }
-                }
-            };
-            mBookmarkAsyncTask.execute();
+            updateBookmarkedStatusForUrl(url);
         }
 
         @Override
@@ -1450,6 +1418,7 @@
         if (mQueuedErrors != null && mQueuedErrors.size() >  0) {
             showError(mQueuedErrors.getFirst());
         }
+        mWebViewController.bookmarkedStatusHasChanged(this);
     }
 
     void putInBackground() {
@@ -1827,4 +1796,55 @@
         return true;
     }
 
+    public void updateBookmarkedStatus() {
+        if (mMainView == null) {
+            return;
+        }
+        String url = mMainView.getUrl();
+        if (url == null) {
+            return;
+        }
+        updateBookmarkedStatusForUrl(url);
+    }
+
+    /**
+     * Update mIsBookmarkedSite, using urlInQuestion to compare.
+     * @param urlInQuestion URL of the current page, to be checked in the
+     *          bookmarks database.
+     */
+    private void updateBookmarkedStatusForUrl(final String urlInQuestion) {
+        if (mBookmarkAsyncTask != null) {
+            mBookmarkAsyncTask.cancel(true);
+        }
+        mBookmarkAsyncTask = new AsyncTask<Void, Void, Boolean>() {
+            @Override
+            protected Boolean doInBackground(Void... unused) {
+                // Check to see if the site is bookmarked
+                Cursor cursor = null;
+                try {
+                    cursor = mActivity.getContentResolver().query(
+                            BrowserContract.Bookmarks.CONTENT_URI,
+                            new String[] { BrowserContract.Bookmarks.URL },
+                            BrowserContract.Bookmarks.URL + " == ?",
+                            new String[] { urlInQuestion },
+                            null);
+                    return cursor.moveToFirst();
+                } catch (SQLiteException e) {
+                    Log.e(LOGTAG, "Error checking for bookmark: " + e);
+                    return false;
+                } finally {
+                    if (cursor != null) cursor.close();
+                }
+            }
+            @Override
+            protected void onPostExecute(Boolean isBookmarked) {
+                if (this == mBookmarkAsyncTask) {
+                    mIsBookmarkedSite = isBookmarked;
+                    mWebViewController.bookmarkedStatusHasChanged(Tab.this);
+                }
+            }
+        };
+        mBookmarkAsyncTask.execute();
+    }
+
 }
diff --git a/src/com/android/browser/UrlHandler.java b/src/com/android/browser/UrlHandler.java
index 72704e0..52945b3 100644
--- a/src/com/android/browser/UrlHandler.java
+++ b/src/com/android/browser/UrlHandler.java
@@ -22,6 +22,7 @@
 import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.AsyncTask;
 import android.util.Log;
 import android.webkit.WebView;
 
@@ -98,22 +99,11 @@
         if (rlzProviderPresent()) {
             Uri siteUri = Uri.parse(url);
             if (needsRlzString(siteUri)) {
-                String rlz = null;
-                Cursor cur = null;
-                try {
-                    cur = mActivity.getContentResolver()
-                            .query(getRlzUri(), null, null, null, null);
-                    if (cur != null && cur.moveToFirst() && !cur.isNull(0)) {
-                        url = siteUri.buildUpon()
-                                     .appendQueryParameter("rlz", cur.getString(0))
-                                     .build().toString();
-                    }
-                } finally {
-                    if (cur != null) {
-                        cur.close();
-                    }
-                }
-                mController.loadUrl(view, url);
+                // Need to look up the RLZ info from a database, so do it in an
+                // 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();
                 return true;
             }
         }
@@ -173,6 +163,39 @@
         return false;
     }
 
+    private class RLZTask extends AsyncTask<Void, Void, String> {
+        private Uri mSiteUri;
+        private WebView mWebView;
+
+        public RLZTask(Uri uri, WebView webView) {
+            mSiteUri = uri;
+            mWebView = webView;
+        }
+
+        protected String doInBackground(Void... unused) {
+            String result = mSiteUri.toString();
+            Cursor cur = null;
+            try {
+                cur = mActivity.getContentResolver()
+                        .query(getRlzUri(), null, null, null, null);
+                if (cur != null && cur.moveToFirst() && !cur.isNull(0)) {
+                    result = mSiteUri.buildUpon()
+                           .appendQueryParameter("rlz", cur.getString(0))
+                           .build().toString();
+                }
+            } finally {
+                if (cur != null) {
+                    cur.close();
+                }
+            }
+            return result;
+        }
+
+        protected void onPostExecute(String result) {
+            mController.loadUrl(mWebView, result);
+        }
+    }
+
     // Determine whether the RLZ provider is present on the system.
     private boolean rlzProviderPresent() {
         if (mIsProviderPresent == null) {