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

Commit e9ae9f2c authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add toast and timeout logic in ringer" into main

parents 44c19845 0cd1b994
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.volume.dialog.dagger

import com.android.systemui.volume.dialog.dagger.module.VolumeDialogModule
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderComponent
@@ -28,7 +29,7 @@ import kotlinx.coroutines.CoroutineScope
 * [com.android.systemui.volume.dialog.VolumeDialogPlugin] and lives alongside it.
 */
@VolumeDialogScope
@Subcomponent(modules = [])
@Subcomponent(modules = [VolumeDialogModule::class])
interface VolumeDialogComponent {

    /**
+32 −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.dagger.module

import com.android.systemui.volume.dialog.ringer.data.repository.VolumeDialogRingerFeedbackRepository
import com.android.systemui.volume.dialog.ringer.data.repository.VolumeDialogRingerFeedbackRepositoryImpl
import dagger.Binds
import dagger.Module

/** Dagger module for volume dialog code in the volume package */
@Module
interface VolumeDialogModule {

    @Binds
    fun bindVolumeDialogRingerFeedbackRepository(
        ringerFeedbackRepository: VolumeDialogRingerFeedbackRepositoryImpl
    ): VolumeDialogRingerFeedbackRepository
}
+57 −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.ringer.data.repository

import android.content.Context
import com.android.systemui.Prefs
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext

interface VolumeDialogRingerFeedbackRepository {

    /** gets number of shown toasts */
    suspend fun getToastCount(): Int

