Skip to content

Commit 6355484

Browse files
committed
Asynchronously connect to media3 controllers
1 parent 55049e2 commit 6355484

File tree

1 file changed

+54
-35
lines changed

1 file changed

+54
-35
lines changed

libraries/session/src/main/java/androidx/media3/session/MediaControllerImplBase.java

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,10 @@
7676
import androidx.media3.common.Tracks;
7777
import androidx.media3.common.VideoSize;
7878
import androidx.media3.common.text.CueGroup;
79+
import androidx.media3.common.util.BackgroundExecutor;
7980
import androidx.media3.common.util.BundleCollectionUtil;
8081
import androidx.media3.common.util.Clock;
82+
import androidx.media3.common.util.Consumer;
8183
import androidx.media3.common.util.ListenerSet;
8284
import androidx.media3.common.util.Log;
8385
import androidx.media3.common.util.Size;
@@ -209,17 +211,19 @@ public MediaControllerImplBase(
209211

210212
@Override
211213
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+
};
213220
if (this.token.getType() == SessionToken.TYPE_SESSION) {
214221
// Session
215222
serviceConnection = null;
216-
connectionRequested = requestConnectToSession(connectionHints);
223+
requestConnectToSession(connectionHints, onConnectionRequested);
217224
} else {
218225
serviceConnection = new SessionServiceConnection(connectionHints);
219-
connectionRequested = requestConnectToService();
220-
}
221-
if (!connectionRequested) {
222-
getInstance().runOnApplicationLooper(getInstance()::release);
226+
requestConnectToService(onConnectionRequested);
223227
}
224228
}
225229

@@ -2617,7 +2621,7 @@ private void notifyPlayerInfoListenersWithReasons(
26172621
listeners.flushEvents();
26182622
}
26192623

2620-
private boolean requestConnectToService() {
2624+
private void requestConnectToService(Consumer<Boolean> onConnectionRequested) {
26212625
int flags =
26222626
SDK_INT >= 29
26232627
? Context.BIND_AUTO_CREATE | Context.BIND_INCLUDE_CAPABILITIES
@@ -2641,34 +2645,49 @@ private boolean requestConnectToService() {
26412645
// If a service wants to keep running, it should be either foreground service or
26422646
// bound service. But there had been request for the feature for system apps
26432647
// 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+
});
26722691
}
26732692

26742693
private void clearSurfacesAndCallbacks() {

0 commit comments

Comments
 (0)