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

Commit 0b9e9dbd authored by Bharat Singh's avatar Bharat Singh
Browse files

[SysUI][Floaty][TempFix] Remove window if invocation effect not playing

Issue: (hard to repro) sometimes invocation effect isn't played on power
button press

Reason: Sometimes, in rare circumstances, rootview attached to window
isn't properly cleaned away and on next iteration onwards no new view is
being attached to the window due to a check "root == null" before
creating and attaching a view to window

Current temp fix:
* Creates a new state "isInvocationEffectHappening" to keep track
  of if invocation effect is being played or not
* If power button is lifted and invocation effect isn't being played,
  clean up the window
* If power button is lifted but invocation effect is being played, let
  the window be cleaned up after invocation effect finishes
* If due to any reason, window isn't cleaned up even in last point,
  before we attempt to add window next time, clean last added window
* Reset "isInvocationEffectHappening" to false after windows are
  cleaned up

Why not proper fix now?
* I am unable to consistently repro it but CL fixes almost all possible
  causes of this issue
* I don't like this solution, but to cleanly fix it might require us to
  move some logic into VM/repo which might require lot more changes
* This unblocks us Teamfood now

Bug: 414267753
Test: manual
Flag: com.android.systemui.shared.enable_lpp_assist_invocation_effect
Change-Id: I5198926318ebe7bc830e7ad39aaaf4e4e0713e80
parent f80c6c37
Loading
Loading
Loading
Loading
+37 −27
Original line number Diff line number Diff line
@@ -67,6 +67,9 @@ constructor(

    private var root: EffectsWindowRoot? = null

    // TODO(b/414267753): Make cleanup of window logic more robust
    private var isInvocationEffectHappening = false

    override fun start() {
        topLevelWindowEffectsScope.launch {
            squeezeEffectInteractor.isSqueezeEffectEnabled.collectLatest { enabled ->
@@ -81,6 +84,8 @@ constructor(
                                roundedCornerInfo.bottomResourceId,
                                roundedCornerInfo.physicalPixelDisplaySizeRatio,
                            )
                        } else if (root != null && !isInvocationEffectHappening) {
                            removeWindow()
                        }
                    }
                }
@@ -93,7 +98,14 @@ constructor(
        @DrawableRes bottomRoundedCornerId: Int,
        physicalPixelDisplaySizeRatio: Float,
    ) {
        if (root == null) {
        if (isInvocationEffectHappening) {
            return
        }

        if (root != null) {
            removeWindow()
        }

        root =
            EffectsWindowRoot(
                    context = context,
@@ -104,31 +116,29 @@ constructor(
                    onEffectFinished = ::removeWindow,
                    appZoomOutOptional = appZoomOutOptional,
                    interactionJankMonitor = interactionJankMonitor,
                    onEffectStarted = { isInvocationEffectHappening = true },
                )
                .apply { visibility = View.GONE }

        root?.let { rootView ->
                if (TopUiControllerRefactor.isEnabled) {
                    topUiController.setRequestTopUi(true, TAG)
                } else {
            runOnMainThread { notificationShadeWindowController.setRequestTopUi(true, TAG) }
                }
            windowManager.addView(rootView, getWindowManagerLayoutParams())
            rootView.post { rootView.visibility = View.VISIBLE }
        }
    }
    }

    private suspend fun removeWindow() {
        if (root?.isAttachedToWindow == true) {
            windowManager.removeView(root)
            root = null
        }

        root = null
        isInvocationEffectHappening = false

        if (TopUiControllerRefactor.isEnabled) {
            topUiController.setRequestTopUi(false, TAG)
        } else {
            runOnMainThread {
                notificationShadeWindowController.setRequestTopUi(false, TAG)
            }
            runOnMainThread { notificationShadeWindowController.setRequestTopUi(false, TAG) }
        }
    }

@@ -158,7 +168,7 @@ constructor(
        lp.layoutInDisplayCutoutMode =
            WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS

        lp.title = "TopLevelWindowEffects"
        lp.title = TAG
        lp.fitInsetsTypes = WindowInsets.Type.systemOverlays()
        lp.gravity = Gravity.TOP

+2 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import java.util.Optional
@SuppressLint("ViewConstructor")
class EffectsWindowRoot(
    context: Context,
    private val onEffectStarted: suspend () -> Unit,
    private val onEffectFinished: suspend () -> Unit,
    private val viewModelFactory: SqueezeEffectViewModel.Factory,
    @DrawableRes private val topRoundedCornerResourceId: Int,
@@ -53,6 +54,7 @@ class EffectsWindowRoot(
    override fun Content() {
        SqueezeEffect(
            viewModelFactory = viewModelFactory,
            onEffectStarted = onEffectStarted,
            onEffectFinished = onEffectFinished,
            topRoundedCornerResourceId = topRoundedCornerResourceId,
            bottomRoundedCornerResourceId = bottomRoundedCornerResourceId,
+3 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ fun SqueezeEffect(
    @DrawableRes topRoundedCornerResourceId: Int,
    @DrawableRes bottomRoundedCornerResourceId: Int,
    physicalPixelDisplaySizeRatio: Float,
    onEffectStarted: suspend () -> Unit,
    onEffectFinished: suspend () -> Unit,
    appZoomOutOptional: Optional<AppZoomOut>,
    interactionJankMonitor: InteractionJankMonitor,
@@ -94,6 +95,8 @@ fun SqueezeEffect(
    // lifting the power button the animation shouldn't be interruptible either.
    var isAnimationInterruptible by remember { mutableStateOf(true) }

    LaunchedEffect(Unit) { onEffectStarted() }

    LaunchedEffect(longPressed) {
        if (longPressed) {
            isAnimationInterruptible = false