Merge "Additional clock interface method for region target and font sizes" into tm-qpr-dev

This commit is contained in:
Hawkwood Glazier
2022-11-15 15:57:18 +00:00
committed by Android (Google) Code Review
9 changed files with 126 additions and 50 deletions

View File

@@ -16,7 +16,6 @@
-packages/SystemUI/checks/tests/com/android/systemui/lint/RegisterReceiverViaContextDetectorTest.kt
-packages/SystemUI/checks/tests/com/android/systemui/lint/SoftwareBitmapDetectorTest.kt
-packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
-packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
-packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSContainerController.kt
-packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt
-packages/SystemUI/shared/src/com/android/systemui/flags/FlagListenable.kt

View File

@@ -70,10 +70,10 @@ interface ClockController {
}
/** Optional method for dumping debug information */
fun dump(pw: PrintWriter) { }
fun dump(pw: PrintWriter) {}
/** Optional method for debug logging */
fun setLogBuffer(logBuffer: LogBuffer) { }
fun setLogBuffer(logBuffer: LogBuffer) {}
}
/** Interface for a specific clock face version rendered by the clock */
@@ -88,40 +88,37 @@ interface ClockFaceController {
/** Events that should call when various rendering parameters change */
interface ClockEvents {
/** Call every time tick */
fun onTimeTick() { }
fun onTimeTick() {}
/** Call whenever timezone changes */
fun onTimeZoneChanged(timeZone: TimeZone) { }
fun onTimeZoneChanged(timeZone: TimeZone) {}
/** Call whenever the text time format changes (12hr vs 24hr) */
fun onTimeFormatChanged(is24Hr: Boolean) { }
fun onTimeFormatChanged(is24Hr: Boolean) {}
/** Call whenever the locale changes */
fun onLocaleChanged(locale: Locale) { }
/** Call whenever font settings change */
fun onFontSettingChanged() { }
fun onLocaleChanged(locale: Locale) {}
/** Call whenever the color palette should update */
fun onColorPaletteChanged(resources: Resources) { }
fun onColorPaletteChanged(resources: Resources) {}
}
/** Methods which trigger various clock animations */
interface ClockAnimations {
/** Runs an enter animation (if any) */
fun enter() { }
fun enter() {}
/** Sets how far into AOD the device currently is. */
fun doze(fraction: Float) { }
fun doze(fraction: Float) {}
/** Sets how far into the folding animation the device is. */
fun fold(fraction: Float) { }
fun fold(fraction: Float) {}
/** Runs the battery animation (if any). */
fun charge() { }
fun charge() {}
/** Move the clock, for example, if the notification tray appears in split-shade mode. */
fun onPositionUpdated(fromRect: Rect, toRect: Rect, fraction: Float) { }
fun onPositionUpdated(fromRect: Rect, toRect: Rect, fraction: Float) {}
/**
* Whether this clock has a custom position update animation. If true, the keyguard will call
@@ -135,11 +132,26 @@ interface ClockAnimations {
/** Events that have specific data about the related face */
interface ClockFaceEvents {
/** Region Darkness specific to the clock face */
fun onRegionDarknessChanged(isDark: Boolean) { }
fun onRegionDarknessChanged(isDark: Boolean) {}
/**
* Call whenever font settings change. Pass in a target font size in pixels. The specific clock
* design is allowed to ignore this target size on a case-by-case basis.
*/
fun onFontSettingChanged(fontSizePx: Float) {}
/**
* Target region information for the clock face. For small clock, this will match the bounds of
* the parent view mostly, but have a target height based on the height of the default clock.
* For large clocks, the parent view is the entire device size, but most clocks will want to
* render within the centered targetRect to avoid obstructing other elements. The specified
* targetRegion is relative to the parent view.
*/
fun onTargetRegionChanged(targetRegion: Rect?) {}
}
/** Some data about a clock design */
data class ClockMetadata(
val clockId: ClockId,
val name: String
val name: String,
)

View File

@@ -37,7 +37,6 @@
android:id="@+id/lockscreen_clock_view_large"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/keyguard_large_clock_top_margin"
android:clipChildren="false"
android:visibility="gone" />

View File

@@ -20,6 +20,7 @@ import android.graphics.Rect
import android.icu.text.NumberFormat
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.widget.FrameLayout
import androidx.annotation.VisibleForTesting
import com.android.systemui.plugins.ClockAnimations
@@ -80,7 +81,7 @@ class DefaultClockController(
}
override fun initialize(resources: Resources, dozeFraction: Float, foldFraction: Float) {
largeClock.recomputePadding()
largeClock.recomputePadding(null)
animations = DefaultClockAnimations(dozeFraction, foldFraction)
events.onColorPaletteChanged(resources)
events.onTimeZoneChanged(TimeZone.getDefault())
@@ -101,6 +102,7 @@ class DefaultClockController(
// MAGENTA is a placeholder, and will be assigned correctly in initialize
private var currentColor = Color.MAGENTA
private var isRegionDark = false
protected var targetRegion: Rect? = null
init {
view.setColors(currentColor, currentColor)
@@ -112,8 +114,20 @@ class DefaultClockController(
this@DefaultClockFaceController.isRegionDark = isRegionDark
updateColor()
}
override fun onTargetRegionChanged(targetRegion: Rect?) {
this@DefaultClockFaceController.targetRegion = targetRegion
recomputePadding(targetRegion)
}
override fun onFontSettingChanged(fontSizePx: Float) {
view.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSizePx)
recomputePadding(targetRegion)
}
}
open fun recomputePadding(targetRegion: Rect?) {}
fun updateColor() {
val color =
if (isRegionDark) {
@@ -135,9 +149,16 @@ class DefaultClockController(
inner class LargeClockFaceController(
view: AnimatableClockView,
) : DefaultClockFaceController(view) {
fun recomputePadding() {
override fun recomputePadding(targetRegion: Rect?) {
// We center the view within the targetRegion instead of within the parent
// view by computing the difference and adding that to the padding.
val parent = view.parent
val yDiff =
if (targetRegion != null && parent is View && parent.isLaidOut())
targetRegion.centerY() - parent.height / 2f
else 0f
val lp = view.getLayoutParams() as FrameLayout.LayoutParams
lp.topMargin = (-0.5f * view.bottom).toInt()
lp.topMargin = (-0.5f * view.bottom + yDiff).toInt()
view.setLayoutParams(lp)
}
@@ -155,18 +176,6 @@ class DefaultClockController(
override fun onTimeZoneChanged(timeZone: TimeZone) =
clocks.forEach { it.onTimeZoneChanged(timeZone) }
override fun onFontSettingChanged() {
smallClock.view.setTextSize(
TypedValue.COMPLEX_UNIT_PX,
resources.getDimensionPixelSize(R.dimen.small_clock_text_size).toFloat()
)
largeClock.view.setTextSize(
TypedValue.COMPLEX_UNIT_PX,
resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat()
)
largeClock.recomputePadding()
}
override fun onColorPaletteChanged(resources: Resources) {
largeClock.updateColor()
smallClock.updateColor()

View File

@@ -26,6 +26,7 @@ import android.view.View
import androidx.annotation.VisibleForTesting
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.R
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -43,6 +44,11 @@ import com.android.systemui.shared.regionsampling.RegionSampler
import com.android.systemui.statusbar.policy.BatteryController
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback
import com.android.systemui.statusbar.policy.ConfigurationController
import java.io.PrintWriter
import java.util.Locale
import java.util.TimeZone
import java.util.concurrent.Executor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.Job
@@ -50,11 +56,6 @@ import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.launch
import java.io.PrintWriter
import java.util.Locale
import java.util.TimeZone
import java.util.concurrent.Executor
import javax.inject.Inject
/**
* Controller for a Clock provided by the registry and used on the keyguard. Instantiated by
@@ -84,6 +85,7 @@ open class ClockEventController @Inject constructor(
value.initialize(resources, dozeAmount, 0f)
updateRegionSamplers(value)
updateFontSizes()
}
}
@@ -150,7 +152,7 @@ open class ClockEventController @Inject constructor(
mainExecutor,
bgExecutor,
regionSamplingEnabled,
updateFun = { updateColors() } )
updateColors)
}
var smallRegionSampler: RegionSampler? = null
@@ -166,7 +168,7 @@ open class ClockEventController @Inject constructor(
}
override fun onDensityOrFontScaleChanged() {
clock?.events?.onFontSettingChanged()
updateFontSizes()
}
}
@@ -251,6 +253,13 @@ open class ClockEventController @Inject constructor(
largeRegionSampler?.stopRegionSampler()
}
private fun updateFontSizes() {
clock?.smallClock?.events?.onFontSettingChanged(
resources.getDimensionPixelSize(R.dimen.small_clock_text_size).toFloat())
clock?.largeClock?.events?.onFontSettingChanged(
resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat())
}
/**
* Dump information for debugging
*/

View File

@@ -5,6 +5,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
@@ -22,6 +23,7 @@ import com.android.systemui.plugins.ClockController;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Switch to show plugin clock when plugin is connected, otherwise it will show default clock.
*/
@@ -46,6 +48,7 @@ public class KeyguardClockSwitch extends RelativeLayout {
*/
private FrameLayout mSmallClockFrame;
private FrameLayout mLargeClockFrame;
private ClockController mClock;
private View mStatusArea;
private int mSmartspaceTopOffset;
@@ -95,6 +98,8 @@ public class KeyguardClockSwitch extends RelativeLayout {
}
void setClock(ClockController clock, int statusBarState) {
mClock = clock;
// Disconnect from existing plugin.
mSmallClockFrame.removeAllViews();
mLargeClockFrame.removeAllViews();
@@ -108,6 +113,35 @@ public class KeyguardClockSwitch extends RelativeLayout {
Log.i(TAG, "Attached new clock views to switch");
mSmallClockFrame.addView(clock.getSmallClock().getView());
mLargeClockFrame.addView(clock.getLargeClock().getView());
updateClockTargetRegions();
}
void updateClockTargetRegions() {
if (mClock != null) {
if (mSmallClockFrame.isLaidOut()) {
int targetHeight = getResources()
.getDimensionPixelSize(R.dimen.small_clock_text_size);
mClock.getSmallClock().getEvents().onTargetRegionChanged(new Rect(
mSmallClockFrame.getLeft(),
mSmallClockFrame.getTop(),
mSmallClockFrame.getRight(),
mSmallClockFrame.getTop() + targetHeight));
}
if (mLargeClockFrame.isLaidOut()) {
int largeClockTopMargin = getResources()
.getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin);
int targetHeight = getResources()
.getDimensionPixelSize(R.dimen.large_clock_text_size) * 2;
int top = mLargeClockFrame.getHeight() / 2 - targetHeight / 2
+ largeClockTopMargin / 2;
mClock.getLargeClock().getEvents().onTargetRegionChanged(new Rect(
mLargeClockFrame.getLeft(),
top,
mLargeClockFrame.getRight(),
top + targetHeight));
}
}
}
private void updateClockViews(boolean useLargeClock, boolean animate) {
@@ -214,6 +248,10 @@ public class KeyguardClockSwitch extends RelativeLayout {
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (changed) {
post(() -> updateClockTargetRegions());
}
if (mDisplayedClockSize != null && !mChildrenAreLaidOut) {
post(() -> updateClockViews(mDisplayedClockSize == LARGE, mAnimateOnLayout));
}

View File

@@ -77,7 +77,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
@KeyguardClockSwitch.ClockSize
private int mCurrentClockSize = SMALL;
private int mKeyguardClockTopMargin = 0;
private int mKeyguardSmallClockTopMargin = 0;
private final ClockRegistry.ClockChangeListener mClockChangedListener;
private ViewGroup mStatusArea;
@@ -162,7 +162,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
mClockRegistry.registerClockChangeListener(mClockChangedListener);
setClock(mClockRegistry.createCurrentClock());
mClockEventController.registerListeners(mView);
mKeyguardClockTopMargin =
mKeyguardSmallClockTopMargin =
mView.getResources().getDimensionPixelSize(R.dimen.keyguard_clock_top_margin);
if (mOnlyClock) {
@@ -244,10 +244,12 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
*/
public void onDensityOrFontScaleChanged() {
mView.onDensityOrFontScaleChanged();
mKeyguardClockTopMargin =
mKeyguardSmallClockTopMargin =
mView.getResources().getDimensionPixelSize(R.dimen.keyguard_clock_top_margin);
mView.updateClockTargetRegions();
}
/**
* Set which clock should be displayed on the keyguard. The other one will be automatically
* hidden.
@@ -327,7 +329,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
return frameHeight / 2 + clockHeight / 2;
} else {
int clockHeight = clock.getSmallClock().getView().getHeight();
return clockHeight + statusBarHeaderHeight + mKeyguardClockTopMargin;
return clockHeight + statusBarHeaderHeight + mKeyguardSmallClockTopMargin;
}
}

View File

@@ -155,7 +155,8 @@ class ClockEventControllerTest : SysuiTestCase() {
verify(configurationController).addCallback(capture(captor))
captor.value.onDensityOrFontScaleChanged()
verify(events).onFontSettingChanged()
verify(smallClockEvents, times(2)).onFontSettingChanged(anyFloat())
verify(largeClockEvents, times(2)).onFontSettingChanged(anyFloat())
}
@Test

View File

@@ -139,12 +139,19 @@ class DefaultClockProviderTest : SysuiTestCase() {
}
@Test
fun defaultClock_events_onFontSettingChanged() {
fun defaultSmallClock_events_onFontSettingChanged() {
val clock = provider.createClock(DEFAULT_CLOCK_ID)
clock.events.onFontSettingChanged()
clock.smallClock.events.onFontSettingChanged(100f)
verify(mockSmallClockView).setTextSize(eq(TypedValue.COMPLEX_UNIT_PX), anyFloat())
verify(mockLargeClockView).setTextSize(eq(TypedValue.COMPLEX_UNIT_PX), anyFloat())
verify(mockSmallClockView).setTextSize(eq(TypedValue.COMPLEX_UNIT_PX), eq(100f))
}
@Test
fun defaultLargeClock_events_onFontSettingChanged() {
val clock = provider.createClock(DEFAULT_CLOCK_ID)
clock.largeClock.events.onFontSettingChanged(200f)
verify(mockLargeClockView).setTextSize(eq(TypedValue.COMPLEX_UNIT_PX), eq(200f))
verify(mockLargeClockView).setLayoutParams(any())
}