@@ -1066,20 +1066,23 @@ protected MediaSessionServiceLegacyStub getLegacyBrowserService() {
10661066 });
10671067 }
10681068
1069- /* package */ boolean onPlayRequested () {
1069+ /* package */ ListenableFuture < Boolean > onPlayRequested () {
10701070 if (Looper .myLooper () != Looper .getMainLooper ()) {
10711071 SettableFuture <Boolean > playRequested = SettableFuture .create ();
1072- mainHandler .post (() -> playRequested .set (onPlayRequested ()));
1073- try {
1074- return playRequested .get ();
1075- } catch (InterruptedException | ExecutionException e ) {
1076- throw new IllegalStateException (e );
1077- }
1072+ mainHandler .post (
1073+ () -> {
1074+ try {
1075+ playRequested .set (onPlayRequested ().get ());
1076+ } catch (ExecutionException | InterruptedException e ) {
1077+ playRequested .setException (new IllegalStateException (e ));
1078+ }
1079+ });
1080+ return playRequested ;
10781081 }
10791082 if (this .mediaSessionListener != null ) {
1080- return this .mediaSessionListener .onPlayRequested (instance );
1083+ return Futures . immediateFuture ( this .mediaSessionListener .onPlayRequested (instance ) );
10811084 }
1082- return true ;
1085+ return Futures . immediateFuture ( true ) ;
10831086 }
10841087
10851088 /**
@@ -1090,83 +1093,102 @@ protected MediaSessionServiceLegacyStub getLegacyBrowserService() {
10901093 *
10911094 * @param controller The controller requesting to play.
10921095 */
1093- /* package */ void handleMediaControllerPlayRequest (
1096+ /* package */ ListenableFuture < SessionResult > handleMediaControllerPlayRequest (
10941097 ControllerInfo controller , boolean callOnPlayerInteractionFinished ) {
1095- if (!onPlayRequested ()) {
1096- // Request denied, e.g. due to missing foreground service abilities.
1097- return ;
1098- }
1099- boolean hasCurrentMediaItem =
1100- playerWrapper .isCommandAvailable (Player .COMMAND_GET_CURRENT_MEDIA_ITEM )
1101- && playerWrapper .getCurrentMediaItem () != null ;
1102- boolean canAddMediaItems =
1103- playerWrapper .isCommandAvailable (COMMAND_SET_MEDIA_ITEM )
1104- || playerWrapper .isCommandAvailable (COMMAND_CHANGE_MEDIA_ITEMS );
1105- ControllerInfo controllerForRequest = resolveControllerInfoForCallback (controller );
1106- Player .Commands playCommand =
1107- new Player .Commands .Builder ().add (Player .COMMAND_PLAY_PAUSE ).build ();
1108- if (hasCurrentMediaItem || !canAddMediaItems ) {
1109- // No playback resumption needed or possible.
1110- if (!hasCurrentMediaItem ) {
1111- Log .w (
1112- TAG ,
1113- "Play requested without current MediaItem, but playback resumption prevented by"
1114- + " missing available commands" );
1115- }
1116- Util .handlePlayButtonAction (playerWrapper );
1117- if (callOnPlayerInteractionFinished ) {
1118- onPlayerInteractionFinishedOnHandler (controllerForRequest , playCommand );
1119- }
1120- } else {
1121- @ Nullable
1122- ListenableFuture <MediaItemsWithStartPosition > future =
1123- checkNotNull (
1124- callback .onPlaybackResumption (instance , controllerForRequest ),
1125- "Callback.onPlaybackResumption must return a non-null future" );
1126- Futures .addCallback (
1127- future ,
1128- new FutureCallback <MediaItemsWithStartPosition >() {
1129- @ Override
1130- public void onSuccess (MediaItemsWithStartPosition mediaItemsWithStartPosition ) {
1131- callWithControllerForCurrentRequestSet (
1132- controllerForRequest ,
1133- () -> {
1134- MediaUtils .setMediaItemsWithStartIndexAndPosition (
1135- playerWrapper , mediaItemsWithStartPosition );
1136- Util .handlePlayButtonAction (playerWrapper );
1137- if (callOnPlayerInteractionFinished ) {
1138- onPlayerInteractionFinishedOnHandler (controllerForRequest , playCommand );
1139- }
1140- })
1141- .run ();
1098+ SettableFuture <SessionResult > sessionFuture = SettableFuture .create ();
1099+ ListenableFuture <Boolean > playRequestedFuture = onPlayRequested ();
1100+ playRequestedFuture .addListener (
1101+ () -> {
1102+ boolean playRequested ;
1103+ try {
1104+ playRequested = playRequestedFuture .get ();
1105+ } catch (ExecutionException | InterruptedException e ) {
1106+ sessionFuture .setException (new IllegalStateException (e ));
1107+ return ;
1108+ }
1109+ if (!playRequested ) {
1110+ // Request denied, e.g. due to missing foreground service abilities.
1111+ sessionFuture .set (new SessionResult (SessionResult .RESULT_ERROR_UNKNOWN ));
1112+ return ;
1113+ }
1114+ boolean hasCurrentMediaItem =
1115+ playerWrapper .isCommandAvailable (Player .COMMAND_GET_CURRENT_MEDIA_ITEM )
1116+ && playerWrapper .getCurrentMediaItem () != null ;
1117+ boolean canAddMediaItems =
1118+ playerWrapper .isCommandAvailable (COMMAND_SET_MEDIA_ITEM )
1119+ || playerWrapper .isCommandAvailable (COMMAND_CHANGE_MEDIA_ITEMS );
1120+ ControllerInfo controllerForRequest = resolveControllerInfoForCallback (controller );
1121+ Player .Commands playCommand =
1122+ new Player .Commands .Builder ().add (Player .COMMAND_PLAY_PAUSE ).build ();
1123+ if (hasCurrentMediaItem || !canAddMediaItems ) {
1124+ // No playback resumption needed or possible.
1125+ if (!hasCurrentMediaItem ) {
1126+ Log .w (
1127+ TAG ,
1128+ "Play requested without current MediaItem, but playback resumption prevented by"
1129+ + " missing available commands" );
11421130 }
1143-
1144- @ Override
1145- public void onFailure (Throwable t ) {
1146- if (t instanceof UnsupportedOperationException ) {
1147- Log .w (
1148- TAG ,
1149- "UnsupportedOperationException: Make sure to implement"
1150- + " MediaSession.Callback.onPlaybackResumption() if you add a"
1151- + " media button receiver to your manifest or if you implement the recent"
1152- + " media item contract with your MediaLibraryService." ,
1153- t );
1154- } else {
1155- Log .e (
1156- TAG ,
1157- "Failure calling MediaSession.Callback.onPlaybackResumption(): "
1158- + t .getMessage (),
1159- t );
1160- }
1161- // Play as requested even if playback resumption fails.
1162- Util .handlePlayButtonAction (playerWrapper );
1163- if (callOnPlayerInteractionFinished ) {
1164- onPlayerInteractionFinishedOnHandler (controllerForRequest , playCommand );
1165- }
1131+ Util .handlePlayButtonAction (playerWrapper );
1132+ sessionFuture .set (new SessionResult (SessionResult .RESULT_SUCCESS ));
1133+ if (callOnPlayerInteractionFinished ) {
1134+ onPlayerInteractionFinishedOnHandler (controllerForRequest , playCommand );
11661135 }
1167- },
1168- this ::postOrRunOnApplicationHandler );
1169- }
1136+ } else {
1137+ @ Nullable
1138+ ListenableFuture <MediaItemsWithStartPosition > future =
1139+ checkNotNull (
1140+ callback .onPlaybackResumption (instance , controllerForRequest ),
1141+ "Callback.onPlaybackResumption must return a non-null future" );
1142+ Futures .addCallback (
1143+ future ,
1144+ new FutureCallback <MediaItemsWithStartPosition >() {
1145+ @ Override
1146+ public void onSuccess (MediaItemsWithStartPosition mediaItemsWithStartPosition ) {
1147+ callWithControllerForCurrentRequestSet (
1148+ controllerForRequest ,
1149+ () -> {
1150+ MediaUtils .setMediaItemsWithStartIndexAndPosition (
1151+ playerWrapper , mediaItemsWithStartPosition );
1152+ Util .handlePlayButtonAction (playerWrapper );
1153+ sessionFuture .set (new SessionResult (SessionResult .RESULT_SUCCESS ));
1154+ if (callOnPlayerInteractionFinished ) {
1155+ onPlayerInteractionFinishedOnHandler (
1156+ controllerForRequest , playCommand );
1157+ }
1158+ })
1159+ .run ();
1160+ }
1161+
1162+ @ Override
1163+ public void onFailure (Throwable t ) {
1164+ if (t instanceof UnsupportedOperationException ) {
1165+ Log .w (
1166+ TAG ,
1167+ "UnsupportedOperationException: Make sure to implement"
1168+ + " MediaSession.Callback.onPlaybackResumption() if you add a media"
1169+ + " button receiver to your manifest or if you implement the recent"
1170+ + " media item contract with your MediaLibraryService." ,
1171+ t );
1172+ } else {
1173+ Log .e (
1174+ TAG ,
1175+ "Failure calling MediaSession.Callback.onPlaybackResumption(): "
1176+ + t .getMessage (),
1177+ t );
1178+ }
1179+ // Play as requested even if playback resumption fails.
1180+ Util .handlePlayButtonAction (playerWrapper );
1181+ sessionFuture .set (new SessionResult (SessionResult .RESULT_SUCCESS ));
1182+ if (callOnPlayerInteractionFinished ) {
1183+ onPlayerInteractionFinishedOnHandler (controllerForRequest , playCommand );
1184+ }
1185+ }
1186+ },
1187+ this ::postOrRunOnApplicationHandler );
1188+ }
1189+ },
1190+ this ::postOrRunOnApplicationHandler );
1191+ return sessionFuture ;
11701192 }
11711193
11721194 private void setLegacyMediaButtonPreferences (
0 commit comments