1 /*
2  * 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.temporarydisplay
18 
19 import android.view.View
20 import com.android.systemui.log.LogBuffer
21 import com.android.systemui.log.core.LogLevel
22 
23 /** A logger for temporary view changes -- see [TemporaryViewDisplayController]. */
24 open class TemporaryViewLogger<T : TemporaryViewInfo>(
25     internal val buffer: LogBuffer,
26     internal val tag: String,
27 ) {
logViewExpirationnull28     fun logViewExpiration(info: T) {
29         buffer.log(
30             tag,
31             LogLevel.DEBUG,
32             {
33                 str1 = info.id
34                 str2 = info.windowTitle
35                 str3 = info.priority.name
36             },
37             { "View timeout has already expired; removing. id=$str1 window=$str2 priority=$str3" }
38         )
39     }
40 
logViewUpdatenull41     fun logViewUpdate(info: T) {
42         buffer.log(
43             tag,
44             LogLevel.DEBUG,
45             {
46                 str1 = info.id
47                 str2 = info.windowTitle
48                 str3 = info.priority.name
49             },
50             { "Existing view updated with new data. id=$str1 window=$str2 priority=$str3" }
51         )
52     }
53 
logViewAdditionDelayednull54     fun logViewAdditionDelayed(info: T) {
55         buffer.log(
56             tag,
57             LogLevel.DEBUG,
58             {
59                 str1 = info.id
60                 str2 = info.windowTitle
61                 str3 = info.priority.name
62             },
63             {
64                 "New view can't be displayed because higher priority view is currently " +
65                     "displayed. New view id=$str1 window=$str2 priority=$str3"
66             }
67         )
68     }
69 
70     /** Logs that we added the view with the given information. */
logViewAdditionnull71     fun logViewAddition(info: T) {
72         buffer.log(
73             tag,
74             LogLevel.DEBUG,
75             {
76                 str1 = info.id
77                 str2 = info.windowTitle
78                 str3 = info.priority.name
79             },
80             { "View added. id=$str1 window=$str2 priority=$str3" }
81         )
82     }
83 
84     /** Logs that there was a failure to animate the view in. */
logAnimateInFailurenull85     fun logAnimateInFailure() {
86         buffer.log(
87             tag,
88             LogLevel.WARNING,
89             {},
90             { "View's appearance animation failed. Forcing view display manually." },
91         )
92     }
93 
94     /** Logs that there was a failure to animate the view out. */
logAnimateOutFailurenull95     fun logAnimateOutFailure() {
96         buffer.log(
97             tag,
98             LogLevel.WARNING,
99             {},
100             { "View's disappearance animation failed." },
101         )
102     }
103 
logViewHiddennull104     fun logViewHidden(info: T) {
105         buffer.log(
106             tag,
107             LogLevel.DEBUG,
108             {
109                 str1 = info.id
110                 str2 = info.windowTitle
111                 str3 = info.priority.name
112             },
113             {
114                 "View hidden in favor of newer view. " +
115                     "Hidden view id=$str1 window=$str2 priority=$str3"
116             }
117         )
118     }
119 
120     /** Logs that we removed the view with the given [id] for the given [reason]. */
logViewRemovalnull121     fun logViewRemoval(id: String, reason: String) {
122         buffer.log(
123             tag,
124             LogLevel.DEBUG,
125             {
126                 str1 = reason
127                 str2 = id
128             },
129             { "View with id=$str2 is removed due to: $str1" }
130         )
131     }
132 
133     /** Logs that we ignored removal of the view with the given [id]. */
logViewRemovalIgnorednull134     fun logViewRemovalIgnored(id: String, reason: String) {
135         buffer.log(
136             tag,
137             LogLevel.DEBUG,
138             {
139                 str1 = reason
140                 str2 = id
141             },
142             { "Removal of view with id=$str2 is ignored because $str1" }
143         )
144     }
145 
logViewAddedToWindowManagernull146     fun logViewAddedToWindowManager(info: T, view: View) {
147         buffer.log(
148             tag,
149             LogLevel.DEBUG,
150             {
151                 str1 = info.id
152                 str2 = info.windowTitle
153                 str3 = view.javaClass.name
154                 int1 = view.getIdForLogging()
155             },
156             {
157                 "Adding view to window manager. " +
158                     "id=$str1 window=$str2 view=$str3(id=${Integer.toHexString(int1)})"
159             }
160         )
161     }
162 
logViewRemovedFromWindowManagernull163     fun logViewRemovedFromWindowManager(info: T, view: View, isReinflation: Boolean = false) {
164         buffer.log(
165             tag,
166             LogLevel.DEBUG,
167             {
168                 str1 = info.id
169                 str2 = info.windowTitle
170                 str3 = view.javaClass.name
171                 int1 = view.getIdForLogging()
172                 bool1 = isReinflation
173             },
174             {
175                 "Removing view from window manager${if (bool1) " due to reinflation" else ""}. " +
176                     "id=$str1 window=$str2 view=$str3(id=${Integer.toHexString(int1)})"
177             }
178         )
179     }
180 
181     companion object {
getIdForLoggingnull182         private fun View.getIdForLogging(): Int {
183             // The identityHashCode is guaranteed to be constant for the lifetime of the object.
184             return System.identityHashCode(this)
185         }
186     }
187 }
188