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

Commit 5dea64fc authored by Andreas Miko's avatar Andreas Miko
Browse files

Consolidate setViewTreeOnBackPressedDispatcherOwner calls

Test: Ran sysui with and without flexiglass enabled
Bug: NONE
Flag: EXEMPT refactor
Change-Id: Icab03884d031dac70b1b319539a58f550d644066
parent 98aafbea
Loading
Loading
Loading
Loading
+65 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui

import android.view.View
import androidx.activity.OnBackPressedDispatcher
import androidx.activity.OnBackPressedDispatcherOwner
import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
import androidx.lifecycle.Lifecycle
import com.android.systemui.scene.shared.flag.SceneContainerFlag

/**
 * Attaches a [OnBackPressedDispatcherOwner] to a [View] to prevent a [IllegalStateException].
 *
 * When [SceneContainerFlag] is enabled this is usually not needed for child [ComposeView]s because
 * it is sufficient to attach it to the root container. However, when [SceneContainerFlag] is
 * disabled, this function needs to be called for each [ComposeView] or one of its ancestors. Needs
 * to be called within [repeatOnLifeCycle] as follows:
 * ```
 * ComposeView(context).apply {
 *     repeatWhenAttached {
 *         repeatOnLifecycle(Lifecycle.State.CREATED) {
 *             initOnBackPressedDispatcherOwner(this@repeatWhenAttached.lifecycle)
 *             setContent {
 *                 PlatformTheme { YourComposable() }
 *             }
 *         }
 *     }
 * }
 * ```
 *
 * Make sure to call [setContent] within the same [repeatOnLifeCycle] block and after this init
 * otherwise a composition might happen before and cause a crash.
 *
 * @param lifecycle The lifecycle of the view.
 * @param force Whether the dispatcher should be set up regardless of any flag checks.
 */
fun View.initOnBackPressedDispatcherOwner(lifecycle: Lifecycle, force: Boolean = false) {
    if (!SceneContainerFlag.isEnabled || force) {
        setViewTreeOnBackPressedDispatcherOwner(
            object : OnBackPressedDispatcherOwner {
                override val onBackPressedDispatcher =
                    OnBackPressedDispatcher().apply {
                        setOnBackInvokedDispatcher(viewRootImpl.onBackInvokedDispatcher)
                    }

                override val lifecycle: Lifecycle = lifecycle
            }
        )
    }
}
+2 −21
Original line number Diff line number Diff line
@@ -18,10 +18,6 @@ package com.android.systemui.notifications.ui.composable.row

import android.content.Context
import android.graphics.drawable.Drawable
import android.view.View
import androidx.activity.OnBackPressedDispatcher
import androidx.activity.OnBackPressedDispatcherOwner
import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
@@ -55,8 +51,8 @@ import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.SceneTransitionLayout
import com.android.compose.theme.PlatformTheme
import com.android.compose.ui.graphics.painter.rememberDrawablePainter
import com.android.systemui.initOnBackPressedDispatcherOwner
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.statusbar.notification.row.ui.viewmodel.BundleHeaderViewModel

