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

Commit 12bc1f10 authored by Fabián Kozynski's avatar Fabián Kozynski
Browse files

Set content of ComposeView after setting back owner

The way the code was written before, there was no guarantee that the
content of the ComposeView would be added and composed before we set the
back dispatcher, and that is needed for the STL.

This way, the content should always be set after the back dispatcher is
set.

Test: manual, no changes as we couldn't repro crash
Fixes: 370869111
Flag: com.android.systemui.qs_ui_refactor_compose_fragment
Change-Id: Ie58955b96a973fcc2cced91e9781a178f4a2efe5
parent f87fc38d
Loading
Loading
Loading
Loading
+65 −68
Original line number Diff line number Diff line
@@ -52,7 +52,6 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.onPlaced
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.layout.positionInRoot
@@ -62,7 +61,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.CustomAccessibilityAction
import androidx.compose.ui.semantics.customActions
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.round
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -191,16 +189,51 @@ constructor(
        val context = inflater.context
        val composeView =
            ComposeView(context).apply {
                setBackPressedDispatcher()
                setContent {
                repeatWhenAttached {
                    repeatOnLifecycle(Lifecycle.State.CREATED) {
                        setViewTreeOnBackPressedDispatcherOwner(
                            object : OnBackPressedDispatcherOwner {
                                override val onBackPressedDispatcher =
                                    OnBackPressedDispatcher().apply {
                                        setOnBackInvokedDispatcher(
                                            it.viewRootImpl.onBackInvokedDispatcher
                                        )
                                    }

                                override val lifecycle: Lifecycle =
                                    this@repeatWhenAttached.lifecycle
                            }
                        )
                        setContent { this@QSFragmentCompose.Content() }
                    }
                }
            }

        val frame =
            FrameLayoutTouchPassthrough(
                context,
                { notificationScrimClippingParams.isEnabled },
                { notificationScrimClippingParams.top },
            )
        frame.addView(
            composeView,
            FrameLayout.LayoutParams.MATCH_PARENT,
            FrameLayout.LayoutParams.MATCH_PARENT,
        )
        return frame
    }

    @Composable
    private fun Content() {
        PlatformTheme {
            val visible by viewModel.qsVisible.collectAsStateWithLifecycle()

            AnimatedVisibility(
                visible = visible,
                modifier =
                                Modifier.windowInsetsPadding(WindowInsets.navigationBars)
                                    .thenIf(notificationScrimClippingParams.isEnabled) {
                    Modifier.windowInsetsPadding(WindowInsets.navigationBars).thenIf(
                        notificationScrimClippingParams.isEnabled
                    ) {
                        Modifier.notificationScrimClip(
                            notificationScrimClippingParams.leftInset,
                            notificationScrimClippingParams.top,
@@ -208,8 +241,7 @@ constructor(
                            notificationScrimClippingParams.bottom,
                            notificationScrimClippingParams.radius,
                        )
                                    }
                                    .graphicsLayer { elevation = 4.dp.toPx() },
                    },
            ) {
                val isEditing by
                    viewModel.containerViewModel.editModeViewModel.isEditing
@@ -218,14 +250,12 @@ constructor(
                AnimatedContent(
                    targetState = isEditing,
                    transitionSpec = {
                                    fadeIn(animationSpecEditMode) togetherWith
                                        fadeOut(animationSpecEditMode)
                        fadeIn(animationSpecEditMode) togetherWith fadeOut(animationSpecEditMode)
                    },
                    label = "EditModeAnimatedContent",
                ) { editing ->
                    if (editing) {
                                    val qqsPadding by
                                        viewModel.qqsHeaderHeight.collectAsStateWithLifecycle()
                        val qqsPadding by viewModel.qqsHeaderHeight.collectAsStateWithLifecycle()
                        EditMode(
                            viewModel = viewModel.containerViewModel.editModeViewModel,
                            modifier =
@@ -233,8 +263,7 @@ constructor(
                                    .padding(top = { qqsPadding })
                                    .padding(
                                        horizontal = {
                                                        QuickSettingsShade.Dimensions.Padding
                                                            .roundToPx()
                                            QuickSettingsShade.Dimensions.Padding.roundToPx()
                                        }
                                    ),
                        )
@@ -245,21 +274,6 @@ constructor(
            }
        }
    }
            }

        val frame =
            FrameLayoutTouchPassthrough(
                context,
                { notificationScrimClippingParams.isEnabled },
                { notificationScrimClippingParams.top },
            )
        frame.addView(
            composeView,
            FrameLayout.LayoutParams.MATCH_PARENT,
            FrameLayout.LayoutParams.MATCH_PARENT,
        )
        return frame
    }

    /**
     * STL that contains both QQS (tiles) and QS (brightness, tiles, footer actions), but no Edit
@@ -649,23 +663,6 @@ constructor(
    }
}

private fun View.setBackPressedDispatcher() {
    repeatWhenAttached {
        repeatOnLifecycle(Lifecycle.State.CREATED) {
            setViewTreeOnBackPressedDispatcherOwner(
                object : OnBackPressedDispatcherOwner {
                    override val onBackPressedDispatcher =
                        OnBackPressedDispatcher().apply {
                            setOnBackInvokedDispatcher(it.viewRootImpl.onBackInvokedDispatcher)
                        }

                    override val lifecycle: Lifecycle = this@repeatWhenAttached.lifecycle
                }
            )
        }
    }
}

private suspend inline fun <Listener : Any, Data> setListenerJob(
    listenerFlow: MutableStateFlow<Listener?>,
    dataFlow: Flow<Data>,