Merge "Migrate KeyguardClockSwitch to new shared Clock library" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
5f092e150a
@@ -485,7 +485,13 @@ class TextInterpolator(
|
|||||||
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(layout.text, lineStart, count, layout.textDirectionHeuristic,
|
TextShaper.shapeText(layout.text, lineStart, count, layout.textDirectionHeuristic,
|
||||||
paint) { _, _, glyphs, _ ->
|
paint) { _, _, glyphs, _ ->
|
||||||
|
|||||||
@@ -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="@string/dream_time_complication_12_hr_time_format"
|
android:format12Hour="@string/dream_time_complication_12_hr_time_format"
|
||||||
|
|||||||
@@ -664,13 +664,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) {
|
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
mClockFrame.addView(smallClockView, -1,
|
ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||||
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
mLargeClockFrame.addView(clock.getLargeClock());
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT));
|
|
||||||
mClockView.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
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) {
|
||||||
|
|||||||
@@ -290,11 +290,6 @@ public final 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.
|
||||||
@@ -1107,13 +1102,6 @@ public final 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;
|
||||||
@@ -3881,9 +3869,10 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
endAction.run();
|
endAction.run();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.setUpdateListener(anim -> {
|
||||||
|
mKeyguardStatusViewController.animateFoldToAod(anim.getAnimatedFraction());
|
||||||
|
})
|
||||||
.start();
|
.start();
|
||||||
|
|
||||||
mKeyguardStatusViewController.animateFoldToAod();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -4596,7 +4585,6 @@ public final 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();
|
||||||
}
|
}
|
||||||
@@ -4706,11 +4694,8 @@ public final 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(((float) mView.getWidth()) / 2f);
|
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;
|
||||||
|
|||||||
@@ -439,7 +439,6 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
|
|||||||
state |= DISABLE_CLOCK;
|
state |= DISABLE_CLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (mNetworkController != null && EncryptionHelper.IS_DATA_ENCRYPTED) {
|
if (mNetworkController != null && EncryptionHelper.IS_DATA_ENCRYPTED) {
|
||||||
if (mNetworkController.hasEmergencyCryptKeeperText()) {
|
if (mNetworkController.hasEmergencyCryptKeeperText()) {
|
||||||
state |= DISABLE_NOTIFICATION_ICONS;
|
state |= DISABLE_NOTIFICATION_ICONS;
|
||||||
@@ -449,13 +448,6 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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(
|
||||||
ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
|
list,
|
||||||
ClockMetadata("clock_1", "clock 1"),
|
listOf(
|
||||||
ClockMetadata("clock_2", "clock 2"),
|
ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
|
||||||
ClockMetadata("clock_3", "clock 3"),
|
ClockMetadata("clock_1", "clock 1"),
|
||||||
ClockMetadata("clock_4", "clock 4")
|
ClockMetadata("clock_2", "clock 2"),
|
||||||
))
|
ClockMetadata("clock_3", "clock 3"),
|
||||||
|
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(
|
||||||
ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
|
list,
|
||||||
ClockMetadata("clock_1", "clock 1"),
|
listOf(
|
||||||
ClockMetadata("clock_2", "clock 2")
|
ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
|
||||||
))
|
ClockMetadata("clock_1", "clock 1"),
|
||||||
|
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)
|
||||||
|
|||||||
@@ -230,10 +230,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);
|
||||||
|
|
||||||
@@ -242,10 +241,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);
|
||||||
|
|
||||||
@@ -253,40 +251,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, getEndSideContentView().getVisibility());
|
|
||||||
assertEquals(View.VISIBLE, getClockView().getVisibility());
|
|
||||||
|
|
||||||
fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
|
|
||||||
|
|
||||||
assertEquals(View.INVISIBLE, getEndSideContentView().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, getEndSideContentView().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, getEndSideContentView().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