Merge "Add historical logs to AnimatableClockView" into tm-qpr-dev am: b64614fc29 am: c52b4ed6ad

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20195508

Change-Id: Ia3b3f2d898eeb03af1242daeb893370be9309412
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Beverly Tai
2022-10-24 20:29:20 +00:00
committed by Automerger Merge Worker
8 changed files with 91 additions and 32 deletions

View File

@@ -18,6 +18,7 @@ import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.view.View
import com.android.systemui.plugins.annotations.ProvidesInterface
import com.android.systemui.plugins.log.LogBuffer
import java.io.PrintWriter
import java.util.Locale
import java.util.TimeZone
@@ -70,6 +71,9 @@ interface ClockController {
/** Optional method for dumping debug information */
fun dump(pw: PrintWriter) { }
/** Optional method for debug logging */
fun setLogBuffer(logBuffer: LogBuffer) { }
}
/** Interface for a specific clock face version rendered by the clock */

View File

@@ -62,7 +62,6 @@ android_library {
optimize: {
proguard_flags_files: ["proguard.flags"],
},
java_version: "1.8",
min_sdk_version: "current",
plugins: ["dagger2-compiler"],
}

View File

@@ -33,6 +33,8 @@ import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.animation.GlyphCallback
import com.android.systemui.animation.Interpolators
import com.android.systemui.animation.TextAnimator
import com.android.systemui.plugins.log.LogBuffer
import com.android.systemui.plugins.log.LogLevel.DEBUG
import com.android.systemui.shared.R
import java.io.PrintWriter
import java.util.Calendar
@@ -52,14 +54,8 @@ class AnimatableClockView @JvmOverloads constructor(
defStyleAttr: Int = 0,
defStyleRes: Int = 0
) : TextView(context, attrs, defStyleAttr, defStyleRes) {
private var lastMeasureCall: CharSequence? = null
private var lastDraw: CharSequence? = null
private var lastTextUpdate: CharSequence? = null
private var lastOnTextChanged: CharSequence? = null
private var lastInvalidate: CharSequence? = null
private var lastTimeZoneChange: CharSequence? = null
private var lastAnimationCall: CharSequence? = null
var tag: String = "UnnamedClockView"
var logBuffer: LogBuffer? = null
private val time = Calendar.getInstance()
@@ -136,6 +132,7 @@ class AnimatableClockView @JvmOverloads constructor(
override fun onAttachedToWindow() {
super.onAttachedToWindow()
logBuffer?.log(tag, DEBUG, "onAttachedToWindow")
refreshFormat()
}
@@ -151,27 +148,39 @@ class AnimatableClockView @JvmOverloads constructor(
time.timeInMillis = timeOverrideInMillis ?: System.currentTimeMillis()
contentDescription = DateFormat.format(descFormat, time)
val formattedText = DateFormat.format(format, time)
logBuffer?.log(tag, DEBUG,
{ str1 = formattedText?.toString() },
{ "refreshTime: new formattedText=$str1" }
)
// Setting text actually triggers a layout pass (because the text view is set to
// wrap_content width and TextView always relayouts for this). Avoid needless
// relayout if the text didn't actually change.
if (!TextUtils.equals(text, formattedText)) {
text = formattedText
logBuffer?.log(tag, DEBUG,
{ str1 = formattedText?.toString() },
{ "refreshTime: done setting new time text to: $str1" }
)
// Because the TextLayout may mutate under the hood as a result of the new text, we
// notify the TextAnimator that it may have changed and request a measure/layout. A
// crash will occur on the next invocation of setTextStyle if the layout is mutated
// without being notified TextInterpolator being notified.
if (layout != null) {
textAnimator?.updateLayout(layout)
logBuffer?.log(tag, DEBUG, "refreshTime: done updating textAnimator layout")
}
requestLayout()
lastTextUpdate = getTimestamp()
logBuffer?.log(tag, DEBUG, "refreshTime: after requestLayout")
}
}
fun onTimeZoneChanged(timeZone: TimeZone?) {
time.timeZone = timeZone
refreshFormat()
lastTimeZoneChange = "${getTimestamp()} timeZone=${time.timeZone}"
logBuffer?.log(tag, DEBUG,
{ str1 = timeZone?.toString() },
{ "onTimeZoneChanged newTimeZone=$str1" }
)
}
@SuppressLint("DrawAllocation")
@@ -185,27 +194,24 @@ class AnimatableClockView @JvmOverloads constructor(
} else {
animator.updateLayout(layout)
}
lastMeasureCall = getTimestamp()
logBuffer?.log(tag, DEBUG, "onMeasure")
}
override fun onDraw(canvas: Canvas) {
lastDraw = getTimestamp()
// Use textAnimator to render text if animation is enabled.
// Otherwise default to using standard draw functions.
if (isAnimationEnabled) {
// intentionally doesn't call super.onDraw here or else the text will be rendered twice
textAnimator?.draw(canvas)
} else {
super.onDraw(canvas)
}
logBuffer?.log(tag, DEBUG, "onDraw lastDraw")
}
override fun invalidate() {
super.invalidate()
lastInvalidate = getTimestamp()
}
private fun getTimestamp(): CharSequence {
return "${DateFormat.format("HH:mm:ss", System.currentTimeMillis())} text=$text"
logBuffer?.log(tag, DEBUG, "invalidate")
}
override fun onTextChanged(
@@ -215,7 +221,10 @@ class AnimatableClockView @JvmOverloads constructor(
lengthAfter: Int
) {
super.onTextChanged(text, start, lengthBefore, lengthAfter)
lastOnTextChanged = "${getTimestamp()}"
logBuffer?.log(tag, DEBUG,
{ str1 = text.toString() },
{ "onTextChanged text=$str1" }
)
}
fun setLineSpacingScale(scale: Float) {
@@ -229,7 +238,7 @@ class AnimatableClockView @JvmOverloads constructor(
}
fun animateAppearOnLockscreen() {
lastAnimationCall = "${getTimestamp()} call=animateAppearOnLockscreen"
logBuffer?.log(tag, DEBUG, "animateAppearOnLockscreen")
setTextStyle(
weight = dozingWeight,
textSize = -1f,
@@ -254,7 +263,7 @@ class AnimatableClockView @JvmOverloads constructor(
if (isAnimationEnabled && textAnimator == null) {
return
}
lastAnimationCall = "${getTimestamp()} call=animateFoldAppear"
logBuffer?.log(tag, DEBUG, "animateFoldAppear")
setTextStyle(
weight = lockScreenWeightInternal,
textSize = -1f,
@@ -281,7 +290,7 @@ class AnimatableClockView @JvmOverloads constructor(
// Skip charge animation if dozing animation is already playing.
return
}
lastAnimationCall = "${getTimestamp()} call=animateCharge"
logBuffer?.log(tag, DEBUG, "animateCharge")
val startAnimPhase2 = Runnable {
setTextStyle(
weight = if (isDozing()) dozingWeight else lockScreenWeight,
@@ -305,7 +314,7 @@ class AnimatableClockView @JvmOverloads constructor(
}
fun animateDoze(isDozing: Boolean, animate: Boolean) {
lastAnimationCall = "${getTimestamp()} call=animateDoze"
logBuffer?.log(tag, DEBUG, "animateDoze")
setTextStyle(
weight = if (isDozing) dozingWeight else lockScreenWeight,
textSize = -1f,
@@ -423,9 +432,12 @@ class AnimatableClockView @JvmOverloads constructor(
isSingleLineInternal && !use24HourFormat -> Patterns.sClockView12
else -> DOUBLE_LINE_FORMAT_12_HOUR
}
logBuffer?.log(tag, DEBUG,
{ str1 = format?.toString() },
{ "refreshFormat format=$str1" }
)
descFormat = if (use24HourFormat) Patterns.sClockView24 else Patterns.sClockView12
refreshTime()
}
@@ -434,15 +446,8 @@ class AnimatableClockView @JvmOverloads constructor(
pw.println(" measuredWidth=$measuredWidth")
pw.println(" measuredHeight=$measuredHeight")
pw.println(" singleLineInternal=$isSingleLineInternal")
pw.println(" lastTextUpdate=$lastTextUpdate")
pw.println(" lastOnTextChanged=$lastOnTextChanged")
pw.println(" lastInvalidate=$lastInvalidate")
pw.println(" lastMeasureCall=$lastMeasureCall")
pw.println(" lastDraw=$lastDraw")
pw.println(" lastTimeZoneChange=$lastTimeZoneChange")
pw.println(" currText=$text")
pw.println(" currTimeContextDesc=$contentDescription")
pw.println(" lastAnimationCall=$lastAnimationCall")
pw.println(" dozingWeightInternal=$dozingWeightInternal")
pw.println(" lockScreenWeightInternal=$lockScreenWeightInternal")
pw.println(" dozingColor=$dozingColor")
@@ -591,6 +596,7 @@ class AnimatableClockView @JvmOverloads constructor(
if (!clockView12Skel.contains("a")) {
sClockView12 = clockView12.replace("a".toRegex(), "").trim { it <= ' ' }
}
sClockView24 = DateFormat.getBestDateTimePattern(locale, clockView24Skel)
sCacheKey = key
}

View File

@@ -27,6 +27,7 @@ import com.android.systemui.plugins.ClockController
import com.android.systemui.plugins.ClockEvents
import com.android.systemui.plugins.ClockFaceController
import com.android.systemui.plugins.ClockFaceEvents
import com.android.systemui.plugins.log.LogBuffer
import com.android.systemui.shared.R
import java.io.PrintWriter
import java.util.Locale
@@ -86,9 +87,17 @@ class DefaultClockController(
events.onTimeTick()
}
override fun setLogBuffer(logBuffer: LogBuffer) {
smallClock.view.tag = "smallClockView"
largeClock.view.tag = "largeClockView"
smallClock.view.logBuffer = logBuffer
largeClock.view.logBuffer = logBuffer
}
open inner class DefaultClockFaceController(
override val view: AnimatableClockView,
) : ClockFaceController {
// MAGENTA is a placeholder, and will be assigned correctly in initialize
private var currentColor = Color.MAGENTA
private var isRegionDark = false

View File

@@ -34,7 +34,9 @@ import com.android.systemui.flags.Flags.REGION_SAMPLING
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.log.dagger.KeyguardClockLog
import com.android.systemui.plugins.ClockController
import com.android.systemui.plugins.log.LogBuffer
import com.android.systemui.shared.regionsampling.RegionSamplingInstance
import com.android.systemui.statusbar.policy.BatteryController
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback
@@ -66,12 +68,14 @@ open class ClockEventController @Inject constructor(
private val context: Context,
@Main private val mainExecutor: Executor,
@Background private val bgExecutor: Executor,
@KeyguardClockLog private val logBuffer: LogBuffer,
private val featureFlags: FeatureFlags
) {
var clock: ClockController? = null
set(value) {
field = value
if (value != null) {
value.setLogBuffer(logBuffer)
value.initialize(resources, dozeAmount, 0f)
updateRegionSamplers(value)
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.log.dagger
import javax.inject.Qualifier
/** A [com.android.systemui.plugins.log.LogBuffer] for keyguard clock logs. */
@Qualifier
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
annotation class KeyguardClockLog

View File

@@ -315,6 +315,16 @@ public class LogModule {
return factory.create("StatusBarNetworkControllerLog", 20);
}
/**
* Provides a {@link LogBuffer} for keyguard clock logs.
*/
@Provides
@SysUISingleton
@KeyguardClockLog
public static LogBuffer provideKeyguardClockLog(LogBufferFactory factory) {
return factory.create("KeyguardClockLog", 500);
}
/**
* Provides a {@link LogBuffer} for use by {@link com.android.keyguard.KeyguardUpdateMonitor}.
*/

View File

@@ -32,6 +32,7 @@ import com.android.systemui.plugins.ClockController
import com.android.systemui.plugins.ClockEvents
import com.android.systemui.plugins.ClockFaceController
import com.android.systemui.plugins.ClockFaceEvents
import com.android.systemui.plugins.log.LogBuffer
import com.android.systemui.statusbar.policy.BatteryController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.mockito.any
@@ -82,7 +83,7 @@ class ClockEventControllerTest : SysuiTestCase() {
@Mock private lateinit var parentView: View
@Mock private lateinit var transitionRepository: KeyguardTransitionRepository
private lateinit var repository: FakeKeyguardRepository
@Mock private lateinit var logBuffer: LogBuffer
private lateinit var underTest: ClockEventController
@Before
@@ -109,6 +110,7 @@ class ClockEventControllerTest : SysuiTestCase() {
context,
mainExecutor,
bgExecutor,
logBuffer,
featureFlags
)
underTest.clock = clock