Loading packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt +2 −9 Original line number Diff line number Diff line Loading @@ -46,7 +46,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.layout.layout Loading @@ -69,7 +68,6 @@ import com.android.compose.animation.Expandable import com.android.compose.modifiers.background import com.android.compose.theme.LocalAndroidColorScheme import com.android.compose.theme.colorAttr import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.ui.compose.Icon Loading @@ -78,6 +76,7 @@ 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 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.res.R import kotlinx.coroutines.launch /** The Quick Settings footer actions row. */ Loading @@ -89,8 +88,7 @@ fun FooterActions( ) { val context = LocalContext.current // Collect visibility and alphas as soon as we are composed, even when not visible. val isVisible by viewModel.isVisible.collectAsState() // Collect alphas as soon as we are composed, even when not visible. val alpha by viewModel.alpha.collectAsState() val backgroundAlpha = viewModel.backgroundAlpha.collectAsState() Loading Loading @@ -142,11 +140,6 @@ fun FooterActions( modifier .fillMaxWidth() .graphicsLayer { this.alpha = alpha } .drawWithContent { if (isVisible) { drawContent() } } .then(backgroundModifier) .padding( top = dimensionResource(R.dimen.qs_footer_actions_top_padding), Loading packages/SystemUI/src/com/android/systemui/qs/QSImpl.java +5 −2 Original line number Diff line number Diff line Loading @@ -170,6 +170,7 @@ public class QSImpl implements QS, CommandQueue.Callbacks, StatusBarStateControl private CommandQueue mCommandQueue; private View mRootView; private View mFooterActionsView; @Inject public QSImpl(RemoteInputQuickSettingsDisabler remoteInputQsDisabler, Loading Loading @@ -285,6 +286,7 @@ public class QSImpl implements QS, CommandQueue.Callbacks, StatusBarStateControl if (!mFeatureFlags.isEnabled(Flags.COMPOSE_QS_FOOTER_ACTIONS) || !ComposeFacade.INSTANCE.isComposeAvailable()) { Log.d(TAG, "Binding the View implementation of the QS footer actions"); mFooterActionsView = footerActionsView; mFooterActionsViewBinder.bind(footerActionsView, mQSFooterActionsViewModel, mListeningAndVisibilityLifecycleOwner); return; Loading @@ -294,6 +296,7 @@ public class QSImpl implements QS, CommandQueue.Callbacks, StatusBarStateControl Log.d(TAG, "Binding the Compose implementation of the QS footer actions"); View composeView = ComposeFacade.INSTANCE.createFooterActionsView(root.getContext(), mQSFooterActionsViewModel, mListeningAndVisibilityLifecycleOwner); mFooterActionsView = composeView; // 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. Loading Loading @@ -472,7 +475,7 @@ public class QSImpl implements QS, CommandQueue.Callbacks, StatusBarStateControl boolean footerVisible = qsPanelVisible && (mQsExpanded || !keyguardShowing || mHeaderAnimating || mShowCollapsedOnKeyguard); mFooter.setVisibility(footerVisible ? View.VISIBLE : View.INVISIBLE); mQSFooterActionsViewModel.onVisibilityChangeRequested(footerVisible); mFooterActionsView.setVisibility(footerVisible ? View.VISIBLE : View.INVISIBLE); mFooter.setExpanded((keyguardShowing && !mHeaderAnimating && !mShowCollapsedOnKeyguard) || (mQsExpanded && !mStackScrollerOverscrolling)); mQSPanelController.setVisibility(qsPanelVisible ? View.VISIBLE : View.INVISIBLE); Loading Loading @@ -856,7 +859,7 @@ public class QSImpl implements QS, CommandQueue.Callbacks, StatusBarStateControl boolean customizing = isCustomizing(); mQSPanelScrollView.setVisibility(!customizing ? View.VISIBLE : View.INVISIBLE); mFooter.setVisibility(!customizing ? View.VISIBLE : View.INVISIBLE); mQSFooterActionsViewModel.onVisibilityChangeRequested(!customizing); mFooterActionsView.setVisibility(!customizing ? View.VISIBLE : View.INVISIBLE); mHeader.setVisibility(!customizing ? View.VISIBLE : View.INVISIBLE); // Let the panel know the position changed and it needs to update where notifications // and whatnot are. Loading packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt +2 −12 Original line number Diff line number Diff line Loading @@ -24,13 +24,11 @@ import android.view.ViewGroup import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView import androidx.core.view.isInvisible import androidx.core.view.isVisible import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.common.ui.binder.IconViewBinder import com.android.systemui.dagger.SysUISingleton Loading @@ -40,6 +38,7 @@ 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 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.res.R import javax.inject.Inject import kotlin.math.roundToInt import kotlinx.coroutines.launch Loading Loading @@ -98,10 +97,6 @@ class FooterActionsViewBinder @Inject constructor() { var previousForegroundServices: FooterActionsForegroundServicesButtonViewModel? = 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 { val attachedScope = this.lifecycleScope Loading @@ -111,12 +106,7 @@ class FooterActionsViewBinder @Inject constructor() { // TODO(b/242040009): Should this move somewhere else? launch { viewModel.observeDeviceMonitoringDialogRequests(view.context) } // Make sure we set the correct visibility and alpha even when QS are not currently // shown. launch { viewModel.isVisible.collect { isVisible -> view.isInvisible = !isVisible } } // Make sure we set the correct alphas even when QS are not currently shown. launch { viewModel.alpha.collect { view.alpha = it } } launch { viewModel.backgroundAlpha.collect { Loading packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt +0 −12 Original line number Diff line number Diff line Loading @@ -77,14 +77,6 @@ class FooterActionsViewModel( */ val observeDeviceMonitoringDialogRequests: suspend (quickSettingsContext: Context) -> Unit, ) { /** * Whether the UI rendering this ViewModel should be visible. Note that even when this is false, * the UI should still participate to the layout it is included in (i.e. in the View world it * should be INVISIBLE, not GONE). */ private val _isVisible = MutableStateFlow(false) val isVisible: StateFlow<Boolean> = _isVisible.asStateFlow() /** The alpha the UI rendering this ViewModel should have. */ private val _alpha = MutableStateFlow(1f) val alpha: StateFlow<Float> = _alpha.asStateFlow() Loading @@ -93,10 +85,6 @@ class FooterActionsViewModel( private val _backgroundAlpha = MutableStateFlow(1f) val backgroundAlpha: StateFlow<Float> = _backgroundAlpha.asStateFlow() fun onVisibilityChangeRequested(visible: Boolean) { _isVisible.value = visible } /** Called when the expansion of the Quick Settings changed. */ fun onQuickSettingsExpansionChanged(expansion: Float, isInSplitShade: Boolean) { if (isInSplitShade) { Loading packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt +0 −12 Original line number Diff line number Diff line Loading @@ -372,18 +372,6 @@ class FooterActionsViewModelTest : SysuiTestCase() { job.cancel() } @Test fun isVisible() { val underTest = utils.footerActionsViewModel() assertThat(underTest.isVisible.value).isFalse() underTest.onVisibilityChangeRequested(visible = true) assertThat(underTest.isVisible.value).isTrue() underTest.onVisibilityChangeRequested(visible = false) assertThat(underTest.isVisible.value).isFalse() } @Test fun alpha_inSplitShade_followsExpansion() { val underTest = utils.footerActionsViewModel() Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt +2 −9 Original line number Diff line number Diff line Loading @@ -46,7 +46,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.layout.layout Loading @@ -69,7 +68,6 @@ import com.android.compose.animation.Expandable import com.android.compose.modifiers.background import com.android.compose.theme.LocalAndroidColorScheme import com.android.compose.theme.colorAttr import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.ui.compose.Icon Loading @@ -78,6 +76,7 @@ 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 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.res.R import kotlinx.coroutines.launch /** The Quick Settings footer actions row. */ Loading @@ -89,8 +88,7 @@ fun FooterActions( ) { val context = LocalContext.current // Collect visibility and alphas as soon as we are composed, even when not visible. val isVisible by viewModel.isVisible.collectAsState() // Collect alphas as soon as we are composed, even when not visible. val alpha by viewModel.alpha.collectAsState() val backgroundAlpha = viewModel.backgroundAlpha.collectAsState() Loading Loading @@ -142,11 +140,6 @@ fun FooterActions( modifier .fillMaxWidth() .graphicsLayer { this.alpha = alpha } .drawWithContent { if (isVisible) { drawContent() } } .then(backgroundModifier) .padding( top = dimensionResource(R.dimen.qs_footer_actions_top_padding), Loading
packages/SystemUI/src/com/android/systemui/qs/QSImpl.java +5 −2 Original line number Diff line number Diff line Loading @@ -170,6 +170,7 @@ public class QSImpl implements QS, CommandQueue.Callbacks, StatusBarStateControl private CommandQueue mCommandQueue; private View mRootView; private View mFooterActionsView; @Inject public QSImpl(RemoteInputQuickSettingsDisabler remoteInputQsDisabler, Loading Loading @@ -285,6 +286,7 @@ public class QSImpl implements QS, CommandQueue.Callbacks, StatusBarStateControl if (!mFeatureFlags.isEnabled(Flags.COMPOSE_QS_FOOTER_ACTIONS) || !ComposeFacade.INSTANCE.isComposeAvailable()) { Log.d(TAG, "Binding the View implementation of the QS footer actions"); mFooterActionsView = footerActionsView; mFooterActionsViewBinder.bind(footerActionsView, mQSFooterActionsViewModel, mListeningAndVisibilityLifecycleOwner); return; Loading @@ -294,6 +296,7 @@ public class QSImpl implements QS, CommandQueue.Callbacks, StatusBarStateControl Log.d(TAG, "Binding the Compose implementation of the QS footer actions"); View composeView = ComposeFacade.INSTANCE.createFooterActionsView(root.getContext(), mQSFooterActionsViewModel, mListeningAndVisibilityLifecycleOwner); mFooterActionsView = composeView; // 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. Loading Loading @@ -472,7 +475,7 @@ public class QSImpl implements QS, CommandQueue.Callbacks, StatusBarStateControl boolean footerVisible = qsPanelVisible && (mQsExpanded || !keyguardShowing || mHeaderAnimating || mShowCollapsedOnKeyguard); mFooter.setVisibility(footerVisible ? View.VISIBLE : View.INVISIBLE); mQSFooterActionsViewModel.onVisibilityChangeRequested(footerVisible); mFooterActionsView.setVisibility(footerVisible ? View.VISIBLE : View.INVISIBLE); mFooter.setExpanded((keyguardShowing && !mHeaderAnimating && !mShowCollapsedOnKeyguard) || (mQsExpanded && !mStackScrollerOverscrolling)); mQSPanelController.setVisibility(qsPanelVisible ? View.VISIBLE : View.INVISIBLE); Loading Loading @@ -856,7 +859,7 @@ public class QSImpl implements QS, CommandQueue.Callbacks, StatusBarStateControl boolean customizing = isCustomizing(); mQSPanelScrollView.setVisibility(!customizing ? View.VISIBLE : View.INVISIBLE); mFooter.setVisibility(!customizing ? View.VISIBLE : View.INVISIBLE); mQSFooterActionsViewModel.onVisibilityChangeRequested(!customizing); mFooterActionsView.setVisibility(!customizing ? View.VISIBLE : View.INVISIBLE); mHeader.setVisibility(!customizing ? View.VISIBLE : View.INVISIBLE); // Let the panel know the position changed and it needs to update where notifications // and whatnot are. Loading
packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt +2 −12 Original line number Diff line number Diff line Loading @@ -24,13 +24,11 @@ import android.view.ViewGroup import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView import androidx.core.view.isInvisible import androidx.core.view.isVisible import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.common.ui.binder.IconViewBinder import com.android.systemui.dagger.SysUISingleton Loading @@ -40,6 +38,7 @@ 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 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.res.R import javax.inject.Inject import kotlin.math.roundToInt import kotlinx.coroutines.launch Loading Loading @@ -98,10 +97,6 @@ class FooterActionsViewBinder @Inject constructor() { var previousForegroundServices: FooterActionsForegroundServicesButtonViewModel? = 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 { val attachedScope = this.lifecycleScope Loading @@ -111,12 +106,7 @@ class FooterActionsViewBinder @Inject constructor() { // TODO(b/242040009): Should this move somewhere else? launch { viewModel.observeDeviceMonitoringDialogRequests(view.context) } // Make sure we set the correct visibility and alpha even when QS are not currently // shown. launch { viewModel.isVisible.collect { isVisible -> view.isInvisible = !isVisible } } // Make sure we set the correct alphas even when QS are not currently shown. launch { viewModel.alpha.collect { view.alpha = it } } launch { viewModel.backgroundAlpha.collect { Loading
packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt +0 −12 Original line number Diff line number Diff line Loading @@ -77,14 +77,6 @@ class FooterActionsViewModel( */ val observeDeviceMonitoringDialogRequests: suspend (quickSettingsContext: Context) -> Unit, ) { /** * Whether the UI rendering this ViewModel should be visible. Note that even when this is false, * the UI should still participate to the layout it is included in (i.e. in the View world it * should be INVISIBLE, not GONE). */ private val _isVisible = MutableStateFlow(false) val isVisible: StateFlow<Boolean> = _isVisible.asStateFlow() /** The alpha the UI rendering this ViewModel should have. */ private val _alpha = MutableStateFlow(1f) val alpha: StateFlow<Float> = _alpha.asStateFlow() Loading @@ -93,10 +85,6 @@ class FooterActionsViewModel( private val _backgroundAlpha = MutableStateFlow(1f) val backgroundAlpha: StateFlow<Float> = _backgroundAlpha.asStateFlow() fun onVisibilityChangeRequested(visible: Boolean) { _isVisible.value = visible } /** Called when the expansion of the Quick Settings changed. */ fun onQuickSettingsExpansionChanged(expansion: Float, isInSplitShade: Boolean) { if (isInSplitShade) { Loading
packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt +0 −12 Original line number Diff line number Diff line Loading @@ -372,18 +372,6 @@ class FooterActionsViewModelTest : SysuiTestCase() { job.cancel() } @Test fun isVisible() { val underTest = utils.footerActionsViewModel() assertThat(underTest.isVisible.value).isFalse() underTest.onVisibilityChangeRequested(visible = true) assertThat(underTest.isVisible.value).isTrue() underTest.onVisibilityChangeRequested(visible = false) assertThat(underTest.isVisible.value).isFalse() } @Test fun alpha_inSplitShade_followsExpansion() { val underTest = utils.footerActionsViewModel() Loading