Merge "Overhaul handling tab data updates"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d26aae7..5b844e0 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -177,7 +177,7 @@
         <activity android:name="AddBookmarkPage" android:label="Save bookmark"
                   android:theme="@style/Dialog"
                   android:configChanges="orientation|keyboardHidden"
-                  android:windowSoftInputMode="stateHidden">
+                  android:windowSoftInputMode="stateHidden|adjustPan">
             <intent-filter>
                 <action android:name="android.intent.action.INSERT" />
                 <category android:name="android.intent.category.DEFAULT" />
diff --git a/res/layout/browser_add_bookmark.xml b/res/layout/browser_add_bookmark.xml
index 8b6feab..27b8e85 100644
--- a/res/layout/browser_add_bookmark.xml
+++ b/res/layout/browser_add_bookmark.xml
@@ -22,13 +22,16 @@
     <RelativeLayout android:id="@+id/crumb_holder"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:minHeight="?android:attr/listPreferredItemHeight"
+        android:gravity="center_vertical"
         android:visibility="gone"
         >
         <com.android.browser.BreadCrumbView android:id="@+id/crumbs"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
+            android:layout_height="?android:attr/listPreferredItemHeight"
             android:layout_alignParentLeft="true"
             android:layout_toLeftOf="@+id/add_divider"
+            android:layout_centerVertical="true"
             />
         <TextView
             android:id="@+id/add_new_folder"
@@ -40,17 +43,20 @@
             android:gravity="center_vertical"
             android:text="@string/new_folder"
             android:visibility="gone"
+            android:layout_centerVertical="true"
             android:textAppearance="?android:attr/textAppearanceMedium" />
         <ImageView android:id="@+id/add_divider"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_toLeftOf="@+id/add_new_folder"
             android:src="@drawable/crumb_divider"
+            android:layout_centerVertical="true"
             />
     </RelativeLayout>
     <TextView android:id="@+id/fake_title"
         android:layout_width="wrap_content"
-        android:layout_height="?android:attr/listPreferredItemHeight"
+        android:layout_height="wrap_content"
+        android:minHeight="?android:attr/listPreferredItemHeight"
         android:drawableLeft="@drawable/ic_list_bookmark"
         android:text="@string/bookmark_this_page"
         android:layout_gravity="left"
@@ -148,7 +154,7 @@
         android:visibility="gone"
         >
 
-        <ListView
+        <view class="com.android.browser.AddBookmarkPage$CustomListView"
             android:id="@+id/list"
             android:layout_marginLeft="16dip"
             android:layout_marginRight="16dip"
@@ -165,14 +171,6 @@
             android:text="@string/no_subfolders"
             android:textStyle="italic"
             android:textAppearance="?android:attr/textAppearanceMedium" />
-        <EditText
-            android:id="@+id/folder_namer"
-            android:layout_marginLeft="16dip"
-            android:layout_marginRight="16dip"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:visibility="gone"
-            />
     </LinearLayout>
 
     <LinearLayout 
diff --git a/res/layout/folder_list_item.xml b/res/layout/folder_list_item.xml
index 56c597b..5d77fd9 100644
--- a/res/layout/folder_list_item.xml
+++ b/res/layout/folder_list_item.xml
@@ -25,7 +25,7 @@
         android:layout_height="wrap_content"
         android:gravity="center_vertical"
         android:minHeight="?android:attr/listPreferredItemHeight"
-        android:src="@drawable/ic_go_normal_white" />
+        android:src="@drawable/ic_folder_bookmark_widget_holo_dark" />
     <TextView
         android:id="@android:id/text1"
         android:layout_width="match_parent"
