Fix camera rotation / phone orientation syncing.

This commit is contained in:
Alex Hart
2025-05-12 14:39:06 -03:00
committed by Michelle Tang
parent 288eda5bb1
commit 8d2979d8ce
3 changed files with 74 additions and 0 deletions

View File

@@ -26,4 +26,12 @@ public enum Orientation {
return PORTRAIT_BOTTOM_EDGE;
}
public static @NonNull Orientation fromSurfaceRotation(int surfaceRotation) {
return switch (surfaceRotation) {
case 1 -> LANDSCAPE_LEFT_EDGE;
case 3 -> LANDSCAPE_RIGHT_EDGE;
default -> PORTRAIT_BOTTOM_EDGE;
};
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2025 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.securesms.components.webrtc.v2
import android.hardware.display.DisplayManager
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.trySendBlocking
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
object DisplayMonitor {
/**
* Emits a flow of events from a [DisplayManager.DisplayListener]
* callback.
*/
fun monitor(displayManager: DisplayManager): Flow<MonitorEvent> {
return callbackFlow {
val displayListener = object : DisplayManager.DisplayListener {
override fun onDisplayAdded(displayId: Int) {
trySendBlocking(MonitorEvent.Added(displayId))
}
override fun onDisplayRemoved(displayId: Int) {
trySendBlocking(MonitorEvent.Removed(displayId))
}
override fun onDisplayChanged(displayId: Int) {
trySendBlocking(MonitorEvent.Changed(displayId))
}
}
displayManager.registerDisplayListener(displayListener, null)
awaitClose {
displayManager.unregisterDisplayListener(displayListener)
}
}
}
sealed interface MonitorEvent {
val displayId: Int
data class Added(override val displayId: Int) : MonitorEvent
data class Removed(override val displayId: Int) : MonitorEvent
data class Changed(override val displayId: Int) : MonitorEvent
}
}

View File

@@ -12,6 +12,7 @@ import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.hardware.display.DisplayManager
import android.media.AudioManager
import android.os.Build
import android.os.Bundle
@@ -24,6 +25,7 @@ import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.ContextCompat
import androidx.core.content.getSystemService
import androidx.core.util.Consumer
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
@@ -44,6 +46,7 @@ import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.signal.core.util.ThreadUtil
import org.signal.core.util.concurrent.LifecycleDisposable
import org.signal.core.util.concurrent.SignalDispatchers
import org.signal.core.util.concurrent.SignalExecutors
import org.signal.core.util.logging.Log
import org.signal.ringrtc.GroupCall
@@ -477,6 +480,19 @@ class WebRtcCallActivity : BaseActivity(), SafetyNumberChangeDialog.Callback, Re
viewModel.setIsInPipMode(isInPipMode())
lifecycleScope.launch {
launch(SignalDispatchers.Unconfined) {
lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) {
val displayManager = application.getSystemService<DisplayManager>()!!
DisplayMonitor.monitor(displayManager)
.collectLatest {
val display = displayManager.getDisplay(it.displayId) ?: return@collectLatest
val orientation = Orientation.fromSurfaceRotation(display.rotation)
AppDependencies.signalCallManager.orientationChanged(true, orientation.degrees)
}
}
}
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
viewModel.microphoneEnabled.collectLatest {