use of androidx.media3.session.MediaSession.ControllerCb in project media by androidx.
the class MediaLibrarySessionImpl method onSubscribeOnHandler.
public ListenableFuture<LibraryResult<Void>> onSubscribeOnHandler(ControllerInfo browser, String parentId, @Nullable LibraryParams params) {
ControllerCb controller = checkStateNotNull(browser.getControllerCb());
synchronized (lock) {
@Nullable Set<String> subscription = subscriptions.get(controller);
if (subscription == null) {
subscription = new HashSet<>();
subscriptions.put(controller, subscription);
}
subscription.add(parentId);
}
// Call callbacks after adding it to the subscription list because library session may want
// to call notifyChildrenChanged() in the callback.
//
// onSubscribe is defined to return a non-null result but it's implemented by applications,
// so we explicitly null-check the result to fail early if an app accidentally returns null.
ListenableFuture<LibraryResult<Void>> future = checkNotNull(callback.onSubscribe(instance, browser, parentId, params), "onSubscribe must return non-null future");
// When error happens, remove from the subscription list.
future.addListener(() -> {
@Nullable LibraryResult<Void> result = tryGetFutureResult(future);
if (result == null || result.resultCode != RESULT_SUCCESS) {
removeSubscription(controller, parentId);
}
}, MoreExecutors.directExecutor());
return future;
}
use of androidx.media3.session.MediaSession.ControllerCb in project media by androidx.
the class MediaSessionImpl method dispatchRemoteControllerTask.
private ListenableFuture<SessionResult> dispatchRemoteControllerTask(ControllerInfo controller, RemoteControllerTask task) {
try {
ListenableFuture<SessionResult> future;
int seq;
@Nullable SequencedFutureManager manager = sessionStub.getConnectedControllersManager().getSequencedFutureManager(controller);
if (manager != null) {
future = manager.createSequencedFuture(RESULT_WHEN_CLOSED);
seq = ((SequencedFuture<SessionResult>) future).getSequenceNumber();
} else {
if (!isConnected(controller)) {
return Futures.immediateFuture(new SessionResult(RESULT_ERROR_SESSION_DISCONNECTED));
}
// 0 is OK for legacy controllers, because they didn't have sequence numbers.
seq = 0;
// Tell that operation is successful, although we don't know the actual result.
future = Futures.immediateFuture(new SessionResult(SessionResult.RESULT_SUCCESS));
}
ControllerCb cb = controller.getControllerCb();
if (cb != null) {
task.run(cb, seq);
}
return future;
} catch (DeadObjectException e) {
onDeadObjectException(controller, e);
return Futures.immediateFuture(new SessionResult(RESULT_ERROR_SESSION_DISCONNECTED));
} catch (RemoteException e) {
// Currently it's TransactionTooLargeException or DeadSystemException.
// We'd better to leave log for those cases because
// - TransactionTooLargeException means that we may need to fix our code.
// (e.g. add pagination or special way to deliver Bitmap)
// - DeadSystemException means that errors around it can be ignored.
Log.w(TAG, "Exception in " + controller.toString(), e);
}
return Futures.immediateFuture(new SessionResult(RESULT_ERROR_UNKNOWN));
}
use of androidx.media3.session.MediaSession.ControllerCb in project media by androidx.
the class MediaSessionLegacyStub method tryGetController.
@Nullable
private ControllerInfo tryGetController(RemoteUserInfo remoteUserInfo) {
@Nullable ControllerInfo controller = connectedControllersManager.getController(remoteUserInfo);
if (controller == null) {
// Try connect.
ControllerCb controllerCb = new ControllerLegacyCb(remoteUserInfo);
controller = new ControllerInfo(remoteUserInfo, /* controllerVersion= */
0, sessionManager.isTrustedForMediaControl(remoteUserInfo), controllerCb, /* connectionHints= */
Bundle.EMPTY);
MediaSession.ConnectionResult connectionResult = sessionImpl.onConnectOnHandler(controller);
if (!connectionResult.isAccepted) {
try {
controllerCb.onDisconnected(/* seq= */
0);
} catch (RemoteException e) {
// Controller may have died prematurely.
}
return null;
}
connectedControllersManager.addController(controller.getRemoteUserInfo(), controller, connectionResult.availableSessionCommands, connectionResult.availablePlayerCommands);
}
// Reset disconnect timeout.
connectionTimeoutHandler.disconnectControllerAfterTimeout(controller, connectionTimeoutMs);
return controller;
}
use of androidx.media3.session.MediaSession.ControllerCb in project media by androidx.
the class MediaSessionImpl method dispatchRemoteControllerTaskWithoutReturn.
protected void dispatchRemoteControllerTaskWithoutReturn(ControllerInfo controller, RemoteControllerTask task) {
try {
int seq;
@Nullable SequencedFutureManager manager = sessionStub.getConnectedControllersManager().getSequencedFutureManager(controller);
if (manager != null) {
seq = manager.obtainNextSequenceNumber();
} else {
if (!isConnected(controller)) {
return;
}
// 0 is OK for legacy controllers, because they didn't have sequence numbers.
seq = 0;
}
ControllerCb cb = controller.getControllerCb();
if (cb != null) {
task.run(cb, seq);
}
} catch (DeadObjectException e) {
onDeadObjectException(controller, e);
} catch (RemoteException e) {
// Currently it's TransactionTooLargeException or DeadSystemException.
// We'd better to leave log for those cases because
// - TransactionTooLargeException means that we may need to fix our code.
// (e.g. add pagination or special way to deliver Bitmap)
// - DeadSystemException means that errors around it can be ignored.
Log.w(TAG, "Exception in " + controller.toString(), e);
}
}
Aggregations