diff --git a/res/layout/new_folder_layout.xml b/res/layout/new_folder_layout.xml
new file mode 100644
index 0000000..4ce0ade
--- /dev/null
+++ b/res/layout/new_folder_layout.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<!-- Keep in sync with folder_list_item.xml -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal">
+    <ImageView
+        android:id="@+id/icon1"
+        style="@style/HoloIcon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="center_vertical"
+        android:minHeight="?android:attr/listPreferredItemHeight"
+        android:src="@drawable/ic_folder_bookmark_widget_holo_dark" />
+    <EditText
+        android:id="@+id/folder_namer"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:gravity="center_vertical"
+        android:paddingLeft="6dip"
+        android:minHeight="?android:attr/listPreferredItemHeight" />
+</LinearLayout>
diff --git a/src/com/android/browser/AddBookmarkPage.java b/src/com/android/browser/AddBookmarkPage.java
index 262884b..f5b677a 100644
--- a/src/com/android/browser/AddBookmarkPage.java
+++ b/src/com/android/browser/AddBookmarkPage.java
@@ -41,6 +41,7 @@
 import android.preference.PreferenceManager;
 import android.provider.BrowserContract;
 import android.text.TextUtils;
+import android.util.AttributeSet;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MenuItem;
@@ -97,6 +98,8 @@
     private View mDefaultView;
     private View mFolderSelector;
     private EditText mFolderNamer;
+    private boolean mIsFolderNamerShowing;
+    private View mFolderNamerHolder;
     private View mAddNewFolder;
     private View mAddSeparator;
     private long mCurrentFolder = 0;
@@ -104,9 +107,11 @@
     private BreadCrumbView mCrumbs;
     private TextView mFakeTitle;
     private View mCrumbHolder;
-    private ListView mListView;
+    private CustomListView mListView;
     private boolean mSaveToHomeScreen;
     private long mRootFolder;
+    private TextView mTopLevelLabel;
+    private Drawable mHeaderIcon;
 
     private static class Folder {
         String Name;
@@ -151,9 +156,19 @@
                 LOADER_ID_FOLDER_CONTENTS));
         loader.setUri(getUriForFolder(folder));
         loader.forceLoad();
-        if (mFolderNamer.getVisibility() == View.VISIBLE) {
+        if (mIsFolderNamerShowing) {
             completeOrCancelFolderNaming(true);
         }
+        setShowBookmarkIcon(level == 1);
+    }
+
+    /**
+     * Show or hide the icon for bookmarks next to "Bookmarks" in the crumb view.
+     * @param show True if the icon should visible, false otherwise.
+     */
+    private void setShowBookmarkIcon(boolean show) {
+        Drawable drawable = show ? mHeaderIcon: null;
+        mTopLevelLabel.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
     }
 
     @Override
@@ -197,7 +212,7 @@
         if (v == mButton) {
             if (mFolderSelector.getVisibility() == View.VISIBLE) {
                 // We are showing the folder selector.
-                if (mFolderNamer.getVisibility() == View.VISIBLE) {
+                if (mIsFolderNamerShowing) {
                     completeOrCancelFolderNaming(false);
                 } else {
                     // User has selected a folder.  Go back to the opening page
@@ -208,7 +223,7 @@
                 finish();
             }
         } else if (v == mCancelButton) {
-            if (mFolderNamer.getVisibility() == View.VISIBLE) {
+            if (mIsFolderNamerShowing) {
                 completeOrCancelFolderNaming(true);
             } else if (mFolderSelector.getVisibility() == View.VISIBLE) {
                 switchToDefaultView(false);
@@ -225,14 +240,16 @@
             popup.setOnMenuItemClickListener(this);
             popup.show();
         } else if (v == mAddNewFolder) {
-            mFolderNamer.setVisibility(View.VISIBLE);
+            setShowFolderNamer(true);
             mFolderNamer.setText(R.string.new_folder);
             mFolderNamer.requestFocus();
-            updateList();
             mAddNewFolder.setVisibility(View.GONE);
             mAddSeparator.setVisibility(View.GONE);
-            getInputMethodManager().showSoftInput(mFolderNamer,
-                    InputMethodManager.SHOW_IMPLICIT);
+            InputMethodManager imm = getInputMethodManager();
+            // Set the InputMethodManager to focus on the ListView so that it
+            // can transfer the focus to mFolderNamer.
+            imm.focusIn(mListView);
+            imm.showSoftInput(mFolderNamer, InputMethodManager.SHOW_IMPLICIT);
         }
     }
 
@@ -258,27 +275,17 @@
         return true;
     }
 
-    // Refresh the ListView to hide or show the empty view, as necessary.
-    // Should be called after mFolderNamer is shown or hidden.
-    private void updateList() {
-        if (mAdapter.getCount() == 0) {
-            // XXX: Is there a better way to refresh the ListView?
-            mListView.setAdapter(mAdapter);
-        }
-    }
-
     private void completeOrCancelFolderNaming(boolean cancel) {
         if (!cancel && !TextUtils.isEmpty(mFolderNamer.getText())) {
             String name = mFolderNamer.getText().toString();
             long id = addFolderToCurrent(mFolderNamer.getText().toString());
             descendInto(name, id);
         }
-        mFolderNamer.setVisibility(View.GONE);
+        setShowFolderNamer(false);
         mAddNewFolder.setVisibility(View.VISIBLE);
         mAddSeparator.setVisibility(View.VISIBLE);
         getInputMethodManager().hideSoftInputFromWindow(
-                mFolderNamer.getWindowToken(), 0);
-        updateList();
+                mListView.getWindowToken(), 0);
     }
 
     private long addFolderToCurrent(String name) {
@@ -461,6 +468,24 @@
         descendInto(tv.getText().toString(), id);
     }
 
+    private void setShowFolderNamer(boolean show) {
+        if (show != mIsFolderNamerShowing) {
+            mIsFolderNamerShowing = show;
+            if (show) {
+                // Set the selection to the folder namer so it will be in
+                // view.
+                mListView.addFooterView(mFolderNamerHolder);
+            } else {
+                mListView.removeFooterView(mFolderNamerHolder);
+            }
+            // Refresh the list.
+            mListView.setAdapter(mAdapter);
+            if (show) {
+                mListView.setSelection(mListView.getCount() - 1);
+            }
+        }
+    }
+
     /**
      * Shows a list of names of folders.
      */
@@ -488,7 +513,7 @@
         @Override
         public boolean isEmpty() {
             // Do not show the empty view if the user is creating a new folder.
-            return super.isEmpty() && mFolderNamer.getVisibility() == View.GONE;
+            return super.isEmpty() && !mIsFolderNamerShowing;
         }
     }
 
