Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,14 @@ val CameraOrientation.degrees: Int
}
}

fun CameraOrientation.Companion.fromDegrees(degrees: Int): CameraOrientation {
val normalizedDegrees = normalizeDegrees(degrees)
return when (normalizedDegrees) {
in 45..135 -> CameraOrientation.LEFT
in 135..225 -> CameraOrientation.DOWN
in 225..315 -> CameraOrientation.RIGHT
else -> CameraOrientation.UP
fun CameraOrientation.Companion.fromDegrees(degrees: Int): CameraOrientation? =
when (degrees) {
in 0 until 45, in 315 until 360 -> CameraOrientation.UP
in 45 until 135 -> CameraOrientation.LEFT
in 135 until 225 -> CameraOrientation.DOWN
in 225 until 315 -> CameraOrientation.RIGHT
else -> null
}
}

private fun CameraOrientation.Companion.normalizeDegrees(degrees: Int): Int {
val normalized = degrees % 360
if (normalized < 0) {
return normalized + 360
}
return normalized
}

/**
* Returns the logical counter-orientation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ val ImageProxy.orientation: CameraOrientation
get() {
val degrees = imageInfo.rotationDegrees
return CameraOrientation.fromDegrees(degrees)
?: throw Error("Invalid ImageProxy rotation degrees: $degrees")
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,16 @@ class HybridDeviceOrientationManager : HybridOrientationManagerSpec() {

override fun startOrientationUpdates(onChanged: (orientation: CameraOrientation) -> Unit) {
orientationListener?.disable()
currentOrientation?.let(onChanged)
orientationListener =
object : OrientationEventListener(context) {
override fun onOrientationChanged(rotationDegrees: Int) {
if (orientationListener !== this) return
if (rotationDegrees == ORIENTATION_UNKNOWN) {
// phone is laying flat - orientation is unknown! Avoid sending out event.
return
}
val orientation = CameraOrientation.fromDegrees(rotationDegrees)
val orientation = CameraOrientation.fromDegrees(rotationDegrees) ?: return
if (currentOrientation != orientation) {
Log.i(TAG, "Device orientation changed! $orientation")
currentOrientation = orientation
Expand All @@ -51,6 +53,8 @@ class HybridDeviceOrientationManager : HybridOrientationManagerSpec() {
}

override fun stopOrientationUpdates() {
orientationListener?.disable()
val listener = orientationListener
orientationListener = null
listener?.disable()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,19 @@ class HybridInterfaceOrientationManager : HybridOrientationManagerSpec() {
listener?.let { listener ->
displayManager.unregisterDisplayListener(listener)
}
val defaultDisplay = displayManager.displays.firstOrNull()
if (defaultDisplay != null) {
currentOrientation = CameraOrientation.fromSurfaceRotation(defaultDisplay.rotation)
}
currentOrientation?.let(onChanged)
val listener =
object : DisplayManager.DisplayListener {
override fun onDisplayAdded(displayId: Int) = Unit

override fun onDisplayRemoved(displayId: Int) = Unit

override fun onDisplayChanged(displayId: Int) {
if (this@HybridInterfaceOrientationManager.listener !== this) return
val display = displayManager.getDisplay(displayId) ?: return
val surfaceRotation = display.rotation
val orientation = CameraOrientation.fromSurfaceRotation(surfaceRotation)
Expand All @@ -54,9 +60,8 @@ class HybridInterfaceOrientationManager : HybridOrientationManagerSpec() {
}

override fun stopOrientationUpdates() {
listener?.let { listener ->
displayManager.unregisterDisplayListener(listener)
}
val currentListener = listener
listener = null
currentListener?.let(displayManager::unregisterDisplayListener)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ extension CameraOrientation {
fatalError("UIImage.Orientation has unknown value: \(uiOrientation)")
}
}
init(interfaceOrientation: UIInterfaceOrientation) {
init?(interfaceOrientation: UIInterfaceOrientation) {
switch interfaceOrientation {
case .portrait:
self = .up
Expand All @@ -34,7 +34,7 @@ extension CameraOrientation {
case .landscapeRight:
self = .left
case .unknown:
self = .up
return nil
@unknown default:
fatalError("UIInterfaceOrientation has unknown value: \(interfaceOrientation)")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ final class HybridDeviceOrientationManager: HybridOrientationManagerSpec {
if motionManager.isAccelerometerActive {
motionManager.stopAccelerometerUpdates()
}
if let currentOrientation {
onChanged(currentOrientation)
}

if motionManager.isAccelerometerAvailable {
motionManager.startAccelerometerUpdates(to: operationQueue) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,23 @@ final class HybridInterfaceOrientationManager: HybridOrientationManagerSpec {
// Start new listener (beginGeneratingDeviceOrientationNotifications() can be nested)
UIDevice.current.beginGeneratingDeviceOrientationNotifications()

let interfaceOrientation = UIApplication.shared.interfaceOrientation
if let orientation = CameraOrientation(interfaceOrientation: interfaceOrientation) {
self.currentOrientation = orientation
onChanged(orientation)
}

self.observer = NotificationCenter.default.addObserver(
forName: UIDevice.orientationDidChangeNotification,
object: nil,
queue: .main
) { [weak self] _ in
guard let self else { return }
let interfaceOrientation = UIApplication.shared.interfaceOrientation
guard interfaceOrientation != .unknown else {
guard let orientation = CameraOrientation(interfaceOrientation: interfaceOrientation) else {
logger.warning("UIInterfaceOrientation is .unknown!")
return
}
let orientation = CameraOrientation(interfaceOrientation: interfaceOrientation)
if self.currentOrientation != orientation {
logger.info("Interface orientation changed: \(orientation.stringValue)")
self.currentOrientation = orientation
Expand All @@ -60,6 +65,7 @@ final class HybridInterfaceOrientationManager: HybridOrientationManagerSpec {
if let observer = self.observer {
logger.info("Stopping interface orientation updates...")
NotificationCenter.default.removeObserver(observer)
self.observer = nil
UIDevice.current.endGeneratingDeviceOrientationNotifications()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export function useOrientation(
): CameraOrientation | undefined {
const orientationManager = useOrientationManager(source)
const currentOrientation = useRef(orientationManager?.currentOrientation)
currentOrientation.current = orientationManager?.currentOrientation

const subscribe = useCallback(
(onStoreChange: () => void) => {
Expand Down
Loading