• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.systemui.biometrics
18 
19 import android.content.Context
20 import android.hardware.display.DisplayManager
21 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
22 import android.os.Handler
23 import android.view.Surface
24 import com.android.systemui.biometrics.BiometricDisplayListener.SensorType.Generic
25 
26 /**
27  * A listener for keeping overlays for biometric sensors aligned with the physical device
28  * device's screen. The [onChanged] will be dispatched on the [handler]
29  * whenever a relevant change to the device's configuration (orientation, fold, display change,
30  * etc.) may require the UI to change for the given [sensorType].
31  */
32 class BiometricDisplayListener(
33     private val context: Context,
34     private val displayManager: DisplayManager,
35     private val handler: Handler,
36     private val sensorType: SensorType = SensorType.Generic,
37     private val onChanged: () -> Unit
38 ) : DisplayManager.DisplayListener {
39 
40     private var lastRotation = Surface.ROTATION_0
41 
onDisplayAddednull42     override fun onDisplayAdded(displayId: Int) {}
onDisplayRemovednull43     override fun onDisplayRemoved(displayId: Int) {}
onDisplayChangednull44     override fun onDisplayChanged(displayId: Int) {
45         val rotationChanged = didRotationChange()
46 
47         when (sensorType) {
48             is SensorType.SideFingerprint -> onChanged()
49             else -> {
50                 if (rotationChanged) {
51                     onChanged()
52                 }
53             }
54         }
55     }
56 
didRotationChangenull57     private fun didRotationChange(): Boolean {
58         val rotation = context.display?.rotation ?: return false
59         val last = lastRotation
60         lastRotation = rotation
61         return last != rotation
62     }
63 
64     /** Listen for changes. */
enablenull65     fun enable() {
66         lastRotation = context.display?.rotation ?: Surface.ROTATION_0
67         displayManager.registerDisplayListener(
68             this,
69             handler,
70             DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
71         )
72     }
73 
74     /** Stop listening for changes. */
disablenull75     fun disable() {
76         displayManager.unregisterDisplayListener(this)
77     }
78 
79     /**
80      * Type of sensor to determine what kind of display changes require layouts.
81      *
82      * The [Generic] type should be used in cases where the modality can vary, such as
83      * biometric prompt (and this object will likely change as multi-mode auth is added).
84      */
85     sealed class SensorType {
86         object Generic : SensorType()
87         object UnderDisplayFingerprint : SensorType()
88         data class SideFingerprint(
89             val properties: FingerprintSensorPropertiesInternal
90         ) : SensorType()
91     }
92 }
93