Merge "Add window layout type calls to PopupWindowCompat"
diff --git a/v4/api/current.txt b/v4/api/current.txt
index 95db435..829616f 100644
--- a/v4/api/current.txt
+++ b/v4/api/current.txt
@@ -2996,7 +2996,9 @@
 
   public class PopupWindowCompat {
     method public static boolean getOverlapAnchor(android.widget.PopupWindow);
+    method public static int getWindowLayoutType(android.widget.PopupWindow);
     method public static void setOverlapAnchor(android.widget.PopupWindow, boolean);
+    method public static void setWindowLayoutType(android.widget.PopupWindow, int);
     method public static void showAsDropDown(android.widget.PopupWindow, android.view.View, int, int, int);
   }
 
diff --git a/v4/api23/android/support/v4/widget/PopupWindowCompatApi23.java b/v4/api23/android/support/v4/widget/PopupWindowCompatApi23.java
index 61d74bd..96bf8d9 100644
--- a/v4/api23/android/support/v4/widget/PopupWindowCompatApi23.java
+++ b/v4/api23/android/support/v4/widget/PopupWindowCompatApi23.java
@@ -28,4 +28,12 @@
         return popupWindow.getOverlapAnchor();
     }
 
+    static void setWindowLayoutType(PopupWindow popupWindow, int layoutType) {
+        popupWindow.setWindowLayoutType(layoutType);
+    }
+
+    static int getWindowLayoutType(PopupWindow popupWindow) {
+        return popupWindow.getWindowLayoutType();
+    }
+
 }
diff --git a/v4/gingerbread/android/support/v4/widget/PopupWindowCompatGingerbread.java b/v4/gingerbread/android/support/v4/widget/PopupWindowCompatGingerbread.java
new file mode 100644
index 0000000..b87db30
--- /dev/null
+++ b/v4/gingerbread/android/support/v4/widget/PopupWindowCompatGingerbread.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 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
+ */
+
+package android.support.v4.widget;
+
+import android.widget.PopupWindow;
+
+import java.lang.reflect.Method;
+
+/**
+ * Implementation of PopupWindow compatibility that can call Gingerbread APIs.
+ */
+class PopupWindowCompatGingerbread {
+
+    private static Method sSetWindowLayoutTypeMethod;
+    private static boolean sSetWindowLayoutTypeMethodAttempted;
+    private static Method sGetWindowLayoutTypeMethod;
+    private static boolean sGetWindowLayoutTypeMethodAttempted;
+
+    static void setWindowLayoutType(PopupWindow popupWindow, int layoutType) {
+        if (!sSetWindowLayoutTypeMethodAttempted) {
+            try {
+                sSetWindowLayoutTypeMethod = PopupWindow.class.getDeclaredMethod(
+                        "setWindowLayoutType", int.class);
+                sSetWindowLayoutTypeMethod.setAccessible(true);
+            } catch (Exception e) {
+                // Reflection method fetch failed. Oh well.
+            }
+            sSetWindowLayoutTypeMethodAttempted = true;
+        }
+
+        if (sSetWindowLayoutTypeMethod != null) {
+            try {
+                sSetWindowLayoutTypeMethod.invoke(popupWindow, layoutType);
+            } catch (Exception e) {
+                // Reflection call failed. Oh well.
+            }
+        }
+    }
+
+    static int getWindowLayoutType(PopupWindow popupWindow) {
+        if (!sGetWindowLayoutTypeMethodAttempted) {
+            try {
+                sGetWindowLayoutTypeMethod = PopupWindow.class.getDeclaredMethod(
+                        "getWindowLayoutType");
+                sGetWindowLayoutTypeMethod.setAccessible(true);
+            } catch (Exception e) {
+                // Reflection method fetch failed. Oh well.
+            }
+            sGetWindowLayoutTypeMethodAttempted = true;
+        }
+
+        if (sGetWindowLayoutTypeMethod != null) {
+            try {
+                return (Integer) sGetWindowLayoutTypeMethod.invoke(popupWindow);
+            } catch (Exception e) {
+                // Reflection call failed. Oh well.
+            }
+        }
+        return 0;
+    }
+
+}
diff --git a/v4/java/android/support/v4/widget/PopupWindowCompat.java b/v4/java/android/support/v4/widget/PopupWindowCompat.java
index c765522..7f4c828 100644
--- a/v4/java/android/support/v4/widget/PopupWindowCompat.java
+++ b/v4/java/android/support/v4/widget/PopupWindowCompat.java
@@ -17,6 +17,7 @@
 package android.support.v4.widget;
 
 import android.view.View;
