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

Commit 10679abb authored by Jordan Demeulenaere's avatar Jordan Demeulenaere Committed by Automerger Merge Worker
Browse files

Merge "Fix flicker of QS footer actions when restarting SystemUI (1/2)" into udc-dev am: 5818342a

parents 05deb7c3 5818342a
Loading
Loading
Loading
Loading
+4 −1
Original line number Original line Diff line number Diff line
@@ -120,6 +120,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
    private final QSLogger mLogger;
    private final QSLogger mLogger;
    private final FooterActionsController mFooterActionsController;
    private final FooterActionsController mFooterActionsController;
    private final FooterActionsViewModel.Factory mFooterActionsViewModelFactory;
    private final FooterActionsViewModel.Factory mFooterActionsViewModelFactory;
    private final FooterActionsViewBinder mFooterActionsViewBinder;
    private final ListeningAndVisibilityLifecycleOwner mListeningAndVisibilityLifecycleOwner;
    private final ListeningAndVisibilityLifecycleOwner mListeningAndVisibilityLifecycleOwner;
    private boolean mShowCollapsedOnKeyguard;
    private boolean mShowCollapsedOnKeyguard;
    private boolean mLastKeyguardAndExpanded;
    private boolean mLastKeyguardAndExpanded;
@@ -177,6 +178,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
            DumpManager dumpManager, QSLogger qsLogger,
            DumpManager dumpManager, QSLogger qsLogger,
            FooterActionsController footerActionsController,
            FooterActionsController footerActionsController,
            FooterActionsViewModel.Factory footerActionsViewModelFactory,
            FooterActionsViewModel.Factory footerActionsViewModelFactory,
            FooterActionsViewBinder footerActionsViewBinder,
            LargeScreenShadeInterpolator largeScreenShadeInterpolator,
            LargeScreenShadeInterpolator largeScreenShadeInterpolator,
            FeatureFlags featureFlags) {
            FeatureFlags featureFlags) {
        mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
        mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
@@ -193,6 +195,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
        mDumpManager = dumpManager;
        mDumpManager = dumpManager;
        mFooterActionsController = footerActionsController;
        mFooterActionsController = footerActionsController;
        mFooterActionsViewModelFactory = footerActionsViewModelFactory;
        mFooterActionsViewModelFactory = footerActionsViewModelFactory;
        mFooterActionsViewBinder = footerActionsViewBinder;
        mListeningAndVisibilityLifecycleOwner = new ListeningAndVisibilityLifecycleOwner();
        mListeningAndVisibilityLifecycleOwner = new ListeningAndVisibilityLifecycleOwner();
    }
    }


@@ -285,7 +288,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca


        if (!ComposeFacade.INSTANCE.isComposeAvailable()) {
        if (!ComposeFacade.INSTANCE.isComposeAvailable()) {
            Log.d(TAG, "Binding the View implementation of the QS footer actions");
            Log.d(TAG, "Binding the View implementation of the QS footer actions");
            FooterActionsViewBinder.bind(footerActionsView, mQSFooterActionsViewModel,
            mFooterActionsViewBinder.bind(footerActionsView, mQSFooterActionsViewModel,
                    mListeningAndVisibilityLifecycleOwner);
                    mListeningAndVisibilityLifecycleOwner);
            return;
            return;
        }
        }
+9 −4
Original line number Original line Diff line number Diff line
@@ -33,27 +33,27 @@ import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.R
import com.android.systemui.R
import com.android.systemui.animation.Expandable
import com.android.systemui.animation.Expandable
import com.android.systemui.common.ui.binder.IconViewBinder
import com.android.systemui.common.ui.binder.IconViewBinder
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.people.ui.view.PeopleViewBinder.bind
import com.android.systemui.people.ui.view.PeopleViewBinder.bind
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsButtonViewModel
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.FooterActionsForegroundServicesButtonViewModel
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsSecurityButtonViewModel
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsSecurityButtonViewModel
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
import javax.inject.Inject
import kotlin.math.roundToInt
import kotlin.math.roundToInt
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import kotlinx.coroutines.launch


/** A ViewBinder for [FooterActionsViewBinder]. */
/** A ViewBinder for [FooterActionsViewBinder]. */
object FooterActionsViewBinder {
@SysUISingleton
class FooterActionsViewBinder @Inject constructor() {
    /** Create a view that can later be [bound][bind] to a [FooterActionsViewModel]. */
    /** Create a view that can later be [bound][bind] to a [FooterActionsViewModel]. */
    @JvmStatic
    fun create(context: Context): LinearLayout {
    fun create(context: Context): LinearLayout {
        return LayoutInflater.from(context).inflate(R.layout.footer_actions, /* root= */ null)
        return LayoutInflater.from(context).inflate(R.layout.footer_actions, /* root= */ null)
            as LinearLayout
            as LinearLayout
    }
    }


