+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
+ ///////////////////////////////////////////////////////////////////////////\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