Add popup window accessors for anchor overlap, gravity, window

Cleans up comments and some code in PopupWindow.

BUG: 18245054
Change-Id: I2111d0c194ee1a39aaa721083041fc139efcf630
diff --git a/api/current.txt b/api/current.txt
index 3eff5e4..2a56ff7 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -38205,9 +38205,11 @@
     ctor public PopupMenu(android.content.Context, android.view.View, int, int, int);
     method public void dismiss();
     method public android.view.View.OnTouchListener getDragToOpenListener();
+    method public int getGravity();
     method public android.view.Menu getMenu();
     method public android.view.MenuInflater getMenuInflater();
     method public void inflate(int);
+    method public void setGravity(int);
     method public void setOnDismissListener(android.widget.PopupMenu.OnDismissListener);
     method public void setOnMenuItemClickListener(android.widget.PopupMenu.OnMenuItemClickListener);
     method public void show();
@@ -38240,6 +38242,7 @@
     method public int getInputMethodMode();
     method public int getMaxAvailableHeight(android.view.View);
     method public int getMaxAvailableHeight(android.view.View, int);
+    method public boolean getOverlapAnchor();
     method public int getSoftInputMode();
     method public int getWidth();
     method public boolean isAboveAnchor();
@@ -38262,6 +38265,7 @@
     method public void setInputMethodMode(int);
     method public void setOnDismissListener(android.widget.PopupWindow.OnDismissListener);
     method public void setOutsideTouchable(boolean);
+    method public void setOverlapAnchor(boolean);
     method public void setSoftInputMode(int);
     method public void setSplitTouchEnabled(boolean);
     method public void setTouchInterceptor(android.view.View.OnTouchListener);
diff --git a/core/java/android/widget/PopupMenu.java b/core/java/android/widget/PopupMenu.java
index 2708398..06ac1c3 100644
--- a/core/java/android/widget/PopupMenu.java
+++ b/core/java/android/widget/PopupMenu.java
@@ -115,6 +115,29 @@
     }
 
     /**
+     * Sets the gravity used to align the popup window to its anchor view.
+     * <p>
+     * If the popup is showing, calling this method will take effect only
+     * the next time the popup is shown.
+     *
+     * @param gravity the gravity used to align the popup window
+     *
+     * @see #getGravity()
+     */
+    public void setGravity(int gravity) {
+        mPopup.setGravity(gravity);
+    }
+
+    /**
+     * @return the gravity used to align the popup window to its anchor view
+     *
+     * @see #setGravity(int)
+     */
+    public int getGravity() {
+        return mPopup.getGravity();
+    }
+
+    /**
      * Returns an {@link OnTouchListener} that can be added to the anchor view
      * to implement drag-to-open behavior.
      * <p>
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 5419ab6c..656d31d 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -18,11 +18,9 @@
 
 import com.android.internal.R;
 
-import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
-import android.graphics.Insets;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
@@ -195,7 +193,7 @@
      */
     public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         mContext = context;
-        mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
+        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
 
         final TypedArray a = context.obtainStyledAttributes(
                 attrs, R.styleable.PopupWindow, defStyleAttr, defStyleRes);
