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

Commit 99bda8cc authored by Jordan Demeulenaere's avatar Jordan Demeulenaere
Browse files

Show the Compose implementation of the footer actions when available

This CLs shows the Compose implementation of the QS footer actions when
Compose is enabled (it is not by default).

Bug: 242040009
Test: Build with SYSTEMUI_USE_COMPOSE=true and use the footer actions buttons.
Change-Id: I41a2a65fdf108849a8b2a7d381dab9d7d644f89a
parent 54a0fae8
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -17,8 +17,12 @@

package com.android.systemui.compose

import android.content.Context
import android.view.View
import androidx.activity.ComponentActivity
import androidx.lifecycle.LifecycleOwner
import com.android.systemui.people.ui.viewmodel.PeopleViewModel
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel

/** The Compose facade, when Compose is *not* available. */
object ComposeFacade : BaseComposeFacade {
@@ -36,6 +40,14 @@ object ComposeFacade : BaseComposeFacade {
        throwComposeUnavailableError()
    }

    override fun createFooterActionsView(
        context: Context,
        viewModel: FooterActionsViewModel,
        qsVisibilityLifecycleOwner: LifecycleOwner
    ): View {
        throwComposeUnavailableError()
    }

    private fun throwComposeUnavailableError(): Nothing {
        error(
            "Compose is not available. Make sure to check isComposeAvailable() before calling any" +
+16 −0
Original line number Diff line number Diff line
@@ -16,11 +16,17 @@

package com.android.systemui.compose

import android.content.Context
import android.view.View
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.ui.platform.ComposeView
import androidx.lifecycle.LifecycleOwner
import com.android.compose.theme.PlatformTheme
import com.android.systemui.people.ui.compose.PeopleScreen
import com.android.systemui.people.ui.viewmodel.PeopleViewModel
import com.android.systemui.qs.footer.ui.compose.FooterActions
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel

/** The Compose facade, when Compose is available. */
object ComposeFacade : BaseComposeFacade {
@@ -35,4 +41,14 @@ object ComposeFacade : BaseComposeFacade {
    ) {
        activity.setContent { PlatformTheme { PeopleScreen(viewModel, onResult) } }
    }

    override fun createFooterActionsView(
        context: Context,
        viewModel: FooterActionsViewModel,
        qsVisibilityLifecycleOwner: LifecycleOwner,
    ): View {
        return ComposeView(context).apply {
            setContent { PlatformTheme { FooterActions(viewModel, qsVisibilityLifecycleOwner) } }
        }
    }
}
+4 −3
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ import com.android.systemui.R
import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.ui.compose.Icon
import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsButtonViewModel
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsForegroundServicesButtonViewModel
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsSecurityButtonViewModel
@@ -180,9 +181,9 @@ fun FooterActions(

            security?.let { SecurityButton(it, Modifier.weight(1f)) }
            foregroundServices?.let { ForegroundServicesButton(it) }
            userSwitcher?.let { IconButton(it) }
            IconButton(viewModel.settings)
            viewModel.power?.let { IconButton(it) }
            userSwitcher?.let { IconButton(it, Modifier.sysuiResTag("multi_user_switch")) }
            IconButton(viewModel.settings, Modifier.sysuiResTag("settings_button_container"))
            viewModel.power?.let { IconButton(it, Modifier.sysuiResTag("pm_lite")) }
        }
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -17,8 +17,12 @@

package com.android.systemui.compose

import android.content.Context
import android.view.View
import androidx.activity.ComponentActivity
import androidx.lifecycle.LifecycleOwner
import com.android.systemui.people.ui.viewmodel.PeopleViewModel
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel

/**
 * A facade to interact with Compose, when it is available.
@@ -46,4 +50,11 @@ interface BaseComposeFacade {
        viewModel: PeopleViewModel,
        onResult: (PeopleViewModel.Result) -> Unit,
    )

    /** Create a [View] to represent [viewModel] on screen. */
    fun createFooterActionsView(
        context: Context,
        viewModel: FooterActionsViewModel,
        qsVisibilityLifecycleOwner: LifecycleOwner,
    ): View
}
+29 −3
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.animation.ShadeInterpolation;
import com.android.systemui.compose.ComposeFacade;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.media.controls.ui.MediaHost;
@@ -225,9 +226,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca

        mQSFooterActionsViewModel = mFooterActionsViewModelFactory.create(/* lifecycleOwner */
                this);
        LinearLayout footerActionsView = view.findViewById(R.id.qs_footer_actions);
        FooterActionsViewBinder.bind(footerActionsView, mQSFooterActionsViewModel,
                mListeningAndVisibilityLifecycleOwner);
        bindFooterActionsView(view);
        mFooterActionsController.init();

        mQSPanelScrollView = view.findViewById(R.id.expanded_qs_scroll_view);
@@ -288,6 +287,33 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
                });
    }

    private void bindFooterActionsView(View root) {
        LinearLayout footerActionsView = root.findViewById(R.id.qs_footer_actions);

        if (!ComposeFacade.INSTANCE.isComposeAvailable()) {
            Log.d(TAG, "Binding the View implementation of the QS footer actions");
            FooterActionsViewBinder.bind(footerActionsView, mQSFooterActionsViewModel,
                    mListeningAndVisibilityLifecycleOwner);
            return;
        }

        // Compose is available, so let's use the Compose implementation of the footer actions.
        Log.d(TAG, "Binding the Compose implementation of the QS footer actions");
        View composeView = ComposeFacade.INSTANCE.createFooterActionsView(root.getContext(),
                mQSFooterActionsViewModel, mListeningAndVisibilityLifecycleOwner);

        // The id R.id.qs_footer_actions is used by QSContainerImpl to set the horizontal margin
        // to all views except for qs_footer_actions, so we set it to the Compose view.
        composeView.setId(R.id.qs_footer_actions);

        // Replace the View by the Compose provided one.
        ViewGroup parent = (ViewGroup) footerActionsView.getParent();
        ViewGroup.LayoutParams layoutParams = footerActionsView.getLayoutParams();
        int index = parent.indexOfChild(footerActionsView);
        parent.removeViewAt(index);
        parent.addView(composeView, index, layoutParams);
    }

    @Override
    public void setScrollListener(ScrollListener listener) {
        mScrollListener = listener;