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

Commit e05a59ff authored by Andreas Miko's avatar Andreas Miko Committed by Android (Google) Code Review
Browse files

Merge "Refactor NotificationMenuRowPlugin to not require the GutsContent to be a View" into main

parents e6a8a785 460b5fee
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -53,25 +53,16 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.compose.theme.PlatformTheme
import com.android.internal.R
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,
    viewModel: BundleHeaderGutsViewModel,
): ComposeView {
fun createBundleHeaderGutsComposeView(context: Context): ComposeView {
    return ComposeView(context).apply {
        repeatWhenAttached {
            repeatOnLifecycle(Lifecycle.State.CREATED) {
                initOnBackPressureDispatcherOwner(this@repeatWhenAttached.lifecycle)
                setContent {
                    // TODO(b/399588047): Check if we can init PlatformTheme once instead of once
                    //  per ComposeView
                    PlatformTheme { BundleHeaderGuts(viewModel) }
                }
            }
        }
    }
+7 −1
Original line number Diff line number Diff line
@@ -58,7 +58,13 @@ public interface NotificationMenuRowPlugin extends Plugin {

        public View getMenuView();

        public View getGutsView();
        /**
         * The guts content that provides the [View] to be displayed.
         *
         * @return Object of type [NotificationGuts.GutsContent]. The interface is not known in this
         *          module, therefore only the implementation returns the proper type.
         */
        Object getGutsContent();

        public String getContentDescription();

+20 −23
Original line number Diff line number Diff line
@@ -17,31 +17,22 @@
package com.android.systemui.statusbar.notification.row

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.widget.FrameLayout
import androidx.compose.ui.platform.ComposeView
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.compose.theme.PlatformTheme
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.notifications.ui.composable.row.BundleHeaderGuts
import com.android.systemui.notifications.ui.composable.row.createBundleHeaderGutsComposeView
import com.android.systemui.statusbar.notification.collection.BundleEntryAdapter
import com.android.systemui.statusbar.notification.row.NotificationGuts.GutsContent
import com.android.systemui.statusbar.notification.row.ui.viewmodel.BundleHeaderGutsViewModel

/**
 * This View is a container for a ComposeView and implements GutsContent. Technically, this should
 * not be a View as GutsContent could just return the ComposeView directly for getContentView().
 * Unfortunately, the legacy design of `NotificationMenuRowPlugin.MenuItem.getGutsView()` forces the
 * GutsContent to be a View itself. Therefore this class is a view that just holds the ComposeView.
 *
 * A redesign of `NotificationMenuRowPlugin.MenuItem.getGutsView()` to return GutsContent instead is
 * desired but it lacks proper module dependencies. As soon as this class does not need to inherit
 * from View it can just return the ComposeView directly instead.
 */
class BundleHeaderGutsContent
@JvmOverloads
constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
    FrameLayout(context, attrs, defStyleAttr), GutsContent {
/** The guts content that provides the view to be displayed when a bundle header is long pressed. */
class BundleHeaderGutsContent(context: Context) : GutsContent {

    private var composeView: ComposeView? = null
    private var composeView: ComposeView = createBundleHeaderGutsComposeView(context)
    private var gutsParent: NotificationGuts? = null

    fun bindNotification(
@@ -50,8 +41,6 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
        onDoneClicked: () -> Unit = {},
        onDismissClicked: () -> Unit = {},
    ) {
        if (composeView != null) return

        val repository = (row.entryAdapter as BundleEntryAdapter).entry.bundleRepository
        val viewModel =
            BundleHeaderGutsViewModel(
@@ -61,8 +50,16 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
                onDoneClicked = onDoneClicked,
                onDismissClicked = onDismissClicked,
            )
        composeView = createBundleHeaderGutsComposeView(context, viewModel)
        addView(composeView)

        composeView.repeatWhenAttached {
            repeatOnLifecycle(Lifecycle.State.CREATED) {
                composeView.setContent {
                    // TODO(b/399588047): Check if we can init PlatformTheme once instead of once
                    //  per ComposeView
                    PlatformTheme { BundleHeaderGuts(viewModel) }
                }
            }
        }
    }

    override fun setGutsParent(listener: NotificationGuts?) {
@@ -70,11 +67,11 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
    }

    override fun getContentView(): View {
        return this
        return composeView
    }

    override fun getActualHeight(): Int {
        return composeView?.measuredHeight ?: 0
        return composeView.measuredHeight
    }

    override fun handleCloseControls(save: Boolean, force: Boolean): Boolean {
+5 −6
Original line number Diff line number Diff line
@@ -1566,8 +1566,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
    }

    public void setGutsView(MenuItem item) {
        if (getGuts() != null && item.getGutsView() instanceof NotificationGuts.GutsContent) {
            getGuts().setGutsContent((NotificationGuts.GutsContent) item.getGutsView());
        if (getGuts() != null
                && item.getGutsContent() instanceof NotificationGuts.GutsContent gutsContent) {
            getGuts().setGutsContent(gutsContent);
        }
    }

@@ -2604,10 +2605,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
            menuItem = provider.getLongpressMenuItem(mContext);
        }
        if (SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY == semanticAction
                && menuItem.getGutsView() instanceof NotificationConversationInfo) {
            NotificationConversationInfo info =
                    (NotificationConversationInfo) menuItem.getGutsView();
            info.setSelectedAction(NotificationConversationInfo.ACTION_FAVORITE);
                && menuItem.getGutsContent() instanceof NotificationConversationInfo gutsContent) {
            gutsContent.setSelectedAction(NotificationConversationInfo.ACTION_FAVORITE);
        }
        doLongClickCallback(x, y, menuItem);
    }
+1 −6
Original line number Diff line number Diff line
@@ -135,11 +135,6 @@ public class NotificationGuts extends FrameLayout {
         * view on the lockscreen
         */
        boolean needsFalsingProtection();

        /**
         * Equivalent to {@link View#setAccessibilityDelegate(AccessibilityDelegate)}
         */
        void setAccessibilityDelegate(AccessibilityDelegate gutsContentAccessibilityDelegate);
    }

    public interface OnGutsClosedListener {
@@ -174,7 +169,7 @@ public class NotificationGuts extends FrameLayout {

    public void setGutsContent(GutsContent content) {
        content.setGutsParent(this);
        content.setAccessibilityDelegate(mGutsContentAccessibilityDelegate);
        content.getContentView().setAccessibilityDelegate(mGutsContentAccessibilityDelegate);
        mGutsContent = content;
        removeAllViews();
        addView(mGutsContent.getContentView());
Loading