1 package com
.actionbarsherlock
;
3 import static android
.view
.ViewGroup
.LayoutParams
.MATCH_PARENT
;
4 import java
.lang
.annotation
.ElementType
;
5 import java
.lang
.annotation
.Retention
;
6 import java
.lang
.annotation
.RetentionPolicy
;
7 import java
.lang
.annotation
.Target
;
8 import java
.lang
.reflect
.Constructor
;
9 import java
.lang
.reflect
.InvocationTargetException
;
10 import java
.util
.HashMap
;
11 import java
.util
.Iterator
;
12 import android
.app
.Activity
;
13 import android
.content
.Context
;
14 import android
.content
.res
.Configuration
;
15 import android
.os
.Build
;
16 import android
.os
.Bundle
;
17 import android
.util
.DisplayMetrics
;
18 import android
.util
.Log
;
19 import android
.view
.KeyEvent
;
20 import android
.view
.View
;
21 import android
.view
.ViewGroup
;
22 import android
.view
.Window
;
23 import com
.actionbarsherlock
.app
.ActionBar
;
24 import com
.actionbarsherlock
.internal
.ActionBarSherlockCompat
;
25 import com
.actionbarsherlock
.internal
.ActionBarSherlockNative
;
26 import com
.actionbarsherlock
.view
.ActionMode
;
27 import com
.actionbarsherlock
.view
.Menu
;
28 import com
.actionbarsherlock
.view
.MenuInflater
;
29 import com
.actionbarsherlock
.view
.MenuItem
;
32 * <p>Helper for implementing the action bar design pattern across all versions
35 * <p>This class will manage interaction with a custom action bar based on the
36 * Android 4.0 source code. The exposed API mirrors that of its native
37 * counterpart and you should refer to its documentation for instruction.</p>
39 * @author Jake Wharton <jakewharton@gmail.com>
41 public abstract class ActionBarSherlock
{
42 protected static final String TAG
= "ActionBarSherlock";
43 protected static final boolean DEBUG
= false
;
45 private static final Class
<?
>[] CONSTRUCTOR_ARGS
= new Class
[] { Activity
.class, int.class };
46 private static final HashMap
<Implementation
, Class
<?
extends ActionBarSherlock
>> IMPLEMENTATIONS
=
47 new HashMap
<Implementation
, Class
<?
extends ActionBarSherlock
>>();
50 //Register our two built-in implementations
51 registerImplementation(ActionBarSherlockCompat
.class);
52 registerImplementation(ActionBarSherlockNative
.class);
57 * <p>Denotes an implementation of ActionBarSherlock which provides an
58 * action bar-enhanced experience.</p>
60 @Target(ElementType
.TYPE
)
61 @Retention(RetentionPolicy
.RUNTIME
)
62 public @interface Implementation
{
63 static final int DEFAULT_API
= -1;
64 static final int DEFAULT_DPI
= -1;
66 int api() default DEFAULT_API
;
67 int dpi() default DEFAULT_DPI
;
71 /** Activity interface for menu creation callback. */
72 public interface OnCreatePanelMenuListener
{
73 public boolean onCreatePanelMenu(int featureId
, Menu menu
);
75 /** Activity interface for menu creation callback. */
76 public interface OnCreateOptionsMenuListener
{
77 public boolean onCreateOptionsMenu(Menu menu
);
79 /** Activity interface for menu item selection callback. */
80 public interface OnMenuItemSelectedListener
{
81 public boolean onMenuItemSelected(int featureId
, MenuItem item
);
83 /** Activity interface for menu item selection callback. */
84 public interface OnOptionsItemSelectedListener
{
85 public boolean onOptionsItemSelected(MenuItem item
);
87 /** Activity interface for menu preparation callback. */
88 public interface OnPreparePanelListener
{
89 public boolean onPreparePanel(int featureId
, View view
, Menu menu
);
91 /** Activity interface for menu preparation callback. */
92 public interface OnPrepareOptionsMenuListener
{
93 public boolean onPrepareOptionsMenu(Menu menu
);
95 /** Activity interface for action mode finished callback. */
96 public interface OnActionModeFinishedListener
{
97 public void onActionModeFinished(ActionMode mode
);
99 /** Activity interface for action mode started callback. */
100 public interface OnActionModeStartedListener
{
101 public void onActionModeStarted(ActionMode mode
);
106 * If set, the logic in these classes will assume that an {@link Activity}
107 * is dispatching all of the required events to the class. This flag should
108 * only be used internally or if you are creating your own base activity
109 * modeled after one of the included types (e.g., {@code SherlockActivity}).
111 public static final int FLAG_DELEGATE
= 1;
115 * Register an ActionBarSherlock implementation.
117 * @param implementationClass Target implementation class which extends
118 * {@link ActionBarSherlock}. This class must also be annotated with
119 * {@link Implementation}.
121 public static void registerImplementation(Class
<?
extends ActionBarSherlock
> implementationClass
) {
122 if (!implementationClass
.isAnnotationPresent(Implementation
.class)) {
123 throw new IllegalArgumentException("Class " + implementationClass
.getSimpleName() + " is not annotated with @Implementation");
124 } else if (IMPLEMENTATIONS
.containsValue(implementationClass
)) {
125 if (DEBUG
) Log
.w(TAG
, "Class " + implementationClass
.getSimpleName() + " already registered");
129 Implementation impl
= implementationClass
.getAnnotation(Implementation
.class);
130 if (DEBUG
) Log
.i(TAG
, "Registering " + implementationClass
.getSimpleName() + " with qualifier " + impl
);
131 IMPLEMENTATIONS
.put(impl
, implementationClass
);
135 * Unregister an ActionBarSherlock implementation. <strong>This should be
136 * considered very volatile and you should only use it if you know what
137 * you are doing.</strong> You have been warned.
139 * @param implementationClass Target implementation class.
140 * @return Boolean indicating whether the class was removed.
142 public static boolean unregisterImplementation(Class
<?
extends ActionBarSherlock
> implementationClass
) {
143 return IMPLEMENTATIONS
.values().remove(implementationClass
);
147 * Wrap an activity with an action bar abstraction which will enable the
148 * use of a custom implementation on platforms where a native version does
151 * @param activity Activity to wrap.
152 * @return Instance to interact with the action bar.
154 public static ActionBarSherlock
wrap(Activity activity
) {
155 return wrap(activity
, 0);
159 * Wrap an activity with an action bar abstraction which will enable the
160 * use of a custom implementation on platforms where a native version does
163 * @param activity Owning activity.
164 * @param flags Option flags to control behavior.
165 * @return Instance to interact with the action bar.
167 public static ActionBarSherlock
wrap(Activity activity
, int flags
) {
168 //Create a local implementation map we can modify
169 HashMap
<Implementation
, Class
<?
extends ActionBarSherlock
>> impls
=
170 new HashMap
<Implementation
, Class
<?
extends ActionBarSherlock
>>(IMPLEMENTATIONS
);
175 for (Implementation key
: impls
.keySet()) {
176 //Only honor TVDPI as a specific qualifier
177 if (key
.dpi() == DisplayMetrics
.DENSITY_TV
) {
183 final boolean isTvDpi
= activity
.getResources().getDisplayMetrics().densityDpi
== DisplayMetrics
.DENSITY_TV
;
184 for (Iterator
<Implementation
> keys
= impls
.keySet().iterator(); keys
.hasNext(); ) {
185 int keyDpi
= keys
.next().dpi();
186 if ((isTvDpi
&& keyDpi
!= DisplayMetrics
.DENSITY_TV
)
187 || (!isTvDpi
&& keyDpi
== DisplayMetrics
.DENSITY_TV
)) {
195 for (Implementation key
: impls
.keySet()) {
196 if (key
.api() != Implementation
.DEFAULT_API
) {
202 final int runtimeApi
= Build
.VERSION
.SDK_INT
;
204 for (Iterator
<Implementation
> keys
= impls
.keySet().iterator(); keys
.hasNext(); ) {
205 int keyApi
= keys
.next().api();
206 if (keyApi
> runtimeApi
) {
208 } else if (keyApi
> bestApi
) {
212 for (Iterator
<Implementation
> keys
= impls
.keySet().iterator(); keys
.hasNext(); ) {
213 if (keys
.next().api() != bestApi
) {
219 if (impls
.size() > 1) {
220 throw new IllegalStateException("More than one implementation matches configuration.");
222 if (impls
.isEmpty()) {
223 throw new IllegalStateException("No implementations match configuration.");
225 Class
<?
extends ActionBarSherlock
> impl
= impls
.values().iterator().next();
226 if (DEBUG
) Log
.i(TAG
, "Using implementation: " + impl
.getSimpleName());
229 Constructor
<?
extends ActionBarSherlock
> ctor
= impl
.getConstructor(CONSTRUCTOR_ARGS
);
230 return ctor
.newInstance(activity
, flags
);
231 } catch (NoSuchMethodException e
) {
232 throw new RuntimeException(e
);
233 } catch (IllegalArgumentException e
) {
234 throw new RuntimeException(e
);
235 } catch (InstantiationException e
) {
236 throw new RuntimeException(e
);
237 } catch (IllegalAccessException e
) {
238 throw new RuntimeException(e
);
239 } catch (InvocationTargetException e
) {
240 throw new RuntimeException(e
);
245 /** Activity which is displaying the action bar. Also used for context. */
246 protected final Activity mActivity
;
247 /** Whether delegating actions for the activity or managing ourselves. */
248 protected final boolean mIsDelegate
;
250 /** Reference to our custom menu inflater which supports action items. */
251 protected MenuInflater mMenuInflater
;
255 protected ActionBarSherlock(Activity activity
, int flags
) {
256 if (DEBUG
) Log
.d(TAG
, "[<ctor>] activity: " + activity
+ ", flags: " + flags
);
258 mActivity
= activity
;
259 mIsDelegate
= (flags
& FLAG_DELEGATE
) != 0;
264 * Get the current action bar instance.
266 * @return Action bar instance.
268 public abstract ActionBar
getActionBar();
271 ///////////////////////////////////////////////////////////////////////////
272 // Lifecycle and interaction callbacks when delegating
273 ///////////////////////////////////////////////////////////////////////////
276 * Notify action bar of a configuration change event. Should be dispatched
277 * after the call to the superclass implementation.
281 * public void onConfigurationChanged(Configuration newConfig) {
282 * super.onConfigurationChanged(newConfig);
283 * mSherlock.dispatchConfigurationChanged(newConfig);
285 * </pre></blockquote>
287 * @param newConfig The new device configuration.
289 public void dispatchConfigurationChanged(Configuration newConfig
) {}
292 * Notify the action bar that the activity has finished its resuming. This
293 * should be dispatched after the call to the superclass implementation.
297 * protected void onPostResume() {
298 * super.onPostResume();
299 * mSherlock.dispatchPostResume();
301 * </pre></blockquote>
303 public void dispatchPostResume() {}
306 * Notify the action bar that the activity is pausing. This should be
307 * dispatched before the call to the superclass implementation.
311 * protected void onPause() {
312 * mSherlock.dispatchPause();
315 * </pre></blockquote>
317 public void dispatchPause() {}
320 * Notify the action bar that the activity is stopping. This should be
321 * called before the superclass implementation.
325 * protected void onStop() {
326 * mSherlock.dispatchStop();
331 public void dispatchStop() {}
334 * Indicate that the menu should be recreated by calling
335 * {@link OnCreateOptionsMenuListener#onCreateOptionsMenu(com.actionbarsherlock.view.Menu)}.
337 public abstract void dispatchInvalidateOptionsMenu();
340 * Notify the action bar that it should display its overflow menu if it is
341 * appropriate for the device. The implementation should conditionally
342 * call the superclass method only if this method returns {@code false}.
346 * public void openOptionsMenu() {
347 * if (!mSherlock.dispatchOpenOptionsMenu()) {
348 * super.openOptionsMenu();
353 * @return {@code true} if the opening of the menu was handled internally.
355 public boolean dispatchOpenOptionsMenu() {
360 * Notify the action bar that it should close its overflow menu if it is
361 * appropriate for the device. This implementation should conditionally
362 * call the superclass method only if this method returns {@code false}.
366 * public void closeOptionsMenu() {
367 * if (!mSherlock.dispatchCloseOptionsMenu()) {
368 * super.closeOptionsMenu();
371 * </pre></blockquote>
373 * @return {@code true} if the closing of the menu was handled internally.
375 public boolean dispatchCloseOptionsMenu() {
380 * Notify the class that the activity has finished its creation. This
381 * should be called after the superclass implementation.
385 * protected void onPostCreate(Bundle savedInstanceState) {
386 * mSherlock.dispatchPostCreate(savedInstanceState);
387 * super.onPostCreate(savedInstanceState);
389 * </pre></blockquote>
391 * @param savedInstanceState If the activity is being re-initialized after
392 * previously being shut down then this Bundle
393 * contains the data it most recently supplied in
394 * {@link Activity#}onSaveInstanceState(Bundle)}.
395 * <strong>Note: Otherwise it is null.</strong>
397 public void dispatchPostCreate(Bundle savedInstanceState
) {}
400 * Notify the action bar that the title has changed and the action bar
401 * should be updated to reflect the change. This should be called before
402 * the superclass implementation.
406 * protected void onTitleChanged(CharSequence title, int color) {
407 * mSherlock.dispatchTitleChanged(title, color);
408 * super.onTitleChanged(title, color);
410 * </pre></blockquote>
412 * @param title New activity title.
413 * @param color New activity color.
415 public void dispatchTitleChanged(CharSequence title
, int color
) {}
418 * Notify the action bar the user has created a key event. This is used to
419 * toggle the display of the overflow action item with the menu key and to
420 * close the action mode or expanded action item with the back key.
424 * public boolean dispatchKeyEvent(KeyEvent event) {
425 * if (mSherlock.dispatchKeyEvent(event)) {
428 * return super.dispatchKeyEvent(event);
430 * </pre></blockquote>
432 * @param event Description of the key event.
433 * @return {@code true} if the event was handled.
435 public boolean dispatchKeyEvent(KeyEvent event
) {
440 * Notify the action bar that the Activity has triggered a menu creation
441 * which should happen on the conclusion of {@link Activity#onCreate}. This
442 * will be used to gain a reference to the native menu for native and
443 * overflow binding as well as to indicate when compatibility create should
444 * occur for the first time.
446 * @param menu Activity native menu.
447 * @return {@code true} since we always want to say that we have a native
449 public abstract boolean dispatchCreateOptionsMenu(android
.view
.Menu menu
);
452 * Notify the action bar that the Activity has triggered a menu preparation
453 * which usually means that the user has requested the overflow menu via a
454 * hardware menu key. You should return the result of this method call and
455 * not call the superclass implementation.
459 * public final boolean onPrepareOptionsMenu(android.view.Menu menu) {
460 * return mSherlock.dispatchPrepareOptionsMenu(menu);
464 * @param menu Activity native menu.
465 * @return {@code true} if menu display should proceed.
467 public abstract boolean dispatchPrepareOptionsMenu(android
.view
.Menu menu
);
470 * Notify the action bar that a native options menu item has been selected.
471 * The implementation should return the result of this method call.
475 * public final boolean onOptionsItemSelected(android.view.MenuItem item) {
476 * return mSherlock.dispatchOptionsItemSelected(item);
480 * @param item Options menu item.
481 * @return @{code true} if the selection was handled.
483 public abstract boolean dispatchOptionsItemSelected(android
.view
.MenuItem item
);
486 * Notify the action bar that the overflow menu has been opened. The
487 * implementation should conditionally return {@code true} if this method
488 * returns {@code true}, otherwise return the result of the superclass
493 * public final boolean onMenuOpened(int featureId, android.view.Menu menu) {
494 * if (mSherlock.dispatchMenuOpened(featureId, menu)) {
497 * return super.onMenuOpened(featureId, menu);
501 * @param featureId Window feature which triggered the event.
502 * @param menu Activity native menu.
503 * @return {@code true} if the event was handled by this method.
505 public boolean dispatchMenuOpened(int featureId
, android
.view
.Menu menu
) {
510 * Notify the action bar that the overflow menu has been closed. This
511 * method should be called before the superclass implementation.
515 * public void onPanelClosed(int featureId, android.view.Menu menu) {
516 * mSherlock.dispatchPanelClosed(featureId, menu);
517 * super.onPanelClosed(featureId, menu);
524 public void dispatchPanelClosed(int featureId
, android
.view
.Menu menu
) {}
527 * Notify the action bar that the activity has been destroyed. This method
528 * should be called before the superclass implementation.
532 * public void onDestroy() {
533 * mSherlock.dispatchDestroy();
538 public void dispatchDestroy() {}
540 public void dispatchSaveInstanceState(Bundle outState
) {}
542 public void dispatchRestoreInstanceState(Bundle savedInstanceState
) {}
544 ///////////////////////////////////////////////////////////////////////////
545 ///////////////////////////////////////////////////////////////////////////
549 * Internal method to trigger the menu creation process.
551 * @return {@code true} if menu creation should proceed.
553 protected final boolean callbackCreateOptionsMenu(Menu menu
) {
554 if (DEBUG
) Log
.d(TAG
, "[callbackCreateOptionsMenu] menu: " + menu
);
556 boolean result
= true
;
557 if (mActivity
instanceof OnCreatePanelMenuListener
) {
558 OnCreatePanelMenuListener listener
= (OnCreatePanelMenuListener
)mActivity
;
559 result
= listener
.onCreatePanelMenu(Window
.FEATURE_OPTIONS_PANEL
, menu
);
560 } else if (mActivity
instanceof OnCreateOptionsMenuListener
) {
561 OnCreateOptionsMenuListener listener
= (OnCreateOptionsMenuListener
)mActivity
;
562 result
= listener
.onCreateOptionsMenu(menu
);
565 if (DEBUG
) Log
.d(TAG
, "[callbackCreateOptionsMenu] returning " + result
);
570 * Internal method to trigger the menu preparation process.
572 * @return {@code true} if menu preparation should proceed.
574 protected final boolean callbackPrepareOptionsMenu(Menu menu
) {
575 if (DEBUG
) Log
.d(TAG
, "[callbackPrepareOptionsMenu] menu: " + menu
);
577 boolean result
= true
;
578 if (mActivity
instanceof OnPreparePanelListener
) {
579 OnPreparePanelListener listener
= (OnPreparePanelListener
)mActivity
;
580 result
= listener
.onPreparePanel(Window
.FEATURE_OPTIONS_PANEL
, null
, menu
);
581 } else if (mActivity
instanceof OnPrepareOptionsMenuListener
) {
582 OnPrepareOptionsMenuListener listener
= (OnPrepareOptionsMenuListener
)mActivity
;
583 result
= listener
.onPrepareOptionsMenu(menu
);
586 if (DEBUG
) Log
.d(TAG
, "[callbackPrepareOptionsMenu] returning " + result
);
591 * Internal method for dispatching options menu selection to the owning
594 * @param item Selected options menu item.
595 * @return {@code true} if the item selection was handled in the callback.
597 protected final boolean callbackOptionsItemSelected(MenuItem item
) {
598 if (DEBUG
) Log
.d(TAG
, "[callbackOptionsItemSelected] item: " + item
.getTitleCondensed());
600 boolean result
= false
;
601 if (mActivity
instanceof OnMenuItemSelectedListener
) {
602 OnMenuItemSelectedListener listener
= (OnMenuItemSelectedListener
)mActivity
;
603 result
= listener
.onMenuItemSelected(Window
.FEATURE_OPTIONS_PANEL
, item
);
604 } else if (mActivity
instanceof OnOptionsItemSelectedListener
) {
605 OnOptionsItemSelectedListener listener
= (OnOptionsItemSelectedListener
)mActivity
;
606 result
= listener
.onOptionsItemSelected(item
);
609 if (DEBUG
) Log
.d(TAG
, "[callbackOptionsItemSelected] returning " + result
);
614 ///////////////////////////////////////////////////////////////////////////
615 ///////////////////////////////////////////////////////////////////////////
619 * Query for the availability of a certain feature.
621 * @param featureId The feature ID to check.
622 * @return {@code true} if feature is enabled, {@code false} otherwise.
624 public abstract boolean hasFeature(int featureId
);
627 * Enable extended screen features. This must be called before
628 * {@code setContentView()}. May be called as many times as desired as long
629 * as it is before {@code setContentView()}. If not called, no extended
630 * features will be available. You can not turn off a feature once it is
633 * @param featureId The desired features, defined as constants by Window.
634 * @return Returns true if the requested feature is supported and now
637 public abstract boolean requestFeature(int featureId
);
640 * Set extra options that will influence the UI for this window.
642 * @param uiOptions Flags specifying extra options for this window.
644 public abstract void setUiOptions(int uiOptions
);
647 * Set extra options that will influence the UI for this window. Only the
648 * bits filtered by mask will be modified.
650 * @param uiOptions Flags specifying extra options for this window.
651 * @param mask Flags specifying which options should be modified. Others
652 * will remain unchanged.
654 public abstract void setUiOptions(int uiOptions
, int mask
);
657 * Set the content of the activity inside the action bar.
659 * @param layoutResId Layout resource ID.
661 public abstract void setContentView(int layoutResId
);
664 * Set the content of the activity inside the action bar.
666 * @param view The desired content to display.
668 public void setContentView(View view
) {
669 if (DEBUG
) Log
.d(TAG
, "[setContentView] view: " + view
);
671 setContentView(view
, new ViewGroup
.LayoutParams(MATCH_PARENT
, MATCH_PARENT
));
675 * Set the content of the activity inside the action bar.
677 * @param view The desired content to display.
678 * @param params Layout parameters to apply to the view.
680 public abstract void setContentView(View view
, ViewGroup
.LayoutParams params
);
683 * Variation on {@link #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)}
684 * to add an additional content view to the screen. Added after any
685 * existing ones on the screen -- existing views are NOT removed.
687 * @param view The desired content to display.
688 * @param params Layout parameters for the view.
690 public abstract void addContentView(View view
, ViewGroup
.LayoutParams params
);
693 * Change the title associated with this activity.
695 public abstract void setTitle(CharSequence title
);
698 * Change the title associated with this activity.
700 public void setTitle(int resId
) {
701 if (DEBUG
) Log
.d(TAG
, "[setTitle] resId: " + resId
);
703 setTitle(mActivity
.getString(resId
));
707 * Sets the visibility of the progress bar in the title.
709 * In order for the progress bar to be shown, the feature must be requested
710 * via {@link #requestWindowFeature(int)}.
712 * @param visible Whether to show the progress bars in the title.
714 public abstract void setProgressBarVisibility(boolean visible
);
717 * Sets the visibility of the indeterminate progress bar in the title.
719 * In order for the progress bar to be shown, the feature must be requested
720 * via {@link #requestWindowFeature(int)}.
722 * @param visible Whether to show the progress bars in the title.
724 public abstract void setProgressBarIndeterminateVisibility(boolean visible
);
727 * Sets whether the horizontal progress bar in the title should be indeterminate (the circular
728 * is always indeterminate).
730 * In order for the progress bar to be shown, the feature must be requested
731 * via {@link #requestWindowFeature(int)}.
733 * @param indeterminate Whether the horizontal progress bar should be indeterminate.
735 public abstract void setProgressBarIndeterminate(boolean indeterminate
);
738 * Sets the progress for the progress bars in the title.
740 * In order for the progress bar to be shown, the feature must be requested
741 * via {@link #requestWindowFeature(int)}.
743 * @param progress The progress for the progress bar. Valid ranges are from
744 * 0 to 10000 (both inclusive). If 10000 is given, the progress
745 * bar will be completely filled and will fade out.
747 public abstract void setProgress(int progress
);
750 * Sets the secondary progress for the progress bar in the title. This
751 * progress is drawn between the primary progress (set via
752 * {@link #setProgress(int)} and the background. It can be ideal for media
753 * scenarios such as showing the buffering progress while the default
754 * progress shows the play progress.
756 * In order for the progress bar to be shown, the feature must be requested
757 * via {@link #requestWindowFeature(int)}.
759 * @param secondaryProgress The secondary progress for the progress bar. Valid ranges are from
760 * 0 to 10000 (both inclusive).
762 public abstract void setSecondaryProgress(int secondaryProgress
);
765 * Get a menu inflater instance which supports the newer menu attributes.
767 * @return Menu inflater instance.
769 public MenuInflater
getMenuInflater() {
770 if (DEBUG
) Log
.d(TAG
, "[getMenuInflater]");
772 // Make sure that action views can get an appropriate theme.
773 if (mMenuInflater
== null
) {
774 if (getActionBar() != null
) {
775 mMenuInflater
= new MenuInflater(getThemedContext(), mActivity
);
777 mMenuInflater
= new MenuInflater(mActivity
);
780 return mMenuInflater
;
783 protected abstract Context
getThemedContext();
786 * Start an action mode.
788 * @param callback Callback that will manage lifecycle events for this
790 * @return The ContextMode that was started, or null if it was canceled.
793 public abstract ActionMode
startActionMode(ActionMode
.Callback callback
);