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

Commit 0a6dd79f authored by George Lin's avatar George Lin
Browse files

Fix smartspace missing on main screen preview (1/3)

1. Fix missing smartspace
2. Make the clock transition smoother

Test: Manually tested.
Bug: 415825642
Flag: com.android.systemui.shared.new_customization_picker_ui
Change-Id: I960e004c8afd50166a69c489b8df3b5176e5a132
parent 2378d9ae
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -36,4 +36,13 @@ object ViewUtils {

    val View.measuredSize: VPointF
        get() = VPointF(measuredWidth, measuredHeight)

    fun View.animateToAlpha(float: Float) {
        this.animate()
            .alpha(float)
            .setDuration(
                this.resources.getInteger(android.R.integer.config_mediumAnimTime).toLong()
            )
            .start()
    }
}
+48 −18
Original line number Diff line number Diff line
@@ -28,8 +28,8 @@ import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.customization.clocks.ViewUtils.animateToAlpha
import com.android.systemui.keyguard.shared.model.ClockSizeSetting
import com.android.systemui.keyguard.ui.view.layout.sections.setVisibility
import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewClockViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.clocks.ClockController
@@ -78,8 +78,13 @@ object KeyguardPreviewClockViewBinder {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                var lastClock: ClockController? = null
                launch("$TAG#viewModel.previewClock") {
                        combine(viewModel.previewClock, viewModel.previewClockSize, ::Pair)
                            .collect { (currentClock, clockSize) ->
                        combine(
                                viewModel.previewClock,
                                viewModel.previewClockSize,
                                viewModel.showClock,
                                ::Triple,
                            )
                            .collect { (currentClock, clockSize, showClock) ->
                                lastClock?.let { clock ->
                                    (clock.largeClock.layout.views + clock.smallClock.layout.views)
                                        .forEach { rootView.removeView(it) }
@@ -106,6 +111,7 @@ object KeyguardPreviewClockViewBinder {
                                    rootView,
                                    currentClock,
                                    clockSize,
                                    showClock,
                                )
                            }
                    }
@@ -121,42 +127,66 @@ object KeyguardPreviewClockViewBinder {
        }
    }

    // Track the current show clock flag. If it turns from false to true, animate fade-in.
    private var currentShowClock: Boolean? = null

    private fun applyPreviewConstraints(
        clockPreviewConfig: ClockPreviewConfig,
        rootView: ConstraintLayout,
        previewClock: ClockController,
        clockSize: ClockSizeSetting?,
        showClock: Boolean,
    ) {
        val cs = ConstraintSet().apply { clone(rootView) }
        val shouldFadeIn = (currentShowClock == false) && showClock

        val cs = ConstraintSet().apply { clone(rootView) }
        val configWithUpdatedLockId =
            if (rootView.getViewById(lockViewId) != null) {
                clockPreviewConfig.copy(lockViewId = lockViewId)
            } else {
                clockPreviewConfig
            }

        previewClock.largeClock.layout.applyPreviewConstraints(configWithUpdatedLockId, cs)
        previewClock.smallClock.layout.applyPreviewConstraints(configWithUpdatedLockId, cs)
        cs.applyTo(rootView)

        // When previewClockSize is the initial value, make both clocks invisible to avoid flicker
        val largeClockVisibility =
            if (showClock)
                when (clockSize) {
                    ClockSizeSetting.DYNAMIC -> VISIBLE
                    ClockSizeSetting.SMALL -> INVISIBLE
                    null -> INVISIBLE
                }
            else INVISIBLE
        val smallClockVisibility =
            if (showClock)
                when (clockSize) {
                    ClockSizeSetting.DYNAMIC -> INVISIBLE
                    ClockSizeSetting.SMALL -> VISIBLE
                    null -> INVISIBLE
                }
        cs.apply {
            setVisibility(previewClock.largeClock.layout.views, largeClockVisibility)
            setVisibility(previewClock.smallClock.layout.views, smallClockVisibility)
            else INVISIBLE
        setVisibility(previewClock.largeClock.layout.views, largeClockVisibility, shouldFadeIn)
        setVisibility(previewClock.smallClock.layout.views, smallClockVisibility, shouldFadeIn)
        if (shouldFadeIn) {
            if (largeClockVisibility == VISIBLE) {
                previewClock.largeClock.layout.views.forEach { it.animateToAlpha(1F) }
            }
            if (smallClockVisibility == VISIBLE) {
                previewClock.smallClock.layout.views.forEach { it.animateToAlpha(1F) }
            }
        }
        currentShowClock = showClock
    }

    private fun setVisibility(views: Iterable<View>, visibility: Int, shouldFadeIn: Boolean) {
        views.forEach { view ->
            if (shouldFadeIn && visibility == VISIBLE) {
                view.alpha = 0F
            }
            view.visibility = visibility
        }
        cs.applyTo(rootView)
    }

    private const val TAG = "KeyguardPreviewClockViewBinder"
+46 −10
Original line number Diff line number Diff line
@@ -22,14 +22,19 @@ import androidx.core.view.isInvisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.customization.clocks.ViewUtils.animateToAlpha
import com.android.systemui.keyguard.shared.model.ClockSizeSetting
import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewSmartspaceViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.clocks.ClockPreviewConfig
import kotlinx.coroutines.flow.combine

/** Binder for the small clock view, large clock view and smartspace. */
object KeyguardPreviewSmartspaceViewBinder {

    // Track the current show smartsapce flag. If it turns from false to true, animate fade-in.
    private var currentShowSmartspace: Boolean? = null

    @JvmStatic
    fun bind(parentView: View, viewModel: KeyguardPreviewSmartspaceViewModel) {
        if (com.android.systemui.shared.Flags.clockReactiveSmartspaceLayout()) {
@@ -42,18 +47,49 @@ object KeyguardPreviewSmartspaceViewBinder {
            parentView.repeatWhenAttached {
                repeatOnLifecycle(Lifecycle.State.STARTED) {
                    launch("$TAG#viewModel.previewClockSize") {
                        viewModel.previewClockSize.collect {
                            when (it) {
                                ClockSizeSetting.DYNAMIC -> {
                                    smallDateView?.visibility = View.GONE
                                    largeDateView?.visibility = View.VISIBLE
                        combine(viewModel.previewClockSize, viewModel.showSmartspace, ::Pair)
                            .collect { (clockSize, showSmartspace) ->
                                val shouldFadeIn =
                                    (currentShowSmartspace == false) && showSmartspace
                                val largeDateViewVisibility =
                                    if (showSmartspace) {
                                        when (clockSize) {
                                            ClockSizeSetting.DYNAMIC -> View.VISIBLE
                                            ClockSizeSetting.SMALL -> View.INVISIBLE
                                        }

                                ClockSizeSetting.SMALL -> {
                                    smallDateView?.visibility = View.VISIBLE
                                    largeDateView?.visibility = View.GONE
                                    } else {
                                        View.INVISIBLE
                                    }
                                val smallDateViewVisibility =
                                    if (showSmartspace) {
                                        when (clockSize) {
                                            ClockSizeSetting.DYNAMIC -> View.INVISIBLE
                                            ClockSizeSetting.SMALL -> View.VISIBLE
                                        }
                                    } else {
                                        View.INVISIBLE
                                    }
                                largeDateView?.let {
                                    if (shouldFadeIn && largeDateViewVisibility == View.VISIBLE) {
                                        it.alpha = 0F
                                    }
                                    it.visibility = largeDateViewVisibility
                                }
                                smallDateView?.let {
                                    if (shouldFadeIn && smallDateViewVisibility == View.VISIBLE) {
                                        it.alpha = 0F
                                    }
                                    it.visibility = smallDateViewVisibility
                                }
                                if (shouldFadeIn) {
                                    if (largeDateViewVisibility == View.VISIBLE) {
                                        largeDateView?.animateToAlpha(1F)
                                    }
                                    if (smallDateViewVisibility == View.VISIBLE) {
                                        smallDateView?.animateToAlpha(1F)
                                    }
                                }
                                currentShowSmartspace = showSmartspace
                            }
                    }
                }
+6 −2
Original line number Diff line number Diff line
@@ -272,7 +272,12 @@ constructor(
     * @param hide TRUE hides smartspace, FALSE shows smartspace
     */
    fun hideSmartspace(hide: Boolean) {
        mainHandler.post { smartSpaceView?.visibility = if (hide) View.INVISIBLE else View.VISIBLE }
        mainHandler.post {
            smartSpaceView?.visibility = if (hide) View.INVISIBLE else View.VISIBLE
            if (com.android.systemui.shared.Flags.clockReactiveSmartspaceLayout()) {
                clockViewModel.setShowClock(!hide)
            }
        }
    }

    /**
@@ -493,7 +498,6 @@ constructor(
    }

    private fun setUpClock(previewContext: Context, parentView: ViewGroup) {
        val resources = parentView.resources
        val receiver =
            object : BroadcastReceiver() {
                override fun onReceive(context: Context?, intent: Intent?) {
+26 −15
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map

@AssistedFactory
@@ -35,11 +37,20 @@ class KeyguardPreviewClockViewModel
@AssistedInject
constructor(
    @Assisted private val interactor: KeyguardPreviewInteractor,
    private val keyguardClockViewModel: KeyguardClockViewModel
    private val keyguardClockViewModel: KeyguardClockViewModel,
) {
    // The flag indicates if the clock should be hidden for the preview the whole time. In this case
    // the clock view will not even be created.
    val shouldHideClock: Boolean
        get() = interactor.shouldHideClock

    private val _showClock: MutableStateFlow<Boolean> = MutableStateFlow(!shouldHideClock)
    val showClock: Flow<Boolean> = _showClock.asStateFlow()

    fun setShowClock(show: Boolean) {
        _showClock.value = show
    }

    val shouldHighlightSelectedAffordance: Boolean
        get() = interactor.shouldHighlightSelectedAffordance

Loading