+import android.view.WindowManager;
 import android.widget.PopupWindow;
 
 /**
@@ -28,10 +29,11 @@
      * Interface for the full API.
      */
     interface PopupWindowImpl {
-        public void showAsDropDown(PopupWindow popup, View anchor, int xoff, int yoff,
-                int gravity);
-        public void setOverlapAnchor(PopupWindow popupWindow, boolean overlapAnchor);
-        public boolean getOverlapAnchor(PopupWindow popupWindow);
+        void showAsDropDown(PopupWindow popup, View anchor, int xoff, int yoff, int gravity);
+        void setOverlapAnchor(PopupWindow popupWindow, boolean overlapAnchor);
+        boolean getOverlapAnchor(PopupWindow popupWindow);
+        void setWindowLayoutType(PopupWindow popupWindow, int layoutType);
+        int getWindowLayoutType(PopupWindow popupWindow);
     }
 
     /**
@@ -53,12 +55,37 @@
         public boolean getOverlapAnchor(PopupWindow popupWindow) {
             return false;
         }
+
+        @Override
+        public void setWindowLayoutType(PopupWindow popupWindow, int layoutType) {
+            // no-op
+        }
+
+        @Override
+        public int getWindowLayoutType(PopupWindow popupWindow) {
+            return 0;
+        }
+    }
+
+    /**
+     * Interface implementation that doesn't use anything above v4 APIs.
+     */
+    static class GingerbreadPopupWindowImpl extends BasePopupWindowImpl {
+        @Override
+        public void setWindowLayoutType(PopupWindow popupWindow, int layoutType) {
+            PopupWindowCompatGingerbread.setWindowLayoutType(popupWindow, layoutType);
+        }
+
+        @Override
+        public int getWindowLayoutType(PopupWindow popupWindow) {
+            return PopupWindowCompatGingerbread.getWindowLayoutType(popupWindow);
+        }
     }
 
     /**
      * Interface implementation for devices with at least KitKat APIs.
      */
-    static class KitKatPopupWindowImpl extends BasePopupWindowImpl {
+    static class KitKatPopupWindowImpl extends GingerbreadPopupWindowImpl {
         @Override
         public void showAsDropDown(PopupWindow popup, View anchor, int xoff, int yoff,
                 int gravity) {
@@ -88,6 +115,16 @@
         public boolean getOverlapAnchor(PopupWindow popupWindow) {
             return PopupWindowCompatApi23.getOverlapAnchor(popupWindow);
         }
+
+        @Override
+        public void setWindowLayoutType(PopupWindow popupWindow, int layoutType) {
+            PopupWindowCompatApi23.setWindowLayoutType(popupWindow, layoutType);
+        }
+
+        @Override
+        public int getWindowLayoutType(PopupWindow popupWindow) {
+            return PopupWindowCompatApi23.getWindowLayoutType(popupWindow);
+        }
     }
 
     /**
@@ -102,6 +139,8 @@
             IMPL = new Api21PopupWindowImpl();
         } else if (version >= 19) {
             IMPL = new KitKatPopupWindowImpl();
+        } else if (version >= 9) {
+            IMPL = new GingerbreadPopupWindowImpl();
         } else {
             IMPL = new BasePopupWindowImpl();
         }
@@ -151,4 +190,26 @@
     public static boolean getOverlapAnchor(PopupWindow popupWindow) {
         return IMPL.getOverlapAnchor(popupWindow);
     }
+
+    /**
+     * Set the layout type for this window. This value will be passed through to
+     * {@link WindowManager.LayoutParams#type} therefore the value should match any value
+     * {@link WindowManager.LayoutParams#type} accepts.
+     *
+     * @param layoutType Layout type for this window.
+     *
+     * @see WindowManager.LayoutParams#type
+     */
+    public static void setWindowLayoutType(PopupWindow popupWindow, int layoutType) {
+        IMPL.setWindowLayoutType(popupWindow, layoutType);
+    }
+
+    /**
+     * Returns the layout type for this window.
+     *
+     * @see #setWindowLayoutType(PopupWindow popupWindow, int)
+     */
+    public static int getWindowLayoutType(PopupWindow popupWindow) {
+        return IMPL.getWindowLayoutType(popupWindow);
+    }
 }