• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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.plugins.clocks
18 
19 import android.view.View
20 import android.view.View.MeasureSpec
21 import com.android.systemui.log.core.LogLevel
22 import com.android.systemui.log.core.LogcatOnlyMessageBuffer
23 import com.android.systemui.log.core.Logger
24 import com.android.systemui.log.core.MessageBuffer
25 import kotlin.math.abs
26 
27 class ClockLogger(private val view: View?, buffer: MessageBuffer, tag: String) :
28     Logger(buffer, tag) {
29 
30     private var loggedAlpha = 1000f
31     private val isDrawn: Boolean
32         get() = ((view?.mPrivateFlags ?: 0x0) and 0x20 /* PFLAG_DRAWN */) > 0
33 
invalidatenull34     fun invalidate() {
35         if (isDrawn && view?.visibility == View.VISIBLE) {
36             d("invalidate()")
37         }
38     }
39 
refreshTimenull40     fun refreshTime() {
41         d("refreshTime()")
42     }
43 
requestLayoutnull44     fun requestLayout() {
45         if (view?.isLayoutRequested() == false) {
46             d("requestLayout()")
47         }
48     }
49 
onMeasurenull50     fun onMeasure(widthSpec: Int, heightSpec: Int) {
51         d({ "onMeasure(${getSpecText(int1)}, ${getSpecText(int2)})" }) {
52             int1 = widthSpec
53             int2 = heightSpec
54         }
55     }
56 
onLayoutnull57     fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
58         d({ "onLayout($bool1, ${VRect.fromLong(long1)})" }) {
59             bool1 = changed
60             long1 = VRect(left, top, right, bottom).toLong()
61         }
62     }
63 
onDrawnull64     fun onDraw() {
65         d("onDraw()")
66     }
67 
onDrawnull68     fun onDraw(str: String?) {
69         d({ "onDraw(${escapeTime(str1)})" }) { str1 = str ?: "" }
70     }
71 
onDrawnull72     fun onDraw(lsStr: String?, aodStr: String?) {
73         d({ "onDraw(ls = ${escapeTime(str1)}, aod = ${escapeTime(str2)}" }) {
74             str1 = lsStr
75             str2 = aodStr
76         }
77     }
78 
setVisibilitynull79     fun setVisibility(visibility: Int) {
80         if (visibility != view?.visibility) {
81             d({ "setVisibility(${getVisText(int1)})" }) { int1 = visibility }
82         }
83     }
84 
setAlphanull85     fun setAlpha(alpha: Float) {
86         val delta = if (alpha <= 0f || alpha >= 1f) 0.001f else 0.5f
87         if (abs(loggedAlpha - alpha) >= delta) {
88             loggedAlpha = alpha
89             d({ "setAlpha($double1)" }) { double1 = alpha.toDouble() }
90         }
91     }
92 
updateAxesnull93     fun updateAxes(lsFVar: String, aodFVar: String, isAnimated: Boolean) {
94         i({ "updateAxes(LS = $str1, AOD = $str2, isAnimated=$bool1)" }) {
95             str1 = lsFVar
96             str2 = aodFVar
97             bool1 = isAnimated
98         }
99     }
100 
onViewAddednull101     fun onViewAdded(child: View) {
102         d({ "onViewAdded($str1 @$int1)" }) {
103             str1 = child::class.simpleName!!
104             int1 = child.id
105         }
106     }
107 
animateDozenull108     fun animateDoze(isDozing: Boolean, isAnimated: Boolean) {
109         d({ "animateDoze(isDozing=$bool1, isAnimated=$bool2)" }) {
110             bool1 = isDozing
111             bool2 = isAnimated
112         }
113     }
114 
animateChargenull115     fun animateCharge() {
116         d("animateCharge()")
117     }
118 
animateFidgetnull119     fun animateFidget(x: Float, y: Float) {
120         d({ "animateFidget(${VPointF.fromLong(long1)})" }) { long1 = VPointF(x, y).toLong() }
121     }
122 
123     companion object {
124         // Used when MessageBuffers are not provided by the host application
125         val DEFAULT_MESSAGE_BUFFER = LogcatOnlyMessageBuffer(LogLevel.INFO)
126 
127         // Debug is primarially used for tests, but can also be used for tracking down hard issues.
128         val DEBUG_MESSAGE_BUFFER = LogcatOnlyMessageBuffer(LogLevel.DEBUG)
129 
130         // Only intended for use during initialization steps before the logger is initialized
131         val INIT_LOGGER = ClockLogger(null, LogcatOnlyMessageBuffer(LogLevel.ERROR), "CLOCK_INIT")
132 
133         @JvmStatic
getVisTextnull134         fun getVisText(visibility: Int): String {
135             return when (visibility) {
136                 View.GONE -> "GONE"
137                 View.INVISIBLE -> "INVISIBLE"
138                 View.VISIBLE -> "VISIBLE"
139                 else -> "$visibility"
140             }
141         }
142 
143         @JvmStatic
getSpecTextnull144         fun getSpecText(spec: Int): String {
145             val size = MeasureSpec.getSize(spec)
146             val mode = MeasureSpec.getMode(spec)
147             val modeText =
148                 when (mode) {
149                     MeasureSpec.EXACTLY -> "EXACTLY"
150                     MeasureSpec.AT_MOST -> "AT MOST"
151                     MeasureSpec.UNSPECIFIED -> "UNSPECIFIED"
152                     else -> "$mode"
153                 }
154             return "($size, $modeText)"
155         }
156 
157         @JvmStatic
escapeTimenull158         fun escapeTime(timeStr: String?): String? {
159             return timeStr?.replace("\n", "\\n")
160         }
161     }
162 }
163