Merge "MediaSession2: Replace PlaybackState2" into pi-dev

gugelfrei
Hyundo Moon 6 years ago committed by Android (Google) Code Review
commit 9d3824e06b

@ -31,15 +31,19 @@ import com.android.media.IMediaSession2;
// TODO(jaewan): (Post P) Handle when the playlist becomes too huge.
// Note that ParcelledSliceList isn't a good idea for the purpose. (see: b/37493677)
oneway interface IMediaController2 {
void onPlaybackStateChanged(in Bundle state);
void onPlayerStateChanged(int state);
void onPositionChanged(long eventTimeMs, long positionMs);
void onPlaybackSpeedChanged(float speed);
void onBufferedPositionChanged(long bufferedPositionMs);
void onPlaylistChanged(in List<Bundle> playlist, in Bundle metadata);
void onPlaylistMetadataChanged(in Bundle metadata);
void onPlaylistParamsChanged(in Bundle params);
void onPlaybackInfoChanged(in Bundle playbackInfo);
void onConnected(IMediaSession2 sessionBinder, in Bundle commandGroup, in Bundle playbackState,
in Bundle playbackInfo, in Bundle params, in List<Bundle> playlist,
in PendingIntent sessionActivity);
void onConnected(IMediaSession2 sessionBinder, in Bundle commandGroup,
int playerState, long positionEventTimeMs, long positionMs, float playbackSpeed,
long bufferedPositionMs, in Bundle playbackInfo, in Bundle params,
in List<Bundle> playlist, in PendingIntent sessionActivity);
void onDisconnected();
void onCustomLayoutChanged(in List<Bundle> commandButtonlist);

@ -16,7 +16,18 @@
package com.android.media;
import static android.media.MediaSession2.*;
import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_SET_VOLUME;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_ADD_ITEM;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_REMOVE_ITEM;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_REPLACE_ITEM;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_SET_LIST;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_SET_LIST_METADATA;
import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_MEDIA_ID;
import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_SEARCH;
import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_URI;
import static android.media.MediaSession2.COMMAND_CODE_PREPARE_FROM_MEDIA_ID;
import static android.media.MediaSession2.COMMAND_CODE_PREPARE_FROM_SEARCH;
import static android.media.MediaSession2.COMMAND_CODE_PREPARE_FROM_URI;
import android.app.PendingIntent;
import android.content.ComponentName;
@ -35,7 +46,6 @@ import android.media.MediaSession2.CommandButton;
import android.media.MediaSession2.CommandGroup;
import android.media.MediaSession2.PlaylistParams;
import android.media.MediaSessionService2;
import android.media.PlaybackState2;
import android.media.Rating2;
import android.media.SessionToken2;
import android.media.update.MediaController2Provider;
@ -73,14 +83,22 @@ public class MediaController2Impl implements MediaController2Provider {
@GuardedBy("mLock")
private boolean mIsReleased;
@GuardedBy("mLock")
private PlaybackState2 mPlaybackState;
@GuardedBy("mLock")
private List<MediaItem2> mPlaylist;
@GuardedBy("mLock")
private MediaMetadata2 mPlaylistMetadata;
@GuardedBy("mLock")
private PlaylistParams mPlaylistParams;
@GuardedBy("mLock")
private int mPlayerState;
@GuardedBy("mLock")
private long mPositionEventTimeMs;
@GuardedBy("mLock")
private long mPositionMs;
@GuardedBy("mLock")
private float mPlaybackSpeed;
@GuardedBy("mLock")
private long mBufferedPositionMs;
@GuardedBy("mLock")
private PlaybackInfo mPlaybackInfo;
@GuardedBy("mLock")
private PendingIntent mSessionActivity;
@ -613,13 +631,6 @@ public class MediaController2Impl implements MediaController2Provider {
*/
}
@Override
public PlaybackState2 getPlaybackState_impl() {
synchronized (mLock) {
return mPlaybackState;
}
}
@Override
public void addPlaylistItem_impl(int index, MediaItem2 item) {
if (index < 0) {
@ -703,26 +714,32 @@ public class MediaController2Impl implements MediaController2Provider {
@Override
public int getPlayerState_impl() {
// TODO(jaewan): Implement
return 0;
synchronized (mLock) {
return mPlayerState;
}
}
@Override
public long getPosition_impl() {
// TODO(jaewan): Implement
return 0;
synchronized (mLock) {
long timeDiff = System.currentTimeMillis() - mPositionEventTimeMs;
long expectedPosition = mPositionMs + (long) (mPlaybackSpeed * timeDiff);
return Math.max(0, expectedPosition);
}
}
@Override
public float getPlaybackSpeed_impl() {
// TODO(jaewan): Implement
return 0;
synchronized (mLock) {
return mPlaybackSpeed;
}
}
@Override
public long getBufferedPosition_impl() {
// TODO(jaewan): Implement
return 0;
synchronized (mLock) {
return mBufferedPositionMs;
}
}
@Override
@ -731,15 +748,52 @@ public class MediaController2Impl implements MediaController2Provider {
return null;
}
void pushPlaybackStateChanges(final PlaybackState2 state) {
void pushPlayerStateChanges(final int state) {
synchronized (mLock) {
mPlayerState = state;
}
mCallbackExecutor.execute(() -> {
if (!mInstance.isConnected()) {
return;
}
mCallback.onPlayerStateChanged(mInstance, state);
});
}
void pushPositionChanges(final long eventTimeMs, final long positionMs) {
synchronized (mLock) {
mPositionEventTimeMs = eventTimeMs;
mPositionMs = positionMs;
}
mCallbackExecutor.execute(() -> {
if (!mInstance.isConnected()) {
return;
}
mCallback.onPositionChanged(mInstance, eventTimeMs, positionMs);
});
}
void pushPlaybackSpeedChanges(final float speed) {
synchronized (mLock) {
mPlaybackSpeed = speed;
}
mCallbackExecutor.execute(() -> {
if (!mInstance.isConnected()) {
return;
}
mCallback.onPlaybackSpeedChanged(mInstance, speed);
});
}
void pushBufferedPositionChanges(final long bufferedPositionMs) {
synchronized (mLock) {
mPlaybackState = state;
mBufferedPositionMs = bufferedPositionMs;
}
mCallbackExecutor.execute(() -> {
if (!mInstance.isConnected()) {
return;
}
mCallback.onPlaybackStateChanged(mInstance, state);
mCallback.onBufferedPositionChanged(mInstance, bufferedPositionMs);
});
}
@ -796,7 +850,13 @@ public class MediaController2Impl implements MediaController2Provider {
// Should be used without a lock to prevent potential deadlock.
void onConnectedNotLocked(IMediaSession2 sessionBinder,
final CommandGroup allowedCommands, final PlaybackState2 state, final PlaybackInfo info,
final CommandGroup allowedCommands,
final int playerState,
final long positionEventTimeMs,
final long positionMs,
final float playbackSpeed,
final long bufferedPositionMs,
final PlaybackInfo info,
final PlaylistParams params, final List<MediaItem2> playlist,
final PendingIntent sessionActivity) {
if (DEBUG) {
@ -821,7 +881,11 @@ public class MediaController2Impl implements MediaController2Provider {
return;
}
mAllowedCommands = allowedCommands;
mPlaybackState = state;
mPlayerState = playerState;
mPositionEventTimeMs = positionEventTimeMs;
mPositionMs = positionMs;
mPlaybackSpeed = playbackSpeed;
mBufferedPositionMs = bufferedPositionMs;
mPlaybackInfo = info;
mPlaylistParams = params;
mPlaylist = playlist;

@ -25,7 +25,6 @@ import android.media.MediaSession2.Command;
import android.media.MediaSession2.CommandButton;
import android.media.MediaSession2.CommandGroup;
import android.media.MediaSession2.PlaylistParams;
import android.media.PlaybackState2;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.text.TextUtils;
@ -69,7 +68,7 @@ public class MediaController2Stub extends IMediaController2.Stub {
}
@Override
public void onPlaybackStateChanged(Bundle state) throws RuntimeException {
public void onPlayerStateChanged(int state) {
final MediaController2Impl controller;
try {
controller = getController();
@ -77,8 +76,55 @@ public class MediaController2Stub extends IMediaController2.Stub {
Log.w(TAG, "Don't fail silently here. Highly likely a bug");
return;
}
controller.pushPlaybackStateChanges(
PlaybackState2.fromBundle(controller.getContext(), state));
controller.pushPlayerStateChanges(state);
}
@Override
public void onPositionChanged(long eventTimeMs, long positionMs) {
final MediaController2Impl controller;
try {
controller = getController();
} catch (IllegalStateException e) {
Log.w(TAG, "Don't fail silently here. Highly likely a bug");
return;
}
if (eventTimeMs < 0) {
Log.w(TAG, "onPositionChanged(): Ignoring negative eventTimeMs");
return;
}
if (positionMs < 0) {
Log.w(TAG, "onPositionChanged(): Ignoring negative positionMs");
return;
}
controller.pushPositionChanges(eventTimeMs, positionMs);
}
@Override
public void onPlaybackSpeedChanged(float speed) {
final MediaController2Impl controller;
try {
controller = getController();
} catch (IllegalStateException e) {
Log.w(TAG, "Don't fail silently here. Highly likely a bug");
return;
}
controller.pushPlaybackSpeedChanges(speed);
}
@Override
public void onBufferedPositionChanged(long bufferedPositionMs) {
final MediaController2Impl controller;
try {
controller = getController();
} catch (IllegalStateException e) {
Log.w(TAG, "Don't fail silently here. Highly likely a bug");
return;
}
if (bufferedPositionMs < 0) {
Log.w(TAG, "onBufferedPositionChanged(): Ignoring negative bufferedPositionMs");
return;
}
controller.pushBufferedPositionChanges(bufferedPositionMs);
}
@Override
@ -163,8 +209,9 @@ public class MediaController2Stub extends IMediaController2.Stub {
@Override
public void onConnected(IMediaSession2 sessionBinder, Bundle commandGroup,
Bundle playbackState, Bundle playbackInfo, Bundle playlistParams, List<Bundle>
itemBundleList, PendingIntent sessionActivity) {
int playerState, long positionEventTimeMs, long positionMs, float playbackSpeed,
long bufferedPositionMs, Bundle playbackInfo, Bundle playlistParams,
List<Bundle> itemBundleList, PendingIntent sessionActivity) {
final MediaController2Impl controller = mController.get();
if (controller == null) {
if (DEBUG) {
@ -185,7 +232,7 @@ public class MediaController2Stub extends IMediaController2.Stub {
}
controller.onConnectedNotLocked(sessionBinder,
CommandGroup.fromBundle(context, commandGroup),
PlaybackState2.fromBundle(context, playbackState),
playerState, positionEventTimeMs, positionMs, playbackSpeed, bufferedPositionMs,
PlaybackInfoImpl.fromBundle(context, playbackInfo),
PlaylistParams.fromBundle(context, playlistParams),
itemList, sessionActivity);

@ -52,7 +52,6 @@ import android.media.MediaSession2.PlaylistParams.RepeatMode;
import android.media.MediaSession2.PlaylistParams.ShuffleMode;
import android.media.MediaSession2.SessionCallback;
import android.media.MediaSessionService2;
import android.media.PlaybackState2;
import android.media.SessionToken2;
import android.media.VolumeProvider2;
import android.media.session.MediaSessionManager;
@ -248,11 +247,11 @@ public class MediaSession2Impl implements MediaSession2Provider {
oldAgent.unregisterPlaylistEventCallback(mPlaylistEventCallback);
}
}
// TODO(jaewan): Notify controllers about the change in the media player base (b/74370608)
// Note that notification will be done indirectly by telling player state,
// position, buffered position, etc.
mSessionStub.notifyPlaybackInfoChanged(info);
notifyPlaybackStateChangedNotLocked(mInstance.getPlaybackState());
if (oldPlayer != null) {
mSessionStub.notifyPlaybackInfoChanged(info);
notifyPlayerUpdatedNotLocked(oldPlayer);
}
}
private PlaybackInfo createPlaybackInfo(VolumeProvider2 volumeProvider, AudioAttributes attrs) {
@ -676,12 +675,6 @@ public class MediaSession2Impl implements MediaSession2Provider {
return;
}
mCallbacks.put(callback, executor);
// TODO: Uncomment or remove
/*
// TODO(jaewan): Double check if we need this.
final PlaybackState2 state = getInstance().getPlaybackState();
executor.execute(() -> callback.onPlaybackStateChanged(state));
*/
}
@Override
@ -693,25 +686,6 @@ public class MediaSession2Impl implements MediaSession2Provider {
mCallbacks.remove(callback);
}
@Override
public PlaybackState2 getPlaybackState_impl() {
ensureCallingThread();
// TODO: Uncomment or remove
/*
final MediaPlayerBase player = mPlayer;
if (player != null) {
// TODO(jaewan): Is it safe to be called on any thread?
// Otherwise MediaSession2 should cache the result from listener.
// TODO implement
//return player.getPlaybackState();
return null;
} else if (DEBUG) {
Log.d(TAG, "API calls after the close()", new IllegalStateException());
}
*/
return null;
}
@Override
public void notifyError_impl(int errorCode, Bundle extras) {
// TODO(jaewan): Implement
@ -761,9 +735,11 @@ public class MediaSession2Impl implements MediaSession2Provider {
mSessionStub.notifyPlaylistMetadataChangedNotLocked(metadata);
}
private void notifyPlaybackStateChangedNotLocked(final PlaybackState2 state) {
private void notifyPlayerUpdatedNotLocked(MediaPlayerBase oldPlayer) {
ArrayMap<PlayerEventCallback, Executor> callbacks = new ArrayMap<>();
MediaPlayerBase player;
synchronized (mLock) {
player = mPlayer;
callbacks.putAll(mCallbacks);
}
// Notify to callbacks added directly to this session
@ -774,7 +750,26 @@ public class MediaSession2Impl implements MediaSession2Provider {
//executor.execute(() -> callback.onPlaybackStateChanged(state));
}
// Notify to controllers as well.
mSessionStub.notifyPlaybackStateChangedNotLocked(state);
final int state = player.getPlayerState();
if (state != oldPlayer.getPlayerState()) {
mSessionStub.notifyPlayerStateChangedNotLocked(state);
}
final long currentTimeMs = System.currentTimeMillis();
final long position = player.getCurrentPosition();
if (position != oldPlayer.getCurrentPosition()) {
mSessionStub.notifyPositionChangedNotLocked(currentTimeMs, position);
}
final float speed = player.getPlaybackSpeed();
if (speed != oldPlayer.getPlaybackSpeed()) {
mSessionStub.notifyPlaybackSpeedChangedNotLocked(speed);
}
final long bufferedPosition = player.getBufferedPosition();
if (bufferedPosition != oldPlayer.getBufferedPosition()) {
mSessionStub.notifyBufferedPositionChangedNotLocked(bufferedPosition);
}
}
private void notifyErrorNotLocked(String mediaId, int what, int extra) {
@ -843,26 +838,64 @@ public class MediaSession2Impl implements MediaSession2Provider {
@Override
public void onCurrentDataSourceChanged(MediaPlayerBase mpb, DataSourceDesc dsd) {
super.onCurrentDataSourceChanged(mpb, dsd);
// TODO(jaewan): Handle this b/74370608
MediaSession2Impl session = getSession();
if (session == null) {
return;
}
session.getCallbackExecutor().execute(() -> {
// TODO (jaewan): Convert dsd to MediaItem (b/74506462)
// TODO (jaewan): Notify controllers through appropriate callback. (b/74505936)
session.getCallback().onCurrentMediaItemChanged(
session.getInstance(), mpb, null /* MediaItem */);
});
}
@Override
public void onMediaPrepared(MediaPlayerBase mpb, DataSourceDesc dsd) {
super.onMediaPrepared(mpb, dsd);
// TODO(jaewan): Handle this b/74370608
MediaSession2Impl session = getSession();
if (session == null) {
return;
}
session.getCallbackExecutor().execute(() -> {
// TODO (jaewan): Convert dsd to MediaItem (b/74506462)
// TODO (jaewan): Notify controllers through appropriate callback. (b/74505936)
session.getCallback().onMediaPrepared(
session.getInstance(), mpb, null /* MediaItem */);
});
}
@Override
public void onPlayerStateChanged(MediaPlayerBase mpb, int state) {
super.onPlayerStateChanged(mpb, state);
// TODO(jaewan): Handle this b/74370608
MediaSession2Impl session = getSession();
if (session == null) {
return;
}
session.getCallbackExecutor().execute(() -> {
session.getCallback().onPlayerStateChanged(session.getInstance(), mpb, state);
session.getSessionStub().notifyPlayerStateChangedNotLocked(state);
});
}
@Override
public void onBufferingStateChanged(MediaPlayerBase mpb, DataSourceDesc dsd, int state) {
super.onBufferingStateChanged(mpb, dsd, state);
// TODO(jaewan): Handle this b/74370608
MediaSession2Impl session = getSession();
if (session == null) {
return;
}
session.getCallbackExecutor().execute(() -> {
// TODO (jaewan): Convert dsd to MediaItem (b/74506462)
// TODO (jaewan): Notify controllers through appropriate callback. (b/74505936)
session.getCallback().onBufferingStateChanged(
session.getInstance(), mpb, null /* MediaItem */, state);
});
}
private MediaSession2Impl getSession() {
final MediaSession2Impl session = mSession.get();
if (session == null && DEBUG) {
Log.d(TAG, "Session is closed", new IllegalStateException());
}
return session;
}
}

@ -22,13 +22,13 @@ import android.media.MediaController2;
import android.media.MediaItem2;
import android.media.MediaLibraryService2.LibraryRoot;
import android.media.MediaMetadata2;
import android.media.MediaPlayerBase;
import android.media.MediaSession2;
import android.media.MediaSession2.Command;
import android.media.MediaSession2.CommandButton;
import android.media.MediaSession2.CommandGroup;
import android.media.MediaSession2.ControllerInfo;
import android.media.MediaSession2.PlaylistParams;
import android.media.PlaybackState2;
import android.media.Rating2;
import android.media.VolumeProvider2;
import android.net.Uri;
@ -259,9 +259,11 @@ public class MediaSession2Stub extends IMediaSession2.Stub {
// that events here are notified after the onConnected() because
// IMediaController2 is oneway (i.e. async call) and Stub will
// use thread poll for incoming calls.
// TODO(jaewan): Should we protect getting playback state?
final PlaybackState2 state = session.getInstance().getPlaybackState();
final Bundle playbackStateBundle = (state != null) ? state.toBundle() : null;
final int playerState = session.getInstance().getPlayerState();
final long positionEventTimeMs = System.currentTimeMillis();
final long positionMs = session.getInstance().getCurrentPosition();
final float playbackSpeed = session.getInstance().getPlaybackSpeed();
final long bufferedPositionMs = session.getInstance().getBufferedPosition();
final Bundle playbackInfoBundle = ((MediaController2Impl.PlaybackInfoImpl)
session.getPlaybackInfo().getProvider()).toBundle();
final PlaylistParams params = session.getInstance().getPlaylistParams();
@ -293,9 +295,10 @@ public class MediaSession2Stub extends IMediaSession2.Stub {
return;
}
try {
caller.onConnected(MediaSession2Stub.this,
allowedCommands.toBundle(), playbackStateBundle, playbackInfoBundle,
paramsBundle, playlistBundle, sessionActivity);
caller.onConnected(MediaSession2Stub.this, allowedCommands.toBundle(),
playerState, positionEventTimeMs, positionMs, playbackSpeed,
bufferedPositionMs, playbackInfoBundle, paramsBundle, playlistBundle,
sessionActivity);
} catch (RemoteException e) {
// Controller may be died prematurely.
// TODO(jaewan): Handle here.
@ -1082,7 +1085,7 @@ public class MediaSession2Stub extends IMediaSession2.Stub {
}
// Should be used without a lock to prevent potential deadlock.
public void notifyPlaybackStateChangedNotLocked(PlaybackState2 state) {
public void notifyPlayerStateChangedNotLocked(int state) {
final List<ControllerInfo> list = getControllers();
for (int i = 0; i < list.size(); i++) {
final IMediaController2 controllerBinder = getControllerBinderIfAble(list.get(i));
@ -1090,8 +1093,55 @@ public class MediaSession2Stub extends IMediaSession2.Stub {
return;
}
try {
final Bundle bundle = state != null ? state.toBundle() : null;
controllerBinder.onPlaybackStateChanged(bundle);
controllerBinder.onPlayerStateChanged(state);
} catch (RemoteException e) {
Log.w(TAG, "Controller is gone", e);
// TODO(jaewan): What to do when the controller is gone?
}
}
}
public void notifyPositionChangedNotLocked(long eventTimeMs, long positionMs) {
final List<ControllerInfo> list = getControllers();
for (int i = 0; i < list.size(); i++) {
final IMediaController2 controllerBinder = getControllerBinderIfAble(list.get(i));
if (controllerBinder == null) {
return;
}
try {
controllerBinder.onPositionChanged(eventTimeMs, positionMs);
} catch (RemoteException e) {
Log.w(TAG, "Controller is gone", e);
// TODO(jaewan): What to do when the controller is gone?
}
}
}
public void notifyPlaybackSpeedChangedNotLocked(float speed) {
final List<ControllerInfo> list = getControllers();
for (int i = 0; i < list.size(); i++) {
final IMediaController2 controllerBinder = getControllerBinderIfAble(list.get(i));
if (controllerBinder == null) {
return;
}
try {
controllerBinder.onPlaybackSpeedChanged(speed);
} catch (RemoteException e) {
Log.w(TAG, "Controller is gone", e);
// TODO(jaewan): What to do when the controller is gone?
}
}
}
public void notifyBufferedPositionChangedNotLocked(long bufferedPositionMs) {
final List<ControllerInfo> list = getControllers();
for (int i = 0; i < list.size(); i++) {
final IMediaController2 controllerBinder = getControllerBinderIfAble(list.get(i));
if (controllerBinder == null) {
return;
}
try {
controllerBinder.onBufferedPositionChanged(bufferedPositionMs);
} catch (RemoteException e) {
Log.w(TAG, "Controller is gone", e);
// TODO(jaewan): What to do when the controller is gone?

@ -27,10 +27,8 @@ import android.media.MediaPlayerBase.PlayerEventCallback;
import android.media.MediaSession2;
import android.media.MediaSessionService2;
import android.media.MediaSessionService2.MediaNotification;
import android.media.PlaybackState2;
import android.media.SessionToken2;
import android.media.SessionToken2.TokenType;
import android.media.session.PlaybackState;
import android.media.update.MediaSessionService2Provider;
import android.os.IBinder;
import android.support.annotation.GuardedBy;
@ -109,13 +107,13 @@ public class MediaSessionService2Impl implements MediaSessionService2Provider {
return null;
}
private void updateNotification(PlaybackState2 state) {
private void updateNotification(int playerState) {
MediaNotification mediaNotification = mInstance.onUpdateNotification();
if (mediaNotification == null) {
return;
}
switch((int) state.getState()) {
case PlaybackState.STATE_PLAYING:
switch(playerState) {
case MediaPlayerBase.PLAYER_STATE_PLAYING:
if (!mIsRunningForeground) {
mIsRunningForeground = true;
mInstance.startForegroundService(mStartSelfIntent);
@ -124,7 +122,8 @@ public class MediaSessionService2Impl implements MediaSessionService2Provider {
return;
}
break;
case PlaybackState.STATE_STOPPED:
case MediaPlayerBase.PLAYER_STATE_IDLE:
case MediaPlayerBase.PLAYER_STATE_ERROR:
if (mIsRunningForeground) {
mIsRunningForeground = false;
mInstance.stopForeground(true);
@ -142,15 +141,6 @@ public class MediaSessionService2Impl implements MediaSessionService2Provider {
// TODO: Implement this
return;
}
// TODO: Uncomment or remove
//public void onPlaybackStateChanged(PlaybackState2 state) {
// if (state == null) {
// Log.w(TAG, "Ignoring null playback state");
// return;
// }
// MediaSession2Impl impl = (MediaSession2Impl) mSession.getProvider();
// updateNotification(impl.getInstance().getPlaybackState());
//}
}
public static class MediaNotificationImpl implements MediaNotificationProvider {

@ -1,132 +0,0 @@
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.media;
import android.content.Context;
import android.media.PlaybackState2;
import android.media.update.PlaybackState2Provider;
import android.os.Bundle;
public final class PlaybackState2Impl implements PlaybackState2Provider {
/**
* Keys used for converting a PlaybackState2 to a bundle object and vice versa.
*/
private static final String KEY_STATE = "android.media.playbackstate2.state";
private static final String KEY_POSITION = "android.media.playbackstate2.position";
private static final String KEY_BUFFERED_POSITION =
"android.media.playbackstate2.buffered_position";
private static final String KEY_SPEED = "android.media.playbackstate2.speed";
private static final String KEY_UPDATE_TIME = "android.media.playbackstate2.update_time";
private static final String KEY_ACTIVE_ITEM_ID = "android.media.playbackstate2.active_item_id";
private final Context mContext;
private final PlaybackState2 mInstance;
private final int mState;
private final long mPosition;
private final long mUpdateTime;
private final float mSpeed;
private final long mBufferedPosition;
private final long mActiveItemId;
public PlaybackState2Impl(Context context, PlaybackState2 instance, int state, long position,
long updateTime, float speed, long bufferedPosition, long activeItemId) {
mContext = context;
mInstance = instance;
mState = state;
mPosition = position;
mSpeed = speed;
mUpdateTime = updateTime;
mBufferedPosition = bufferedPosition;
mActiveItemId = activeItemId;
}
@Override
public String toString_impl() {
StringBuilder bob = new StringBuilder("PlaybackState {");
bob.append("state=").append(mState);
bob.append(", position=").append(mPosition);
bob.append(", buffered position=").append(mBufferedPosition);
bob.append(", speed=").append(mSpeed);
bob.append(", updated=").append(mUpdateTime);
bob.append(", active item id=").append(mActiveItemId);
bob.append("}");
return bob.toString();
}
@Override
public int getState_impl() {
return mState;
}
@Override
public long getPosition_impl() {
return mPosition;
}
@Override
public long getBufferedPosition_impl() {
return mBufferedPosition;
}
@Override
public float getPlaybackSpeed_impl() {
return mSpeed;
}
@Override
public long getLastPositionUpdateTime_impl() {
return mUpdateTime;
}
@Override
public long getCurrentPlaylistItemIndex_impl() {
return mActiveItemId;
}
@Override
public Bundle toBundle_impl() {
Bundle bundle = new Bundle();
bundle.putInt(KEY_STATE, mState);
bundle.putLong(KEY_POSITION, mPosition);
bundle.putLong(KEY_UPDATE_TIME, mUpdateTime);
bundle.putFloat(KEY_SPEED, mSpeed);
bundle.putLong(KEY_BUFFERED_POSITION, mBufferedPosition);
bundle.putLong(KEY_ACTIVE_ITEM_ID, mActiveItemId);
return bundle;
}
public static PlaybackState2 fromBundle(Context context, Bundle bundle) {
if (bundle == null) {
return null;
}
if (!bundle.containsKey(KEY_STATE)
|| !bundle.containsKey(KEY_POSITION)
|| !bundle.containsKey(KEY_UPDATE_TIME)
|| !bundle.containsKey(KEY_SPEED)
|| !bundle.containsKey(KEY_BUFFERED_POSITION)
|| !bundle.containsKey(KEY_ACTIVE_ITEM_ID)) {
return null;
}
return new PlaybackState2(context,
bundle.getInt(KEY_STATE),
bundle.getLong(KEY_POSITION),
bundle.getLong(KEY_UPDATE_TIME),
bundle.getFloat(KEY_SPEED),
bundle.getLong(KEY_BUFFERED_POSITION),
bundle.getLong(KEY_ACTIVE_ITEM_ID));
}
}

@ -39,7 +39,6 @@ import android.media.MediaSession2.PlaylistParams;
import android.media.MediaSession2.SessionCallback;
import android.media.MediaSessionService2;
import android.media.MediaSessionService2.MediaNotification;
import android.media.PlaybackState2;
import android.media.Rating2;
import android.media.SessionToken2;
import android.media.VolumeProvider2;
@ -56,7 +55,6 @@ import android.media.update.MediaSession2Provider.CommandButtonProvider.BuilderP
import android.media.update.MediaSession2Provider.PlaylistParamsProvider;
import android.media.update.MediaSessionService2Provider;
import android.media.update.MediaSessionService2Provider.MediaNotificationProvider;
import android.media.update.PlaybackState2Provider;
import android.media.update.SessionToken2Provider;
import android.media.update.StaticProvider;
import android.media.update.VideoView2Provider;
@ -80,7 +78,6 @@ import com.android.media.MediaPlaylistAgentImpl;
import com.android.media.MediaSession2Impl;
import com.android.media.MediaSession2Impl.PlaylistParamsImpl;
import com.android.media.MediaSessionService2Impl;
import com.android.media.PlaybackState2Impl;
import com.android.media.Rating2Impl;
import com.android.media.SessionToken2Impl;
import com.android.media.VolumeProvider2Impl;
@ -290,19 +287,6 @@ public class ApiFactory implements StaticProvider {
return Rating2Impl.newPercentageRating(context, percent);
}
@Override
public PlaybackState2Provider createPlaybackState2(Context context, PlaybackState2 instance,
int state, long position, long updateTime, float speed, long bufferedPosition,
long activeItemId) {
return new PlaybackState2Impl(context, instance, state, position, updateTime, speed,
bufferedPosition, activeItemId);
}
@Override
public PlaybackState2 fromBundle_PlaybackState2(Context context, Bundle bundle) {
return PlaybackState2Impl.fromBundle(context, bundle);
}
@Override
public MediaPlaylistAgentProvider createMediaPlaylistAgent(Context context,
MediaPlaylistAgent instance) {

Loading…
Cancel
Save