1 /*
2  * 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.settings.notification
18 
19 import android.content.Context
20 import android.media.AudioManager
21 import android.media.AudioManager.STREAM_BLUETOOTH_SCO
22 import android.media.AudioManager.STREAM_VOICE_CALL
23 import android.os.UserManager
24 import androidx.preference.Preference
25 import com.android.settings.PreferenceRestrictionMixin
26 import com.android.settings.R
27 import com.android.settingslib.datastore.KeyValueStore
28 import com.android.settingslib.datastore.NoOpKeyedObservable
29 import com.android.settingslib.metadata.PersistentPreference
30 import com.android.settingslib.metadata.PreferenceAvailabilityProvider
31 import com.android.settingslib.metadata.PreferenceIconProvider
32 import com.android.settingslib.metadata.PreferenceMetadata
33 import com.android.settingslib.metadata.RangeValue
34 import com.android.settingslib.metadata.ReadWritePermit
35 import com.android.settingslib.metadata.SensitivityLevel
36 import com.android.settingslib.preference.PreferenceBinding
37 
38 // LINT.IfChange
39 open class CallVolumePreference :
40     PreferenceMetadata,
41     PreferenceBinding,
42     PersistentPreference<Int>,
43     RangeValue,
44     PreferenceAvailabilityProvider,
45     PreferenceIconProvider,
46     PreferenceRestrictionMixin {
47     override val key: String
48         get() = KEY
49 
50     override val title: Int
51         get() = R.string.call_volume_option_title
52 
getIconnull53     override fun getIcon(context: Context) = R.drawable.ic_local_phone_24_lib
54 
55     override fun isAvailable(context: Context) =
56         context.resources.getBoolean(R.bool.config_show_call_volume) &&
57             !createAudioHelper(context).isSingleVolume
58 
59     override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context)
60 
61     override val restrictionKeys
62         get() = arrayOf(UserManager.DISALLOW_ADJUST_VOLUME)
63 
64     override fun storage(context: Context): KeyValueStore {
65         val helper = createAudioHelper(context)
66         return object : NoOpKeyedObservable<String>(), KeyValueStore {
67             override fun contains(key: String) = key == KEY
68 
69             @Suppress("UNCHECKED_CAST")
70             override fun <T : Any> getValue(key: String, valueType: Class<T>) =
71                 helper.getStreamVolume(getAudioStream(context)) as T
72 
73             override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) {
74                 helper.setStreamVolume(getAudioStream(context), value as Int)
75             }
76         }
77     }
78 
getReadPermitnull79     override fun getReadPermit(context: Context, myUid: Int, callingUid: Int) =
80         ReadWritePermit.ALLOW
81 
82     override fun getWritePermit(context: Context, value: Int?, myUid: Int, callingUid: Int) =
83         ReadWritePermit.ALLOW
84 
85     override val sensitivityLevel
86         get() = SensitivityLevel.NO_SENSITIVITY
87 
88     override fun getMinValue(context: Context) =
89         createAudioHelper(context).getMinVolume(getAudioStream(context))
90 
91     override fun getMaxValue(context: Context) =
92         createAudioHelper(context).getMaxVolume(getAudioStream(context))
93 
94     override fun createWidget(context: Context) = VolumeSeekBarPreference(context)
95 
96     override fun bind(preference: Preference, metadata: PreferenceMetadata) {
97         super.bind(preference, metadata)
98         (preference as VolumeSeekBarPreference).setStream(getAudioStream(preference.context))
99     }
100 
createAudioHelpernull101     open fun createAudioHelper(context: Context) = AudioHelper(context)
102 
103     @Suppress("DEPRECATION")
104     fun getAudioStream(context: Context): Int {
105         val audioManager = context.getSystemService(AudioManager::class.java)
106         return when {
107             audioManager.isBluetoothScoOn() -> STREAM_BLUETOOTH_SCO
108             else -> STREAM_VOICE_CALL
109         }
110     }
111 
112     companion object {
113         const val KEY = "call_volume"
114     }
115 }
116 // LINT.ThenChange(CallVolumePreferenceController.java)
117