Merge "Seperate clockface specific callbacks" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
883ecccdfc
@@ -39,19 +39,19 @@ interface ClockProvider {
|
|||||||
fun getClocks(): List<ClockMetadata>
|
fun getClocks(): List<ClockMetadata>
|
||||||
|
|
||||||
/** Initializes and returns the target clock design */
|
/** Initializes and returns the target clock design */
|
||||||
fun createClock(id: ClockId): Clock
|
fun createClock(id: ClockId): ClockController
|
||||||
|
|
||||||
/** A static thumbnail for rendering in some examples */
|
/** A static thumbnail for rendering in some examples */
|
||||||
fun getClockThumbnail(id: ClockId): Drawable?
|
fun getClockThumbnail(id: ClockId): Drawable?
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Interface for controlling an active clock */
|
/** Interface for controlling an active clock */
|
||||||
interface Clock {
|
interface ClockController {
|
||||||
/** A small version of the clock, appropriate for smaller viewports */
|
/** A small version of the clock, appropriate for smaller viewports */
|
||||||
val smallClock: View
|
val smallClock: ClockFaceController
|
||||||
|
|
||||||
/** A large version of the clock, appropriate when a bigger viewport is available */
|
/** A large version of the clock, appropriate when a bigger viewport is available */
|
||||||
val largeClock: View
|
val largeClock: ClockFaceController
|
||||||
|
|
||||||
/** Events that clocks may need to respond to */
|
/** Events that clocks may need to respond to */
|
||||||
val events: ClockEvents
|
val events: ClockEvents
|
||||||
@@ -61,7 +61,7 @@ interface Clock {
|
|||||||
|
|
||||||
/** Initializes various rendering parameters. If never called, provides reasonable defaults. */
|
/** Initializes various rendering parameters. If never called, provides reasonable defaults. */
|
||||||
fun initialize(resources: Resources, dozeFraction: Float, foldFraction: Float) {
|
fun initialize(resources: Resources, dozeFraction: Float, foldFraction: Float) {
|
||||||
events.onColorPaletteChanged(resources, true, true)
|
events.onColorPaletteChanged(resources)
|
||||||
animations.doze(dozeFraction)
|
animations.doze(dozeFraction)
|
||||||
animations.fold(foldFraction)
|
animations.fold(foldFraction)
|
||||||
events.onTimeTick()
|
events.onTimeTick()
|
||||||
@@ -71,10 +71,19 @@ interface Clock {
|
|||||||
fun dump(pw: PrintWriter) { }
|
fun dump(pw: PrintWriter) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Interface for a specific clock face version rendered by the clock */
|
||||||
|
interface ClockFaceController {
|
||||||
|
/** View that renders the clock face */
|
||||||
|
val view: View
|
||||||
|
|
||||||
|
/** Events specific to this clock face */
|
||||||
|
val events: ClockFaceEvents
|
||||||
|
}
|
||||||
|
|
||||||
/** Events that should call when various rendering parameters change */
|
/** Events that should call when various rendering parameters change */
|
||||||
interface ClockEvents {
|
interface ClockEvents {
|
||||||
/** Call every time tick */
|
/** Call every time tick */
|
||||||
fun onTimeTick()
|
fun onTimeTick() { }
|
||||||
|
|
||||||
/** Call whenever timezone changes */
|
/** Call whenever timezone changes */
|
||||||
fun onTimeZoneChanged(timeZone: TimeZone) { }
|
fun onTimeZoneChanged(timeZone: TimeZone) { }
|
||||||
@@ -89,11 +98,7 @@ interface ClockEvents {
|
|||||||
fun onFontSettingChanged() { }
|
fun onFontSettingChanged() { }
|
||||||
|
|
||||||
/** Call whenever the color palette should update */
|
/** Call whenever the color palette should update */
|
||||||
fun onColorPaletteChanged(
|
fun onColorPaletteChanged(resources: Resources) { }
|
||||||
resources: Resources,
|
|
||||||
smallClockIsDark: Boolean,
|
|
||||||
largeClockIsDark: Boolean
|
|
||||||
) { }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Methods which trigger various clock animations */
|
/** Methods which trigger various clock animations */
|
||||||
@@ -111,6 +116,12 @@ interface ClockAnimations {
|
|||||||
fun charge() { }
|
fun charge() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Events that have specific data about the related face */
|
||||||
|
interface ClockFaceEvents {
|
||||||
|
/** Region Darkness specific to the clock face */
|
||||||
|
fun onRegionDarknessChanged(isDark: Boolean) { }
|
||||||
|
}
|
||||||
|
|
||||||
/** Some data about a clock design */
|
/** Some data about a clock design */
|
||||||
data class ClockMetadata(
|
data class ClockMetadata(
|
||||||
val clockId: ClockId,
|
val clockId: ClockId,
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import android.os.UserHandle
|
|||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.android.systemui.dagger.qualifiers.Main
|
import com.android.systemui.dagger.qualifiers.Main
|
||||||
import com.android.systemui.plugins.Clock
|
import com.android.systemui.plugins.ClockController
|
||||||
import com.android.systemui.plugins.ClockId
|
import com.android.systemui.plugins.ClockId
|
||||||
import com.android.systemui.plugins.ClockMetadata
|
import com.android.systemui.plugins.ClockMetadata
|
||||||
import com.android.systemui.plugins.ClockProvider
|
import com.android.systemui.plugins.ClockProvider
|
||||||
@@ -33,7 +33,7 @@ import com.google.gson.Gson
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
private val TAG = ClockRegistry::class.simpleName
|
private val TAG = ClockRegistry::class.simpleName
|
||||||
private val DEBUG = true
|
private const val DEBUG = true
|
||||||
|
|
||||||
/** ClockRegistry aggregates providers and plugins */
|
/** ClockRegistry aggregates providers and plugins */
|
||||||
open class ClockRegistry(
|
open class ClockRegistry(
|
||||||
@@ -130,6 +130,10 @@ open class ClockRegistry(
|
|||||||
}
|
}
|
||||||
|
|
||||||
availableClocks[id] = ClockInfo(clock, provider)
|
availableClocks[id] = ClockInfo(clock, provider)
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.i(TAG, "Added ${clock.clockId}")
|
||||||
|
}
|
||||||
|
|
||||||
if (currentId == id) {
|
if (currentId == id) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.i(TAG, "Current clock ($currentId) was connected")
|
Log.i(TAG, "Current clock ($currentId) was connected")
|
||||||
@@ -143,6 +147,9 @@ open class ClockRegistry(
|
|||||||
val currentId = currentClockId
|
val currentId = currentClockId
|
||||||
for (clock in provider.getClocks()) {
|
for (clock in provider.getClocks()) {
|
||||||
availableClocks.remove(clock.clockId)
|
availableClocks.remove(clock.clockId)
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.i(TAG, "Removed ${clock.clockId}")
|
||||||
|
}
|
||||||
|
|
||||||
if (currentId == clock.clockId) {
|
if (currentId == clock.clockId) {
|
||||||
Log.w(TAG, "Current clock ($currentId) was disconnected")
|
Log.w(TAG, "Current clock ($currentId) was disconnected")
|
||||||
@@ -161,7 +168,7 @@ open class ClockRegistry(
|
|||||||
fun getClockThumbnail(clockId: ClockId): Drawable? =
|
fun getClockThumbnail(clockId: ClockId): Drawable? =
|
||||||
availableClocks[clockId]?.provider?.getClockThumbnail(clockId)
|
availableClocks[clockId]?.provider?.getClockThumbnail(clockId)
|
||||||
|
|
||||||
fun createExampleClock(clockId: ClockId): Clock? = createClock(clockId)
|
fun createExampleClock(clockId: ClockId): ClockController? = createClock(clockId)
|
||||||
|
|
||||||
fun registerClockChangeListener(listener: ClockChangeListener) =
|
fun registerClockChangeListener(listener: ClockChangeListener) =
|
||||||
clockChangeListeners.add(listener)
|
clockChangeListeners.add(listener)
|
||||||
@@ -169,11 +176,14 @@ open class ClockRegistry(
|
|||||||
fun unregisterClockChangeListener(listener: ClockChangeListener) =
|
fun unregisterClockChangeListener(listener: ClockChangeListener) =
|
||||||
clockChangeListeners.remove(listener)
|
clockChangeListeners.remove(listener)
|
||||||
|
|
||||||
fun createCurrentClock(): Clock {
|
fun createCurrentClock(): ClockController {
|
||||||
val clockId = currentClockId
|
val clockId = currentClockId
|
||||||
if (isEnabled && clockId.isNotEmpty()) {
|
if (isEnabled && clockId.isNotEmpty()) {
|
||||||
val clock = createClock(clockId)
|
val clock = createClock(clockId)
|
||||||
if (clock != null) {
|
if (clock != null) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.i(TAG, "Rendering clock $clockId")
|
||||||
|
}
|
||||||
return clock
|
return clock
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "Clock $clockId not found; using default")
|
Log.e(TAG, "Clock $clockId not found; using default")
|
||||||
@@ -183,7 +193,7 @@ open class ClockRegistry(
|
|||||||
return createClock(DEFAULT_CLOCK_ID)!!
|
return createClock(DEFAULT_CLOCK_ID)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createClock(clockId: ClockId): Clock? =
|
private fun createClock(clockId: ClockId): ClockController? =
|
||||||
availableClocks[clockId]?.provider?.createClock(clockId)
|
availableClocks[clockId]?.provider?.createClock(clockId)
|
||||||
|
|
||||||
private data class ClockInfo(
|
private data class ClockInfo(
|
||||||
|
|||||||
@@ -0,0 +1,234 @@
|
|||||||
|
/*
|
||||||
|
* 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.shared.clocks
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.res.Resources
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.icu.text.NumberFormat
|
||||||
|
import android.util.TypedValue
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import androidx.annotation.VisibleForTesting
|
||||||
|
import com.android.systemui.plugins.ClockAnimations
|
||||||
|
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.shared.R
|
||||||
|
import java.io.PrintWriter
|
||||||
|
import java.util.Locale
|
||||||
|
import java.util.TimeZone
|
||||||
|
|
||||||
|
private val TAG = DefaultClockController::class.simpleName
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls the default clock visuals.
|
||||||
|
*
|
||||||
|
* This serves as an adapter between the clock interface and the AnimatableClockView used by the
|
||||||
|
* existing lockscreen clock.
|
||||||
|
*/
|
||||||
|
class DefaultClockController(
|
||||||
|
ctx: Context,
|
||||||
|
private val layoutInflater: LayoutInflater,
|
||||||
|
private val resources: Resources,
|
||||||
|
) : ClockController {
|
||||||
|
override val smallClock: DefaultClockFaceController
|
||||||
|
override val largeClock: LargeClockFaceController
|
||||||
|
private val clocks: List<AnimatableClockView>
|
||||||
|
|
||||||
|
private val burmeseNf = NumberFormat.getInstance(Locale.forLanguageTag("my"))
|
||||||
|
private val burmeseNumerals = burmeseNf.format(FORMAT_NUMBER.toLong())
|
||||||
|
private val burmeseLineSpacing =
|
||||||
|
resources.getFloat(R.dimen.keyguard_clock_line_spacing_scale_burmese)
|
||||||
|
private val defaultLineSpacing = resources.getFloat(R.dimen.keyguard_clock_line_spacing_scale)
|
||||||
|
|
||||||
|
override val events: DefaultClockEvents
|
||||||
|
override lateinit var animations: DefaultClockAnimations
|
||||||
|
private set
|
||||||
|
|
||||||
|
init {
|
||||||
|
val parent = FrameLayout(ctx)
|
||||||
|
smallClock =
|
||||||
|
DefaultClockFaceController(
|
||||||
|
layoutInflater.inflate(R.layout.clock_default_small, parent, false)
|
||||||
|
as AnimatableClockView
|
||||||
|
)
|
||||||
|
largeClock =
|
||||||
|
LargeClockFaceController(
|
||||||
|
layoutInflater.inflate(R.layout.clock_default_large, parent, false)
|
||||||
|
as AnimatableClockView
|
||||||
|
)
|
||||||
|
clocks = listOf(smallClock.view, largeClock.view)
|
||||||
|
|
||||||
|
events = DefaultClockEvents()
|
||||||
|
animations = DefaultClockAnimations(0f, 0f)
|
||||||
|
events.onLocaleChanged(Locale.getDefault())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initialize(resources: Resources, dozeFraction: Float, foldFraction: Float) {
|
||||||
|
largeClock.recomputePadding()
|
||||||
|
animations = DefaultClockAnimations(dozeFraction, foldFraction)
|
||||||
|
events.onColorPaletteChanged(resources)
|
||||||
|
events.onTimeZoneChanged(TimeZone.getDefault())
|
||||||
|
events.onTimeTick()
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
init {
|
||||||
|
view.setColors(currentColor, currentColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val events =
|
||||||
|
object : ClockFaceEvents {
|
||||||
|
override fun onRegionDarknessChanged(isRegionDark: Boolean) {
|
||||||
|
this@DefaultClockFaceController.isRegionDark = isRegionDark
|
||||||
|
updateColor()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateColor() {
|
||||||
|
val color =
|
||||||
|
if (isRegionDark) {
|
||||||
|
resources.getColor(android.R.color.system_accent1_100)
|
||||||
|
} else {
|
||||||
|
resources.getColor(android.R.color.system_accent2_600)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentColor == color) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
currentColor = color
|
||||||
|
view.setColors(DOZE_COLOR, color)
|
||||||
|
view.animateAppearOnLockscreen()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class LargeClockFaceController(
|
||||||
|
view: AnimatableClockView,
|
||||||
|
) : DefaultClockFaceController(view) {
|
||||||
|
fun recomputePadding() {
|
||||||
|
val lp = view.getLayoutParams() as FrameLayout.LayoutParams
|
||||||
|
lp.topMargin = (-0.5f * view.bottom).toInt()
|
||||||
|
view.setLayoutParams(lp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class DefaultClockEvents : ClockEvents {
|
||||||
|
override fun onTimeTick() = clocks.forEach { it.refreshTime() }
|
||||||
|
|
||||||
|
override fun onTimeFormatChanged(is24Hr: Boolean) =
|
||||||
|
clocks.forEach { it.refreshFormat(is24Hr) }
|
||||||
|
|
||||||
|
override fun onTimeZoneChanged(timeZone: TimeZone) =
|
||||||
|
clocks.forEach { it.onTimeZoneChanged(timeZone) }
|
||||||
|
|
||||||
|
override fun onFontSettingChanged() {
|
||||||
|
smallClock.view.setTextSize(
|
||||||
|
TypedValue.COMPLEX_UNIT_PX,
|
||||||
|
resources.getDimensionPixelSize(R.dimen.small_clock_text_size).toFloat()
|
||||||
|
)
|
||||||
|
largeClock.view.setTextSize(
|
||||||
|
TypedValue.COMPLEX_UNIT_PX,
|
||||||
|
resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat()
|
||||||
|
)
|
||||||
|
largeClock.recomputePadding()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onColorPaletteChanged(resources: Resources) {
|
||||||
|
largeClock.updateColor()
|
||||||
|
smallClock.updateColor()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLocaleChanged(locale: Locale) {
|
||||||
|
val nf = NumberFormat.getInstance(locale)
|
||||||
|
if (nf.format(FORMAT_NUMBER.toLong()) == burmeseNumerals) {
|
||||||
|
clocks.forEach { it.setLineSpacingScale(burmeseLineSpacing) }
|
||||||
|
} else {
|
||||||
|
clocks.forEach { it.setLineSpacingScale(defaultLineSpacing) }
|
||||||
|
}
|
||||||
|
|
||||||
|
clocks.forEach { it.refreshFormat() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class DefaultClockAnimations(
|
||||||
|
dozeFraction: Float,
|
||||||
|
foldFraction: Float,
|
||||||
|
) : ClockAnimations {
|
||||||
|
private var foldState = AnimationState(0f)
|
||||||
|
private var dozeState = AnimationState(0f)
|
||||||
|
|
||||||
|
init {
|
||||||
|
dozeState = AnimationState(dozeFraction)
|
||||||
|
foldState = AnimationState(foldFraction)
|
||||||
|
|
||||||
|
if (foldState.isActive) {
|
||||||
|
clocks.forEach { it.animateFoldAppear(false) }
|
||||||
|
} else {
|
||||||
|
clocks.forEach { it.animateDoze(dozeState.isActive, false) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun enter() {
|
||||||
|
if (!dozeState.isActive) {
|
||||||
|
clocks.forEach { it.animateAppearOnLockscreen() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun charge() = clocks.forEach { it.animateCharge { dozeState.isActive } }
|
||||||
|
|
||||||
|
override fun fold(fraction: Float) {
|
||||||
|
val (hasChanged, hasJumped) = foldState.update(fraction)
|
||||||
|
if (hasChanged) {
|
||||||
|
clocks.forEach { it.animateFoldAppear(!hasJumped) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun doze(fraction: Float) {
|
||||||
|
val (hasChanged, hasJumped) = dozeState.update(fraction)
|
||||||
|
if (hasChanged) {
|
||||||
|
clocks.forEach { it.animateDoze(dozeState.isActive, !hasJumped) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AnimationState(
|
||||||
|
var fraction: Float,
|
||||||
|
) {
|
||||||
|
var isActive: Boolean = fraction < 0.5f
|
||||||
|
fun update(newFraction: Float): Pair<Boolean, Boolean> {
|
||||||
|
val wasActive = isActive
|
||||||
|
val hasJumped =
|
||||||
|
(fraction == 0f && newFraction == 1f) || (fraction == 1f && newFraction == 0f)
|
||||||
|
isActive = newFraction > fraction
|
||||||
|
fraction = newFraction
|
||||||
|
return Pair(wasActive != isActive, hasJumped)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dump(pw: PrintWriter) = clocks.forEach { it.dump(pw) }
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@VisibleForTesting const val DOZE_COLOR = Color.WHITE
|
||||||
|
private const val FORMAT_NUMBER = 1234567890
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,24 +15,14 @@ package com.android.systemui.shared.clocks
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.icu.text.NumberFormat
|
|
||||||
import android.util.TypedValue
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.widget.FrameLayout
|
|
||||||
import com.android.internal.annotations.VisibleForTesting
|
|
||||||
import com.android.systemui.dagger.qualifiers.Main
|
import com.android.systemui.dagger.qualifiers.Main
|
||||||
import com.android.systemui.plugins.Clock
|
import com.android.systemui.plugins.ClockController
|
||||||
import com.android.systemui.plugins.ClockAnimations
|
|
||||||
import com.android.systemui.plugins.ClockEvents
|
|
||||||
import com.android.systemui.plugins.ClockId
|
import com.android.systemui.plugins.ClockId
|
||||||
import com.android.systemui.plugins.ClockMetadata
|
import com.android.systemui.plugins.ClockMetadata
|
||||||
import com.android.systemui.plugins.ClockProvider
|
import com.android.systemui.plugins.ClockProvider
|
||||||
import com.android.systemui.shared.R
|
import com.android.systemui.shared.R
|
||||||
import java.io.PrintWriter
|
|
||||||
import java.util.Locale
|
|
||||||
import java.util.TimeZone
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
private val TAG = DefaultClockProvider::class.simpleName
|
private val TAG = DefaultClockProvider::class.simpleName
|
||||||
@@ -48,11 +38,12 @@ class DefaultClockProvider @Inject constructor(
|
|||||||
override fun getClocks(): List<ClockMetadata> =
|
override fun getClocks(): List<ClockMetadata> =
|
||||||
listOf(ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME))
|
listOf(ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME))
|
||||||
|
|
||||||
override fun createClock(id: ClockId): Clock {
|
override fun createClock(id: ClockId): ClockController {
|
||||||
if (id != DEFAULT_CLOCK_ID) {
|
if (id != DEFAULT_CLOCK_ID) {
|
||||||
throw IllegalArgumentException("$id is unsupported by $TAG")
|
throw IllegalArgumentException("$id is unsupported by $TAG")
|
||||||
}
|
}
|
||||||
return DefaultClock(ctx, layoutInflater, resources)
|
|
||||||
|
return DefaultClockController(ctx, layoutInflater, resources)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getClockThumbnail(id: ClockId): Drawable? {
|
override fun getClockThumbnail(id: ClockId): Drawable? {
|
||||||
@@ -64,190 +55,3 @@ class DefaultClockProvider @Inject constructor(
|
|||||||
return resources.getDrawable(R.drawable.clock_default_thumbnail, null)
|
return resources.getDrawable(R.drawable.clock_default_thumbnail, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Controls the default clock visuals.
|
|
||||||
*
|
|
||||||
* This serves as an adapter between the clock interface and the
|
|
||||||
* AnimatableClockView used by the existing lockscreen clock.
|
|
||||||
*/
|
|
||||||
class DefaultClock(
|
|
||||||
ctx: Context,
|
|
||||||
private val layoutInflater: LayoutInflater,
|
|
||||||
private val resources: Resources
|
|
||||||
) : Clock {
|
|
||||||
override val smallClock: AnimatableClockView
|
|
||||||
override val largeClock: AnimatableClockView
|
|
||||||
private val clocks get() = listOf(smallClock, largeClock)
|
|
||||||
|
|
||||||
private val burmeseNf = NumberFormat.getInstance(Locale.forLanguageTag("my"))
|
|
||||||
private val burmeseNumerals = burmeseNf.format(FORMAT_NUMBER.toLong())
|
|
||||||
private val burmeseLineSpacing =
|
|
||||||
resources.getFloat(R.dimen.keyguard_clock_line_spacing_scale_burmese)
|
|
||||||
private val defaultLineSpacing = resources.getFloat(R.dimen.keyguard_clock_line_spacing_scale)
|
|
||||||
|
|
||||||
override val events: ClockEvents
|
|
||||||
override lateinit var animations: ClockAnimations
|
|
||||||
private set
|
|
||||||
|
|
||||||
private var smallRegionDarkness = false
|
|
||||||
private var largeRegionDarkness = false
|
|
||||||
|
|
||||||
init {
|
|
||||||
val parent = FrameLayout(ctx)
|
|
||||||
|
|
||||||
smallClock = layoutInflater.inflate(
|
|
||||||
R.layout.clock_default_small,
|
|
||||||
parent,
|
|
||||||
false
|
|
||||||
) as AnimatableClockView
|
|
||||||
|
|
||||||
largeClock = layoutInflater.inflate(
|
|
||||||
R.layout.clock_default_large,
|
|
||||||
parent,
|
|
||||||
false
|
|
||||||
) as AnimatableClockView
|
|
||||||
|
|
||||||
events = DefaultClockEvents()
|
|
||||||
animations = DefaultClockAnimations(0f, 0f)
|
|
||||||
|
|
||||||
events.onLocaleChanged(Locale.getDefault())
|
|
||||||
|
|
||||||
// DOZE_COLOR is a placeholder, and will be assigned correctly in initialize
|
|
||||||
clocks.forEach { it.setColors(DOZE_COLOR, DOZE_COLOR) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun initialize(resources: Resources, dozeFraction: Float, foldFraction: Float) {
|
|
||||||
recomputePadding()
|
|
||||||
animations = DefaultClockAnimations(dozeFraction, foldFraction)
|
|
||||||
events.onColorPaletteChanged(resources, true, true)
|
|
||||||
events.onTimeZoneChanged(TimeZone.getDefault())
|
|
||||||
events.onTimeTick()
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class DefaultClockEvents() : ClockEvents {
|
|
||||||
override fun onTimeTick() = clocks.forEach { it.refreshTime() }
|
|
||||||
|
|
||||||
override fun onTimeFormatChanged(is24Hr: Boolean) =
|
|
||||||
clocks.forEach { it.refreshFormat(is24Hr) }
|
|
||||||
|
|
||||||
override fun onTimeZoneChanged(timeZone: TimeZone) =
|
|
||||||
clocks.forEach { it.onTimeZoneChanged(timeZone) }
|
|
||||||
|
|
||||||
override fun onFontSettingChanged() {
|
|
||||||
smallClock.setTextSize(
|
|
||||||
TypedValue.COMPLEX_UNIT_PX,
|
|
||||||
resources.getDimensionPixelSize(R.dimen.small_clock_text_size).toFloat()
|
|
||||||
)
|
|
||||||
largeClock.setTextSize(
|
|
||||||
TypedValue.COMPLEX_UNIT_PX,
|
|
||||||
resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat()
|
|
||||||
)
|
|
||||||
recomputePadding()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onColorPaletteChanged(
|
|
||||||
resources: Resources,
|
|
||||||
smallClockIsDark: Boolean,
|
|
||||||
largeClockIsDark: Boolean
|
|
||||||
) {
|
|
||||||
if (smallRegionDarkness != smallClockIsDark) {
|
|
||||||
smallRegionDarkness = smallClockIsDark
|
|
||||||
updateClockColor(smallClock, smallClockIsDark)
|
|
||||||
}
|
|
||||||
if (largeRegionDarkness != largeClockIsDark) {
|
|
||||||
largeRegionDarkness = largeClockIsDark
|
|
||||||
updateClockColor(largeClock, largeClockIsDark)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onLocaleChanged(locale: Locale) {
|
|
||||||
val nf = NumberFormat.getInstance(locale)
|
|
||||||
if (nf.format(FORMAT_NUMBER.toLong()) == burmeseNumerals) {
|
|
||||||
clocks.forEach { it.setLineSpacingScale(burmeseLineSpacing) }
|
|
||||||
} else {
|
|
||||||
clocks.forEach { it.setLineSpacingScale(defaultLineSpacing) }
|
|
||||||
}
|
|
||||||
|
|
||||||
clocks.forEach { it.refreshFormat() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class DefaultClockAnimations(
|
|
||||||
dozeFraction: Float,
|
|
||||||
foldFraction: Float
|
|
||||||
) : ClockAnimations {
|
|
||||||
private var foldState = AnimationState(0f)
|
|
||||||
private var dozeState = AnimationState(0f)
|
|
||||||
|
|
||||||
init {
|
|
||||||
dozeState = AnimationState(dozeFraction)
|
|
||||||
foldState = AnimationState(foldFraction)
|
|
||||||
|
|
||||||
if (foldState.isActive) {
|
|
||||||
clocks.forEach { it.animateFoldAppear(false) }
|
|
||||||
} else {
|
|
||||||
clocks.forEach { it.animateDoze(dozeState.isActive, false) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun enter() {
|
|
||||||
if (!dozeState.isActive) {
|
|
||||||
clocks.forEach { it.animateAppearOnLockscreen() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun charge() = clocks.forEach { it.animateCharge { dozeState.isActive } }
|
|
||||||
|
|
||||||
override fun fold(fraction: Float) {
|
|
||||||
val (hasChanged, hasJumped) = foldState.update(fraction)
|
|
||||||
if (hasChanged) {
|
|
||||||
clocks.forEach { it.animateFoldAppear(!hasJumped) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun doze(fraction: Float) {
|
|
||||||
val (hasChanged, hasJumped) = dozeState.update(fraction)
|
|
||||||
if (hasChanged) {
|
|
||||||
clocks.forEach { it.animateDoze(dozeState.isActive, !hasJumped) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class AnimationState(
|
|
||||||
var fraction: Float
|
|
||||||
) {
|
|
||||||
var isActive: Boolean = fraction < 0.5f
|
|
||||||
fun update(newFraction: Float): Pair<Boolean, Boolean> {
|
|
||||||
val wasActive = isActive
|
|
||||||
val hasJumped = (fraction == 0f && newFraction == 1f) ||
|
|
||||||
(fraction == 1f && newFraction == 0f)
|
|
||||||
isActive = newFraction > fraction
|
|
||||||
fraction = newFraction
|
|
||||||
return Pair(wasActive != isActive, hasJumped)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateClockColor(clock: AnimatableClockView, isRegionDark: Boolean) {
|
|
||||||
val color = if (isRegionDark) {
|
|
||||||
resources.getColor(android.R.color.system_accent1_100)
|
|
||||||
} else {
|
|
||||||
resources.getColor(android.R.color.system_accent2_600)
|
|
||||||
}
|
|
||||||
clock.setColors(DOZE_COLOR, color)
|
|
||||||
clock.animateAppearOnLockscreen()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun recomputePadding() {
|
|
||||||
val lp = largeClock.getLayoutParams() as FrameLayout.LayoutParams
|
|
||||||
lp.topMargin = (-0.5f * largeClock.bottom).toInt()
|
|
||||||
largeClock.setLayoutParams(lp)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun dump(pw: PrintWriter) = clocks.forEach { it.dump(pw) }
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@VisibleForTesting const val DOZE_COLOR = Color.WHITE
|
|
||||||
private const val FORMAT_NUMBER = 1234567890
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher
|
|||||||
import com.android.systemui.dagger.qualifiers.Background
|
import com.android.systemui.dagger.qualifiers.Background
|
||||||
import com.android.systemui.dagger.qualifiers.Main
|
import com.android.systemui.dagger.qualifiers.Main
|
||||||
import com.android.systemui.flags.FeatureFlags
|
import com.android.systemui.flags.FeatureFlags
|
||||||
import com.android.systemui.plugins.Clock
|
import com.android.systemui.plugins.ClockController
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||||
import com.android.systemui.shared.regionsampling.RegionSamplingInstance
|
import com.android.systemui.shared.regionsampling.RegionSamplingInstance
|
||||||
import com.android.systemui.statusbar.policy.BatteryController
|
import com.android.systemui.statusbar.policy.BatteryController
|
||||||
@@ -53,9 +53,9 @@ open class ClockEventController @Inject constructor(
|
|||||||
private val context: Context,
|
private val context: Context,
|
||||||
@Main private val mainExecutor: Executor,
|
@Main private val mainExecutor: Executor,
|
||||||
@Background private val bgExecutor: Executor,
|
@Background private val bgExecutor: Executor,
|
||||||
private val featureFlags: FeatureFlags
|
private val featureFlags: FeatureFlags,
|
||||||
) {
|
) {
|
||||||
var clock: Clock? = null
|
var clock: ClockController? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
@@ -74,42 +74,45 @@ open class ClockEventController @Inject constructor(
|
|||||||
private val regionSamplingEnabled =
|
private val regionSamplingEnabled =
|
||||||
featureFlags.isEnabled(com.android.systemui.flags.Flags.REGION_SAMPLING)
|
featureFlags.isEnabled(com.android.systemui.flags.Flags.REGION_SAMPLING)
|
||||||
|
|
||||||
private val updateFun = object : RegionSamplingInstance.UpdateColorCallback {
|
private fun updateColors() {
|
||||||
override fun updateColors() {
|
if (regionSamplingEnabled && smallRegionSampler != null && largeRegionSampler != null) {
|
||||||
if (regionSamplingEnabled) {
|
smallClockIsDark = smallRegionSampler!!.currentRegionDarkness().isDark
|
||||||
smallClockIsDark = smallRegionSamplingInstance.currentRegionDarkness().isDark
|
largeClockIsDark = largeRegionSampler!!.currentRegionDarkness().isDark
|
||||||
largeClockIsDark = largeRegionSamplingInstance.currentRegionDarkness().isDark
|
|
||||||
} else {
|
} else {
|
||||||
val isLightTheme = TypedValue()
|
val isLightTheme = TypedValue()
|
||||||
context.theme.resolveAttribute(android.R.attr.isLightTheme, isLightTheme, true)
|
context.theme.resolveAttribute(android.R.attr.isLightTheme, isLightTheme, true)
|
||||||
smallClockIsDark = isLightTheme.data == 0
|
smallClockIsDark = isLightTheme.data == 0
|
||||||
largeClockIsDark = isLightTheme.data == 0
|
largeClockIsDark = isLightTheme.data == 0
|
||||||
}
|
}
|
||||||
clock?.events?.onColorPaletteChanged(resources, smallClockIsDark, largeClockIsDark)
|
|
||||||
}
|
clock?.smallClock?.events?.onRegionDarknessChanged(smallClockIsDark)
|
||||||
|
clock?.largeClock?.events?.onRegionDarknessChanged(largeClockIsDark)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateRegionSamplers(currentClock: Clock?) {
|
private fun updateRegionSamplers(currentClock: ClockController?) {
|
||||||
smallRegionSamplingInstance = createRegionSampler(
|
smallRegionSampler?.stopRegionSampler()
|
||||||
currentClock?.smallClock,
|
largeRegionSampler?.stopRegionSampler()
|
||||||
|
|
||||||
|
smallRegionSampler = createRegionSampler(
|
||||||
|
currentClock?.smallClock?.view,
|
||||||
mainExecutor,
|
mainExecutor,
|
||||||
bgExecutor,
|
bgExecutor,
|
||||||
regionSamplingEnabled,
|
regionSamplingEnabled,
|
||||||
updateFun
|
::updateColors
|
||||||
)
|
)
|
||||||
|
|
||||||
largeRegionSamplingInstance = createRegionSampler(
|
largeRegionSampler = createRegionSampler(
|
||||||
currentClock?.largeClock,
|
currentClock?.largeClock?.view,
|
||||||
mainExecutor,
|
mainExecutor,
|
||||||
bgExecutor,
|
bgExecutor,
|
||||||
regionSamplingEnabled,
|
regionSamplingEnabled,
|
||||||
updateFun
|
::updateColors
|
||||||
)
|
)
|
||||||
|
|
||||||
smallRegionSamplingInstance.startRegionSampler()
|
smallRegionSampler!!.startRegionSampler()
|
||||||
largeRegionSamplingInstance.startRegionSampler()
|
largeRegionSampler!!.startRegionSampler()
|
||||||
|
|
||||||
updateFun.updateColors()
|
updateColors()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun createRegionSampler(
|
protected open fun createRegionSampler(
|
||||||
@@ -117,25 +120,29 @@ open class ClockEventController @Inject constructor(
|
|||||||
mainExecutor: Executor?,
|
mainExecutor: Executor?,
|
||||||
bgExecutor: Executor?,
|
bgExecutor: Executor?,
|
||||||
regionSamplingEnabled: Boolean,
|
regionSamplingEnabled: Boolean,
|
||||||
updateFun: RegionSamplingInstance.UpdateColorCallback
|
updateColors: () -> Unit
|
||||||
): RegionSamplingInstance {
|
): RegionSamplingInstance {
|
||||||
return RegionSamplingInstance(
|
return RegionSamplingInstance(
|
||||||
sampledView,
|
sampledView,
|
||||||
mainExecutor,
|
mainExecutor,
|
||||||
bgExecutor,
|
bgExecutor,
|
||||||
regionSamplingEnabled,
|
regionSamplingEnabled,
|
||||||
updateFun)
|
object : RegionSamplingInstance.UpdateColorCallback {
|
||||||
|
override fun updateColors() {
|
||||||
|
updateColors()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
lateinit var smallRegionSamplingInstance: RegionSamplingInstance
|
var smallRegionSampler: RegionSamplingInstance? = null
|
||||||
lateinit var largeRegionSamplingInstance: RegionSamplingInstance
|
var largeRegionSampler: RegionSamplingInstance? = null
|
||||||
|
|
||||||
private var smallClockIsDark = true
|
private var smallClockIsDark = true
|
||||||
private var largeClockIsDark = true
|
private var largeClockIsDark = true
|
||||||
|
|
||||||
private val configListener = object : ConfigurationController.ConfigurationListener {
|
private val configListener = object : ConfigurationController.ConfigurationListener {
|
||||||
override fun onThemeChanged() {
|
override fun onThemeChanged() {
|
||||||
updateFun.updateColors()
|
clock?.events?.onColorPaletteChanged(resources)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDensityOrFontScaleChanged() {
|
override fun onDensityOrFontScaleChanged() {
|
||||||
@@ -204,8 +211,8 @@ open class ClockEventController @Inject constructor(
|
|||||||
batteryController.addCallback(batteryCallback)
|
batteryController.addCallback(batteryCallback)
|
||||||
keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
|
keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
|
||||||
statusBarStateController.addCallback(statusBarStateListener)
|
statusBarStateController.addCallback(statusBarStateListener)
|
||||||
smallRegionSamplingInstance.startRegionSampler()
|
smallRegionSampler?.startRegionSampler()
|
||||||
largeRegionSamplingInstance.startRegionSampler()
|
largeRegionSampler?.startRegionSampler()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unregisterListeners() {
|
fun unregisterListeners() {
|
||||||
@@ -214,8 +221,8 @@ open class ClockEventController @Inject constructor(
|
|||||||
batteryController.removeCallback(batteryCallback)
|
batteryController.removeCallback(batteryCallback)
|
||||||
keyguardUpdateMonitor.removeCallback(keyguardUpdateMonitorCallback)
|
keyguardUpdateMonitor.removeCallback(keyguardUpdateMonitorCallback)
|
||||||
statusBarStateController.removeCallback(statusBarStateListener)
|
statusBarStateController.removeCallback(statusBarStateListener)
|
||||||
smallRegionSamplingInstance.stopRegionSampler()
|
smallRegionSampler?.stopRegionSampler()
|
||||||
largeRegionSamplingInstance.stopRegionSampler()
|
largeRegionSampler?.stopRegionSampler()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -224,8 +231,8 @@ open class ClockEventController @Inject constructor(
|
|||||||
fun dump(pw: PrintWriter) {
|
fun dump(pw: PrintWriter) {
|
||||||
pw.println(this)
|
pw.println(this)
|
||||||
clock?.dump(pw)
|
clock?.dump(pw)
|
||||||
smallRegionSamplingInstance.dump(pw)
|
smallRegionSampler?.dump(pw)
|
||||||
largeRegionSamplingInstance.dump(pw)
|
largeRegionSampler?.dump(pw)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import androidx.annotation.VisibleForTesting;
|
|||||||
import com.android.keyguard.dagger.KeyguardStatusViewScope;
|
import com.android.keyguard.dagger.KeyguardStatusViewScope;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.animation.Interpolators;
|
import com.android.systemui.animation.Interpolators;
|
||||||
import com.android.systemui.plugins.Clock;
|
import com.android.systemui.plugins.ClockController;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
@@ -94,7 +94,7 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
|||||||
onDensityOrFontScaleChanged();
|
onDensityOrFontScaleChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setClock(Clock clock, int statusBarState) {
|
void setClock(ClockController clock, int statusBarState) {
|
||||||
// Disconnect from existing plugin.
|
// Disconnect from existing plugin.
|
||||||
mSmallClockFrame.removeAllViews();
|
mSmallClockFrame.removeAllViews();
|
||||||
mLargeClockFrame.removeAllViews();
|
mLargeClockFrame.removeAllViews();
|
||||||
@@ -105,8 +105,8 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attach small and big clock views to hierarchy.
|
// Attach small and big clock views to hierarchy.
|
||||||
mSmallClockFrame.addView(clock.getSmallClock());
|
mSmallClockFrame.addView(clock.getSmallClock().getView());
|
||||||
mLargeClockFrame.addView(clock.getLargeClock());
|
mLargeClockFrame.addView(clock.getLargeClock().getView());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateClockViews(boolean useLargeClock, boolean animate) {
|
private void updateClockViews(boolean useLargeClock, boolean animate) {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ import com.android.systemui.dump.DumpManager;
|
|||||||
import com.android.systemui.flags.FeatureFlags;
|
import com.android.systemui.flags.FeatureFlags;
|
||||||
import com.android.systemui.flags.Flags;
|
import com.android.systemui.flags.Flags;
|
||||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||||
import com.android.systemui.plugins.Clock;
|
import com.android.systemui.plugins.ClockController;
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.shared.clocks.ClockRegistry;
|
import com.android.systemui.shared.clocks.ClockRegistry;
|
||||||
import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
|
import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
|
||||||
@@ -262,7 +262,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
|
|
||||||
mCurrentClockSize = clockSize;
|
mCurrentClockSize = clockSize;
|
||||||
|
|
||||||
Clock clock = getClock();
|
ClockController clock = getClock();
|
||||||
boolean appeared = mView.switchToClock(clockSize, animate);
|
boolean appeared = mView.switchToClock(clockSize, animate);
|
||||||
if (clock != null && animate && appeared && clockSize == LARGE) {
|
if (clock != null && animate && appeared && clockSize == LARGE) {
|
||||||
clock.getAnimations().enter();
|
clock.getAnimations().enter();
|
||||||
@@ -273,7 +273,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
* Animates the clock view between folded and unfolded states
|
* Animates the clock view between folded and unfolded states
|
||||||
*/
|
*/
|
||||||
public void animateFoldToAod(float foldFraction) {
|
public void animateFoldToAod(float foldFraction) {
|
||||||
Clock clock = getClock();
|
ClockController clock = getClock();
|
||||||
if (clock != null) {
|
if (clock != null) {
|
||||||
clock.getAnimations().fold(foldFraction);
|
clock.getAnimations().fold(foldFraction);
|
||||||
}
|
}
|
||||||
@@ -286,7 +286,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
if (mSmartspaceController != null) {
|
if (mSmartspaceController != null) {
|
||||||
mSmartspaceController.requestSmartspaceUpdate();
|
mSmartspaceController.requestSmartspaceUpdate();
|
||||||
}
|
}
|
||||||
Clock clock = getClock();
|
ClockController clock = getClock();
|
||||||
if (clock != null) {
|
if (clock != null) {
|
||||||
clock.getEvents().onTimeTick();
|
clock.getEvents().onTimeTick();
|
||||||
}
|
}
|
||||||
@@ -319,17 +319,17 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
* We can't directly getBottom() because clock changes positions in AOD for burn-in
|
* We can't directly getBottom() because clock changes positions in AOD for burn-in
|
||||||
*/
|
*/
|
||||||
int getClockBottom(int statusBarHeaderHeight) {
|
int getClockBottom(int statusBarHeaderHeight) {
|
||||||
Clock clock = getClock();
|
ClockController clock = getClock();
|
||||||
if (clock == null) {
|
if (clock == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mLargeClockFrame.getVisibility() == View.VISIBLE) {
|
if (mLargeClockFrame.getVisibility() == View.VISIBLE) {
|
||||||
int frameHeight = mLargeClockFrame.getHeight();
|
int frameHeight = mLargeClockFrame.getHeight();
|
||||||
int clockHeight = clock.getLargeClock().getHeight();
|
int clockHeight = clock.getLargeClock().getView().getHeight();
|
||||||
return frameHeight / 2 + clockHeight / 2;
|
return frameHeight / 2 + clockHeight / 2;
|
||||||
} else {
|
} else {
|
||||||
int clockHeight = clock.getSmallClock().getHeight();
|
int clockHeight = clock.getSmallClock().getView().getHeight();
|
||||||
return clockHeight + statusBarHeaderHeight + mKeyguardClockTopMargin;
|
return clockHeight + statusBarHeaderHeight + mKeyguardClockTopMargin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -338,15 +338,15 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
* Get the height of the currently visible clock on the keyguard.
|
* Get the height of the currently visible clock on the keyguard.
|
||||||
*/
|
*/
|
||||||
int getClockHeight() {
|
int getClockHeight() {
|
||||||
Clock clock = getClock();
|
ClockController clock = getClock();
|
||||||
if (clock == null) {
|
if (clock == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mLargeClockFrame.getVisibility() == View.VISIBLE) {
|
if (mLargeClockFrame.getVisibility() == View.VISIBLE) {
|
||||||
return clock.getLargeClock().getHeight();
|
return clock.getLargeClock().getView().getHeight();
|
||||||
} else {
|
} else {
|
||||||
return clock.getSmallClock().getHeight();
|
return clock.getSmallClock().getView().getHeight();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,12 +361,12 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
mNotificationIconAreaController.setupAodIcons(nic);
|
mNotificationIconAreaController.setupAodIcons(nic);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setClock(Clock clock) {
|
private void setClock(ClockController clock) {
|
||||||
mClockEventController.setClock(clock);
|
mClockEventController.setClock(clock);
|
||||||
mView.setClock(clock, mStatusBarStateController.getState());
|
mView.setClock(clock, mStatusBarStateController.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Clock getClock() {
|
private ClockController getClock() {
|
||||||
return mClockEventController.getClock();
|
return mClockEventController.getClock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,7 +398,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
|
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
|
||||||
pw.println("currentClockSizeLarge=" + (mCurrentClockSize == LARGE));
|
pw.println("currentClockSizeLarge=" + (mCurrentClockSize == LARGE));
|
||||||
pw.println("mCanShowDoubleLineClock=" + mCanShowDoubleLineClock);
|
pw.println("mCanShowDoubleLineClock=" + mCanShowDoubleLineClock);
|
||||||
Clock clock = getClock();
|
ClockController clock = getClock();
|
||||||
if (clock != null) {
|
if (clock != null) {
|
||||||
clock.dump(pw);
|
clock.dump(pw);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,11 @@ import androidx.test.filters.SmallTest
|
|||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher
|
import com.android.systemui.broadcast.BroadcastDispatcher
|
||||||
import com.android.systemui.flags.FeatureFlags
|
import com.android.systemui.flags.FeatureFlags
|
||||||
import com.android.systemui.plugins.Clock
|
|
||||||
import com.android.systemui.plugins.ClockAnimations
|
import com.android.systemui.plugins.ClockAnimations
|
||||||
|
import com.android.systemui.plugins.ClockController
|
||||||
import com.android.systemui.plugins.ClockEvents
|
import com.android.systemui.plugins.ClockEvents
|
||||||
|
import com.android.systemui.plugins.ClockFaceController
|
||||||
|
import com.android.systemui.plugins.ClockFaceEvents
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||||
import com.android.systemui.statusbar.policy.BatteryController
|
import com.android.systemui.statusbar.policy.BatteryController
|
||||||
import com.android.systemui.statusbar.policy.ConfigurationController
|
import com.android.systemui.statusbar.policy.ConfigurationController
|
||||||
@@ -40,6 +42,7 @@ import org.junit.Before
|
|||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
|
import org.mockito.ArgumentMatchers.anyBoolean
|
||||||
import org.mockito.ArgumentMatchers.anyFloat
|
import org.mockito.ArgumentMatchers.anyFloat
|
||||||
import org.mockito.ArgumentMatchers.anyInt
|
import org.mockito.ArgumentMatchers.anyInt
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
@@ -61,17 +64,25 @@ class ClockEventControllerTest : SysuiTestCase() {
|
|||||||
@Mock private lateinit var configurationController: ConfigurationController
|
@Mock private lateinit var configurationController: ConfigurationController
|
||||||
@Mock private lateinit var animations: ClockAnimations
|
@Mock private lateinit var animations: ClockAnimations
|
||||||
@Mock private lateinit var events: ClockEvents
|
@Mock private lateinit var events: ClockEvents
|
||||||
@Mock private lateinit var clock: Clock
|
@Mock private lateinit var clock: ClockController
|
||||||
@Mock private lateinit var mainExecutor: Executor
|
@Mock private lateinit var mainExecutor: Executor
|
||||||
@Mock private lateinit var bgExecutor: Executor
|
@Mock private lateinit var bgExecutor: Executor
|
||||||
@Mock private lateinit var featureFlags: FeatureFlags
|
@Mock private lateinit var featureFlags: FeatureFlags
|
||||||
|
@Mock private lateinit var smallClockController: ClockFaceController
|
||||||
|
@Mock private lateinit var largeClockController: ClockFaceController
|
||||||
|
@Mock private lateinit var smallClockEvents: ClockFaceEvents
|
||||||
|
@Mock private lateinit var largeClockEvents: ClockFaceEvents
|
||||||
|
|
||||||
private lateinit var clockEventController: ClockEventController
|
private lateinit var clockEventController: ClockEventController
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
whenever(clock.smallClock).thenReturn(TextView(context))
|
whenever(clock.smallClock).thenReturn(smallClockController)
|
||||||
whenever(clock.largeClock).thenReturn(TextView(context))
|
whenever(clock.largeClock).thenReturn(largeClockController)
|
||||||
|
whenever(smallClockController.view).thenReturn(TextView(context))
|
||||||
|
whenever(largeClockController.view).thenReturn(TextView(context))
|
||||||
|
whenever(smallClockController.events).thenReturn(smallClockEvents)
|
||||||
|
whenever(largeClockController.events).thenReturn(largeClockEvents)
|
||||||
whenever(clock.events).thenReturn(events)
|
whenever(clock.events).thenReturn(events)
|
||||||
whenever(clock.animations).thenReturn(animations)
|
whenever(clock.animations).thenReturn(animations)
|
||||||
|
|
||||||
@@ -107,7 +118,8 @@ class ClockEventControllerTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun themeChanged_verifyClockPaletteUpdated() {
|
fun themeChanged_verifyClockPaletteUpdated() {
|
||||||
clockEventController.clock = clock
|
clockEventController.clock = clock
|
||||||
verify(events).onColorPaletteChanged(any(), any(), any())
|
verify(smallClockEvents).onRegionDarknessChanged(anyBoolean())
|
||||||
|
verify(largeClockEvents).onRegionDarknessChanged(anyBoolean())
|
||||||
|
|
||||||
clockEventController.registerListeners()
|
clockEventController.registerListeners()
|
||||||
|
|
||||||
@@ -115,13 +127,14 @@ class ClockEventControllerTest : SysuiTestCase() {
|
|||||||
verify(configurationController).addCallback(capture(captor))
|
verify(configurationController).addCallback(capture(captor))
|
||||||
captor.value.onThemeChanged()
|
captor.value.onThemeChanged()
|
||||||
|
|
||||||
verify(events, times(2)).onColorPaletteChanged(any(), any(), any())
|
verify(events).onColorPaletteChanged(any())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun fontChanged_verifyFontSizeUpdated() {
|
fun fontChanged_verifyFontSizeUpdated() {
|
||||||
clockEventController.clock = clock
|
clockEventController.clock = clock
|
||||||
verify(events).onColorPaletteChanged(any(), any(), any())
|
verify(smallClockEvents).onRegionDarknessChanged(anyBoolean())
|
||||||
|
verify(largeClockEvents).onRegionDarknessChanged(anyBoolean())
|
||||||
|
|
||||||
clockEventController.registerListeners()
|
clockEventController.registerListeners()
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ import com.android.systemui.SysuiTestCase;
|
|||||||
import com.android.systemui.dump.DumpManager;
|
import com.android.systemui.dump.DumpManager;
|
||||||
import com.android.systemui.flags.FeatureFlags;
|
import com.android.systemui.flags.FeatureFlags;
|
||||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||||
import com.android.systemui.plugins.Clock;
|
import com.android.systemui.plugins.ClockController;
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.shared.clocks.AnimatableClockView;
|
import com.android.systemui.shared.clocks.AnimatableClockView;
|
||||||
import com.android.systemui.shared.clocks.ClockRegistry;
|
import com.android.systemui.shared.clocks.ClockRegistry;
|
||||||
@@ -87,7 +87,7 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
|
|||||||
@Mock
|
@Mock
|
||||||
KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
|
KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
|
||||||
@Mock
|
@Mock
|
||||||
private Clock mClock;
|
private ClockController mClock;
|
||||||
@Mock
|
@Mock
|
||||||
DumpManager mDumpManager;
|
DumpManager mDumpManager;
|
||||||
@Mock
|
@Mock
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
import com.android.systemui.plugins.Clock;
|
import com.android.systemui.plugins.ClockController;
|
||||||
|
import com.android.systemui.plugins.ClockFaceController;
|
||||||
import com.android.systemui.statusbar.StatusBarState;
|
import com.android.systemui.statusbar.StatusBarState;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -61,7 +62,13 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
|
|||||||
ViewGroup mMockKeyguardSliceView;
|
ViewGroup mMockKeyguardSliceView;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
Clock mClock;
|
ClockController mClock;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ClockFaceController mSmallClock;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ClockFaceController mLargeClock;
|
||||||
|
|
||||||
private FrameLayout mSmallClockFrame;
|
private FrameLayout mSmallClockFrame;
|
||||||
private FrameLayout mLargeClockFrame;
|
private FrameLayout mLargeClockFrame;
|
||||||
@@ -75,8 +82,11 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
|
|||||||
when(mMockKeyguardSliceView.findViewById(R.id.keyguard_status_area))
|
when(mMockKeyguardSliceView.findViewById(R.id.keyguard_status_area))
|
||||||
.thenReturn(mMockKeyguardSliceView);
|
.thenReturn(mMockKeyguardSliceView);
|
||||||
|
|
||||||
when(mClock.getSmallClock()).thenReturn(new TextView(getContext()));
|
when(mClock.getSmallClock()).thenReturn(mSmallClock);
|
||||||
when(mClock.getLargeClock()).thenReturn(new TextView(getContext()));
|
when(mClock.getLargeClock()).thenReturn(mLargeClock);
|
||||||
|
|
||||||
|
when(mSmallClock.getView()).thenReturn(new TextView(getContext()));
|
||||||
|
when(mLargeClock.getView()).thenReturn(new TextView(getContext()));
|
||||||
|
|
||||||
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
|
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
|
||||||
layoutInflater.setPrivateFactory(new LayoutInflater.Factory2() {
|
layoutInflater.setPrivateFactory(new LayoutInflater.Factory2() {
|
||||||
@@ -124,41 +134,49 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
|
|||||||
public void onPluginConnected_showClock() {
|
public void onPluginConnected_showClock() {
|
||||||
mKeyguardClockSwitch.setClock(mClock, StatusBarState.KEYGUARD);
|
mKeyguardClockSwitch.setClock(mClock, StatusBarState.KEYGUARD);
|
||||||
|
|
||||||
assertEquals(mClock.getSmallClock().getParent(), mSmallClockFrame);
|
assertEquals(mClock.getSmallClock().getView().getParent(), mSmallClockFrame);
|
||||||
assertEquals(mClock.getLargeClock().getParent(), mLargeClockFrame);
|
assertEquals(mClock.getLargeClock().getView().getParent(), mLargeClockFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onPluginConnected_showSecondPluginClock() {
|
public void onPluginConnected_showSecondPluginClock() {
|
||||||
// GIVEN a plugin has already connected
|
// GIVEN a plugin has already connected
|
||||||
Clock otherClock = mock(Clock.class);
|
ClockController otherClock = mock(ClockController.class);
|
||||||
when(otherClock.getSmallClock()).thenReturn(new TextView(getContext()));
|
ClockFaceController smallClock = mock(ClockFaceController.class);
|
||||||
when(otherClock.getLargeClock()).thenReturn(new TextView(getContext()));
|
ClockFaceController largeClock = mock(ClockFaceController.class);
|
||||||
|
when(otherClock.getSmallClock()).thenReturn(smallClock);
|
||||||
|
when(otherClock.getLargeClock()).thenReturn(largeClock);
|
||||||
|
when(smallClock.getView()).thenReturn(new TextView(getContext()));
|
||||||
|
when(largeClock.getView()).thenReturn(new TextView(getContext()));
|
||||||
mKeyguardClockSwitch.setClock(mClock, StatusBarState.KEYGUARD);
|
mKeyguardClockSwitch.setClock(mClock, StatusBarState.KEYGUARD);
|
||||||
mKeyguardClockSwitch.setClock(otherClock, StatusBarState.KEYGUARD);
|
mKeyguardClockSwitch.setClock(otherClock, StatusBarState.KEYGUARD);
|
||||||
|
|
||||||
// THEN only the view from the second plugin should be a child of KeyguardClockSwitch.
|
// THEN only the view from the second plugin should be a child of KeyguardClockSwitch.
|
||||||
assertThat(otherClock.getSmallClock().getParent()).isEqualTo(mSmallClockFrame);
|
assertThat(otherClock.getSmallClock().getView().getParent()).isEqualTo(mSmallClockFrame);
|
||||||
assertThat(otherClock.getLargeClock().getParent()).isEqualTo(mLargeClockFrame);
|
assertThat(otherClock.getLargeClock().getView().getParent()).isEqualTo(mLargeClockFrame);
|
||||||
assertThat(mClock.getSmallClock().getParent()).isNull();
|
assertThat(mClock.getSmallClock().getView().getParent()).isNull();
|
||||||
assertThat(mClock.getLargeClock().getParent()).isNull();
|
assertThat(mClock.getLargeClock().getView().getParent()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onPluginDisconnected_secondOfTwoDisconnected() {
|
public void onPluginDisconnected_secondOfTwoDisconnected() {
|
||||||
// GIVEN two plugins are connected
|
// GIVEN two plugins are connected
|
||||||
Clock otherClock = mock(Clock.class);
|
ClockController otherClock = mock(ClockController.class);
|
||||||
when(otherClock.getSmallClock()).thenReturn(new TextView(getContext()));
|
ClockFaceController smallClock = mock(ClockFaceController.class);
|
||||||
when(otherClock.getLargeClock()).thenReturn(new TextView(getContext()));
|
ClockFaceController largeClock = mock(ClockFaceController.class);
|
||||||
|
when(otherClock.getSmallClock()).thenReturn(smallClock);
|
||||||
|
when(otherClock.getLargeClock()).thenReturn(largeClock);
|
||||||
|
when(smallClock.getView()).thenReturn(new TextView(getContext()));
|
||||||
|
when(largeClock.getView()).thenReturn(new TextView(getContext()));
|
||||||
mKeyguardClockSwitch.setClock(otherClock, StatusBarState.KEYGUARD);
|
mKeyguardClockSwitch.setClock(otherClock, StatusBarState.KEYGUARD);
|
||||||
mKeyguardClockSwitch.setClock(mClock, StatusBarState.KEYGUARD);
|
mKeyguardClockSwitch.setClock(mClock, StatusBarState.KEYGUARD);
|
||||||
// WHEN the second plugin is disconnected
|
// WHEN the second plugin is disconnected
|
||||||
mKeyguardClockSwitch.setClock(null, StatusBarState.KEYGUARD);
|
mKeyguardClockSwitch.setClock(null, StatusBarState.KEYGUARD);
|
||||||
// THEN nothing should be shown
|
// THEN nothing should be shown
|
||||||
assertThat(otherClock.getSmallClock().getParent()).isNull();
|
assertThat(otherClock.getSmallClock().getView().getParent()).isNull();
|
||||||
assertThat(otherClock.getLargeClock().getParent()).isNull();
|
assertThat(otherClock.getLargeClock().getView().getParent()).isNull();
|
||||||
assertThat(mClock.getSmallClock().getParent()).isNull();
|
assertThat(mClock.getSmallClock().getView().getParent()).isNull();
|
||||||
assertThat(mClock.getLargeClock().getParent()).isNull();
|
assertThat(mClock.getLargeClock().getView().getParent()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import android.os.Handler
|
|||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.plugins.Clock
|
import com.android.systemui.plugins.ClockController
|
||||||
import com.android.systemui.plugins.ClockId
|
import com.android.systemui.plugins.ClockId
|
||||||
import com.android.systemui.plugins.ClockMetadata
|
import com.android.systemui.plugins.ClockMetadata
|
||||||
import com.android.systemui.plugins.ClockProviderPlugin
|
import com.android.systemui.plugins.ClockProviderPlugin
|
||||||
@@ -48,8 +48,8 @@ class ClockRegistryTest : SysuiTestCase() {
|
|||||||
@JvmField @Rule val mockito = MockitoJUnit.rule()
|
@JvmField @Rule val mockito = MockitoJUnit.rule()
|
||||||
@Mock private lateinit var mockContext: Context
|
@Mock private lateinit var mockContext: Context
|
||||||
@Mock private lateinit var mockPluginManager: PluginManager
|
@Mock private lateinit var mockPluginManager: PluginManager
|
||||||
@Mock private lateinit var mockClock: Clock
|
@Mock private lateinit var mockClock: ClockController
|
||||||
@Mock private lateinit var mockDefaultClock: Clock
|
@Mock private lateinit var mockDefaultClock: ClockController
|
||||||
@Mock private lateinit var mockThumbnail: Drawable
|
@Mock private lateinit var mockThumbnail: Drawable
|
||||||
@Mock private lateinit var mockHandler: Handler
|
@Mock private lateinit var mockHandler: Handler
|
||||||
@Mock private lateinit var mockContentResolver: ContentResolver
|
@Mock private lateinit var mockContentResolver: ContentResolver
|
||||||
@@ -60,7 +60,7 @@ class ClockRegistryTest : SysuiTestCase() {
|
|||||||
private var settingValue: String = ""
|
private var settingValue: String = ""
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private fun failFactory(): Clock {
|
private fun failFactory(): ClockController {
|
||||||
fail("Unexpected call to createClock")
|
fail("Unexpected call to createClock")
|
||||||
return null!!
|
return null!!
|
||||||
}
|
}
|
||||||
@@ -73,17 +73,17 @@ class ClockRegistryTest : SysuiTestCase() {
|
|||||||
|
|
||||||
private class FakeClockPlugin : ClockProviderPlugin {
|
private class FakeClockPlugin : ClockProviderPlugin {
|
||||||
private val metadata = mutableListOf<ClockMetadata>()
|
private val metadata = mutableListOf<ClockMetadata>()
|
||||||
private val createCallbacks = mutableMapOf<ClockId, () -> Clock>()
|
private val createCallbacks = mutableMapOf<ClockId, () -> ClockController>()
|
||||||
private val thumbnailCallbacks = mutableMapOf<ClockId, () -> Drawable?>()
|
private val thumbnailCallbacks = mutableMapOf<ClockId, () -> Drawable?>()
|
||||||
|
|
||||||
override fun getClocks() = metadata
|
override fun getClocks() = metadata
|
||||||
override fun createClock(id: ClockId): Clock = createCallbacks[id]!!()
|
override fun createClock(id: ClockId): ClockController = createCallbacks[id]!!()
|
||||||
override fun getClockThumbnail(id: ClockId): Drawable? = thumbnailCallbacks[id]!!()
|
override fun getClockThumbnail(id: ClockId): Drawable? = thumbnailCallbacks[id]!!()
|
||||||
|
|
||||||
fun addClock(
|
fun addClock(
|
||||||
id: ClockId,
|
id: ClockId,
|
||||||
name: String,
|
name: String,
|
||||||
create: () -> Clock = ::failFactory,
|
create: () -> ClockController = ::failFactory,
|
||||||
getThumbnail: () -> Drawable? = ::failThumbnail
|
getThumbnail: () -> Drawable? = ::failThumbnail
|
||||||
): FakeClockPlugin {
|
): FakeClockPlugin {
|
||||||
metadata.add(ClockMetadata(id, name))
|
metadata.add(ClockMetadata(id, name))
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.systemui.shared.clocks
|
package com.android.systemui.shared.clocks
|
||||||
|
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
|
import android.graphics.Color
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
@@ -25,7 +26,7 @@ import android.widget.FrameLayout
|
|||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.shared.clocks.DefaultClock.Companion.DOZE_COLOR
|
import com.android.systemui.shared.clocks.DefaultClockController.Companion.DOZE_COLOR
|
||||||
import com.android.systemui.util.mockito.any
|
import com.android.systemui.util.mockito.any
|
||||||
import com.android.systemui.util.mockito.eq
|
import com.android.systemui.util.mockito.eq
|
||||||
import com.android.systemui.util.mockito.mock
|
import com.android.systemui.util.mockito.mock
|
||||||
@@ -88,17 +89,20 @@ class DefaultClockProviderTest : SysuiTestCase() {
|
|||||||
// Default clock provider must always provide the default clock
|
// Default clock provider must always provide the default clock
|
||||||
val clock = provider.createClock(DEFAULT_CLOCK_ID)
|
val clock = provider.createClock(DEFAULT_CLOCK_ID)
|
||||||
assertNotNull(clock)
|
assertNotNull(clock)
|
||||||
assertEquals(clock.smallClock, mockSmallClockView)
|
assertEquals(mockSmallClockView, clock.smallClock.view)
|
||||||
assertEquals(clock.largeClock, mockLargeClockView)
|
assertEquals(mockLargeClockView, clock.largeClock.view)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun defaultClock_initialize() {
|
fun defaultClock_initialize() {
|
||||||
val clock = provider.createClock(DEFAULT_CLOCK_ID)
|
val clock = provider.createClock(DEFAULT_CLOCK_ID)
|
||||||
|
verify(mockSmallClockView).setColors(Color.MAGENTA, Color.MAGENTA)
|
||||||
|
verify(mockLargeClockView).setColors(Color.MAGENTA, Color.MAGENTA)
|
||||||
|
|
||||||
clock.initialize(resources, 0f, 0f)
|
clock.initialize(resources, 0f, 0f)
|
||||||
|
|
||||||
verify(mockSmallClockView, times(2)).setColors(eq(DOZE_COLOR), anyInt())
|
verify(mockSmallClockView).setColors(eq(DOZE_COLOR), anyInt())
|
||||||
verify(mockLargeClockView, times(2)).setColors(eq(DOZE_COLOR), anyInt())
|
verify(mockLargeClockView).setColors(eq(DOZE_COLOR), anyInt())
|
||||||
verify(mockSmallClockView).onTimeZoneChanged(notNull())
|
verify(mockSmallClockView).onTimeZoneChanged(notNull())
|
||||||
verify(mockLargeClockView).onTimeZoneChanged(notNull())
|
verify(mockLargeClockView).onTimeZoneChanged(notNull())
|
||||||
verify(mockSmallClockView).refreshTime()
|
verify(mockSmallClockView).refreshTime()
|
||||||
@@ -147,10 +151,14 @@ class DefaultClockProviderTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun defaultClock_events_onColorPaletteChanged() {
|
fun defaultClock_events_onColorPaletteChanged() {
|
||||||
val clock = provider.createClock(DEFAULT_CLOCK_ID)
|
val clock = provider.createClock(DEFAULT_CLOCK_ID)
|
||||||
clock.events.onColorPaletteChanged(resources, true, true)
|
|
||||||
|
|
||||||
verify(mockSmallClockView, times(2)).setColors(eq(DOZE_COLOR), anyInt())
|
verify(mockSmallClockView).setColors(Color.MAGENTA, Color.MAGENTA)
|
||||||
verify(mockLargeClockView, times(2)).setColors(eq(DOZE_COLOR), anyInt())
|
verify(mockLargeClockView).setColors(Color.MAGENTA, Color.MAGENTA)
|
||||||
|
|
||||||
|
clock.events.onColorPaletteChanged(resources)
|
||||||
|
|
||||||
|
verify(mockSmallClockView).setColors(eq(DOZE_COLOR), anyInt())
|
||||||
|
verify(mockLargeClockView).setColors(eq(DOZE_COLOR), anyInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user