1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.biometrics.fingerprint2.domain.interactor 18 19 import android.content.Context 20 import android.view.OrientationEventListener 21 import com.android.internal.R 22 import kotlinx.coroutines.channels.awaitClose 23 import kotlinx.coroutines.flow.Flow 24 import kotlinx.coroutines.flow.callbackFlow 25 import kotlinx.coroutines.flow.map 26 import kotlinx.coroutines.flow.transform 27 28 /** Interactor which provides information about orientation */ 29 interface OrientationInteractor { 30 /** A flow that contains the information about the orientation changing */ 31 val orientation: Flow<Int> 32 /** 33 * This indicates the surface rotation that hte view is currently in. For instance its possible to 34 * rotate a view to 90 degrees but for it to still be portrait mode. In this case, this flow 35 * should emit that we are in rotation 0 (SurfaceView.Rotation_0) 36 */ 37 val rotation: Flow<Int> 38 /** 39 * A flow that contains the rotation info matched against the def [config_reverseDefaultRotation] 40 */ 41 val rotationFromDefault: Flow<Int> 42 43 /** 44 * A Helper function that computes rotation if device is in 45 * [R.bool.config_reverseDefaultConfigRotation] 46 */ getRotationFromDefaultnull47 fun getRotationFromDefault(rotation: Int): Int 48 } 49 50 class OrientationInteractorImpl(private val context: Context) : OrientationInteractor { 51 52 override val orientation: Flow<Int> = callbackFlow { 53 val orientationEventListener = 54 object : OrientationEventListener(context) { 55 override fun onOrientationChanged(orientation: Int) { 56 trySend(orientation) 57 } 58 } 59 orientationEventListener.enable() 60 awaitClose { orientationEventListener.disable() } 61 } 62 63 override val rotation: Flow<Int> = orientation.transform { emit(context.display.rotation) } 64 65 override val rotationFromDefault: Flow<Int> = rotation.map { getRotationFromDefault(it) } 66 67 override fun getRotationFromDefault(rotation: Int): Int { 68 val isReverseDefaultRotation = 69 context.resources.getBoolean(R.bool.config_reverseDefaultRotation) 70 return if (isReverseDefaultRotation) { 71 (rotation + 1) % 4 72 } else { 73 rotation 74 } 75 } 76 } 77