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.log
18 
19 import android.graphics.Point
20 import android.graphics.Rect
21 import android.graphics.RectF
22 import androidx.core.graphics.toRectF
23 import com.android.systemui.dagger.SysUISingleton
24 import com.android.systemui.log.core.LogLevel.DEBUG
25 import com.android.systemui.log.core.LogLevel.ERROR
26 import com.android.systemui.log.core.LogLevel.INFO
27 import com.android.systemui.log.dagger.ScreenDecorationsLog
28 import com.google.errorprone.annotations.CompileTimeConstant
29 import javax.inject.Inject
30 
31 private const val TAG = "ScreenDecorationsLog"
32 
33 /**
34  * Helper class for logging for [com.android.systemui.ScreenDecorations]
35  *
36  * To enable logcat echoing for an entire buffer:
37  * ```
38  *   adb shell settings put global systemui/buffer/ScreenDecorationsLog <logLevel>
39  *
40  * ```
41  */
42 @SysUISingleton
43 class ScreenDecorationsLogger
44 @Inject
45 constructor(
46     @ScreenDecorationsLog private val logBuffer: LogBuffer,
47 ) {
48     fun cameraProtectionBoundsForScanningOverlay(bounds: Rect) {
49         logBuffer.log(
50             TAG,
51             DEBUG,
52             { str1 = bounds.toShortString() },
53             { "Face scanning overlay present camera protection bounds: $str1" }
54         )
55     }
56 
57     fun hwcLayerCameraProtectionBounds(bounds: Rect) {
58         logBuffer.log(
59             TAG,
60             DEBUG,
61             { str1 = bounds.toShortString() },
62             { "Hwc layer present camera protection bounds: $str1" }
63         )
64     }
65 
66     fun dcvCameraBounds(id: Int, bounds: Rect) {
67         logBuffer.log(
68             TAG,
69             DEBUG,
70             {
71                 str1 = bounds.toShortString()
72                 int1 = id
73             },
74             { "DisplayCutoutView id=$int1 present, camera protection bounds: $str1" }
75         )
76     }
77 
78     fun cutoutViewNotInitialized() {
79         logBuffer.log(TAG, ERROR, "CutoutView not initialized showCameraProtection")
80     }
81 
82     fun boundingRect(boundingRectangle: RectF, context: String) {
83         logBuffer.log(
84             TAG,
85             DEBUG,
86             {
87                 str1 = context
88                 str2 = boundingRectangle.toShortString()
89             },
90             { "Bounding rect $str1 : $str2" }
91         )
92     }
93 
94     fun boundingRect(boundingRectangle: Rect, context: String) {
95         boundingRect(boundingRectangle.toRectF(), context)
96     }
97 
98     fun onMeasureDimensions(
99         widthMeasureSpec: Int,
100         heightMeasureSpec: Int,
101         measuredWidth: Int,
102         measuredHeight: Int
103     ) {
104         logBuffer.log(
105             TAG,
106             DEBUG,
107             {
108                 long1 = widthMeasureSpec.toLong()
109                 long2 = heightMeasureSpec.toLong()
110                 int1 = measuredWidth
111                 int2 = measuredHeight
112             },
113             {
114                 "Face scanning animation: widthMeasureSpec: $long1 measuredWidth: $int1, " +
115                     "heightMeasureSpec: $long2 measuredHeight: $int2"
116             }
117         )
118     }
119 
120     fun faceSensorLocation(faceSensorLocation: Point?) {
121         logBuffer.log(
122             TAG,
123             DEBUG,
124             {
125                 int1 = faceSensorLocation?.y?.times(2) ?: 0
126                 str1 = "$faceSensorLocation"
127             },
128             { "Reinflating view: Face sensor location: $str1, faceScanningHeight: $int1" }
129         )
130     }
131 
132     fun onSensorLocationChanged() {
133         logBuffer.log(TAG, DEBUG, "AuthControllerCallback in ScreenDecorations triggered")
134     }
135 
136     fun cameraProtectionShownOrHidden(
137         faceDetectionRunning: Boolean,
138         biometricPromptShown: Boolean,
139         requestedState: Boolean,
140         currentlyShowing: Boolean
141     ) {
142         logBuffer.log(
143             TAG,
144             DEBUG,
145             {
146                 bool1 = faceDetectionRunning
147                 bool2 = biometricPromptShown
148                 bool3 = requestedState
149                 bool4 = currentlyShowing
150             },
151             {
152                 "isFaceDetectionRunning: $bool1, " +
153                     "isBiometricPromptShowing: $bool2, " +
154                     "requestedState: $bool3, " +
155                     "currentState: $bool4"
156             }
157         )
158     }
159 
160     fun biometricEvent(@CompileTimeConstant info: String) {
161         logBuffer.log(TAG, DEBUG, info)
162     }
163 
164     fun cameraProtectionEvent(@CompileTimeConstant cameraProtectionEvent: String) {
165         logBuffer.log(TAG, DEBUG, cameraProtectionEvent)
166     }
167 
168     fun logRotationChangeDeferred(currentRot: Int, newRot: Int) {
169         logBuffer.log(
170             TAG,
171             INFO,
172             {
173                 int1 = currentRot
174                 int2 = newRot
175             },
176             { "Rotation changed, deferring $int2, staying at $int2" },
177         )
178     }
179 
180     fun logRotationChanged(oldRot: Int, newRot: Int) {
181         logBuffer.log(
182             TAG,
183             INFO,
184             {
185                 int1 = oldRot
186                 int2 = newRot
187             },
188             { "Rotation changed from $int1 to $int2" }
189         )
190     }
191 
192     fun logDisplaySizeChanged(currentSize: Point, newSize: Point) {
193         logBuffer.log(
194             TAG,
195             INFO,
196             {
197                 str1 = currentSize.flattenToString()
198                 str2 = newSize.flattenToString()
199             },
200             { "Resolution changed, deferring size change to $str2, staying at $str1" },
201         )
202     }
203 
204     fun logUserSwitched(newUser: Int) {
205         logBuffer.log(
206             TAG,
207             DEBUG,
208             { int1 = newUser },
209             { "UserSwitched newUserId=$int1. Updating color inversion setting" },
210         )
211     }
212 }
213