Loading packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt +4 −3 Original line number Diff line number Diff line Loading @@ -85,7 +85,8 @@ class DefaultClockController( animations = DefaultClockAnimations(dozeFraction, foldFraction) events.onColorPaletteChanged(resources) events.onTimeZoneChanged(TimeZone.getDefault()) events.onTimeTick() smallClock.events.onTimeTick() largeClock.events.onTimeTick() } open inner class DefaultClockFaceController( Loading @@ -109,6 +110,8 @@ class DefaultClockController( override val events = object : ClockFaceEvents { override fun onTimeTick() = view.refreshTime() override fun onRegionDarknessChanged(isRegionDark: Boolean) { this@DefaultClockFaceController.isRegionDark = isRegionDark updateColor() Loading Loading @@ -169,8 +172,6 @@ class DefaultClockController( } inner class DefaultClockEvents : ClockEvents { override fun onTimeTick() = clocks.forEach { it.refreshTime() } override fun onTimeFormatChanged(is24Hr: Boolean) = clocks.forEach { it.refreshFormat(is24Hr) } Loading packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt +16 −4 Original line number Diff line number Diff line Loading @@ -66,7 +66,8 @@ interface ClockController { events.onColorPaletteChanged(resources) animations.doze(dozeFraction) animations.fold(foldFraction) events.onTimeTick() smallClock.events.onTimeTick() largeClock.events.onTimeTick() } /** Optional method for dumping debug information */ Loading @@ -87,9 +88,6 @@ interface ClockFaceController { /** Events that should call when various rendering parameters change */ interface ClockEvents { /** Call every time tick */ fun onTimeTick() {} /** Call whenever timezone changes */ fun onTimeZoneChanged(timeZone: TimeZone) {} Loading Loading @@ -131,6 +129,13 @@ interface ClockAnimations { /** Events that have specific data about the related face */ interface ClockFaceEvents { /** Call every time tick */ fun onTimeTick() {} /** Expected interval between calls to onTimeTick. Can always reduce to PER_MINUTE in AOD. */ val tickRate: ClockTickRate get() = ClockTickRate.PER_MINUTE /** Region Darkness specific to the clock face */ fun onRegionDarknessChanged(isDark: Boolean) {} Loading @@ -150,6 +155,13 @@ interface ClockFaceEvents { fun onTargetRegionChanged(targetRegion: Rect?) {} } /** Tick rates for clocks */ enum class ClockTickRate(val value: Int) { PER_MINUTE(2), // Update the clock once per minute. PER_SECOND(1), // Update the clock once per second. PER_FRAME(0), // Update the clock every second. } /** Some data about a clock design */ data class ClockMetadata( val clockId: ClockId, Loading packages/SystemUI/src/com/android/keyguard/ClockEventController.kt +91 −7 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.text.format.DateFormat import android.util.TypedValue import android.view.View import android.widget.FrameLayout import android.view.ViewTreeObserver import androidx.annotation.VisibleForTesting import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle Loading @@ -42,12 +43,15 @@ import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.log.dagger.KeyguardSmallClockLog import com.android.systemui.log.dagger.KeyguardLargeClockLog import com.android.systemui.plugins.ClockController import com.android.systemui.plugins.ClockFaceController import com.android.systemui.plugins.ClockTickRate import com.android.systemui.plugins.log.LogBuffer import com.android.systemui.plugins.log.LogLevel.DEBUG import com.android.systemui.shared.regionsampling.RegionSampler import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.concurrency.DelayableExecutor import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DisposableHandle import kotlinx.coroutines.Job Loading @@ -72,7 +76,7 @@ open class ClockEventController @Inject constructor( private val configurationController: ConfigurationController, @Main private val resources: Resources, private val context: Context, @Main private val mainExecutor: Executor, @Main private val mainExecutor: DelayableExecutor, @Background private val bgExecutor: Executor, @KeyguardSmallClockLog private val smallLogBuffer: LogBuffer?, @KeyguardLargeClockLog private val largeLogBuffer: LogBuffer?, Loading @@ -94,6 +98,7 @@ open class ClockEventController @Inject constructor( clock?.largeClock?.view?.addOnLayoutChangeListener(mLayoutChangedListener) } updateFontSizes() updateTimeListeners() } } Loading Loading @@ -208,6 +213,10 @@ open class ClockEventController @Inject constructor( } var regionSampler: RegionSampler? = null var smallTimeListener: TimeListener? = null var largeTimeListener: TimeListener? = null val shouldTimeListenerRun: Boolean get() = isKeyguardVisible && dozeAmount < DOZE_TICKRATE_THRESHOLD private var smallClockIsDark = true private var largeClockIsDark = true Loading Loading @@ -246,6 +255,9 @@ open class ClockEventController @Inject constructor( clock?.animations?.doze(if (isDozing) 1f else 0f) } } smallTimeListener?.update(shouldTimeListenerRun) largeTimeListener?.update(shouldTimeListenerRun) } override fun onTimeFormatChanged(timeFormat: String) { Loading Loading @@ -285,6 +297,8 @@ open class ClockEventController @Inject constructor( } } } smallTimeListener?.update(shouldTimeListenerRun) largeTimeListener?.update(shouldTimeListenerRun) } fun unregisterListeners() { Loading @@ -299,6 +313,25 @@ open class ClockEventController @Inject constructor( batteryController.removeCallback(batteryCallback) keyguardUpdateMonitor.removeCallback(keyguardUpdateMonitorCallback) regionSampler?.stopRegionSampler() smallTimeListener?.stop() largeTimeListener?.stop() } private fun updateTimeListeners() { smallTimeListener?.stop() largeTimeListener?.stop() smallTimeListener = null largeTimeListener = null clock?.smallClock?.let { smallTimeListener = TimeListener(it, mainExecutor) smallTimeListener?.update(shouldTimeListenerRun) } clock?.largeClock?.let { largeTimeListener = TimeListener(it, mainExecutor) largeTimeListener?.update(shouldTimeListenerRun) } } private fun updateFontSizes() { Loading @@ -308,12 +341,18 @@ open class ClockEventController @Inject constructor( resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat()) } private fun handleDoze(doze: Float) { dozeAmount = doze clock?.animations?.doze(dozeAmount) smallTimeListener?.update(doze < DOZE_TICKRATE_THRESHOLD) largeTimeListener?.update(doze < DOZE_TICKRATE_THRESHOLD) } @VisibleForTesting internal fun listenForDozeAmount(scope: CoroutineScope): Job { return scope.launch { keyguardInteractor.dozeAmount.collect { dozeAmount = it clock?.animations?.doze(dozeAmount) handleDoze(it) } } } Loading @@ -322,8 +361,7 @@ open class ClockEventController @Inject constructor( internal fun listenForDozeAmountTransition(scope: CoroutineScope): Job { return scope.launch { keyguardTransitionInteractor.dozeAmountTransition.collect { dozeAmount = it.value clock?.animations?.doze(dozeAmount) handleDoze(it.value) } } } Loading @@ -338,8 +376,7 @@ open class ClockEventController @Inject constructor( keyguardTransitionInteractor.anyStateToAodTransition.filter { it.transitionState == TransitionState.FINISHED }.collect { dozeAmount = 1f clock?.animations?.doze(dozeAmount) handleDoze(1f) } } } Loading @@ -359,7 +396,54 @@ open class ClockEventController @Inject constructor( } } class TimeListener(val clockFace: ClockFaceController, val executor: DelayableExecutor) { val predrawListener = ViewTreeObserver.OnPreDrawListener { clockFace.events.onTimeTick() true } val secondsRunnable = object : Runnable { override fun run() { if (!isRunning) { return } executor.executeDelayed(this, 990) clockFace.events.onTimeTick() } } var isRunning: Boolean = false private set fun start() { if (isRunning) { return } isRunning = true when (clockFace.events.tickRate) { ClockTickRate.PER_MINUTE -> {/* Handled by KeyguardClockSwitchController */} ClockTickRate.PER_SECOND -> executor.execute(secondsRunnable) ClockTickRate.PER_FRAME -> { clockFace.view.viewTreeObserver.addOnPreDrawListener(predrawListener) clockFace.view.invalidate() } } } fun stop() { if (!isRunning) { return } isRunning = false clockFace.view.viewTreeObserver.removeOnPreDrawListener(predrawListener) } fun update(shouldRun: Boolean) = if (shouldRun) start() else stop() } companion object { private val TAG = ClockEventController::class.simpleName!! private val DOZE_TICKRATE_THRESHOLD = 0.99f } } packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java +2 −1 Original line number Diff line number Diff line Loading @@ -344,7 +344,8 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS } ClockController clock = getClock(); if (clock != null) { clock.getEvents().onTimeTick(); clock.getSmallClock().getEvents().onTimeTick(); clock.getLargeClock().getEvents().onTimeTick(); } } Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt +2 −1 Original line number Diff line number Diff line Loading @@ -177,7 +177,8 @@ constructor( val receiver = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { clockController.clock?.events?.onTimeTick() clockController.clock?.smallClock?.events?.onTimeTick() clockController.clock?.largeClock?.events?.onTimeTick() } } broadcastDispatcher.registerReceiver( Loading Loading
packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt +4 −3 Original line number Diff line number Diff line Loading @@ -85,7 +85,8 @@ class DefaultClockController( animations = DefaultClockAnimations(dozeFraction, foldFraction) events.onColorPaletteChanged(resources) events.onTimeZoneChanged(TimeZone.getDefault()) events.onTimeTick() smallClock.events.onTimeTick() largeClock.events.onTimeTick() } open inner class DefaultClockFaceController( Loading @@ -109,6 +110,8 @@ class DefaultClockController( override val events = object : ClockFaceEvents { override fun onTimeTick() = view.refreshTime() override fun onRegionDarknessChanged(isRegionDark: Boolean) { this@DefaultClockFaceController.isRegionDark = isRegionDark updateColor() Loading Loading @@ -169,8 +172,6 @@ class DefaultClockController( } inner class DefaultClockEvents : ClockEvents { override fun onTimeTick() = clocks.forEach { it.refreshTime() } override fun onTimeFormatChanged(is24Hr: Boolean) = clocks.forEach { it.refreshFormat(is24Hr) } Loading
packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt +16 −4 Original line number Diff line number Diff line Loading @@ -66,7 +66,8 @@ interface ClockController { events.onColorPaletteChanged(resources) animations.doze(dozeFraction) animations.fold(foldFraction) events.onTimeTick() smallClock.events.onTimeTick() largeClock.events.onTimeTick() } /** Optional method for dumping debug information */ Loading @@ -87,9 +88,6 @@ interface ClockFaceController { /** Events that should call when various rendering parameters change */ interface ClockEvents { /** Call every time tick */ fun onTimeTick() {} /** Call whenever timezone changes */ fun onTimeZoneChanged(timeZone: TimeZone) {} Loading Loading @@ -131,6 +129,13 @@ interface ClockAnimations { /** Events that have specific data about the related face */ interface ClockFaceEvents { /** Call every time tick */ fun onTimeTick() {} /** Expected interval between calls to onTimeTick. Can always reduce to PER_MINUTE in AOD. */ val tickRate: ClockTickRate get() = ClockTickRate.PER_MINUTE /** Region Darkness specific to the clock face */ fun onRegionDarknessChanged(isDark: Boolean) {} Loading @@ -150,6 +155,13 @@ interface ClockFaceEvents { fun onTargetRegionChanged(targetRegion: Rect?) {} } /** Tick rates for clocks */ enum class ClockTickRate(val value: Int) { PER_MINUTE(2), // Update the clock once per minute. PER_SECOND(1), // Update the clock once per second. PER_FRAME(0), // Update the clock every second. } /** Some data about a clock design */ data class ClockMetadata( val clockId: ClockId, Loading
packages/SystemUI/src/com/android/keyguard/ClockEventController.kt +91 −7 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.text.format.DateFormat import android.util.TypedValue import android.view.View import android.widget.FrameLayout import android.view.ViewTreeObserver import androidx.annotation.VisibleForTesting import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle Loading @@ -42,12 +43,15 @@ import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.log.dagger.KeyguardSmallClockLog import com.android.systemui.log.dagger.KeyguardLargeClockLog import com.android.systemui.plugins.ClockController import com.android.systemui.plugins.ClockFaceController import com.android.systemui.plugins.ClockTickRate import com.android.systemui.plugins.log.LogBuffer import com.android.systemui.plugins.log.LogLevel.DEBUG import com.android.systemui.shared.regionsampling.RegionSampler import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.concurrency.DelayableExecutor import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DisposableHandle import kotlinx.coroutines.Job Loading @@ -72,7 +76,7 @@ open class ClockEventController @Inject constructor( private val configurationController: ConfigurationController, @Main private val resources: Resources, private val context: Context, @Main private val mainExecutor: Executor, @Main private val mainExecutor: DelayableExecutor, @Background private val bgExecutor: Executor, @KeyguardSmallClockLog private val smallLogBuffer: LogBuffer?, @KeyguardLargeClockLog private val largeLogBuffer: LogBuffer?, Loading @@ -94,6 +98,7 @@ open class ClockEventController @Inject constructor( clock?.largeClock?.view?.addOnLayoutChangeListener(mLayoutChangedListener) } updateFontSizes() updateTimeListeners() } } Loading Loading @@ -208,6 +213,10 @@ open class ClockEventController @Inject constructor( } var regionSampler: RegionSampler? = null var smallTimeListener: TimeListener? = null var largeTimeListener: TimeListener? = null val shouldTimeListenerRun: Boolean get() = isKeyguardVisible && dozeAmount < DOZE_TICKRATE_THRESHOLD private var smallClockIsDark = true private var largeClockIsDark = true Loading Loading @@ -246,6 +255,9 @@ open class ClockEventController @Inject constructor( clock?.animations?.doze(if (isDozing) 1f else 0f) } } smallTimeListener?.update(shouldTimeListenerRun) largeTimeListener?.update(shouldTimeListenerRun) } override fun onTimeFormatChanged(timeFormat: String) { Loading Loading @@ -285,6 +297,8 @@ open class ClockEventController @Inject constructor( } } } smallTimeListener?.update(shouldTimeListenerRun) largeTimeListener?.update(shouldTimeListenerRun) } fun unregisterListeners() { Loading @@ -299,6 +313,25 @@ open class ClockEventController @Inject constructor( batteryController.removeCallback(batteryCallback) keyguardUpdateMonitor.removeCallback(keyguardUpdateMonitorCallback) regionSampler?.stopRegionSampler() smallTimeListener?.stop() largeTimeListener?.stop() } private fun updateTimeListeners() { smallTimeListener?.stop() largeTimeListener?.stop() smallTimeListener = null largeTimeListener = null clock?.smallClock?.let { smallTimeListener = TimeListener(it, mainExecutor) smallTimeListener?.update(shouldTimeListenerRun) } clock?.largeClock?.let { largeTimeListener = TimeListener(it, mainExecutor) largeTimeListener?.update(shouldTimeListenerRun) } } private fun updateFontSizes() { Loading @@ -308,12 +341,18 @@ open class ClockEventController @Inject constructor( resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat()) } private fun handleDoze(doze: Float) { dozeAmount = doze clock?.animations?.doze(dozeAmount) smallTimeListener?.update(doze < DOZE_TICKRATE_THRESHOLD) largeTimeListener?.update(doze < DOZE_TICKRATE_THRESHOLD) } @VisibleForTesting internal fun listenForDozeAmount(scope: CoroutineScope): Job { return scope.launch { keyguardInteractor.dozeAmount.collect { dozeAmount = it clock?.animations?.doze(dozeAmount) handleDoze(it) } } } Loading @@ -322,8 +361,7 @@ open class ClockEventController @Inject constructor( internal fun listenForDozeAmountTransition(scope: CoroutineScope): Job { return scope.launch { keyguardTransitionInteractor.dozeAmountTransition.collect { dozeAmount = it.value clock?.animations?.doze(dozeAmount) handleDoze(it.value) } } } Loading @@ -338,8 +376,7 @@ open class ClockEventController @Inject constructor( keyguardTransitionInteractor.anyStateToAodTransition.filter { it.transitionState == TransitionState.FINISHED }.collect { dozeAmount = 1f clock?.animations?.doze(dozeAmount) handleDoze(1f) } } } Loading @@ -359,7 +396,54 @@ open class ClockEventController @Inject constructor( } } class TimeListener(val clockFace: ClockFaceController, val executor: DelayableExecutor) { val predrawListener = ViewTreeObserver.OnPreDrawListener { clockFace.events.onTimeTick() true } val secondsRunnable = object : Runnable { override fun run() { if (!isRunning) { return } executor.executeDelayed(this, 990) clockFace.events.onTimeTick() } } var isRunning: Boolean = false private set fun start() { if (isRunning) { return } isRunning = true when (clockFace.events.tickRate) { ClockTickRate.PER_MINUTE -> {/* Handled by KeyguardClockSwitchController */} ClockTickRate.PER_SECOND -> executor.execute(secondsRunnable) ClockTickRate.PER_FRAME -> { clockFace.view.viewTreeObserver.addOnPreDrawListener(predrawListener) clockFace.view.invalidate() } } } fun stop() { if (!isRunning) { return } isRunning = false clockFace.view.viewTreeObserver.removeOnPreDrawListener(predrawListener) } fun update(shouldRun: Boolean) = if (shouldRun) start() else stop() } companion object { private val TAG = ClockEventController::class.simpleName!! private val DOZE_TICKRATE_THRESHOLD = 0.99f } }
packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java +2 −1 Original line number Diff line number Diff line Loading @@ -344,7 +344,8 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS } ClockController clock = getClock(); if (clock != null) { clock.getEvents().onTimeTick(); clock.getSmallClock().getEvents().onTimeTick(); clock.getLargeClock().getEvents().onTimeTick(); } } Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt +2 −1 Original line number Diff line number Diff line Loading @@ -177,7 +177,8 @@ constructor( val receiver = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { clockController.clock?.events?.onTimeTick() clockController.clock?.smallClock?.events?.onTimeTick() clockController.clock?.largeClock?.events?.onTimeTick() } } broadcastDispatcher.registerReceiver( Loading