Migrate KeyguardClockSwitch to new shared Clock library
This change modifies the KeyguardClockSwitch and Controller to get clocks from the ClockRegistry. Since the only clock available from the registry is the default one, this should have no user-facing changes, and is intended only to update the relevant codepaths. Bug: 229771520 Test: Manual and Automated Change-Id: Ia053aaec6987e00de980388a6c024d8bcf5203a2
This commit is contained in:
@@ -474,7 +474,13 @@ class TextInterpolator(layout: Layout) {
|
|||||||
val out = mutableListOf<List<PositionedGlyphs>>()
|
val out = mutableListOf<List<PositionedGlyphs>>()
|
||||||
for (lineNo in 0 until layout.lineCount) { // Shape all lines.
|
for (lineNo in 0 until layout.lineCount) { // Shape all lines.
|
||||||
val lineStart = layout.getLineStart(lineNo)
|
val lineStart = layout.getLineStart(lineNo)
|
||||||
val count = layout.getLineEnd(lineNo) - lineStart
|
var count = layout.getLineEnd(lineNo) - lineStart
|
||||||
|
// Do not render the last character in the line if it's a newline and unprintable
|
||||||
|
val last = lineStart + count - 1
|
||||||
|
if (last > lineStart && last < layout.text.length && layout.text[last] == '\n') {
|
||||||
|
count--
|
||||||
|
}
|
||||||
|
|
||||||
val runs = mutableListOf<PositionedGlyphs>()
|
val runs = mutableListOf<PositionedGlyphs>()
|
||||||
TextShaper.shapeText(
|
TextShaper.shapeText(
|
||||||
layout.text,
|
layout.text,
|
||||||
|
|||||||
@@ -13,9 +13,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.systemui.plugins
|
package com.android.systemui.plugins
|
||||||
|
|
||||||
|
import android.content.res.Resources
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import com.android.internal.colorextraction.ColorExtractor
|
|
||||||
import com.android.systemui.plugins.annotations.ProvidesInterface
|
import com.android.systemui.plugins.annotations.ProvidesInterface
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
@@ -57,7 +57,15 @@ interface Clock {
|
|||||||
val events: ClockEvents
|
val events: ClockEvents
|
||||||
|
|
||||||
/** Triggers for various animations */
|
/** Triggers for various animations */
|
||||||
val animation: ClockAnimation
|
val animations: ClockAnimations
|
||||||
|
|
||||||
|
/** Initializes various rendering parameters. If never called, provides reasonable defaults. */
|
||||||
|
fun initialize(resources: Resources, dozeFraction: Float, foldFraction: Float) {
|
||||||
|
events.onColorPaletteChanged(resources)
|
||||||
|
animations.doze(dozeFraction)
|
||||||
|
animations.fold(foldFraction)
|
||||||
|
events.onTimeTick()
|
||||||
|
}
|
||||||
|
|
||||||
/** Optional method for dumping debug information */
|
/** Optional method for dumping debug information */
|
||||||
fun dump(pw: PrintWriter) { }
|
fun dump(pw: PrintWriter) { }
|
||||||
@@ -80,15 +88,12 @@ interface ClockEvents {
|
|||||||
/** Call whenever font settings change */
|
/** Call whenever font settings change */
|
||||||
fun onFontSettingChanged() { }
|
fun onFontSettingChanged() { }
|
||||||
|
|
||||||
/** Call whenever the color pallete should update */
|
/** Call whenever the color palette should update */
|
||||||
fun onColorPaletteChanged(palette: ColorExtractor.GradientColors) { }
|
fun onColorPaletteChanged(resources: Resources) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Methods which trigger various clock animations */
|
/** Methods which trigger various clock animations */
|
||||||
interface ClockAnimation {
|
interface ClockAnimations {
|
||||||
/** Initializes the doze & fold animation positions. Defaults to neither folded nor dozing. */
|
|
||||||
fun initialize(dozeFraction: Float, foldFraction: Float) { }
|
|
||||||
|
|
||||||
/** Runs an enter animation (if any) */
|
/** Runs an enter animation (if any) */
|
||||||
fun enter() { }
|
fun enter() { }
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
**
|
|
||||||
** Copyright 2020, 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.
|
|
||||||
*/
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
** AOD/LockScreen Clock font.
|
|
||||||
** Should include all numeric glyphs in all supported locales.
|
|
||||||
** Recommended: font with variable width to support AOD => LS animations
|
|
||||||
-->
|
|
||||||
<!-- TODO: Remove when clock migration complete -->
|
|
||||||
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<font android:typeface="monospace"/>
|
|
||||||
</font-family>
|
|
||||||
@@ -31,42 +31,14 @@
|
|||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:paddingStart="@dimen/clock_padding_start">
|
android:paddingStart="@dimen/clock_padding_start">
|
||||||
<com.android.systemui.shared.clocks.AnimatableClockView
|
|
||||||
android:id="@+id/animatable_clock_view"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="start"
|
|
||||||
android:gravity="start"
|
|
||||||
android:textSize="@dimen/clock_text_size"
|
|
||||||
android:fontFamily="@font/clock"
|
|
||||||
android:elegantTextHeight="false"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:fontFeatureSettings="pnum"
|
|
||||||
chargeAnimationDelay="350"
|
|
||||||
dozeWeight="200"
|
|
||||||
lockScreenWeight="400"
|
|
||||||
/>
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/lockscreen_clock_view_large"
|
android:id="@+id/lockscreen_clock_view_large"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_below="@id/keyguard_slice_view"
|
android:layout_below="@id/keyguard_slice_view"
|
||||||
|
android:paddingTop="@dimen/keyguard_large_clock_top_padding"
|
||||||
android:visibility="gone">
|
android:visibility="gone">
|
||||||
<com.android.systemui.shared.clocks.AnimatableClockView
|
|
||||||
android:id="@+id/animatable_clock_view_large"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:textSize="@dimen/large_clock_text_size"
|
|
||||||
android:fontFamily="@font/clock"
|
|
||||||
android:typeface="monospace"
|
|
||||||
android:elegantTextHeight="false"
|
|
||||||
chargeAnimationDelay="200"
|
|
||||||
dozeWeight="200"
|
|
||||||
lockScreenWeight="400"
|
|
||||||
/>
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<!-- Not quite optimal but needed to translate these items as a group. The
|
<!-- Not quite optimal but needed to translate these items as a group. The
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
android:id="@+id/time_view"
|
android:id="@+id/time_view"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fontFamily="@font/clock"
|
android:fontFamily="@*android:string/config_clockFontFamily"
|
||||||
android:includeFontPadding="false"
|
android:includeFontPadding="false"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:format12Hour="h:mm"
|
android:format12Hour="h:mm"
|
||||||
|
|||||||
@@ -661,13 +661,7 @@
|
|||||||
<!-- When large clock is showing, offset the smartspace by this amount -->
|
<!-- When large clock is showing, offset the smartspace by this amount -->
|
||||||
<dimen name="keyguard_smartspace_top_offset">12dp</dimen>
|
<dimen name="keyguard_smartspace_top_offset">12dp</dimen>
|
||||||
<!-- With the large clock, move up slightly from the center -->
|
<!-- With the large clock, move up slightly from the center -->
|
||||||
<dimen name="keyguard_large_clock_top_margin">-60dp</dimen>
|
<dimen name="keyguard_large_clock_top_padding">100dp</dimen>
|
||||||
|
|
||||||
<!-- TODO: Remove during migration -->
|
|
||||||
<!-- Default line spacing multiplier between hours and minutes of the keyguard clock -->
|
|
||||||
<item name="keyguard_clock_line_spacing_scale" type="dimen" format="float">.7</item>
|
|
||||||
<!-- Burmese line spacing multiplier between hours and minutes of the keyguard clock -->
|
|
||||||
<item name="keyguard_clock_line_spacing_scale_burmese" type="dimen" format="float">1</item>
|
|
||||||
|
|
||||||
<dimen name="notification_scrim_corner_radius">32dp</dimen>
|
<dimen name="notification_scrim_corner_radius">32dp</dimen>
|
||||||
|
|
||||||
@@ -890,11 +884,6 @@
|
|||||||
burn-in on AOD. -->
|
burn-in on AOD. -->
|
||||||
<dimen name="burn_in_prevention_offset_y_clock">42dp</dimen>
|
<dimen name="burn_in_prevention_offset_y_clock">42dp</dimen>
|
||||||
|
|
||||||
<!-- Clock maximum font size (dp is intentional, to prevent any further scaling) -->
|
|
||||||
<!-- TODO: Remove when clock migration complete -->
|
|
||||||
<dimen name="large_clock_text_size">150dp</dimen>
|
|
||||||
<dimen name="clock_text_size">86dp</dimen>
|
|
||||||
|
|
||||||
<!-- The maximum offset in either direction that icons move to prevent burn-in on AOD. -->
|
<!-- The maximum offset in either direction that icons move to prevent burn-in on AOD. -->
|
||||||
<dimen name="default_burn_in_prevention_offset">15dp</dimen>
|
<dimen name="default_burn_in_prevention_offset">15dp</dimen>
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
-->
|
-->
|
||||||
<com.android.systemui.shared.clocks.AnimatableClockView
|
<com.android.systemui.shared.clocks.AnimatableClockView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/animatable_clock_view_large"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
-->
|
-->
|
||||||
<com.android.systemui.shared.clocks.AnimatableClockView
|
<com.android.systemui.shared.clocks.AnimatableClockView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/animatable_clock_view"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="start"
|
||||||
@@ -26,6 +25,7 @@
|
|||||||
android:textSize="@dimen/small_clock_text_size"
|
android:textSize="@dimen/small_clock_text_size"
|
||||||
android:fontFamily="@*android:string/config_clockFontFamily"
|
android:fontFamily="@*android:string/config_clockFontFamily"
|
||||||
android:elegantTextHeight="false"
|
android:elegantTextHeight="false"
|
||||||
|
android:ellipsize="none"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:fontFeatureSettings="pnum"
|
android:fontFeatureSettings="pnum"
|
||||||
chargeAnimationDelay="350"
|
chargeAnimationDelay="350"
|
||||||
|
|||||||
@@ -20,12 +20,15 @@ import android.annotation.ColorInt
|
|||||||
import android.annotation.FloatRange
|
import android.annotation.FloatRange
|
||||||
import android.annotation.IntRange
|
import android.annotation.IntRange
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.compat.ChangeIdStateCache.invalidate
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.text.format.DateFormat
|
import android.text.format.DateFormat
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import com.android.internal.R.attr.contentDescription
|
||||||
|
import com.android.internal.R.attr.format
|
||||||
import com.android.systemui.animation.GlyphCallback
|
import com.android.systemui.animation.GlyphCallback
|
||||||
import com.android.systemui.animation.Interpolators
|
import com.android.systemui.animation.Interpolators
|
||||||
import com.android.systemui.animation.TextAnimator
|
import com.android.systemui.animation.TextAnimator
|
||||||
@@ -75,6 +78,12 @@ class AnimatableClockView @JvmOverloads constructor(
|
|||||||
val lockScreenWeight: Int
|
val lockScreenWeight: Int
|
||||||
get() = if (useBoldedVersion()) lockScreenWeightInternal + 100 else lockScreenWeightInternal
|
get() = if (useBoldedVersion()) lockScreenWeightInternal + 100 else lockScreenWeightInternal
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of pixels below the baseline. For fonts that support languages such as
|
||||||
|
* Burmese, this space can be significant and should be accounted for when computing layout.
|
||||||
|
*/
|
||||||
|
val bottom get() = paint?.fontMetrics?.bottom ?: 0f
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val animatableClockViewAttributes = context.obtainStyledAttributes(
|
val animatableClockViewAttributes = context.obtainStyledAttributes(
|
||||||
attrs, R.styleable.AnimatableClockView, defStyleAttr, defStyleRes
|
attrs, R.styleable.AnimatableClockView, defStyleAttr, defStyleRes
|
||||||
@@ -133,6 +142,15 @@ class AnimatableClockView @JvmOverloads constructor(
|
|||||||
// relayout if the text didn't actually change.
|
// relayout if the text didn't actually change.
|
||||||
if (!TextUtils.equals(text, formattedText)) {
|
if (!TextUtils.equals(text, formattedText)) {
|
||||||
text = formattedText
|
text = formattedText
|
||||||
|
|
||||||
|
// Because the TextLayout may mutate under the hood as a result of the new text, we
|
||||||
|
// notify the TextAnimator that it may have changed and request a measure/layout. A
|
||||||
|
// crash will occur on the next invocation of setTextStyle if the layout is mutated
|
||||||
|
// without being notified TextInterpolator being notified.
|
||||||
|
if (layout != null) {
|
||||||
|
textAnimator?.updateLayout(layout)
|
||||||
|
}
|
||||||
|
requestLayout()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,6 @@ import javax.inject.Inject
|
|||||||
private val TAG = ClockRegistry::class.simpleName
|
private val TAG = ClockRegistry::class.simpleName
|
||||||
private val DEBUG = true
|
private val DEBUG = true
|
||||||
|
|
||||||
typealias ClockChangeListener = () -> Unit
|
|
||||||
|
|
||||||
/** ClockRegistry aggregates providers and plugins */
|
/** ClockRegistry aggregates providers and plugins */
|
||||||
open class ClockRegistry(
|
open class ClockRegistry(
|
||||||
val context: Context,
|
val context: Context,
|
||||||
@@ -51,12 +49,17 @@ open class ClockRegistry(
|
|||||||
defaultClockProvider: DefaultClockProvider
|
defaultClockProvider: DefaultClockProvider
|
||||||
) : this(context, pluginManager, handler, defaultClockProvider as ClockProvider) { }
|
) : this(context, pluginManager, handler, defaultClockProvider as ClockProvider) { }
|
||||||
|
|
||||||
|
// Usually this would be a typealias, but a SAM provides better java interop
|
||||||
|
fun interface ClockChangeListener {
|
||||||
|
fun onClockChanged()
|
||||||
|
}
|
||||||
|
|
||||||
private val gson = Gson()
|
private val gson = Gson()
|
||||||
private val availableClocks = mutableMapOf<ClockId, ClockInfo>()
|
private val availableClocks = mutableMapOf<ClockId, ClockInfo>()
|
||||||
private val clockChangeListeners = mutableListOf<ClockChangeListener>()
|
private val clockChangeListeners = mutableListOf<ClockChangeListener>()
|
||||||
private val settingObserver = object : ContentObserver(handler) {
|
private val settingObserver = object : ContentObserver(handler) {
|
||||||
override fun onChange(selfChange: Boolean, uris: Collection<Uri>, flags: Int, userId: Int) =
|
override fun onChange(selfChange: Boolean, uris: Collection<Uri>, flags: Int, userId: Int) =
|
||||||
clockChangeListeners.forEach { it() }
|
clockChangeListeners.forEach { it.onClockChanged() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val pluginListener = object : PluginListener<ClockProviderPlugin> {
|
private val pluginListener = object : PluginListener<ClockProviderPlugin> {
|
||||||
@@ -73,7 +76,7 @@ open class ClockRegistry(
|
|||||||
context.contentResolver,
|
context.contentResolver,
|
||||||
Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE
|
Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE
|
||||||
)
|
)
|
||||||
return gson.fromJson(json, ClockSetting::class.java).clockId
|
return gson.fromJson(json, ClockSetting::class.java)?.clockId ?: DEFAULT_CLOCK_ID
|
||||||
}
|
}
|
||||||
set(value) {
|
set(value) {
|
||||||
val json = gson.toJson(ClockSetting(value, System.currentTimeMillis()))
|
val json = gson.toJson(ClockSetting(value, System.currentTimeMillis()))
|
||||||
@@ -100,8 +103,11 @@ open class ClockRegistry(
|
|||||||
val id = clock.clockId
|
val id = clock.clockId
|
||||||
val current = availableClocks[id]
|
val current = availableClocks[id]
|
||||||
if (current != null) {
|
if (current != null) {
|
||||||
Log.e(TAG, "Clock Id conflict: $id is registered by both " +
|
Log.e(
|
||||||
"${provider::class.simpleName} and ${current.provider::class.simpleName}")
|
TAG,
|
||||||
|
"Clock Id conflict: $id is registered by both " +
|
||||||
|
"${provider::class.simpleName} and ${current.provider::class.simpleName}"
|
||||||
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +116,7 @@ open class ClockRegistry(
|
|||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.i(TAG, "Current clock ($currentId) was connected")
|
Log.i(TAG, "Current clock ($currentId) was connected")
|
||||||
}
|
}
|
||||||
clockChangeListeners.forEach { it() }
|
clockChangeListeners.forEach { it.onClockChanged() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,7 +128,7 @@ open class ClockRegistry(
|
|||||||
|
|
||||||
if (currentId == clock.clockId) {
|
if (currentId == clock.clockId) {
|
||||||
Log.w(TAG, "Current clock ($currentId) was disconnected")
|
Log.w(TAG, "Current clock ($currentId) was disconnected")
|
||||||
clockChangeListeners.forEach { it() }
|
clockChangeListeners.forEach { it.onClockChanged() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,9 @@ import android.graphics.drawable.Drawable
|
|||||||
import android.icu.text.NumberFormat
|
import android.icu.text.NumberFormat
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import com.android.internal.colorextraction.ColorExtractor
|
|
||||||
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.Clock
|
||||||
import com.android.systemui.plugins.ClockAnimation
|
import com.android.systemui.plugins.ClockAnimations
|
||||||
import com.android.systemui.plugins.ClockEvents
|
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
|
||||||
@@ -102,10 +101,13 @@ class DefaultClock(
|
|||||||
TypedValue.COMPLEX_UNIT_PX,
|
TypedValue.COMPLEX_UNIT_PX,
|
||||||
resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat()
|
resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat()
|
||||||
)
|
)
|
||||||
|
recomputePadding()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onColorPaletteChanged(palette: ColorExtractor.GradientColors) =
|
override fun onColorPaletteChanged(resources: Resources) {
|
||||||
clocks.forEach { it.setColors(DOZE_COLOR, palette.mainColor) }
|
val color = resources.getColor(android.R.color.system_accent1_100)
|
||||||
|
clocks.forEach { it.setColors(DOZE_COLOR, color) }
|
||||||
|
}
|
||||||
|
|
||||||
override fun onLocaleChanged(locale: Locale) {
|
override fun onLocaleChanged(locale: Locale) {
|
||||||
val nf = NumberFormat.getInstance(locale)
|
val nf = NumberFormat.getInstance(locale)
|
||||||
@@ -119,8 +121,17 @@ class DefaultClock(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val animation = object : ClockAnimation {
|
override var animations = DefaultClockAnimations(0f, 0f)
|
||||||
override fun initialize(dozeFraction: Float, foldFraction: Float) {
|
private set
|
||||||
|
|
||||||
|
inner class DefaultClockAnimations(
|
||||||
|
dozeFraction: Float,
|
||||||
|
foldFraction: Float
|
||||||
|
) : ClockAnimations {
|
||||||
|
private var foldState = AnimationState(0f)
|
||||||
|
private var dozeState = AnimationState(0f)
|
||||||
|
|
||||||
|
init {
|
||||||
dozeState = AnimationState(dozeFraction)
|
dozeState = AnimationState(dozeFraction)
|
||||||
foldState = AnimationState(foldFraction)
|
foldState = AnimationState(foldFraction)
|
||||||
|
|
||||||
@@ -132,14 +143,13 @@ class DefaultClock(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun enter() {
|
override fun enter() {
|
||||||
if (dozeState.isActive) {
|
if (!dozeState.isActive) {
|
||||||
clocks.forEach { it.animateAppearOnLockscreen() }
|
clocks.forEach { it.animateAppearOnLockscreen() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun charge() = clocks.forEach { it.animateCharge { dozeState.isActive } }
|
override fun charge() = clocks.forEach { it.animateCharge { dozeState.isActive } }
|
||||||
|
|
||||||
private var foldState = AnimationState(0f)
|
|
||||||
override fun fold(fraction: Float) {
|
override fun fold(fraction: Float) {
|
||||||
val (hasChanged, hasJumped) = foldState.update(fraction)
|
val (hasChanged, hasJumped) = foldState.update(fraction)
|
||||||
if (hasChanged) {
|
if (hasChanged) {
|
||||||
@@ -147,7 +157,6 @@ class DefaultClock(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var dozeState = AnimationState(0f)
|
|
||||||
override fun doze(fraction: Float) {
|
override fun doze(fraction: Float) {
|
||||||
val (hasChanged, hasJumped) = dozeState.update(fraction)
|
val (hasChanged, hasJumped) = dozeState.update(fraction)
|
||||||
if (hasChanged) {
|
if (hasChanged) {
|
||||||
@@ -172,6 +181,19 @@ class DefaultClock(
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
events.onLocaleChanged(Locale.getDefault())
|
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)
|
||||||
|
events.onTimeTick()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun recomputePadding() {
|
||||||
|
val topPadding = -1 * (largeClock.bottom.toInt() - 180)
|
||||||
|
largeClock.setPadding(0, topPadding, 0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dump(pw: PrintWriter) = clocks.forEach { it.dump(pw) }
|
override fun dump(pw: PrintWriter) = clocks.forEach { it.dump(pw) }
|
||||||
|
|||||||
@@ -182,18 +182,6 @@ public class AnimatableClockController extends ViewController<AnimatableClockVie
|
|||||||
mStatusBarStateController.removeCallback(mStatusBarStateListener);
|
mStatusBarStateController.removeCallback(mStatusBarStateListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the number of pixels below the baseline. For fonts that support languages such as
|
|
||||||
* Burmese, this space can be significant.
|
|
||||||
*/
|
|
||||||
public float getBottom() {
|
|
||||||
if (mView.getPaint() != null && mView.getPaint().getFontMetrics() != null) {
|
|
||||||
return mView.getPaint().getFontMetrics().bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Animate the clock appearance */
|
/** Animate the clock appearance */
|
||||||
public void animateAppear() {
|
public void animateAppear() {
|
||||||
if (!mIsDozing) mView.animateAppearOnLockscreen();
|
if (!mIsDozing) mView.animateAppearOnLockscreen();
|
||||||
|
|||||||
@@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* 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.keyguard
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.IntentFilter
|
||||||
|
import android.content.res.Resources
|
||||||
|
import android.text.format.DateFormat
|
||||||
|
import com.android.systemui.broadcast.BroadcastDispatcher
|
||||||
|
import com.android.systemui.dagger.qualifiers.Main
|
||||||
|
import com.android.systemui.plugins.Clock
|
||||||
|
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||||
|
import com.android.systemui.statusbar.policy.BatteryController
|
||||||
|
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback
|
||||||
|
import com.android.systemui.statusbar.policy.ConfigurationController
|
||||||
|
import java.io.PrintWriter
|
||||||
|
import java.util.Locale
|
||||||
|
import java.util.TimeZone
|
||||||
|
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(
|
||||||
|
private val statusBarStateController: StatusBarStateController,
|
||||||
|
private val broadcastDispatcher: BroadcastDispatcher,
|
||||||
|
private val batteryController: BatteryController,
|
||||||
|
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
|
||||||
|
private val configurationController: ConfigurationController,
|
||||||
|
@Main private val resources: Resources,
|
||||||
|
private val context: Context
|
||||||
|
) {
|
||||||
|
var clock: Clock? = null
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
if (value != null) {
|
||||||
|
value.initialize(resources, dozeAmount, 0f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var isDozing = false
|
||||||
|
private set
|
||||||
|
|
||||||
|
private var isCharging = false
|
||||||
|
private var dozeAmount = 0f
|
||||||
|
private var isKeyguardShowing = false
|
||||||
|
|
||||||
|
private val configListener = object : ConfigurationController.ConfigurationListener {
|
||||||
|
override fun onThemeChanged() {
|
||||||
|
clock?.events?.onColorPaletteChanged(resources)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val batteryCallback = object : BatteryStateChangeCallback {
|
||||||
|
override fun onBatteryLevelChanged(level: Int, pluggedIn: Boolean, charging: Boolean) {
|
||||||
|
if (isKeyguardShowing && !isCharging && charging) {
|
||||||
|
clock?.animations?.charge()
|
||||||
|
}
|
||||||
|
isCharging = charging
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val localeBroadcastReceiver = object : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
clock?.events?.onLocaleChanged(Locale.getDefault())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val statusBarStateListener = object : StatusBarStateController.StateListener {
|
||||||
|
override fun onDozeAmountChanged(linear: Float, eased: Float) {
|
||||||
|
clock?.animations?.doze(linear)
|
||||||
|
|
||||||
|
isDozing = linear > dozeAmount
|
||||||
|
dozeAmount = linear
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() {
|
||||||
|
override fun onKeyguardVisibilityChanged(showing: Boolean) {
|
||||||
|
isKeyguardShowing = showing
|
||||||
|
if (!isKeyguardShowing) {
|
||||||
|
clock?.animations?.doze(if (isDozing) 1f else 0f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTimeFormatChanged(timeFormat: String) {
|
||||||
|
clock?.events?.onTimeFormatChanged(DateFormat.is24HourFormat(context))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTimeZoneChanged(timeZone: TimeZone) {
|
||||||
|
clock?.events?.onTimeZoneChanged(timeZone)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUserSwitchComplete(userId: Int) {
|
||||||
|
clock?.events?.onTimeFormatChanged(DateFormat.is24HourFormat(context))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
isDozing = statusBarStateController.isDozing
|
||||||
|
}
|
||||||
|
|
||||||
|
fun registerListeners() {
|
||||||
|
dozeAmount = statusBarStateController.dozeAmount
|
||||||
|
isDozing = statusBarStateController.isDozing || dozeAmount != 0f
|
||||||
|
|
||||||
|
broadcastDispatcher.registerReceiver(
|
||||||
|
localeBroadcastReceiver,
|
||||||
|
IntentFilter(Intent.ACTION_LOCALE_CHANGED)
|
||||||
|
)
|
||||||
|
configurationController.addCallback(configListener)
|
||||||
|
batteryController.addCallback(batteryCallback)
|
||||||
|
keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
|
||||||
|
statusBarStateController.addCallback(statusBarStateListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unregisterListeners() {
|
||||||
|
broadcastDispatcher.unregisterReceiver(localeBroadcastReceiver)
|
||||||
|
configurationController.removeCallback(configListener)
|
||||||
|
batteryController.removeCallback(batteryCallback)
|
||||||
|
keyguardUpdateMonitor.removeCallback(keyguardUpdateMonitorCallback)
|
||||||
|
statusBarStateController.removeCallback(statusBarStateListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dump information for debugging
|
||||||
|
*/
|
||||||
|
fun dump(pw: PrintWriter) {
|
||||||
|
pw.println(this)
|
||||||
|
clock?.dump(pw)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val TAG = ClockEventController::class.simpleName
|
||||||
|
private const val FORMAT_NUMBER = 1234567890
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,10 +5,8 @@ import android.animation.AnimatorListenerAdapter;
|
|||||||
import android.animation.AnimatorSet;
|
import android.animation.AnimatorSet;
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.Paint.Style;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.TypedValue;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
@@ -17,19 +15,14 @@ import android.widget.RelativeLayout;
|
|||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import com.android.internal.colorextraction.ColorExtractor;
|
|
||||||
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.ClockPlugin;
|
import com.android.systemui.plugins.Clock;
|
||||||
import com.android.systemui.shared.clocks.AnimatableClockView;
|
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch to show plugin clock when plugin is connected, otherwise it will show default clock.
|
* Switch to show plugin clock when plugin is connected, otherwise it will show default clock.
|
||||||
*/
|
*/
|
||||||
@@ -49,18 +42,11 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
|||||||
public static final int LARGE = 0;
|
public static final int LARGE = 0;
|
||||||
public static final int SMALL = 1;
|
public static final int SMALL = 1;
|
||||||
|
|
||||||
/**
|
|
||||||
* Optional/alternative clock injected via plugin.
|
|
||||||
*/
|
|
||||||
private ClockPlugin mClockPlugin;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frame for small/large clocks
|
* Frame for small/large clocks
|
||||||
*/
|
*/
|
||||||
private FrameLayout mClockFrame;
|
private FrameLayout mSmallClockFrame;
|
||||||
private FrameLayout mLargeClockFrame;
|
private FrameLayout mLargeClockFrame;
|
||||||
private AnimatableClockView mClockView;
|
|
||||||
private AnimatableClockView mLargeClockView;
|
|
||||||
|
|
||||||
private View mStatusArea;
|
private View mStatusArea;
|
||||||
private int mSmartspaceTopOffset;
|
private int mSmartspaceTopOffset;
|
||||||
@@ -80,12 +66,6 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
|||||||
@VisibleForTesting AnimatorSet mClockOutAnim = null;
|
@VisibleForTesting AnimatorSet mClockOutAnim = null;
|
||||||
private ObjectAnimator mStatusAreaAnim = null;
|
private ObjectAnimator mStatusAreaAnim = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* If the Keyguard Slice has a header (big center-aligned text.)
|
|
||||||
*/
|
|
||||||
private boolean mSupportsDarkText;
|
|
||||||
private int[] mColorPalette;
|
|
||||||
|
|
||||||
private int mClockSwitchYAmount;
|
private int mClockSwitchYAmount;
|
||||||
@VisibleForTesting boolean mChildrenAreLaidOut = false;
|
@VisibleForTesting boolean mChildrenAreLaidOut = false;
|
||||||
|
|
||||||
@@ -97,97 +77,38 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
|||||||
* Apply dp changes on font/scale change
|
* Apply dp changes on font/scale change
|
||||||
*/
|
*/
|
||||||
public void onDensityOrFontScaleChanged() {
|
public void onDensityOrFontScaleChanged() {
|
||||||
mLargeClockView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mContext.getResources()
|
|
||||||
.getDimensionPixelSize(R.dimen.large_clock_text_size));
|
|
||||||
mClockView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mContext.getResources()
|
|
||||||
.getDimensionPixelSize(R.dimen.clock_text_size));
|
|
||||||
|
|
||||||
mClockSwitchYAmount = mContext.getResources().getDimensionPixelSize(
|
mClockSwitchYAmount = mContext.getResources().getDimensionPixelSize(
|
||||||
R.dimen.keyguard_clock_switch_y_shift);
|
R.dimen.keyguard_clock_switch_y_shift);
|
||||||
|
|
||||||
mSmartspaceTopOffset = mContext.getResources().getDimensionPixelSize(
|
mSmartspaceTopOffset = mContext.getResources().getDimensionPixelSize(
|
||||||
R.dimen.keyguard_smartspace_top_offset);
|
R.dimen.keyguard_smartspace_top_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if this view is presenting a custom clock, or the default implementation.
|
|
||||||
*/
|
|
||||||
public boolean hasCustomClock() {
|
|
||||||
return mClockPlugin != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onFinishInflate() {
|
protected void onFinishInflate() {
|
||||||
super.onFinishInflate();
|
super.onFinishInflate();
|
||||||
|
|
||||||
mClockFrame = findViewById(R.id.lockscreen_clock_view);
|
mSmallClockFrame = findViewById(R.id.lockscreen_clock_view);
|
||||||
mClockView = findViewById(R.id.animatable_clock_view);
|
|
||||||
mLargeClockFrame = findViewById(R.id.lockscreen_clock_view_large);
|
mLargeClockFrame = findViewById(R.id.lockscreen_clock_view_large);
|
||||||
mLargeClockView = findViewById(R.id.animatable_clock_view_large);
|
|
||||||
mStatusArea = findViewById(R.id.keyguard_status_area);
|
mStatusArea = findViewById(R.id.keyguard_status_area);
|
||||||
|
|
||||||
onDensityOrFontScaleChanged();
|
onDensityOrFontScaleChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setClockPlugin(ClockPlugin plugin, int statusBarState) {
|
void setClock(Clock clock, int statusBarState) {
|
||||||
// Disconnect from existing plugin.
|
// Disconnect from existing plugin.
|
||||||
if (mClockPlugin != null) {
|
mSmallClockFrame.removeAllViews();
|
||||||
View smallClockView = mClockPlugin.getView();
|
mLargeClockFrame.removeAllViews();
|
||||||
if (smallClockView != null && smallClockView.getParent() == mClockFrame) {
|
|
||||||
mClockFrame.removeView(smallClockView);
|
if (clock == null) {
|
||||||
}
|
Log.e(TAG, "No clock being shown");
|
||||||
View bigClockView = mClockPlugin.getBigClockView();
|
|
||||||
if (bigClockView != null && bigClockView.getParent() == mLargeClockFrame) {
|
|
||||||
mLargeClockFrame.removeView(bigClockView);
|
|
||||||
}
|
|
||||||
mClockPlugin.onDestroyView();
|
|
||||||
mClockPlugin = null;
|
|
||||||
}
|
|
||||||
if (plugin == null) {
|
|
||||||
mClockView.setVisibility(View.VISIBLE);
|
|
||||||
mLargeClockView.setVisibility(View.VISIBLE);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach small and big clock views to hierarchy.
|
// Attach small and big clock views to hierarchy.
|
||||||
View smallClockView = plugin.getView();
|
mSmallClockFrame.addView(clock.getSmallClock(), -1,
|
||||||
if (smallClockView != null) {
|
|
||||||
mClockFrame.addView(smallClockView, -1,
|
|
||||||
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT));
|
ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||||
mClockView.setVisibility(View.GONE);
|
mLargeClockFrame.addView(clock.getLargeClock());
|
||||||
}
|
|
||||||
View bigClockView = plugin.getBigClockView();
|
|
||||||
if (bigClockView != null) {
|
|
||||||
mLargeClockFrame.addView(bigClockView);
|
|
||||||
mLargeClockView.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize plugin parameters.
|
|
||||||
mClockPlugin = plugin;
|
|
||||||
mClockPlugin.setStyle(getPaint().getStyle());
|
|
||||||
mClockPlugin.setTextColor(getCurrentTextColor());
|
|
||||||
mClockPlugin.setDarkAmount(mDarkAmount);
|
|
||||||
if (mColorPalette != null) {
|
|
||||||
mClockPlugin.setColorPalette(mSupportsDarkText, mColorPalette);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* It will also update plugin setStyle if plugin is connected.
|
|
||||||
*/
|
|
||||||
public void setStyle(Style style) {
|
|
||||||
if (mClockPlugin != null) {
|
|
||||||
mClockPlugin.setStyle(style);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* It will also update plugin setTextColor if plugin is connected.
|
|
||||||
*/
|
|
||||||
public void setTextColor(int color) {
|
|
||||||
if (mClockPlugin != null) {
|
|
||||||
mClockPlugin.setTextColor(color);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateClockViews(boolean useLargeClock, boolean animate) {
|
private void updateClockViews(boolean useLargeClock, boolean animate) {
|
||||||
@@ -203,14 +124,14 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
|||||||
int direction = 1;
|
int direction = 1;
|
||||||
float statusAreaYTranslation;
|
float statusAreaYTranslation;
|
||||||
if (useLargeClock) {
|
if (useLargeClock) {
|
||||||
out = mClockFrame;
|
out = mSmallClockFrame;
|
||||||
in = mLargeClockFrame;
|
in = mLargeClockFrame;
|
||||||
if (indexOfChild(in) == -1) addView(in);
|
if (indexOfChild(in) == -1) addView(in);
|
||||||
direction = -1;
|
direction = -1;
|
||||||
statusAreaYTranslation = mClockFrame.getTop() - mStatusArea.getTop()
|
statusAreaYTranslation = mSmallClockFrame.getTop() - mStatusArea.getTop()
|
||||||
+ mSmartspaceTopOffset;
|
+ mSmartspaceTopOffset;
|
||||||
} else {
|
} else {
|
||||||
in = mClockFrame;
|
in = mSmallClockFrame;
|
||||||
out = mLargeClockFrame;
|
out = mLargeClockFrame;
|
||||||
statusAreaYTranslation = 0f;
|
statusAreaYTranslation = 0f;
|
||||||
|
|
||||||
@@ -268,18 +189,6 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
|||||||
mStatusAreaAnim.start();
|
mStatusAreaAnim.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the amount (ratio) that the device has transitioned to doze.
|
|
||||||
*
|
|
||||||
* @param darkAmount Amount of transition to doze: 1f for doze and 0f for awake.
|
|
||||||
*/
|
|
||||||
public void setDarkAmount(float darkAmount) {
|
|
||||||
mDarkAmount = darkAmount;
|
|
||||||
if (mClockPlugin != null) {
|
|
||||||
mClockPlugin.setDarkAmount(darkAmount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the desired clock and hide the other one
|
* Display the desired clock and hide the other one
|
||||||
*
|
*
|
||||||
@@ -311,64 +220,11 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
|||||||
mChildrenAreLaidOut = true;
|
mChildrenAreLaidOut = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Paint getPaint() {
|
|
||||||
return mClockView.getPaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCurrentTextColor() {
|
|
||||||
return mClockView.getCurrentTextColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getTextSize() {
|
|
||||||
return mClockView.getTextSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Refresh the time of the clock, due to either time tick broadcast or doze time tick alarm.
|
|
||||||
*/
|
|
||||||
public void refresh() {
|
|
||||||
if (mClockPlugin != null) {
|
|
||||||
mClockPlugin.onTimeTick();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notifies that the time zone has changed.
|
|
||||||
*/
|
|
||||||
public void onTimeZoneChanged(TimeZone timeZone) {
|
|
||||||
if (mClockPlugin != null) {
|
|
||||||
mClockPlugin.onTimeZoneChanged(timeZone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notifies that the time format has changed.
|
|
||||||
*
|
|
||||||
* @param timeFormat "12" for 12-hour format, "24" for 24-hour format
|
|
||||||
*/
|
|
||||||
public void onTimeFormatChanged(String timeFormat) {
|
|
||||||
if (mClockPlugin != null) {
|
|
||||||
mClockPlugin.onTimeFormatChanged(timeFormat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateColors(ColorExtractor.GradientColors colors) {
|
|
||||||
mSupportsDarkText = colors.supportsDarkText();
|
|
||||||
mColorPalette = colors.getColorPalette();
|
|
||||||
if (mClockPlugin != null) {
|
|
||||||
mClockPlugin.setColorPalette(mSupportsDarkText, mColorPalette);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dump(PrintWriter pw, String[] args) {
|
public void dump(PrintWriter pw, String[] args) {
|
||||||
pw.println("KeyguardClockSwitch:");
|
pw.println("KeyguardClockSwitch:");
|
||||||
pw.println(" mClockPlugin: " + mClockPlugin);
|
pw.println(" mClockFrame: " + mSmallClockFrame);
|
||||||
pw.println(" mClockFrame: " + mClockFrame);
|
|
||||||
pw.println(" mLargeClockFrame: " + mLargeClockFrame);
|
pw.println(" mLargeClockFrame: " + mLargeClockFrame);
|
||||||
pw.println(" mStatusArea: " + mStatusArea);
|
pw.println(" mStatusArea: " + mStatusArea);
|
||||||
pw.println(" mDarkAmount: " + mDarkAmount);
|
|
||||||
pw.println(" mSupportsDarkText: " + mSupportsDarkText);
|
|
||||||
pw.println(" mColorPalette: " + Arrays.toString(mColorPalette));
|
|
||||||
pw.println(" mDisplayedClockSize: " + mDisplayedClockSize);
|
pw.println(" mDisplayedClockSize: " + mDisplayedClockSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,6 @@ import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
|||||||
import static com.android.keyguard.KeyguardClockSwitch.LARGE;
|
import static com.android.keyguard.KeyguardClockSwitch.LARGE;
|
||||||
import static com.android.keyguard.KeyguardClockSwitch.SMALL;
|
import static com.android.keyguard.KeyguardClockSwitch.SMALL;
|
||||||
|
|
||||||
import android.app.WallpaperManager;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
@@ -32,34 +30,28 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.internal.colorextraction.ColorExtractor;
|
|
||||||
import com.android.keyguard.clock.ClockManager;
|
|
||||||
import com.android.systemui.Dumpable;
|
import com.android.systemui.Dumpable;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
|
||||||
import com.android.systemui.colorextraction.SysuiColorExtractor;
|
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
import com.android.systemui.dump.DumpManager;
|
import com.android.systemui.dump.DumpManager;
|
||||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||||
import com.android.systemui.plugins.ClockPlugin;
|
import com.android.systemui.plugins.Clock;
|
||||||
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.statusbar.lockscreen.LockscreenSmartspaceController;
|
import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
|
||||||
import com.android.systemui.statusbar.notification.AnimatableProperty;
|
import com.android.systemui.statusbar.notification.AnimatableProperty;
|
||||||
import com.android.systemui.statusbar.notification.PropertyAnimator;
|
import com.android.systemui.statusbar.notification.PropertyAnimator;
|
||||||
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
|
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
|
||||||
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
|
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
|
||||||
import com.android.systemui.statusbar.phone.NotificationIconContainer;
|
import com.android.systemui.statusbar.phone.NotificationIconContainer;
|
||||||
import com.android.systemui.statusbar.policy.BatteryController;
|
|
||||||
import com.android.systemui.util.ViewController;
|
import com.android.systemui.util.ViewController;
|
||||||
import com.android.systemui.util.settings.SecureSettings;
|
import com.android.systemui.util.settings.SecureSettings;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.TimeZone;
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -69,48 +61,24 @@ import javax.inject.Inject;
|
|||||||
*/
|
*/
|
||||||
public class KeyguardClockSwitchController extends ViewController<KeyguardClockSwitch>
|
public class KeyguardClockSwitchController extends ViewController<KeyguardClockSwitch>
|
||||||
implements Dumpable {
|
implements Dumpable {
|
||||||
private static final boolean CUSTOM_CLOCKS_ENABLED = true;
|
|
||||||
|
|
||||||
private final StatusBarStateController mStatusBarStateController;
|
private final StatusBarStateController mStatusBarStateController;
|
||||||
private final SysuiColorExtractor mColorExtractor;
|
private final ClockRegistry mClockRegistry;
|
||||||
private final ClockManager mClockManager;
|
|
||||||
private final KeyguardSliceViewController mKeyguardSliceViewController;
|
private final KeyguardSliceViewController mKeyguardSliceViewController;
|
||||||
private final NotificationIconAreaController mNotificationIconAreaController;
|
private final NotificationIconAreaController mNotificationIconAreaController;
|
||||||
private final BroadcastDispatcher mBroadcastDispatcher;
|
|
||||||
private final BatteryController mBatteryController;
|
|
||||||
private final LockscreenSmartspaceController mSmartspaceController;
|
private final LockscreenSmartspaceController mSmartspaceController;
|
||||||
private final Resources mResources;
|
|
||||||
private final SecureSettings mSecureSettings;
|
private final SecureSettings mSecureSettings;
|
||||||
private final DumpManager mDumpManager;
|
private final DumpManager mDumpManager;
|
||||||
|
private final ClockEventController mClockEventController;
|
||||||
|
|
||||||
/**
|
/** Clock frames for both small and large sizes */
|
||||||
* Clock for both small and large sizes
|
private FrameLayout mSmallClockFrame; // top aligned clock
|
||||||
*/
|
|
||||||
private AnimatableClockController mClockViewController;
|
|
||||||
private FrameLayout mClockFrame; // top aligned clock
|
|
||||||
private AnimatableClockController mLargeClockViewController;
|
|
||||||
private FrameLayout mLargeClockFrame; // centered clock
|
private FrameLayout mLargeClockFrame; // centered clock
|
||||||
|
|
||||||
@KeyguardClockSwitch.ClockSize
|
@KeyguardClockSwitch.ClockSize
|
||||||
private int mCurrentClockSize = SMALL;
|
private int mCurrentClockSize = SMALL;
|
||||||
|
|
||||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
|
||||||
|
|
||||||
private int mKeyguardClockTopMargin = 0;
|
private int mKeyguardClockTopMargin = 0;
|
||||||
|
private final ClockRegistry.ClockChangeListener mClockChangedListener;
|
||||||
/**
|
|
||||||
* Listener for changes to the color palette.
|
|
||||||
*
|
|
||||||
* The color palette changes when the wallpaper is changed.
|
|
||||||
*/
|
|
||||||
private final ColorExtractor.OnColorsChangedListener mColorsListener =
|
|
||||||
(extractor, which) -> {
|
|
||||||
if ((which & WallpaperManager.FLAG_LOCK) != 0) {
|
|
||||||
mView.updateColors(getGradientColors());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final ClockManager.ClockChangedListener mClockChangedListener = this::setClockPlugin;
|
|
||||||
|
|
||||||
private ViewGroup mStatusArea;
|
private ViewGroup mStatusArea;
|
||||||
// If set will replace keyguard_slice_view
|
// If set will replace keyguard_slice_view
|
||||||
@@ -119,9 +87,9 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
|
private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
|
||||||
|
|
||||||
private boolean mOnlyClock = false;
|
private boolean mOnlyClock = false;
|
||||||
private Executor mUiExecutor;
|
private final Executor mUiExecutor;
|
||||||
private boolean mCanShowDoubleLineClock = true;
|
private boolean mCanShowDoubleLineClock = true;
|
||||||
private ContentObserver mDoubleLineClockObserver = new ContentObserver(null) {
|
private final ContentObserver mDoubleLineClockObserver = new ContentObserver(null) {
|
||||||
@Override
|
@Override
|
||||||
public void onChange(boolean change) {
|
public void onChange(boolean change) {
|
||||||
updateDoubleLineClock();
|
updateDoubleLineClock();
|
||||||
@@ -142,34 +110,30 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
public KeyguardClockSwitchController(
|
public KeyguardClockSwitchController(
|
||||||
KeyguardClockSwitch keyguardClockSwitch,
|
KeyguardClockSwitch keyguardClockSwitch,
|
||||||
StatusBarStateController statusBarStateController,
|
StatusBarStateController statusBarStateController,
|
||||||
SysuiColorExtractor colorExtractor,
|
ClockRegistry clockRegistry,
|
||||||
ClockManager clockManager,
|
|
||||||
KeyguardSliceViewController keyguardSliceViewController,
|
KeyguardSliceViewController keyguardSliceViewController,
|
||||||
NotificationIconAreaController notificationIconAreaController,
|
NotificationIconAreaController notificationIconAreaController,
|
||||||
BroadcastDispatcher broadcastDispatcher,
|
|
||||||
BatteryController batteryController,
|
|
||||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
|
||||||
LockscreenSmartspaceController smartspaceController,
|
LockscreenSmartspaceController smartspaceController,
|
||||||
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
|
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
|
||||||
SecureSettings secureSettings,
|
SecureSettings secureSettings,
|
||||||
@Main Executor uiExecutor,
|
@Main Executor uiExecutor,
|
||||||
@Main Resources resources,
|
DumpManager dumpManager,
|
||||||
DumpManager dumpManager) {
|
ClockEventController clockEventController) {
|
||||||
super(keyguardClockSwitch);
|
super(keyguardClockSwitch);
|
||||||
mStatusBarStateController = statusBarStateController;
|
mStatusBarStateController = statusBarStateController;
|
||||||
mColorExtractor = colorExtractor;
|
mClockRegistry = clockRegistry;
|
||||||
mClockManager = clockManager;
|
|
||||||
mKeyguardSliceViewController = keyguardSliceViewController;
|
mKeyguardSliceViewController = keyguardSliceViewController;
|
||||||
mNotificationIconAreaController = notificationIconAreaController;
|
mNotificationIconAreaController = notificationIconAreaController;
|
||||||
mBroadcastDispatcher = broadcastDispatcher;
|
|
||||||
mBatteryController = batteryController;
|
|
||||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
|
||||||
mSmartspaceController = smartspaceController;
|
mSmartspaceController = smartspaceController;
|
||||||
mResources = resources;
|
|
||||||
mSecureSettings = secureSettings;
|
mSecureSettings = secureSettings;
|
||||||
mUiExecutor = uiExecutor;
|
mUiExecutor = uiExecutor;
|
||||||
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
|
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
|
||||||
mDumpManager = dumpManager;
|
mDumpManager = dumpManager;
|
||||||
|
mClockEventController = clockEventController;
|
||||||
|
|
||||||
|
mClockChangedListener = () -> {
|
||||||
|
setClock(mClockRegistry.createCurrentClock());
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -186,40 +150,18 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
public void onInit() {
|
public void onInit() {
|
||||||
mKeyguardSliceViewController.init();
|
mKeyguardSliceViewController.init();
|
||||||
|
|
||||||
mClockFrame = mView.findViewById(R.id.lockscreen_clock_view);
|
mSmallClockFrame = mView.findViewById(R.id.lockscreen_clock_view);
|
||||||
mLargeClockFrame = mView.findViewById(R.id.lockscreen_clock_view_large);
|
mLargeClockFrame = mView.findViewById(R.id.lockscreen_clock_view_large);
|
||||||
|
|
||||||
mClockViewController =
|
|
||||||
new AnimatableClockController(
|
|
||||||
mView.findViewById(R.id.animatable_clock_view),
|
|
||||||
mStatusBarStateController,
|
|
||||||
mBroadcastDispatcher,
|
|
||||||
mBatteryController,
|
|
||||||
mKeyguardUpdateMonitor,
|
|
||||||
mResources);
|
|
||||||
mClockViewController.init();
|
|
||||||
|
|
||||||
mLargeClockViewController =
|
|
||||||
new AnimatableClockController(
|
|
||||||
mView.findViewById(R.id.animatable_clock_view_large),
|
|
||||||
mStatusBarStateController,
|
|
||||||
mBroadcastDispatcher,
|
|
||||||
mBatteryController,
|
|
||||||
mKeyguardUpdateMonitor,
|
|
||||||
mResources);
|
|
||||||
mLargeClockViewController.init();
|
|
||||||
|
|
||||||
mDumpManager.unregisterDumpable(getClass().toString()); // unregister previous clocks
|
mDumpManager.unregisterDumpable(getClass().toString()); // unregister previous clocks
|
||||||
mDumpManager.registerDumpable(getClass().toString(), this);
|
mDumpManager.registerDumpable(getClass().toString(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onViewAttached() {
|
protected void onViewAttached() {
|
||||||
if (CUSTOM_CLOCKS_ENABLED) {
|
mClockRegistry.registerClockChangeListener(mClockChangedListener);
|
||||||
mClockManager.addOnClockChangedListener(mClockChangedListener);
|
setClock(mClockRegistry.createCurrentClock());
|
||||||
}
|
mClockEventController.registerListeners();
|
||||||
mColorExtractor.addOnColorsChangedListener(mColorsListener);
|
|
||||||
mView.updateColors(getGradientColors());
|
|
||||||
mKeyguardClockTopMargin =
|
mKeyguardClockTopMargin =
|
||||||
mView.getResources().getDimensionPixelSize(R.dimen.keyguard_clock_top_margin);
|
mView.getResources().getDimensionPixelSize(R.dimen.keyguard_clock_top_margin);
|
||||||
|
|
||||||
@@ -242,7 +184,6 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
ksv.setVisibility(View.GONE);
|
ksv.setVisibility(View.GONE);
|
||||||
|
|
||||||
addSmartspaceView(ksvIndex);
|
addSmartspaceView(ksvIndex);
|
||||||
updateClockLayout();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mSecureSettings.registerContentObserverForUser(
|
mSecureSettings.registerContentObserverForUser(
|
||||||
@@ -264,11 +205,9 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onViewDetached() {
|
protected void onViewDetached() {
|
||||||
if (CUSTOM_CLOCKS_ENABLED) {
|
mClockRegistry.unregisterClockChangeListener(mClockChangedListener);
|
||||||
mClockManager.removeOnClockChangedListener(mClockChangedListener);
|
mClockEventController.unregisterListeners();
|
||||||
}
|
setClock(null);
|
||||||
mColorExtractor.removeOnColorsChangedListener(mColorsListener);
|
|
||||||
mView.setClockPlugin(null, mStatusBarStateController.getState());
|
|
||||||
|
|
||||||
mSecureSettings.unregisterContentObserver(mDoubleLineClockObserver);
|
mSecureSettings.unregisterContentObserver(mDoubleLineClockObserver);
|
||||||
|
|
||||||
@@ -307,18 +246,6 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
mView.onDensityOrFontScaleChanged();
|
mView.onDensityOrFontScaleChanged();
|
||||||
mKeyguardClockTopMargin =
|
mKeyguardClockTopMargin =
|
||||||
mView.getResources().getDimensionPixelSize(R.dimen.keyguard_clock_top_margin);
|
mView.getResources().getDimensionPixelSize(R.dimen.keyguard_clock_top_margin);
|
||||||
|
|
||||||
updateClockLayout();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateClockLayout() {
|
|
||||||
int largeClockTopMargin = getContext().getResources().getDimensionPixelSize(
|
|
||||||
R.dimen.keyguard_large_clock_top_margin)
|
|
||||||
- (int) mLargeClockViewController.getBottom();
|
|
||||||
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(MATCH_PARENT,
|
|
||||||
MATCH_PARENT);
|
|
||||||
lp.topMargin = largeClockTopMargin;
|
|
||||||
mLargeClockFrame.setLayoutParams(lp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -334,44 +261,31 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
|
|
||||||
boolean appeared = mView.switchToClock(clockSize, animate);
|
boolean appeared = mView.switchToClock(clockSize, animate);
|
||||||
if (animate && appeared && clockSize == LARGE) {
|
if (animate && appeared && clockSize == LARGE) {
|
||||||
mLargeClockViewController.animateAppear();
|
getClock().getAnimations().enter();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void animateFoldToAod() {
|
|
||||||
if (mClockViewController != null) {
|
|
||||||
mClockViewController.animateFoldAppear();
|
|
||||||
mLargeClockViewController.animateFoldAppear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If we're presenting a custom clock of just the default one.
|
* Animates the clock view between folded and unfolded states
|
||||||
*/
|
*/
|
||||||
public boolean hasCustomClock() {
|
public void animateFoldToAod(float foldFraction) {
|
||||||
return mView.hasCustomClock();
|
Clock clock = getClock();
|
||||||
|
if (clock != null) {
|
||||||
|
clock.getAnimations().fold(foldFraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the clock text size.
|
|
||||||
*/
|
|
||||||
public float getClockTextSize() {
|
|
||||||
return mView.getTextSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refresh clock. Called in response to TIME_TICK broadcasts.
|
* Refresh clock. Called in response to TIME_TICK broadcasts.
|
||||||
*/
|
*/
|
||||||
void refresh() {
|
void refresh() {
|
||||||
if (mClockViewController != null) {
|
|
||||||
mClockViewController.refreshTime();
|
|
||||||
mLargeClockViewController.refreshTime();
|
|
||||||
}
|
|
||||||
if (mSmartspaceController != null) {
|
if (mSmartspaceController != null) {
|
||||||
mSmartspaceController.requestSmartspaceUpdate();
|
mSmartspaceController.requestSmartspaceUpdate();
|
||||||
}
|
}
|
||||||
|
Clock clock = getClock();
|
||||||
mView.refresh();
|
if (clock != null) {
|
||||||
|
clock.getEvents().onTimeTick();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -383,7 +297,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
void updatePosition(int x, float scale, AnimationProperties props, boolean animate) {
|
void updatePosition(int x, float scale, AnimationProperties props, boolean animate) {
|
||||||
x = getCurrentLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? -x : x;
|
x = getCurrentLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? -x : x;
|
||||||
|
|
||||||
PropertyAnimator.setProperty(mClockFrame, AnimatableProperty.TRANSLATION_X,
|
PropertyAnimator.setProperty(mSmallClockFrame, AnimatableProperty.TRANSLATION_X,
|
||||||
x, props, animate);
|
x, props, animate);
|
||||||
PropertyAnimator.setProperty(mLargeClockFrame, AnimatableProperty.SCALE_X,
|
PropertyAnimator.setProperty(mLargeClockFrame, AnimatableProperty.SCALE_X,
|
||||||
scale, props, animate);
|
scale, props, animate);
|
||||||
@@ -396,25 +310,39 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateTimeZone(TimeZone timeZone) {
|
|
||||||
mView.onTimeZoneChanged(timeZone);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get y-bottom position of the currently visible clock on the keyguard.
|
* Get y-bottom position of the currently visible clock on the keyguard.
|
||||||
* 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();
|
||||||
|
if (clock == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (mLargeClockFrame.getVisibility() == View.VISIBLE) {
|
if (mLargeClockFrame.getVisibility() == View.VISIBLE) {
|
||||||
View clock = mLargeClockFrame.findViewById(
|
|
||||||
com.android.systemui.R.id.animatable_clock_view_large);
|
|
||||||
int frameHeight = mLargeClockFrame.getHeight();
|
int frameHeight = mLargeClockFrame.getHeight();
|
||||||
int clockHeight = clock.getHeight();
|
int clockHeight = clock.getLargeClock().getHeight();
|
||||||
return frameHeight / 2 + clockHeight / 2;
|
return frameHeight / 2 + clockHeight / 2;
|
||||||
} else {
|
} else {
|
||||||
return mClockFrame.findViewById(
|
int clockHeight = clock.getSmallClock().getHeight();
|
||||||
com.android.systemui.R.id.animatable_clock_view).getHeight()
|
return clockHeight + statusBarHeaderHeight + mKeyguardClockTopMargin;
|
||||||
+ statusBarHeaderHeight + mKeyguardClockTopMargin;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the height of the currently visible clock on the keyguard.
|
||||||
|
*/
|
||||||
|
int getClockHeight() {
|
||||||
|
Clock clock = getClock();
|
||||||
|
if (clock == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mLargeClockFrame.getVisibility() == View.VISIBLE) {
|
||||||
|
return clock.getLargeClock().getHeight();
|
||||||
|
} else {
|
||||||
|
return clock.getSmallClock().getHeight();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,12 +357,13 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
mNotificationIconAreaController.setupAodIcons(nic);
|
mNotificationIconAreaController.setupAodIcons(nic);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setClockPlugin(ClockPlugin plugin) {
|
private void setClock(Clock clock) {
|
||||||
mView.setClockPlugin(plugin, mStatusBarStateController.getState());
|
mClockEventController.setClock(clock);
|
||||||
|
mView.setClock(clock, mStatusBarStateController.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ColorExtractor.GradientColors getGradientColors() {
|
private Clock getClock() {
|
||||||
return mColorExtractor.getColors(WallpaperManager.FLAG_LOCK);
|
return mClockEventController.getClock();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getCurrentLayoutDirection() {
|
private int getCurrentLayoutDirection() {
|
||||||
@@ -467,8 +396,10 @@ 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);
|
||||||
mClockViewController.dump(pw);
|
Clock clock = getClock();
|
||||||
mLargeClockViewController.dump(pw);
|
if (clock != null) {
|
||||||
|
clock.dump(pw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,14 +17,11 @@
|
|||||||
package com.android.keyguard;
|
package com.android.keyguard;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.GridLayout;
|
import android.widget.GridLayout;
|
||||||
|
|
||||||
import androidx.core.graphics.ColorUtils;
|
|
||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.statusbar.CrossFadeHelper;
|
import com.android.systemui.statusbar.CrossFadeHelper;
|
||||||
|
|
||||||
@@ -46,7 +43,6 @@ public class KeyguardStatusView extends GridLayout {
|
|||||||
private View mMediaHostContainer;
|
private View mMediaHostContainer;
|
||||||
|
|
||||||
private float mDarkAmount = 0;
|
private float mDarkAmount = 0;
|
||||||
private int mTextColor;
|
|
||||||
|
|
||||||
public KeyguardStatusView(Context context) {
|
public KeyguardStatusView(Context context) {
|
||||||
this(context, null, 0);
|
this(context, null, 0);
|
||||||
@@ -71,7 +67,6 @@ public class KeyguardStatusView extends GridLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mKeyguardSlice = findViewById(R.id.keyguard_slice_view);
|
mKeyguardSlice = findViewById(R.id.keyguard_slice_view);
|
||||||
mTextColor = mClockView.getCurrentTextColor();
|
|
||||||
|
|
||||||
mMediaHostContainer = findViewById(R.id.status_view_media_container);
|
mMediaHostContainer = findViewById(R.id.status_view_media_container);
|
||||||
|
|
||||||
@@ -83,15 +78,12 @@ public class KeyguardStatusView extends GridLayout {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mDarkAmount = darkAmount;
|
mDarkAmount = darkAmount;
|
||||||
mClockView.setDarkAmount(darkAmount);
|
|
||||||
CrossFadeHelper.fadeOut(mMediaHostContainer, darkAmount);
|
CrossFadeHelper.fadeOut(mMediaHostContainer, darkAmount);
|
||||||
updateDark();
|
updateDark();
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateDark() {
|
void updateDark() {
|
||||||
final int blendedTextColor = ColorUtils.blendARGB(mTextColor, Color.WHITE, mDarkAmount);
|
|
||||||
mKeyguardSlice.setDarkAmount(mDarkAmount);
|
mKeyguardSlice.setDarkAmount(mDarkAmount);
|
||||||
mClockView.setTextColor(blendedTextColor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets a translationY value on every child view except for the media view. */
|
/** Sets a translationY value on every child view except for the media view. */
|
||||||
@@ -113,7 +105,6 @@ public class KeyguardStatusView extends GridLayout {
|
|||||||
public void dump(PrintWriter pw, String[] args) {
|
public void dump(PrintWriter pw, String[] args) {
|
||||||
pw.println("KeyguardStatusView:");
|
pw.println("KeyguardStatusView:");
|
||||||
pw.println(" mDarkAmount: " + mDarkAmount);
|
pw.println(" mDarkAmount: " + mDarkAmount);
|
||||||
pw.println(" mTextColor: " + Integer.toHexString(mTextColor));
|
|
||||||
if (mClockView != null) {
|
if (mClockView != null) {
|
||||||
mClockView.dump(pw, args);
|
mClockView.dump(pw, args);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
|
|||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
import com.android.systemui.util.ViewController;
|
import com.android.systemui.util.ViewController;
|
||||||
|
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -95,13 +93,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
|||||||
mKeyguardSliceViewController.refresh();
|
mKeyguardSliceViewController.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The amount we're in doze.
|
|
||||||
*/
|
|
||||||
public void setDarkAmount(float darkAmount) {
|
|
||||||
mView.setDarkAmount(darkAmount);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set which clock should be displayed on the keyguard. The other one will be automatically
|
* Set which clock should be displayed on the keyguard. The other one will be automatically
|
||||||
* hidden.
|
* hidden.
|
||||||
@@ -114,16 +105,10 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
|||||||
* Performs fold to aod animation of the clocks (changes font weight from bold to thin).
|
* Performs fold to aod animation of the clocks (changes font weight from bold to thin).
|
||||||
* This animation is played when AOD is enabled and foldable device is fully folded, it is
|
* This animation is played when AOD is enabled and foldable device is fully folded, it is
|
||||||
* displayed on the outer screen
|
* displayed on the outer screen
|
||||||
|
* @param foldFraction current fraction of fold animation complete
|
||||||
*/
|
*/
|
||||||
public void animateFoldToAod() {
|
public void animateFoldToAod(float foldFraction) {
|
||||||
mKeyguardClockSwitchController.animateFoldToAod();
|
mKeyguardClockSwitchController.animateFoldToAod(foldFraction);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If we're presenting a custom clock of just the default one.
|
|
||||||
*/
|
|
||||||
public boolean hasCustomClock() {
|
|
||||||
return mKeyguardClockSwitchController.hasCustomClock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -143,24 +128,11 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set pivot x.
|
* Update the pivot position based on the parent view
|
||||||
*/
|
*/
|
||||||
public void setPivotX(float pivot) {
|
public void updatePivot(float parentWidth, float parentHeight) {
|
||||||
mView.setPivotX(pivot);
|
mView.setPivotX(parentWidth / 2f);
|
||||||
}
|
mView.setPivotY(mKeyguardClockSwitchController.getClockHeight() / 2f);
|
||||||
|
|
||||||
/**
|
|
||||||
* Set pivot y.
|
|
||||||
*/
|
|
||||||
public void setPivotY(float pivot) {
|
|
||||||
mView.setPivotY(pivot);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the clock text size.
|
|
||||||
*/
|
|
||||||
public float getClockTextSize() {
|
|
||||||
return mKeyguardClockSwitchController.getClockTextSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -239,11 +211,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
|||||||
refreshTime();
|
refreshTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTimeZoneChanged(TimeZone timeZone) {
|
|
||||||
mKeyguardClockSwitchController.updateTimeZone(timeZone);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onKeyguardVisibilityChanged(boolean showing) {
|
public void onKeyguardVisibilityChanged(boolean showing) {
|
||||||
if (showing) {
|
if (showing) {
|
||||||
|
|||||||
@@ -276,11 +276,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
|
private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
|
||||||
private final NotificationIconAreaController mNotificationIconAreaController;
|
private final NotificationIconAreaController mNotificationIconAreaController;
|
||||||
|
|
||||||
// Cap and total height of Roboto font. Needs to be adjusted when font for the big clock is
|
|
||||||
// changed.
|
|
||||||
private static final int CAP_HEIGHT = 1456;
|
|
||||||
private static final int FONT_HEIGHT = 2163;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum time before which we will expand the panel even for slow motions when getting a
|
* Maximum time before which we will expand the panel even for slow motions when getting a
|
||||||
* touch passed over from launcher.
|
* touch passed over from launcher.
|
||||||
@@ -1123,13 +1118,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if there's a custom clock being presented.
|
|
||||||
*/
|
|
||||||
public boolean hasCustomClock() {
|
|
||||||
return mKeyguardStatusViewController.hasCustomClock();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setCentralSurfaces(CentralSurfaces centralSurfaces) {
|
private void setCentralSurfaces(CentralSurfaces centralSurfaces) {
|
||||||
// TODO: this can be injected.
|
// TODO: this can be injected.
|
||||||
mCentralSurfaces = centralSurfaces;
|
mCentralSurfaces = centralSurfaces;
|
||||||
@@ -4009,9 +3997,10 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
endAction.run();
|
endAction.run();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.setUpdateListener(anim -> {
|
||||||
|
mKeyguardStatusViewController.animateFoldToAod(anim.getAnimatedFraction());
|
||||||
|
})
|
||||||
.start();
|
.start();
|
||||||
|
|
||||||
mKeyguardStatusViewController.animateFoldToAod();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -4873,7 +4862,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
public void onDozeAmountChanged(float linearAmount, float amount) {
|
public void onDozeAmountChanged(float linearAmount, float amount) {
|
||||||
mInterpolatedDarkAmount = amount;
|
mInterpolatedDarkAmount = amount;
|
||||||
mLinearDarkAmount = linearAmount;
|
mLinearDarkAmount = linearAmount;
|
||||||
mKeyguardStatusViewController.setDarkAmount(mInterpolatedDarkAmount);
|
|
||||||
mKeyguardBottomArea.setDarkAmount(mInterpolatedDarkAmount);
|
mKeyguardBottomArea.setDarkAmount(mInterpolatedDarkAmount);
|
||||||
positionClockAndNotifications();
|
positionClockAndNotifications();
|
||||||
}
|
}
|
||||||
@@ -4982,11 +4970,8 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
updateMaxDisplayedNotifications(!shouldAvoidChangingNotificationsCount());
|
updateMaxDisplayedNotifications(!shouldAvoidChangingNotificationsCount());
|
||||||
setIsFullWidth(mNotificationStackScrollLayoutController.getWidth() == mView.getWidth());
|
setIsFullWidth(mNotificationStackScrollLayoutController.getWidth() == mView.getWidth());
|
||||||
|
|
||||||
// Update Clock Pivot
|
// Update Clock Pivot (used by anti-burnin transformations)
|
||||||
mKeyguardStatusViewController.setPivotX(mView.getWidth() / 2);
|
mKeyguardStatusViewController.updatePivot(mView.getWidth(), mView.getHeight());
|
||||||
mKeyguardStatusViewController.setPivotY(
|
|
||||||
(FONT_HEIGHT - CAP_HEIGHT) / 2048f
|
|
||||||
* mKeyguardStatusViewController.getClockTextSize());
|
|
||||||
|
|
||||||
// Calculate quick setting heights.
|
// Calculate quick setting heights.
|
||||||
int oldMaxHeight = mQsMaxExpansionHeight;
|
int oldMaxHeight = mQsMaxExpansionHeight;
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedul
|
|||||||
import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.SHOWING_PERSISTENT_DOT;
|
import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.SHOWING_PERSISTENT_DOT;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.annotation.NonNull;
|
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
@@ -395,14 +394,6 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
|
|||||||
state |= DISABLE_CLOCK;
|
state |= DISABLE_CLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// The shelf will be hidden when dozing with a custom clock, we must show notification
|
|
||||||
// icons in this occasion.
|
|
||||||
if (mStatusBarStateController.isDozing()
|
|
||||||
&& mNotificationPanelViewController.hasCustomClock()) {
|
|
||||||
state |= DISABLE_CLOCK | DISABLE_SYSTEM_INFO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mOngoingCallController.hasOngoingCall()) {
|
if (mOngoingCallController.hasOngoingCall()) {
|
||||||
state &= ~DISABLE_ONGOING_CALL_CHIP;
|
state &= ~DISABLE_ONGOING_CALL_CHIP;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -0,0 +1,259 @@
|
|||||||
|
/*
|
||||||
|
* 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.keyguard
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.testing.AndroidTestingRunner
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.test.filters.SmallTest
|
||||||
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.broadcast.BroadcastDispatcher
|
||||||
|
import com.android.systemui.plugins.Clock
|
||||||
|
import com.android.systemui.plugins.ClockAnimations
|
||||||
|
import com.android.systemui.plugins.ClockEvents
|
||||||
|
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||||
|
import com.android.systemui.statusbar.policy.BatteryController
|
||||||
|
import com.android.systemui.statusbar.policy.ConfigurationController
|
||||||
|
import com.android.systemui.util.mockito.any
|
||||||
|
import com.android.systemui.util.mockito.argumentCaptor
|
||||||
|
import com.android.systemui.util.mockito.capture
|
||||||
|
import com.android.systemui.util.mockito.eq
|
||||||
|
import com.android.systemui.util.mockito.mock
|
||||||
|
import java.util.TimeZone
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.mockito.ArgumentMatchers.anyFloat
|
||||||
|
import org.mockito.ArgumentMatchers.anyInt
|
||||||
|
import org.mockito.Mock
|
||||||
|
import org.mockito.Mockito.never
|
||||||
|
import org.mockito.Mockito.times
|
||||||
|
import org.mockito.Mockito.verify
|
||||||
|
import org.mockito.Mockito.`when` as whenever
|
||||||
|
import org.mockito.junit.MockitoJUnit
|
||||||
|
|
||||||
|
@RunWith(AndroidTestingRunner::class)
|
||||||
|
@SmallTest
|
||||||
|
class ClockEventControllerTest : SysuiTestCase() {
|
||||||
|
|
||||||
|
@JvmField @Rule val mockito = MockitoJUnit.rule()
|
||||||
|
@Mock private lateinit var statusBarStateController: StatusBarStateController
|
||||||
|
@Mock private lateinit var broadcastDispatcher: BroadcastDispatcher
|
||||||
|
@Mock private lateinit var batteryController: BatteryController
|
||||||
|
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
|
||||||
|
@Mock private lateinit var configurationController: ConfigurationController
|
||||||
|
@Mock private lateinit var animations: ClockAnimations
|
||||||
|
@Mock private lateinit var events: ClockEvents
|
||||||
|
@Mock private lateinit var clock: Clock
|
||||||
|
|
||||||
|
private lateinit var clockEventController: ClockEventController
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
whenever(clock.smallClock).thenReturn(TextView(context))
|
||||||
|
whenever(clock.largeClock).thenReturn(TextView(context))
|
||||||
|
whenever(clock.events).thenReturn(events)
|
||||||
|
whenever(clock.animations).thenReturn(animations)
|
||||||
|
|
||||||
|
clockEventController = ClockEventController(
|
||||||
|
statusBarStateController,
|
||||||
|
broadcastDispatcher,
|
||||||
|
batteryController,
|
||||||
|
keyguardUpdateMonitor,
|
||||||
|
configurationController,
|
||||||
|
context.resources,
|
||||||
|
context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun clockSet_validateInitialization() {
|
||||||
|
clockEventController.clock = clock
|
||||||
|
|
||||||
|
verify(clock).initialize(any(), anyFloat(), anyFloat())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun clockUnset_validateState() {
|
||||||
|
clockEventController.clock = clock
|
||||||
|
clockEventController.clock = null
|
||||||
|
|
||||||
|
assertEquals(clockEventController.clock, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun themeChanged_verifyClockPaletteUpdated() {
|
||||||
|
clockEventController.clock = clock
|
||||||
|
clockEventController.registerListeners()
|
||||||
|
|
||||||
|
val captor = argumentCaptor<ConfigurationController.ConfigurationListener>()
|
||||||
|
verify(configurationController).addCallback(capture(captor))
|
||||||
|
captor.value.onThemeChanged()
|
||||||
|
|
||||||
|
verify(events).onColorPaletteChanged(any())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun batteryCallback_keyguardShowingCharging_verifyChargeAnimation() {
|
||||||
|
clockEventController.clock = clock
|
||||||
|
clockEventController.registerListeners()
|
||||||
|
|
||||||
|
val batteryCaptor = argumentCaptor<BatteryController.BatteryStateChangeCallback>()
|
||||||
|
verify(batteryController).addCallback(capture(batteryCaptor))
|
||||||
|
val keyguardCaptor = argumentCaptor<KeyguardUpdateMonitorCallback>()
|
||||||
|
verify(keyguardUpdateMonitor).registerCallback(capture(keyguardCaptor))
|
||||||
|
keyguardCaptor.value.onKeyguardVisibilityChanged(true)
|
||||||
|
batteryCaptor.value.onBatteryLevelChanged(10, false, true)
|
||||||
|
|
||||||
|
verify(animations).charge()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun batteryCallback_keyguardShowingCharging_Duplicate_verifyChargeAnimation() {
|
||||||
|
clockEventController.clock = clock
|
||||||
|
clockEventController.registerListeners()
|
||||||
|
|
||||||
|
val batteryCaptor = argumentCaptor<BatteryController.BatteryStateChangeCallback>()
|
||||||
|
verify(batteryController).addCallback(capture(batteryCaptor))
|
||||||
|
val keyguardCaptor = argumentCaptor<KeyguardUpdateMonitorCallback>()
|
||||||
|
verify(keyguardUpdateMonitor).registerCallback(capture(keyguardCaptor))
|
||||||
|
keyguardCaptor.value.onKeyguardVisibilityChanged(true)
|
||||||
|
batteryCaptor.value.onBatteryLevelChanged(10, false, true)
|
||||||
|
batteryCaptor.value.onBatteryLevelChanged(10, false, true)
|
||||||
|
|
||||||
|
verify(animations, times(1)).charge()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun batteryCallback_keyguardHiddenCharging_verifyChargeAnimation() {
|
||||||
|
clockEventController.clock = clock
|
||||||
|
clockEventController.registerListeners()
|
||||||
|
|
||||||
|
val batteryCaptor = argumentCaptor<BatteryController.BatteryStateChangeCallback>()
|
||||||
|
verify(batteryController).addCallback(capture(batteryCaptor))
|
||||||
|
val keyguardCaptor = argumentCaptor<KeyguardUpdateMonitorCallback>()
|
||||||
|
verify(keyguardUpdateMonitor).registerCallback(capture(keyguardCaptor))
|
||||||
|
keyguardCaptor.value.onKeyguardVisibilityChanged(false)
|
||||||
|
batteryCaptor.value.onBatteryLevelChanged(10, false, true)
|
||||||
|
|
||||||
|
verify(animations, never()).charge()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun batteryCallback_keyguardShowingNotCharging_verifyChargeAnimation() {
|
||||||
|
clockEventController.clock = clock
|
||||||
|
clockEventController.registerListeners()
|
||||||
|
|
||||||
|
val batteryCaptor = argumentCaptor<BatteryController.BatteryStateChangeCallback>()
|
||||||
|
verify(batteryController).addCallback(capture(batteryCaptor))
|
||||||
|
val keyguardCaptor = argumentCaptor<KeyguardUpdateMonitorCallback>()
|
||||||
|
verify(keyguardUpdateMonitor).registerCallback(capture(keyguardCaptor))
|
||||||
|
keyguardCaptor.value.onKeyguardVisibilityChanged(true)
|
||||||
|
batteryCaptor.value.onBatteryLevelChanged(10, false, false)
|
||||||
|
|
||||||
|
verify(animations, never()).charge()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun localeCallback_verifyClockNotified() {
|
||||||
|
clockEventController.clock = clock
|
||||||
|
clockEventController.registerListeners()
|
||||||
|
|
||||||
|
val captor = argumentCaptor<BroadcastReceiver>()
|
||||||
|
verify(broadcastDispatcher).registerReceiver(
|
||||||
|
capture(captor), any(), eq(null), eq(null), anyInt(), eq(null)
|
||||||
|
)
|
||||||
|
captor.value.onReceive(context, mock())
|
||||||
|
|
||||||
|
verify(events).onLocaleChanged(any())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun keyguardCallback_visibilityChanged_clockDozeCalled() {
|
||||||
|
clockEventController.clock = clock
|
||||||
|
clockEventController.registerListeners()
|
||||||
|
|
||||||
|
val captor = argumentCaptor<KeyguardUpdateMonitorCallback>()
|
||||||
|
verify(keyguardUpdateMonitor).registerCallback(capture(captor))
|
||||||
|
|
||||||
|
captor.value.onKeyguardVisibilityChanged(true)
|
||||||
|
verify(animations, never()).doze(0f)
|
||||||
|
|
||||||
|
captor.value.onKeyguardVisibilityChanged(false)
|
||||||
|
verify(animations, times(1)).doze(0f)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun keyguardCallback_timeFormat_clockNotified() {
|
||||||
|
clockEventController.clock = clock
|
||||||
|
clockEventController.registerListeners()
|
||||||
|
|
||||||
|
val captor = argumentCaptor<KeyguardUpdateMonitorCallback>()
|
||||||
|
verify(keyguardUpdateMonitor).registerCallback(capture(captor))
|
||||||
|
captor.value.onTimeFormatChanged("12h")
|
||||||
|
|
||||||
|
verify(events).onTimeFormatChanged(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun keyguardCallback_timezoneChanged_clockNotified() {
|
||||||
|
val mockTimeZone = mock<TimeZone>()
|
||||||
|
clockEventController.clock = clock
|
||||||
|
clockEventController.registerListeners()
|
||||||
|
|
||||||
|
val captor = argumentCaptor<KeyguardUpdateMonitorCallback>()
|
||||||
|
verify(keyguardUpdateMonitor).registerCallback(capture(captor))
|
||||||
|
captor.value.onTimeZoneChanged(mockTimeZone)
|
||||||
|
|
||||||
|
verify(events).onTimeZoneChanged(mockTimeZone)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun keyguardCallback_userSwitched_clockNotified() {
|
||||||
|
clockEventController.clock = clock
|
||||||
|
clockEventController.registerListeners()
|
||||||
|
|
||||||
|
val captor = argumentCaptor<KeyguardUpdateMonitorCallback>()
|
||||||
|
verify(keyguardUpdateMonitor).registerCallback(capture(captor))
|
||||||
|
captor.value.onUserSwitchComplete(10)
|
||||||
|
|
||||||
|
verify(events).onTimeFormatChanged(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun keyguardCallback_verifyKeyguardChanged() {
|
||||||
|
clockEventController.clock = clock
|
||||||
|
clockEventController.registerListeners()
|
||||||
|
|
||||||
|
val captor = argumentCaptor<StatusBarStateController.StateListener>()
|
||||||
|
verify(statusBarStateController).addCallback(capture(captor))
|
||||||
|
captor.value.onDozeAmountChanged(0.4f, 0.6f)
|
||||||
|
|
||||||
|
verify(animations).doze(0.4f)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun unregisterListeners_validate() {
|
||||||
|
clockEventController.unregisterListeners()
|
||||||
|
verify(broadcastDispatcher).unregisterReceiver(any())
|
||||||
|
verify(configurationController).removeCallback(any())
|
||||||
|
verify(batteryController).removeCallback(any())
|
||||||
|
verify(keyguardUpdateMonitor).removeCallback(any())
|
||||||
|
verify(statusBarStateController).removeCallback(any())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,6 @@ package com.android.keyguard;
|
|||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
@@ -41,23 +40,18 @@ import android.widget.RelativeLayout;
|
|||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
import com.android.internal.colorextraction.ColorExtractor;
|
|
||||||
import com.android.keyguard.clock.ClockManager;
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
|
||||||
import com.android.systemui.colorextraction.SysuiColorExtractor;
|
|
||||||
import com.android.systemui.dump.DumpManager;
|
import com.android.systemui.dump.DumpManager;
|
||||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||||
import com.android.systemui.plugins.ClockPlugin;
|
import com.android.systemui.plugins.Clock;
|
||||||
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.statusbar.StatusBarState;
|
import com.android.systemui.statusbar.StatusBarState;
|
||||||
import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
|
import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
|
||||||
import com.android.systemui.statusbar.phone.KeyguardBypassController;
|
|
||||||
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
|
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
|
||||||
import com.android.systemui.statusbar.phone.NotificationIconContainer;
|
import com.android.systemui.statusbar.phone.NotificationIconContainer;
|
||||||
import com.android.systemui.statusbar.policy.BatteryController;
|
|
||||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||||
import com.android.systemui.util.settings.SecureSettings;
|
import com.android.systemui.util.settings.SecureSettings;
|
||||||
import com.android.systemui.util.time.FakeSystemClock;
|
import com.android.systemui.util.time.FakeSystemClock;
|
||||||
@@ -79,22 +73,12 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
|
|||||||
@Mock
|
@Mock
|
||||||
private StatusBarStateController mStatusBarStateController;
|
private StatusBarStateController mStatusBarStateController;
|
||||||
@Mock
|
@Mock
|
||||||
private SysuiColorExtractor mColorExtractor;
|
private ClockRegistry mClockRegistry;
|
||||||
@Mock
|
|
||||||
private ClockManager mClockManager;
|
|
||||||
@Mock
|
@Mock
|
||||||
KeyguardSliceViewController mKeyguardSliceViewController;
|
KeyguardSliceViewController mKeyguardSliceViewController;
|
||||||
@Mock
|
@Mock
|
||||||
NotificationIconAreaController mNotificationIconAreaController;
|
NotificationIconAreaController mNotificationIconAreaController;
|
||||||
@Mock
|
@Mock
|
||||||
BroadcastDispatcher mBroadcastDispatcher;
|
|
||||||
@Mock
|
|
||||||
BatteryController mBatteryController;
|
|
||||||
@Mock
|
|
||||||
KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
|
||||||
@Mock
|
|
||||||
KeyguardBypassController mBypassController;
|
|
||||||
@Mock
|
|
||||||
LockscreenSmartspaceController mSmartspaceController;
|
LockscreenSmartspaceController mSmartspaceController;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
@@ -102,11 +86,11 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
|
|||||||
@Mock
|
@Mock
|
||||||
KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
|
KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
|
||||||
@Mock
|
@Mock
|
||||||
private ClockPlugin mClockPlugin;
|
private Clock mClock;
|
||||||
@Mock
|
|
||||||
ColorExtractor.GradientColors mGradientColors;
|
|
||||||
@Mock
|
@Mock
|
||||||
DumpManager mDumpManager;
|
DumpManager mDumpManager;
|
||||||
|
@Mock
|
||||||
|
ClockEventController mClockEventController;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private NotificationIconContainer mNotificationIcons;
|
private NotificationIconContainer mNotificationIcons;
|
||||||
@@ -136,8 +120,6 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
|
|||||||
when(mView.getContext()).thenReturn(getContext());
|
when(mView.getContext()).thenReturn(getContext());
|
||||||
when(mView.getResources()).thenReturn(mResources);
|
when(mView.getResources()).thenReturn(mResources);
|
||||||
|
|
||||||
when(mView.findViewById(R.id.animatable_clock_view)).thenReturn(mClockView);
|
|
||||||
when(mView.findViewById(R.id.animatable_clock_view_large)).thenReturn(mLargeClockView);
|
|
||||||
when(mView.findViewById(R.id.lockscreen_clock_view_large)).thenReturn(mLargeClockFrame);
|
when(mView.findViewById(R.id.lockscreen_clock_view_large)).thenReturn(mLargeClockFrame);
|
||||||
when(mClockView.getContext()).thenReturn(getContext());
|
when(mClockView.getContext()).thenReturn(getContext());
|
||||||
when(mLargeClockView.getContext()).thenReturn(getContext());
|
when(mLargeClockView.getContext()).thenReturn(getContext());
|
||||||
@@ -148,23 +130,19 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
|
|||||||
mController = new KeyguardClockSwitchController(
|
mController = new KeyguardClockSwitchController(
|
||||||
mView,
|
mView,
|
||||||
mStatusBarStateController,
|
mStatusBarStateController,
|
||||||
mColorExtractor,
|
mClockRegistry,
|
||||||
mClockManager,
|
|
||||||
mKeyguardSliceViewController,
|
mKeyguardSliceViewController,
|
||||||
mNotificationIconAreaController,
|
mNotificationIconAreaController,
|
||||||
mBroadcastDispatcher,
|
|
||||||
mBatteryController,
|
|
||||||
mKeyguardUpdateMonitor,
|
|
||||||
mSmartspaceController,
|
mSmartspaceController,
|
||||||
mKeyguardUnlockAnimationController,
|
mKeyguardUnlockAnimationController,
|
||||||
mSecureSettings,
|
mSecureSettings,
|
||||||
mExecutor,
|
mExecutor,
|
||||||
mResources,
|
mDumpManager,
|
||||||
mDumpManager
|
mClockEventController
|
||||||
);
|
);
|
||||||
|
|
||||||
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
|
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
|
||||||
when(mColorExtractor.getColors(anyInt())).thenReturn(mGradientColors);
|
when(mClockRegistry.createCurrentClock()).thenReturn(mClock);
|
||||||
|
|
||||||
mSliceView = new View(getContext());
|
mSliceView = new View(getContext());
|
||||||
when(mView.findViewById(R.id.keyguard_slice_view)).thenReturn(mSliceView);
|
when(mView.findViewById(R.id.keyguard_slice_view)).thenReturn(mSliceView);
|
||||||
@@ -211,20 +189,20 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
|
|||||||
verifyAttachment(times(1));
|
verifyAttachment(times(1));
|
||||||
|
|
||||||
listenerArgumentCaptor.getValue().onViewDetachedFromWindow(mView);
|
listenerArgumentCaptor.getValue().onViewDetachedFromWindow(mView);
|
||||||
verify(mColorExtractor).removeOnColorsChangedListener(
|
verify(mClockEventController).unregisterListeners();
|
||||||
any(ColorExtractor.OnColorsChangedListener.class));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPluginPassesStatusBarState() {
|
public void testPluginPassesStatusBarState() {
|
||||||
ArgumentCaptor<ClockManager.ClockChangedListener> listenerArgumentCaptor =
|
ArgumentCaptor<ClockRegistry.ClockChangeListener> listenerArgumentCaptor =
|
||||||
ArgumentCaptor.forClass(ClockManager.ClockChangedListener.class);
|
ArgumentCaptor.forClass(ClockRegistry.ClockChangeListener.class);
|
||||||
|
|
||||||
mController.init();
|
mController.init();
|
||||||
verify(mClockManager).addOnClockChangedListener(listenerArgumentCaptor.capture());
|
verify(mClockRegistry).registerClockChangeListener(listenerArgumentCaptor.capture());
|
||||||
|
|
||||||
listenerArgumentCaptor.getValue().onClockChanged(mClockPlugin);
|
listenerArgumentCaptor.getValue().onClockChanged();
|
||||||
verify(mView).setClockPlugin(mClockPlugin, StatusBarState.SHADE);
|
verify(mView, times(2)).setClock(mClock, StatusBarState.SHADE);
|
||||||
|
verify(mClockEventController, times(2)).setClock(mClock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -281,10 +259,8 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void verifyAttachment(VerificationMode times) {
|
private void verifyAttachment(VerificationMode times) {
|
||||||
verify(mClockManager, times).addOnClockChangedListener(
|
verify(mClockRegistry, times).registerClockChangeListener(
|
||||||
any(ClockManager.ClockChangedListener.class));
|
any(ClockRegistry.ClockChangeListener.class));
|
||||||
verify(mColorExtractor, times).addOnColorsChangedListener(
|
verify(mClockEventController, times).registerListeners();
|
||||||
any(ColorExtractor.OnColorsChangedListener.class));
|
|
||||||
verify(mView, times).updateColors(mGradientColors);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package com.android.keyguard;
|
package com.android.keyguard;
|
||||||
|
|
||||||
import static android.view.View.GONE;
|
|
||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
|
|
||||||
import static com.android.keyguard.KeyguardClockSwitch.LARGE;
|
import static com.android.keyguard.KeyguardClockSwitch.LARGE;
|
||||||
@@ -24,56 +23,61 @@ import static com.android.keyguard.KeyguardClockSwitch.SMALL;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint.Style;
|
|
||||||
import android.test.suitebuilder.annotation.SmallTest;
|
import android.test.suitebuilder.annotation.SmallTest;
|
||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
import android.testing.TestableLooper.RunWithLooper;
|
import android.testing.TestableLooper.RunWithLooper;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.TextClock;
|
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.ClockPlugin;
|
import com.android.systemui.plugins.Clock;
|
||||||
import com.android.systemui.shared.clocks.AnimatableClockView;
|
|
||||||
import com.android.systemui.statusbar.StatusBarState;
|
import com.android.systemui.statusbar.StatusBarState;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidTestingRunner.class)
|
@RunWith(AndroidTestingRunner.class)
|
||||||
// Need to run on the main thread because KeyguardSliceView$Row init checks for
|
// Need to run on the main thread because KeyguardSliceView$Row init checks for
|
||||||
// the main thread before acquiring a wake lock. This class is constructed when
|
// the main thread before acquiring a wake lock. This class is constructed when
|
||||||
// the keyguard_clcok_switch layout is inflated.
|
// the keyguard_clock_switch layout is inflated.
|
||||||
@RunWithLooper(setAsMainLooper = true)
|
@RunWithLooper(setAsMainLooper = true)
|
||||||
public class KeyguardClockSwitchTest extends SysuiTestCase {
|
public class KeyguardClockSwitchTest extends SysuiTestCase {
|
||||||
private FrameLayout mClockFrame;
|
@Mock
|
||||||
private FrameLayout mLargeClockFrame;
|
ViewGroup mMockKeyguardSliceView;
|
||||||
private TextClock mBigClock;
|
|
||||||
|
@Mock
|
||||||
|
Clock mClock;
|
||||||
|
|
||||||
|
private FrameLayout mSmallClockFrame;
|
||||||
|
private FrameLayout mLargeClockFrame;
|
||||||
|
|
||||||
private AnimatableClockView mClockView;
|
|
||||||
private AnimatableClockView mLargeClockView;
|
|
||||||
View mMockKeyguardSliceView;
|
|
||||||
KeyguardClockSwitch mKeyguardClockSwitch;
|
KeyguardClockSwitch mKeyguardClockSwitch;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
mMockKeyguardSliceView = mock(KeyguardSliceView.class);
|
MockitoAnnotations.initMocks(this);
|
||||||
when(mMockKeyguardSliceView.getContext()).thenReturn(mContext);
|
when(mMockKeyguardSliceView.getContext()).thenReturn(mContext);
|
||||||
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.getLargeClock()).thenReturn(new TextView(getContext()));
|
||||||
|
|
||||||
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
|
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
|
||||||
layoutInflater.setPrivateFactory(new LayoutInflater.Factory2() {
|
layoutInflater.setPrivateFactory(new LayoutInflater.Factory2() {
|
||||||
|
|
||||||
@@ -93,164 +97,68 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
|
|||||||
});
|
});
|
||||||
mKeyguardClockSwitch =
|
mKeyguardClockSwitch =
|
||||||
(KeyguardClockSwitch) layoutInflater.inflate(R.layout.keyguard_clock_switch, null);
|
(KeyguardClockSwitch) layoutInflater.inflate(R.layout.keyguard_clock_switch, null);
|
||||||
mClockFrame = mKeyguardClockSwitch.findViewById(R.id.lockscreen_clock_view);
|
mSmallClockFrame = mKeyguardClockSwitch.findViewById(R.id.lockscreen_clock_view);
|
||||||
mClockView = mKeyguardClockSwitch.findViewById(R.id.animatable_clock_view);
|
|
||||||
mLargeClockFrame = mKeyguardClockSwitch.findViewById(R.id.lockscreen_clock_view_large);
|
mLargeClockFrame = mKeyguardClockSwitch.findViewById(R.id.lockscreen_clock_view_large);
|
||||||
mLargeClockView = mKeyguardClockSwitch.findViewById(R.id.animatable_clock_view_large);
|
|
||||||
mBigClock = new TextClock(getContext());
|
|
||||||
mKeyguardClockSwitch.mChildrenAreLaidOut = true;
|
mKeyguardClockSwitch.mChildrenAreLaidOut = true;
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onPluginConnected_showPluginClock() {
|
public void noPluginConnected_showNothing() {
|
||||||
ClockPlugin plugin = mock(ClockPlugin.class);
|
mKeyguardClockSwitch.setClock(null, StatusBarState.KEYGUARD);
|
||||||
TextClock pluginView = new TextClock(getContext());
|
assertEquals(mLargeClockFrame.getChildCount(), 0);
|
||||||
when(plugin.getView()).thenReturn(pluginView);
|
assertEquals(mSmallClockFrame.getChildCount(), 0);
|
||||||
|
|
||||||
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
|
|
||||||
|
|
||||||
assertThat(mClockView.getVisibility()).isEqualTo(GONE);
|
|
||||||
assertThat(plugin.getView().getParent()).isEqualTo(mClockFrame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onPluginConnected_showPluginBigClock() {
|
public void pluginConnectedThenDisconnected_showNothing() {
|
||||||
// GIVEN the plugin returns a view for the big clock
|
mKeyguardClockSwitch.setClock(mClock, StatusBarState.KEYGUARD);
|
||||||
ClockPlugin plugin = mock(ClockPlugin.class);
|
assertEquals(mLargeClockFrame.getChildCount(), 1);
|
||||||
when(plugin.getBigClockView()).thenReturn(mBigClock);
|
assertEquals(mSmallClockFrame.getChildCount(), 1);
|
||||||
// WHEN the plugin is connected
|
|
||||||
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
|
mKeyguardClockSwitch.setClock(null, StatusBarState.KEYGUARD);
|
||||||
// THEN the big clock container is visible and it is the parent of the
|
assertEquals(mLargeClockFrame.getChildCount(), 0);
|
||||||
// big clock view.
|
assertEquals(mSmallClockFrame.getChildCount(), 0);
|
||||||
assertThat(mLargeClockView.getVisibility()).isEqualTo(View.GONE);
|
|
||||||
assertThat(mBigClock.getParent()).isEqualTo(mLargeClockFrame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onPluginConnected_nullView() {
|
public void onPluginConnected_showClock() {
|
||||||
ClockPlugin plugin = mock(ClockPlugin.class);
|
mKeyguardClockSwitch.setClock(mClock, StatusBarState.KEYGUARD);
|
||||||
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
|
|
||||||
assertThat(mClockView.getVisibility()).isEqualTo(VISIBLE);
|
assertEquals(mClock.getSmallClock().getParent(), mSmallClockFrame);
|
||||||
|
assertEquals(mClock.getLargeClock().getParent(), mLargeClockFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onPluginConnected_showSecondPluginClock() {
|
public void onPluginConnected_showSecondPluginClock() {
|
||||||
// GIVEN a plugin has already connected
|
// GIVEN a plugin has already connected
|
||||||
ClockPlugin plugin1 = mock(ClockPlugin.class);
|
Clock otherClock = mock(Clock.class);
|
||||||
when(plugin1.getView()).thenReturn(new TextClock(getContext()));
|
when(otherClock.getSmallClock()).thenReturn(new TextView(getContext()));
|
||||||
mKeyguardClockSwitch.setClockPlugin(plugin1, StatusBarState.KEYGUARD);
|
when(otherClock.getLargeClock()).thenReturn(new TextView(getContext()));
|
||||||
// WHEN a second plugin is connected
|
mKeyguardClockSwitch.setClock(mClock, StatusBarState.KEYGUARD);
|
||||||
ClockPlugin plugin2 = mock(ClockPlugin.class);
|
mKeyguardClockSwitch.setClock(otherClock, StatusBarState.KEYGUARD);
|
||||||
when(plugin2.getView()).thenReturn(new TextClock(getContext()));
|
|
||||||
mKeyguardClockSwitch.setClockPlugin(plugin2, 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(plugin2.getView().getParent()).isEqualTo(mClockFrame);
|
assertThat(otherClock.getSmallClock().getParent()).isEqualTo(mSmallClockFrame);
|
||||||
assertThat(plugin1.getView().getParent()).isNull();
|
assertThat(otherClock.getLargeClock().getParent()).isEqualTo(mLargeClockFrame);
|
||||||
}
|
assertThat(mClock.getSmallClock().getParent()).isNull();
|
||||||
|
assertThat(mClock.getLargeClock().getParent()).isNull();
|
||||||
@Test
|
|
||||||
public void onPluginConnected_darkAmountInitialized() {
|
|
||||||
// GIVEN that the dark amount has already been set
|
|
||||||
mKeyguardClockSwitch.setDarkAmount(0.5f);
|
|
||||||
// WHEN a plugin is connected
|
|
||||||
ClockPlugin plugin = mock(ClockPlugin.class);
|
|
||||||
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
|
|
||||||
// THEN dark amount should be initalized on the plugin.
|
|
||||||
verify(plugin).setDarkAmount(0.5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onPluginDisconnected_showDefaultClock() {
|
|
||||||
ClockPlugin plugin = mock(ClockPlugin.class);
|
|
||||||
TextClock pluginView = new TextClock(getContext());
|
|
||||||
when(plugin.getView()).thenReturn(pluginView);
|
|
||||||
|
|
||||||
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
|
|
||||||
assertThat(mClockView.getVisibility()).isEqualTo(GONE);
|
|
||||||
|
|
||||||
mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
|
|
||||||
assertThat(mClockView.getVisibility()).isEqualTo(VISIBLE);
|
|
||||||
|
|
||||||
assertThat(plugin.getView().getParent()).isNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onPluginDisconnected_hidePluginBigClock() {
|
|
||||||
// GIVEN the plugin returns a view for the big clock
|
|
||||||
ClockPlugin plugin = mock(ClockPlugin.class);
|
|
||||||
TextClock pluginView = new TextClock(getContext());
|
|
||||||
when(plugin.getBigClockView()).thenReturn(pluginView);
|
|
||||||
// WHEN the plugin is connected and then disconnected
|
|
||||||
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
|
|
||||||
mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
|
|
||||||
// THEN the big lock container is GONE and the big clock view doesn't have
|
|
||||||
// a parent.
|
|
||||||
assertThat(mLargeClockView.getVisibility()).isEqualTo(VISIBLE);
|
|
||||||
assertThat(pluginView.getParent()).isNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onPluginDisconnected_nullView() {
|
|
||||||
ClockPlugin plugin = mock(ClockPlugin.class);
|
|
||||||
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
|
|
||||||
mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
|
|
||||||
assertThat(mClockView.getVisibility()).isEqualTo(VISIBLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onPluginDisconnected_secondOfTwoDisconnected() {
|
public void onPluginDisconnected_secondOfTwoDisconnected() {
|
||||||
// GIVEN two plugins are connected
|
// GIVEN two plugins are connected
|
||||||
ClockPlugin plugin1 = mock(ClockPlugin.class);
|
Clock otherClock = mock(Clock.class);
|
||||||
when(plugin1.getView()).thenReturn(new TextClock(getContext()));
|
when(otherClock.getSmallClock()).thenReturn(new TextView(getContext()));
|
||||||
mKeyguardClockSwitch.setClockPlugin(plugin1, StatusBarState.KEYGUARD);
|
when(otherClock.getLargeClock()).thenReturn(new TextView(getContext()));
|
||||||
ClockPlugin plugin2 = mock(ClockPlugin.class);
|
mKeyguardClockSwitch.setClock(otherClock, StatusBarState.KEYGUARD);
|
||||||
when(plugin2.getView()).thenReturn(new TextClock(getContext()));
|
mKeyguardClockSwitch.setClock(mClock, StatusBarState.KEYGUARD);
|
||||||
mKeyguardClockSwitch.setClockPlugin(plugin2, StatusBarState.KEYGUARD);
|
|
||||||
// WHEN the second plugin is disconnected
|
// WHEN the second plugin is disconnected
|
||||||
mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
|
mKeyguardClockSwitch.setClock(null, StatusBarState.KEYGUARD);
|
||||||
// THEN the default clock should be shown.
|
// THEN nothing should be shown
|
||||||
assertThat(mClockView.getVisibility()).isEqualTo(VISIBLE);
|
assertThat(otherClock.getSmallClock().getParent()).isNull();
|
||||||
assertThat(plugin1.getView().getParent()).isNull();
|
assertThat(otherClock.getLargeClock().getParent()).isNull();
|
||||||
assertThat(plugin2.getView().getParent()).isNull();
|
assertThat(mClock.getSmallClock().getParent()).isNull();
|
||||||
}
|
assertThat(mClock.getLargeClock().getParent()).isNull();
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onPluginDisconnected_onDestroyView() {
|
|
||||||
// GIVEN a plugin is connected
|
|
||||||
ClockPlugin clockPlugin = mock(ClockPlugin.class);
|
|
||||||
when(clockPlugin.getView()).thenReturn(new TextClock(getContext()));
|
|
||||||
mKeyguardClockSwitch.setClockPlugin(clockPlugin, StatusBarState.KEYGUARD);
|
|
||||||
// WHEN the plugin is disconnected
|
|
||||||
mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
|
|
||||||
// THEN onDestroyView is called on the plugin
|
|
||||||
verify(clockPlugin).onDestroyView();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void setTextColor_pluginClockSetTextColor() {
|
|
||||||
ClockPlugin plugin = mock(ClockPlugin.class);
|
|
||||||
TextClock pluginView = new TextClock(getContext());
|
|
||||||
when(plugin.getView()).thenReturn(pluginView);
|
|
||||||
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
|
|
||||||
|
|
||||||
mKeyguardClockSwitch.setTextColor(Color.WHITE);
|
|
||||||
|
|
||||||
verify(plugin).setTextColor(Color.WHITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void setStyle_pluginClockSetStyle() {
|
|
||||||
ClockPlugin plugin = mock(ClockPlugin.class);
|
|
||||||
TextClock pluginView = new TextClock(getContext());
|
|
||||||
when(plugin.getView()).thenReturn(pluginView);
|
|
||||||
Style style = mock(Style.class);
|
|
||||||
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
|
|
||||||
|
|
||||||
mKeyguardClockSwitch.setStyle(style);
|
|
||||||
|
|
||||||
verify(plugin).setStyle(style);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -262,7 +170,7 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
|
|||||||
|
|
||||||
assertThat(mLargeClockFrame.getAlpha()).isEqualTo(1);
|
assertThat(mLargeClockFrame.getAlpha()).isEqualTo(1);
|
||||||
assertThat(mLargeClockFrame.getVisibility()).isEqualTo(VISIBLE);
|
assertThat(mLargeClockFrame.getVisibility()).isEqualTo(VISIBLE);
|
||||||
assertThat(mClockFrame.getAlpha()).isEqualTo(0);
|
assertThat(mSmallClockFrame.getAlpha()).isEqualTo(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -271,7 +179,7 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
|
|||||||
|
|
||||||
assertThat(mLargeClockFrame.getAlpha()).isEqualTo(1);
|
assertThat(mLargeClockFrame.getAlpha()).isEqualTo(1);
|
||||||
assertThat(mLargeClockFrame.getVisibility()).isEqualTo(VISIBLE);
|
assertThat(mLargeClockFrame.getVisibility()).isEqualTo(VISIBLE);
|
||||||
assertThat(mClockFrame.getAlpha()).isEqualTo(0);
|
assertThat(mSmallClockFrame.getAlpha()).isEqualTo(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -281,8 +189,8 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
|
|||||||
mKeyguardClockSwitch.mClockInAnim.end();
|
mKeyguardClockSwitch.mClockInAnim.end();
|
||||||
mKeyguardClockSwitch.mClockOutAnim.end();
|
mKeyguardClockSwitch.mClockOutAnim.end();
|
||||||
|
|
||||||
assertThat(mClockFrame.getAlpha()).isEqualTo(1);
|
assertThat(mSmallClockFrame.getAlpha()).isEqualTo(1);
|
||||||
assertThat(mClockFrame.getVisibility()).isEqualTo(VISIBLE);
|
assertThat(mSmallClockFrame.getVisibility()).isEqualTo(VISIBLE);
|
||||||
// only big clock is removed at switch
|
// only big clock is removed at switch
|
||||||
assertThat(mLargeClockFrame.getParent()).isNull();
|
assertThat(mLargeClockFrame.getParent()).isNull();
|
||||||
assertThat(mLargeClockFrame.getAlpha()).isEqualTo(0);
|
assertThat(mLargeClockFrame.getAlpha()).isEqualTo(0);
|
||||||
@@ -292,8 +200,8 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
|
|||||||
public void switchingToSmallClockNoAnimation_makesBigClockDisappear() {
|
public void switchingToSmallClockNoAnimation_makesBigClockDisappear() {
|
||||||
mKeyguardClockSwitch.switchToClock(SMALL, false);
|
mKeyguardClockSwitch.switchToClock(SMALL, false);
|
||||||
|
|
||||||
assertThat(mClockFrame.getAlpha()).isEqualTo(1);
|
assertThat(mSmallClockFrame.getAlpha()).isEqualTo(1);
|
||||||
assertThat(mClockFrame.getVisibility()).isEqualTo(VISIBLE);
|
assertThat(mSmallClockFrame.getVisibility()).isEqualTo(VISIBLE);
|
||||||
// only big clock is removed at switch
|
// only big clock is removed at switch
|
||||||
assertThat(mLargeClockFrame.getParent()).isNull();
|
assertThat(mLargeClockFrame.getParent()).isNull();
|
||||||
assertThat(mLargeClockFrame.getAlpha()).isEqualTo(0);
|
assertThat(mLargeClockFrame.getAlpha()).isEqualTo(0);
|
||||||
|
|||||||
@@ -129,13 +129,16 @@ class ClockRegistryTest : SysuiTestCase() {
|
|||||||
pluginListener.onPluginConnected(plugin1, mockContext)
|
pluginListener.onPluginConnected(plugin1, mockContext)
|
||||||
pluginListener.onPluginConnected(plugin2, mockContext)
|
pluginListener.onPluginConnected(plugin2, mockContext)
|
||||||
val list = registry.getClocks()
|
val list = registry.getClocks()
|
||||||
assertEquals(list, listOf(
|
assertEquals(
|
||||||
|
list,
|
||||||
|
listOf(
|
||||||
ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
|
ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
|
||||||
ClockMetadata("clock_1", "clock 1"),
|
ClockMetadata("clock_1", "clock 1"),
|
||||||
ClockMetadata("clock_2", "clock 2"),
|
ClockMetadata("clock_2", "clock 2"),
|
||||||
ClockMetadata("clock_3", "clock 3"),
|
ClockMetadata("clock_3", "clock 3"),
|
||||||
ClockMetadata("clock_4", "clock 4")
|
ClockMetadata("clock_4", "clock 4")
|
||||||
))
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -157,11 +160,14 @@ class ClockRegistryTest : SysuiTestCase() {
|
|||||||
pluginListener.onPluginConnected(plugin1, mockContext)
|
pluginListener.onPluginConnected(plugin1, mockContext)
|
||||||
pluginListener.onPluginConnected(plugin2, mockContext)
|
pluginListener.onPluginConnected(plugin2, mockContext)
|
||||||
val list = registry.getClocks()
|
val list = registry.getClocks()
|
||||||
assertEquals(list, listOf(
|
assertEquals(
|
||||||
|
list,
|
||||||
|
listOf(
|
||||||
ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
|
ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
|
||||||
ClockMetadata("clock_1", "clock 1"),
|
ClockMetadata("clock_1", "clock 1"),
|
||||||
ClockMetadata("clock_2", "clock 2")
|
ClockMetadata("clock_2", "clock 2")
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
assertEquals(registry.createExampleClock("clock_1"), mockClock)
|
assertEquals(registry.createExampleClock("clock_1"), mockClock)
|
||||||
assertEquals(registry.createExampleClock("clock_2"), mockClock)
|
assertEquals(registry.createExampleClock("clock_2"), mockClock)
|
||||||
@@ -221,7 +227,7 @@ class ClockRegistryTest : SysuiTestCase() {
|
|||||||
pluginListener.onPluginConnected(plugin2, mockContext)
|
pluginListener.onPluginConnected(plugin2, mockContext)
|
||||||
|
|
||||||
var changeCallCount = 0
|
var changeCallCount = 0
|
||||||
registry.registerClockChangeListener({ changeCallCount++ })
|
registry.registerClockChangeListener { changeCallCount++ }
|
||||||
|
|
||||||
pluginListener.onPluginDisconnected(plugin1)
|
pluginListener.onPluginDisconnected(plugin1)
|
||||||
assertEquals(0, changeCallCount)
|
assertEquals(0, changeCallCount)
|
||||||
|
|||||||
@@ -223,10 +223,9 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void disable_isDozingButNoCustomClock_clockAndSystemInfoVisible() {
|
public void disable_isDozing_clockAndSystemInfoVisible() {
|
||||||
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
|
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
|
||||||
when(mStatusBarStateController.isDozing()).thenReturn(true);
|
when(mStatusBarStateController.isDozing()).thenReturn(true);
|
||||||
when(mNotificationPanelViewController.hasCustomClock()).thenReturn(false);
|
|
||||||
|
|
||||||
fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
|
fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
|
||||||
|
|
||||||
@@ -235,10 +234,9 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void disable_customClockButNotDozing_clockAndSystemInfoVisible() {
|
public void disable_NotDozing_clockAndSystemInfoVisible() {
|
||||||
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
|
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
|
||||||
when(mStatusBarStateController.isDozing()).thenReturn(false);
|
when(mStatusBarStateController.isDozing()).thenReturn(false);
|
||||||
when(mNotificationPanelViewController.hasCustomClock()).thenReturn(true);
|
|
||||||
|
|
||||||
fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
|
fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
|
||||||
|
|
||||||
@@ -246,40 +244,6 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
|
|||||||
assertEquals(View.VISIBLE, getClockView().getVisibility());
|
assertEquals(View.VISIBLE, getClockView().getVisibility());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void disable_dozingAndCustomClock_clockAndSystemInfoHidden() {
|
|
||||||
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
|
|
||||||
when(mStatusBarStateController.isDozing()).thenReturn(true);
|
|
||||||
when(mNotificationPanelViewController.hasCustomClock()).thenReturn(true);
|
|
||||||
|
|
||||||
// Make sure they start out as visible
|
|
||||||
assertEquals(View.VISIBLE, getSystemIconAreaView().getVisibility());
|
|
||||||
assertEquals(View.VISIBLE, getClockView().getVisibility());
|
|
||||||
|
|
||||||
fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
|
|
||||||
|
|
||||||
assertEquals(View.INVISIBLE, getSystemIconAreaView().getVisibility());
|
|
||||||
assertEquals(View.GONE, getClockView().getVisibility());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onDozingChanged_clockAndSystemInfoVisibilitiesUpdated() {
|
|
||||||
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
|
|
||||||
when(mStatusBarStateController.isDozing()).thenReturn(true);
|
|
||||||
when(mNotificationPanelViewController.hasCustomClock()).thenReturn(true);
|
|
||||||
|
|
||||||
// Make sure they start out as visible
|
|
||||||
assertEquals(View.VISIBLE, getSystemIconAreaView().getVisibility());
|
|
||||||
assertEquals(View.VISIBLE, getClockView().getVisibility());
|
|
||||||
|
|
||||||
fragment.onDozingChanged(true);
|
|
||||||
|
|
||||||
// When this callback is triggered, we want to make sure the clock and system info
|
|
||||||
// visibilities are recalculated. Since dozing=true, they shouldn't be visible.
|
|
||||||
assertEquals(View.INVISIBLE, getSystemIconAreaView().getVisibility());
|
|
||||||
assertEquals(View.GONE, getClockView().getVisibility());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void disable_headsUpShouldBeVisibleTrue_clockDisabled() {
|
public void disable_headsUpShouldBeVisibleTrue_clockDisabled() {
|
||||||
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
|
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
|
||||||
|
|||||||
Reference in New Issue
Block a user