    /** Bind [view] to [viewModel]. */
    /** Bind [view] to [viewModel]. */
    @JvmStatic
    fun bind(
    fun bind(
        view: LinearLayout,
        view: LinearLayout,
        viewModel: FooterActionsViewModel,
        viewModel: FooterActionsViewModel,
@@ -98,6 +98,11 @@ object FooterActionsViewBinder {
        var previousForegroundServices: FooterActionsForegroundServicesButtonViewModel? = null
        var previousForegroundServices: FooterActionsForegroundServicesButtonViewModel? = null
        var previousUserSwitcher: FooterActionsButtonViewModel? = null
        var previousUserSwitcher: FooterActionsButtonViewModel? = null


        // Set the initial visibility on the View directly so that we don't briefly show it for a
        // few frames before [viewModel.isVisible] is collected.
        view.isInvisible = !viewModel.isVisible.value

        // Listen for ViewModel updates when the View is attached.
        view.repeatWhenAttached {
        view.repeatWhenAttached {
            val attachedScope = this.lifecycleScope
            val attachedScope = this.lifecycleScope


+1 −1
Original line number Original line Diff line number Diff line
@@ -64,7 +64,7 @@ class FooterActionsViewModel(
     * the UI should still participate to the layout it is included in (i.e. in the View world it
     * the UI should still participate to the layout it is included in (i.e. in the View world it
     * should be INVISIBLE, not GONE).
     * should be INVISIBLE, not GONE).
     */
     */
    private val _isVisible = MutableStateFlow(true)
    private val _isVisible = MutableStateFlow(false)
    val isVisible: StateFlow<Boolean> = _isVisible.asStateFlow()
    val isVisible: StateFlow<Boolean> = _isVisible.asStateFlow()


    /** The alpha the UI rendering this ViewModel should have. */
    /** The alpha the UI rendering this ViewModel should have. */
+3 −1
Original line number Original line Diff line number Diff line
@@ -106,6 +106,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
    @Mock private QSSquishinessController mSquishinessController;
    @Mock private QSSquishinessController mSquishinessController;
    @Mock private FooterActionsViewModel mFooterActionsViewModel;
    @Mock private FooterActionsViewModel mFooterActionsViewModel;
    @Mock private FooterActionsViewModel.Factory mFooterActionsViewModelFactory;
    @Mock private FooterActionsViewModel.Factory mFooterActionsViewModelFactory;
    @Mock private FooterActionsViewBinder mFooterActionsViewBinder;
    @Mock private LargeScreenShadeInterpolator mLargeScreenShadeInterpolator;
    @Mock private LargeScreenShadeInterpolator mLargeScreenShadeInterpolator;
    @Mock private FeatureFlags mFeatureFlags;
    @Mock private FeatureFlags mFeatureFlags;
    private View mQsFragmentView;
    private View mQsFragmentView;
@@ -558,6 +559,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
                mock(QSLogger.class),
                mock(QSLogger.class),
                mock(FooterActionsController.class),
                mock(FooterActionsController.class),
                mFooterActionsViewModelFactory,
                mFooterActionsViewModelFactory,
                mFooterActionsViewBinder,
                mLargeScreenShadeInterpolator,
                mLargeScreenShadeInterpolator,
                mFeatureFlags);
                mFeatureFlags);
    }
    }
@@ -584,7 +586,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
        when(mQsFragmentView.findViewById(R.id.header)).thenReturn(mHeader);
        when(mQsFragmentView.findViewById(R.id.header)).thenReturn(mHeader);
        when(mQsFragmentView.findViewById(android.R.id.edit)).thenReturn(new View(mContext));
        when(mQsFragmentView.findViewById(android.R.id.edit)).thenReturn(new View(mContext));
        when(mQsFragmentView.findViewById(R.id.qs_footer_actions)).thenAnswer(
        when(mQsFragmentView.findViewById(R.id.qs_footer_actions)).thenAnswer(
                invocation -> FooterActionsViewBinder.create(mContext));
                invocation -> new FooterActionsViewBinder().create(mContext));
    }
    }


    private void setUpInflater() {
    private void setUpInflater() {
+3 −3
Original line number Original line Diff line number Diff line
@@ -376,13 +376,13 @@ class FooterActionsViewModelTest : SysuiTestCase() {
    @Test
    @Test
    fun isVisible() {
    fun isVisible() {
        val underTest = utils.footerActionsViewModel()
        val underTest = utils.footerActionsViewModel()
        assertThat(underTest.isVisible.value).isTrue()

        underTest.onVisibilityChangeRequested(visible = false)
        assertThat(underTest.isVisible.value).isFalse()
        assertThat(underTest.isVisible.value).isFalse()


        underTest.onVisibilityChangeRequested(visible = true)
        underTest.onVisibilityChangeRequested(visible = true)
        assertThat(underTest.isVisible.value).isTrue()
        assertThat(underTest.isVisible.value).isTrue()

        underTest.onVisibilityChangeRequested(visible = false)
        assertThat(underTest.isVisible.value).isFalse()
    }
    }


    @Test
    @Test