Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9a391b41 authored by Brad Hinegardner's avatar Brad Hinegardner
Browse files

Replace default clock with FlexClockView

Hook DefaultClockProvider up to FlexClockView.

Turning the flag on and having the default clock selected now utilizes
the FlexClockView

Fixes: 372479433
Test: manual - enable flag and observe that the default clock uses FlexClockView
Flag: com.android.systemui.clock_reactive_variants
Change-Id: I170519260d998476ef9380b18a8ef11e0ba0e1eb
parent db6e75f5
Loading
Loading
Loading
Loading
+203 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.shared.clocks

import android.content.Context
import android.content.res.Resources
import android.graphics.Rect
import androidx.annotation.VisibleForTesting
import com.android.systemui.log.core.Logger
import com.android.systemui.log.core.MessageBuffer
import com.android.systemui.plugins.clocks.AlarmData
import com.android.systemui.plugins.clocks.ClockAnimations
import com.android.systemui.plugins.clocks.ClockEvents
import com.android.systemui.plugins.clocks.ClockFaceConfig
import com.android.systemui.plugins.clocks.ClockFaceEvents
import com.android.systemui.plugins.clocks.ClockReactiveSetting
import com.android.systemui.plugins.clocks.WeatherData
import com.android.systemui.plugins.clocks.ZenData
import com.android.systemui.shared.clocks.view.DigitalClockFaceView
import com.android.systemui.shared.clocks.view.FlexClockView
import java.util.Locale
import java.util.TimeZone

class ComposedDigitalLayerController(
    private val ctx: Context,
    private val assets: AssetLoader,
    private val layer: ComposedDigitalHandLayer,
    private val isLargeClock: Boolean,
    messageBuffer: MessageBuffer,
) : SimpleClockLayerController {
    private val logger = Logger(messageBuffer, ComposedDigitalLayerController::class.simpleName!!)

    val layerControllers = mutableListOf<SimpleClockLayerController>()
    val dozeState = DefaultClockController.AnimationState(1F)
    var isRegionDark = true

    override var view: DigitalClockFaceView =
        when (layer.customizedView) {
            "FlexClockView" -> FlexClockView(ctx, assets, messageBuffer)
            else -> {
                throw IllegalStateException("CustomizedView string is not valid")
            }
        }

    // Matches LayerControllerConstructor
    internal constructor(
        ctx: Context,
        assets: AssetLoader,
        layer: ClockLayer,
        isLargeClock: Boolean,
        messageBuffer: MessageBuffer,
    ) : this(ctx, assets, layer as ComposedDigitalHandLayer, isLargeClock, messageBuffer)

    init {
        layer.digitalLayers.forEach {
            val controller =
                SimpleClockLayerController.Factory.create(
                    ctx,
                    assets,
                    it,
                    isLargeClock,
                    messageBuffer,
                )
            view.addView(controller.view)
            layerControllers.add(controller)
        }
    }

    private fun refreshTime() {
        layerControllers.forEach { it.faceEvents.onTimeTick() }
        view.refreshTime()
    }

    override val events =
        object : ClockEvents {
            override fun onTimeZoneChanged(timeZone: TimeZone) {
                layerControllers.forEach { it.events.onTimeZoneChanged(timeZone) }
                refreshTime()
            }

            override fun onTimeFormatChanged(is24Hr: Boolean) {
                layerControllers.forEach { it.events.onTimeFormatChanged(is24Hr) }
                refreshTime()
            }

            override fun onLocaleChanged(locale: Locale) {
                layerControllers.forEach { it.events.onLocaleChanged(locale) }
                view.onLocaleChanged(locale)
                refreshTime()
            }

            override fun onWeatherDataChanged(data: WeatherData) {
                view.onWeatherDataChanged(data)
            }

            override fun onAlarmDataChanged(data: AlarmData) {
                view.onAlarmDataChanged(data)
            }

            override fun onZenDataChanged(data: ZenData) {
                view.onZenDataChanged(data)
            }

            override fun onColorPaletteChanged(resources: Resources) {}

            override fun onSeedColorChanged(seedColor: Int?) {}

            override fun onReactiveAxesChanged(axes: List<ClockReactiveSetting>) {}

            override var isReactiveTouchInteractionEnabled
                get() = view.isReactiveTouchInteractionEnabled
                set(value) {
                    view.isReactiveTouchInteractionEnabled = value
                }
        }

    override fun updateColors() {
        view.updateColors(assets, isRegionDark)
    }

    override val animations =
        object : ClockAnimations {
            override fun enter() {
                refreshTime()
            }

            override fun doze(fraction: Float) {
                val (hasChanged, hasJumped) = dozeState.update(fraction)
                if (hasChanged) view.animateDoze(dozeState.isActive, !hasJumped)
                view.dozeFraction = fraction
                view.invalidate()
            }

            override fun fold(fraction: Float) {
                refreshTime()
            }

            override fun charge() {
                view.animateCharge()
            }

            override fun onPositionUpdated(fromLeft: Int, direction: Int, fraction: Float) {
                view.onPositionUpdated(fromLeft, direction, fraction)
            }

            override fun onPositionUpdated(distance: Float, fraction: Float) {}

            override fun onPickerCarouselSwiping(swipingFraction: Float) {
                view.onPickerCarouselSwiping(swipingFraction)
            }
        }

    override val faceEvents =
        object : ClockFaceEvents {
            override fun onTimeTick() {
                refreshTime()
            }

            override fun onRegionDarknessChanged(isRegionDark: Boolean) {
                this@ComposedDigitalLayerController.isRegionDark = isRegionDark
                updateColors()
            }

            override fun onFontSettingChanged(fontSizePx: Float) {
                view.onFontSettingChanged(fontSizePx)
            }

            override fun onTargetRegionChanged(targetRegion: Rect?) {}

            override fun onSecondaryDisplayChanged(onSecondaryDisplay: Boolean) {}
        }

    override val config =
        ClockFaceConfig(
            hasCustomWeatherDataDisplay = view.hasCustomWeatherDataDisplay,
            hasCustomPositionUpdatedAnimation = view.hasCustomPositionUpdatedAnimation,
            useCustomClockScene = view.useCustomClockScene,
        )

    @VisibleForTesting
    override var fakeTimeMills: Long? = null
        get() = field
        set(timeInMills) {
            field = timeInMills
            for (layerController in layerControllers) {
                layerController.fakeTimeMills = timeInMills
            }
        }
}
+181 −11
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@ import com.android.systemui.plugins.clocks.ClockMetadata
import com.android.systemui.plugins.clocks.ClockPickerConfig
import com.android.systemui.plugins.clocks.ClockProvider
import com.android.systemui.plugins.clocks.ClockSettings
import com.android.systemui.shared.clocks.view.HorizontalAlignment
import com.android.systemui.shared.clocks.view.VerticalAlignment

