Merge commit '42b2e5ca519766e37ce6941ba4faecc9691cc403' into upstream
[debian/openrocket] / android-libraries / ActionBarSherlock / src / com / actionbarsherlock / ActionBarSherlock.java
diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/ActionBarSherlock.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/ActionBarSherlock.java
new file mode 100644 (file)
index 0000000..8340fb5
--- /dev/null
@@ -0,0 +1,791 @@
+package com.actionbarsherlock;\r
+\r
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;\r
+import java.lang.annotation.ElementType;\r
+import java.lang.annotation.Retention;\r
+import java.lang.annotation.RetentionPolicy;\r
+import java.lang.annotation.Target;\r
+import java.lang.reflect.Constructor;\r
+import java.lang.reflect.InvocationTargetException;\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import android.app.Activity;\r
+import android.content.Context;\r
+import android.content.res.Configuration;\r
+import android.os.Build;\r
+import android.os.Bundle;\r
+import android.util.DisplayMetrics;\r
+import android.util.Log;\r
+import android.view.KeyEvent;\r
+import android.view.View;\r
+import android.view.ViewGroup;\r
+import android.view.Window;\r
+import com.actionbarsherlock.app.ActionBar;\r
+import com.actionbarsherlock.internal.ActionBarSherlockCompat;\r
+import com.actionbarsherlock.internal.ActionBarSherlockNative;\r
+import com.actionbarsherlock.view.ActionMode;\r
+import com.actionbarsherlock.view.Menu;\r
+import com.actionbarsherlock.view.MenuInflater;\r
+import com.actionbarsherlock.view.MenuItem;\r
+\r
+/**\r
+ * <p>Helper for implementing the action bar design pattern across all versions\r
+ * of Android.</p>\r
+ *\r
+ * <p>This class will manage interaction with a custom action bar based on the\r
+ * Android 4.0 source code. The exposed API mirrors that of its native\r
+ * counterpart and you should refer to its documentation for instruction.</p>\r
+ *\r
+ * @author Jake Wharton <jakewharton@gmail.com>\r
+ */\r
+public abstract class ActionBarSherlock {\r
+    protected static final String TAG = "ActionBarSherlock";\r
+    protected static final boolean DEBUG = false;\r
+\r
+    private static final Class<?>[] CONSTRUCTOR_ARGS = new Class[] { Activity.class, int.class };\r
+    private static final HashMap<Implementation, Class<? extends ActionBarSherlock>> IMPLEMENTATIONS =\r
+            new HashMap<Implementation, Class<? extends ActionBarSherlock>>();\r
+\r
+    static {\r
+        //Register our two built-in implementations\r
+        registerImplementation(ActionBarSherlockCompat.class);\r
+        registerImplementation(ActionBarSherlockNative.class);\r
+    }\r
+\r
+\r
+    /**\r
+     * <p>Denotes an implementation of ActionBarSherlock which provides an\r
+     * action bar-enhanced experience.</p>\r
+     */\r
+    @Target(ElementType.TYPE)\r
+    @Retention(RetentionPolicy.RUNTIME)\r
+    public @interface Implementation {\r
+        static final int DEFAULT_API = -1;\r
+        static final int DEFAULT_DPI = -1;\r
+\r
+        int api() default DEFAULT_API;\r
+        int dpi() default DEFAULT_DPI;\r
+    }\r
+\r
+\r
+    /** Activity interface for menu creation callback. */\r
+    public interface OnCreatePanelMenuListener {\r
+        public boolean onCreatePanelMenu(int featureId, Menu menu);\r
+    }\r
+    /** Activity interface for menu creation callback. */\r
+    public interface OnCreateOptionsMenuListener {\r
+        public boolean onCreateOptionsMenu(Menu menu);\r
+    }\r
+    /** Activity interface for menu item selection callback. */\r
+    public interface OnMenuItemSelectedListener {\r
+        public boolean onMenuItemSelected(int featureId, MenuItem item);\r
+    }\r
+    /** Activity interface for menu item selection callback. */\r
+    public interface OnOptionsItemSelectedListener {\r
+        public boolean onOptionsItemSelected(MenuItem item);\r
+    }\r
+    /** Activity interface for menu preparation callback. */\r
+    public interface OnPreparePanelListener {\r
+        public boolean onPreparePanel(int featureId, View view, Menu menu);\r
+    }\r
+    /** Activity interface for menu preparation callback. */\r
+    public interface OnPrepareOptionsMenuListener {\r
+        public boolean onPrepareOptionsMenu(Menu menu);\r
+    }\r
+    /** Activity interface for action mode finished callback. */\r
+    public interface OnActionModeFinishedListener {\r
+        public void onActionModeFinished(ActionMode mode);\r
+    }\r
+    /** Activity interface for action mode started callback. */\r
+    public interface OnActionModeStartedListener {\r
+        public void onActionModeStarted(ActionMode mode);\r
+    }\r
+\r
+\r
+    /**\r
+     * If set, the logic in these classes will assume that an {@link Activity}\r
+     * is dispatching all of the required events to the class. This flag should\r
+     * only be used internally or if you are creating your own base activity\r
+     * modeled after one of the included types (e.g., {@code SherlockActivity}).\r
+     */\r
+    public static final int FLAG_DELEGATE = 1;\r
+\r
+\r
+    /**\r
+     * Register an ActionBarSherlock implementation.\r
+     *\r
+     * @param implementationClass Target implementation class which extends\r
+     * {@link ActionBarSherlock}. This class must also be annotated with\r
+     * {@link Implementation}.\r
+     */\r
+    public static void registerImplementation(Class<? extends ActionBarSherlock> implementationClass) {\r
+        if (!implementationClass.isAnnotationPresent(Implementation.class)) {\r
+            throw new IllegalArgumentException("Class " + implementationClass.getSimpleName() + " is not annotated with @Implementation");\r
+        } else if (IMPLEMENTATIONS.containsValue(implementationClass)) {\r
+            if (DEBUG) Log.w(TAG, "Class " + implementationClass.getSimpleName() + " already registered");\r
+            return;\r
+        }\r
+\r
+        Implementation impl = implementationClass.getAnnotation(Implementation.class);\r
+        if (DEBUG) Log.i(TAG, "Registering " + implementationClass.getSimpleName() + " with qualifier " + impl);\r
+        IMPLEMENTATIONS.put(impl, implementationClass);\r
+    }\r
+\r
+    /**\r
+     * Unregister an ActionBarSherlock implementation. <strong>This should be\r
+     * considered very volatile and you should only use it if you know what\r
+     * you are doing.</strong> You have been warned.\r
+     *\r
+     * @param implementationClass Target implementation class.\r
+     * @return Boolean indicating whether the class was removed.\r
+     */\r
+    public static boolean unregisterImplementation(Class<? extends ActionBarSherlock> implementationClass) {\r
+        return IMPLEMENTATIONS.values().remove(implementationClass);\r
+    }\r
+\r
+    /**\r
+     * Wrap an activity with an action bar abstraction which will enable the\r
+     * use of a custom implementation on platforms where a native version does\r
+     * not exist.\r
+     *\r
+     * @param activity Activity to wrap.\r
+     * @return Instance to interact with the action bar.\r
+     */\r
+    public static ActionBarSherlock wrap(Activity activity) {\r
+        return wrap(activity, 0);\r
+    }\r
+\r
+    /**\r
+     * Wrap an activity with an action bar abstraction which will enable the\r
+     * use of a custom implementation on platforms where a native version does\r
+     * not exist.\r
+     *\r
+     * @param activity Owning activity.\r
+     * @param flags Option flags to control behavior.\r
+     * @return Instance to interact with the action bar.\r
+     */\r
+    public static ActionBarSherlock wrap(Activity activity, int flags) {\r
+        //Create a local implementation map we can modify\r
+        HashMap<Implementation, Class<? extends ActionBarSherlock>> impls =\r
+                new HashMap<Implementation, Class<? extends ActionBarSherlock>>(IMPLEMENTATIONS);\r
+        boolean hasQualfier;\r
+\r
+        /* DPI FILTERING */\r
+        hasQualfier = false;\r
+        for (Implementation key : impls.keySet()) {\r
+            //Only honor TVDPI as a specific qualifier\r
+            if (key.dpi() == DisplayMetrics.DENSITY_TV) {\r
+                hasQualfier = true;\r
+                break;\r
+            }\r
+        }\r
+        if (hasQualfier) {\r
+            final boolean isTvDpi = activity.getResources().getDisplayMetrics().densityDpi == DisplayMetrics.DENSITY_TV;\r
+            for (Iterator<Implementation> keys = impls.keySet().iterator(); keys.hasNext(); ) {\r
+                int keyDpi = keys.next().dpi();\r
+                if ((isTvDpi && keyDpi != DisplayMetrics.DENSITY_TV)\r
+                        || (!isTvDpi && keyDpi == DisplayMetrics.DENSITY_TV)) {\r
+                    keys.remove();\r
+                }\r
+            }\r
+        }\r
+\r
+        /* API FILTERING */\r
+        hasQualfier = false;\r
+        for (Implementation key : impls.keySet()) {\r
+            if (key.api() != Implementation.DEFAULT_API) {\r
+                hasQualfier = true;\r
+                break;\r
+            }\r
+        }\r
+        if (hasQualfier) {\r
+            final int runtimeApi = Build.VERSION.SDK_INT;\r
+            int bestApi = 0;\r
+            for (Iterator<Implementation> keys = impls.keySet().iterator(); keys.hasNext(); ) {\r
+                int keyApi = keys.next().api();\r
+                if (keyApi > runtimeApi) {\r
+                    keys.remove();\r
+                } else if (keyApi > bestApi) {\r
+                    bestApi = keyApi;\r
+                }\r
+            }\r
+            for (Iterator<Implementation> keys = impls.keySet().iterator(); keys.hasNext(); ) {\r
+                if (keys.next().api() != bestApi) {\r
+                    keys.remove();\r
+                }\r
+            }\r
+        }\r
+\r
+        if (impls.size() > 1) {\r
+            throw new IllegalStateException("More than one implementation matches configuration.");\r
+        }\r
+        if (impls.isEmpty()) {\r
+            throw new IllegalStateException("No implementations match configuration.");\r
+        }\r
+        Class<? extends ActionBarSherlock> impl = impls.values().iterator().next();\r
+        if (DEBUG) Log.i(TAG, "Using implementation: " + impl.getSimpleName());\r
+\r
+        try {\r
+            Constructor<? extends ActionBarSherlock> ctor = impl.getConstructor(CONSTRUCTOR_ARGS);\r
+            return ctor.newInstance(activity, flags);\r
+        } catch (NoSuchMethodException e) {\r
+            throw new RuntimeException(e);\r
+        } catch (IllegalArgumentException e) {\r
+            throw new RuntimeException(e);\r
+        } catch (InstantiationException e) {\r
+            throw new RuntimeException(e);\r
+        } catch (IllegalAccessException e) {\r
+            throw new RuntimeException(e);\r
+        } catch (InvocationTargetException e) {\r
+            throw new RuntimeException(e);\r
+        }\r
+    }\r
+\r
+\r
+    /** Activity which is displaying the action bar. Also used for context. */\r
+    protected final Activity mActivity;\r
+    /** Whether delegating actions for the activity or managing ourselves. */\r
+    protected final boolean mIsDelegate;\r
+\r
+    /** Reference to our custom menu inflater which supports action items. */\r
+    protected MenuInflater mMenuInflater;\r
+\r
+\r
+\r
+    protected ActionBarSherlock(Activity activity, int flags) {\r
+        if (DEBUG) Log.d(TAG, "[<ctor>] activity: " + activity + ", flags: " + flags);\r
+\r
+        mActivity = activity;\r
+        mIsDelegate = (flags & FLAG_DELEGATE) != 0;\r
+    }\r
+\r
+\r
+    /**\r
+     * Get the current action bar instance.\r
+     *\r
+     * @return Action bar instance.\r
+     */\r
+    public abstract ActionBar getActionBar();\r
+\r
+\r
+    ///////////////////////////////////////////////////////////////////////////\r
+    // Lifecycle and interaction callbacks when delegating\r
+    ///////////////////////////////////////////////////////////////////////////\r
+\r
+    /**\r
+     * Notify action bar of a configuration change event. Should be dispatched\r
+     * after the call to the superclass implementation.\r
+     *\r
+     * <blockquote><pre>\r
+     * @Override\r
+     * public void onConfigurationChanged(Configuration newConfig) {\r
+     *     super.onConfigurationChanged(newConfig);\r
+     *     mSherlock.dispatchConfigurationChanged(newConfig);\r
+     * }\r
+     * </pre></blockquote>\r
+     *\r
+     * @param newConfig The new device configuration.\r
+     */\r
+    public void dispatchConfigurationChanged(Configuration newConfig) {}\r
+\r
+    /**\r
+     * Notify the action bar that the activity has finished its resuming. This\r
+     * should be dispatched after the call to the superclass implementation.\r
+     *\r
+     * <blockquote><pre>\r
+     * @Override\r
+     * protected void onPostResume() {\r
+     *     super.onPostResume();\r
+     *     mSherlock.dispatchPostResume();\r
+     * }\r
+     * </pre></blockquote>\r
+     */\r
+    public void dispatchPostResume() {}\r
+\r
+    /**\r
+     * Notify the action bar that the activity is pausing. This should be\r
+     * dispatched before the call to the superclass implementation.\r
+     *\r
+     * <blockquote><pre>\r
+     * @Override\r
+     * protected void onPause() {\r
+     *     mSherlock.dispatchPause();\r
+     *     super.onPause();\r
+     * }\r
+     * </pre></blockquote>\r
+     */\r
+    public void dispatchPause() {}\r
+\r
+    /**\r
+     * Notify the action bar that the activity is stopping. This should be\r
+     * called before the superclass implementation.\r
+     *\r
+     * <blockquote><p>\r
+     * @Override\r
+     * protected void onStop() {\r
+     *     mSherlock.dispatchStop();\r
+     *     super.onStop();\r
+     * }\r
+     * </p></blockquote>\r
+     */\r
+    public void dispatchStop() {}\r
+\r
+    /**\r
+     * Indicate that the menu should be recreated by calling\r
+     * {@link OnCreateOptionsMenuListener#onCreateOptionsMenu(com.actionbarsherlock.view.Menu)}.\r
+     */\r
+    public abstract void dispatchInvalidateOptionsMenu();\r
+\r
+    /**\r
+     * Notify the action bar that it should display its overflow menu if it is\r
+     * appropriate for the device. The implementation should conditionally\r
+     * call the superclass method only if this method returns {@code false}.\r
+     *\r
+     * <blockquote><p>\r
+     * @Override\r
+     * public void openOptionsMenu() {\r
+     *     if (!mSherlock.dispatchOpenOptionsMenu()) {\r
+     *         super.openOptionsMenu();\r
+     *     }\r
+     * }\r
+     * </p></blockquote>\r
+     *\r
+     * @return {@code true} if the opening of the menu was handled internally.\r
+     */\r
+    public boolean dispatchOpenOptionsMenu() {\r
+        return false;\r
+    }\r
+\r
+    /**\r
+     * Notify the action bar that it should close its overflow menu if it is\r
+     * appropriate for the device. This implementation should conditionally\r
+     * call the superclass method only if this method returns {@code false}.\r
+     *\r
+     * <blockquote><pre>\r
+     * @Override\r
+     * public void closeOptionsMenu() {\r
+     *     if (!mSherlock.dispatchCloseOptionsMenu()) {\r
+     *         super.closeOptionsMenu();\r
+     *     }\r
+     * }\r
+     * </pre></blockquote>\r
+     *\r
+     * @return {@code true} if the closing of the menu was handled internally.\r
+     */\r
+    public boolean dispatchCloseOptionsMenu() {\r
+        return false;\r
+    }\r
+\r
+    /**\r
+     * Notify the class that the activity has finished its creation. This\r
+     * should be called after the superclass implementation.\r
+     *\r
+     * <blockquote><pre>\r
+     * @Override\r
+     * protected void onPostCreate(Bundle savedInstanceState) {\r
+     *     mSherlock.dispatchPostCreate(savedInstanceState);\r
+     *     super.onPostCreate(savedInstanceState);\r
+     * }\r
+     * </pre></blockquote>\r
+     *\r
+     * @param savedInstanceState If the activity is being re-initialized after\r
+     *                           previously being shut down then this Bundle\r
+     *                           contains the data it most recently supplied in\r
+     *                           {@link Activity#}onSaveInstanceState(Bundle)}.\r
+     *                           <strong>Note: Otherwise it is null.</strong>\r
+     */\r
+    public void dispatchPostCreate(Bundle savedInstanceState) {}\r
+\r
+    /**\r
+     * Notify the action bar that the title has changed and the action bar\r
+     * should be updated to reflect the change. This should be called before\r
+     * the superclass implementation.\r
+     *\r
+     * <blockquote><pre>\r
+     *  @Override\r
+     *  protected void onTitleChanged(CharSequence title, int color) {\r
+     *      mSherlock.dispatchTitleChanged(title, color);\r
+     *      super.onTitleChanged(title, color);\r
+     *  }\r
+     * </pre></blockquote>\r
+     *\r
+     * @param title New activity title.\r
+     * @param color New activity color.\r
+     */\r
+    public void dispatchTitleChanged(CharSequence title, int color) {}\r
+\r
+    /**\r
+     * Notify the action bar the user has created a key event. This is used to\r
+     * toggle the display of the overflow action item with the menu key and to\r
+     * close the action mode or expanded action item with the back key.\r
+     *\r
+     * <blockquote><pre>\r
+     * @Override\r
+     * public boolean dispatchKeyEvent(KeyEvent event) {\r
+     *     if (mSherlock.dispatchKeyEvent(event)) {\r
+     *         return true;\r
+     *     }\r
+     *     return super.dispatchKeyEvent(event);\r
+     * }\r
+     * </pre></blockquote>\r
+     *\r
+     * @param event Description of the key event.\r
+     * @return {@code true} if the event was handled.\r
+     */\r
+    public boolean dispatchKeyEvent(KeyEvent event) {\r
+        return false;\r
+    }\r
+\r
+    /**\r
+     * Notify the action bar that the Activity has triggered a menu creation\r
+     * which should happen on the conclusion of {@link Activity#onCreate}. This\r
+     * will be used to gain a reference to the native menu for native and\r
+     * overflow binding as well as to indicate when compatibility create should\r
+     * occur for the first time.\r
+     *\r
+     * @param menu Activity native menu.\r
+     * @return {@code true} since we always want to say that we have a native\r
+     */\r
+    public abstract boolean dispatchCreateOptionsMenu(android.view.Menu menu);\r
+\r
+    /**\r
+     * Notify the action bar that the Activity has triggered a menu preparation\r
+     * which usually means that the user has requested the overflow menu via a\r
+     * hardware menu key. You should return the result of this method call and\r
+     * not call the superclass implementation.\r
+     *\r
+     * <blockquote><p>\r
+     * @Override\r
+     * public final boolean onPrepareOptionsMenu(android.view.Menu menu) {\r
+     *     return mSherlock.dispatchPrepareOptionsMenu(menu);\r
+     * }\r
+     * </p></blockquote>\r
+     *\r
+     * @param menu Activity native menu.\r
+     * @return {@code true} if menu display should proceed.\r
+     */\r
+    public abstract boolean dispatchPrepareOptionsMenu(android.view.Menu menu);\r
+\r
+    /**\r
+     * Notify the action bar that a native options menu item has been selected.\r
+     * The implementation should return the result of this method call.\r
+     *\r
+     * <blockquote><p>\r
+     * @Override\r
+     * public final boolean onOptionsItemSelected(android.view.MenuItem item) {\r
+     *     return mSherlock.dispatchOptionsItemSelected(item);\r
+     * }\r
+     * </p></blockquote>\r
+     *\r
+     * @param item Options menu item.\r
+     * @return @{code true} if the selection was handled.\r
+     */\r
+    public abstract boolean dispatchOptionsItemSelected(android.view.MenuItem item);\r
+\r
+    /**\r
+     * Notify the action bar that the overflow menu has been opened. The\r
+     * implementation should conditionally return {@code true} if this method\r
+     * returns {@code true}, otherwise return the result of the superclass\r
+     * method.\r
+     *\r
+     * <blockquote><p>\r
+     * @Override\r
+     * public final boolean onMenuOpened(int featureId, android.view.Menu menu) {\r
+     *     if (mSherlock.dispatchMenuOpened(featureId, menu)) {\r
+     *         return true;\r
+     *     }\r
+     *     return super.onMenuOpened(featureId, menu);\r
+     * }\r
+     * </p></blockquote>\r
+     *\r
+     * @param featureId Window feature which triggered the event.\r
+     * @param menu Activity native menu.\r
+     * @return {@code true} if the event was handled by this method.\r
+     */\r
+    public boolean dispatchMenuOpened(int featureId, android.view.Menu menu) {\r
+        return false;\r
+    }\r
+\r
+    /**\r
+     * Notify the action bar that the overflow menu has been closed. This\r
+     * method should be called before the superclass implementation.\r
+     *\r
+     * <blockquote><p>\r
+     * @Override\r
+     * public void onPanelClosed(int featureId, android.view.Menu menu) {\r
+     *     mSherlock.dispatchPanelClosed(featureId, menu);\r
+     *     super.onPanelClosed(featureId, menu);\r
+     * }\r
+     * </p></blockquote>\r
+     *\r
+     * @param featureId\r
+     * @param menu\r
+     */\r
+    public void dispatchPanelClosed(int featureId, android.view.Menu menu) {}\r
+\r
+    /**\r
+     * Notify the action bar that the activity has been destroyed. This method\r
+     * should be called before the superclass implementation.\r
+     *\r
+     * <blockquote><p>\r
+     * @Override\r
+     * public void onDestroy() {\r
+     *     mSherlock.dispatchDestroy();\r
+     *     super.onDestroy();\r
+     * }\r
+     * </p></blockquote>\r
+     */\r
+    public void dispatchDestroy() {}\r
+\r
+\r
+    ///////////////////////////////////////////////////////////////////////////\r
+    ///////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+    /**\r
+     * Internal method to trigger the menu creation process.\r
+     *\r
+     * @return {@code true} if menu creation should proceed.\r
+     */\r
+    protected final boolean callbackCreateOptionsMenu(Menu menu) {\r
+        if (DEBUG) Log.d(TAG, "[callbackCreateOptionsMenu] menu: " + menu);\r
+\r
+        boolean result = true;\r
+        if (mActivity instanceof OnCreatePanelMenuListener) {\r
+            OnCreatePanelMenuListener listener = (OnCreatePanelMenuListener)mActivity;\r
+            result = listener.onCreatePanelMenu(Window.FEATURE_OPTIONS_PANEL, menu);\r
+        } else if (mActivity instanceof OnCreateOptionsMenuListener) {\r
+            OnCreateOptionsMenuListener listener = (OnCreateOptionsMenuListener)mActivity;\r
+            result = listener.onCreateOptionsMenu(menu);\r
+        }\r
+\r
+        if (DEBUG) Log.d(TAG, "[callbackCreateOptionsMenu] returning " + result);\r
+        return result;\r
+    }\r
+\r
+    /**\r
+     * Internal method to trigger the menu preparation process.\r
+     *\r
+     * @return {@code true} if menu preparation should proceed.\r
+     */\r
+    protected final boolean callbackPrepareOptionsMenu(Menu menu) {\r
+        if (DEBUG) Log.d(TAG, "[callbackPrepareOptionsMenu] menu: " + menu);\r
+\r
+        boolean result = true;\r
+        if (mActivity instanceof OnPreparePanelListener) {\r
+            OnPreparePanelListener listener = (OnPreparePanelListener)mActivity;\r
+            result = listener.onPreparePanel(Window.FEATURE_OPTIONS_PANEL, null, menu);\r
+        } else if (mActivity instanceof OnPrepareOptionsMenuListener) {\r
+            OnPrepareOptionsMenuListener listener = (OnPrepareOptionsMenuListener)mActivity;\r
+            result = listener.onPrepareOptionsMenu(menu);\r
+        }\r
+\r
+        if (DEBUG) Log.d(TAG, "[callbackPrepareOptionsMenu] returning " + result);\r
+        return result;\r
+    }\r
+\r
+    /**\r
+     * Internal method for dispatching options menu selection to the owning\r
+     * activity callback.\r
+     *\r
+     * @param item Selected options menu item.\r
+     * @return {@code true} if the item selection was handled in the callback.\r
+     */\r
+    protected final boolean callbackOptionsItemSelected(MenuItem item) {\r
+        if (DEBUG) Log.d(TAG, "[callbackOptionsItemSelected] item: " + item.getTitleCondensed());\r
+\r
+        boolean result = false;\r
+        if (mActivity instanceof OnMenuItemSelectedListener) {\r
+            OnMenuItemSelectedListener listener = (OnMenuItemSelectedListener)mActivity;\r
+            result = listener.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, item);\r
+        } else if (mActivity instanceof OnOptionsItemSelectedListener) {\r
+            OnOptionsItemSelectedListener listener = (OnOptionsItemSelectedListener)mActivity;\r
+            result = listener.onOptionsItemSelected(item);\r
+        }\r
+\r
+        if (DEBUG) Log.d(TAG, "[callbackOptionsItemSelected] returning " + result);\r
+        return result;\r
+    }\r
+\r
+\r
+    ///////////////////////////////////////////////////////////////////////////\r
+    ///////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+    /**\r
+     * Query for the availability of a certain feature.\r
+     *\r
+     * @param featureId The feature ID to check.\r
+     * @return {@code true} if feature is enabled, {@code false} otherwise.\r
+     */\r
+    public abstract boolean hasFeature(int featureId);\r
+\r
+    /**\r
+     * Enable extended screen features. This must be called before\r
+     * {@code setContentView()}. May be called as many times as desired as long\r
+     * as it is before {@code setContentView()}. If not called, no extended\r
+     * features will be available. You can not turn off a feature once it is\r
+     * requested.\r
+     *\r
+     * @param featureId The desired features, defined as constants by Window.\r
+     * @return Returns true if the requested feature is supported and now\r
+     * enabled.\r
+     */\r
+    public abstract boolean requestFeature(int featureId);\r
+\r
+    /**\r
+     * Set extra options that will influence the UI for this window.\r
+     *\r
+     * @param uiOptions Flags specifying extra options for this window.\r
+     */\r
+    public abstract void setUiOptions(int uiOptions);\r
+\r
+    /**\r
+     * Set extra options that will influence the UI for this window. Only the\r
+     * bits filtered by mask will be modified.\r
+     *\r
+     * @param uiOptions Flags specifying extra options for this window.\r
+     * @param mask Flags specifying which options should be modified. Others\r
+     *             will remain unchanged.\r
+     */\r
+    public abstract void setUiOptions(int uiOptions, int mask);\r
+\r
+    /**\r
+     * Set the content of the activity inside the action bar.\r
+     *\r
+     * @param layoutResId Layout resource ID.\r
+     */\r
+    public abstract void setContentView(int layoutResId);\r
+\r
+    /**\r
+     * Set the content of the activity inside the action bar.\r
+     *\r
+     * @param view The desired content to display.\r
+     */\r
+    public void setContentView(View view) {\r
+        if (DEBUG) Log.d(TAG, "[setContentView] view: " + view);\r
+\r
+        setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));\r
+    }\r
+\r
+    /**\r
+     * Set the content of the activity inside the action bar.\r
+     *\r
+     * @param view The desired content to display.\r
+     * @param params Layout parameters to apply to the view.\r
+     */\r
+    public abstract void setContentView(View view, ViewGroup.LayoutParams params);\r
+\r
+    /**\r
+     * Variation on {@link #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)}\r
+     * to add an additional content view to the screen. Added after any\r
+     * existing ones on the screen -- existing views are NOT removed.\r
+     *\r
+     * @param view The desired content to display.\r
+     * @param params Layout parameters for the view.\r
+     */\r
+    public abstract void addContentView(View view, ViewGroup.LayoutParams params);\r
+\r
+    /**\r
+     * Change the title associated with this activity.\r
+     */\r
+    public abstract void setTitle(CharSequence title);\r
+\r
+    /**\r
+     * Change the title associated with this activity.\r
+     */\r
+    public void setTitle(int resId) {\r
+        if (DEBUG) Log.d(TAG, "[setTitle] resId: " + resId);\r
+\r
+        setTitle(mActivity.getString(resId));\r
+    }\r
+\r
+    /**\r
+     * Sets the visibility of the progress bar in the title.\r
+     * <p>\r
+     * In order for the progress bar to be shown, the feature must be requested\r
+     * via {@link #requestWindowFeature(int)}.\r
+     *\r
+     * @param visible Whether to show the progress bars in the title.\r
+     */\r
+    public abstract void setProgressBarVisibility(boolean visible);\r
+\r
+    /**\r
+     * Sets the visibility of the indeterminate progress bar in the title.\r
+     * <p>\r
+     * In order for the progress bar to be shown, the feature must be requested\r
+     * via {@link #requestWindowFeature(int)}.\r
+     *\r
+     * @param visible Whether to show the progress bars in the title.\r
+     */\r
+    public abstract void setProgressBarIndeterminateVisibility(boolean visible);\r
+\r
+    /**\r
+     * Sets whether the horizontal progress bar in the title should be indeterminate (the circular\r
+     * is always indeterminate).\r
+     * <p>\r
+     * In order for the progress bar to be shown, the feature must be requested\r
+     * via {@link #requestWindowFeature(int)}.\r
+     *\r
+     * @param indeterminate Whether the horizontal progress bar should be indeterminate.\r
+     */\r
+    public abstract void setProgressBarIndeterminate(boolean indeterminate);\r
+\r
+    /**\r
+     * Sets the progress for the progress bars in the title.\r
+     * <p>\r
+     * In order for the progress bar to be shown, the feature must be requested\r
+     * via {@link #requestWindowFeature(int)}.\r
+     *\r
+     * @param progress The progress for the progress bar. Valid ranges are from\r
+     *            0 to 10000 (both inclusive). If 10000 is given, the progress\r
+     *            bar will be completely filled and will fade out.\r
+     */\r
+    public abstract void setProgress(int progress);\r
+\r
+    /**\r
+     * Sets the secondary progress for the progress bar in the title. This\r
+     * progress is drawn between the primary progress (set via\r
+     * {@link #setProgress(int)} and the background. It can be ideal for media\r
+     * scenarios such as showing the buffering progress while the default\r
+     * progress shows the play progress.\r
+     * <p>\r
+     * In order for the progress bar to be shown, the feature must be requested\r
+     * via {@link #requestWindowFeature(int)}.\r
+     *\r
+     * @param secondaryProgress The secondary progress for the progress bar. Valid ranges are from\r
+     *            0 to 10000 (both inclusive).\r
+     */\r
+    public abstract void setSecondaryProgress(int secondaryProgress);\r
+\r
+    /**\r
+     * Get a menu inflater instance which supports the newer menu attributes.\r
+     *\r
+     * @return Menu inflater instance.\r
+     */\r
+    public MenuInflater getMenuInflater() {\r
+        if (DEBUG) Log.d(TAG, "[getMenuInflater]");\r
+\r
+        // Make sure that action views can get an appropriate theme.\r
+        if (mMenuInflater == null) {\r
+            if (getActionBar() != null) {\r
+                mMenuInflater = new MenuInflater(getThemedContext());\r
+            } else {\r
+                mMenuInflater = new MenuInflater(mActivity);\r
+            }\r
+        }\r
+        return mMenuInflater;\r
+    }\r
+\r
+    protected abstract Context getThemedContext();\r
+\r
+    /**\r
+     * Start an action mode.\r
+     *\r
+     * @param callback Callback that will manage lifecycle events for this\r
+     *                 context mode.\r
+     * @return The ContextMode that was started, or null if it was canceled.\r
+     * @see ActionMode\r
+     */\r
+    public abstract ActionMode startActionMode(ActionMode.Callback callback);\r
+}\r