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.STREAM_MUSIC 21 import android.os.UserManager 22 import androidx.preference.Preference 23 import com.android.settings.PreferenceRestrictionMixin 24 import com.android.settings.R 25 import com.android.settingslib.datastore.KeyValueStore 26 import com.android.settingslib.datastore.NoOpKeyedObservable 27 import com.android.settingslib.metadata.PersistentPreference 28 import com.android.settingslib.metadata.PreferenceAvailabilityProvider 29 import com.android.settingslib.metadata.PreferenceIconProvider 30 import com.android.settingslib.metadata.PreferenceMetadata 31 import com.android.settingslib.metadata.RangeValue 32 import com.android.settingslib.metadata.ReadWritePermit 33 import com.android.settingslib.metadata.SensitivityLevel 34 import com.android.settingslib.preference.PreferenceBinding 35 36 // LINT.IfChange 37 open class MediaVolumePreference : 38 PreferenceMetadata, 39 PreferenceBinding, 40 PersistentPreference<Int>, 41 RangeValue, 42 PreferenceAvailabilityProvider, 43 PreferenceIconProvider, 44 PreferenceRestrictionMixin { 45 override val key: String 46 get() = KEY 47 48 override val title: Int 49 get() = R.string.media_volume_option_title 50 getIconnull51 override fun getIcon(context: Context) = 52 when { 53 VolumeHelper.isMuted(context, STREAM_MUSIC) -> R.drawable.ic_media_stream_off 54 else -> R.drawable.ic_media_stream 55 } 56 isAvailablenull57 override fun isAvailable(context: Context) = 58 context.resources.getBoolean(R.bool.config_show_media_volume) 59 60 override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context) 61 62 override val restrictionKeys 63 get() = arrayOf(UserManager.DISALLOW_ADJUST_VOLUME) 64 65 override fun storage(context: Context): KeyValueStore { 66 val helper = createAudioHelper(context) 67 return object : NoOpKeyedObservable<String>(), KeyValueStore { 68 override fun contains(key: String) = key == KEY 69 70 @Suppress("UNCHECKED_CAST") 71 override fun <T : Any> getValue(key: String, valueType: Class<T>) = 72 helper.getStreamVolume(STREAM_MUSIC) as T 73 74 override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) { 75 helper.setStreamVolume(STREAM_MUSIC, value as Int) 76 } 77 } 78 } 79 getReadPermitnull80 override fun getReadPermit(context: Context, myUid: Int, callingUid: Int) = 81 ReadWritePermit.ALLOW 82 83 override fun getWritePermit(context: Context, value: Int?, myUid: Int, callingUid: Int) = 84 ReadWritePermit.ALLOW 85 86 override val sensitivityLevel 87 get() = SensitivityLevel.NO_SENSITIVITY 88 89 override fun getMinValue(context: Context) = 90 createAudioHelper(context).getMinVolume(STREAM_MUSIC) 91 92 override fun getMaxValue(context: Context) = 93 createAudioHelper(context).getMaxVolume(STREAM_MUSIC) 94 95 override fun createWidget(context: Context) = VolumeSeekBarPreference(context) 96 97 override fun bind(preference: Preference, metadata: PreferenceMetadata) { 98 super.bind(preference, metadata) 99 (preference as VolumeSeekBarPreference).apply { 100 setStream(STREAM_MUSIC) 101 setMuteIcon(R.drawable.ic_media_stream_off) 102 setListener { updateContentDescription(this) } 103 } 104 } 105 createAudioHelpernull106 open fun createAudioHelper(context: Context) = AudioHelper(context) 107 108 private fun updateContentDescription(preference: VolumeSeekBarPreference) { 109 when { 110 preference.isMuted -> 111 preference.updateContentDescription( 112 preference.context.getString( 113 R.string.volume_content_description_silent_mode, 114 preference.title, 115 ) 116 ) 117 else -> preference.updateContentDescription(preference.title) 118 } 119 } 120 121 companion object { 122 const val KEY = "media_volume" 123 } 124 } 125 // LINT.ThenChange(MediaVolumePreferenceController.java) 126