1 /*
2  * Copyright (C) 2023 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.view.MotionEvent
20 import com.android.systemui.log.LogBuffer
21 import com.android.systemui.log.core.LogLevel
22 
23 private const val TAG = "systemui.shade.touch"
24 
25 /**
26  * A logger for tracking touch dispatching in the shade view hierarchy. The purpose of this logger
27  * is to passively observe dispatchTouchEvent calls in order to see which subtrees of the shade are
28  * handling touches. Additionally, some touches may be passively observed for views near the top of
29  * the shade hierarchy that cannot intercept touches, i.e. scrims. The usage of static methods for
30  * logging is sub-optimal in many ways, but it was selected in this case to make usage of this
31  * non-function diagnostic code as low friction as possible.
32  */
33 class TouchLogger {
34     companion object {
35         private var touchLogger: DispatchTouchLogger? = null
36 
37         @JvmStatic
logTouchesTonull38         fun logTouchesTo(buffer: LogBuffer) {
39             touchLogger = DispatchTouchLogger(buffer)
40         }
41 
42         @JvmStatic
logDispatchTouchnull43         fun logDispatchTouch(viewTag: String, ev: MotionEvent, result: Boolean): Boolean {
44             touchLogger?.logDispatchTouch(viewTag, ev, result)
45             return result
46         }
47     }
48 }
49 
50 /** Logs touches. */
51 private class DispatchTouchLogger(private val buffer: LogBuffer) {
logDispatchTouchnull52     fun logDispatchTouch(viewTag: String, ev: MotionEvent, result: Boolean) {
53         // NOTE: never log position of touches for security purposes
54         buffer.log(
55             TAG,
56             LogLevel.DEBUG,
57             {
58                 str1 = viewTag
59                 int1 = ev.action
60                 long1 = ev.downTime
61                 bool1 = result
62             },
63             { "Touch: view=$str1, type=${typeToString(int1)}, downtime=$long1, result=$bool1" }
64         )
65     }
66 
typeToStringnull67     private fun typeToString(type: Int): String {
68         return when (type) {
69             MotionEvent.ACTION_DOWN -> "DOWN"
70             MotionEvent.ACTION_UP -> "UP"
71             MotionEvent.ACTION_MOVE -> "MOVE"
72             MotionEvent.ACTION_CANCEL -> "CANCEL"
73             MotionEvent.ACTION_POINTER_DOWN -> "POINTER_DOWN"
74             MotionEvent.ACTION_POINTER_UP -> "POINTER_UP"
75             else -> "OTHER"
76         }
77     }
78 }
79