diff options
author | RoboErik <epastern@google.com> | 2014-07-14 13:40:43 -0700 |
---|---|---|
committer | RoboErik <epastern@google.com> | 2014-07-14 13:40:43 -0700 |
commit | c785a78fb483fe54012175c53d3758b2412de7b9 (patch) | |
tree | 381234db29ffa13f3f34972052d282978df86915 /media | |
parent | 550116576cce028d3c435f7c3ae9f6e3b92b5cf2 (diff) | |
download | frameworks_base-c785a78fb483fe54012175c53d3758b2412de7b9.zip frameworks_base-c785a78fb483fe54012175c53d3758b2412de7b9.tar.gz frameworks_base-c785a78fb483fe54012175c53d3758b2412de7b9.tar.bz2 |
Make PlaybackState immutable with a builder
bug:15862252
Change-Id: I51f2e466bd2c41bbe80d20aa9785126a7ac6ab3f
Diffstat (limited to 'media')
-rw-r--r-- | media/java/android/media/RemoteControlClient.java | 17 | ||||
-rw-r--r-- | media/java/android/media/RemoteController.java | 2 | ||||
-rw-r--r-- | media/java/android/media/session/PlaybackState.java | 303 |
3 files changed, 207 insertions, 115 deletions
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); + } + } } |