object BundleHeader {
@@ -77,7 +73,7 @@ fun createComposeView(viewModel: BundleHeaderViewModel, context: Context): Compo
    return ComposeView(context).apply {
        repeatWhenAttached {
            repeatOnLifecycle(Lifecycle.State.CREATED) {
                initOnBackPressureDispatcherOwner(this@repeatWhenAttached.lifecycle)
                initOnBackPressedDispatcherOwner(this@repeatWhenAttached.lifecycle)
                setContent {
                    // TODO(b/399588047): Check if we can init PlatformTheme once instead of once
                    //  per ComposeView
@@ -88,21 +84,6 @@ fun createComposeView(viewModel: BundleHeaderViewModel, context: Context): Compo
    }
}

private fun View.initOnBackPressureDispatcherOwner(lifecycle: Lifecycle) {
    if (!SceneContainerFlag.isEnabled) {
        setViewTreeOnBackPressedDispatcherOwner(
            object : OnBackPressedDispatcherOwner {
                override val onBackPressedDispatcher =
                    OnBackPressedDispatcher().apply {
                        setOnBackInvokedDispatcher(viewRootImpl.onBackInvokedDispatcher)
                    }

                override val lifecycle: Lifecycle = lifecycle
            }
        )
    }
}

@Composable
fun BundleHeader(viewModel: BundleHeaderViewModel, modifier: Modifier = Modifier) {
    Box(modifier) {
+2 −21
Original line number Diff line number Diff line
@@ -19,10 +19,6 @@
package com.android.systemui.notifications.ui.composable.row

import android.content.Context
import android.view.View
import androidx.activity.OnBackPressedDispatcher
import androidx.activity.OnBackPressedDispatcherOwner
import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@@ -54,35 +50,20 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.internal.R
import com.android.systemui.initOnBackPressedDispatcherOwner
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.statusbar.notification.row.ui.viewmodel.BundleHeaderGutsViewModel

fun createBundleHeaderGutsComposeView(context: Context): ComposeView {
    return ComposeView(context).apply {
        repeatWhenAttached {
            repeatOnLifecycle(Lifecycle.State.CREATED) {
                initOnBackPressureDispatcherOwner(this@repeatWhenAttached.lifecycle)
                initOnBackPressedDispatcherOwner(this@repeatWhenAttached.lifecycle)
            }
        }
    }
}

private fun View.initOnBackPressureDispatcherOwner(lifecycle: Lifecycle) {
    if (!SceneContainerFlag.isEnabled) {
        setViewTreeOnBackPressedDispatcherOwner(
            object : OnBackPressedDispatcherOwner {
                override val onBackPressedDispatcher =
                    OnBackPressedDispatcher().apply {
                        setOnBackInvokedDispatcher(viewRootImpl.onBackInvokedDispatcher)
                    }

                override val lifecycle: Lifecycle = lifecycle
            }
        )
    }
}

@Composable
fun BundleHeaderGuts(viewModel: BundleHeaderGutsViewModel, modifier: Modifier = Modifier) {
    Column(modifier.padding(horizontal = 16.dp)) {
+4 −15
Original line number Diff line number Diff line
@@ -33,9 +33,6 @@ import android.view.View.VISIBLE
import android.view.ViewGroup
import android.view.ViewGroup.OnHierarchyChangeListener
import android.view.WindowInsets
import androidx.activity.OnBackPressedDispatcher
import androidx.activity.OnBackPressedDispatcherOwner
import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.app.tracing.coroutines.launchTraced as launch
@@ -50,6 +47,7 @@ import com.android.systemui.common.ui.view.onApplyWindowInsets
import com.android.systemui.common.ui.view.onLayoutChanged
import com.android.systemui.common.ui.view.onTouchListener
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInteractor
import com.android.systemui.initOnBackPressedDispatcherOwner
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.ui.view.layout.sections.AodPromotedNotificationSection
import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
@@ -229,18 +227,9 @@ object KeyguardRootViewBinder {
            view.repeatWhenAttached {
                repeatOnLifecycle(Lifecycle.State.CREATED) {
                    if (SceneContainerFlag.isEnabled) {
                        view.setViewTreeOnBackPressedDispatcherOwner(
                            object : OnBackPressedDispatcherOwner {
                                override val onBackPressedDispatcher =
                                    OnBackPressedDispatcher().apply {
                                        setOnBackInvokedDispatcher(
                                            view.viewRootImpl.onBackInvokedDispatcher
                                        )
                                    }

                                override val lifecycle: Lifecycle =
                                    this@repeatWhenAttached.lifecycle
                            }
                        view.initOnBackPressedDispatcherOwner(
                            this@repeatWhenAttached.lifecycle,
                            force = true,
                        )
                    }
                    launch {
+2 −17
Original line number Diff line number Diff line
@@ -31,9 +31,6 @@ import android.view.View
import android.view.ViewConfiguration
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.activity.OnBackPressedDispatcher
import androidx.activity.OnBackPressedDispatcherOwner
import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
import androidx.annotation.VisibleForTesting
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ScrollState
@@ -57,7 +54,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
@@ -120,6 +116,7 @@ import com.android.systemui.compose.modifiers.sysUiResTagContainer
import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dump.DumpManager
import com.android.systemui.initOnBackPressedDispatcherOwner
import com.android.systemui.keyboard.shortcut.ui.composable.InteractionsConfig
import com.android.systemui.keyboard.shortcut.ui.composable.ProvideShortcutHelperIndication
import com.android.systemui.lifecycle.repeatWhenAttached
@@ -222,19 +219,7 @@ constructor(
                id = R.id.quick_settings_container
                repeatWhenAttached {
                    repeatOnLifecycle(Lifecycle.State.CREATED) {
                        setViewTreeOnBackPressedDispatcherOwner(
                            object : OnBackPressedDispatcherOwner {
                                override val onBackPressedDispatcher =
                                    OnBackPressedDispatcher().apply {
                                        setOnBackInvokedDispatcher(
                                            it.viewRootImpl.onBackInvokedDispatcher
                                        )
                                    }

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