• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.statusbar.phone
18 
19 import android.content.Context
20 import android.content.pm.PackageManager
21 import android.hardware.Sensor
22 import android.hardware.TriggerEvent
23 import android.hardware.TriggerEventListener
24 import com.android.keyguard.ActiveUnlockConfig
25 import com.android.keyguard.FaceAuthApiRequestReason
26 import com.android.keyguard.KeyguardUpdateMonitor
27 import com.android.keyguard.KeyguardUpdateMonitorCallback
28 import com.android.systemui.CoreStartable
29 import com.android.systemui.Dumpable
30 import com.android.systemui.dagger.SysUISingleton
31 import com.android.systemui.dump.DumpManager
32 import com.android.systemui.plugins.statusbar.StatusBarStateController
33 import com.android.systemui.util.Assert
34 import com.android.systemui.util.sensors.AsyncSensorManager
35 import java.io.PrintWriter
36 import javax.inject.Inject
37 
38 /**
39  * Triggers face auth on lift when the device is showing the lock screen. Only initialized
40  * if face auth is supported on the device. Not to be confused with the lift to wake gesture
41  * which is handled by {@link com.android.server.policy.PhoneWindowManager}.
42  */
43 @SysUISingleton
44 class KeyguardLiftController @Inject constructor(
45     private val context: Context,
46     private val statusBarStateController: StatusBarStateController,
47     private val asyncSensorManager: AsyncSensorManager,
48     private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
49     private val dumpManager: DumpManager
50 ) : Dumpable, CoreStartable {
51 
52     private val pickupSensor = asyncSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE)
53     private var isListening = false
54     private var bouncerVisible = false
55 
startnull56     override fun start() {
57         if (context.packageManager.hasSystemFeature(PackageManager.FEATURE_FACE)) {
58             init()
59         }
60     }
61 
initnull62     private fun init() {
63         dumpManager.registerDumpable(javaClass.name, this)
64         statusBarStateController.addCallback(statusBarStateListener)
65         keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
66         updateListeningState()
67     }
68 
69     private val listener: TriggerEventListener = object : TriggerEventListener() {
onTriggernull70         override fun onTrigger(event: TriggerEvent?) {
71             Assert.isMainThread()
72             // Not listening anymore since trigger events unregister themselves
73             isListening = false
74             updateListeningState()
75             keyguardUpdateMonitor.requestFaceAuth(
76                 FaceAuthApiRequestReason.PICK_UP_GESTURE_TRIGGERED
77             )
78             keyguardUpdateMonitor.requestActiveUnlock(
79                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE,
80                 "KeyguardLiftController")
81         }
82     }
83 
84     private val keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() {
onKeyguardBouncerFullyShowingChangednull85         override fun onKeyguardBouncerFullyShowingChanged(bouncer: Boolean) {
86             bouncerVisible = bouncer
87             updateListeningState()
88         }
89 
onKeyguardVisibilityChangednull90         override fun onKeyguardVisibilityChanged(visible: Boolean) {
91             updateListeningState()
92         }
93     }
94 
95     private val statusBarStateListener = object : StatusBarStateController.StateListener {
onDozingChangednull96         override fun onDozingChanged(isDozing: Boolean) {
97             updateListeningState()
98         }
99     }
100 
dumpnull101     override fun dump(pw: PrintWriter, args: Array<out String>) {
102         pw.println("KeyguardLiftController:")
103         pw.println("  pickupSensor: $pickupSensor")
104         pw.println("  isListening: $isListening")
105         pw.println("  bouncerVisible: $bouncerVisible")
106     }
107 
updateListeningStatenull108     private fun updateListeningState() {
109         if (pickupSensor == null) {
110             return
111         }
112         val onKeyguard = keyguardUpdateMonitor.isKeyguardVisible &&
113                 !statusBarStateController.isDozing
114 
115         val userId = KeyguardUpdateMonitor.getCurrentUser()
116         val isFaceEnabled = keyguardUpdateMonitor.isFaceAuthEnabledForUser(userId)
117         val shouldListen = (onKeyguard || bouncerVisible) && isFaceEnabled
118         if (shouldListen != isListening) {
119             isListening = shouldListen
120 
121             if (shouldListen) {
122                 asyncSensorManager.requestTriggerSensor(listener, pickupSensor)
123             } else {
124                 asyncSensorManager.cancelTriggerSensor(listener, pickupSensor)
125             }
126         }
127     }
128 }
129