76
76
import androidx .media3 .common .Tracks ;
77
77
import androidx .media3 .common .VideoSize ;
78
78
import androidx .media3 .common .text .CueGroup ;
79
+ import androidx .media3 .common .util .BackgroundExecutor ;
79
80
import androidx .media3 .common .util .BundleCollectionUtil ;
80
81
import androidx .media3 .common .util .Clock ;
82
+ import androidx .media3 .common .util .Consumer ;
81
83
import androidx .media3 .common .util .ListenerSet ;
82
84
import androidx .media3 .common .util .Log ;
83
85
import androidx .media3 .common .util .Size ;
@@ -209,17 +211,19 @@ public MediaControllerImplBase(
209
211
210
212
@ Override
211
213
public void connect (@ UnderInitialization MediaControllerImplBase this ) {
212
- boolean connectionRequested ;
214
+ Consumer <Boolean > onConnectionRequested =
215
+ connectionRequested -> {
216
+ if (!connectionRequested ) {
217
+ getInstance ().runOnApplicationLooper (getInstance ()::release );
218
+ }
219
+ };
213
220
if (this .token .getType () == SessionToken .TYPE_SESSION ) {
214
221
// Session
215
222
serviceConnection = null ;
216
- connectionRequested = requestConnectToSession (connectionHints );
223
+ requestConnectToSession (connectionHints , onConnectionRequested );
217
224
} else {
218
225
serviceConnection = new SessionServiceConnection (connectionHints );
219
- connectionRequested = requestConnectToService ();
220
- }
221
- if (!connectionRequested ) {
222
- getInstance ().runOnApplicationLooper (getInstance ()::release );
226
+ requestConnectToService (onConnectionRequested );
223
227
}
224
228
}
225
229
@@ -2617,7 +2621,7 @@ private void notifyPlayerInfoListenersWithReasons(
2617
2621
listeners .flushEvents ();
2618
2622
}
2619
2623
2620
- private boolean requestConnectToService () {
2624
+ private void requestConnectToService (Consumer < Boolean > onConnectionRequested ) {
2621
2625
int flags =
2622
2626
SDK_INT >= 29
2623
2627
? Context .BIND_AUTO_CREATE | Context .BIND_INCLUDE_CAPABILITIES
@@ -2641,34 +2645,49 @@ private boolean requestConnectToService() {
2641
2645
// If a service wants to keep running, it should be either foreground service or
2642
2646
// bound service. But there had been request for the feature for system apps
2643
2647
// and using bindService() will be better fit with it.
2644
- try {
2645
- if (context .bindService (intent , serviceConnection , flags )) {
2646
- return true ;
2647
- }
2648
- Log .w (TAG , "bind to " + token + " failed" );
2649
- } catch (SecurityException e ) {
2650
- Log .w (TAG , "bind to " + token + " not allowed" , e );
2651
- }
2652
- return false ;
2653
- }
2654
-
2655
- private boolean requestConnectToSession (Bundle connectionHints ) {
2656
- IMediaSession iSession =
2657
- IMediaSession .Stub .asInterface ((IBinder ) checkNotNull (token .getBinder ()));
2658
- int seq = sequencedFutureManager .obtainNextSequenceNumber ();
2659
- ConnectionRequest request =
2660
- new ConnectionRequest (
2661
- context .getPackageName (),
2662
- Process .myPid (),
2663
- connectionHints ,
2664
- instance .getMaxCommandsForMediaItems ());
2665
- try {
2666
- iSession .connect (controllerStub , seq , request .toBundle ());
2667
- } catch (RemoteException e ) {
2668
- Log .w (TAG , "Failed to call connection request." , e );
2669
- return false ;
2670
- }
2671
- return true ;
2648
+ BackgroundExecutor .get ()
2649
+ .execute (
2650
+ () -> {
2651
+ try {
2652
+ if (context .bindService (intent , serviceConnection , flags )) {
2653
+ onConnectionRequested .accept (true );
2654
+ return ;
2655
+ }
2656
+ Log .w (TAG , "bind to " + token + " failed" );
2657
+ } catch (SecurityException e ) {
2658
+ Log .w (TAG , "bind to " + token + " not allowed" , e );
2659
+ }
2660
+ onConnectionRequested .accept (false );
2661
+ });
2662
+ }
2663
+
2664
+ private void requestConnectToSession (
2665
+ Bundle connectionHints , Consumer <Boolean > onConnectionRequested ) {
2666
+ // If the session is not remote, it will answer swiftly. In order to support creating a media
2667
+ // controller in the media session service onCreate, connect in-place if not remote.
2668
+ (token .getBinder () instanceof MediaSessionStub
2669
+ ? MoreExecutors .directExecutor ()
2670
+ : BackgroundExecutor .get ())
2671
+ .execute (
2672
+ () -> {
2673
+ IMediaSession iSession =
2674
+ IMediaSession .Stub .asInterface ((IBinder ) checkNotNull (token .getBinder ()));
2675
+ int seq = sequencedFutureManager .obtainNextSequenceNumber ();
2676
+ ConnectionRequest request =
2677
+ new ConnectionRequest (
2678
+ context .getPackageName (),
2679
+ Process .myPid (),
2680
+ connectionHints ,
2681
+ instance .getMaxCommandsForMediaItems ());
2682
+ try {
2683
+ iSession .connect (controllerStub , seq , request .toBundle ());
2684
+ } catch (RemoteException e ) {
2685
+ Log .w (TAG , "Failed to call connection request." , e );
2686
+ onConnectionRequested .accept (false );
2687
+ return ;
2688
+ }
2689
+ onConnectionRequested .accept (true );
2690
+ });
2672
2691
}
2673
2692
2674
2693
private void clearSurfacesAndCallbacks () {
0 commit comments