SecurityException with ListenableFuture<MediaController>.Get()
@marcbaechinger is already working on this.
Since Mar 23, 2023.
- Dominant language
- Java
- Stars
- 3k
- Forks
- 955
- Avg merge
- 12d 14h
- Merged PRs (30d)
- 2
Description
Hello,
Currently working on a video feature supporting multiple session for a compose app.
For our example I have 1 video who appear in a middle of a list which contain other items.
The feature is fully working when scrolling normally.
The video isn't composed yet and when user scroll down the list, when the video appear on view, it create the component which get connected to the mediaSessionService to retrieve or Add a new session.
If user continue to scroll down and video is out of the view, we release the component.
The code is simple, I have a Composable containing an AndroidView for the player view and a DisposableEffect which call MediaController.releaseFuture(controllerFuture) when the component is unload.
DisposableEffect(Unit) {
onDispose { state.onDispose() }
}
AndroidView(
factory = { _ -> state.view // return the view },
update = {}
)
The logic is made in a VideoPlayerState:
class VideoPlayerState(...) {
private val controllerBundle: Bundle = Bundle().apply {...}
private val controllerFuture: ListenableFuture<MediaController> = MediaController.Builder(
context,
SessionToken(context, ComponentName(context, ApolloMediaSessionService::class.java))
)
.setConnectionHints(controllerBundle)
.buildAsync()
// Todo crash: when scroll fast down and up.
val controller: MediaController?
get() = if (controllerFuture.isDone) controllerFuture.get() else null
init {
controllerFuture.addListener({ setController() }, MoreExecutors.directExecutor())
}
private fun setController() {
val controller: MediaController = this.controller ?: return
....
}
When a user Scroll fast to the bottom the MediaController.releaseFuture(controllerFuture) is called and Future.get() will throw a CancellationException: "Task was cancelled" which is the normal behaviour.
But if a user scroll up to reload the component video I see in AbstractFuture.Get() that localValue = javax.net.ssl.SSLHandshakeException: Connection closed by peer.
I couldn't go any further in my investigation as limited knowledge on Future. But I understand the issue is coming from MediaSessionService who reject the connection.
FATAL EXCEPTION: main
Process: android.AbcApplication, PID: 5170
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:558)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
Caused by: java.util.concurrent.ExecutionException: java.lang.SecurityException: Session rejected the connection request.
at com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture.java:588)
at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:547)
at au.net.abc.apollo.media3.VideoPlayerState.getController(TeaserVideoPlayer.kt:257)
at au.net.abc.apollo.media3.VideoPlayerState.setController(TeaserVideoPlayer.kt:293)
at au.net.abc.apollo.media3.VideoPlayerState._init_$lambda$1(TeaserVideoPlayer.kt:288)
at au.net.abc.apollo.media3.VideoPlayerState.$r8$lambda$j26VTzzHmtGX48tuw1ld6HqiIsc(Unknown Source:0)
at au.net.abc.apollo.media3.VideoPlayerState$$ExternalSyntheticLambda0.run(Unknown Source:2)
at com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:31)
at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1270)
at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:1038)
at com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:808)
at androidx.media3.session.MediaControllerHolder.maybeSetException(MediaControllerHolder.java:67)
at androidx.media3.session.MediaControllerHolder.onRejected(MediaControllerHolder.java:57)
at androidx.media3.session.MediaController.release(MediaController.java:512)
at androidx.media3.session.MediaControllerImplBase$$ExternalSyntheticLambda63.run(Unknown Source:2)
at androidx.media3.common.util.Util.postOrRun(Util.java:607)
at androidx.media3.session.MediaController.runOnApplicationLooper(MediaController.java:1837)
at androidx.media3.session.MediaControllerStub.lambda$onDisconnected$1(MediaControllerStub.java:94)
at androidx.media3.session.MediaControllerStub$$ExternalSyntheticLambda3.run(Unknown Source:0)
at androidx.media3.session.MediaControllerStub.lambda$dispatchControllerTaskOnHandler$11(MediaControllerStub.java:301)
at androidx.media3.session.MediaControllerStub$$ExternalSyntheticLambda11.run(Unknown Source:4)
at androidx.media3.common.util.Util.postOrRun(Util.java:607)
at androidx.media3.session.MediaControllerStub.dispatchControllerTaskOnHandler(MediaControllerStub.java:293)
at androidx.media3.session.MediaControllerStub.onDisconnected(MediaControllerStub.java:92)
at androidx.media3.session.MediaSessionService$MediaSessionServiceStub.lambda$connect$0$androidx-media3-session-MediaSessionService$MediaSessionServiceStub(MediaSessionService.java:712)
at androidx.media3.session.MediaSessionService$MediaSessionServiceStub$$ExternalSyntheticLambda0.run(Unknown Source:14)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7872)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
Caused by: java.lang.SecurityException: Session rejected the connection request.
at androidx.media3.session.MediaControllerHolder.maybeSetException(MediaControllerHolder.java:67)
at androidx.media3.session.MediaControllerHolder.onRejected(MediaControllerHolder.java:57)
at androidx.media3.session.MediaController.release(MediaController.java:512)
at androidx.media3.session.MediaControllerImplBase$$ExternalSyntheticLambda63.run(Unknown Source:2)
at androidx.media3.common.util.Util.postOrRun(Util.java:607)
at androidx.media3.session.MediaController.runOnApplicationLooper(MediaController.java:1837)
at androidx.media3.session.MediaControllerStub.lambda$onDisconnected$1(MediaControllerStub.java:94)
at androidx.media3.session.MediaControllerStub$$ExternalSyntheticLambda3.run(Unknown Source:0)
at androidx.media3.session.MediaControllerStub.lambda$dispatchControllerTaskOnHandler$11(MediaControllerStub.java:301)
at androidx.media3.session.MediaControllerStub$$ExternalSyntheticLambda11.run(Unknown Source:4)
at androidx.media3.common.util.Util.postOrRun(Util.java:607)
at androidx.media3.session.MediaControllerStub.dispatchControllerTaskOnHandler(MediaControllerStub.java:293)
at androidx.media3.session.MediaControllerStub.onDisconnected(MediaControllerStub.java:92)
at androidx.media3.session.MediaSessionService$MediaSessionServiceStub.lambda$connect$0$androidx-media3-session-MediaSessionService$MediaSessionServiceStub(MediaSessionService.java:712)
at androidx.media3.session.MediaSessionService$MediaSessionServiceStub$$ExternalSyntheticLambda0.run(Unknown Source:14)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7872)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
My question is, If I had to understand why the connection is rejected on service side, where should I look?
Thank you
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.