1 /*
<lambda>null2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *       http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */
16 
17 package com.android.settingslib.statusbar.notification.domain.interactor
18 
19 import android.app.NotificationManager
20 import android.media.AudioManager
21 import android.provider.Settings
22 import android.service.notification.ZenModeConfig
23 import com.android.settingslib.statusbar.notification.data.model.ZenMode
24 import com.android.settingslib.statusbar.notification.data.repository.NotificationsSoundPolicyRepository
25 import com.android.settingslib.volume.shared.model.AudioStream
26 import kotlinx.coroutines.flow.Flow
27 import kotlinx.coroutines.flow.StateFlow
28 import kotlinx.coroutines.flow.combine
29 import kotlinx.coroutines.flow.filterNotNull
30 import kotlinx.coroutines.flow.map
31 
32 /** Determines notification sounds state and limitations. */
33 class NotificationsSoundPolicyInteractor(
34     private val repository: NotificationsSoundPolicyRepository
35 ) {
36 
37     /** @see NotificationManager.getNotificationPolicy */
38     val notificationPolicy: StateFlow<NotificationManager.Policy?>
39         get() = repository.notificationPolicy
40 
41     /** @see NotificationManager.getZenMode */
42     val zenMode: StateFlow<ZenMode?>
43         get() = repository.zenMode
44 
45     /** Checks if [notificationPolicy] allows alarms. */
46     val areAlarmsAllowed: Flow<Boolean?> = notificationPolicy.map { it?.allowAlarms() }
47 
48     /** Checks if [notificationPolicy] allows media. */
49     val isMediaAllowed: Flow<Boolean?> = notificationPolicy.map { it?.allowMedia() }
50 
51     /** Checks if [notificationPolicy] allows system sounds. */
52     val isSystemAllowed: Flow<Boolean?> = notificationPolicy.map { it?.allowSystem() }
53 
54     /** Checks if [notificationPolicy] allows ringer. */
55     val isRingerAllowed: Flow<Boolean?> =
56         notificationPolicy.map { policy ->
57             policy ?: return@map null
58             !ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(policy)
59         }
60 
61     /** Checks if the [stream] is muted by either [zenMode] or [notificationPolicy]. */
62     fun isZenMuted(stream: AudioStream): Flow<Boolean> {
63         return combine(
64             zenMode.filterNotNull(),
65             areAlarmsAllowed.filterNotNull(),
66             isMediaAllowed.filterNotNull(),
67             isRingerAllowed.filterNotNull(),
68             isSystemAllowed.filterNotNull(),
69         ) { zenMode, areAlarmsAllowed, isMediaAllowed, isRingerAllowed, isSystemAllowed ->
70             when (zenMode.zenMode) {
71                 // Everything is muted
72                 Settings.Global.ZEN_MODE_NO_INTERRUPTIONS -> return@combine true
73                 Settings.Global.ZEN_MODE_ALARMS ->
74                     return@combine stream.value == AudioManager.STREAM_RING ||
75                         stream.value == AudioManager.STREAM_NOTIFICATION ||
76                         stream.value == AudioManager.STREAM_SYSTEM
77                 Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS -> {
78                     when {
79                         stream.value == AudioManager.STREAM_ALARM && !areAlarmsAllowed ->
80                             return@combine true
81                         stream.value == AudioManager.STREAM_MUSIC && !isMediaAllowed ->
82                             return@combine true
83                         stream.value == AudioManager.STREAM_SYSTEM && !isSystemAllowed ->
84                             return@combine true
85                         (stream.value == AudioManager.STREAM_RING ||
86                             stream.value == AudioManager.STREAM_NOTIFICATION) && !isRingerAllowed ->
87                             return@combine true
88                     }
89                 }
90             }
91             return@combine false
92         }
93     }
94 }
95