Merge "Floating toolbars: Add content rect related methods to API"
diff --git a/api/current.txt b/api/current.txt
index 7bac613..7e74c61 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -32918,6 +32918,7 @@
     method public boolean getTitleOptionalHint();
     method public int getType();
     method public abstract void invalidate();
+    method public void invalidateContentRect();
     method public boolean isTitleOptional();
     method public abstract void setCustomView(android.view.View);
     method public abstract void setSubtitle(java.lang.CharSequence);
@@ -32938,6 +32939,11 @@
     method public abstract boolean onPrepareActionMode(android.view.ActionMode, android.view.Menu);
   }
 
+  public static abstract class ActionMode.Callback2 implements android.view.ActionMode.Callback {
+    ctor public ActionMode.Callback2();
+    method public void onGetContentRect(android.view.ActionMode, android.view.View, android.graphics.Rect);
+  }
+
   public abstract class ActionProvider {
     ctor public ActionProvider(android.content.Context);
     method public boolean hasSubMenu();
diff --git a/api/system-current.txt b/api/system-current.txt
index 89c0460e..30da80c 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -35274,6 +35274,7 @@
     method public boolean getTitleOptionalHint();
     method public int getType();
     method public abstract void invalidate();
+    method public void invalidateContentRect();
     method public boolean isTitleOptional();
     method public abstract void setCustomView(android.view.View);
     method public abstract void setSubtitle(java.lang.CharSequence);
@@ -35294,6 +35295,11 @@
     method public abstract boolean onPrepareActionMode(android.view.ActionMode, android.view.Menu);
   }
 
+  public static abstract class ActionMode.Callback2 implements android.view.ActionMode.Callback {
+    ctor public ActionMode.Callback2();
+    method public void onGetContentRect(android.view.ActionMode, android.view.View, android.graphics.Rect);
+  }
+
   public abstract class ActionProvider {
     ctor public ActionProvider(android.content.Context);
     method public boolean hasSubMenu();
diff --git a/core/java/android/view/ActionMode.java b/core/java/android/view/ActionMode.java
index a018138..9f202a9 100644
--- a/core/java/android/view/ActionMode.java
+++ b/core/java/android/view/ActionMode.java
@@ -18,6 +18,7 @@
 
 
 import android.annotation.StringRes;
+import android.graphics.Rect;
 
 /**
  * Represents a contextual mode of the user interface. Action modes can be used to provide
@@ -197,6 +198,15 @@
     public abstract void invalidate();
 
     /**
+     * Invalidate the content rect associated to this ActionMode. This only makes sense for
+     * action modes that support dynamic positioning on the screen, and provides a more efficient
+     * way to reposition it without invalidating the whole action mode.
+     *
+     * @see Callback2#onGetContentRect(ActionMode, View, Rect) .
+     */
+    public void invalidateContentRect() {}
+
+    /**
      * Finish and close this action mode. The action mode's {@link ActionMode.Callback} will
      * have its {@link Callback#onDestroyActionMode(ActionMode)} method called.
      */
@@ -298,4 +308,31 @@
          */
         public void onDestroyActionMode(ActionMode mode);
     }
-}
\ No newline at end of file
+
+    /**
+     * Extension of {@link ActionMode.Callback} to provide content rect information. This is
+     * required for ActionModes with dynamic positioning such as the ones with type
+     * {@link ActionMode#TYPE_FLOATING} to ensure the positioning doesn't obscure app content. If
+     * an app fails to provide a subclass of this class, a default implementation will be used.
+     */
+    public static abstract class Callback2 implements ActionMode.Callback {
+
+        /**
+         * Called when an ActionMode needs to be positioned on screen, potentially occluding view
+         * content. Note this may be called on a per-frame basis.
+         *
+         * @param mode The ActionMode that requires positioning.
+         * @param view The View that originated the ActionMode, in whose coordinates the Rect should
+         *          be provided.
+         * @param outRect The Rect to be populated with the content position.
+         */
+        public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
+            if (view != null) {
+                outRect.set(0, 0, view.getWidth(), view.getHeight());
+            } else {
+                outRect.set(0, 0, 0, 0);
+            }
+        }
+
+    }
+}
diff --git a/core/java/android/view/PhoneWindow.java b/core/java/android/view/PhoneWindow.java
index 8aef18a..37859b8 100644
--- a/core/java/android/view/PhoneWindow.java
+++ b/core/java/android/view/PhoneWindow.java
@@ -2669,17 +2669,13 @@
         @Override
         public ActionMode startActionModeForChild(View originalView,
                 ActionMode.Callback callback) {
-            // originalView can be used here to be sure that we don't obscure
-            // relevant content with the context mode UI.
-            return startActionMode(callback);
+            return startActionModeForChild(originalView, callback, ActionMode.TYPE_PRIMARY);
         }
 
         @Override
         public ActionMode startActionModeForChild(
                 View child, ActionMode.Callback callback, int type) {
-            // originalView can be used here to be sure that we don't obscure
-            // relevant content with the context mode UI.
-            return startActionMode(callback, type);
+            return startActionMode(child, callback, type);
         }
 
         @Override
@@ -2689,7 +2685,12 @@
 
         @Override
         public ActionMode startActionMode(ActionMode.Callback callback, int type) {
-            ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapper(callback);
+            return startActionMode(this, callback, type);
+        }
+
+        private ActionMode startActionMode(
+                View originatingView, ActionMode.Callback callback, int type) {
+            ActionMode.Callback2 wrappedCallback = new ActionModeCallback2Wrapper(callback);
             ActionMode mode = null;
             if (getCallback() != null && !isDestroyed()) {
                 try {
@@ -3291,12 +3292,12 @@
         }
 
         /**
-         * Clears out internal reference when the action mode is destroyed.
+         * Clears out internal references when the action mode is destroyed.
          */
-        private class ActionModeCallbackWrapper implements ActionMode.Callback {
-            private ActionMode.Callback mWrapped;
+        private class ActionModeCallback2Wrapper extends ActionMode.Callback2 {
+            private final ActionMode.Callback mWrapped;
 
-            public ActionModeCallbackWrapper(ActionMode.Callback wrapped) {
+            public ActionModeCallback2Wrapper(ActionMode.Callback wrapped) {
                 mWrapped = wrapped;
             }