@@ -1100,20 +1100,23 @@ protected MediaSessionServiceLegacyStub getLegacyBrowserService() {
11001100 });
11011101 }
11021102
1103- /* package */ boolean onPlayRequested () {
1103+ /* package */ ListenableFuture < Boolean > onPlayRequested () {
11041104 if (Looper .myLooper () != Looper .getMainLooper ()) {
11051105 SettableFuture <Boolean > playRequested = SettableFuture .create ();
1106- mainHandler .post (() -> playRequested .set (onPlayRequested ()));
1107- try {
1108- return playRequested .get ();
1109- } catch (InterruptedException | ExecutionException e ) {
1110- throw new IllegalStateException (e );
1111- }
1106+ mainHandler .post (
1107+ () -> {
1108+ try {
1109+ playRequested .set (onPlayRequested ().get ());
1110+ } catch (ExecutionException | InterruptedException e ) {
1111+ playRequested .setException (new IllegalStateException (e ));
1112+ }
1113+ });
1114+ return playRequested ;
11121115 }
11131116 if (this .mediaSessionListener != null ) {
1114- return this .mediaSessionListener .onPlayRequested (instance );
1117+ return Futures . immediateFuture ( this .mediaSessionListener .onPlayRequested (instance ) );
11151118 }
1116- return true ;
1119+ return Futures . immediateFuture ( true ) ;
11171120 }
11181121
11191122 /**
@@ -1124,84 +1127,103 @@ protected MediaSessionServiceLegacyStub getLegacyBrowserService() {
11241127 *
11251128 * @param controller The controller requesting to play.
11261129 */
1127- /* package */ void handleMediaControllerPlayRequest (
1130+ /* package */ ListenableFuture < SessionResult > handleMediaControllerPlayRequest (
11281131 ControllerInfo controller , boolean callOnPlayerInteractionFinished ) {
1129- if (!onPlayRequested ()) {
1130- // Request denied, e.g. due to missing foreground service abilities.
1131- return ;
1132- }
1133- boolean hasCurrentMediaItem =
1134- playerWrapper .isCommandAvailable (Player .COMMAND_GET_CURRENT_MEDIA_ITEM )
1135- && playerWrapper .getCurrentMediaItem () != null ;
1136- boolean canAddMediaItems =
1137- playerWrapper .isCommandAvailable (COMMAND_SET_MEDIA_ITEM )
1138- || playerWrapper .isCommandAvailable (COMMAND_CHANGE_MEDIA_ITEMS );
1139- ControllerInfo controllerForRequest = resolveControllerInfoForCallback (controller );
1140- Player .Commands playCommand =
1141- new Player .Commands .Builder ().add (Player .COMMAND_PLAY_PAUSE ).build ();
1142- if (hasCurrentMediaItem || !canAddMediaItems ) {
1143- // No playback resumption needed or possible.
1144- if (!hasCurrentMediaItem ) {
1145- Log .w (
1146- TAG ,
1147- "Play requested without current MediaItem, but playback resumption prevented by"
1148- + " missing available commands" );
1149- }
1150- Util .handlePlayButtonAction (playerWrapper );
1151- if (callOnPlayerInteractionFinished ) {
1152- onPlayerInteractionFinishedOnHandler (controllerForRequest , playCommand );
1153- }
1154- } else {
1155- @ Nullable
1156- ListenableFuture <MediaItemsWithStartPosition > future =
1157- checkNotNull (
1158- callback .onPlaybackResumption (
1159- instance , controllerForRequest , /* isForPlayback= */ true ),
1160- "Callback.onPlaybackResumption must return a non-null future" );
1161- Futures .addCallback (
1162- future ,
1163- new FutureCallback <MediaItemsWithStartPosition >() {
1164- @ Override
1165- public void onSuccess (MediaItemsWithStartPosition mediaItemsWithStartPosition ) {
1166- callWithControllerForCurrentRequestSet (
1167- controllerForRequest ,
1168- () -> {
1169- MediaUtils .setMediaItemsWithStartIndexAndPosition (
1170- playerWrapper , mediaItemsWithStartPosition );
1171- Util .handlePlayButtonAction (playerWrapper );
1172- if (callOnPlayerInteractionFinished ) {
1173- onPlayerInteractionFinishedOnHandler (controllerForRequest , playCommand );
1174- }
1175- })
1176- .run ();
1132+ SettableFuture <SessionResult > sessionFuture = SettableFuture .create ();
1133+ ListenableFuture <Boolean > playRequestedFuture = onPlayRequested ();
1134+ playRequestedFuture .addListener (
1135+ () -> {
1136+ boolean playRequested ;
1137+ try {
1138+ playRequested = playRequestedFuture .get ();
1139+ } catch (ExecutionException | InterruptedException e ) {
1140+ sessionFuture .setException (new IllegalStateException (e ));
1141+ return ;
1142+ }
1143+ if (!playRequested ) {
1144+ // Request denied, e.g. due to missing foreground service abilities.
1145+ sessionFuture .set (new SessionResult (SessionResult .RESULT_ERROR_UNKNOWN ));
1146+ return ;
1147+ }
1148+ boolean hasCurrentMediaItem =
1149+ playerWrapper .isCommandAvailable (Player .COMMAND_GET_CURRENT_MEDIA_ITEM )
1150+ && playerWrapper .getCurrentMediaItem () != null ;
1151+ boolean canAddMediaItems =
1152+ playerWrapper .isCommandAvailable (COMMAND_SET_MEDIA_ITEM )
1153+ || playerWrapper .isCommandAvailable (COMMAND_CHANGE_MEDIA_ITEMS );
1154+ ControllerInfo controllerForRequest = resolveControllerInfoForCallback (controller );
1155+ Player .Commands playCommand =
1156+ new Player .Commands .Builder ().add (Player .COMMAND_PLAY_PAUSE ).build ();
1157+ if (hasCurrentMediaItem || !canAddMediaItems ) {
1158+ // No playback resumption needed or possible.
1159+ if (!hasCurrentMediaItem ) {
1160+ Log .w (
1161+ TAG ,
1162+ "Play requested without current MediaItem, but playback resumption prevented by"
1163+ + " missing available commands" );
11771164 }
1178-
1179- @ Override
1180- public void onFailure (Throwable t ) {
1181- if (t instanceof UnsupportedOperationException ) {
1182- Log .w (
1183- TAG ,
1184- "UnsupportedOperationException: Make sure to implement"
1185- + " MediaSession.Callback.onPlaybackResumption() if you add a"
1186- + " media button receiver to your manifest or if you implement the recent"
1187- + " media item contract with your MediaLibraryService." ,
1188- t );
1189- } else {
1190- Log .e (
1191- TAG ,
1192- "Failure calling MediaSession.Callback.onPlaybackResumption(): "
1193- + t .getMessage (),
1194- t );
1195- }
1196- // Play as requested even if playback resumption fails.
1197- Util .handlePlayButtonAction (playerWrapper );
1198- if (callOnPlayerInteractionFinished ) {
1199- onPlayerInteractionFinishedOnHandler (controllerForRequest , playCommand );
1200- }
1165+ Util .handlePlayButtonAction (playerWrapper );
1166+ sessionFuture .set (new SessionResult (SessionResult .RESULT_SUCCESS ));
1167+ if (callOnPlayerInteractionFinished ) {
1168+ onPlayerInteractionFinishedOnHandler (controllerForRequest , playCommand );
12011169 }
1202- },
1203- this ::postOrRunOnApplicationHandler );
1204- }
1170+ } else {
1171+ @ Nullable
1172+ ListenableFuture <MediaItemsWithStartPosition > future =
1173+ checkNotNull (
1174+ callback .onPlaybackResumption (
1175+ instance , controllerForRequest , /* isForPlayback= */ true ),
1176+ "Callback.onPlaybackResumption must return a non-null future" );
1177+ Futures .addCallback (
1178+ future ,
1179+ new FutureCallback <MediaItemsWithStartPosition >() {
1180+ @ Override
1181+ public void onSuccess (MediaItemsWithStartPosition mediaItemsWithStartPosition ) {
1182+ callWithControllerForCurrentRequestSet (
1183+ controllerForRequest ,
1184+ () -> {
1185+ MediaUtils .setMediaItemsWithStartIndexAndPosition (
1186+ playerWrapper , mediaItemsWithStartPosition );
1187+ Util .handlePlayButtonAction (playerWrapper );
1188+ sessionFuture .set (new SessionResult (SessionResult .RESULT_SUCCESS ));
1189+ if (callOnPlayerInteractionFinished ) {
1190+ onPlayerInteractionFinishedOnHandler (
1191+ controllerForRequest , playCommand );
1192+ }
1193+ })
1194+ .run ();
1195+ }
1196+
1197+ @ Override
1198+ public void onFailure (Throwable t ) {
1199+ if (t instanceof UnsupportedOperationException ) {
1200+ Log .w (
1201+ TAG ,
1202+ "UnsupportedOperationException: Make sure to implement"
1203+ + " MediaSession.Callback.onPlaybackResumption() if you add a media"
1204+ + " button receiver to your manifest or if you implement the recent"
1205+ + " media item contract with your MediaLibraryService." ,
1206+ t );
1207+ } else {
1208+ Log .e (
1209+ TAG ,
1210+ "Failure calling MediaSession.Callback.onPlaybackResumption(): "
1211+ + t .getMessage (),
1212+ t );
1213+ }
1214+ // Play as requested even if playback resumption fails.
1215+ Util .handlePlayButtonAction (playerWrapper );
1216+ sessionFuture .set (new SessionResult (SessionResult .RESULT_SUCCESS ));
1217+ if (callOnPlayerInteractionFinished ) {
1218+ onPlayerInteractionFinishedOnHandler (controllerForRequest , playCommand );
1219+ }
1220+ }
1221+ },
1222+ this ::postOrRunOnApplicationHandler );
1223+ }
1224+ },
1225+ this ::postOrRunOnApplicationHandler );
1226+ return sessionFuture ;
12051227 }
12061228
12071229 /* package */ void triggerPlayerInfoUpdate () {
0 commit comments