androidx / androidx/media

SecurityException with ListenableFuture<MediaController>.Get()

Open
#277 12 comments 0 reactions 1 assignee View on GitHub

@marcbaechinger is already working on this.

Since Mar 23, 2023.

question
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.