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

Commit ba21715e authored by Bharat Singh's avatar Bharat Singh
Browse files

[SysUI][Floaty] Move a few window operations to background

Bug: 399263897
Test: atest TopLevelWindowEffectsTest
Flag: com.android.systemui.shared.enable_lpp_assist_invocation_effect
Change-Id: Ia93764743744ec9aea1203d22394e5a497f49b1e
parent 6b81bf05
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import com.android.systemui.topwindoweffects.ui.viewmodel.SqueezeEffectViewModel
import java.util.Optional
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.test.StandardTestDispatcher
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -69,8 +70,8 @@ class TopLevelWindowEffectsTest : SysuiTestCase() {
        Kosmos.Fixture {
            TopLevelWindowEffects(
                context = mContext,
                applicationScope = testScope.backgroundScope,
                bgContext = testScope.testScheduler,
                mainDispatcher = StandardTestDispatcher(testScope.testScheduler),
                topLevelWindowEffectsScope = testScope.backgroundScope,
                windowManager = windowManager,
                keyEventInteractor = keyEventInteractor,
                viewModelFactory = viewModelFactory,
+28 −34
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyevent.domain.interactor.KeyEventInteractor
import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.topwindoweffects.domain.interactor.SqueezeEffectInteractor
@@ -35,21 +36,20 @@ import com.android.systemui.topwindoweffects.ui.viewmodel.SqueezeEffectViewModel
import com.android.wm.shell.appzoomout.AppZoomOut
import java.util.Optional
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

@SysUISingleton
class TopLevelWindowEffects
@Inject
constructor(
    @Application private val context: Context,
    @Application private val applicationScope: CoroutineScope,
    @Background private val bgContext: CoroutineContext,
    @Main private val mainDispatcher: CoroutineDispatcher,
    @Background private val topLevelWindowEffectsScope: CoroutineScope,
    private val windowManager: WindowManager,
    private val squeezeEffectInteractor: SqueezeEffectInteractor,
    private val keyEventInteractor: KeyEventInteractor,
@@ -62,47 +62,32 @@ constructor(
    private var root: EffectsWindowRoot? = null

    override fun start() {
        applicationScope.launch {
            var launchWindowEffect: Job? = null
        topLevelWindowEffectsScope.launch {
            squeezeEffectInteractor.isSqueezeEffectEnabled.collectLatest { enabled ->
                if (enabled) {
                    keyEventInteractor.isPowerButtonDown.collectLatest { down ->
                        // cancel creating effects window if UP event is received within timeout
                        // threshold of initial delay
                        launchWindowEffect?.cancel()
                        if (down) {
                            val roundedCornerInfo =
                                async(context = bgContext) {
                                squeezeEffectInteractor.getRoundedCornersResourceId()
                                }
                            val initialDelay =
                                async(context = bgContext) {
                                    squeezeEffectInteractor.getInvocationEffectInitialDelayMs()
                                }
                            launchWindowEffect = launch {
                                delay(initialDelay.await())
                            delay(squeezeEffectInteractor.getInvocationEffectInitialDelayMs())
                            addWindow(
                                    roundedCornerInfo.await().topResourceId,
                                    roundedCornerInfo.await().bottomResourceId,
                                    roundedCornerInfo.await().physicalPixelDisplaySizeRatio,
                                roundedCornerInfo.topResourceId,
                                roundedCornerInfo.bottomResourceId,
                                roundedCornerInfo.physicalPixelDisplaySizeRatio,
                            )
                        }
                        } else {
                            launchWindowEffect = null
                        }
                    }
                }
            }
        }
    }

    private fun addWindow(
    private suspend fun addWindow(
        @DrawableRes topRoundedCornerId: Int,
        @DrawableRes bottomRoundedCornerId: Int,
        physicalPixelDisplaySizeRatio: Float,
    ) {
        if (root == null) {
            notificationShadeWindowController.setRequestTopUi(true, TAG)
            root =
                EffectsWindowRoot(
                    context = context,
@@ -111,19 +96,28 @@ constructor(
                    bottomRoundedCornerResourceId = bottomRoundedCornerId,
                    physicalPixelDisplaySizeRatio = physicalPixelDisplaySizeRatio,
                    onEffectFinished = {
                        notificationShadeWindowController.setRequestTopUi(false, TAG)
                        runOnMainThread {
                            if (root?.isAttachedToWindow == true) {
                                windowManager.removeView(root)
                                root = null
                            }
                            notificationShadeWindowController.setRequestTopUi(false, TAG)
                        }
                    },
                    appZoomOutOptional = appZoomOutOptional,
                )
            root?.let { rootView ->
                runOnMainThread {
                    notificationShadeWindowController.setRequestTopUi(true, TAG)
                    windowManager.addView(rootView, getWindowManagerLayoutParams())
                }
            }
        }
    }

    private suspend fun runOnMainThread(block: () -> Unit) {
        withContext(mainDispatcher) { block() }
    }

    private fun getWindowManagerLayoutParams(): WindowManager.LayoutParams {
        val lp =
+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ import java.util.Optional
@SuppressLint("ViewConstructor")
class EffectsWindowRoot(
    context: Context,
    private val onEffectFinished: () -> Unit,
    private val onEffectFinished: suspend () -> Unit,
    private val viewModelFactory: SqueezeEffectViewModel.Factory,
    @DrawableRes private val topRoundedCornerResourceId: Int,
    @DrawableRes private val bottomRoundedCornerResourceId: Int,
+1 −1
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ fun SqueezeEffect(
    @DrawableRes topRoundedCornerResourceId: Int,
    @DrawableRes bottomRoundedCornerResourceId: Int,
    physicalPixelDisplaySizeRatio: Float,
    onEffectFinished: () -> Unit,
    onEffectFinished: suspend () -> Unit,
    appZoomOutOptional: Optional<AppZoomOut>,
) {
    val viewModel = rememberViewModel(traceName = "SqueezeEffect") { viewModelFactory.create() }