@@ -871,6 +869,34 @@
     }
 
     /**
+     * Sets whether the popup window should overlap its anchor view when
+     * displayed as a drop-down.
+     * <p>
+     * If the popup is showing, calling this method will take effect only
+     * the next time the popup is shown.
+     *
+     * @param overlapAnchor Whether the popup should overlap its anchor.
+     *
+     * @see #getOverlapAnchor()
+     * @see #isShowing()
+     */
+    public void setOverlapAnchor(boolean overlapAnchor) {
+        mOverlapAnchor = overlapAnchor;
+    }
+
+    /**
+     * Returns whether the popup window should overlap its anchor view when
+     * displayed as a drop-down.
+     *
+     * @return Whether the popup should overlap its anchor.
+     *
+     * @see #setOverlapAnchor(boolean)
+     */
+    public boolean getOverlapAnchor() {
+        return mOverlapAnchor;
+    }
+
+    /**
      * <p>Indicate whether this popup window is showing on screen.</p>
      *
      * @return true if the popup is showing, false otherwise
@@ -934,11 +960,12 @@
     }
 
     /**
-     * <p>Display the content view in a popup window anchored to the bottom-left
+     * Display the content view in a popup window anchored to the bottom-left
      * corner of the anchor view. If there is not enough room on screen to show
      * the popup in its entirety, this method tries to find a parent scroll
-     * view to scroll. If no parent scroll view can be scrolled, the bottom-left
-     * corner of the popup is pinned at the top left corner of the anchor view.</p>
+     * view to scroll. If no parent scroll view can be scrolled, the
+     * bottom-left corner of the popup is pinned at the top left corner of the
+     * anchor view.
      *
      * @param anchor the view on which to pin the popup window
      *
@@ -949,14 +976,15 @@
     }
 
     /**
-     * <p>Display the content view in a popup window anchored to the bottom-left
+     * Display the content view in a popup window anchored to the bottom-left
      * corner of the anchor view offset by the specified x and y coordinates.
-     * If there is not enough room on screen to show
-     * the popup in its entirety, this method tries to find a parent scroll
-     * view to scroll. If no parent scroll view can be scrolled, the bottom-left
-     * corner of the popup is pinned at the top left corner of the anchor view.</p>
-     * <p>If the view later scrolls to move <code>anchor</code> to a different
-     * location, the popup will be moved correspondingly.</p>
+     * If there is not enough room on screen to show the popup in its entirety,
+     * this method tries to find a parent scroll view to scroll. If no parent
+     * scroll view can be scrolled, the bottom-left corner of the popup is
+     * pinned at the top left corner of the anchor view.
+     * <p>
+     * If the view later scrolls to move <code>anchor</code> to a different
+     * location, the popup will be moved correspondingly.
      *
      * @param anchor the view on which to pin the popup window
      * @param xoff A horizontal offset from the anchor in pixels
@@ -969,14 +997,17 @@
     }
 
     /**
-     * <p>Display the content view in a popup window anchored to the bottom-left
-     * corner of the anchor view offset by the specified x and y coordinates.
-     * If there is not enough room on screen to show
-     * the popup in its entirety, this method tries to find a parent scroll
-     * view to scroll. If no parent scroll view can be scrolled, the bottom-left
-     * corner of the popup is pinned at the top left corner of the anchor view.</p>
-     * <p>If the view later scrolls to move <code>anchor</code> to a different
-     * location, the popup will be moved correspondingly.</p>
+     * Displays the content view in a popup window anchored to the corner of
+     * another view. The window is positioned according to the specified
+     * gravity and offset by the specified x and y coordinates.
+     * <p>
+     * If there is not enough room on screen to show the popup in its entirety,
+     * this method tries to find a parent scroll view to scroll. If no parent
+     * view can be scrolled, the specified vertical gravity will be ignored and
+     * the popup will anchor itself such that it is visible.
+     * <p>
+     * If the view later scrolls to move <code>anchor</code> to a different
+     * location, the popup will be moved correspondingly.
      *
      * @param anchor the view on which to pin the popup window
      * @param xoff A horizontal offset from the anchor in pixels
@@ -1571,7 +1602,7 @@
      * @param height the new height, can be -1 to ignore
      */
     public void update(View anchor, int width, int height) {
-        update(anchor, false, 0, 0, true, width, height, mAnchoredGravity);
+        update(anchor, false, 0, 0, true, width, height);
     }
 
     /**
@@ -1590,30 +1621,26 @@
      * @param height the new height, can be -1 to ignore
      */
     public void update(View anchor, int xoff, int yoff, int width, int height) {
-        update(anchor, true, xoff, yoff, true, width, height, mAnchoredGravity);
+        update(anchor, true, xoff, yoff, true, width, height);
     }
 
     private void update(View anchor, boolean updateLocation, int xoff, int yoff,
-            boolean updateDimension, int width, int height, int gravity) {
+            boolean updateDimension, int width, int height) {
 
         if (!isShowing() || mContentView == null) {
             return;
         }
 
-        WeakReference<View> oldAnchor = mAnchor;
-        final boolean needsUpdate = updateLocation
-                && (mAnchorXoff != xoff || mAnchorYoff != yoff);
+        final WeakReference<View> oldAnchor = mAnchor;
+        final boolean needsUpdate = updateLocation && (mAnchorXoff != xoff || mAnchorYoff != yoff);
         if (oldAnchor == null || oldAnchor.get() != anchor || (needsUpdate && !mIsDropdown)) {
-            registerForScrollChanged(anchor, xoff, yoff, gravity);
+            registerForScrollChanged(anchor, xoff, yoff, mAnchoredGravity);
         } else if (needsUpdate) {
             // No need to register again if this is a DropDown, showAsDropDown already did.
             mAnchorXoff = xoff;
             mAnchorYoff = yoff;
-            mAnchoredGravity = gravity;
         }
 
-        WindowManager.LayoutParams p = (WindowManager.LayoutParams) mPopupView.getLayoutParams();
-
         if (updateDimension) {
             if (width == -1) {
                 width = mPopupWidth;
@@ -1627,11 +1654,12 @@
             }
         }
 
-        int x = p.x;
-        int y = p.y;
-
+        final WindowManager.LayoutParams p =
+                (WindowManager.LayoutParams) mPopupView.getLayoutParams();
+        final int x = p.x;
+        final int y = p.y;
         if (updateLocation) {
-            updateAboveAnchor(findDropDownPosition(anchor, p, xoff, yoff, gravity));
+            updateAboveAnchor(findDropDownPosition(anchor, p, xoff, yoff, mAnchoredGravity));
         } else {
             updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff,
                     mAnchoredGravity));
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 99bb1ac..2b20b38 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -118,6 +118,10 @@
         mDropDownGravity = gravity;
     }
 
+    public int getGravity() {
+        return mDropDownGravity;
+    }
+
     public void show() {
         if (!tryShow()) {
             throw new IllegalStateException("MenuPopupHelper cannot be used without an anchor");
@@ -135,7 +139,7 @@
         mPopup.setAdapter(mAdapter);
         mPopup.setModal(true);
 
-        View anchor = mAnchorView;
+        final View anchor = mAnchorView;
         if (anchor != null) {
             final boolean addGlobalListener = mTreeObserver == null;
             mTreeObserver = anchor.getViewTreeObserver(); // Refresh to latest