Fix bug 2948913 - provide lifecycle notifications for action modes
Change-Id: I432e29a7bddb18bc32dfbe21a8ecd7d83158e3a0
diff --git a/api/current.xml b/api/current.xml
index 19c1384..d2bd8e5 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -21087,6 +21087,32 @@
<parameter name="nonRoot" type="boolean">
</parameter>
</method>
+<method name="onActionModeFinished"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mode" type="android.view.ActionMode">
+</parameter>
+</method>
+<method name="onActionModeStarted"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mode" type="android.view.ActionMode">
+</parameter>
+</method>
<method name="onActivityResult"
return="void"
abstract="false"
@@ -21722,19 +21748,6 @@
visibility="protected"
>
</method>
-<method name="onStartActionMode"
- return="android.view.ActionMode"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="callback" type="android.view.ActionMode.Callback">
-</parameter>
-</method>
<method name="onStop"
return="void"
abstract="false"
@@ -21835,6 +21848,19 @@
<parameter name="hasFocus" type="boolean">
</parameter>
</method>
+<method name="onWindowStartingActionMode"
+ return="android.view.ActionMode"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="callback" type="android.view.ActionMode.Callback">
+</parameter>
+</method>
<method name="openContextMenu"
return="void"
abstract="false"
@@ -25434,6 +25460,32 @@
visibility="public"
>
</method>
+<method name="onActionModeFinished"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mode" type="android.view.ActionMode">
+</parameter>
+</method>
+<method name="onActionModeStarted"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mode" type="android.view.ActionMode">
+</parameter>
+</method>
<method name="onAttachedToWindow"
return="void"
abstract="false"
@@ -25784,19 +25836,6 @@
visibility="protected"
>
</method>
-<method name="onStartActionMode"
- return="android.view.ActionMode"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="callback" type="android.view.ActionMode.Callback">
-</parameter>
-</method>
<method name="onStop"
return="void"
abstract="false"
@@ -25860,6 +25899,19 @@
<parameter name="hasFocus" type="boolean">
</parameter>
</method>
+<method name="onWindowStartingActionMode"
+ return="android.view.ActionMode"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="callback" type="android.view.ActionMode.Callback">
+</parameter>
+</method>
<method name="openContextMenu"
return="void"
abstract="false"
@@ -212083,6 +212135,32 @@
<parameter name="event" type="android.view.MotionEvent">
</parameter>
</method>
+<method name="onActionModeFinished"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mode" type="android.view.ActionMode">
+</parameter>
+</method>
+<method name="onActionModeStarted"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mode" type="android.view.ActionMode">
+</parameter>
+</method>
<method name="onAttachedToWindow"
return="void"
abstract="true"
@@ -212217,19 +212295,6 @@
visibility="public"
>
</method>
-<method name="onStartActionMode"
- return="android.view.ActionMode"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="callback" type="android.view.ActionMode.Callback">
-</parameter>
-</method>
<method name="onWindowAttributesChanged"
return="void"
abstract="true"
@@ -212256,6 +212321,19 @@
<parameter name="hasFocus" type="boolean">
</parameter>
</method>
+<method name="onWindowStartingActionMode"
+ return="android.view.ActionMode"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="callback" type="android.view.ActionMode.Callback">
+</parameter>
+</method>
</interface>
<interface name="WindowManager"
abstract="true"
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 33f88d8..07d21fb 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -4174,7 +4174,7 @@
}
/**
- * Start a context mode.
+ * Start an action mode.
*
* @param callback Callback that will manage lifecycle events for this context mode
* @return The ContextMode that was started, or null if it was canceled
@@ -4185,7 +4185,18 @@
return mWindow.getDecorView().startActionMode(callback);
}
- public ActionMode onStartActionMode(ActionMode.Callback callback) {
+ /**
+ * Give the Activity a chance to control the UI for an action mode requested
+ * by the system.
+ *
+ * <p>Note: If you are looking for a notification callback that an action mode
+ * has been started for this activity, see {@link #onActionModeStarted(ActionMode)}.</p>
+ *
+ * @param callback The callback that should control the new action mode
+ * @return The new action mode, or <code>null</code> if the activity does not want to
+ * provide special handling for this action mode. (It will be handled by the system.)
+ */
+ public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
initActionBar();
if (mActionBar != null) {
return mActionBar.startActionMode(callback);
@@ -4193,6 +4204,24 @@
return null;
}
+ /**
+ * Notifies the Activity that an action mode has been started.
+ * Activity subclasses overriding this method should call the superclass implementation.
+ *
+ * @param mode The new action mode.
+ */
+ public void onActionModeStarted(ActionMode mode) {
+ }
+
+ /**
+ * Notifies the activity that an action mode has finished.
+ * Activity subclasses overriding this method should call the superclass implementation.
+ *
+ * @param mode The action mode that just finished.
+ */
+ public void onActionModeFinished(ActionMode mode) {
+ }
+
// ------------------ Internal API ------------------
final void setParent(Activity parent) {
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 526129a..64a4d7a 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -867,13 +867,19 @@
}
}
- public ActionMode onStartActionMode(ActionMode.Callback callback) {
+ public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
if (mActionBar != null) {
return mActionBar.startActionMode(callback);
}
return null;
}
+ public void onActionModeStarted(ActionMode mode) {
+ }
+
+ public void onActionModeFinished(ActionMode mode) {
+ }
+
/**
* @return The activity associated with this dialog, or null if there is no associated activity.
*/
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index d5d9a2e..5385cd9 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -313,12 +313,31 @@
public boolean onSearchRequested();
/**
- * Called when an action mode is being started.
+ * Called when an action mode is being started for this window. Gives the
+ * callback an opportunity to handle the action mode in its own unique and
+ * beautiful way. If this method returns null the system can choose a way
+ * to present the mode or choose not to start the mode at all.
*
* @param callback Callback to control the lifecycle of this action mode
- * @return The ActionMode that was started, or null if it was canceled
+ * @return The ActionMode that was started, or null if the system should present it
*/
- public ActionMode onStartActionMode(ActionMode.Callback callback);
+ public ActionMode onWindowStartingActionMode(ActionMode.Callback callback);
+
+ /**
+ * Called when an action mode has been started. The appropriate mode callback
+ * method will have already been invoked.
+ *
+ * @param mode The new mode that has just been started.
+ */
+ public void onActionModeStarted(ActionMode mode);
+
+ /**
+ * Called when an action mode has been finished. The appropriate mode callback
+ * method will have already been invoked.
+ *
+ * @param mode The mode that was just finished.
+ */
+ public void onActionModeFinished(ActionMode mode);
}
public Window(Context context) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 3dd6510..bb39c8f 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -1832,7 +1832,7 @@
}
final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapper(callback);
- ActionMode mode = getCallback().onStartActionMode(wrappedCallback);
+ ActionMode mode = getCallback().onWindowStartingActionMode(wrappedCallback);
if (mode != null) {
mActionMode = mode;
} else {
@@ -1876,6 +1876,9 @@
}
}
}
+ if (mActionMode != null) {
+ getCallback().onActionModeStarted(mActionMode);
+ }
return mActionMode;
}
@@ -2091,6 +2094,7 @@
if (mActionModeView != null) {
mActionModeView.removeAllViews();
}
+ getCallback().onActionModeFinished(mActionMode);
mActionMode = null;
}
}