Loading packages/MediaComponents/src/com/android/media/IMediaSession2.aidl +5 −3 Original line number Diff line number Diff line Loading @@ -28,12 +28,12 @@ import com.android.media.IMediaSession2Callback; * Keep this interface oneway. Otherwise a malicious app may implement fake version of this, * and holds calls from session to make session owner(s) frozen. */ // 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 IMediaSession2 { // TODO(jaewan): add onCommand() to send private command // TODO(jaewan): Due to the nature of oneway calls, APIs can be called in out of order // Add id for individual calls to address this. // TODO(jaewan): We may consider to add another binder just for the connection // TODO(jaewan): (Post P) We may consider to add another binder just for the connection // not to expose other methods to the controller whose connection wasn't accepted. // But this would be enough for now because it's the same as existing // MediaBrowser and MediaBrowserService. Loading @@ -59,6 +59,8 @@ oneway interface IMediaSession2 { void playFromMediaId(IMediaSession2Callback caller, String mediaId, in Bundle extras); void setRating(IMediaSession2Callback caller, String mediaId, in Bundle rating); void setPlaylist(IMediaSession2Callback caller, in List<Bundle> playlist, in Bundle metadata); ////////////////////////////////////////////////////////////////////////////////////////////// // library service specific ////////////////////////////////////////////////////////////////////////////////////////////// Loading packages/MediaComponents/src/com/android/media/IMediaSession2Callback.aidl +3 −2 Original line number Diff line number Diff line Loading @@ -28,13 +28,14 @@ import com.android.media.IMediaSession2; * Keep this interface oneway. Otherwise a malicious app may implement fake version of this, * and holds calls from session to make session owner(s) frozen. */ // 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 IMediaSession2Callback { void onPlaybackStateChanged(in Bundle state); void onPlaylistChanged(in List<Bundle> playlist); void onPlaylistChanged(in List<Bundle> playlist, in Bundle metadata); void onPlaylistParamsChanged(in Bundle params); void onPlaybackInfoChanged(in Bundle playbackInfo); // TODO(jaewan): Handle when the playlist becomes too huge. void onConnected(IMediaSession2 sessionBinder, in Bundle commandGroup, in Bundle playbackState, in Bundle playbackInfo, in Bundle params, in List<Bundle> playlist, in PendingIntent sessionActivity); Loading packages/MediaComponents/src/com/android/media/MediaController2Impl.java +34 −7 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.media.MediaController2; import android.media.MediaController2.ControllerCallback; import android.media.MediaController2.PlaybackInfo; import android.media.MediaItem2; import android.media.MediaMetadata2; import android.media.MediaSession2; import android.media.MediaSession2.Command; import android.media.MediaSession2.CommandButton; Loading Loading @@ -76,6 +77,8 @@ public class MediaController2Impl implements MediaController2Provider { @GuardedBy("mLock") private List<MediaItem2> mPlaylist; @GuardedBy("mLock") private MediaMetadata2 mPlaylistMetadata; @GuardedBy("mLock") private PlaylistParams mPlaylistParams; @GuardedBy("mLock") private PlaybackInfo mPlaybackInfo; Loading Loading @@ -525,6 +528,28 @@ public class MediaController2Impl implements MediaController2Provider { } } @Override public void setPlaylist_impl(List<MediaItem2> list, MediaMetadata2 metadata) { if (list == null) { throw new IllegalArgumentException("list shouldn't be null"); } final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PLAYLIST_SET_LIST); if (binder != null) { List<Bundle> bundleList = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { bundleList.add(list.get(i).toBundle()); } Bundle metadataBundle = (metadata == null) ? null : metadata.toBundle(); try { binder.setPlaylist(mSessionCallbackStub, bundleList, metadataBundle); } catch (RemoteException e) { Log.w(TAG, "Cannot connect to the service or the session is gone", e); } } else { Log.w(TAG, "Session isn't active", new IllegalStateException()); } } @Override public void prepare_impl() { sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_PREPARE); Loading Loading @@ -692,17 +717,19 @@ public class MediaController2Impl implements MediaController2Provider { }); } void pushPlaylistChanges(final List<MediaItem2> playlist) { void pushPlaylistChanges(final List<MediaItem2> playlist, final MediaMetadata2 metadata) { synchronized (mLock) { mPlaylist = playlist; mPlaylistMetadata = metadata; } mCallbackExecutor.execute(() -> { if (!mInstance.isConnected()) { return; } mCallback.onPlaylistChanged(mInstance, playlist); // TODO(jaewan): Fix public API not to take playlistAgent. mCallback.onPlaylistChanged(mInstance, null, playlist, metadata); }); } } // Should be used without a lock to prevent potential deadlock. void onConnectedNotLocked(IMediaSession2 sessionBinder, Loading packages/MediaComponents/src/com/android/media/MediaMetadata2Impl.java +1 −1 Original line number Diff line number Diff line Loading @@ -228,7 +228,7 @@ public class MediaMetadata2Impl implements MediaMetadata2Provider { } public static MediaMetadata2 fromBundle(Context context, Bundle bundle) { return new MediaMetadata2Impl(context, bundle).getInstance(); return (bundle == null) ? null : new MediaMetadata2Impl(context, bundle).getInstance(); } public static final class BuilderImpl implements MediaMetadata2Provider.BuilderProvider { Loading packages/MediaComponents/src/com/android/media/MediaSession2CallbackStub.java +6 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.app.PendingIntent; import android.content.Context; import android.media.MediaController2; import android.media.MediaItem2; import android.media.MediaMetadata2; import android.media.MediaSession2.Command; import android.media.MediaSession2.CommandButton; import android.media.MediaSession2.CommandGroup; Loading Loading @@ -81,7 +82,7 @@ public class MediaSession2CallbackStub extends IMediaSession2Callback.Stub { } @Override public void onPlaylistChanged(List<Bundle> playlistBundle) throws RuntimeException { public void onPlaylistChanged(List<Bundle> playlistBundle, Bundle metadataBundle) { final MediaController2Impl controller; try { controller = getController(); Loading @@ -90,7 +91,7 @@ public class MediaSession2CallbackStub extends IMediaSession2Callback.Stub { return; } if (playlistBundle == null) { Log.w(TAG, "onPlaylistChanged(): Ignoring null playlist"); Log.w(TAG, "onPlaylistChanged(): Ignoring null playlist from " + controller); return; } List<MediaItem2> playlist = new ArrayList<>(); Loading @@ -102,7 +103,9 @@ public class MediaSession2CallbackStub extends IMediaSession2Callback.Stub { playlist.add(item); } } controller.pushPlaylistChanges(playlist); MediaMetadata2 metadata = MediaMetadata2.fromBundle(controller.getContext(), metadataBundle); controller.pushPlaylistChanges(playlist, metadata); } @Override Loading Loading
packages/MediaComponents/src/com/android/media/IMediaSession2.aidl +5 −3 Original line number Diff line number Diff line Loading @@ -28,12 +28,12 @@ import com.android.media.IMediaSession2Callback; * Keep this interface oneway. Otherwise a malicious app may implement fake version of this, * and holds calls from session to make session owner(s) frozen. */ // 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 IMediaSession2 { // TODO(jaewan): add onCommand() to send private command // TODO(jaewan): Due to the nature of oneway calls, APIs can be called in out of order // Add id for individual calls to address this. // TODO(jaewan): We may consider to add another binder just for the connection // TODO(jaewan): (Post P) We may consider to add another binder just for the connection // not to expose other methods to the controller whose connection wasn't accepted. // But this would be enough for now because it's the same as existing // MediaBrowser and MediaBrowserService. Loading @@ -59,6 +59,8 @@ oneway interface IMediaSession2 { void playFromMediaId(IMediaSession2Callback caller, String mediaId, in Bundle extras); void setRating(IMediaSession2Callback caller, String mediaId, in Bundle rating); void setPlaylist(IMediaSession2Callback caller, in List<Bundle> playlist, in Bundle metadata); ////////////////////////////////////////////////////////////////////////////////////////////// // library service specific ////////////////////////////////////////////////////////////////////////////////////////////// Loading
packages/MediaComponents/src/com/android/media/IMediaSession2Callback.aidl +3 −2 Original line number Diff line number Diff line Loading @@ -28,13 +28,14 @@ import com.android.media.IMediaSession2; * Keep this interface oneway. Otherwise a malicious app may implement fake version of this, * and holds calls from session to make session owner(s) frozen. */ // 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 IMediaSession2Callback { void onPlaybackStateChanged(in Bundle state); void onPlaylistChanged(in List<Bundle> playlist); void onPlaylistChanged(in List<Bundle> playlist, in Bundle metadata); void onPlaylistParamsChanged(in Bundle params); void onPlaybackInfoChanged(in Bundle playbackInfo); // TODO(jaewan): Handle when the playlist becomes too huge. void onConnected(IMediaSession2 sessionBinder, in Bundle commandGroup, in Bundle playbackState, in Bundle playbackInfo, in Bundle params, in List<Bundle> playlist, in PendingIntent sessionActivity); Loading
packages/MediaComponents/src/com/android/media/MediaController2Impl.java +34 −7 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.media.MediaController2; import android.media.MediaController2.ControllerCallback; import android.media.MediaController2.PlaybackInfo; import android.media.MediaItem2; import android.media.MediaMetadata2; import android.media.MediaSession2; import android.media.MediaSession2.Command; import android.media.MediaSession2.CommandButton; Loading Loading @@ -76,6 +77,8 @@ public class MediaController2Impl implements MediaController2Provider { @GuardedBy("mLock") private List<MediaItem2> mPlaylist; @GuardedBy("mLock") private MediaMetadata2 mPlaylistMetadata; @GuardedBy("mLock") private PlaylistParams mPlaylistParams; @GuardedBy("mLock") private PlaybackInfo mPlaybackInfo; Loading Loading @@ -525,6 +528,28 @@ public class MediaController2Impl implements MediaController2Provider { } } @Override public void setPlaylist_impl(List<MediaItem2> list, MediaMetadata2 metadata) { if (list == null) { throw new IllegalArgumentException("list shouldn't be null"); } final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PLAYLIST_SET_LIST); if (binder != null) { List<Bundle> bundleList = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { bundleList.add(list.get(i).toBundle()); } Bundle metadataBundle = (metadata == null) ? null : metadata.toBundle(); try { binder.setPlaylist(mSessionCallbackStub, bundleList, metadataBundle); } catch (RemoteException e) { Log.w(TAG, "Cannot connect to the service or the session is gone", e); } } else { Log.w(TAG, "Session isn't active", new IllegalStateException()); } } @Override public void prepare_impl() { sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_PREPARE); Loading Loading @@ -692,17 +717,19 @@ public class MediaController2Impl implements MediaController2Provider { }); } void pushPlaylistChanges(final List<MediaItem2> playlist) { void pushPlaylistChanges(final List<MediaItem2> playlist, final MediaMetadata2 metadata) { synchronized (mLock) { mPlaylist = playlist; mPlaylistMetadata = metadata; } mCallbackExecutor.execute(() -> { if (!mInstance.isConnected()) { return; } mCallback.onPlaylistChanged(mInstance, playlist); // TODO(jaewan): Fix public API not to take playlistAgent. mCallback.onPlaylistChanged(mInstance, null, playlist, metadata); }); } } // Should be used without a lock to prevent potential deadlock. void onConnectedNotLocked(IMediaSession2 sessionBinder, Loading
packages/MediaComponents/src/com/android/media/MediaMetadata2Impl.java +1 −1 Original line number Diff line number Diff line Loading @@ -228,7 +228,7 @@ public class MediaMetadata2Impl implements MediaMetadata2Provider { } public static MediaMetadata2 fromBundle(Context context, Bundle bundle) { return new MediaMetadata2Impl(context, bundle).getInstance(); return (bundle == null) ? null : new MediaMetadata2Impl(context, bundle).getInstance(); } public static final class BuilderImpl implements MediaMetadata2Provider.BuilderProvider { Loading
packages/MediaComponents/src/com/android/media/MediaSession2CallbackStub.java +6 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.app.PendingIntent; import android.content.Context; import android.media.MediaController2; import android.media.MediaItem2; import android.media.MediaMetadata2; import android.media.MediaSession2.Command; import android.media.MediaSession2.CommandButton; import android.media.MediaSession2.CommandGroup; Loading Loading @@ -81,7 +82,7 @@ public class MediaSession2CallbackStub extends IMediaSession2Callback.Stub { } @Override public void onPlaylistChanged(List<Bundle> playlistBundle) throws RuntimeException { public void onPlaylistChanged(List<Bundle> playlistBundle, Bundle metadataBundle) { final MediaController2Impl controller; try { controller = getController(); Loading @@ -90,7 +91,7 @@ public class MediaSession2CallbackStub extends IMediaSession2Callback.Stub { return; } if (playlistBundle == null) { Log.w(TAG, "onPlaylistChanged(): Ignoring null playlist"); Log.w(TAG, "onPlaylistChanged(): Ignoring null playlist from " + controller); return; } List<MediaItem2> playlist = new ArrayList<>(); Loading @@ -102,7 +103,9 @@ public class MediaSession2CallbackStub extends IMediaSession2Callback.Stub { playlist.add(item); } } controller.pushPlaylistChanges(playlist); MediaMetadata2 metadata = MediaMetadata2.fromBundle(controller.getContext(), metadataBundle); controller.pushPlaylistChanges(playlist, metadata); } @Override Loading