@@ -33,14 +33,21 @@ import androidx.activity.result.ActivityResultLauncher
3333import androidx.activity.result.contract.ActivityResultContracts
3434import androidx.annotation.RequiresApi
3535import androidx.appcompat.app.AppCompatActivity
36+ import androidx.compose.runtime.Composable
37+ import androidx.compose.runtime.DisposableEffect
38+ import androidx.compose.runtime.getValue
3639import androidx.compose.runtime.mutableStateOf
40+ import androidx.compose.runtime.rememberUpdatedState
41+ import androidx.core.app.PictureInPictureModeChangedInfo
3742import androidx.core.content.IntentCompat
43+ import androidx.core.util.Consumer
3844import androidx.lifecycle.Lifecycle
3945import io.element.android.features.call.api.CallType
4046import io.element.android.features.call.impl.DefaultElementCallEntryPoint
4147import io.element.android.features.call.impl.di.CallBindings
4248import io.element.android.features.call.impl.pip.PictureInPictureEvents
4349import io.element.android.features.call.impl.pip.PictureInPicturePresenter
50+ import io.element.android.features.call.impl.pip.PictureInPictureState
4451import io.element.android.features.call.impl.pip.PipActivity
4552import io.element.android.features.call.impl.services.CallForegroundService
4653import io.element.android.features.call.impl.utils.CallIntentDataParser
@@ -74,7 +81,6 @@ class ElementCallActivity :
7481 private val webViewTarget = mutableStateOf<CallType ?>(null )
7582
7683 private var eventSink: ((CallScreenEvents ) -> Unit )? = null
77- private var pipEventSink: ((PictureInPictureEvents ) -> Unit )? = null
7884
7985 override fun onCreate (savedInstanceState : Bundle ? ) {
8086 super .onCreate(savedInstanceState)
@@ -102,7 +108,7 @@ class ElementCallActivity :
102108
103109 setContent {
104110 val pipState = pictureInPicturePresenter.present()
105- pipEventSink = pipState.eventSink
111+ ListenToAndroidEvents ( pipState)
106112 ElementThemeApp (appPreferencesStore) {
107113 val state = presenter.present()
108114 eventSink = state.eventSink
@@ -118,21 +124,38 @@ class ElementCallActivity :
118124 }
119125 }
120126
127+ @Composable
128+ private fun ListenToAndroidEvents (pipState : PictureInPictureState ) {
129+ val pipEventSink by rememberUpdatedState(pipState.eventSink)
130+ DisposableEffect (Unit ) {
131+ val onUserLeaveHintListener = Runnable {
132+ pipEventSink(PictureInPictureEvents .EnterPictureInPicture )
133+ }
134+ addOnUserLeaveHintListener(onUserLeaveHintListener)
135+ onDispose {
136+ removeOnUserLeaveHintListener(onUserLeaveHintListener)
137+ }
138+ }
139+ DisposableEffect (Unit ) {
140+ val onPictureInPictureModeChangedListener = Consumer { _: PictureInPictureModeChangedInfo ->
141+ pipEventSink(PictureInPictureEvents .OnPictureInPictureModeChanged (isInPictureInPictureMode))
142+ if (! isInPictureInPictureMode && ! lifecycle.currentState.isAtLeast(Lifecycle .State .STARTED )) {
143+ Timber .d(" Exiting PiP mode: Hangup the call" )
144+ eventSink?.invoke(CallScreenEvents .Hangup )
145+ }
146+ }
147+ addOnPictureInPictureModeChangedListener(onPictureInPictureModeChangedListener)
148+ onDispose {
149+ removeOnPictureInPictureModeChangedListener(onPictureInPictureModeChangedListener)
150+ }
151+ }
152+ }
153+
121154 override fun onConfigurationChanged (newConfig : Configuration ) {
122155 super .onConfigurationChanged(newConfig)
123156 updateUiMode(newConfig)
124157 }
125158
126- override fun onPictureInPictureModeChanged (isInPictureInPictureMode : Boolean , newConfig : Configuration ) {
127- super .onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
128- pipEventSink?.invoke(PictureInPictureEvents .OnPictureInPictureModeChanged (isInPictureInPictureMode))
129-
130- if (! isInPictureInPictureMode && ! lifecycle.currentState.isAtLeast(Lifecycle .State .STARTED )) {
131- Timber .d(" Exiting PiP mode: Hangup the call" )
132- eventSink?.invoke(CallScreenEvents .Hangup )
133- }
134- }
135-
136159 override fun onNewIntent (intent : Intent ) {
137160 super .onNewIntent(intent)
138161 setCallType(intent)
@@ -150,11 +173,6 @@ class ElementCallActivity :
150173 }
151174 }
152175
153- override fun onUserLeaveHint () {
154- super .onUserLeaveHint()
155- pipEventSink?.invoke(PictureInPictureEvents .EnterPictureInPicture )
156- }
157-
158176 override fun onDestroy () {
159177 super .onDestroy()
160178 releaseAudioFocus()
0 commit comments