Make the search dialog's autocomplete dropdown behave correctly
with respect to the soft keyboard. getMaxAvailableHeight in
PopupWindow relies on View's getWindowVisibleDisplayFrame, which
always takes into account the IME, whereas in this case, because
we want the window to extend down to the bottom of the display
when it is being interacted with by the user, I added a new
boolean option 'ignoreBottomDecorations' to getMaxAvailableHeight.
If true, the method returns the height which will extend the
PopupWindow down to the bottom of the screen, rather than just
down to the IME.

Then in AutoCompleteTextView, I set this to true when the
dropDownAlwaysVisible attribute is true and the PopupWindow's
input method mode is INPUT_METHOD_NOT_NEEDED (which happens when
the list is dragged or otherwise interacted with).

Then, because the dropdown height is only calculated when we call
showDropDown(), I had to replace a couple calls to mPopup.update().

There are still a few remaining bugs here I'm tracking Still to do:
  * Fix a strange re-placement of the window which happens
    intermittently.
  * Strange behavior when using the directional pad.
  * In a few cases, the list does not correctly size itself to the IME.
    This seems to be because the available height is calculated before
    the IME is yet on screen, and thus is calculated as the entire screen.
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 8fc2447..0aa5975 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -171,7 +171,7 @@
                 // having windows anchored by their parent but not clipped by them.
                 ViewGroup.LayoutParams.FILL_PARENT);
         WindowManager.LayoutParams lp = theWindow.getAttributes();
-        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE;
+        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
         theWindow.setAttributes(lp);
 
         // get the view elements for local access
@@ -528,6 +528,7 @@
         mSearchAutoComplete.setDropDownAnimationStyle(0); // no animation
         mSearchAutoComplete.setThreshold(mSearchable.getSuggestThreshold());
 
+        // TODO: Use different dropdown background resource for in-app search.
         if (mGlobalSearchMode) {
             mSearchAutoComplete.setDropDownAlwaysVisible(true);  // fill space until results come in
             mSearchAutoComplete.setDropDownDismissedOnCompletion(false);
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 9c10f0a..a1d16ea 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -208,7 +208,7 @@
                 && mPopup.isShowing()
                 && mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED) {
             mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
-            mPopup.update();
+            showDropDown();
         }
     }
 
@@ -1171,9 +1171,14 @@
             }
         }
 
-        // Max height available on the screen for a popup
-        final int maxHeight =
-                mPopup.getMaxAvailableHeight(getDropDownAnchorView(), mDropDownVerticalOffset);
+        // Max height available on the screen for a popup. If this AutoCompleteTextView has
+        // the dropDownAlwaysVisible attribute, and the input method is not currently required,
+        // we then we ask for the height ignoring any bottom decorations like the input method.
+        // Otherwise we respect the input method.
+        boolean ignoreBottomDecorations = mDropDownAlwaysVisible &&
+                mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED;
+        final int maxHeight = mPopup.getMaxAvailableHeight(
+                getDropDownAnchorView(), mDropDownVerticalOffset, ignoreBottomDecorations);
 
         final int measuredHeight = mDropDownList.measureHeightOfChildren(MeasureSpec.UNSPECIFIED,
                 0, ListView.NO_POSITION, maxHeight - otherHeights, 2) + otherHeights;
@@ -1255,7 +1260,7 @@
         public boolean onTouch(View v, MotionEvent event) {
             if (event.getAction() == MotionEvent.ACTION_DOWN) {
                 mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
-                mPopup.update();
+                showDropDown();
             }
             return false;
         }
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 2c9714e..acd25ee 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -25,6 +25,7 @@
 import android.view.Gravity;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
+import android.view.WindowManagerImpl;
 import android.view.ViewTreeObserver.OnScrollChangedListener;
 import android.view.View.OnTouchListener;
 import android.graphics.PixelFormat;
@@ -948,14 +949,38 @@
      *         shown.
      */
     public int getMaxAvailableHeight(View anchor, int yOffset) {
+        return getMaxAvailableHeight(anchor, yOffset, false);
+    }
+    
+    /**
+     * Returns the maximum height that is available for the popup to be
+     * completely shown, optionally ignoring any bottom decorations such as
+     * the input method. It is recommended that this height be the maximum for
+     * the popup's height, otherwise it is possible that the popup will be
+     * clipped.
+     * 
+     * @param anchor The view on which the popup window must be anchored.
+     * @param yOffset y offset from the view's bottom edge
+     * @param ignoreBottomDecorations if true, the height returned will be
+     *        all the way to the bottom of the display, ignoring any
+     *        bottom decorations
+     * @return The maximum available height for the popup to be completely
+     *         shown.
+     *         
+     * @hide Pending API council approval.
+     */
+    public int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) {
         final Rect displayFrame = new Rect();
         anchor.getWindowVisibleDisplayFrame(displayFrame);
 
         final int[] anchorPos = mDrawingLocation;
         anchor.getLocationOnScreen(anchorPos);
         
-        final int distanceToBottom = displayFrame.bottom -
-                (anchorPos[1] + anchor.getHeight()) - yOffset;
+        int bottomEdge = displayFrame.bottom;
+        if (ignoreBottomDecorations) {
+            bottomEdge = WindowManagerImpl.getDefault().getDefaultDisplay().getHeight();
+        }
+        final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset;
         final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset;
 
         // anchorPos[1] is distance from anchor to top of screen
@@ -1116,7 +1141,7 @@
             p.flags = newFlags;
             update = true;
         }
-        
+
         if (update) {
             mWindowManager.updateViewLayout(mPopupView, p);
         }