diff options
-rw-r--r-- | api/current.txt | 24 | ||||
-rw-r--r-- | core/java/android/app/Activity.java | 790 | ||||
-rw-r--r-- | core/java/android/view/Window.java | 99 | ||||
-rw-r--r-- | media/java/android/media/RemoteControlClient.java | 17 | ||||
-rw-r--r-- | media/java/android/media/RemoteController.java | 2 | ||||
-rw-r--r-- | media/java/android/media/session/PlaybackState.java | 303 | ||||
-rw-r--r-- | policy/src/com/android/internal/policy/impl/PhoneWindow.java | 84 | ||||
-rw-r--r-- | services/core/java/com/android/server/media/MediaSessionRecord.java | 11 | ||||
-rw-r--r-- | tests/OneMedia/src/com/android/onemedia/PlayerController.java | 12 | ||||
-rw-r--r-- | tests/OneMedia/src/com/android/onemedia/PlayerSession.java | 48 | ||||
-rw-r--r-- | tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java | 39 |
11 files changed, 843 insertions, 586 deletions
diff --git a/api/current.txt b/api/current.txt index 94f50b2..77cc1f6 100644 --- a/api/current.txt +++ b/api/current.txt @@ -3309,6 +3309,7 @@ package android.app { method public android.view.LayoutInflater getLayoutInflater(); method public android.app.LoaderManager getLoaderManager(); method public java.lang.String getLocalClassName(); + method public final android.media.session.MediaController getMediaController(); method public android.view.MenuInflater getMenuInflater(); method public final android.app.Activity getParent(); method public android.content.Intent getParentActivityIntent(); @@ -3432,6 +3433,7 @@ package android.app { method public void setFinishOnTouchOutside(boolean); method public void setImmersive(boolean); method public void setIntent(android.content.Intent); + method public final void setMediaController(android.media.session.MediaController); method public boolean setMediaPlaying(boolean); method public final void setProgress(int); method public final void setProgressBarIndeterminate(boolean); @@ -16224,19 +16226,14 @@ package android.media.session { } public final class PlaybackState implements android.os.Parcelable { - ctor public PlaybackState(); - ctor public PlaybackState(android.media.session.PlaybackState); method public int describeContents(); method public long getActions(); method public long getBufferPosition(); method public java.lang.CharSequence getErrorMessage(); - method public float getPlaybackRate(); + method public long getLastPositionUpdateTime(); + method public float getPlaybackSpeed(); method public long getPosition(); method public int getState(); - method public void setActions(long); - method public void setBufferPosition(long); - method public void setErrorMessage(java.lang.CharSequence); - method public void setState(int, long, float); method public void writeToParcel(android.os.Parcel, int); field public static final long ACTION_FAST_FORWARD = 64L; // 0x40L field public static final long ACTION_PAUSE = 2L; // 0x2L @@ -16263,6 +16260,17 @@ package android.media.session { field public static final int STATE_STOPPED = 1; // 0x1 } + public static final class PlaybackState.Builder { + ctor public PlaybackState.Builder(); + ctor public PlaybackState.Builder(android.media.session.PlaybackState); + method public android.media.session.PlaybackState build(); + method public android.media.session.PlaybackState.Builder setActions(long); + method public android.media.session.PlaybackState.Builder setBufferPosition(long); + method public android.media.session.PlaybackState.Builder setErrorMessage(java.lang.CharSequence); + method public android.media.session.PlaybackState.Builder setState(int, long, float, long); + method public android.media.session.PlaybackState.Builder setState(int, long, float); + } + } package android.media.tv { @@ -34285,6 +34293,7 @@ package android.view { method protected final int getForcedWindowFlags(); method public abstract android.view.LayoutInflater getLayoutInflater(); method protected final int getLocalFeatures(); + method public android.media.session.MediaController getMediaController(); method public abstract int getNavigationBarColor(); method public android.transition.Transition getSharedElementEnterTransition(); method public android.transition.Transition getSharedElementExitTransition(); @@ -34341,6 +34350,7 @@ package android.view { method public void setLayout(int, int); method public void setLocalFocus(boolean, boolean); method public void setLogo(int); + method public void setMediaController(android.media.session.MediaController); method public abstract void setNavigationBarColor(int); method public void setSharedElementEnterTransition(android.transition.Transition); method public void setSharedElementExitTransition(android.transition.Transition); diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index d20a5dc..cac646d 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -23,6 +23,7 @@ import android.transition.TransitionManager; import android.util.ArrayMap; import android.util.SuperNotCalledException; import android.widget.Toolbar; + import com.android.internal.app.IVoiceInteractor; import com.android.internal.app.WindowDecorActionBar; import com.android.internal.app.ToolbarActionBar; @@ -51,6 +52,8 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.media.AudioManager; +import android.media.session.MediaController; +import android.media.session.MediaSession; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -109,14 +112,14 @@ import java.util.HashMap; * or embedded inside of another activity (using {@link ActivityGroup}). * * There are two methods almost all subclasses of Activity will implement: - * + * * <ul> * <li> {@link #onCreate} is where you initialize your activity. Most * importantly, here you will usually call {@link #setContentView(int)} * with a layout resource defining your UI, and using {@link #findViewById} * to retrieve the widgets in that UI that you need to interact with * programmatically. - * + * * <li> {@link #onPause} is where you deal with the user leaving your * activity. Most importantly, any changes made by the user should at this * point be committed (usually to the @@ -127,7 +130,7 @@ import java.util.HashMap; * activity classes must have a corresponding * {@link android.R.styleable#AndroidManifestActivity <activity>} * declaration in their package's <code>AndroidManifest.xml</code>.</p> - * + * * <p>Topics covered here: * <ol> * <li><a href="#Fragments">Fragments</a> @@ -170,14 +173,14 @@ import java.util.HashMap; * and becomes the running activity -- the previous activity always remains * below it in the stack, and will not come to the foreground again until * the new activity exits.</p> - * + * * <p>An activity has essentially four states:</p> * <ul> * <li> If an activity in the foreground of the screen (at the top of * the stack), * it is <em>active</em> or <em>running</em>. </li> * <li>If an activity has lost focus but is still visible (that is, a new non-full-sized - * or transparent activity has focus on top of your activity), it + * or transparent activity has focus on top of your activity), it * is <em>paused</em>. A paused activity is completely alive (it * maintains all state and member information and remains attached to * the window manager), but can be killed by the system in extreme @@ -197,13 +200,13 @@ import java.util.HashMap; * The square rectangles represent callback methods you can implement to * perform operations when the Activity moves between states. The colored * ovals are major states the Activity can be in.</p> - * + * * <p><img src="../../../images/activity_lifecycle.png" * alt="State diagram for an Android Activity Lifecycle." border="0" /></p> - * + * * <p>There are three key loops you may be interested in monitoring within your * activity: - * + * * <ul> * <li>The <b>entire lifetime</b> of an activity happens between the first call * to {@link android.app.Activity#onCreate} through to a single final call @@ -212,7 +215,7 @@ import java.util.HashMap; * onDestroy(). For example, if it has a thread running in the background * to download data from the network, it may create that thread in onCreate() * and then stop the thread in onDestroy(). - * + * * <li>The <b>visible lifetime</b> of an activity happens between a call to * {@link android.app.Activity#onStart} until a corresponding call to * {@link android.app.Activity#onStop}. During this time the user can see the @@ -224,7 +227,7 @@ import java.util.HashMap; * longer sees what you are displaying. The onStart() and onStop() methods * can be called multiple times, as the activity becomes visible and hidden * to the user. - * + * * <li>The <b>foreground lifetime</b> of an activity happens between a call to * {@link android.app.Activity#onResume} until a corresponding call to * {@link android.app.Activity#onPause}. During this time the activity is @@ -234,7 +237,7 @@ import java.util.HashMap; * intent is delivered -- so the code in these methods should be fairly * lightweight. * </ul> - * + * * <p>The entire lifecycle of an activity is defined by the following * Activity methods. All of these are hooks that you can override * to do appropriate work when the activity changes state. All @@ -250,7 +253,7 @@ import java.util.HashMap; * protected void onCreate(Bundle savedInstanceState); * * protected void onStart(); - * + * * protected void onRestart(); * * protected void onResume(); @@ -366,7 +369,7 @@ import java.util.HashMap; * {@link #onSaveInstanceState(Bundle)} is called before placing the activity * in such a background state, allowing you to save away any dynamic instance * state in your activity into the given Bundle, to be later received in - * {@link #onCreate} if the activity needs to be re-created. + * {@link #onCreate} if the activity needs to be re-created. * See the <a href="#ProcessLifecycle">Process Lifecycle</a> * section for more information on how the lifecycle of a process is tied * to the activities it is hosting. Note that it is important to save @@ -390,14 +393,14 @@ import java.util.HashMap; * * <a name="ConfigurationChanges"></a> * <h3>Configuration Changes</h3> - * + * * <p>If the configuration of the device (as defined by the * {@link Configuration Resources.Configuration} class) changes, * then anything displaying a user interface will need to update to match that * configuration. Because Activity is the primary mechanism for interacting * with the user, it includes special support for handling configuration * changes.</p> - * + * * <p>Unless you specify otherwise, a configuration change (such as a change * in screen orientation, language, input devices, etc) will cause your * current activity to be <em>destroyed</em>, going through the normal activity @@ -407,7 +410,7 @@ import java.util.HashMap; * called in that instance then a new instance of the activity will be * created, with whatever savedInstanceState the previous instance had generated * from {@link #onSaveInstanceState}.</p> - * + * * <p>This is done because any application resource, * including layout files, can change based on any configuration value. Thus * the only safe way to handle a configuration change is to re-retrieve all @@ -415,7 +418,7 @@ import java.util.HashMap; * must already know how to save their state and re-create themselves from * that state, this is a convenient way to have an activity restart itself * with a new configuration.</p> - * + * * <p>In some special cases, you may want to bypass restarting of your * activity based on one or more types of configuration changes. This is * done with the {@link android.R.attr#configChanges android:configChanges} @@ -425,7 +428,7 @@ import java.util.HashMap; * a configuration change involves any that you do not handle, however, the * activity will still be restarted and {@link #onConfigurationChanged} * will not be called.</p> - * + * * <a name="StartingActivities"></a> * <h3>Starting Activities and Getting Results</h3> * @@ -440,10 +443,10 @@ import java.util.HashMap; * ends. For example, you may start an activity that lets the user pick * a person in a list of contacts; when it ends, it returns the person * that was selected. To do this, you call the - * {@link android.app.Activity#startActivityForResult(Intent, int)} - * version with a second integer parameter identifying the call. The result + * {@link android.app.Activity#startActivityForResult(Intent, int)} + * version with a second integer parameter identifying the call. The result * will come back through your {@link android.app.Activity#onActivityResult} - * method.</p> + * method.</p> * * <p>When an activity exits, it can call * {@link android.app.Activity#setResult(int)} @@ -570,17 +573,17 @@ import java.util.HashMap; * * protected void onPause() { * super.onPause(); - * + * * SharedPreferences.Editor ed = mPrefs.edit(); * ed.putInt("view_mode", mCurViewMode); * ed.commit(); * } * } * </pre> - * + * * <a name="Permissions"></a> * <h3>Permissions</h3> - * + * * <p>The ability to start a particular Activity can be enforced when it is * declared in its * manifest's {@link android.R.styleable#AndroidManifestActivity <activity>} @@ -601,10 +604,10 @@ import java.util.HashMap; * * <p>See the <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> * document for more information on permissions and security in general. - * + * * <a name="ProcessLifecycle"></a> * <h3>Process Lifecycle</h3> - * + * * <p>The Android system attempts to keep application process around for as * long as possible, but eventually will need to remove old processes when * memory runs low. As described in <a href="#ActivityLifecycle">Activity @@ -614,7 +617,7 @@ import java.util.HashMap; * listed here in order of importance. The system will kill less important * processes (the last ones) before it resorts to killing more important * processes (the first ones). - * + * * <ol> * <li> <p>The <b>foreground activity</b> (the activity at the top of the screen * that the user is currently interacting with) is considered the most important. @@ -642,7 +645,7 @@ import java.util.HashMap; * context of an activity BroadcastReceiver or Service to ensure that the system * knows it needs to keep your process around. * </ol> - * + * * <p>Sometimes an Activity may need to do a long-running operation that exists * independently of the activity lifecycle itself. An example may be a camera * application that allows you to upload a picture to a web site. The upload @@ -720,7 +723,7 @@ public class Activity extends ContextThemeWrapper VoiceInteractor voiceInteractor; } /* package */ NonConfigurationInstances mLastNonConfigurationInstances; - + private Window mWindow; private WindowManager mWindowManager; @@ -764,7 +767,7 @@ public class Activity extends ContextThemeWrapper private final ArrayList<ManagedCursor> mManagedCursors = new ArrayList<ManagedCursor>(); - // protected by synchronized (this) + // protected by synchronized (this) int mResultCode = RESULT_CANCELED; Intent mResultData = null; @@ -775,7 +778,7 @@ public class Activity extends ContextThemeWrapper private int mDefaultKeyMode = DEFAULT_KEYS_DISABLE; private SpannableStringBuilder mDefaultKeySsb = null; - + protected static final int[] FOCUSED_STATE_SET = {com.android.internal.R.attr.state_focused}; @SuppressWarnings("unused") @@ -793,16 +796,16 @@ public class Activity extends ContextThemeWrapper return mIntent; } - /** - * Change the intent returned by {@link #getIntent}. This holds a - * reference to the given intent; it does not copy it. Often used in - * conjunction with {@link #onNewIntent}. - * - * @param newIntent The new Intent object to return from getIntent - * + /** + * Change the intent returned by {@link #getIntent}. This holds a + * reference to the given intent; it does not copy it. Often used in + * conjunction with {@link #onNewIntent}. + * + * @param newIntent The new Intent object to return from getIntent + * * @see #getIntent * @see #onNewIntent - */ + */ public void setIntent(Intent newIntent) { mIntent = newIntent; } @@ -816,7 +819,7 @@ public class Activity extends ContextThemeWrapper public final boolean isChild() { return mParent != null; } - + /** Return the parent activity if this view is an embedded child. */ public final Activity getParent() { return mParent; @@ -831,7 +834,7 @@ public class Activity extends ContextThemeWrapper * Retrieve the current {@link android.view.Window} for the activity. * This can be used to directly access parts of the Window API that * are not available through Activity/Screen. - * + * * @return Window The current window, or null if the activity is not * visual. */ @@ -850,7 +853,7 @@ public class Activity extends ContextThemeWrapper mLoaderManager = getLoaderManager("(root)", mLoadersStarted, true); return mLoaderManager; } - + LoaderManagerImpl getLoaderManager(String who, boolean started, boolean create) { if (mAllLoaderManagers == null) { mAllLoaderManagers = new ArrayMap<String, LoaderManagerImpl>(); @@ -866,13 +869,13 @@ public class Activity extends ContextThemeWrapper } return lm; } - + /** * Calls {@link android.view.Window#getCurrentFocus} on the * Window of this Activity to return the currently focused view. - * + * * @return View The current View with focus or null. - * + * * @see #getWindow * @see android.view.Window#getCurrentFocus */ @@ -888,20 +891,20 @@ public class Activity extends ContextThemeWrapper * with widgets in the UI, calling * {@link #managedQuery(android.net.Uri , String[], String, String[], String)} to retrieve * cursors for data being displayed, etc. - * + * * <p>You can call {@link #finish} from within this function, in * which case onDestroy() will be immediately called without any of the rest * of the activity lifecycle ({@link #onStart}, {@link #onResume}, * {@link #onPause}, etc) executing. - * + * * <p><em>Derived classes must call through to the super class's * implementation of this method. If they do not, an exception will be * thrown.</em></p> - * + * * @param savedInstanceState If the activity is being re-initialized after * previously being shut down then this Bundle contains the data it most * recently supplied in {@link #onSaveInstanceState}. <b><i>Note: Otherwise it is null.</i></b> - * + * * @see #onStart * @see #onSaveInstanceState * @see #onRestoreInstanceState @@ -996,12 +999,12 @@ public class Activity extends ContextThemeWrapper * decide whether to use your default implementation. The default * implementation of this method performs a restore of any view state that * had previously been frozen by {@link #onSaveInstanceState}. - * + * * <p>This method is called between {@link #onStart} and * {@link #onPostCreate}. - * + * * @param savedInstanceState the data most recently supplied in {@link #onSaveInstanceState}. - * + * * @see #onCreate * @see #onPostCreate * @see #onResume @@ -1098,11 +1101,11 @@ public class Activity extends ContextThemeWrapper * and {@link #onRestoreInstanceState} have been called). Applications will * generally not implement this method; it is intended for system * classes to do final initialization after application code has run. - * + * * <p><em>Derived classes must call through to the super class's * implementation of this method. If they do not, an exception will be * thrown.</em></p> - * + * * @param savedInstanceState If the activity is being re-initialized after * previously being shut down then this Bundle contains the data it most * recently supplied in {@link #onSaveInstanceState}. <b><i>Note: Otherwise it is null.</i></b> @@ -1133,14 +1136,14 @@ public class Activity extends ContextThemeWrapper } /** - * Called after {@link #onCreate} — or after {@link #onRestart} when - * the activity had been stopped, but is now again being displayed to the + * Called after {@link #onCreate} — or after {@link #onRestart} when + * the activity had been stopped, but is now again being displayed to the * user. It will be followed by {@link #onResume}. * * <p><em>Derived classes must call through to the super class's * implementation of this method. If they do not, an exception will be * thrown.</em></p> - * + * * @see #onCreate * @see #onStop * @see #onResume @@ -1148,7 +1151,7 @@ public class Activity extends ContextThemeWrapper protected void onStart() { if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStart " + this); mCalled = true; - + if (!mLoadersStarted) { mLoadersStarted = true; if (mLoaderManager != null) { @@ -1173,11 +1176,11 @@ public class Activity extends ContextThemeWrapper * this is usually the place * where the cursor should be requeried (because you had deactivated it in * {@link #onStop}. - * + * * <p><em>Derived classes must call through to the super class's * implementation of this method. If they do not, an exception will be * thrown.</em></p> - * + * * @see #onStop * @see #onStart * @see #onResume @@ -1200,7 +1203,7 @@ public class Activity extends ContextThemeWrapper * <p><em>Derived classes must call through to the super class's * implementation of this method. If they do not, an exception will be * thrown.</em></p> - * + * * @see #onRestoreInstanceState * @see #onRestart * @see #onPostResume @@ -1218,11 +1221,11 @@ public class Activity extends ContextThemeWrapper * been called). Applications will generally not implement this method; * it is intended for system classes to do final setup after application * resume code has run. - * + * * <p><em>Derived classes must call through to the super class's * implementation of this method. If they do not, an exception will be * thrown.</em></p> - * + * * @see #onResume */ protected void onPostResume() { @@ -1256,19 +1259,19 @@ public class Activity extends ContextThemeWrapper * activity is re-launched while at the top of the activity stack instead * of a new instance of the activity being started, onNewIntent() will be * called on the existing instance with the Intent that was used to - * re-launch it. - * - * <p>An activity will always be paused before receiving a new intent, so - * you can count on {@link #onResume} being called after this method. - * - * <p>Note that {@link #getIntent} still returns the original Intent. You - * can use {@link #setIntent} to update it to this new Intent. - * - * @param intent The new intent that was started for the activity. - * + * re-launch it. + * + * <p>An activity will always be paused before receiving a new intent, so + * you can count on {@link #onResume} being called after this method. + * + * <p>Note that {@link #getIntent} still returns the original Intent. You + * can use {@link #setIntent} to update it to this new Intent. + * + * @param intent The new intent that was started for the activity. + * * @see #getIntent - * @see #setIntent - * @see #onResume + * @see #setIntent + * @see #onResume */ protected void onNewIntent(Intent intent) { } @@ -1342,9 +1345,9 @@ public class Activity extends ContextThemeWrapper * * <p>If called, this method will occur before {@link #onStop}. There are * no guarantees about whether it will occur before or after {@link #onPause}. - * + * * @param outState Bundle in which to place your saved state. - * + * * @see #onCreate * @see #onRestoreInstanceState * @see #onPause @@ -1429,23 +1432,23 @@ public class Activity extends ContextThemeWrapper * noticeable amount of CPU in order to make the switch to the next activity * as fast as possible, or to close resources that are exclusive access * such as the camera. - * + * * <p>In situations where the system needs more memory it may kill paused * processes to reclaim resources. Because of this, you should be sure * that all of your state is saved by the time you return from * this function. In general {@link #onSaveInstanceState} is used to save * per-instance state in the activity and this method is used to store * global persistent data (in content providers, files, etc.) - * + * * <p>After receiving this call you will usually receive a following call * to {@link #onStop} (after the next activity has been resumed and * displayed), however in some cases there will be a direct call back to * {@link #onResume} without going through the stopped state. - * + * * <p><em>Derived classes must call through to the super class's * implementation of this method. If they do not, an exception will be * thrown.</em></p> - * + * * @see #onResume * @see #onSaveInstanceState * @see #onStop @@ -1464,32 +1467,32 @@ public class Activity extends ContextThemeWrapper * brought to the foreground, {@link #onUserLeaveHint} will not be called on * the activity being interrupted. In cases when it is invoked, this method * is called right before the activity's {@link #onPause} callback. - * + * * <p>This callback and {@link #onUserInteraction} are intended to help * activities manage status bar notifications intelligently; specifically, * for helping activities determine the proper time to cancel a notfication. - * + * * @see #onUserInteraction() */ protected void onUserLeaveHint() { } - + /** * Generate a new thumbnail for this activity. This method is called before * pausing the activity, and should draw into <var>outBitmap</var> the * imagery for the desired thumbnail in the dimensions of that bitmap. It * can use the given <var>canvas</var>, which is configured to draw into the * bitmap, for rendering if desired. - * + * * <p>The default implementation returns fails and does not draw a thumbnail; * this will result in the platform creating its own thumbnail if needed. - * + * * @param outBitmap The bitmap to contain the thumbnail. * @param canvas Can be used to render into the bitmap. - * + * * @return Return true if you have drawn into the bitmap; otherwise after * you return it will be filled with a default thumbnail. - * + * * @see #onCreateDescription * @see #onSaveInstanceState * @see #onPause @@ -1502,15 +1505,15 @@ public class Activity extends ContextThemeWrapper * Generate a new description for this activity. This method is called * before pausing the activity and can, if desired, return some textual * description of its current state to be displayed to the user. - * + * * <p>The default implementation returns null, which will cause you to * inherit the description from the previous activity. If all activities * return null, generally the label of the top activity will be used as the * description. - * + * * @return A description of what the user is doing. It should be short and * sweet (only a few words). - * + * * @see #onCreateThumbnail * @see #onSaveInstanceState * @see #onPause @@ -1538,15 +1541,15 @@ public class Activity extends ContextThemeWrapper * Called when you are no longer visible to the user. You will next * receive either {@link #onRestart}, {@link #onDestroy}, or nothing, * depending on later user activity. - * + * * <p>Note that this method may never be called, in low memory situations * where the system does not have enough memory to keep your activity's * process running after its {@link #onPause} method is called. - * + * * <p><em>Derived classes must call through to the super class's * implementation of this method. If they do not, an exception will be * thrown.</em></p> - * + * * @see #onRestart * @see #onResume * @see #onSaveInstanceState @@ -1567,7 +1570,7 @@ public class Activity extends ContextThemeWrapper * {@link #finish} on it, or because the system is temporarily destroying * this instance of the activity to save space. You can distinguish * between these two scenarios with the {@link #isFinishing} method. - * + * * <p><em>Note: do not count on this method being called as a place for * saving data! For example, if an activity is editing data in a content * provider, those edits should be committed in either {@link #onPause} or @@ -1579,11 +1582,11 @@ public class Activity extends ContextThemeWrapper * calling this method (or any others) in it, so it should not be used to * do things that are intended to remain around after the process goes * away. - * + * * <p><em>Derived classes must call through to the super class's * implementation of this method. If they do not, an exception will be * thrown.</em></p> - * + * * @see #onPause * @see #onStop * @see #finish @@ -1657,11 +1660,11 @@ public class Activity extends ContextThemeWrapper * by that attribute, then instead of reporting it the system will stop * and restart the activity (to have it launched with the new * configuration). - * + * * <p>At the time that this function has been called, your Resources * object will have been updated to return resource values matching the * new configuration. - * + * * @param newConfig The new device configuration. */ public void onConfigurationChanged(Configuration newConfig) { @@ -1681,7 +1684,7 @@ public class Activity extends ContextThemeWrapper mActionBar.onConfigurationChanged(newConfig); } } - + /** * If this activity is being destroyed because it can not handle a * configuration parameter being changed (and thus its @@ -1691,7 +1694,7 @@ public class Activity extends ContextThemeWrapper * destroyed. Note that there is no guarantee that these will be * accurate (other changes could have happened at any time), so you should * only use this as an optimization hint. - * + * * @return Returns a bit field of the configuration parameters that are * changing, as defined by the {@link android.content.res.Configuration} * class. @@ -1699,21 +1702,21 @@ public class Activity extends ContextThemeWrapper public int getChangingConfigurations() { return mConfigChangeFlags; } - + /** * Retrieve the non-configuration instance data that was previously * returned by {@link #onRetainNonConfigurationInstance()}. This will * be available from the initial {@link #onCreate} and * {@link #onStart} calls to the new instance, allowing you to extract * any useful dynamic state from the previous instance. - * + * * <p>Note that the data you retrieve here should <em>only</em> be used * as an optimization for handling configuration changes. You should always * be able to handle getting a null pointer back, and an activity must * still be able to restore itself to its previous state (through the * normal {@link #onSaveInstanceState(Bundle)} mechanism) even if this * function returns null. - * + * * @return Returns the object previously returned by * {@link #onRetainNonConfigurationInstance()}. * @@ -1727,7 +1730,7 @@ public class Activity extends ContextThemeWrapper return mLastNonConfigurationInstances != null ? mLastNonConfigurationInstances.activity : null; } - + /** * Called by the system, as part of destroying an * activity due to a configuration change, when it is known that a new @@ -1736,7 +1739,7 @@ public class Activity extends ContextThemeWrapper * itself, which can later be retrieved by calling * {@link #getLastNonConfigurationInstance()} in the new activity * instance. - * + * * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} * or later, consider instead using a {@link Fragment} with * {@link Fragment#setRetainInstance(boolean) @@ -1756,14 +1759,14 @@ public class Activity extends ContextThemeWrapper * the {@link #getLastNonConfigurationInstance()} method of the following * activity instance as described there. * </ul> - * + * * <p>These guarantees are designed so that an activity can use this API * to propagate extensive state from the old to new activity instance, from * loaded bitmaps, to network connections, to evenly actively running * threads. Note that you should <em>not</em> propagate any data that * may change based on the configuration, including any data loaded from * resources such as strings, layouts, or drawables. - * + * * <p>The guarantee of no message handling during the switch to the next * activity simplifies use with active objects. For example if your retained * state is an {@link android.os.AsyncTask} you are guaranteed that its @@ -1783,21 +1786,21 @@ public class Activity extends ContextThemeWrapper public Object onRetainNonConfigurationInstance() { return null; } - + /** * Retrieve the non-configuration instance data that was previously * returned by {@link #onRetainNonConfigurationChildInstances()}. This will * be available from the initial {@link #onCreate} and * {@link #onStart} calls to the new instance, allowing you to extract * any useful dynamic state from the previous instance. - * + * * <p>Note that the data you retrieve here should <em>only</em> be used * as an optimization for handling configuration changes. You should always * be able to handle getting a null pointer back, and an activity must * still be able to restore itself to its previous state (through the * normal {@link #onSaveInstanceState(Bundle)} mechanism) even if this * function returns null. - * + * * @return Returns the object previously returned by * {@link #onRetainNonConfigurationChildInstances()} */ @@ -1806,7 +1809,7 @@ public class Activity extends ContextThemeWrapper return mLastNonConfigurationInstances != null ? mLastNonConfigurationInstances.children : null; } - + /** * This method is similar to {@link #onRetainNonConfigurationInstance()} except that * it should return either a mapping from child activity id strings to arbitrary objects, @@ -1818,7 +1821,7 @@ public class Activity extends ContextThemeWrapper HashMap<String,Object> onRetainNonConfigurationChildInstances() { return null; } - + NonConfigurationInstances retainNonConfigurationInstances() { Object activity = onRetainNonConfigurationInstance(); HashMap<String, Object> children = onRetainNonConfigurationChildInstances(); @@ -1846,7 +1849,7 @@ public class Activity extends ContextThemeWrapper && mVoiceInteractor == null) { return null; } - + NonConfigurationInstances nci = new NonConfigurationInstances(); nci.activity = activity; nci.children = children; @@ -1886,7 +1889,7 @@ public class Activity extends ContextThemeWrapper } } } - + /** * Called when a Fragment is being attached to this activity, immediately * after the call to its {@link Fragment#onAttach Fragment.onAttach()} @@ -1894,14 +1897,14 @@ public class Activity extends ContextThemeWrapper */ public void onAttachFragment(Fragment fragment) { } - + /** * Wrapper around * {@link ContentResolver#query(android.net.Uri , String[], String, String[], String)} * that gives the resulting {@link Cursor} to call * {@link #startManagingCursor} so that the activity will manage its * lifecycle for you. - * + * * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} * or later, consider instead using {@link LoaderManager} instead, available * via {@link #getLoaderManager()}.</em> @@ -1911,14 +1914,14 @@ public class Activity extends ContextThemeWrapper * you call {@link #stopManagingCursor} on a cursor from a managed query, the system <em>will * not</em> automatically close the cursor and, in that case, you must call * {@link Cursor#close()}.</p> - * + * * @param uri The URI of the content provider to query. * @param projection List of columns to return. * @param selection SQL WHERE clause. * @param sortOrder SQL ORDER BY clause. - * + * * @return The Cursor that was returned by query(). - * + * * @see ContentResolver#query(android.net.Uri , String[], String, String[], String) * @see #startManagingCursor * @hide @@ -1941,7 +1944,7 @@ public class Activity extends ContextThemeWrapper * that gives the resulting {@link Cursor} to call * {@link #startManagingCursor} so that the activity will manage its * lifecycle for you. - * + * * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} * or later, consider instead using {@link LoaderManager} instead, available * via {@link #getLoaderManager()}.</em> @@ -1951,15 +1954,15 @@ public class Activity extends ContextThemeWrapper * you call {@link #stopManagingCursor} on a cursor from a managed query, the system <em>will * not</em> automatically close the cursor and, in that case, you must call * {@link Cursor#close()}.</p> - * + * * @param uri The URI of the content provider to query. * @param projection List of columns to return. * @param selection SQL WHERE clause. * @param selectionArgs The arguments to selection, if any ?s are pesent * @param sortOrder SQL ORDER BY clause. - * + * * @return The Cursor that was returned by query(). - * + * * @see ContentResolver#query(android.net.Uri , String[], String, String[], String) * @see #startManagingCursor * @@ -1982,7 +1985,7 @@ public class Activity extends ContextThemeWrapper * {@link Cursor#deactivate} on the given Cursor, and when it is later restarted * it will call {@link Cursor#requery} for you. When the activity is * destroyed, all managed Cursors will be closed automatically. - * + * * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} * or later, consider instead using {@link LoaderManager} instead, available * via {@link #getLoaderManager()}.</em> @@ -1992,9 +1995,9 @@ public class Activity extends ContextThemeWrapper * However, if you call {@link #stopManagingCursor} on a cursor from a managed query, the system * <em>will not</em> automatically close the cursor and, in that case, you must call * {@link Cursor#close()}.</p> - * + * * @param c The Cursor to be managed. - * + * * @see #managedQuery(android.net.Uri , String[], String, String[], String) * @see #stopManagingCursor * @@ -2013,13 +2016,13 @@ public class Activity extends ContextThemeWrapper * Given a Cursor that was previously given to * {@link #startManagingCursor}, stop the activity's management of that * cursor. - * + * * <p><strong>Warning:</strong> After calling this method on a cursor from a managed query, - * the system <em>will not</em> automatically close the cursor and you must call + * the system <em>will not</em> automatically close the cursor and you must call * {@link Cursor#close()}.</p> - * + * * @param c The Cursor that was being managed. - * + * * @see #startManagingCursor * * @deprecated Use the new {@link android.content.CursorLoader} class with @@ -2058,7 +2061,7 @@ public class Activity extends ContextThemeWrapper public View findViewById(int id) { return getWindow().findViewById(id); } - + /** * Retrieve a reference to this activity's ActionBar. * @@ -2094,7 +2097,7 @@ public class Activity extends ContextThemeWrapper mActionBar = new ToolbarActionBar(toolbar, getTitle(), this); mActionBar.invalidateOptionsMenu(); } - + /** * Creates a new ActionBar, locates the inflated ActionBarView, * initializes the ActionBar with the view, and sets mActionBar. @@ -2116,13 +2119,13 @@ public class Activity extends ContextThemeWrapper mWindow.setDefaultIcon(mActivityInfo.getIconResource()); mWindow.setDefaultLogo(mActivityInfo.getLogoResource()); } - + /** * Set the activity content from a layout resource. The resource will be * inflated, adding all top-level views to the activity. * * @param layoutResID Resource ID to be inflated. - * + * * @see #setContentView(android.view.View) * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams) */ @@ -2140,7 +2143,7 @@ public class Activity extends ContextThemeWrapper * your own layout parameters, invoke * {@link #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)} * instead. - * + * * @param view The desired content to display. * * @see #setContentView(int) @@ -2155,7 +2158,7 @@ public class Activity extends ContextThemeWrapper * Set the activity content to an explicit view. This view is placed * directly into the activity's view hierarchy. It can itself be a complex * view hierarchy. - * + * * @param view The desired content to display. * @param params Layout parameters for the view. * @@ -2170,7 +2173,7 @@ public class Activity extends ContextThemeWrapper /** * Add an additional content view to the activity. Added after any existing * ones in the activity -- existing views are NOT removed. - * + * * @param view The desired content to display. * @param params Layout parameters for the view. */ @@ -2235,23 +2238,23 @@ public class Activity extends ContextThemeWrapper /** * Use with {@link #setDefaultKeyMode} to turn off default handling of * keys. - * + * * @see #setDefaultKeyMode */ static public final int DEFAULT_KEYS_DISABLE = 0; /** * Use with {@link #setDefaultKeyMode} to launch the dialer during default * key handling. - * + * * @see #setDefaultKeyMode */ static public final int DEFAULT_KEYS_DIALER = 1; /** * Use with {@link #setDefaultKeyMode} to execute a menu shortcut in * default key handling. - * + * * <p>That is, the user does not need to hold down the menu key to execute menu shortcuts. - * + * * @see #setDefaultKeyMode */ static public final int DEFAULT_KEYS_SHORTCUT = 2; @@ -2259,9 +2262,9 @@ public class Activity extends ContextThemeWrapper * Use with {@link #setDefaultKeyMode} to specify that unhandled keystrokes * will start an application-defined search. (If the application or activity does not * actually define a search, the the keys will be ignored.) - * + * * <p>See {@link android.app.SearchManager android.app.SearchManager} for more details. - * + * * @see #setDefaultKeyMode */ static public final int DEFAULT_KEYS_SEARCH_LOCAL = 3; @@ -2270,9 +2273,9 @@ public class Activity extends ContextThemeWrapper * Use with {@link #setDefaultKeyMode} to specify that unhandled keystrokes * will start a global search (typically web search, but some platforms may define alternate * methods for global search) - * + * * <p>See {@link android.app.SearchManager android.app.SearchManager} for more details. - * + * * @see #setDefaultKeyMode */ static public final int DEFAULT_KEYS_SEARCH_GLOBAL = 4; @@ -2284,16 +2287,16 @@ public class Activity extends ContextThemeWrapper * floor. Other modes allow you to launch the dialer * ({@link #DEFAULT_KEYS_DIALER}), execute a shortcut in your options * menu without requiring the menu key be held down - * ({@link #DEFAULT_KEYS_SHORTCUT}), or launch a search ({@link #DEFAULT_KEYS_SEARCH_LOCAL} + * ({@link #DEFAULT_KEYS_SHORTCUT}), or launch a search ({@link #DEFAULT_KEYS_SEARCH_LOCAL} * and {@link #DEFAULT_KEYS_SEARCH_GLOBAL}). - * + * * <p>Note that the mode selected here does not impact the default * handling of system keys, such as the "back" and "menu" keys, and your * activity and its views always get a first chance to receive and handle * all application keys. - * + * * @param mode The desired default key mode constant. - * + * * @see #DEFAULT_KEYS_DISABLE * @see #DEFAULT_KEYS_DIALER * @see #DEFAULT_KEYS_SHORTCUT @@ -2303,7 +2306,7 @@ public class Activity extends ContextThemeWrapper */ public final void setDefaultKeyMode(@DefaultKeyMode int mode) { mDefaultKeyMode = mode; - + // Some modes use a SpannableStringBuilder to track & dispatch input events // This list must remain in sync with the switch in onKeyDown() switch (mode) { @@ -2324,10 +2327,10 @@ public class Activity extends ContextThemeWrapper /** * Called when a key was pressed down and not handled by any of the views - * inside of the activity. So, for example, key presses while the cursor + * inside of the activity. So, for example, key presses while the cursor * is inside a TextView will not trigger the event (unless it is a navigation * to another object) because TextView handles its own key presses. - * + * * <p>If the focused view didn't want this event, this method is called. * * <p>The default implementation takes care of {@link KeyEvent#KEYCODE_BACK} @@ -2338,12 +2341,12 @@ public class Activity extends ContextThemeWrapper * will be performed; for earlier applications, it will perform the * action immediately in on-down, as those versions of the platform * behaved. - * + * * <p>Other additional default key handling may be performed * if configured with {@link #setDefaultKeyMode}. - * + * * @return Return <code>true</code> to prevent this event from being propagated - * further, or <code>false</code> to indicate that you have not handled + * further, or <code>false</code> to indicate that you have not handled * this event and it should continue to be propagated. * @see #onKeyUp * @see android.view.KeyEvent @@ -2358,11 +2361,11 @@ public class Activity extends ContextThemeWrapper } return true; } - + if (mDefaultKeyMode == DEFAULT_KEYS_DISABLE) { return false; } else if (mDefaultKeyMode == DEFAULT_KEYS_SHORTCUT) { - if (getWindow().performPanelShortcut(Window.FEATURE_OPTIONS_PANEL, + if (getWindow().performPanelShortcut(Window.FEATURE_OPTIONS_PANEL, keyCode, event, Menu.FLAG_ALWAYS_PERFORM_CLOSE)) { return true; } @@ -2382,12 +2385,12 @@ public class Activity extends ContextThemeWrapper final String str = mDefaultKeySsb.toString(); clearSpannable = true; - + switch (mDefaultKeyMode) { case DEFAULT_KEYS_DIALER: Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + str)); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); + startActivity(intent); break; case DEFAULT_KEYS_SEARCH_LOCAL: startSearch(str, false, null, false); @@ -2418,16 +2421,16 @@ public class Activity extends ContextThemeWrapper /** * Called when a key was released and not handled by any of the views - * inside of the activity. So, for example, key presses while the cursor + * inside of the activity. So, for example, key presses while the cursor * is inside a TextView will not trigger the event (unless it is a navigation * to another object) because TextView handles its own key presses. - * + * * <p>The default implementation handles KEYCODE_BACK to stop the activity * and go back. - * + * * @return Return <code>true</code> to prevent this event from being propagated - * further, or <code>false</code> to indicate that you have not handled - * this event and it should continue to be propagated. + * further, or <code>false</code> to indicate that you have not handled + * this event and it should continue to be propagated. * @see #onKeyDown * @see KeyEvent */ @@ -2451,7 +2454,7 @@ public class Activity extends ContextThemeWrapper public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { return false; } - + /** * Called when the activity has detected the user's press of the back * key. The default implementation simply finishes the current activity, @@ -2485,9 +2488,9 @@ public class Activity extends ContextThemeWrapper * Called when a touch screen event was not handled by any of the views * under it. This is most useful to process touch events that happen * outside of your window bounds, where there is no view to receive it. - * + * * @param event The touch screen event being processed. - * + * * @return Return true if you have consumed the event, false if you haven't. * The default implementation always returns false. */ @@ -2496,10 +2499,10 @@ public class Activity extends ContextThemeWrapper finish(); return true; } - + return false; } - + /** * Called when the trackball was moved and not handled by any of the * views inside of the activity. So, for example, if the trackball moves @@ -2508,9 +2511,9 @@ public class Activity extends ContextThemeWrapper * here happens <em>before</em> trackball movements are converted to * DPAD key events, which then get sent back to the view hierarchy, and * will be processed at the point for things like focus navigation. - * + * * @param event The trackball event being processed. - * + * * @return Return true if you have consumed the event, false if you haven't. * The default implementation always returns false. */ @@ -2554,21 +2557,21 @@ public class Activity extends ContextThemeWrapper * This callback and {@link #onUserLeaveHint} are intended to help * activities manage status bar notifications intelligently; specifically, * for helping activities determine the proper time to cancel a notfication. - * + * * <p>All calls to your activity's {@link #onUserLeaveHint} callback will * be accompanied by calls to {@link #onUserInteraction}. This * ensures that your activity will be told of relevant user activity such * as pulling down the notification pane and touching an item there. - * + * * <p>Note that this callback will be invoked for the touch down action * that begins a touch gesture, but may not be invoked for the touch-moved * and touch-up actions that follow. - * + * * @see #onUserLeaveHint() */ public void onUserInteraction() { } - + public void onWindowAttributesChanged(WindowManager.LayoutParams params) { // Update window manager if: we have a view, that view is // attached to its parent (which will be a RootView), and @@ -2589,14 +2592,14 @@ public class Activity extends ContextThemeWrapper * focus. This is the best indicator of whether this activity is visible * to the user. The default implementation clears the key tracking * state, so should always be called. - * + * * <p>Note that this provides information about global focus state, which * is managed independently of activity lifecycles. As such, while focus * changes will generally have some relation to lifecycle changes (an * activity that is stopped will not generally get window focus), you * should not rely on any particular order between the callbacks here and * those in the other lifecycle methods such as {@link #onResume}. - * + * * <p>As a general rule, however, a resumed activity will have window * focus... unless it has displayed other dialogs or popups that take * input focus, in which case the activity itself will not have focus @@ -2606,14 +2609,14 @@ public class Activity extends ContextThemeWrapper * pausing the foreground activity. * * @param hasFocus Whether the window of this activity has focus. - * + * * @see #hasWindowFocus() * @see #onResume * @see View#onWindowFocusChanged(boolean) */ public void onWindowFocusChanged(boolean hasFocus) { } - + /** * Called when the main window associated with the activity has been * attached to the window manager. @@ -2623,7 +2626,7 @@ public class Activity extends ContextThemeWrapper */ public void onAttachedToWindow() { } - + /** * Called when the main window associated with the activity has been * detached from the window manager. @@ -2633,13 +2636,13 @@ public class Activity extends ContextThemeWrapper */ public void onDetachedFromWindow() { } - + /** * Returns true if this activity's <em>main</em> window currently has window focus. * Note that this is not the same as the view itself having focus. - * + * * @return True if this activity's main window currently has window focus. - * + * * @see #onWindowAttributesChanged(android.view.WindowManager.LayoutParams) */ public boolean hasWindowFocus() { @@ -2661,14 +2664,14 @@ public class Activity extends ContextThemeWrapper public void onWindowDismissed() { finish(); } - + /** - * Called to process key events. You can override this to intercept all - * key events before they are dispatched to the window. Be sure to call + * Called to process key events. You can override this to intercept all + * key events before they are dispatched to the window. Be sure to call * this implementation for key events that should be handled normally. - * + * * @param event The key event. - * + * * @return boolean Return true if this event was consumed. */ public boolean dispatchKeyEvent(KeyEvent event) { @@ -2713,9 +2716,9 @@ public class Activity extends ContextThemeWrapper * intercept all touch screen events before they are dispatched to the * window. Be sure to call this implementation for touch screen events * that should be handled normally. - * + * * @param ev The touch screen event. - * + * * @return boolean Return true if this event was consumed. */ public boolean dispatchTouchEvent(MotionEvent ev) { @@ -2727,15 +2730,15 @@ public class Activity extends ContextThemeWrapper } return onTouchEvent(ev); } - + /** * Called to process trackball events. You can override this to * intercept all trackball events before they are dispatched to the * window. Be sure to call this implementation for trackball events * that should be handled normally. - * + * * @param ev The trackball event. - * + * * @return boolean Return true if this event was consumed. */ public boolean dispatchTrackballEvent(MotionEvent ev) { @@ -2830,7 +2833,7 @@ public class Activity extends ContextThemeWrapper /** * {@inheritDoc} - * + * * @return The default implementation returns true. */ public boolean onMenuOpened(int featureId, Menu menu) { @@ -2880,7 +2883,7 @@ public class Activity extends ContextThemeWrapper } } return false; - + case Window.FEATURE_CONTEXT_MENU: if(titleCondensed != null) { EventLog.writeEvent(50000, 1, titleCondensed.toString()); @@ -2894,7 +2897,7 @@ public class Activity extends ContextThemeWrapper return false; } } - + /** * Default implementation of * {@link android.view.Window.Callback#onPanelClosed(int, Menu)} for @@ -2910,7 +2913,7 @@ public class Activity extends ContextThemeWrapper mFragments.dispatchOptionsMenuClosed(menu); onOptionsMenuClosed(menu); break; - + case Window.FEATURE_CONTEXT_MENU: onContextMenuClosed(menu); break; @@ -2932,32 +2935,32 @@ public class Activity extends ContextThemeWrapper mWindow.invalidatePanelMenu(Window.FEATURE_OPTIONS_PANEL); } } - + /** * Initialize the contents of the Activity's standard options menu. You * should place your menu items in to <var>menu</var>. - * + * * <p>This is only called once, the first time the options menu is * displayed. To update the menu every time it is displayed, see * {@link #onPrepareOptionsMenu}. - * + * * <p>The default implementation populates the menu with standard system - * menu items. These are placed in the {@link Menu#CATEGORY_SYSTEM} group so that - * they will be correctly ordered with application-defined menu items. - * Deriving classes should always call through to the base implementation. - * + * menu items. These are placed in the {@link Menu#CATEGORY_SYSTEM} group so that + * they will be correctly ordered with application-defined menu items. + * Deriving classes should always call through to the base implementation. + * * <p>You can safely hold on to <var>menu</var> (and any items created * from it), making modifications to it as desired, until the next * time onCreateOptionsMenu() is called. - * + * * <p>When you add items to the menu, you can implement the Activity's * {@link #onOptionsItemSelected} method to handle them there. - * + * * @param menu The options menu in which you place your items. - * + * * @return You must return true for the menu to be displayed; * if you return false it will not be shown. - * + * * @see #onPrepareOptionsMenu * @see #onOptionsItemSelected */ @@ -2973,17 +2976,17 @@ public class Activity extends ContextThemeWrapper * called right before the menu is shown, every time it is shown. You can * use this method to efficiently enable/disable items or otherwise * dynamically modify the contents. - * + * * <p>The default implementation updates the system menu items based on the * activity's state. Deriving classes should always call through to the * base class implementation. - * + * * @param menu The options menu as last shown or first initialized by * onCreateOptionsMenu(). - * + * * @return You must return true for the menu to be displayed; * if you return false it will not be shown. - * + * * @see #onCreateOptionsMenu */ public boolean onPrepareOptionsMenu(Menu menu) { @@ -3000,15 +3003,15 @@ public class Activity extends ContextThemeWrapper * its Handler as appropriate). You can use this method for any items * for which you would like to do processing without those other * facilities. - * + * * <p>Derived classes should call through to the base class for it to * perform the default menu handling.</p> - * + * * @param item The menu item that was selected. - * + * * @return boolean Return false to allow normal menu processing to * proceed, true to consume it here. - * + * * @see #onCreateOptionsMenu */ public boolean onOptionsItemSelected(MenuItem item) { @@ -3125,7 +3128,7 @@ public class Activity extends ContextThemeWrapper /** * This hook is called whenever the options menu is being closed (either by the user canceling * the menu with the back/menu button, or when an item is selected). - * + * * @param menu The options menu as last shown or first initialized by * onCreateOptionsMenu(). */ @@ -3134,7 +3137,7 @@ public class Activity extends ContextThemeWrapper mParent.onOptionsMenuClosed(menu); } } - + /** * Programmatically opens the options menu. If the options menu is already * open, this method does nothing. @@ -3144,7 +3147,7 @@ public class Activity extends ContextThemeWrapper mWindow.openPanel(Window.FEATURE_OPTIONS_PANEL, null); } } - + /** * Progammatically closes the options menu. If the options menu is already * closed, this method does nothing. @@ -3175,43 +3178,43 @@ public class Activity extends ContextThemeWrapper * {@link OnCreateContextMenuListener} on the view to this activity, so * {@link #onCreateContextMenu(ContextMenu, View, ContextMenuInfo)} will be * called when it is time to show the context menu. - * + * * @see #unregisterForContextMenu(View) * @param view The view that should show a context menu. */ public void registerForContextMenu(View view) { view.setOnCreateContextMenuListener(this); } - + /** * Prevents a context menu to be shown for the given view. This method will remove the * {@link OnCreateContextMenuListener} on the view. - * + * * @see #registerForContextMenu(View) * @param view The view that should stop showing a context menu. */ public void unregisterForContextMenu(View view) { view.setOnCreateContextMenuListener(null); } - + /** * Programmatically opens the context menu for a particular {@code view}. * The {@code view} should have been added via * {@link #registerForContextMenu(View)}. - * + * * @param view The view to show the context menu for. */ public void openContextMenu(View view) { view.showContextMenu(); } - + /** * Programmatically closes the most recently opened context menu, if showing. */ public void closeContextMenu() { mWindow.closePanel(Window.FEATURE_CONTEXT_MENU); } - + /** * This hook is called whenever an item in a context menu is selected. The * default implementation simply returns false to have the normal processing @@ -3224,7 +3227,7 @@ public class Activity extends ContextThemeWrapper * <p> * Derived classes should call through to the base class for it to perform * the default menu handling. - * + * * @param item The context menu item that was selected. * @return boolean Return false to allow normal context menu processing to * proceed, true to consume it here. @@ -3240,7 +3243,7 @@ public class Activity extends ContextThemeWrapper * This hook is called whenever the context menu is being closed (either by * the user canceling the menu with the back/menu button, or when an item is * selected). - * + * * @param menu The context menu that is being closed. */ public void onContextMenuClosed(Menu menu) { @@ -3309,14 +3312,14 @@ public class Activity extends ContextThemeWrapper * Provides an opportunity to prepare a managed dialog before it is being * shown. The default implementation calls through to * {@link #onPrepareDialog(int, Dialog)} for compatibility. - * + * * <p> * Override this if you need to update a managed dialog based on the state * of the application each time it is shown. For example, a time picker * dialog might want to be updated with the current time. You should call * through to the superclass's implementation. The default implementation * will set this Activity as the owner activity on the Dialog. - * + * * @param id The id of the managed dialog. * @param dialog The dialog. * @param args The dialog arguments provided to {@link #showDialog(int, Bundle)}. @@ -3367,7 +3370,7 @@ public class Activity extends ContextThemeWrapper * If you need to rebuild the dialog, call {@link #removeDialog(int)} first. * @return Returns true if the Dialog was created; false is returned if * it is not created because {@link #onCreateDialog(int, Bundle)} returns false. - * + * * @see Dialog * @see #onCreateDialog(int, Bundle) * @see #onPrepareDialog(int, Dialog, Bundle) @@ -3393,7 +3396,7 @@ public class Activity extends ContextThemeWrapper } mManagedDialogs.put(id, md); } - + md.mArgs = args; onPrepareDialog(id, md.mDialog, args); md.mDialog.show(); @@ -3422,7 +3425,7 @@ public class Activity extends ContextThemeWrapper if (mManagedDialogs == null) { throw missingDialog(id); } - + final ManagedDialog md = mManagedDialogs.get(id); if (md == null) { throw missingDialog(id); @@ -3449,7 +3452,7 @@ public class Activity extends ContextThemeWrapper * <p>As of {@link android.os.Build.VERSION_CODES#GINGERBREAD}, this function * will not throw an exception if you try to remove an ID that does not * currently have an associated dialog.</p> - * + * * @param id The id of the managed dialog. * * @see #onCreateDialog(int, Bundle) @@ -3474,37 +3477,37 @@ public class Activity extends ContextThemeWrapper /** * This hook is called when the user signals the desire to start a search. - * + * * <p>You can use this function as a simple way to launch the search UI, in response to a - * menu item, search button, or other widgets within your activity. Unless overidden, + * menu item, search button, or other widgets within your activity. Unless overidden, * calling this function is the same as calling * {@link #startSearch startSearch(null, false, null, false)}, which launches * search for the current activity as specified in its manifest, see {@link SearchManager}. - * + * * <p>You can override this function to force global search, e.g. in response to a dedicated * search key, or to block search entirely (by simply returning false). - * + * * @return Returns {@code true} if search launched, and {@code false} if activity blocks it. * The default implementation always returns {@code true}. - * + * * @see android.app.SearchManager */ public boolean onSearchRequested() { - startSearch(null, false, null, false); + startSearch(null, false, null, false); return true; } - + /** * This hook is called to launch the search UI. - * - * <p>It is typically called from onSearchRequested(), either directly from - * Activity.onSearchRequested() or from an overridden version in any given + * + * <p>It is typically called from onSearchRequested(), either directly from + * Activity.onSearchRequested() or from an overridden version in any given * Activity. If your goal is simply to activate search, it is preferred to call * onSearchRequested(), which may have been overridden elsewhere in your Activity. If your goal * is to inject specific data such as context data, it is preferred to <i>override</i> * onSearchRequested(), so that any callers to it will benefit from the override. - * - * @param initialQuery Any non-null non-empty string will be inserted as + * + * @param initialQuery Any non-null non-empty string will be inserted as * pre-entered text in the search query box. * @param selectInitialQuery If true, the initial query will be preselected, which means that * any further typing will replace it. This is useful for cases where an entire pre-formed @@ -3512,15 +3515,15 @@ public class Activity extends ContextThemeWrapper * inserted query. This is useful when the inserted query is text that the user entered, * and the user would expect to be able to keep typing. <i>This parameter is only meaningful * if initialQuery is a non-empty string.</i> - * @param appSearchData An application can insert application-specific - * context here, in order to improve quality or specificity of its own + * @param appSearchData An application can insert application-specific + * context here, in order to improve quality or specificity of its own * searches. This data will be returned with SEARCH intent(s). Null if * no extra data is required. * @param globalSearch If false, this will only launch the search that has been specifically - * defined by the application (which is usually defined as a local search). If no default + * defined by the application (which is usually defined as a local search). If no default * search is defined in the current application or activity, global search will be launched. * If true, this will always launch a platform-global (e.g. web-based) search instead. - * + * * @see android.app.SearchManager * @see #onSearchRequested */ @@ -3528,7 +3531,7 @@ public class Activity extends ContextThemeWrapper @Nullable Bundle appSearchData, boolean globalSearch) { ensureSearchManager(); mSearchManager.startSearch(initialQuery, selectInitialQuery, getComponentName(), - appSearchData, globalSearch); + appSearchData, globalSearch); } /** @@ -3550,7 +3553,7 @@ public class Activity extends ContextThemeWrapper * Request that key events come to this activity. Use this if your * activity has no views with focus, but the activity still wants * a chance to process key events. - * + * * @see android.view.Window#takeKeyEvents */ public void takeKeyEvents(boolean get) { @@ -3560,12 +3563,12 @@ public class Activity extends ContextThemeWrapper /** * Enable extended window features. This is a convenience for calling * {@link android.view.Window#requestFeature getWindow().requestFeature()}. - * + * * @param featureId The desired feature as defined in * {@link android.view.Window}. * @return Returns true if the requested feature is supported and now * enabled. - * + * * @see android.view.Window#requestFeature */ public final boolean requestWindowFeature(int featureId) { @@ -3677,7 +3680,7 @@ public class Activity extends ContextThemeWrapper * Launch an activity for which you would like a result when it finished. * When this activity exits, your * onActivityResult() method will be called with the given requestCode. - * Using a negative requestCode is the same as calling + * Using a negative requestCode is the same as calling * {@link #startActivity} (the activity is not launched as a sub-activity). * * <p>Note that this method should only be used with Intent protocols @@ -3687,7 +3690,7 @@ public class Activity extends ContextThemeWrapper * are launching uses the singleTask launch mode, it will not run in your * task and thus you will immediately receive a cancel result. * - * <p>As a special case, if you call startActivityForResult() with a requestCode + * <p>As a special case, if you call startActivityForResult() with a requestCode * >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your * activity, then your window will not be displayed until a result is * returned back from the started activity. This is to avoid visible @@ -3845,7 +3848,7 @@ public class Activity extends ContextThemeWrapper * here; otherwise, its associated action will be executed (such as * sending a broadcast) as if you had called * {@link IntentSender#sendIntent IntentSender.sendIntent} on it. - * + * * @param intent The IntentSender to launch. * @param requestCode If >= 0, this code will be returned in * onActivityResult() when the activity exits. @@ -3936,19 +3939,19 @@ public class Activity extends ContextThemeWrapper * information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not * required; if not specified, the new activity will be added to the * task of the caller. - * + * * <p>This method throws {@link android.content.ActivityNotFoundException} * if there was no Activity found to run the given Intent. - * - * @param intent The intent to start. + * + * @param intent The intent to start. * @param options Additional options for how the Activity should be started. * See {@link android.content.Context#startActivity(Intent, Bundle) * Context.startActivity(Intent, Bundle)} for more details. - * + * * @throws android.content.ActivityNotFoundException * * @see {@link #startActivity(Intent)} - * @see #startActivityForResult + * @see #startActivityForResult */ @Override public void startActivity(Intent intent, @Nullable Bundle options) { @@ -4008,7 +4011,7 @@ public class Activity extends ContextThemeWrapper /** * Same as calling {@link #startIntentSender(IntentSender, Intent, int, int, int, Bundle)} * with no options. - * + * * @param intent The IntentSender to launch. * @param fillInIntent If non-null, this will be provided as the * intent parameter to {@link IntentSender#sendIntent}. @@ -4081,19 +4084,19 @@ public class Activity extends ContextThemeWrapper /** * A special variation to launch an activity only if a new activity * instance is needed to handle the given Intent. In other words, this is - * just like {@link #startActivityForResult(Intent, int)} except: if you are + * just like {@link #startActivityForResult(Intent, int)} except: if you are * using the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP} flag, or - * singleTask or singleTop + * singleTask or singleTop * {@link android.R.styleable#AndroidManifestActivity_launchMode launchMode}, - * and the activity - * that handles <var>intent</var> is the same as your currently running - * activity, then a new instance is not needed. In this case, instead of - * the normal behavior of calling {@link #onNewIntent} this function will - * return and you can handle the Intent yourself. - * + * and the activity + * that handles <var>intent</var> is the same as your currently running + * activity, then a new instance is not needed. In this case, instead of + * the normal behavior of calling {@link #onNewIntent} this function will + * return and you can handle the Intent yourself. + * * <p>This function can only be called from a top-level activity; if it is * called from a child activity, a runtime exception will be thrown. - * + * * @param intent The intent to start. * @param requestCode If >= 0, this code will be returned in * onActivityResult() when the activity exits, as described in @@ -4101,10 +4104,10 @@ public class Activity extends ContextThemeWrapper * @param options Additional options for how the Activity should be started. * See {@link android.content.Context#startActivity(Intent, Bundle) * Context.startActivity(Intent, Bundle)} for more details. - * + * * @return If a new activity was launched then true is returned; otherwise * false is returned and you must handle the Intent yourself. - * + * * @see #startActivity * @see #startActivityForResult */ @@ -4167,7 +4170,7 @@ public class Activity extends ContextThemeWrapper * other activity components. You can use this to hand the Intent off * to the next Activity that can handle it. You typically call this in * {@link #onCreate} with the Intent returned by {@link #getIntent}. - * + * * @param intent The intent to dispatch to the next activity. For * correct behavior, this must be the same as the Intent that started * your own activity; the only changes you can make are to the extras @@ -4175,7 +4178,7 @@ public class Activity extends ContextThemeWrapper * @param options Additional options for how the Activity should be started. * See {@link android.content.Context#startActivity(Intent, Bundle) * Context.startActivity(Intent, Bundle)} for more details. - * + * * @return Returns a boolean indicating whether there was another Activity * to start: true if there was a next activity to start, false if there * wasn't. In general, if true is returned you will then want to call @@ -4217,23 +4220,23 @@ public class Activity extends ContextThemeWrapper } /** - * This is called when a child activity of this one calls its + * This is called when a child activity of this one calls its * {@link #startActivity} or {@link #startActivityForResult} method. - * + * * <p>This method throws {@link android.content.ActivityNotFoundException} * if there was no Activity found to run the given Intent. - * + * * @param child The activity making the call. * @param intent The intent to start. * @param requestCode Reply request code. < 0 if reply is not requested. * @param options Additional options for how the Activity should be started. * See {@link android.content.Context#startActivity(Intent, Bundle) * Context.startActivity(Intent, Bundle)} for more details. - * + * * @throws android.content.ActivityNotFoundException - * - * @see #startActivity - * @see #startActivityForResult + * + * @see #startActivity + * @see #startActivityForResult */ public void startActivityFromChild(@NonNull Activity child, Intent intent, int requestCode, @Nullable Bundle options) { @@ -4267,24 +4270,24 @@ public class Activity extends ContextThemeWrapper } /** - * This is called when a Fragment in this activity calls its + * This is called when a Fragment in this activity calls its * {@link Fragment#startActivity} or {@link Fragment#startActivityForResult} * method. - * + * * <p>This method throws {@link android.content.ActivityNotFoundException} * if there was no Activity found to run the given Intent. - * + * * @param fragment The fragment making the call. * @param intent The intent to start. - * @param requestCode Reply request code. < 0 if reply is not requested. + * @param requestCode Reply request code. < 0 if reply is not requested. * @param options Additional options for how the Activity should be started. * See {@link android.content.Context#startActivity(Intent, Bundle) * Context.startActivity(Intent, Bundle)} for more details. - * + * * @throws android.content.ActivityNotFoundException - * - * @see Fragment#startActivity - * @see Fragment#startActivityForResult + * + * @see Fragment#startActivity + * @see Fragment#startActivityForResult */ public void startActivityFromFragment(@NonNull Fragment fragment, Intent intent, int requestCode, @Nullable Bundle options) { @@ -4352,14 +4355,14 @@ public class Activity extends ContextThemeWrapper } catch (RemoteException e) { } } - + /** * Call this to set the result that your activity will return to its * caller. - * + * * @param resultCode The result code to propagate back to the originating * activity, often RESULT_CANCELED or RESULT_OK - * + * * @see #RESULT_CANCELED * @see #RESULT_OK * @see #RESULT_FIRST_USER @@ -4388,7 +4391,7 @@ public class Activity extends ContextThemeWrapper * @param resultCode The result code to propagate back to the originating * activity, often RESULT_CANCELED or RESULT_OK * @param data The data to propagate back to the originating activity. - * + * * @see #RESULT_CANCELED * @see #RESULT_OK * @see #RESULT_FIRST_USER @@ -4406,10 +4409,10 @@ public class Activity extends ContextThemeWrapper * the data in {@link #setResult setResult()} will be sent to. You can * use this information to validate that the recipient is allowed to * receive the data. - * + * * <p class="note">Note: if the calling activity is not expecting a result (that is it - * did not use the {@link #startActivityForResult} - * form that includes a request code), then the calling package will be + * did not use the {@link #startActivityForResult} + * form that includes a request code), then the calling package will be * null.</p> * * <p class="note">Note: prior to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, @@ -4417,7 +4420,7 @@ public class Activity extends ContextThemeWrapper * package was no longer running, it would return null instead of the proper package * name. You can use {@link #getCallingActivity()} and retrieve the package name * from that instead.</p> - * + * * @return The package of the activity that will receive your * reply, or null if none. */ @@ -4435,12 +4438,12 @@ public class Activity extends ContextThemeWrapper * who the data in {@link #setResult setResult()} will be sent to. You * can use this information to validate that the recipient is allowed to * receive the data. - * + * * <p class="note">Note: if the calling activity is not expecting a result (that is it - * did not use the {@link #startActivityForResult} - * form that includes a request code), then the calling package will be - * null. - * + * did not use the {@link #startActivityForResult} + * form that includes a request code), then the calling package will be + * null. + * * @return The ComponentName of the activity that will receive your * reply, or null if none. */ @@ -4459,7 +4462,7 @@ public class Activity extends ContextThemeWrapper * UI itself, but can't just finish prior to onResume() because it needs * to wait for a service binding or such. Setting this to false allows * you to prevent your UI from being shown during that time. - * + * * <p>The default value for this is taken from the * {@link android.R.attr#windowNoDisplay} attribute of the activity's theme. */ @@ -4472,7 +4475,7 @@ public class Activity extends ContextThemeWrapper } } } - + void makeVisible() { if (!mWindowAdded) { ViewManager wm = getWindowManager(); @@ -4481,16 +4484,16 @@ public class Activity extends ContextThemeWrapper } mDecor.setVisibility(View.VISIBLE); } - + /** * Check to see whether this activity is in the process of finishing, * either because you called {@link #finish} on it or someone else * has requested that it finished. This is often used in * {@link #onPause} to determine whether the activity is simply pausing or * completely finishing. - * + * * @return If the activity is finishing, returns true; else returns false. - * + * * @see #finish */ public boolean isFinishing() { @@ -4510,7 +4513,7 @@ public class Activity extends ContextThemeWrapper * recreated with a new configuration. This is often used in * {@link #onStop} to determine whether the state needs to be cleaned up or will be passed * on to the next instance of the activity via {@link #onRetainNonConfigurationInstance()}. - * + * * @return If the activity is being torn down in order to be recreated with a new configuration, * returns true; else returns false. */ @@ -4603,12 +4606,12 @@ public class Activity extends ContextThemeWrapper } /** - * This is called when a child activity of this one calls its + * This is called when a child activity of this one calls its * {@link #finish} method. The default implementation simply calls * finish() on this activity (the parent), finishing the entire group. - * + * * @param child The activity making the call. - * + * * @see #finish */ public void finishFromChild(Activity child) { @@ -4631,7 +4634,7 @@ public class Activity extends ContextThemeWrapper /** * Force finish another activity that you had previously started with * {@link #startActivityForResult}. - * + * * @param requestCode The request code of the activity that you had * given to startActivityForResult(). If there are multiple * activities started with this request code, they @@ -4653,7 +4656,7 @@ public class Activity extends ContextThemeWrapper /** * This is called when a child activity of this one calls its * finishActivity(). - * + * * @param child The activity making the call. * @param requestCode Request code that had been used to start the * activity. @@ -4681,10 +4684,10 @@ public class Activity extends ContextThemeWrapper * data from it. The <var>resultCode</var> will be * {@link #RESULT_CANCELED} if the activity explicitly returned that, * didn't return any result, or crashed during its operation. - * + * * <p>You will receive this call immediately before onResume() when your * activity is re-starting. - * + * * @param requestCode The integer request code originally supplied to * startActivityForResult(), allowing you to identify who this * result came from. @@ -4692,7 +4695,7 @@ public class Activity extends ContextThemeWrapper * through its setResult(). * @param data An Intent, which can return result data to the caller * (various data can be attached to Intent "extras"). - * + * * @see #startActivityForResult * @see #createPendingResult * @see #setResult(int) @@ -4722,12 +4725,12 @@ public class Activity extends ContextThemeWrapper } /** - * Create a new PendingIntent object which you can hand to others - * for them to use to send result data back to your - * {@link #onActivityResult} callback. The created object will be either - * one-shot (becoming invalid after a result is sent back) or multiple - * (allowing any number of results to be sent through it). - * + * Create a new PendingIntent object which you can hand to others + * for them to use to send result data back to your + * {@link #onActivityResult} callback. The created object will be either + * one-shot (becoming invalid after a result is sent back) or multiple + * (allowing any number of results to be sent through it). + * * @param requestCode Private request code for the sender that will be * associated with the result data when it is returned. The sender can not * modify this value, allowing you to identify incoming results. @@ -4740,12 +4743,12 @@ public class Activity extends ContextThemeWrapper * or any of the flags as supported by * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts * of the intent that can be supplied when the actual send happens. - * + * * @return Returns an existing or new PendingIntent matching the given * parameters. May return null only if * {@link PendingIntent#FLAG_NO_CREATE PendingIntent.FLAG_NO_CREATE} has been * supplied. - * + * * @see PendingIntent */ public PendingIntent createPendingResult(int requestCode, @NonNull Intent data, @@ -4772,7 +4775,7 @@ public class Activity extends ContextThemeWrapper * orientation, the screen will immediately be changed (possibly causing * the activity to be restarted). Otherwise, this will be used the next * time the activity is visible. - * + * * @param requestedOrientation An orientation constant as used in * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}. */ @@ -4788,13 +4791,13 @@ public class Activity extends ContextThemeWrapper mParent.setRequestedOrientation(requestedOrientation); } } - + /** * Return the current requested orientation of the activity. This will * either be the orientation requested in its component's manifest, or * the last requested orientation given to * {@link #setRequestedOrientation(int)}. - * + * * @return Returns an orientation constant as used in * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}. */ @@ -4812,11 +4815,11 @@ public class Activity extends ContextThemeWrapper } return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; } - + /** * Return the identifier of the task this activity is in. This identifier * will remain the same for the lifetime of the activity. - * + * * @return Task identifier, an opaque integer. */ public int getTaskId() { @@ -4831,7 +4834,7 @@ public class Activity extends ContextThemeWrapper /** * Return whether this activity is the root of a task. The root is the * first activity in a task. - * + * * @return True if this is the root activity, else false. */ public boolean isTaskRoot() { @@ -4846,11 +4849,11 @@ public class Activity extends ContextThemeWrapper /** * Move the task containing this activity to the back of the activity * stack. The activity's order within the task is unchanged. - * + * * @param nonRoot If false then this only works if the activity is the root * of a task; if true it will work for any activity in * a task. - * + * * @return If the task was moved (or it was already at the * back) true is returned, else false. */ @@ -4867,7 +4870,7 @@ public class Activity extends ContextThemeWrapper /** * Returns class name for this activity with the package prefix removed. * This is the default name used to read and write settings. - * + * * @return The local class name. */ @NonNull @@ -4881,10 +4884,10 @@ public class Activity extends ContextThemeWrapper } return cls.substring(packageLen+1); } - + /** * Returns complete component name of this activity. - * + * * @return Returns the complete component name for this activity */ public ComponentName getComponentName() @@ -4897,9 +4900,9 @@ public class Activity extends ContextThemeWrapper * that are private to this activity. This simply calls the underlying * {@link #getSharedPreferences(String, int)} method by passing in this activity's * class name as the preferences name. - * - * @param mode Operating mode. Use {@link #MODE_PRIVATE} for the default - * operation, {@link #MODE_WORLD_READABLE} and + * + * @param mode Operating mode. Use {@link #MODE_PRIVATE} for the default + * operation, {@link #MODE_WORLD_READABLE} and * {@link #MODE_WORLD_WRITEABLE} to control permissions. * * @return Returns the single SharedPreferences instance that can be used @@ -4908,12 +4911,12 @@ public class Activity extends ContextThemeWrapper public SharedPreferences getPreferences(int mode) { return getSharedPreferences(getLocalClassName(), mode); } - + private void ensureSearchManager() { if (mSearchManager != null) { return; } - + mSearchManager = new SearchManager(this, null); } @@ -5031,7 +5034,7 @@ public class Activity extends ContextThemeWrapper * <p> * In order for the progress bar to be shown, the feature must be requested * via {@link #requestWindowFeature(int)}. - * + * * @param visible Whether to show the progress bars in the title. */ public final void setProgressBarVisibility(boolean visible) { @@ -5051,14 +5054,14 @@ public class Activity extends ContextThemeWrapper getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, visible ? Window.PROGRESS_VISIBILITY_ON : Window.PROGRESS_VISIBILITY_OFF); } - + /** * Sets whether the horizontal progress bar in the title should be indeterminate (the circular * is always indeterminate). * <p> * In order for the progress bar to be shown, the feature must be requested * via {@link #requestWindowFeature(int)}. - * + * * @param indeterminate Whether the horizontal progress bar should be indeterminate. */ public final void setProgressBarIndeterminate(boolean indeterminate) { @@ -5066,13 +5069,13 @@ public class Activity extends ContextThemeWrapper indeterminate ? Window.PROGRESS_INDETERMINATE_ON : Window.PROGRESS_INDETERMINATE_OFF); } - + /** * Sets the progress for the progress bars in the title. * <p> * In order for the progress bar to be shown, the feature must be requested * via {@link #requestWindowFeature(int)}. - * + * * @param progress The progress for the progress bar. Valid ranges are from * 0 to 10000 (both inclusive). If 10000 is given, the progress * bar will be completely filled and will fade out. @@ -5080,7 +5083,7 @@ public class Activity extends ContextThemeWrapper public final void setProgress(int progress) { getWindow().setFeatureInt(Window.FEATURE_PROGRESS, progress + Window.PROGRESS_START); } - + /** * Sets the secondary progress for the progress bar in the title. This * progress is drawn between the primary progress (set via @@ -5090,7 +5093,7 @@ public class Activity extends ContextThemeWrapper * <p> * In order for the progress bar to be shown, the feature must be requested * via {@link #requestWindowFeature(int)}. - * + * * @param secondaryProgress The secondary progress for the progress bar. Valid ranges are from * 0 to 10000 (both inclusive). */ @@ -5104,16 +5107,16 @@ public class Activity extends ContextThemeWrapper * volume controls. * <p> * The suggested audio stream will be tied to the window of this Activity. - * If the Activity is switched, the stream set here is no longer the - * suggested stream. The client does not need to save and restore the old - * suggested stream value in onPause and onResume. - * + * Volume requests which are received while the Activity is in the + * foreground will affect this stream. + * <p> + * It is not guaranteed that the hardware volume controls will always change + * this stream's volume (for example, if a call is in progress, its stream's + * volume may be changed instead). To reset back to the default, use + * {@link AudioManager#USE_DEFAULT_STREAM_TYPE}. + * * @param streamType The type of the audio stream whose volume should be - * changed by the hardware volume controls. It is not guaranteed that - * the hardware volume controls will always change this stream's - * volume (for example, if a call is in progress, its stream's volume - * may be changed instead). To reset back to the default, use - * {@link AudioManager#USE_DEFAULT_STREAM_TYPE}. + * changed by the hardware volume controls. */ public final void setVolumeControlStream(int streamType) { getWindow().setVolumeControlStream(streamType); @@ -5122,7 +5125,7 @@ public class Activity extends ContextThemeWrapper /** * Gets the suggested audio stream whose volume should be changed by the * hardware volume controls. - * + * * @return The suggested audio stream type whose volume should be changed by * the hardware volume controls. * @see #setVolumeControlStream(int) @@ -5130,7 +5133,40 @@ public class Activity extends ContextThemeWrapper public final int getVolumeControlStream() { return getWindow().getVolumeControlStream(); } - + + /** + * Sets a {@link MediaController} to send media keys and volume changes to. + * <p> + * The controller will be tied to the window of this Activity. Media key and + * volume events which are received while the Activity is in the foreground + * will be forwarded to the controller and used to invoke transport controls + * or adjust the volume. This may be used instead of or in addition to + * {@link #setVolumeControlStream} to affect a specific session instead of a + * specific stream. + * <p> + * It is not guaranteed that the hardware volume controls will always change + * this session's volume (for example, if a call is in progress, its + * stream's volume may be changed instead). To reset back to the default use + * null as the controller. + * + * @param controller The controller for the session which should receive + * media keys and volume changes. + */ + public final void setMediaController(MediaController controller) { + getWindow().setMediaController(controller); + } + + /** + * Gets the controller which should be receiving media key and volume events + * while this activity is in the foreground. + * + * @return The controller which should receive events. + * @see #setMediaController(android.media.session.MediaController) + */ + public final MediaController getMediaController() { + return getWindow().getMediaController(); + } + /** * Runs the specified action on the UI thread. If the current thread is the UI * thread, then the action is executed immediately. If the current thread is @@ -5176,7 +5212,7 @@ public class Activity extends ContextThemeWrapper if (!"fragment".equals(name)) { return onCreateView(name, context, attrs); } - + return mFragments.onCreateView(parent, name, context, attrs); } @@ -5737,7 +5773,7 @@ public class Activity extends ContextThemeWrapper } // ------------------ Internal API ------------------ - + final void setParent(Activity parent) { mParent = parent; } @@ -5751,7 +5787,7 @@ public class Activity extends ContextThemeWrapper attachBaseContext(context); mFragments.attachActivity(this, mContainer, null); - + mWindow = PolicyManager.makeNewWindow(this); mWindow.setCallback(this); mWindow.setOnWindowDismissedCallback(this); @@ -5846,7 +5882,7 @@ public class Activity extends ContextThemeWrapper } mActivityTransitionState.enterReady(this); } - + final void performRestart() { mFragments.noteStateNotSaved(); @@ -5885,14 +5921,14 @@ public class Activity extends ContextThemeWrapper performStart(); } } - + final void performResume() { performRestart(); - + mFragments.execPendingActions(); - + mLastNonConfigurationInstances = null; - + mCalled = false; // mResumed is set by the instrumentation mInstrumentation.callActivityOnResume(this); @@ -5904,10 +5940,10 @@ public class Activity extends ContextThemeWrapper // Now really resume, and install the current status bar and menu. mCalled = false; - + mFragments.dispatchResume(); mFragments.execPendingActions(); - + onPostResume(); if (!mCalled) { throw new SuperNotCalledException( @@ -5930,12 +5966,12 @@ public class Activity extends ContextThemeWrapper } mResumed = false; } - + final void performUserLeaving() { onUserInteraction(); onUserLeaveHint(); } - + final void performStop() { mDoReportFullyDrawn = false; if (mLoadersStarted) { @@ -5948,7 +5984,7 @@ public class Activity extends ContextThemeWrapper } } } - + if (!mStopped) { if (mWindow != null) { mWindow.closeAllPanels(); @@ -5957,9 +5993,9 @@ public class Activity extends ContextThemeWrapper if (mToken != null && mParent == null) { WindowManagerGlobal.getInstance().setStoppedState(mToken, true); } - + mFragments.dispatchStop(); - + mCalled = false; mInstrumentation.callActivityOnStop(this); if (!mCalled) { @@ -5967,7 +6003,7 @@ public class Activity extends ContextThemeWrapper "Activity " + mComponent.toShortString() + " did not call through to super.onStop()"); } - + synchronized (mManagedCursors) { final int N = mManagedCursors.size(); for (int i=0; i<N; i++) { diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index aa71ed8..c169d35 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -23,6 +23,8 @@ import android.content.res.Configuration; import android.content.res.TypedArray; import android.graphics.PixelFormat; import android.graphics.drawable.Drawable; +import android.media.session.MediaController; +import android.media.session.MediaSession; import android.net.Uri; import android.os.Bundle; import android.os.IBinder; @@ -157,7 +159,7 @@ public abstract class Window { private static final String PROPERTY_HARDWARE_UI = "persist.sys.ui.hw"; private final Context mContext; - + private TypedArray mWindowStyle; private Callback mCallback; private OnWindowDismissedCallback mOnWindowDismissedCallback; @@ -181,7 +183,7 @@ public abstract class Window { private int mDefaultWindowFormat = PixelFormat.OPAQUE; private boolean mHasSoftInputMode = false; - + private boolean mDestroyed; // The current window attributes. @@ -227,7 +229,7 @@ public abstract class Window { * @return boolean Return true if this event was consumed. */ public boolean dispatchTouchEvent(MotionEvent event); - + /** * Called to process trackball events. At the very least your * implementation must call @@ -313,14 +315,14 @@ public abstract class Window { * Called when a panel's menu is opened by the user. This may also be * called when the menu is changing from one type to another (for * example, from the icon menu to the expanded menu). - * + * * @param featureId The panel that the menu is in. * @param menu The menu that is opened. * @return Return true to allow the menu to open, or false to prevent * the menu from opening. */ public boolean onMenuOpened(int featureId, Menu menu); - + /** * Called when a panel's menu item has been selected by the user. * @@ -364,31 +366,31 @@ public abstract class Window { * for more information. */ public void onAttachedToWindow(); - + /** * Called when the window has been attached to the window manager. * See {@link View#onDetachedFromWindow() View.onDetachedFromWindow()} * for more information. */ public void onDetachedFromWindow(); - + /** * Called when a panel is being closed. If another logical subsequent * panel is being opened (and this panel is being closed to make room for the subsequent * panel), this method will NOT be called. - * + * * @param featureId The panel that is being displayed. * @param menu If onCreatePanelView() returned null, this is the Menu * being displayed in the panel. */ public void onPanelClosed(int featureId, Menu menu); - + /** * Called when the user signals the desire to start a search. - * + * * @return true if search launched, false if activity refuses (blocks) - * - * @see android.app.Activity#onSearchRequested() + * + * @see android.app.Activity#onSearchRequested() */ public boolean onSearchRequested(); @@ -457,7 +459,7 @@ public abstract class Window { return mWindowStyle; } } - + /** * Set the container for this window. If not set, the DecorWindow * operates as a top-level window; otherwise, it negotiates with the @@ -488,7 +490,7 @@ public abstract class Window { public final boolean hasChildren() { return mHasChildren; } - + /** @hide */ public final void destroy() { mDestroyed = true; @@ -622,14 +624,14 @@ public abstract class Window { * callback will be used to tell you about state changes to the surface. */ public abstract void takeSurface(SurfaceHolder.Callback2 callback); - + /** * Take ownership of this window's InputQueue. The window will no * longer read and dispatch input events from the queue; it is your * responsibility to do so. */ public abstract void takeInputQueue(InputQueue.Callback callback); - + /** * Return whether this window is being displayed with a floating style * (based on the {@link android.R.attr#windowIsFloating} attribute in @@ -740,7 +742,7 @@ public abstract class Window { } dispatchWindowAttributesChanged(attrs); } - + /** * Convenience function to set the flag bits as specified in flags, as * per {@link #setFlags}. @@ -756,7 +758,7 @@ public abstract class Window { public void addPrivateFlags(int flags) { setPrivateFlags(flags, flags); } - + /** * Convenience function to clear the flag bits as specified in flags, as * per {@link #setFlags}. @@ -772,7 +774,7 @@ public abstract class Window { * Set the flags of the window, as per the * {@link WindowManager.LayoutParams WindowManager.LayoutParams} * flags. - * + * * <p>Note that some flags must be set before the window decoration is * created (by the first call to * {@link #setContentView(View, android.view.ViewGroup.LayoutParams)} or @@ -859,20 +861,20 @@ public abstract class Window { protected final int getForcedWindowFlags() { return mForcedWindowFlags; } - + /** * Has the app specified their own soft input mode? */ protected final boolean hasSoftInputMode() { return mHasSoftInputMode; } - + /** @hide */ public void setCloseOnTouchOutside(boolean close) { mCloseOnTouchOutside = close; mSetCloseOnTouchOutside = true; } - + /** @hide */ public void setCloseOnTouchOutsideIfNotSet(boolean close) { if (!mSetCloseOnTouchOutside) { @@ -880,10 +882,10 @@ public abstract class Window { mSetCloseOnTouchOutside = true; } } - + /** @hide */ public abstract void alwaysReadCloseOnTouchAttr(); - + /** @hide */ public boolean shouldCloseOnTouch(Context context, MotionEvent event) { if (mCloseOnTouchOutside && event.getAction() == MotionEvent.ACTION_DOWN @@ -892,7 +894,7 @@ public abstract class Window { } return false; } - + private boolean isOutOfBounds(Context context, MotionEvent event) { final int x = (int) event.getX(); final int y = (int) event.getY(); @@ -902,7 +904,7 @@ public abstract class Window { || (x > (decorView.getWidth()+slop)) || (y > (decorView.getHeight()+slop)); } - + /** * Enable extended screen features. This must be called before * setContentView(). May be called as many times as desired as long as it @@ -989,7 +991,7 @@ public abstract class Window { * of the window that can not, from this point forward, be changed: the * features that have been requested with {@link #requestFeature(int)}, * and certain window flags as described in {@link #setFlags(int, int)}. - * + * * @param view The desired content to display. * @param params Layout parameters for the view. */ @@ -1037,7 +1039,7 @@ public abstract class Window { public abstract void togglePanel(int featureId, KeyEvent event); public abstract void invalidatePanelMenu(int featureId); - + public abstract boolean performPanelShortcut(int featureId, int keyCode, KeyEvent event, @@ -1052,17 +1054,17 @@ public abstract class Window { /** * Should be called when the configuration is changed. - * + * * @param newConfig The new configuration. */ public abstract void onConfigurationChanged(Configuration newConfig); - + /** * Change the background of this window to a Drawable resource. Setting the * background to null will make the window be opaque. To make the window * transparent, you can use an empty drawable (for instance a ColorDrawable * with the color 0 or the system drawable android:drawable/empty.) - * + * * @param resid The resource identifier of a drawable resource which will be * installed as the new background. */ @@ -1173,7 +1175,7 @@ public abstract class Window { * */ public abstract boolean superDispatchTouchEvent(MotionEvent event); - + /** * Used by custom windows, such as Dialog, to pass the trackball event * further down the view hierarchy. Application developers should @@ -1181,7 +1183,7 @@ public abstract class Window { * */ public abstract boolean superDispatchTrackballEvent(MotionEvent event); - + /** * Used by custom windows, such as Dialog, to pass the generic motion event * further down the view hierarchy. Application developers should @@ -1194,11 +1196,11 @@ public abstract class Window { * Retrieve the top-level window decor view (containing the standard * window frame/decorations and the client's content inside of that), which * can be added as a window to the window manager. - * + * * <p><em>Note that calling this function for the first time "locks in" * various window characteristics as described in * {@link #setContentView(View, android.view.ViewGroup.LayoutParams)}.</em></p> - * + * * @return Returns the top-level window decor view. */ public abstract View getDecorView(); @@ -1206,16 +1208,16 @@ public abstract class Window { /** * Retrieve the current decor view, but only if it has already been created; * otherwise returns null. - * + * * @return Returns the top-level window decor or null. * @see #getDecorView */ public abstract View peekDecorView(); public abstract Bundle saveHierarchyState(); - + public abstract void restoreHierarchyState(Bundle savedInstanceState); - + protected abstract void onActive(); /** @@ -1233,10 +1235,10 @@ public abstract class Window { { return mFeatures; } - + /** * Query for the availability of a certain feature. - * + * * @param feature The feature ID to check * @return true if the feature is enabled, false otherwise. */ @@ -1290,9 +1292,9 @@ public abstract class Window { * @param event the {@link android.view.KeyEvent} to use to help check. */ public abstract boolean isShortcutKey(int keyCode, KeyEvent event); - + /** - * @see android.app.Activity#setVolumeControlStream(int) + * @see android.app.Activity#setVolumeControlStream(int) */ public abstract void setVolumeControlStream(int streamType); @@ -1302,6 +1304,19 @@ public abstract class Window { public abstract int getVolumeControlStream(); /** + * @see android.app.Activity#setMediaController(android.media.session.MediaController) + */ + public void setMediaController(MediaController controller) { + } + + /** + * @see android.app.Activity#getMediaController() + */ + public MediaController getMediaController() { + return null; + } + + /** * Set extra options that will influence the UI for this window. * @param uiOptions Flags specifying extra options for this window. */ diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java index 73bc61a..740a9d3 100644 --- a/media/java/android/media/RemoteControlClient.java +++ b/media/java/android/media/RemoteControlClient.java @@ -682,9 +682,13 @@ public class RemoteControlClient // USE_SESSIONS if (mSession != null) { int pbState = PlaybackState.getStateFromRccState(state); - mSessionPlaybackState.setState(pbState, hasPosition ? - mPlaybackPositionMs : PlaybackState.PLAYBACK_POSITION_UNKNOWN, - playbackSpeed); + long position = hasPosition ? mPlaybackPositionMs + : PlaybackState.PLAYBACK_POSITION_UNKNOWN; + + PlaybackState.Builder bob = new PlaybackState.Builder(mSessionPlaybackState); + bob.setState(pbState, position, playbackSpeed, SystemClock.elapsedRealtime()); + bob.setErrorMessage(null); + mSessionPlaybackState = bob.build(); mSession.setPlaybackState(mSessionPlaybackState); } } @@ -745,8 +749,9 @@ public class RemoteControlClient // USE_SESSIONS if (mSession != null) { - mSessionPlaybackState.setActions(PlaybackState - .getActionsFromRccControlFlags(transportControlFlags)); + PlaybackState.Builder bob = new PlaybackState.Builder(mSessionPlaybackState); + bob.setActions(PlaybackState.getActionsFromRccControlFlags(transportControlFlags)); + mSessionPlaybackState = bob.build(); mSession.setPlaybackState(mSessionPlaybackState); } } @@ -946,7 +951,7 @@ public class RemoteControlClient /** * Cache for the current playback state using Session APIs. */ - private final PlaybackState mSessionPlaybackState = new PlaybackState(); + private PlaybackState mSessionPlaybackState = null; /** * Cache for metadata using Session APIs. This is re-initialized in apply(). diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java index 1f5b216..9ea3f26 100644 --- a/media/java/android/media/RemoteController.java +++ b/media/java/android/media/RemoteController.java @@ -1020,7 +1020,7 @@ public final class RemoteController l.onClientPlaybackStateUpdate(playstate); } else { l.onClientPlaybackStateUpdate(playstate, state.getLastPositionUpdateTime(), - state.getPosition(), state.getPlaybackRate()); + state.getPosition(), state.getPlaybackSpeed()); } if (state != null) { l.onClientTransportControlUpdate(PlaybackState.getRccControlFlagsFromActions(state diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java index 9ae2436..f7e7176 100644 --- a/media/java/android/media/session/PlaybackState.java +++ b/media/java/android/media/session/PlaybackState.java @@ -184,41 +184,29 @@ public final class PlaybackState implements Parcelable { */ public final static long PLAYBACK_POSITION_UNKNOWN = -1; - private int mState; - private long mPosition; - private long mBufferPosition; - private float mRate; - private long mActions; - private CharSequence mErrorMessage; - private long mUpdateTime; - - /** - * Create an empty PlaybackState. At minimum a state and actions should be - * set before publishing a PlaybackState. - */ - public PlaybackState() { - } - - /** - * Create a new PlaybackState from an existing PlaybackState. All fields - * will be copied to the new state. - * - * @param from The PlaybackState to duplicate - */ - public PlaybackState(PlaybackState from) { - mState = from.mState; - mPosition = from.mPosition; - mRate = from.mRate; - mUpdateTime = from.mUpdateTime; - mBufferPosition = from.mBufferPosition; - mActions = from.mActions; - mErrorMessage = from.mErrorMessage; + private final int mState; + private final long mPosition; + private final long mBufferPosition; + private final float mSpeed; + private final long mActions; + private final CharSequence mErrorMessage; + private final long mUpdateTime; + + private PlaybackState(int state, long position, long updateTime, float speed, + long bufferPosition, long actions, CharSequence error) { + mState = state; + mPosition = position; + mSpeed = speed; + mUpdateTime = updateTime; + mBufferPosition = bufferPosition; + mActions = actions; + mErrorMessage = error; } private PlaybackState(Parcel in) { mState = in.readInt(); mPosition = in.readLong(); - mRate = in.readFloat(); + mSpeed = in.readFloat(); mUpdateTime = in.readLong(); mBufferPosition = in.readLong(); mActions = in.readLong(); @@ -232,7 +220,7 @@ public final class PlaybackState implements Parcelable { bob.append("state=").append(mState); bob.append(", position=").append(mPosition); bob.append(", buffered position=").append(mBufferPosition); - bob.append(", rate=").append(mRate); + bob.append(", speed=").append(mSpeed); bob.append(", updated=").append(mUpdateTime); bob.append(", actions=").append(mActions); bob.append(", error=").append(mErrorMessage); @@ -249,7 +237,7 @@ public final class PlaybackState implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mState); dest.writeLong(mPosition); - dest.writeFloat(mRate); + dest.writeFloat(mSpeed); dest.writeLong(mUpdateTime); dest.writeLong(mBufferPosition); dest.writeLong(mActions); @@ -271,41 +259,6 @@ public final class PlaybackState implements Parcelable { public int getState() { return mState; } - - /** - * Set the current state of playback. - * <p> - * The position must be in ms and indicates the current playback position - * within the track. If the position is unknown use - * {@link #PLAYBACK_POSITION_UNKNOWN}. - * <p> - * The rate is a multiple of normal playback and should be 0 when paused and - * negative when rewinding. Normal playback rate is 1.0. - * <p> - * The state must be one of the following: - * <ul> - * <li> {@link PlaybackState#STATE_NONE}</li> - * <li> {@link PlaybackState#STATE_STOPPED}</li> - * <li> {@link PlaybackState#STATE_PLAYING}</li> - * <li> {@link PlaybackState#STATE_PAUSED}</li> - * <li> {@link PlaybackState#STATE_FAST_FORWARDING}</li> - * <li> {@link PlaybackState#STATE_REWINDING}</li> - * <li> {@link PlaybackState#STATE_BUFFERING}</li> - * <li> {@link PlaybackState#STATE_ERROR}</li> - * </ul> - * - * @param state The current state of playback. - * @param position The position in the current track in ms. - * @param playbackRate The current rate of playback as a multiple of normal - * playback. - */ - public void setState(int state, long position, float playbackRate) { - this.mState = state; - this.mPosition = position; - this.mRate = playbackRate; - mUpdateTime = SystemClock.elapsedRealtime(); - } - /** * Get the current playback position in ms. */ @@ -323,23 +276,14 @@ public final class PlaybackState implements Parcelable { } /** - * Set the current buffer position in ms. This is the farthest playback - * point that can be reached from the current position using only buffered - * content. - */ - public void setBufferPosition(long bufferPosition) { - mBufferPosition = bufferPosition; - } - - /** - * Get the current playback rate as a multiple of normal playback. This + * Get the current playback speed as a multiple of normal playback. This * should be negative when rewinding. A value of 1 means normal playback and * 0 means paused. * - * @return The current rate of playback. + * @return The current speed of playback. */ - public float getPlaybackRate() { - return mRate; + public float getPlaybackSpeed() { + return mSpeed; } /** @@ -362,25 +306,6 @@ public final class PlaybackState implements Parcelable { } /** - * Set the current capabilities available on this session. This should use a - * bitmask of the available capabilities. - * <ul> - * <li> {@link PlaybackState#ACTION_SKIP_TO_PREVIOUS}</li> - * <li> {@link PlaybackState#ACTION_REWIND}</li> - * <li> {@link PlaybackState#ACTION_PLAY}</li> - * <li> {@link PlaybackState#ACTION_PAUSE}</li> - * <li> {@link PlaybackState#ACTION_STOP}</li> - * <li> {@link PlaybackState#ACTION_FAST_FORWARD}</li> - * <li> {@link PlaybackState#ACTION_SKIP_TO_NEXT}</li> - * <li> {@link PlaybackState#ACTION_SEEK_TO}</li> - * <li> {@link PlaybackState#ACTION_SET_RATING}</li> - * </ul> - */ - public void setActions(long capabilities) { - mActions = capabilities; - } - - /** * Get a user readable error message. This should be set when the state is * {@link PlaybackState#STATE_ERROR}. */ @@ -393,21 +318,12 @@ public final class PlaybackState implements Parcelable { * position has never been set this will return 0; * * @return The last time the position was updated. - * @hide */ public long getLastPositionUpdateTime() { return mUpdateTime; } /** - * Set a user readable error message. This should be set when the state is - * {@link PlaybackState#STATE_ERROR}. - */ - public void setErrorMessage(CharSequence errorMessage) { - mErrorMessage = errorMessage; - } - - /** * Get the {@link PlaybackState} state for the given * {@link RemoteControlClient} state. * @@ -574,4 +490,175 @@ public final class PlaybackState implements Parcelable { return new PlaybackState[size]; } }; + + /** + * Builder for {@link PlaybackState} objects. + */ + public static final class Builder { + private int mState; + private long mPosition; + private long mBufferPosition; + private float mSpeed; + private long mActions; + private CharSequence mErrorMessage; + private long mUpdateTime; + + /** + * Creates an initially empty state builder. + */ + public Builder() { + } + + /** + * Creates a builder with the same initial values as those in the from + * state. + * + * @param from The state to use for initializing the builder. + */ + public Builder(PlaybackState from) { + if (from == null) { + return; + } + mState = from.mState; + mPosition = from.mPosition; + mBufferPosition = from.mBufferPosition; + mSpeed = from.mSpeed; + mActions = from.mActions; + mErrorMessage = from.mErrorMessage; + mUpdateTime = from.mUpdateTime; + } + + /** + * Set the current state of playback. + * <p> + * The position must be in ms and indicates the current playback + * position within the track. If the position is unknown use + * {@link #PLAYBACK_POSITION_UNKNOWN}. When not using an unknown + * position the time at which the position was updated must be provided. + * It is okay to use {@link SystemClock#elapsedRealtime()} if the + * current position was just retrieved. + * <p> + * The speed is a multiple of normal playback and should be 0 when + * paused and negative when rewinding. Normal playback speed is 1.0. + * <p> + * The state must be one of the following: + * <ul> + * <li> {@link PlaybackState#STATE_NONE}</li> + * <li> {@link PlaybackState#STATE_STOPPED}</li> + * <li> {@link PlaybackState#STATE_PLAYING}</li> + * <li> {@link PlaybackState#STATE_PAUSED}</li> + * <li> {@link PlaybackState#STATE_FAST_FORWARDING}</li> + * <li> {@link PlaybackState#STATE_REWINDING}</li> + * <li> {@link PlaybackState#STATE_BUFFERING}</li> + * <li> {@link PlaybackState#STATE_ERROR}</li> + * </ul> + * + * @param state The current state of playback. + * @param position The position in the current track in ms. + * @param playbackSpeed The current speed of playback as a multiple of + * normal playback. + * @param updateTime The time in the {@link SystemClock#elapsedRealtime} + * timebase that the position was updated at. + * @return this + */ + public Builder setState(int state, long position, float playbackSpeed, long updateTime) { + mState = state; + mPosition = position; + mUpdateTime = updateTime; + mSpeed = playbackSpeed; + return this; + } + + /** + * Set the current state of playback. + * <p> + * The position must be in ms and indicates the current playback + * position within the track. If the position is unknown use + * {@link #PLAYBACK_POSITION_UNKNOWN}. The update time will be set to + * the current {@link SystemClock#elapsedRealtime()}. + * <p> + * The speed is a multiple of normal playback and should be 0 when + * paused and negative when rewinding. Normal playback speed is 1.0. + * <p> + * The state must be one of the following: + * <ul> + * <li> {@link PlaybackState#STATE_NONE}</li> + * <li> {@link PlaybackState#STATE_STOPPED}</li> + * <li> {@link PlaybackState#STATE_PLAYING}</li> + * <li> {@link PlaybackState#STATE_PAUSED}</li> + * <li> {@link PlaybackState#STATE_FAST_FORWARDING}</li> + * <li> {@link PlaybackState#STATE_REWINDING}</li> + * <li> {@link PlaybackState#STATE_BUFFERING}</li> + * <li> {@link PlaybackState#STATE_ERROR}</li> + * </ul> + * + * @param state The current state of playback. + * @param position The position in the current track in ms. + * @param playbackSpeed The current speed of playback as a multiple of + * normal playback. + * @return this + */ + public Builder setState(int state, long position, float playbackSpeed) { + return setState(state, position, playbackSpeed, SystemClock.elapsedRealtime()); + } + + /** + * Set the current actions available on this session. This should use a + * bitmask of possible actions. + * <ul> + * <li> {@link PlaybackState#ACTION_SKIP_TO_PREVIOUS}</li> + * <li> {@link PlaybackState#ACTION_REWIND}</li> + * <li> {@link PlaybackState#ACTION_PLAY}</li> + * <li> {@link PlaybackState#ACTION_PAUSE}</li> + * <li> {@link PlaybackState#ACTION_STOP}</li> + * <li> {@link PlaybackState#ACTION_FAST_FORWARD}</li> + * <li> {@link PlaybackState#ACTION_SKIP_TO_NEXT}</li> + * <li> {@link PlaybackState#ACTION_SEEK_TO}</li> + * <li> {@link PlaybackState#ACTION_SET_RATING}</li> + * </ul> + * + * @param actions The set of actions allowed. + * @return this + */ + public Builder setActions(long actions) { + mActions = actions; + return this; + } + + /** + * Set the current buffer position in ms. This is the farthest playback + * point that can be reached from the current position using only + * buffered content. + * + * @param bufferPosition The position in ms that playback is buffered + * to. + * @return this + */ + public Builder setBufferPosition(long bufferPosition) { + mBufferPosition = bufferPosition; + return this; + } + + /** + * Set a user readable error message. This should be set when the state + * is {@link PlaybackState#STATE_ERROR}. + * + * @param error The error message for display to the user. + * @return this + */ + public Builder setErrorMessage(CharSequence error) { + mErrorMessage = error; + return this; + } + + /** + * Build and return the PlaybackState instance with these values. + * + * @return A new state instance. + */ + public PlaybackState build() { + return new PlaybackState(mState, mPosition, mUpdateTime, mSpeed, mBufferPosition, + mActions, mErrorMessage); + } + } } diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index adfa1f2..2e7d331 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -49,6 +49,9 @@ import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.media.AudioManager; +import android.media.session.MediaController; +import android.media.session.MediaSession; +import android.media.session.MediaSessionLegacyHelper; import android.net.Uri; import android.os.Bundle; import android.os.Handler; @@ -224,6 +227,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private boolean mClosingActionMenu; private int mVolumeControlStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE; + private MediaController mMediaController; private AudioManager mAudioManager; private KeyguardManager mKeyguardManager; @@ -1688,15 +1692,42 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { switch (keyCode) { case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_DOWN: + case KeyEvent.KEYCODE_VOLUME_DOWN: { + int direction = keyCode == KeyEvent.KEYCODE_VOLUME_UP ? AudioManager.ADJUST_RAISE + : AudioManager.ADJUST_LOWER; + // If we have a session send it the volume command, otherwise + // use the suggested stream. + if (mMediaController != null) { + mMediaController.adjustVolumeBy(direction, AudioManager.FLAG_SHOW_UI); + } else { + MediaSessionLegacyHelper.getHelper(getContext()).sendAdjustVolumeBy( + mVolumeControlStreamType, direction, AudioManager.FLAG_SHOW_UI); + } + return true; + } case KeyEvent.KEYCODE_VOLUME_MUTE: { - // Similar code is in PhoneFallbackEventHandler in case the window - // doesn't have one of these. In this case, we execute it here and - // eat the event instead, because we have mVolumeControlStreamType - // and they don't. getAudioManager().handleKeyDown(event, mVolumeControlStreamType); return true; } + // These are all the recognized media key codes in + // KeyEvent.isMediaKey() + case KeyEvent.KEYCODE_MEDIA_PLAY: + case KeyEvent.KEYCODE_MEDIA_PAUSE: + case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: + case KeyEvent.KEYCODE_MUTE: + case KeyEvent.KEYCODE_HEADSETHOOK: + case KeyEvent.KEYCODE_MEDIA_STOP: + case KeyEvent.KEYCODE_MEDIA_NEXT: + case KeyEvent.KEYCODE_MEDIA_PREVIOUS: + case KeyEvent.KEYCODE_MEDIA_REWIND: + case KeyEvent.KEYCODE_MEDIA_RECORD: + case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: { + if (mMediaController != null) { + if (mMediaController.dispatchMediaButtonEvent(event)) { + return true; + } + } + } case KeyEvent.KEYCODE_MENU: { onKeyDownPanel((featureId < 0) ? FEATURE_OPTIONS_PANEL : featureId, event); @@ -1750,7 +1781,19 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { switch (keyCode) { case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_DOWN: + case KeyEvent.KEYCODE_VOLUME_DOWN: { + // If we have a session send it the volume command, otherwise + // use the suggested stream. + if (mMediaController != null) { + mMediaController.adjustVolumeBy(0, AudioManager.FLAG_PLAY_SOUND + | AudioManager.FLAG_VIBRATE); + } else { + MediaSessionLegacyHelper.getHelper(getContext()).sendAdjustVolumeBy( + mVolumeControlStreamType, 0, + AudioManager.FLAG_PLAY_SOUND | AudioManager.FLAG_VIBRATE); + } + return true; + } case KeyEvent.KEYCODE_VOLUME_MUTE: { // Similar code is in PhoneFallbackEventHandler in case the window // doesn't have one of these. In this case, we execute it here and @@ -1759,6 +1802,25 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { getAudioManager().handleKeyUp(event, mVolumeControlStreamType); return true; } + // These are all the recognized media key codes in + // KeyEvent.isMediaKey() + case KeyEvent.KEYCODE_MEDIA_PLAY: + case KeyEvent.KEYCODE_MEDIA_PAUSE: + case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: + case KeyEvent.KEYCODE_MUTE: + case KeyEvent.KEYCODE_HEADSETHOOK: + case KeyEvent.KEYCODE_MEDIA_STOP: + case KeyEvent.KEYCODE_MEDIA_NEXT: + case KeyEvent.KEYCODE_MEDIA_PREVIOUS: + case KeyEvent.KEYCODE_MEDIA_REWIND: + case KeyEvent.KEYCODE_MEDIA_RECORD: + case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: { + if (mMediaController != null) { + if (mMediaController.dispatchMediaButtonEvent(event)) { + return true; + } + } + } case KeyEvent.KEYCODE_MENU: { onKeyUpPanel(featureId < 0 ? FEATURE_OPTIONS_PANEL : featureId, @@ -3773,6 +3835,16 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { return mVolumeControlStreamType; } + @Override + public void setMediaController(MediaController controller) { + mMediaController = controller; + } + + @Override + public MediaController getMediaController() { + return mMediaController; + } + private boolean isTranslucent() { TypedArray a = getWindowStyle(); return a.getBoolean(a.getResourceId( diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index 341c7a9..01a21f4 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -505,16 +505,19 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { || state.getState() == PlaybackState.STATE_FAST_FORWARDING || state.getState() == PlaybackState.STATE_REWINDING) { long updateTime = state.getLastPositionUpdateTime(); + long currentTime = SystemClock.elapsedRealtime(); if (updateTime > 0) { - long position = (long) (state.getPlaybackRate() - * (SystemClock.elapsedRealtime() - updateTime)) + state.getPosition(); + long position = (long) (state.getPlaybackSpeed() + * (currentTime - updateTime)) + state.getPosition(); if (duration >= 0 && position > duration) { position = duration; } else if (position < 0) { position = 0; } - result = new PlaybackState(state); - result.setState(state.getState(), position, state.getPlaybackRate()); + PlaybackState.Builder builder = new PlaybackState.Builder(state); + builder.setState(state.getState(), position, state.getPlaybackSpeed(), + currentTime); + result = builder.build(); } } } diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerController.java b/tests/OneMedia/src/com/android/onemedia/PlayerController.java index 802f473..9cbb455 100644 --- a/tests/OneMedia/src/com/android/onemedia/PlayerController.java +++ b/tests/OneMedia/src/com/android/onemedia/PlayerController.java @@ -18,12 +18,14 @@ package com.android.onemedia; import android.media.MediaMetadata; import android.media.session.MediaController; +import android.media.session.MediaSession; import android.media.session.MediaSessionManager; import android.media.session.PlaybackState; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; +import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -43,7 +45,7 @@ public class PlayerController { protected MediaController.TransportControls mTransportControls; private final Intent mServiceIntent; - private Context mContext; + private Activity mContext; private Listener mListener; private SessionCallback mControllerCb; private MediaSessionManager mManager; @@ -51,7 +53,7 @@ public class PlayerController { private boolean mResumed; - public PlayerController(Context context, Intent serviceIntent) { + public PlayerController(Activity context, Intent serviceIntent) { mContext = context; if (serviceIntent == null) { mServiceIntent = new Intent(mContext, PlayerService.class); @@ -140,6 +142,7 @@ public class PlayerController { mBinder = null; mController = null; mTransportControls = null; + mContext.setMediaController(null); Log.d(TAG, "Disconnected from PlayerService"); if (mListener != null) { @@ -151,12 +154,15 @@ public class PlayerController { public void onServiceConnected(ComponentName name, IBinder service) { mBinder = IPlayerService.Stub.asInterface(service); Log.d(TAG, "service is " + service + " binder is " + mBinder); + MediaSession.Token token; try { - mController = MediaController.fromToken(mBinder.getSessionToken()); + token = mBinder.getSessionToken(); } catch (RemoteException e) { Log.e(TAG, "Error getting session", e); return; } + mController = MediaController.fromToken(token); + mContext.setMediaController(mController); mController.addCallback(mControllerCb, mHandler); mTransportControls = mController.getTransportControls(); Log.d(TAG, "Ready to use PlayerService"); diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java index 7c0eabe..78353b2 100644 --- a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java +++ b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java @@ -28,6 +28,7 @@ import android.media.session.PlaybackState; import android.os.Bundle; import android.support.media.protocols.MediaPlayerProtocol; import android.support.media.protocols.MediaPlayerProtocol.MediaStatus; +import android.os.SystemClock; import android.util.Log; import android.view.KeyEvent; @@ -59,9 +60,9 @@ public class PlayerSession { mRenderer = new LocalRenderer(context, null); mCallback = new SessionCb(); mRenderListener = new RenderListener(); - mPlaybackState = new PlaybackState(); - mPlaybackState.setActions(PlaybackState.ACTION_PAUSE - | PlaybackState.ACTION_PLAY); + PlaybackState.Builder psBob = new PlaybackState.Builder(); + psBob.setActions(PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_PLAY); + mPlaybackState = psBob.build(); mRenderer.registerListener(mRenderListener); } @@ -131,7 +132,10 @@ public class PlayerSession { private void updateState(int newState) { float rate = newState == PlaybackState.STATE_PLAYING ? 1 : 0; long position = mRenderer == null ? -1 : mRenderer.getSeekPosition(); - mPlaybackState.setState(newState, position, rate); + PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState); + bob.setState(newState, position, rate, SystemClock.elapsedRealtime()); + bob.setErrorMessage(null); + mPlaybackState = bob.build(); mSession.setPlaybackState(mPlaybackState); } @@ -144,10 +148,12 @@ public class PlayerSession { @Override public void onError(int type, int extra, Bundle extras, Throwable error) { Log.d(TAG, "Sending onError with type " + type + " and extra " + extra); - mPlaybackState.setState(PlaybackState.STATE_ERROR, -1, 0); + PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState); + bob.setState(PlaybackState.STATE_ERROR, -1, 0, 0); if (error != null) { - mPlaybackState.setErrorMessage(error.getLocalizedMessage()); + bob.setErrorMessage(error.getLocalizedMessage()); } + mPlaybackState = bob.build(); mSession.setPlaybackState(mPlaybackState); if (mListener != null) { mListener.onPlayStateChanged(mPlaybackState); @@ -156,36 +162,41 @@ public class PlayerSession { @Override public void onStateChanged(int newState) { - if (newState != Renderer.STATE_ERROR) { - mPlaybackState.setErrorMessage(null); - } long position = -1; if (mRenderer != null) { position = mRenderer.getSeekPosition(); } + int pbState; + float rate = 0; + String errorMsg = null; switch (newState) { case Renderer.STATE_ENDED: case Renderer.STATE_STOPPED: - mPlaybackState.setState(PlaybackState.STATE_STOPPED, position, 0); + pbState = PlaybackState.STATE_STOPPED; break; case Renderer.STATE_INIT: case Renderer.STATE_PREPARING: - mPlaybackState.setState(PlaybackState.STATE_BUFFERING, position, 0); + pbState = PlaybackState.STATE_BUFFERING; break; case Renderer.STATE_ERROR: - mPlaybackState.setState(PlaybackState.STATE_ERROR, position, 0); + pbState = PlaybackState.STATE_ERROR; break; case Renderer.STATE_PAUSED: - mPlaybackState.setState(PlaybackState.STATE_PAUSED, position, 0); + pbState = PlaybackState.STATE_PAUSED; break; case Renderer.STATE_PLAYING: - mPlaybackState.setState(PlaybackState.STATE_PLAYING, position, 1); + pbState = PlaybackState.STATE_PLAYING; + rate = 1; break; default: - mPlaybackState.setState(PlaybackState.STATE_ERROR, position, 0); - mPlaybackState.setErrorMessage("unkown state"); + pbState = PlaybackState.STATE_ERROR; + errorMsg = "unknown state"; break; } + PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState); + bob.setState(pbState, position, rate, SystemClock.elapsedRealtime()); + bob.setErrorMessage(errorMsg); + mPlaybackState = bob.build(); mSession.setPlaybackState(mPlaybackState); if (mListener != null) { mListener.onPlayStateChanged(mPlaybackState); @@ -200,7 +211,10 @@ public class PlayerSession { public void onFocusLost() { Log.d(TAG, "Focus lost, changing state to " + Renderer.STATE_PAUSED); long position = mRenderer == null ? -1 : mRenderer.getSeekPosition(); - mPlaybackState.setState(PlaybackState.STATE_PAUSED, position, 0); + PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState); + bob.setState(PlaybackState.STATE_PAUSED, position, 0, SystemClock.elapsedRealtime()); + bob.setErrorMessage(null); + mPlaybackState = bob.build(); mSession.setPlaybackState(mPlaybackState); if (mListener != null) { mListener.onPlayStateChanged(mPlaybackState); diff --git a/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java b/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java index 2e1478b..5845e48 100644 --- a/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java +++ b/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java @@ -29,6 +29,9 @@ import android.os.Process; import android.support.media.protocols.MediaPlayerProtocol; import android.support.media.protocols.MediaPlayerProtocol.MediaInfo; import android.support.media.protocols.MediaPlayerProtocol.MediaStatus; +import android.os.Looper; +import android.os.ResultReceiver; +import android.os.SystemClock; import android.util.Log; import com.android.onemedia.playback.LocalRenderer; @@ -60,9 +63,9 @@ public class OneMediaRouteProvider extends MediaRouteService { mHandler = new Handler(); mRenderer = new LocalRenderer(this, null); mRenderListener = new RenderListener(); - mPlaybackState = new PlaybackState(); - mPlaybackState.setActions(PlaybackState.ACTION_PAUSE - | PlaybackState.ACTION_PLAY); + PlaybackState.Builder bob = new PlaybackState.Builder(); + bob.setActions(PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_PLAY); + mPlaybackState = bob.build(); mRenderer.registerListener(mRenderListener); } @@ -178,36 +181,41 @@ public class OneMediaRouteProvider extends MediaRouteService { @Override public void onStateChanged(int newState) { - if (newState != Renderer.STATE_ERROR) { - mPlaybackState.setErrorMessage(null); - } long position = -1; if (mRenderer != null) { position = mRenderer.getSeekPosition(); } + int pbState; + float rate = 0; + String errorMsg = null; switch (newState) { case Renderer.STATE_ENDED: case Renderer.STATE_STOPPED: - mPlaybackState.setState(PlaybackState.STATE_STOPPED, position, 0); + pbState = PlaybackState.STATE_STOPPED; break; case Renderer.STATE_INIT: case Renderer.STATE_PREPARING: - mPlaybackState.setState(PlaybackState.STATE_BUFFERING, position, 0); + pbState = PlaybackState.STATE_BUFFERING; break; case Renderer.STATE_ERROR: - mPlaybackState.setState(PlaybackState.STATE_ERROR, position, 0); + pbState = PlaybackState.STATE_ERROR; break; case Renderer.STATE_PAUSED: - mPlaybackState.setState(PlaybackState.STATE_PAUSED, position, 0); + pbState = PlaybackState.STATE_PAUSED; break; case Renderer.STATE_PLAYING: - mPlaybackState.setState(PlaybackState.STATE_PLAYING, position, 1); + pbState = PlaybackState.STATE_PLAYING; + rate = 1; break; default: - mPlaybackState.setState(PlaybackState.STATE_ERROR, position, 0); - mPlaybackState.setErrorMessage("unkown state"); + pbState = PlaybackState.STATE_ERROR; + errorMsg = "unknown state"; break; } + PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState); + bob.setState(pbState, position, rate, SystemClock.elapsedRealtime()); + bob.setErrorMessage(errorMsg); + mPlaybackState = bob.build(); sendStatusUpdate(mPlaybackState.getState()); } @@ -218,8 +226,9 @@ public class OneMediaRouteProvider extends MediaRouteService { @Override public void onFocusLost() { - Log.d(TAG, "Focus lost, changing state to " + Renderer.STATE_PAUSED); - mPlaybackState.setState(PlaybackState.STATE_PAUSED, mRenderer.getSeekPosition(), 0); + Log.d(TAG, "Focus lost, pausing"); + // Don't update state here, we'll get a separate call to + // onStateChanged when it pauses mRenderer.onPause(); } |