summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt24
-rw-r--r--core/java/android/app/Activity.java790
-rw-r--r--core/java/android/view/Window.java99
-rw-r--r--media/java/android/media/RemoteControlClient.java17
-rw-r--r--media/java/android/media/RemoteController.java2
-rw-r--r--media/java/android/media/session/PlaybackState.java303
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java84
-rw-r--r--services/core/java/com/android/server/media/MediaSessionRecord.java11
-rw-r--r--tests/OneMedia/src/com/android/onemedia/PlayerController.java12
-rw-r--r--tests/OneMedia/src/com/android/onemedia/PlayerSession.java48
-rw-r--r--tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java39
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 &lt;activity&gt;}
* 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 &lt;activity&gt;}
@@ -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} &mdash; or after {@link #onRestart} when
- * the activity had been stopped, but is now again being displayed to the
+ * Called after {@link #onCreate} &mdash; 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();
}