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

Commit 2f236d59 authored by Steve Elliott's avatar Steve Elliott
Browse files

only recreate onboarding controller on view change

Flag: com.android.systemui.notification_bundle_ui
Fixes: 426424951
Test: manual
  1. Have bundle onboarding in shade
  2. Scroll down such that onboarding is barely visible above shelf
  3. Receive alerting notification
  Observe: onboarding not invisible in shade
Change-Id: I464412d509618d343084a29b13d2c585ff14c039
parent 8f661d5f
Loading
Loading
Loading
Loading
+24 −14
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.systemui.statusbar.notification

import android.view.View
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
import com.android.systemui.statusbar.notification.collection.render.NodeController
@@ -25,29 +24,40 @@ import dagger.Module
import dagger.Provides
import javax.inject.Qualifier
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow

class OnboardingAffordanceManager(
    private val label: String,
    private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider,
) {
    val view = MutableStateFlow<OnboardingAffordanceView?>(null)
    private val _view = MutableStateFlow<OnboardingAffordanceView?>(null)
    val view: StateFlow<OnboardingAffordanceView?> = _view.asStateFlow()

    val addAffordanceToStack: Boolean
        get() = view.value != null && sectionHeaderVisibilityProvider.sectionHeadersVisible
    private var _nodeController: NodeController? = null
    val nodeController: NodeController?
        get() = _nodeController?.takeIf { sectionHeaderVisibilityProvider.sectionHeadersVisible }

    val controller: NodeController
        get() =
            object : NodeController {
                override val nodeLabel: String
                    get() = label

                override val view: View = this@OnboardingAffordanceManager.view.value!!
    fun setOnboardingAffordanceView(view: OnboardingAffordanceView?) {
        if (view != _view.value) {
            _view.value = view
            _nodeController = view?.let { AffordanceNodeController(label, view) }
        }
    }

    private class AffordanceNodeController(
        override val nodeLabel: String,
        override val view: OnboardingAffordanceView,
    ) : NodeController {
        override fun offerToKeepInParentForAnimation(): Boolean = false

        override fun removeFromParentIfKeptForAnimation(): Boolean = false

        override fun resetKeepInParentForAnimation() {}

        override fun onViewAdded() {
            view.setContentVisibleAnimated(true)
        }
    }
}

+4 −6
Original line number Diff line number Diff line
@@ -70,8 +70,8 @@ class NodeSpecBuilder(

            // If needed, the AI summaries onboarding affordance should be added above all
            // notifications.
            if (summaryOnboardingAffordanceManager.addAffordanceToStack) {
                root.children.add(NodeSpecImpl(root, summaryOnboardingAffordanceManager.controller))
            summaryOnboardingAffordanceManager.nodeController?.let { controller ->
                root.children.add(NodeSpecImpl(root, controller))
            }

            for (entry in notifList) {
@@ -102,10 +102,8 @@ class NodeSpecBuilder(
                // Include onboarding affordance for bundles above the first bundle, if needed.
                if (!seenBundle && entry is BundleEntry) {
                    seenBundle = true
                    if (bundleOnboardingAffordanceManager.addAffordanceToStack) {
                        root.children.add(
                            NodeSpecImpl(root, bundleOnboardingAffordanceManager.controller)
                        )
                    bundleOnboardingAffordanceManager.nodeController?.let { controller ->
                        root.children.add(NodeSpecImpl(root, controller))
                    }
                }

+37 −32
Original line number Diff line number Diff line
@@ -42,19 +42,32 @@ constructor(
    private val commandRegistry: CommandRegistry,
    private val bundleOnboardingInteractor: BundleOnboardingInteractor,
    private val summarizationOnboardingInteractor: SummarizationOnboardingInteractor,
) :
) : CoreStartable {

    override fun start() {
        commandRegistry.registerCommand(CMD_RESTORE_ONBOARDING) { Command() }
    }

    private enum class Target {
        Bundle,
        Summarization,
    }

    private inner class Command :
        ParseableCommand(
            name = CMD_RESTORE_ONBOARDING,
            description = "Restores a dismissed notification onboarding affordance.",
    ),
    CoreStartable {
        ) {

        private val target: Target by
            param(
                    shortName = "t",
                    longName = "target",
                    description =
                    """Which onboarding affordance to restore. One of "bundles" or "summaries".""",
                        """
                            Which onboarding affordance to restore. One of "bundles" or "summaries".
                        """
                            .trimIndent(),
                    valueParser = { arg ->
                        when (arg) {
                            "bundles",
@@ -67,20 +80,12 @@ constructor(
                )
                .required()

    override fun start() {
        commandRegistry.registerCommand(CMD_RESTORE_ONBOARDING) { this }
    }

        override fun execute(pw: PrintWriter) {
            when (target) {
                Target.Bundle -> bundleOnboardingInteractor.resurrectOnboarding()
                Target.Summarization -> summarizationOnboardingInteractor.resurrectOnboarding()
            }
        }

    private enum class Target {
        Bundle,
        Summarization,
    }

    @dagger.Module
+2 −2
Original line number Diff line number Diff line
@@ -342,7 +342,7 @@ constructor(
                }
            }
            .collectLatest { onboardingView ->
                bundleOnboardingMgr.view.value = onboardingView
                bundleOnboardingMgr.setOnboardingAffordanceView(onboardingView)
                onboardingView?.let {
                    bundleOnboardingBinder.get().bind(onboardingViewModel, onboardingView)
                }
@@ -368,7 +368,7 @@ constructor(
                }
            }
            .collectLatest { summariesView ->
                summarizationOnboardingMgr.view.value = summariesView
                summarizationOnboardingMgr.setOnboardingAffordanceView(summariesView)
                summariesView?.let {
                    summarizationOnboardingBinder.get().bind(summarizationViewModel, summariesView)
                }