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

Commit b92581b3 authored by Johannes Gallmann's avatar Johannes Gallmann
Browse files

[Floaty] HapticPlayer#start coroutine improvements

Bug: 412325043
Flag: com.android.systemui.shared.enable_lpp_assist_invocation_haptic_effect
Test: TopLevelWindowEffectsTest
Change-Id: Ie33aa8eaa5568d9ee19efdfdc016e2e478c0de08
parent 2e27b9f5
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -97,9 +97,11 @@ constructor(
    private suspend fun startSqueeze() {
        delay(squeezeEffectInteractor.getInvocationEffectInitialDelayMs())
        setRequestTopUi(true)
        val inwardsAnimationDuration =
            squeezeEffectInteractor.getInvocationEffectInwardsAnimationDurationMs()
        animateSqueezeProgressTo(
            targetProgress = 1f,
            duration = squeezeEffectInteractor.getInvocationEffectInwardsAnimationDurationMs(),
            duration = inwardsAnimationDuration,
            interpolator = InterpolatorsAndroidX.LEGACY,
        ) {
            animateSqueezeProgressTo(
@@ -110,7 +112,7 @@ constructor(
                finishAnimation()
            }
        }
        hapticPlayer?.start()
        hapticPlayer?.start(inwardsAnimationDuration.toInt() + DEFAULT_OUTWARD_EFFECT_DURATION)
        keyEventInteractor.isPowerButtonLongPressed.collectLatest { isLongPressed ->
            if (isLongPressed) {
                isAnimationInterruptible = false
+23 −27
Original line number Diff line number Diff line
@@ -17,24 +17,21 @@
package com.android.systemui.topwindoweffects.ui.viewmodel

import android.os.VibrationEffect
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.topwindoweffects.data.repository.SqueezeEffectRepositoryImpl.Companion.DEFAULT_OUTWARD_EFFECT_DURATION
import com.android.systemui.topwindoweffects.domain.interactor.SqueezeEffectInteractor
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch

class SqueezeEffectHapticPlayer
@AssistedInject
constructor(
    private val vibratorHelper: VibratorHelper,
    @Background private val bgScope: CoroutineScope,
    private val squeezeEffectInteractor: SqueezeEffectInteractor,
    @Application private val applicationScope: CoroutineScope,
) {

    private val primitiveDurations =
@@ -44,43 +41,42 @@ constructor(
            VibrationEffect.Composition.PRIMITIVE_TICK,
        )

    private suspend fun buildInvocationHaptics() =
    private fun buildInvocationHaptics(totalDurationMillis: Int) =
        SqueezeEffectHapticsBuilder.createInvocationHaptics(
            lowTickDuration = primitiveDurations[0],
            quickRiseDuration = primitiveDurations[1],
            tickDuration = primitiveDurations[2],
            totalEffectDuration = calculateHapticsEffectTotalDuration(),
            totalEffectDuration = totalDurationMillis,
        )

    private suspend fun calculateHapticsEffectTotalDuration(): Int {
        return bgScope
            .async { squeezeEffectInteractor.getInvocationEffectInwardsAnimationDurationMs() }
            .await()
            .toInt() + DEFAULT_OUTWARD_EFFECT_DURATION
    }

    private var vibrationJob: Job? = null

    fun start() {
    fun start(totalDurationMillis: Int) {
        cancel()
        val invocationHaptics = buildInvocationHaptics(totalDurationMillis)
        if (invocationHaptics.initialDelay <= 0) {
            vibrate(invocationHaptics.vibration)
        } else {
            vibrationJob =
            bgScope.launch {
                val invocationHaptics = buildInvocationHaptics()
                applicationScope.launch {
                    delay(invocationHaptics.initialDelay.toLong())
                vibratorHelper.vibrate(
                    invocationHaptics.vibration,
                    SqueezeEffectHapticsBuilder.VIBRATION_ATTRIBUTES,
                )
                    if (isActive) {
                        vibrate(invocationHaptics.vibration)
                    }
                    vibrationJob = null
                }
        }
    }

    fun cancel() {
        vibratorHelper.cancel()
        vibrationJob?.cancel()
        vibrationJob = null
        vibratorHelper.cancel()
    }

    private fun vibrate(vibrationEffect: VibrationEffect) =
        vibratorHelper.vibrate(vibrationEffect, SqueezeEffectHapticsBuilder.VIBRATION_ATTRIBUTES)

    @AssistedFactory
    interface Factory {
        fun create(): SqueezeEffectHapticPlayer
+1 −11
Original line number Diff line number Diff line
@@ -17,12 +17,8 @@
package com.android.systemui.topwindoweffects.ui.viewmodel

import com.android.systemui.haptics.vibratorHelper
import com.android.systemui.keyevent.data.repository.fakeKeyEventRepository
import com.android.systemui.keyevent.domain.interactor.KeyEventInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.topwindoweffects.data.repository.fakeSqueezeEffectRepository
import com.android.systemui.topwindoweffects.domain.interactor.SqueezeEffectInteractor

val Kosmos.squeezeEffectHapticPlayerFactory by
    Kosmos.Fixture {
@@ -30,13 +26,7 @@ val Kosmos.squeezeEffectHapticPlayerFactory by
            override fun create(): SqueezeEffectHapticPlayer =
                SqueezeEffectHapticPlayer(
                    vibratorHelper = vibratorHelper,
                    bgScope = testScope.backgroundScope,
                    squeezeEffectInteractor =
                        SqueezeEffectInteractor(
                            squeezeEffectRepository = fakeSqueezeEffectRepository,
                            keyEventInteractor = KeyEventInteractor(fakeKeyEventRepository),
                            coroutineContext = testScope.testScheduler,
                        ),
                    applicationScope = testScope,
                )
        }
    }