Merge changes from topic "clock_cherrypick_fixes-master"
* changes: Initialize TimeZone during DefaultClockProvider init Correct large clock position Additional Tests for DefaultClock Update DefaultClockProvider colors Allow manually specified time
This commit is contained in:
committed by
Android (Google) Code Review
commit
d16b0c13b3
@@ -39,6 +39,7 @@
|
||||
-packages/SystemUI/src-release/com/android/systemui/flags/FlagsModule.kt
|
||||
-packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
|
||||
-packages/SystemUI/src/com/android/keyguard/BouncerPanelExpansionCalculator.kt
|
||||
-packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
|
||||
-packages/SystemUI/src/com/android/keyguard/KeyguardBiometricLockoutLogger.kt
|
||||
-packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
|
||||
-packages/SystemUI/src/com/android/keyguard/KeyguardListenQueue.kt
|
||||
@@ -156,6 +157,8 @@
|
||||
-packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
|
||||
-packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt
|
||||
-packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
|
||||
-packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderFactory.kt
|
||||
-packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderImpl.kt
|
||||
-packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt
|
||||
-packages/SystemUI/src/com/android/systemui/decor/DecorProviderFactory.kt
|
||||
-packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt
|
||||
@@ -246,6 +249,7 @@
|
||||
-packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt
|
||||
-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
|
||||
-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
|
||||
-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipRootView.kt
|
||||
-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLogger.kt
|
||||
-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt
|
||||
-packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
|
||||
@@ -575,6 +579,7 @@
|
||||
-packages/SystemUI/src/com/android/systemui/volume/VolumePanelFactory.kt
|
||||
-packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
|
||||
-packages/SystemUI/tests/src/com/android/keyguard/BouncerPanelExpansionCalculatorTest.kt
|
||||
-packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
|
||||
-packages/SystemUI/tests/src/com/android/keyguard/KeyguardBiometricLockoutLoggerTest.kt
|
||||
-packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
|
||||
-packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
|
||||
@@ -633,6 +638,7 @@
|
||||
-packages/SystemUI/tests/src/com/android/systemui/controls/management/TestControlsRequestDialog.kt
|
||||
-packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt
|
||||
-packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
|
||||
-packages/SystemUI/tests/src/com/android/systemui/decor/CutoutDecorProviderFactoryTest.kt
|
||||
-packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt
|
||||
-packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt
|
||||
-packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt
|
||||
@@ -720,6 +726,7 @@
|
||||
-packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordDialogTest.kt
|
||||
-packages/SystemUI/tests/src/com/android/systemui/screenshot/ImageCaptureImplTest.kt
|
||||
-packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt
|
||||
-packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt
|
||||
-packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt
|
||||
-packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt
|
||||
-packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
|
||||
|
||||
@@ -17,7 +17,6 @@ import android.content.res.Resources
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.View
|
||||
import com.android.systemui.plugins.annotations.ProvidesInterface
|
||||
import com.android.systemui.shared.regionsampling.RegionDarkness
|
||||
import java.io.PrintWriter
|
||||
import java.util.Locale
|
||||
import java.util.TimeZone
|
||||
@@ -62,7 +61,7 @@ interface Clock {
|
||||
|
||||
/** Initializes various rendering parameters. If never called, provides reasonable defaults. */
|
||||
fun initialize(resources: Resources, dozeFraction: Float, foldFraction: Float) {
|
||||
events.onColorPaletteChanged(resources, RegionDarkness.DEFAULT, RegionDarkness.DEFAULT)
|
||||
events.onColorPaletteChanged(resources, true, true)
|
||||
animations.doze(dozeFraction)
|
||||
animations.fold(foldFraction)
|
||||
events.onTimeTick()
|
||||
@@ -92,8 +91,8 @@ interface ClockEvents {
|
||||
/** Call whenever the color palette should update */
|
||||
fun onColorPaletteChanged(
|
||||
resources: Resources,
|
||||
smallClockIsDark: RegionDarkness,
|
||||
largeClockIsDark: RegionDarkness
|
||||
smallClockIsDark: Boolean,
|
||||
largeClockIsDark: Boolean
|
||||
) { }
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
android:id="@+id/keyguard_clock_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:layout_gravity="center_horizontal|top">
|
||||
<FrameLayout
|
||||
android:id="@+id/lockscreen_clock_view"
|
||||
@@ -30,16 +31,13 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:paddingStart="@dimen/clock_padding_start">
|
||||
</FrameLayout>
|
||||
android:paddingStart="@dimen/clock_padding_start" />
|
||||
<FrameLayout
|
||||
android:id="@+id/lockscreen_clock_view_large"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/keyguard_slice_view"
|
||||
android:paddingTop="@dimen/keyguard_large_clock_top_padding"
|
||||
android:visibility="gone">
|
||||
</FrameLayout>
|
||||
android:layout_marginTop="@dimen/keyguard_large_clock_top_margin"
|
||||
android:visibility="gone" />
|
||||
|
||||
<!-- Not quite optimal but needed to translate these items as a group. The
|
||||
NotificationIconContainer has its own logic for translation. -->
|
||||
|
||||
@@ -669,7 +669,7 @@
|
||||
<!-- When large clock is showing, offset the smartspace by this amount -->
|
||||
<dimen name="keyguard_smartspace_top_offset">12dp</dimen>
|
||||
<!-- With the large clock, move up slightly from the center -->
|
||||
<dimen name="keyguard_large_clock_top_padding">100dp</dimen>
|
||||
<dimen name="keyguard_large_clock_top_margin">-60dp</dimen>
|
||||
|
||||
<dimen name="notification_scrim_corner_radius">32dp</dimen>
|
||||
|
||||
|
||||
@@ -36,9 +36,13 @@ import platform.test.screenshot.DeviceEmulationSpec
|
||||
import platform.test.screenshot.MaterialYouColorsRule
|
||||
import platform.test.screenshot.ScreenshotTestRule
|
||||
import platform.test.screenshot.getEmulatedDevicePathConfig
|
||||
import platform.test.screenshot.matchers.BitmapMatcher
|
||||
|
||||
/** A rule for View screenshot diff unit tests. */
|
||||
class ViewScreenshotTestRule(emulationSpec: DeviceEmulationSpec) : TestRule {
|
||||
class ViewScreenshotTestRule(
|
||||
emulationSpec: DeviceEmulationSpec,
|
||||
private val matcher: BitmapMatcher = UnitTestBitmapMatcher
|
||||
) : TestRule {
|
||||
private val colorsRule = MaterialYouColorsRule()
|
||||
private val deviceEmulationRule = DeviceEmulationRule(emulationSpec)
|
||||
private val screenshotRule =
|
||||
@@ -51,7 +55,6 @@ class ViewScreenshotTestRule(emulationSpec: DeviceEmulationSpec) : TestRule {
|
||||
.around(deviceEmulationRule)
|
||||
.around(screenshotRule)
|
||||
.around(activityRule)
|
||||
private val matcher = UnitTestBitmapMatcher
|
||||
|
||||
override fun apply(base: Statement, description: Description): Statement {
|
||||
return delegateRule.apply(base, description)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
-->
|
||||
<com.android.systemui.shared.clocks.AnimatableClockView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:gravity="start"
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.util.AttributeSet
|
||||
import android.widget.TextView
|
||||
import com.android.internal.R.attr.contentDescription
|
||||
import com.android.internal.R.attr.format
|
||||
import com.android.internal.annotations.VisibleForTesting
|
||||
import com.android.systemui.animation.GlyphCallback
|
||||
import com.android.systemui.animation.Interpolators
|
||||
import com.android.systemui.animation.TextAnimator
|
||||
@@ -77,6 +78,9 @@ class AnimatableClockView @JvmOverloads constructor(
|
||||
private var textAnimator: TextAnimator? = null
|
||||
private var onTextAnimatorInitialized: Runnable? = null
|
||||
|
||||
@VisibleForTesting var isAnimationEnabled: Boolean = true
|
||||
@VisibleForTesting var timeOverrideInMillis: Long? = null
|
||||
|
||||
val dozingWeight: Int
|
||||
get() = if (useBoldedVersion()) dozingWeightInternal + 100 else dozingWeightInternal
|
||||
|
||||
@@ -139,7 +143,7 @@ class AnimatableClockView @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
fun refreshTime() {
|
||||
time.timeInMillis = System.currentTimeMillis()
|
||||
time.timeInMillis = timeOverrideInMillis ?: System.currentTimeMillis()
|
||||
contentDescription = DateFormat.format(descFormat, time)
|
||||
val formattedText = DateFormat.format(format, time)
|
||||
// Setting text actually triggers a layout pass (because the text view is set to
|
||||
@@ -215,7 +219,7 @@ class AnimatableClockView @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
fun animateAppearOnLockscreen() {
|
||||
if (textAnimator == null) {
|
||||
if (isAnimationEnabled && textAnimator == null) {
|
||||
return
|
||||
}
|
||||
setTextStyle(
|
||||
@@ -231,7 +235,7 @@ class AnimatableClockView @JvmOverloads constructor(
|
||||
weight = lockScreenWeight,
|
||||
textSize = -1f,
|
||||
color = lockScreenColor,
|
||||
animate = true,
|
||||
animate = isAnimationEnabled,
|
||||
duration = APPEAR_ANIM_DURATION,
|
||||
delay = 0,
|
||||
onAnimationEnd = null
|
||||
@@ -239,7 +243,7 @@ class AnimatableClockView @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
fun animateFoldAppear(animate: Boolean = true) {
|
||||
if (textAnimator == null) {
|
||||
if (isAnimationEnabled && textAnimator == null) {
|
||||
return
|
||||
}
|
||||
setTextStyle(
|
||||
@@ -255,7 +259,7 @@ class AnimatableClockView @JvmOverloads constructor(
|
||||
weight = dozingWeightInternal,
|
||||
textSize = -1f,
|
||||
color = dozingColor,
|
||||
animate = animate,
|
||||
animate = animate && isAnimationEnabled,
|
||||
interpolator = Interpolators.EMPHASIZED_DECELERATE,
|
||||
duration = ANIMATION_DURATION_FOLD_TO_AOD.toLong(),
|
||||
delay = 0,
|
||||
@@ -273,7 +277,7 @@ class AnimatableClockView @JvmOverloads constructor(
|
||||
weight = if (isDozing()) dozingWeight else lockScreenWeight,
|
||||
textSize = -1f,
|
||||
color = null,
|
||||
animate = true,
|
||||
animate = isAnimationEnabled,
|
||||
duration = CHARGE_ANIM_DURATION_PHASE_1,
|
||||
delay = 0,
|
||||
onAnimationEnd = null
|
||||
@@ -283,7 +287,7 @@ class AnimatableClockView @JvmOverloads constructor(
|
||||
weight = if (isDozing()) lockScreenWeight else dozingWeight,
|
||||
textSize = -1f,
|
||||
color = null,
|
||||
animate = true,
|
||||
animate = isAnimationEnabled,
|
||||
duration = CHARGE_ANIM_DURATION_PHASE_0,
|
||||
delay = chargeAnimationDelay.toLong(),
|
||||
onAnimationEnd = startAnimPhase2
|
||||
@@ -295,7 +299,7 @@ class AnimatableClockView @JvmOverloads constructor(
|
||||
weight = if (isDozing) dozingWeight else lockScreenWeight,
|
||||
textSize = -1f,
|
||||
color = if (isDozing) dozingColor else lockScreenColor,
|
||||
animate = animate,
|
||||
animate = animate && isAnimationEnabled,
|
||||
duration = DOZE_ANIM_DURATION,
|
||||
delay = 0,
|
||||
onAnimationEnd = null
|
||||
@@ -329,7 +333,7 @@ class AnimatableClockView @JvmOverloads constructor(
|
||||
weight = weight,
|
||||
textSize = textSize,
|
||||
color = color,
|
||||
animate = animate,
|
||||
animate = animate && isAnimationEnabled,
|
||||
duration = duration,
|
||||
interpolator = interpolator,
|
||||
delay = delay,
|
||||
@@ -367,7 +371,7 @@ class AnimatableClockView @JvmOverloads constructor(
|
||||
weight = weight,
|
||||
textSize = textSize,
|
||||
color = color,
|
||||
animate = animate,
|
||||
animate = animate && isAnimationEnabled,
|
||||
interpolator = null,
|
||||
duration = duration,
|
||||
delay = delay,
|
||||
|
||||
@@ -13,12 +13,15 @@
|
||||
*/
|
||||
package com.android.systemui.shared.clocks
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.icu.text.NumberFormat
|
||||
import android.util.TypedValue
|
||||
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.plugins.Clock
|
||||
import com.android.systemui.plugins.ClockAnimations
|
||||
@@ -27,7 +30,6 @@ import com.android.systemui.plugins.ClockId
|
||||
import com.android.systemui.plugins.ClockMetadata
|
||||
import com.android.systemui.plugins.ClockProvider
|
||||
import com.android.systemui.shared.R
|
||||
import com.android.systemui.shared.regionsampling.RegionDarkness
|
||||
import java.io.PrintWriter
|
||||
import java.util.Locale
|
||||
import java.util.TimeZone
|
||||
@@ -39,6 +41,7 @@ const val DEFAULT_CLOCK_ID = "DEFAULT"
|
||||
|
||||
/** Provides the default system clock */
|
||||
class DefaultClockProvider @Inject constructor(
|
||||
val ctx: Context,
|
||||
val layoutInflater: LayoutInflater,
|
||||
@Main val resources: Resources
|
||||
) : ClockProvider {
|
||||
@@ -49,7 +52,7 @@ class DefaultClockProvider @Inject constructor(
|
||||
if (id != DEFAULT_CLOCK_ID) {
|
||||
throw IllegalArgumentException("$id is unsupported by $TAG")
|
||||
}
|
||||
return DefaultClock(layoutInflater, resources)
|
||||
return DefaultClock(ctx, layoutInflater, resources)
|
||||
}
|
||||
|
||||
override fun getClockThumbnail(id: ClockId): Drawable? {
|
||||
@@ -69,14 +72,13 @@ class DefaultClockProvider @Inject constructor(
|
||||
* AnimatableClockView used by the existing lockscreen clock.
|
||||
*/
|
||||
class DefaultClock(
|
||||
ctx: Context,
|
||||
private val layoutInflater: LayoutInflater,
|
||||
private val resources: Resources
|
||||
) : Clock {
|
||||
override val smallClock =
|
||||
layoutInflater.inflate(R.layout.clock_default_small, null) as AnimatableClockView
|
||||
override val largeClock =
|
||||
layoutInflater.inflate(R.layout.clock_default_large, null) as AnimatableClockView
|
||||
private val clocks = listOf(smallClock, largeClock)
|
||||
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())
|
||||
@@ -84,20 +86,46 @@ class DefaultClock(
|
||||
resources.getFloat(R.dimen.keyguard_clock_line_spacing_scale_burmese)
|
||||
private val defaultLineSpacing = resources.getFloat(R.dimen.keyguard_clock_line_spacing_scale)
|
||||
|
||||
private var smallRegionDarkness = RegionDarkness.DEFAULT
|
||||
private var largeRegionDarkness = RegionDarkness.DEFAULT
|
||||
override val events: ClockEvents
|
||||
override lateinit var animations: ClockAnimations
|
||||
private set
|
||||
|
||||
private fun updateClockColor(clock: AnimatableClockView, isRegionDark: RegionDarkness) {
|
||||
val color = if (isRegionDark.isDark) {
|
||||
resources.getColor(android.R.color.system_accent2_100)
|
||||
} else {
|
||||
resources.getColor(android.R.color.system_accent1_600)
|
||||
}
|
||||
clock.setColors(DOZE_COLOR, color)
|
||||
clock.animateAppearOnLockscreen()
|
||||
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 val events = object : ClockEvents {
|
||||
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) =
|
||||
@@ -120,8 +148,8 @@ class DefaultClock(
|
||||
|
||||
override fun onColorPaletteChanged(
|
||||
resources: Resources,
|
||||
smallClockIsDark: RegionDarkness,
|
||||
largeClockIsDark: RegionDarkness
|
||||
smallClockIsDark: Boolean,
|
||||
largeClockIsDark: Boolean
|
||||
) {
|
||||
if (smallRegionDarkness != smallClockIsDark) {
|
||||
smallRegionDarkness = smallClockIsDark
|
||||
@@ -145,9 +173,6 @@ class DefaultClock(
|
||||
}
|
||||
}
|
||||
|
||||
override var animations = DefaultClockAnimations(0f, 0f)
|
||||
private set
|
||||
|
||||
inner class DefaultClockAnimations(
|
||||
dozeFraction: Float,
|
||||
foldFraction: Float
|
||||
@@ -203,35 +228,26 @@ class DefaultClock(
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
events.onLocaleChanged(Locale.getDefault())
|
||||
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,
|
||||
RegionDarkness.DEFAULT,
|
||||
RegionDarkness.DEFAULT
|
||||
)
|
||||
events.onTimeTick()
|
||||
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 topPadding = -1 * (largeClock.bottom.toInt() - 180)
|
||||
largeClock.setPadding(0, topPadding, 0, 0)
|
||||
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 {
|
||||
private const val DOZE_COLOR = Color.WHITE
|
||||
@VisibleForTesting const val DOZE_COLOR = Color.WHITE
|
||||
private const val FORMAT_NUMBER = 1234567890
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.res.Resources
|
||||
import android.text.format.DateFormat
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher
|
||||
import com.android.systemui.dagger.qualifiers.Background
|
||||
import com.android.systemui.dagger.qualifiers.Main
|
||||
@@ -41,7 +43,7 @@ import javax.inject.Inject
|
||||
* Controller for a Clock provided by the registry and used on the keyguard. Instantiated by
|
||||
* [KeyguardClockSwitchController]. Functionality is forked from [AnimatableClockController].
|
||||
*/
|
||||
class ClockEventController @Inject constructor(
|
||||
open class ClockEventController @Inject constructor(
|
||||
private val statusBarStateController: StatusBarStateController,
|
||||
private val broadcastDispatcher: BroadcastDispatcher,
|
||||
private val batteryController: BatteryController,
|
||||
@@ -74,18 +76,21 @@ class ClockEventController @Inject constructor(
|
||||
|
||||
private val updateFun = object : RegionSamplingInstance.UpdateColorCallback {
|
||||
override fun updateColors() {
|
||||
smallClockIsDark = smallRegionSamplingInstance.currentRegionDarkness()
|
||||
largeClockIsDark = largeRegionSamplingInstance.currentRegionDarkness()
|
||||
|
||||
if (regionSamplingEnabled) {
|
||||
smallClockIsDark = smallRegionSamplingInstance.currentRegionDarkness().isDark
|
||||
largeClockIsDark = largeRegionSamplingInstance.currentRegionDarkness().isDark
|
||||
} else {
|
||||
val isLightTheme = TypedValue()
|
||||
context.theme.resolveAttribute(android.R.attr.isLightTheme, isLightTheme, true)
|
||||
smallClockIsDark = isLightTheme.data == 0
|
||||
largeClockIsDark = isLightTheme.data == 0
|
||||
}
|
||||
clock?.events?.onColorPaletteChanged(resources, smallClockIsDark, largeClockIsDark)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateRegionSamplers(currentClock: Clock?) {
|
||||
smallRegionSamplingInstance.stopRegionSampler()
|
||||
largeRegionSamplingInstance.stopRegionSampler()
|
||||
|
||||
smallRegionSamplingInstance = RegionSamplingInstance(
|
||||
smallRegionSamplingInstance = createRegionSampler(
|
||||
currentClock?.smallClock,
|
||||
mainExecutor,
|
||||
bgExecutor,
|
||||
@@ -93,7 +98,7 @@ class ClockEventController @Inject constructor(
|
||||
updateFun
|
||||
)
|
||||
|
||||
largeRegionSamplingInstance = RegionSamplingInstance(
|
||||
largeRegionSamplingInstance = createRegionSampler(
|
||||
currentClock?.largeClock,
|
||||
mainExecutor,
|
||||
bgExecutor,
|
||||
@@ -107,24 +112,26 @@ class ClockEventController @Inject constructor(
|
||||
updateFun.updateColors()
|
||||
}
|
||||
|
||||
var smallRegionSamplingInstance: RegionSamplingInstance = RegionSamplingInstance(
|
||||
clock?.smallClock,
|
||||
protected open fun createRegionSampler(
|
||||
sampledView: View?,
|
||||
mainExecutor: Executor?,
|
||||
bgExecutor: Executor?,
|
||||
regionSamplingEnabled: Boolean,
|
||||
updateFun: RegionSamplingInstance.UpdateColorCallback
|
||||
): RegionSamplingInstance {
|
||||
return RegionSamplingInstance(
|
||||
sampledView,
|
||||
mainExecutor,
|
||||
bgExecutor,
|
||||
regionSamplingEnabled,
|
||||
updateFun
|
||||
)
|
||||
updateFun)
|
||||
}
|
||||
|
||||
var largeRegionSamplingInstance: RegionSamplingInstance = RegionSamplingInstance(
|
||||
clock?.largeClock,
|
||||
mainExecutor,
|
||||
bgExecutor,
|
||||
regionSamplingEnabled,
|
||||
updateFun
|
||||
)
|
||||
lateinit var smallRegionSamplingInstance: RegionSamplingInstance
|
||||
lateinit var largeRegionSamplingInstance: RegionSamplingInstance
|
||||
|
||||
private var smallClockIsDark = smallRegionSamplingInstance.currentRegionDarkness()
|
||||
private var largeClockIsDark = largeRegionSamplingInstance.currentRegionDarkness()
|
||||
private var smallClockIsDark = true
|
||||
private var largeClockIsDark = true
|
||||
|
||||
private val configListener = object : ConfigurationController.ConfigurationListener {
|
||||
override fun onThemeChanged() {
|
||||
@@ -179,7 +186,6 @@ class ClockEventController @Inject constructor(
|
||||
|
||||
init {
|
||||
isDozing = statusBarStateController.isDozing
|
||||
clock?.events?.onColorPaletteChanged(resources, smallClockIsDark, largeClockIsDark)
|
||||
}
|
||||
|
||||
fun registerListeners() {
|
||||
|
||||
@@ -8,7 +8,6 @@ import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
@@ -68,6 +67,7 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
||||
|
||||
private int mClockSwitchYAmount;
|
||||
@VisibleForTesting boolean mChildrenAreLaidOut = false;
|
||||
@VisibleForTesting boolean mAnimateOnLayout = true;
|
||||
|
||||
public KeyguardClockSwitch(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@@ -105,9 +105,7 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
||||
}
|
||||
|
||||
// Attach small and big clock views to hierarchy.
|
||||
mSmallClockFrame.addView(clock.getSmallClock(), -1,
|
||||
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
mSmallClockFrame.addView(clock.getSmallClock());
|
||||
mLargeClockFrame.addView(clock.getLargeClock());
|
||||
}
|
||||
|
||||
@@ -214,7 +212,7 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
||||
super.onLayout(changed, l, t, r, b);
|
||||
|
||||
if (mDisplayedClockSize != null && !mChildrenAreLaidOut) {
|
||||
post(() -> updateClockViews(mDisplayedClockSize == LARGE, /* animate */ true));
|
||||
post(() -> updateClockViews(mDisplayedClockSize == LARGE, mAnimateOnLayout));
|
||||
}
|
||||
|
||||
mChildrenAreLaidOut = true;
|
||||
@@ -222,7 +220,7 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
||||
|
||||
public void dump(PrintWriter pw, String[] args) {
|
||||
pw.println("KeyguardClockSwitch:");
|
||||
pw.println(" mClockFrame: " + mSmallClockFrame);
|
||||
pw.println(" mSmallClockFrame: " + mSmallClockFrame);
|
||||
pw.println(" mLargeClockFrame: " + mLargeClockFrame);
|
||||
pw.println(" mStatusArea: " + mStatusArea);
|
||||
pw.println(" mDisplayedClockSize: " + mDisplayedClockSize);
|
||||
|
||||
@@ -72,7 +72,6 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
||||
private final DumpManager mDumpManager;
|
||||
private final ClockEventController mClockEventController;
|
||||
|
||||
/** Clock frames for both small and large sizes */
|
||||
private FrameLayout mSmallClockFrame; // top aligned clock
|
||||
private FrameLayout mLargeClockFrame; // centered clock
|
||||
|
||||
@@ -151,7 +150,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
||||
* Attach the controller to the view it relates to.
|
||||
*/
|
||||
@Override
|
||||
public void onInit() {
|
||||
protected void onInit() {
|
||||
mKeyguardSliceViewController.init();
|
||||
|
||||
mSmallClockFrame = mView.findViewById(R.id.lockscreen_clock_view);
|
||||
@@ -390,8 +389,6 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
||||
* bounds during the unlock transition.
|
||||
*/
|
||||
private void setClipChildrenForUnlock(boolean clip) {
|
||||
mView.setClipChildren(clip);
|
||||
|
||||
if (mStatusArea != null) {
|
||||
mStatusArea.setClipChildren(clip);
|
||||
}
|
||||
|
||||
@@ -259,6 +259,7 @@ class ClockEventControllerTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun unregisterListeners_validate() {
|
||||
clockEventController.clock = clock
|
||||
clockEventController.unregisterListeners()
|
||||
verify(broadcastDispatcher).unregisterReceiver(any())
|
||||
verify(configurationController).removeCallback(any())
|
||||
|
||||
@@ -19,17 +19,31 @@ package com.android.systemui.shared.clocks
|
||||
import android.content.res.Resources
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.FrameLayout
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.shared.clocks.DefaultClock.Companion.DOZE_COLOR
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.eq
|
||||
import com.android.systemui.util.mockito.mock
|
||||
import java.util.Locale
|
||||
import java.util.TimeZone
|
||||
import junit.framework.Assert.assertEquals
|
||||
import junit.framework.Assert.assertNotNull
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentMatchers.anyBoolean
|
||||
import org.mockito.ArgumentMatchers.anyFloat
|
||||
import org.mockito.ArgumentMatchers.anyInt
|
||||
import org.mockito.ArgumentMatchers.notNull
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.times
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
|
||||
@@ -39,7 +53,8 @@ class DefaultClockProviderTest : SysuiTestCase() {
|
||||
|
||||
@JvmField @Rule val mockito = MockitoJUnit.rule()
|
||||
|
||||
@Mock private lateinit var mockClockView: AnimatableClockView
|
||||
@Mock private lateinit var mockSmallClockView: AnimatableClockView
|
||||
@Mock private lateinit var mockLargeClockView: AnimatableClockView
|
||||
@Mock private lateinit var layoutInflater: LayoutInflater
|
||||
@Mock private lateinit var mockClockThumbnail: Drawable
|
||||
@Mock private lateinit var resources: Resources
|
||||
@@ -47,14 +62,16 @@ class DefaultClockProviderTest : SysuiTestCase() {
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
whenever(layoutInflater.inflate(R.layout.clock_default_small, null))
|
||||
.thenReturn(mockClockView)
|
||||
whenever(layoutInflater.inflate(R.layout.clock_default_large, null))
|
||||
.thenReturn(mockClockView)
|
||||
whenever(layoutInflater.inflate(eq(R.layout.clock_default_small), any(), anyBoolean()))
|
||||
.thenReturn(mockSmallClockView)
|
||||
whenever(layoutInflater.inflate(eq(R.layout.clock_default_large), any(), anyBoolean()))
|
||||
.thenReturn(mockLargeClockView)
|
||||
whenever(resources.getDrawable(R.drawable.clock_default_thumbnail, null))
|
||||
.thenReturn(mockClockThumbnail)
|
||||
whenever(mockSmallClockView.getLayoutParams()).thenReturn(FrameLayout.LayoutParams(10, 10))
|
||||
whenever(mockLargeClockView.getLayoutParams()).thenReturn(FrameLayout.LayoutParams(10, 10))
|
||||
|
||||
provider = DefaultClockProvider(layoutInflater, resources)
|
||||
provider = DefaultClockProvider(context, layoutInflater, resources)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -71,7 +88,79 @@ class DefaultClockProviderTest : SysuiTestCase() {
|
||||
// Default clock provider must always provide the default clock
|
||||
val clock = provider.createClock(DEFAULT_CLOCK_ID)
|
||||
assertNotNull(clock)
|
||||
assertEquals(clock.smallClock, mockClockView)
|
||||
assertEquals(clock.largeClock, mockClockView)
|
||||
assertEquals(clock.smallClock, mockSmallClockView)
|
||||
assertEquals(clock.largeClock, mockLargeClockView)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun defaultClock_initialize() {
|
||||
val clock = provider.createClock(DEFAULT_CLOCK_ID)
|
||||
clock.initialize(resources, 0f, 0f)
|
||||
|
||||
verify(mockSmallClockView, times(2)).setColors(eq(DOZE_COLOR), anyInt())
|
||||
verify(mockLargeClockView, times(2)).setColors(eq(DOZE_COLOR), anyInt())
|
||||
verify(mockSmallClockView).onTimeZoneChanged(notNull())
|
||||
verify(mockLargeClockView).onTimeZoneChanged(notNull())
|
||||
verify(mockSmallClockView).refreshTime()
|
||||
verify(mockLargeClockView).refreshTime()
|
||||
verify(mockLargeClockView).setLayoutParams(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun defaultClock_events_onTimeTick() {
|
||||
val clock = provider.createClock(DEFAULT_CLOCK_ID)
|
||||
clock.events.onTimeTick()
|
||||
|
||||
verify(mockSmallClockView).refreshTime()
|
||||
verify(mockLargeClockView).refreshTime()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun defaultClock_events_onTimeFormatChanged() {
|
||||
val clock = provider.createClock(DEFAULT_CLOCK_ID)
|
||||
clock.events.onTimeFormatChanged(true)
|
||||
|
||||
verify(mockSmallClockView).refreshFormat(true)
|
||||
verify(mockLargeClockView).refreshFormat(true)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun defaultClock_events_onTimeZoneChanged() {
|
||||
val timeZone = mock<TimeZone>()
|
||||
val clock = provider.createClock(DEFAULT_CLOCK_ID)
|
||||
clock.events.onTimeZoneChanged(timeZone)
|
||||
|
||||
verify(mockSmallClockView).onTimeZoneChanged(timeZone)
|
||||
verify(mockLargeClockView).onTimeZoneChanged(timeZone)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun defaultClock_events_onFontSettingChanged() {
|
||||
val clock = provider.createClock(DEFAULT_CLOCK_ID)
|
||||
clock.events.onFontSettingChanged()
|
||||
|
||||
verify(mockSmallClockView).setTextSize(eq(TypedValue.COMPLEX_UNIT_PX), anyFloat())
|
||||
verify(mockLargeClockView).setTextSize(eq(TypedValue.COMPLEX_UNIT_PX), anyFloat())
|
||||
verify(mockLargeClockView).setLayoutParams(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun defaultClock_events_onColorPaletteChanged() {
|
||||
val clock = provider.createClock(DEFAULT_CLOCK_ID)
|
||||
clock.events.onColorPaletteChanged(resources, true, true)
|
||||
|
||||
verify(mockSmallClockView, times(2)).setColors(eq(DOZE_COLOR), anyInt())
|
||||
verify(mockLargeClockView, times(2)).setColors(eq(DOZE_COLOR), anyInt())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun defaultClock_events_onLocaleChanged() {
|
||||
val clock = provider.createClock(DEFAULT_CLOCK_ID)
|
||||
clock.events.onLocaleChanged(Locale.getDefault())
|
||||
|
||||
verify(mockSmallClockView, times(2)).setLineSpacingScale(anyFloat())
|
||||
verify(mockLargeClockView, times(2)).setLineSpacingScale(anyFloat())
|
||||
verify(mockSmallClockView, times(2)).refreshFormat()
|
||||
verify(mockLargeClockView, times(2)).refreshFormat()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user