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

Commit 0544b34c authored by Anton Potapov's avatar Anton Potapov Committed by Android (Google) Code Review
Browse files

Merge "Add show-hide animations for the new Volume Dialog" into main

parents 1505c5ce 684d86ce
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.fakeVolumeDialogController
import com.android.systemui.testKosmos
import com.android.systemui.volume.Events
import com.android.systemui.volume.dialog.domain.model.VolumeDialogVisibilityModel
import com.android.systemui.volume.dialog.shared.model.VolumeDialogVisibilityModel
import com.google.common.truth.Truth.assertThat
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.seconds
+8 −1
Original line number Diff line number Diff line
@@ -17,6 +17,13 @@
package com.android.systemui.volume.dialog.dagger.module

import com.android.systemui.volume.dialog.dagger.VolumeDialogComponent
import com.android.systemui.volume.dialog.utils.VolumeTracer
import com.android.systemui.volume.dialog.utils.VolumeTracerImpl
import dagger.Binds
import dagger.Module

@Module(subcomponents = [VolumeDialogComponent::class]) interface VolumeDialogPluginModule
@Module(subcomponents = [VolumeDialogComponent::class])
interface VolumeDialogPluginModule {

    @Binds fun bindVolumeTracer(volumeTracer: VolumeTracerImpl): VolumeTracer
}
+39 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.volume.dialog.data

import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.volume.dialog.shared.model.VolumeDialogVisibilityModel
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update

@SysUISingleton
class VolumeDialogVisibilityRepository @Inject constructor() {

    private val mutableDialogVisibility =
        MutableStateFlow<VolumeDialogVisibilityModel>(VolumeDialogVisibilityModel.Invisible)
    val dialogVisibility: Flow<VolumeDialogVisibilityModel> = mutableDialogVisibility.asStateFlow()

    fun updateVisibility(
        update: (current: VolumeDialogVisibilityModel) -> VolumeDialogVisibilityModel
    ) {
        mutableDialogVisibility.update(update)
    }
}
+32 −17
Original line number Diff line number Diff line
@@ -20,8 +20,12 @@ import android.annotation.SuppressLint
import com.android.systemui.volume.Events
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPlugin
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPluginScope
import com.android.systemui.volume.dialog.data.VolumeDialogVisibilityRepository
import com.android.systemui.volume.dialog.domain.model.VolumeDialogEventModel
import com.android.systemui.volume.dialog.domain.model.VolumeDialogVisibilityModel
import com.android.systemui.volume.dialog.shared.model.VolumeDialogVisibilityModel
import com.android.systemui.volume.dialog.shared.model.VolumeDialogVisibilityModel.Dismissed
import com.android.systemui.volume.dialog.shared.model.VolumeDialogVisibilityModel.Visible
import com.android.systemui.volume.dialog.utils.VolumeTracer
import javax.inject.Inject
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds
@@ -30,13 +34,11 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.update

private val MAX_DIALOG_SHOW_TIME: Duration = 3.seconds

@@ -53,14 +55,13 @@ class VolumeDialogVisibilityInteractor
constructor(
    @VolumeDialogPlugin coroutineScope: CoroutineScope,
    callbacksInteractor: VolumeDialogCallbacksInteractor,
    private val tracer: VolumeTracer,
    private val repository: VolumeDialogVisibilityRepository,
) {

    @SuppressLint("SharedFlowCreation")
    private val mutableDismissDialogEvents = MutableSharedFlow<Unit>()
    private val mutableDialogVisibility =
        MutableStateFlow<VolumeDialogVisibilityModel>(VolumeDialogVisibilityModel.Invisible)

    val dialogVisibility: Flow<VolumeDialogVisibilityModel> = mutableDialogVisibility.asStateFlow()
    val dialogVisibility: Flow<VolumeDialogVisibilityModel> = repository.dialogVisibility

    init {
        merge(
@@ -70,14 +71,13 @@ constructor(
                },
                callbacksInteractor.event,
            )
            .onEach { event ->
                VolumeDialogVisibilityModel.fromEvent(event)?.let { model ->
                    mutableDialogVisibility.value = model
            .mapNotNull { it.toVisibilityModel() }
            .onEach { model ->
                updateVisibility { model }
                if (model is VolumeDialogVisibilityModel.Visible) {
                    resetDismissTimeout()
                }
            }
            }
            .launchIn(coroutineScope)
    }

@@ -86,9 +86,9 @@ constructor(
     * [dialogVisibility].
     */
    fun dismissDialog(reason: Int) {
        mutableDialogVisibility.update {
            if (it is VolumeDialogVisibilityModel.Dismissed) {
                it
        updateVisibility { visibilityModel ->
            if (visibilityModel is VolumeDialogVisibilityModel.Dismissed) {
                visibilityModel
            } else {
                VolumeDialogVisibilityModel.Dismissed(reason)
            }
@@ -99,4 +99,19 @@ constructor(
    suspend fun resetDismissTimeout() {
        mutableDismissDialogEvents.emit(Unit)
    }

    private fun updateVisibility(
        update: (VolumeDialogVisibilityModel) -> VolumeDialogVisibilityModel
    ) {
        repository.updateVisibility { update(it).also(tracer::traceVisibilityStart) }
    }

    private fun VolumeDialogEventModel.toVisibilityModel(): VolumeDialogVisibilityModel? {
        return when (this) {
            is VolumeDialogEventModel.DismissRequested -> Dismissed(reason)
            is VolumeDialogEventModel.ShowRequested ->
                Visible(reason, keyguardLocked, lockTaskModeState)
            else -> null
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ import com.android.systemui.volume.Events
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogVisibilityInteractor
import com.android.systemui.volume.dialog.domain.model.VolumeDialogVisibilityModel
import com.android.systemui.volume.dialog.shared.model.VolumeDialogVisibilityModel
import com.android.systemui.volume.panel.domain.interactor.VolumePanelGlobalStateInteractor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
Loading