• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2022 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.shade
18 
19 import android.hardware.display.AmbientDisplayConfiguration
20 import android.os.PowerManager
21 import android.os.SystemClock
22 import android.provider.Settings
23 import android.view.GestureDetector
24 import android.view.MotionEvent
25 import com.android.systemui.Dumpable
26 import com.android.systemui.dock.DockManager
27 import com.android.systemui.dump.DumpManager
28 import com.android.systemui.plugins.FalsingManager
29 import com.android.systemui.plugins.FalsingManager.LOW_PENALTY
30 import com.android.systemui.plugins.statusbar.StatusBarStateController
31 import com.android.systemui.settings.UserTracker
32 import com.android.systemui.statusbar.phone.CentralSurfaces
33 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
34 import com.android.systemui.tuner.TunerService
35 import com.android.systemui.tuner.TunerService.Tunable
36 import java.io.PrintWriter
37 import javax.inject.Inject
38 
39 /**
40  * If tap and/or double tap to wake is enabled, this gestureListener will wake the display on
41  * tap/double tap when the device is pulsing (AoD2) or transitioning to AoD. Taps are gated by the
42  * proximity sensor and falsing manager.
43  *
44  * Touches go through the [NotificationShadeWindowViewController] when the device is dozing but the
45  * screen is still ON and not in the true AoD display state. When the device is in the true AoD
46  * display state, wake-ups are handled by [com.android.systemui.doze.DozeSensors].
47  */
48 @CentralSurfacesComponent.CentralSurfacesScope
49 class PulsingGestureListener @Inject constructor(
50         private val notificationShadeWindowView: NotificationShadeWindowView,
51         private val falsingManager: FalsingManager,
52         private val dockManager: DockManager,
53         private val centralSurfaces: CentralSurfaces,
54         private val ambientDisplayConfiguration: AmbientDisplayConfiguration,
55         private val statusBarStateController: StatusBarStateController,
56         private val shadeLogger: ShadeLogger,
57         userTracker: UserTracker,
58         tunerService: TunerService,
59         dumpManager: DumpManager
60 ) : GestureDetector.SimpleOnGestureListener(), Dumpable {
61     private var doubleTapEnabled = false
62     private var singleTapEnabled = false
63 
64     init {
65         val tunable = Tunable { key: String?, _: String? ->
66             when (key) {
67                 Settings.Secure.DOZE_DOUBLE_TAP_GESTURE ->
68                     doubleTapEnabled = ambientDisplayConfiguration.doubleTapGestureEnabled(
69                             userTracker.userId)
70                 Settings.Secure.DOZE_TAP_SCREEN_GESTURE ->
71                     singleTapEnabled = ambientDisplayConfiguration.tapGestureEnabled(
72                             userTracker.userId)
73             }
74         }
75         tunerService.addTunable(tunable,
76                 Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
77                 Settings.Secure.DOZE_TAP_SCREEN_GESTURE)
78 
79         dumpManager.registerDumpable(this)
80     }
81 
82     override fun onSingleTapUp(e: MotionEvent): Boolean {
83         val isNotDocked = !dockManager.isDocked
84         shadeLogger.logSingleTapUp(statusBarStateController.isDozing, singleTapEnabled, isNotDocked)
85         if (statusBarStateController.isDozing && singleTapEnabled && isNotDocked) {
86             val proximityIsNotNear = !falsingManager.isProximityNear
87             val isNotAFalseTap = !falsingManager.isFalseTap(LOW_PENALTY)
88             shadeLogger.logSingleTapUpFalsingState(proximityIsNotNear, isNotAFalseTap)
89             if (proximityIsNotNear && isNotAFalseTap) {
90                 shadeLogger.d("Single tap handled, requesting centralSurfaces.wakeUpIfDozing")
91                 centralSurfaces.wakeUpIfDozing(
92                     SystemClock.uptimeMillis(),
93                     notificationShadeWindowView,
94                     "PULSING_SINGLE_TAP",
95                     PowerManager.WAKE_REASON_TAP
96                 )
97             }
98             return true
99         }
100         shadeLogger.d("onSingleTapUp event ignored")
101         return false
102     }
103 
104     /**
105      * Receives [MotionEvent.ACTION_DOWN], [MotionEvent.ACTION_MOVE], and [MotionEvent.ACTION_UP]
106      * motion events for a double tap.
107      */
108     override fun onDoubleTapEvent(e: MotionEvent): Boolean {
109         // React to the [MotionEvent.ACTION_UP] event after double tap is detected. Falsing
110         // checks MUST be on the ACTION_UP event.
111         if (e.actionMasked == MotionEvent.ACTION_UP &&
112                 statusBarStateController.isDozing &&
113                 (doubleTapEnabled || singleTapEnabled) &&
114                 !falsingManager.isProximityNear &&
115                 !falsingManager.isFalseDoubleTap
116         ) {
117             centralSurfaces.wakeUpIfDozing(
118                     SystemClock.uptimeMillis(),
119                     notificationShadeWindowView,
120                     "PULSING_DOUBLE_TAP",
121                     PowerManager.WAKE_REASON_TAP
122             )
123             return true
124         }
125         return false
126     }
127 
128     override fun dump(pw: PrintWriter, args: Array<out String>) {
129         pw.println("singleTapEnabled=$singleTapEnabled")
130         pw.println("doubleTapEnabled=$doubleTapEnabled")
131         pw.println("isDocked=${dockManager.isDocked}")
132         pw.println("isProxCovered=${falsingManager.isProximityNear}")
133     }
134 }
135