    /** updates number of shown toasts */
    suspend fun updateToastCount(toastCount: Int)
}

class VolumeDialogRingerFeedbackRepositoryImpl
@Inject
constructor(
    @Application private val applicationContext: Context,
    @Background val backgroundDispatcher: CoroutineDispatcher,
) : VolumeDialogRingerFeedbackRepository {

    override suspend fun getToastCount(): Int =
        withContext(backgroundDispatcher) {
            return@withContext Prefs.getInt(
                applicationContext,
                Prefs.Key.SEEN_RINGER_GUIDANCE_COUNT,
                0,
            )
        }

    override suspend fun updateToastCount(toastCount: Int) {
        withContext(backgroundDispatcher) {
            Prefs.putInt(applicationContext, Prefs.Key.SEEN_RINGER_GUIDANCE_COUNT, toastCount + 1)
        }
    }
}
+10 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.settingslib.volume.shared.model.RingerMode
import com.android.systemui.plugins.VolumeDialogController
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog
import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogStateInteractor
import com.android.systemui.volume.dialog.ringer.data.repository.VolumeDialogRingerFeedbackRepository
import com.android.systemui.volume.dialog.ringer.shared.model.VolumeDialogRingerModel
import com.android.systemui.volume.dialog.shared.model.VolumeDialogStateModel
import javax.inject.Inject
@@ -45,6 +46,7 @@ constructor(
    volumeDialogStateInteractor: VolumeDialogStateInteractor,
    private val controller: VolumeDialogController,
    private val audioSystemRepository: AudioSystemRepository,
    private val ringerFeedbackRepository: VolumeDialogRingerFeedbackRepository,
) {

    val ringerModel: Flow<VolumeDialogRingerModel> =
@@ -84,4 +86,12 @@ constructor(
    fun scheduleTouchFeedback() {
        controller.scheduleTouchFeedback()
    }

    suspend fun getToastCount(): Int {
        return ringerFeedbackRepository.getToastCount()
    }

    suspend fun updateToastCount(toastCount: Int) {
        ringerFeedbackRepository.updateToastCount(toastCount)
    }
}
+59 −0
Original line number Diff line number Diff line
@@ -16,17 +16,23 @@

package com.android.systemui.volume.dialog.ringer.ui.viewmodel

import android.content.Context
import android.media.AudioAttributes
import android.media.AudioManager.RINGER_MODE_NORMAL
import android.media.AudioManager.RINGER_MODE_SILENT
import android.media.AudioManager.RINGER_MODE_VIBRATE
import android.os.VibrationEffect
import android.widget.Toast
import com.android.internal.R as internalR
import com.android.settingslib.Utils
import com.android.settingslib.volume.shared.model.RingerMode
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.res.R
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.volume.Events
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog
import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogVisibilityInteractor
import com.android.systemui.volume.dialog.ringer.domain.VolumeDialogRingerInteractor
import com.android.systemui.volume.dialog.ringer.shared.model.VolumeDialogRingerModel
import com.android.systemui.volume.dialog.shared.VolumeDialogLogger
@@ -40,26 +46,37 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch

private const val SHOW_RINGER_TOAST_COUNT = 12

class VolumeDialogRingerDrawerViewModel
@AssistedInject
constructor(
    @Application private val applicationContext: Context,
    @VolumeDialog private val coroutineScope: CoroutineScope,
    @Background private val backgroundDispatcher: CoroutineDispatcher,
    private val interactor: VolumeDialogRingerInteractor,
    private val vibrator: VibratorHelper,
    private val volumeDialogLogger: VolumeDialogLogger,
    private val visibilityInteractor: VolumeDialogVisibilityInteractor,
) {

    private val drawerState = MutableStateFlow<RingerDrawerState>(RingerDrawerState.Initial)

    val ringerViewModel: StateFlow<RingerViewModelState> =
        combine(interactor.ringerModel, drawerState) { ringerModel, state ->
                level = ringerModel.level
                levelMax = ringerModel.levelMax
                ringerModel.toViewModel(state)
            }
            .flowOn(backgroundDispatcher)
            .stateIn(coroutineScope, SharingStarted.Eagerly, RingerViewModelState.Unavailable)

    // Level and Maximum level of Ring Stream.
    private var level = -1
    private var levelMax = -1

    // Vibration attributes.
    private val sonificiationVibrationAttributes =
        AudioAttributes.Builder()
@@ -71,8 +88,10 @@ constructor(
        if (drawerState.value is RingerDrawerState.Open) {
            Events.writeEvent(Events.EVENT_RINGER_TOGGLE, ringerMode.value)
            provideTouchFeedback(ringerMode)
            maybeShowToast(ringerMode)
            interactor.setRingerMode(ringerMode)
        }
        visibilityInteractor.resetDismissTimeout()
        drawerState.value =
            when (drawerState.value) {
                is RingerDrawerState.Initial -> {
@@ -201,6 +220,46 @@ constructor(
        }
    }

    private fun maybeShowToast(ringerMode: RingerMode) {
        coroutineScope.launch {
            val seenToastCount = interactor.getToastCount()
            if (seenToastCount > SHOW_RINGER_TOAST_COUNT) {
                return@launch
            }

            val toastText =
                when (ringerMode.value) {
                    RINGER_MODE_NORMAL -> {
                        if (level != -1 && levelMax != -1) {
                            applicationContext.getString(
                                R.string.volume_dialog_ringer_guidance_ring,
                                Utils.formatPercentage(level.toLong(), levelMax.toLong()),
                            )
                        } else {
                            null
                        }
                    }

                    RINGER_MODE_SILENT ->
                        applicationContext.getString(
                            internalR.string.volume_dialog_ringer_guidance_silent
                        )

                    RINGER_MODE_VIBRATE ->
                        applicationContext.getString(
                            internalR.string.volume_dialog_ringer_guidance_vibrate
                        )

                    else ->
                        applicationContext.getString(
                            internalR.string.volume_dialog_ringer_guidance_vibrate
                        )
                }
            toastText?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_SHORT).show() }
            interactor.updateToastCount(seenToastCount)
        }
    }

    @AssistedFactory
    interface Factory {
        fun create(): VolumeDialogRingerDrawerViewModel
Loading