@@ -554,7 +579,8 @@
         mDefaultView = findViewById(R.id.default_view);
         mFolderSelector = findViewById(R.id.folder_selector);
 
-        mFolderNamer = (EditText) findViewById(R.id.folder_namer);
+        mFolderNamerHolder = getLayoutInflater().inflate(R.layout.new_folder_layout, null);
+        mFolderNamer = (EditText) mFolderNamerHolder.findViewById(R.id.folder_namer);
         mFolderNamer.setOnEditorActionListener(this);
 
         mAddNewFolder = findViewById(R.id.add_new_folder);
@@ -565,20 +591,26 @@
         mCrumbs.setUseBackButton(true);
         mCrumbs.setController(this);
         String name = getString(R.string.bookmarks);
-        mCrumbs.pushView(name, false, new Folder(name, mRootFolder));
+        mTopLevelLabel = (TextView) mCrumbs.pushView(name, false, new Folder(name, mRootFolder));
+        // To better match the other folders.
+        mTopLevelLabel.setCompoundDrawablePadding(6);
+        mHeaderIcon = getResources().getDrawable(R.drawable.ic_folder_bookmark_widget_holo_dark);
         mCrumbHolder = findViewById(R.id.crumb_holder);
         mCrumbs.setMaxVisible(MAX_CRUMBS_SHOWN);
 
         mAdapter = new FolderAdapter(this);
-        mListView = (ListView) findViewById(R.id.list);
+        mListView = (CustomListView) findViewById(R.id.list);
         View empty = findViewById(R.id.empty);
         mListView.setEmptyView(empty);
         mListView.setAdapter(mAdapter);
         mListView.setOnItemClickListener(this);
+        mListView.addEditText(mFolderNamer);
         LoaderManager manager = getLoaderManager();
         if (mCurrentFolder != mRootFolder) {
             // Find all the folders
             manager.initLoader(LOADER_ID_ALL_FOLDERS, null, this);
+        } else {
+            setShowBookmarkIcon(true);
         }
         // Find the contents of the current folder
         manager.initLoader(LOADER_ID_FOLDER_CONTENTS, null, this);
@@ -848,4 +880,32 @@
         }
         return true;
     }
