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

Commit 0180b2f6 authored by Luna Zhang's avatar Luna Zhang Committed by Android (Google) Code Review
Browse files

Merge "Add volume slider to shade" into main

parents ccef0224 66f5c901
Loading
Loading
Loading
Loading
+43 −9
Original line number Diff line number Diff line
@@ -46,6 +46,8 @@ import androidx.compose.ui.layout.onPlaced
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.compose.PlatformSliderDefaults
import com.android.compose.animation.scene.ContentScope
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.UserAction
@@ -80,8 +82,11 @@ import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrim
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape
import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
import com.android.systemui.volume.panel.component.volume.ui.composable.VolumeSlider
import dagger.Lazy
import javax.inject.Inject
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow

@SysUISingleton
@@ -90,7 +95,7 @@ class QuickSettingsShadeOverlay
constructor(
    private val actionsViewModelFactory: QuickSettingsShadeOverlayActionsViewModel.Factory,
    private val contentViewModelFactory: QuickSettingsShadeOverlayContentViewModel.Factory,
    private val quickSettingsContainerViewModelFactory: QuickSettingsContainerViewModel.Factory,
    quickSettingsContainerViewModelFactory: QuickSettingsContainerViewModel.Factory,
    private val notificationStackScrollView: Lazy<NotificationScrollView>,
    private val notificationsPlaceholderViewModelFactory: NotificationsPlaceholderViewModel.Factory,
) : Overlay {
@@ -103,8 +108,19 @@ constructor(

    override val userActions: Flow<Map<UserAction, UserActionResult>> = actionsViewModel.actions

    private val quickSettingsContainerViewModel by lazy {
        quickSettingsContainerViewModelFactory.create(
            supportsBrightnessMirroring = true,
            expansion = COLLAPSED,
        )
    }

    override suspend fun activate(): Nothing {
        actionsViewModel.activate()
        coroutineScope {
            launch { quickSettingsContainerViewModel.activate() }
            launch { actionsViewModel.activate() }
        }
        awaitCancellation()
    }

    @Composable
@@ -113,13 +129,6 @@ constructor(
            rememberViewModel("QuickSettingsShadeOverlayContent") {
                contentViewModelFactory.create()
            }
        val quickSettingsContainerViewModel =
            rememberViewModel("QuickSettingsShadeOverlayContainer") {
                quickSettingsContainerViewModelFactory.create(
                    supportsBrightnessMirroring = true,
                    expansion = COLLAPSED,
                )
            }
        val hunPlaceholderViewModel =
            rememberViewModel("QuickSettingsShadeOverlayPlaceholder") {
                notificationsPlaceholderViewModelFactory.create()
@@ -278,6 +287,31 @@ fun ContentScope.QuickSettingsLayout(
                )
            }

            val volumeSliderViewModel = viewModel.volumeSliderViewModel
            if (volumeSliderViewModel != null) {
                val volumeSliderState by volumeSliderViewModel.slider.collectAsStateWithLifecycle()

                Box(
                    Modifier.systemGestureExclusionInShade(
                        enabled = { layoutState.transitionState is TransitionState.Idle }
                    )
                ) {
                    VolumeSlider(
                        modifier = Modifier.fillMaxWidth(),
                        showLabel = false,
                        state = volumeSliderState,
                        onValueChange = { newValue: Float ->
                            volumeSliderViewModel.onValueChanged(volumeSliderState, newValue)
                        },
                        onValueChangeFinished = { volumeSliderViewModel.onValueChangeFinished() },
                        onIconTapped = { volumeSliderViewModel.toggleMuted(volumeSliderState) },
                        sliderColors = PlatformSliderDefaults.defaultPlatformSliderColors(),
                        hapticsViewModelFactory =
                            volumeSliderViewModel.getSliderHapticsViewModelFactory(),
                    )
                }
            }

            Box {
                GridAnchor()
                TileGrid(
+9 −6
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ fun VolumeSlider(
    hapticsViewModelFactory: SliderHapticsViewModel.Factory?,
    onValueChangeFinished: (() -> Unit)? = null,
    button: (@Composable RowScope.() -> Unit)? = null,
    showLabel: Boolean = true,
) {
    if (!Flags.volumeRedesign()) {
        LegacyVolumeSlider(
@@ -114,12 +115,14 @@ fun VolumeSlider(
    }

    Column(modifier = modifier.animateContentSize()) {
        if (showLabel) {
            Text(
                text = state.label,
                style = MaterialTheme.typography.titleMedium,
                color = MaterialTheme.colorScheme.onSurface,
                modifier = Modifier.fillMaxWidth().clearAndSetSemantics {},
            )
        }
        Row(
            horizontalArrangement = Arrangement.spacedBy(8.dp),
            modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp),
+30 −1
Original line number Diff line number Diff line
@@ -16,7 +16,10 @@

package com.android.systemui.qs.ui.viewmodel

import android.content.Context
import android.media.AudioManager
import androidx.compose.runtime.getValue
import com.android.settingslib.volume.shared.model.AudioStream
import com.android.systemui.brightness.ui.viewmodel.BrightnessSliderViewModel
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
@@ -24,11 +27,16 @@ import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarou
import com.android.systemui.media.controls.ui.controller.MediaCarouselController
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.dagger.MediaModule
import com.android.systemui.qs.flags.QsDetailedView
import com.android.systemui.qs.panels.ui.viewmodel.DetailsViewModel
import com.android.systemui.qs.panels.ui.viewmodel.EditModeViewModel
import com.android.systemui.qs.panels.ui.viewmodel.TileGridViewModel
import com.android.systemui.qs.panels.ui.viewmodel.toolbar.ToolbarViewModel
import com.android.systemui.res.R
import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel
import com.android.systemui.volume.panel.component.volume.domain.model.SliderType
import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.AudioStreamSliderViewModel
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@@ -40,10 +48,12 @@ import kotlinx.coroutines.launch
class QuickSettingsContainerViewModel
@AssistedInject
constructor(
    @ShadeDisplayAware shadeContext: Context,
    brightnessSliderViewModelFactory: BrightnessSliderViewModel.Factory,
    private val audioStreamSliderViewModelFactory: AudioStreamSliderViewModel.Factory,
    shadeHeaderViewModelFactory: ShadeHeaderViewModel.Factory,
    tileGridViewModelFactory: TileGridViewModel.Factory,
    @Assisted supportsBrightnessMirroring: Boolean,
    @Assisted private val supportsBrightnessMirroring: Boolean,
    @Assisted private val expansion: Float?,
    val editModeViewModel: EditModeViewModel,
    val detailsViewModel: DetailsViewModel,
@@ -58,6 +68,12 @@ constructor(
    val brightnessSliderViewModel =
        brightnessSliderViewModelFactory.create(supportsBrightnessMirroring)

    private val showVolumeSlider =
        QsDetailedView.isEnabled &&
            shadeContext.resources.getBoolean(R.bool.config_enableDesktopAudioTileDetailsView)

    var volumeSliderViewModel: AudioStreamSliderViewModel? = null

    val toolbarViewModel = toolbarViewModelFactory.create()

    val shadeHeaderViewModel = shadeHeaderViewModelFactory.create()
@@ -72,6 +88,19 @@ constructor(

    override suspend fun onActivated(): Nothing {
        coroutineScope {
            if (showVolumeSlider) {
                val volumeSliderStream =
                    SliderType.Stream(AudioStream(AudioManager.STREAM_MUSIC)).stream
                launch {
                    volumeSliderViewModel =
                        audioStreamSliderViewModelFactory.create(
                            AudioStreamSliderViewModel.FactoryAudioStreamWrapper(
                                volumeSliderStream
                            ),
                            this,
                        )
                }
            }
            expansion?.let { mediaHost.expansion = it }
            launch { hydrator.activate() }
            launch { brightnessSliderViewModel.activate() }
+4 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.qs.ui.viewmodel

import android.content.applicationContext
import com.android.systemui.brightness.ui.viewmodel.brightnessSliderViewModelFactory
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
@@ -26,6 +27,7 @@ import com.android.systemui.qs.panels.ui.viewmodel.editModeViewModel
import com.android.systemui.qs.panels.ui.viewmodel.tileGridViewModelFactory
import com.android.systemui.qs.panels.ui.viewmodel.toolbar.toolbarViewModelFactory
import com.android.systemui.shade.ui.viewmodel.shadeHeaderViewModelFactory
import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.audioStreamSliderViewModelFactory
import org.mockito.kotlin.mock

val Kosmos.quickSettingsContainerViewModelFactory by
@@ -36,7 +38,9 @@ val Kosmos.quickSettingsContainerViewModelFactory by
                expansion: Float?,
            ): QuickSettingsContainerViewModel {
                return QuickSettingsContainerViewModel(
                    shadeContext = applicationContext,
                    brightnessSliderViewModelFactory = brightnessSliderViewModelFactory,
                    audioStreamSliderViewModelFactory = audioStreamSliderViewModelFactory,
                    shadeHeaderViewModelFactory = shadeHeaderViewModelFactory,
                    tileGridViewModelFactory = tileGridViewModelFactory,
                    supportsBrightnessMirroring = supportsBrightnessMirroring,