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