+
+    /*
+     * Class used as a proxy for the InputMethodManager to get to mFolderNamer
+     */
+    public static class CustomListView extends ListView {
+        private EditText mEditText;
+
+        public void addEditText(EditText editText) {
+            mEditText = editText;
+        }
+
+        public CustomListView(Context context) {
+            super(context);
+        }
+
+        public CustomListView(Context context, AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        public CustomListView(Context context, AttributeSet attrs, int defStyle) {
+            super(context, attrs, defStyle);
+        }
+
+        @Override
+        public boolean checkInputConnectionProxy(View view) {
+            return view == mEditText;
+        }
+    }
 }
diff --git a/src/com/android/browser/BreadCrumbView.java b/src/com/android/browser/BreadCrumbView.java
index 643bfc7..113d55b 100644
--- a/src/com/android/browser/BreadCrumbView.java
+++ b/src/com/android/browser/BreadCrumbView.java
@@ -135,13 +135,14 @@
         }
     }
 
-    public void pushView(String name, Object data) {
-        pushView(name, true, data);
+    public View pushView(String name, Object data) {
+        return pushView(name, true, data);
     }
 
-    public void pushView(String name, boolean canGoBack, Object data) {
+    public View pushView(String name, boolean canGoBack, Object data) {
         Crumb crumb = new Crumb(name, canGoBack, data);
         pushCrumb(crumb);
+        return crumb.crumbView;
     }
 
     public void pushView(View view, Object data) {
@@ -160,7 +161,7 @@
         mBackButton.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
                 LayoutParams.MATCH_PARENT));
         mBackButton.setOnClickListener(this);
-        mBackButton.setVisibility(View.INVISIBLE);
+        mBackButton.setVisibility(View.GONE);
         addView(mBackButton, 0);
     }
 
@@ -196,7 +197,7 @@
                 if (top != null && top.canGoBack) {
                     mBackButton.setVisibility(View.VISIBLE);
                 } else {
-                    mBackButton.setVisibility(View.INVISIBLE);
+                    mBackButton.setVisibility(View.GONE);
                 }
             }
             updateVisible();
@@ -241,7 +242,7 @@
         }
         if (mUseBackButton) {
             boolean canGoBack = getTopCrumb() != null ? getTopCrumb().canGoBack : false;
-            mBackButton.setVisibility(canGoBack ? View.VISIBLE : View.INVISIBLE);
+            mBackButton.setVisibility(canGoBack ? View.VISIBLE : View.GONE);
         } else {
             mBackButton.setVisibility(View.GONE);
         }
diff --git a/src/com/android/browser/CombinedBookmarkHistoryView.java b/src/com/android/browser/CombinedBookmarkHistoryView.java
index cc56489..426b34d 100644
--- a/src/com/android/browser/CombinedBookmarkHistoryView.java
+++ b/src/com/android/browser/CombinedBookmarkHistoryView.java
@@ -197,6 +197,7 @@
                 fragment = mBookmarks;
                 mSeperateSelectAdd.setVisibility(View.VISIBLE);
                 mBookmarksHeader.setVisibility(View.VISIBLE);
+                mAddBookmark.setVisibility(View.VISIBLE);
                 mTabBookmarks.setActivated(true);
                 mTabHistory.setActivated(false);
                 break;
@@ -204,6 +205,7 @@
                 fragment = mHistory;
                 mBookmarksHeader.setVisibility(View.INVISIBLE);
                 mSeperateSelectAdd.setVisibility(View.INVISIBLE);
+                mAddBookmark.setVisibility(View.INVISIBLE);
                 mTabBookmarks.setActivated(false);
                 mTabHistory.setActivated(true);
                 break;
diff --git a/tests/src/com/android/browser/PopularUrlsTest.java b/tests/src/com/android/browser/PopularUrlsTest.java
index e407194..5e367be 100644
--- a/tests/src/com/android/browser/PopularUrlsTest.java
+++ b/tests/src/com/android/browser/PopularUrlsTest.java
@@ -294,7 +294,7 @@
             // try to wait for count down latch again
             timedout = !mLatch.await(5000, TimeUnit.MILLISECONDS);
             if (timedout) {
-                Log.e(TAG, "failed to stop the timedout site in 5s");
+                throw new RuntimeException("failed to stop timedout site, is browser pegged?");
             }
         }
     }