Merge "Add historical logs to AnimatableClockView" into tm-qpr-dev am: b64614fc29
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20195508 Change-Id: I953b6980117dee80c0318829c8cddd8977b3a015 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -62,7 +62,6 @@ android_library {
|
||||
optimize: {
|
||||
proguard_flags_files: ["proguard.flags"],
|
||||
},
|
||||
java_version: "1.8",
|
||||
min_sdk_version: "current",
|
||||
plugins: ["dagger2-compiler"],
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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}.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user