private val TAG = DefaultClockProvider::class.simpleName
const val DEFAULT_CLOCK_ID = "DEFAULT"
@@ -33,8 +35,9 @@ class DefaultClockProvider(
    val ctx: Context,
    val layoutInflater: LayoutInflater,
    val resources: Resources,
    val hasStepClockAnimation: Boolean = false,
    val migratedClocks: Boolean = false,
    private val hasStepClockAnimation: Boolean = false,
    private val migratedClocks: Boolean = false,
    private val clockReactiveVariants: Boolean = false,
) : ClockProvider {
    private var messageBuffers: ClockMessageBuffers? = null

@@ -49,7 +52,14 @@ class DefaultClockProvider(
            throw IllegalArgumentException("${settings.clockId} is unsupported by $TAG")
        }

        return DefaultClockController(
        return if (clockReactiveVariants) {
            // TODO handle the case here where only the smallClock message buffer is added
            val assetLoader =
                AssetLoader(ctx, ctx, "clocks/", messageBuffers?.smallClockMessageBuffer!!)

            SimpleClockController(ctx, assetLoader, FLEX_DESIGN, messageBuffers)
        } else {
            DefaultClockController(
                ctx,
                layoutInflater,
                resources,
@@ -59,6 +69,7 @@ class DefaultClockProvider(
                messageBuffers,
            )
        }
    }

    override fun getClockPickerConfig(id: ClockId): ClockPickerConfig {
        if (id != DEFAULT_CLOCK_ID) {
@@ -73,4 +84,163 @@ class DefaultClockProvider(
            resources.getDrawable(R.drawable.clock_default_thumbnail, null),
        )
    }

    companion object {
        val FLEX_DESIGN = run {
            val largeLayer =
                listOf(
                    ComposedDigitalHandLayer(
                        layerBounds = LayerBounds.FIT,
                        customizedView = "FlexClockView",
                        digitalLayers =
                            listOf(
                                DigitalHandLayer(
                                    layerBounds = LayerBounds.FIT,
                                    timespec = DigitalTimespec.FIRST_DIGIT,
                                    style =
                                        FontTextStyle(
                                            fontFamily = "google_sans_flex.ttf",
                                            lineHeight = 147.25f,
                                            fontVariation =
                                                "'wght' 603, 'wdth' 100, 'opsz' 144, 'ROND' 100",
                                        ),
                                    aodStyle =
                                        FontTextStyle(
                                            fontVariation =
                                                "'wght' 74, 'wdth' 43, 'opsz' 144, 'ROND' 100",
                                            fontFamily = "google_sans_flex.ttf",
                                            fillColorLight = "#FFFFFFFF",
                                            outlineColor = "#00000000",
                                            renderType = RenderType.CHANGE_WEIGHT,
                                            transitionInterpolator = InterpolatorEnum.EMPHASIZED,
                                            transitionDuration = 750,
                                        ),
                                    alignment =
                                        DigitalAlignment(
                                            HorizontalAlignment.CENTER,
                                            VerticalAlignment.CENTER
                                        ),
                                    dateTimeFormat = "hh"
                                ),
                                DigitalHandLayer(
                                    layerBounds = LayerBounds.FIT,
                                    timespec = DigitalTimespec.SECOND_DIGIT,
                                    style =
                                        FontTextStyle(
                                            fontFamily = "google_sans_flex.ttf",
                                            lineHeight = 147.25f,
                                            fontVariation =
                                                "'wght' 603, 'wdth' 100, 'opsz' 144, 'ROND' 100",
                                        ),
                                    aodStyle =
                                        FontTextStyle(
                                            fontVariation =
                                                "'wght' 74, 'wdth' 43, 'opsz' 144, 'ROND' 100",
                                            fontFamily = "google_sans_flex.ttf",
                                            fillColorLight = "#FFFFFFFF",
                                            outlineColor = "#00000000",
                                            renderType = RenderType.CHANGE_WEIGHT,
                                            transitionInterpolator = InterpolatorEnum.EMPHASIZED,
                                            transitionDuration = 750,
                                        ),
                                    alignment =
                                        DigitalAlignment(
                                            HorizontalAlignment.CENTER,
                                            VerticalAlignment.CENTER
                                        ),
                                    dateTimeFormat = "hh"
                                ),
                                DigitalHandLayer(
                                    layerBounds = LayerBounds.FIT,
                                    timespec = DigitalTimespec.FIRST_DIGIT,
                                    style =
                                        FontTextStyle(
                                            fontFamily = "google_sans_flex.ttf",
                                            lineHeight = 147.25f,
                                            fontVariation =
                                                "'wght' 603, 'wdth' 100, 'opsz' 144, 'ROND' 100",
                                        ),
                                    aodStyle =
                                        FontTextStyle(
                                            fontVariation =
                                                "'wght' 74, 'wdth' 43, 'opsz' 144, 'ROND' 100",
                                            fontFamily = "google_sans_flex.ttf",
                                            fillColorLight = "#FFFFFFFF",
                                            outlineColor = "#00000000",
                                            renderType = RenderType.CHANGE_WEIGHT,
                                            transitionInterpolator = InterpolatorEnum.EMPHASIZED,
                                            transitionDuration = 750,
                                        ),
                                    alignment =
                                        DigitalAlignment(
                                            HorizontalAlignment.CENTER,
                                            VerticalAlignment.CENTER
                                        ),
                                    dateTimeFormat = "mm"
                                ),
                                DigitalHandLayer(
                                    layerBounds = LayerBounds.FIT,
                                    timespec = DigitalTimespec.SECOND_DIGIT,
                                    style =
                                        FontTextStyle(
                                            fontFamily = "google_sans_flex.ttf",
                                            lineHeight = 147.25f,
                                            fontVariation =
                                                "'wght' 603, 'wdth' 100, 'opsz' 144, 'ROND' 100",
                                        ),
                                    aodStyle =
                                        FontTextStyle(
                                            fontVariation =
                                                "'wght' 74, 'wdth' 43, 'opsz' 144, 'ROND' 100",
                                            fontFamily = "google_sans_flex.ttf",
                                            fillColorLight = "#FFFFFFFF",
                                            outlineColor = "#00000000",
                                            renderType = RenderType.CHANGE_WEIGHT,
                                            transitionInterpolator = InterpolatorEnum.EMPHASIZED,
                                            transitionDuration = 750,
                                        ),
                                    alignment =
                                        DigitalAlignment(
                                            HorizontalAlignment.CENTER,
                                            VerticalAlignment.CENTER
                                        ),
                                    dateTimeFormat = "mm"
                                )
                            )
                    )
                )

            val smallLayer =
                listOf(
                    DigitalHandLayer(
                        layerBounds = LayerBounds.FIT,
                        timespec = DigitalTimespec.TIME_FULL_FORMAT,
                        style =
                            FontTextStyle(
                                fontFamily = "google_sans_flex.ttf",
                                fontVariation = "'wght' 600, 'wdth' 100, 'opsz' 144, 'ROND' 100",
                                fontSizeScale = 0.98f,
                            ),
                        aodStyle =
                            FontTextStyle(
                                fontFamily = "google_sans_flex.ttf",
                                fontVariation = "'wght' 133, 'wdth' 43, 'opsz' 144, 'ROND' 100",
                                fillColorLight = "#FFFFFFFF",
                                outlineColor = "#00000000",
                                renderType = RenderType.CHANGE_WEIGHT,
                            ),
                        alignment = DigitalAlignment(HorizontalAlignment.LEFT, null),
                        dateTimeFormat = "h:mm"
                    )
                )

            ClockDesign(
                id = DEFAULT_CLOCK_ID,
                name = "@string/clock_default_name",
                description = "@string/clock_default_description",
                large = ClockFace(layers = largeLayer),
                small = ClockFace(layers = smallLayer)
            )
        }
    }
}
+35 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.shared.clocks

import android.graphics.Rect
import android.view.View

fun computeLayoutDiff(
    view: View,
    targetRegion: Rect,
    isLargeClock: Boolean,
): Pair<Float, Float> {
    val parent = view.parent
    if (parent is View && parent.isLaidOut() && isLargeClock) {
        return Pair(
            targetRegion.centerX() - parent.width / 2f,
            targetRegion.centerY() - parent.height / 2f
        )
    }
    return Pair(0f, 0f)
}
+152 −0

File added.

Preview size limit exceeded, changes collapsed.

+314 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading