1 /* 2 * Copyright (C) 2006 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.server.audio; 18 19 import static android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED; 20 import static android.Manifest.permission.REMOTE_AUDIO_PLAYBACK; 21 import static android.app.BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT; 22 import static android.media.AudioDeviceInfo.TYPE_BLE_HEADSET; 23 import static android.media.AudioDeviceInfo.TYPE_BLE_SPEAKER; 24 import static android.media.AudioDeviceInfo.TYPE_BLUETOOTH_A2DP; 25 import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES; 26 import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_UNKNOWN; 27 import static android.media.AudioManager.DEVICE_OUT_BLE_HEADSET; 28 import static android.media.AudioManager.DEVICE_OUT_BLE_SPEAKER; 29 import static android.media.AudioManager.DEVICE_OUT_BLUETOOTH_A2DP; 30 import static android.media.AudioManager.RINGER_MODE_NORMAL; 31 import static android.media.AudioManager.RINGER_MODE_SILENT; 32 import static android.media.AudioManager.RINGER_MODE_VIBRATE; 33 import static android.media.AudioManager.STREAM_MUSIC; 34 import static android.media.AudioManager.STREAM_SYSTEM; 35 import static android.os.Process.FIRST_APPLICATION_UID; 36 import static android.os.Process.INVALID_UID; 37 import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE; 38 import static android.provider.Settings.Secure.VOLUME_HUSH_OFF; 39 import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE; 40 41 import static com.android.server.audio.SoundDoseHelper.ACTION_CHECK_MUSIC_ACTIVE; 42 import static com.android.server.utils.EventLogger.Event.ALOGE; 43 import static com.android.server.utils.EventLogger.Event.ALOGI; 44 import static com.android.server.utils.EventLogger.Event.ALOGW; 45 46 import android.Manifest; 47 import android.annotation.IntDef; 48 import android.annotation.IntRange; 49 import android.annotation.NonNull; 50 import android.annotation.Nullable; 51 import android.annotation.RequiresPermission; 52 import android.annotation.SuppressLint; 53 import android.annotation.UserIdInt; 54 import android.app.ActivityManager; 55 import android.app.ActivityManagerInternal; 56 import android.app.AppGlobals; 57 import android.app.AppOpsManager; 58 import android.app.BroadcastOptions; 59 import android.app.IUidObserver; 60 import android.app.NotificationManager; 61 import android.app.UidObserver; 62 import android.app.role.OnRoleHoldersChangedListener; 63 import android.app.role.RoleManager; 64 import android.bluetooth.BluetoothDevice; 65 import android.bluetooth.BluetoothHeadset; 66 import android.bluetooth.BluetoothProfile; 67 import android.content.BroadcastReceiver; 68 import android.content.ComponentName; 69 import android.content.ContentResolver; 70 import android.content.Context; 71 import android.content.Intent; 72 import android.content.IntentFilter; 73 import android.content.pm.ApplicationInfo; 74 import android.content.pm.PackageInfo; 75 import android.content.pm.PackageManager; 76 import android.content.pm.ResolveInfo; 77 import android.content.pm.UserInfo; 78 import android.content.res.Configuration; 79 import android.content.res.Resources; 80 import android.database.ContentObserver; 81 import android.hardware.SensorPrivacyManager; 82 import android.hardware.SensorPrivacyManagerInternal; 83 import android.hardware.hdmi.HdmiAudioSystemClient; 84 import android.hardware.hdmi.HdmiClient; 85 import android.hardware.hdmi.HdmiControlManager; 86 import android.hardware.hdmi.HdmiPlaybackClient; 87 import android.hardware.hdmi.HdmiTvClient; 88 import android.hardware.input.InputManager; 89 import android.hardware.usb.UsbManager; 90 import android.hidl.manager.V1_0.IServiceManager; 91 import android.media.AudioAttributes; 92 import android.media.AudioAttributes.AttributeSystemUsage; 93 import android.media.AudioDeviceAttributes; 94 import android.media.AudioDeviceInfo; 95 import android.media.AudioDeviceVolumeManager; 96 import android.media.AudioFocusInfo; 97 import android.media.AudioFocusRequest; 98 import android.media.AudioFormat; 99 import android.media.AudioHalVersionInfo; 100 import android.media.AudioManager; 101 import android.media.AudioManager.AudioDeviceCategory; 102 import android.media.AudioManagerInternal; 103 import android.media.AudioMixerAttributes; 104 import android.media.AudioPlaybackConfiguration; 105 import android.media.AudioRecordingConfiguration; 106 import android.media.AudioRoutesInfo; 107 import android.media.AudioSystem; 108 import android.media.BluetoothProfileConnectionInfo; 109 import android.media.IAudioDeviceVolumeDispatcher; 110 import android.media.IAudioFocusDispatcher; 111 import android.media.IAudioModeDispatcher; 112 import android.media.IAudioRoutesObserver; 113 import android.media.IAudioServerStateDispatcher; 114 import android.media.IAudioService; 115 import android.media.ICapturePresetDevicesRoleDispatcher; 116 import android.media.ICommunicationDeviceDispatcher; 117 import android.media.IDeviceVolumeBehaviorDispatcher; 118 import android.media.IDevicesForAttributesCallback; 119 import android.media.IMuteAwaitConnectionCallback; 120 import android.media.IPlaybackConfigDispatcher; 121 import android.media.IPreferredMixerAttributesDispatcher; 122 import android.media.IRecordingConfigDispatcher; 123 import android.media.IRingtonePlayer; 124 import android.media.ISpatializerCallback; 125 import android.media.ISpatializerHeadToSoundStagePoseCallback; 126 import android.media.ISpatializerHeadTrackerAvailableCallback; 127 import android.media.ISpatializerHeadTrackingModeCallback; 128 import android.media.ISpatializerOutputCallback; 129 import android.media.IStrategyNonDefaultDevicesDispatcher; 130 import android.media.IStrategyPreferredDevicesDispatcher; 131 import android.media.IStreamAliasingDispatcher; 132 import android.media.IVolumeController; 133 import android.media.MediaMetrics; 134 import android.media.MediaRecorder.AudioSource; 135 import android.media.PlayerBase; 136 import android.media.Spatializer; 137 import android.media.VolumeInfo; 138 import android.media.VolumePolicy; 139 import android.media.audiofx.AudioEffect; 140 import android.media.audiopolicy.AudioMix; 141 import android.media.audiopolicy.AudioPolicy; 142 import android.media.audiopolicy.AudioPolicyConfig; 143 import android.media.audiopolicy.AudioProductStrategy; 144 import android.media.audiopolicy.AudioVolumeGroup; 145 import android.media.audiopolicy.IAudioPolicyCallback; 146 import android.media.permission.ClearCallingIdentityContext; 147 import android.media.permission.SafeCloseable; 148 import android.media.projection.IMediaProjection; 149 import android.media.projection.IMediaProjectionCallback; 150 import android.media.projection.IMediaProjectionManager; 151 import android.net.Uri; 152 import android.os.Binder; 153 import android.os.Build; 154 import android.os.Bundle; 155 import android.os.Handler; 156 import android.os.HwBinder; 157 import android.os.IBinder; 158 import android.os.Looper; 159 import android.os.Message; 160 import android.os.PermissionEnforcer; 161 import android.os.PersistableBundle; 162 import android.os.PowerManager; 163 import android.os.Process; 164 import android.os.RemoteCallbackList; 165 import android.os.RemoteException; 166 import android.os.ResultReceiver; 167 import android.os.ServiceDebugInfo; 168 import android.os.ServiceManager; 169 import android.os.ShellCallback; 170 import android.os.SystemClock; 171 import android.os.SystemProperties; 172 import android.os.UserHandle; 173 import android.os.UserManager; 174 import android.os.VibrationAttributes; 175 import android.os.VibrationEffect; 176 import android.os.Vibrator; 177 import android.os.VibratorManager; 178 import android.provider.Settings; 179 import android.provider.Settings.System; 180 import android.service.notification.ZenModeConfig; 181 import android.telecom.TelecomManager; 182 import android.telephony.SubscriptionManager; 183 import android.text.TextUtils; 184 import android.util.AndroidRuntimeException; 185 import android.util.ArrayMap; 186 import android.util.ArraySet; 187 import android.util.IntArray; 188 import android.util.Log; 189 import android.util.PrintWriterPrinter; 190 import android.util.Slog; 191 import android.util.SparseArray; 192 import android.util.SparseIntArray; 193 import android.view.KeyEvent; 194 import android.view.accessibility.AccessibilityManager; 195 import android.widget.Toast; 196 197 import com.android.internal.annotations.GuardedBy; 198 import com.android.internal.annotations.VisibleForTesting; 199 import com.android.internal.os.SomeArgs; 200 import com.android.internal.util.DumpUtils; 201 import com.android.internal.util.Preconditions; 202 import com.android.server.EventLogTags; 203 import com.android.server.LocalServices; 204 import com.android.server.SystemService; 205 import com.android.server.audio.AudioServiceEvents.DeviceVolumeEvent; 206 import com.android.server.audio.AudioServiceEvents.PhoneStateEvent; 207 import com.android.server.audio.AudioServiceEvents.VolChangedBroadcastEvent; 208 import com.android.server.audio.AudioServiceEvents.VolumeEvent; 209 import com.android.server.pm.UserManagerInternal; 210 import com.android.server.pm.UserManagerInternal.UserRestrictionsListener; 211 import com.android.server.pm.UserManagerService; 212 import com.android.server.utils.EventLogger; 213 import com.android.server.wm.ActivityTaskManagerInternal; 214 215 import java.io.FileDescriptor; 216 import java.io.PrintWriter; 217 import java.lang.annotation.Retention; 218 import java.lang.annotation.RetentionPolicy; 219 import java.text.SimpleDateFormat; 220 import java.util.ArrayList; 221 import java.util.Arrays; 222 import java.util.Collection; 223 import java.util.Date; 224 import java.util.HashMap; 225 import java.util.HashSet; 226 import java.util.Iterator; 227 import java.util.LinkedHashMap; 228 import java.util.List; 229 import java.util.Map; 230 import java.util.NoSuchElementException; 231 import java.util.Objects; 232 import java.util.Set; 233 import java.util.TreeSet; 234 import java.util.UUID; 235 import java.util.concurrent.Executor; 236 import java.util.concurrent.atomic.AtomicBoolean; 237 import java.util.concurrent.atomic.AtomicInteger; 238 import java.util.function.BooleanSupplier; 239 import java.util.stream.Collectors; 240 241 /** 242 * The implementation of the audio service for volume, audio focus, device management... 243 * <p> 244 * This implementation focuses on delivering a responsive UI. Most methods are 245 * asynchronous to external calls. For example, the task of setting a volume 246 * will update our internal state, but in a separate thread will set the system 247 * volume and later persist to the database. Similarly, setting the ringer mode 248 * will update the state and broadcast a change and in a separate thread later 249 * persist the ringer mode. 250 * 251 * @hide 252 */ 253 public class AudioService extends IAudioService.Stub 254 implements AccessibilityManager.TouchExplorationStateChangeListener, 255 AccessibilityManager.AccessibilityServicesStateChangeListener, 256 AudioSystemAdapter.OnRoutingUpdatedListener, 257 AudioSystemAdapter.OnVolRangeInitRequestListener { 258 259 private static final String TAG = "AS.AudioService"; 260 261 private final AudioSystemAdapter mAudioSystem; 262 private final SystemServerAdapter mSystemServer; 263 private final SettingsAdapter mSettings; 264 private final AudioPolicyFacade mAudioPolicy; 265 266 /** Debug audio mode */ 267 protected static final boolean DEBUG_MODE = false; 268 269 /** Debug audio policy feature */ 270 protected static final boolean DEBUG_AP = false; 271 272 /** Debug volumes */ 273 protected static final boolean DEBUG_VOL = false; 274 275 /** debug calls to devices APIs */ 276 protected static final boolean DEBUG_DEVICES = false; 277 278 /** Debug communication route */ 279 protected static final boolean DEBUG_COMM_RTE = false; 280 281 /** Debug log sound fx (touchsounds...) in dumpsys */ 282 protected static final boolean DEBUG_LOG_SOUND_FX = false; 283 284 /** How long to delay before persisting a change in volume/ringer mode. */ 285 private static final int PERSIST_DELAY = 500; 286 287 /** How long to delay after a volume down event before unmuting a stream */ 288 private static final int UNMUTE_STREAM_DELAY = 350; 289 290 /** 291 * Delay before disconnecting a device that would cause BECOMING_NOISY intent to be sent, 292 * to give a chance to applications to pause. 293 */ 294 @VisibleForTesting 295 public static final int BECOMING_NOISY_DELAY_MS = 1000; 296 297 /** 298 * Only used in the result from {@link #checkForRingerModeChange(int, int, int)} 299 */ 300 private static final int FLAG_ADJUST_VOLUME = 1; 301 302 final Context mContext; 303 private final ContentResolver mContentResolver; 304 private final AppOpsManager mAppOps; 305 306 // the platform type affects volume and silent mode behavior 307 private final int mPlatformType; 308 309 // indicates whether the system maps all streams to a single stream. 310 private final boolean mIsSingleVolume; 311 312 /** 313 * indicates whether STREAM_NOTIFICATION is aliased to STREAM_RING 314 * not final due to test method, see {@link #setNotifAliasRingForTest(boolean)}. 315 */ 316 private boolean mNotifAliasRing = false; 317 318 /** 319 * Test method to temporarily override whether STREAM_NOTIFICATION is aliased to STREAM_RING, 320 * volumes will be updated in case of a change. 321 * @param alias if true, STREAM_NOTIFICATION is aliased to STREAM_RING 322 */ 323 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setNotifAliasRingForTest(boolean alias)324 public void setNotifAliasRingForTest(boolean alias) { 325 super.setNotifAliasRingForTest_enforcePermission(); 326 boolean update = (mNotifAliasRing != alias); 327 mNotifAliasRing = alias; 328 if (update) { 329 updateStreamVolumeAlias(true, "AudioServiceTest"); 330 } 331 } 332 isPlatformVoice()333 /*package*/ boolean isPlatformVoice() { 334 return mPlatformType == AudioSystem.PLATFORM_VOICE; 335 } 336 isPlatformTelevision()337 /*package*/ boolean isPlatformTelevision() { 338 return mPlatformType == AudioSystem.PLATFORM_TELEVISION; 339 } 340 isPlatformAutomotive()341 /*package*/ boolean isPlatformAutomotive() { 342 return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); 343 } 344 345 /** The controller for the volume UI. */ 346 private final VolumeController mVolumeController = new VolumeController(); 347 348 // sendMsg() flags 349 /** If the msg is already queued, replace it with this one. */ 350 private static final int SENDMSG_REPLACE = 0; 351 /** If the msg is already queued, ignore this one and leave the old. */ 352 private static final int SENDMSG_NOOP = 1; 353 /** If the msg is already queued, queue this one and leave the old. */ 354 private static final int SENDMSG_QUEUE = 2; 355 356 // AudioHandler messages 357 /*package*/ static final int MSG_SET_DEVICE_VOLUME = 0; 358 private static final int MSG_PERSIST_VOLUME = 1; 359 private static final int MSG_PERSIST_VOLUME_GROUP = 2; 360 private static final int MSG_PERSIST_RINGER_MODE = 3; 361 private static final int MSG_AUDIO_SERVER_DIED = 4; 362 private static final int MSG_PLAY_SOUND_EFFECT = 5; 363 private static final int MSG_LOAD_SOUND_EFFECTS = 7; 364 private static final int MSG_SET_FORCE_USE = 8; 365 private static final int MSG_SET_ALL_VOLUMES = 10; 366 private static final int MSG_UNLOAD_SOUND_EFFECTS = 15; 367 private static final int MSG_SYSTEM_READY = 16; 368 private static final int MSG_UNMUTE_STREAM = 18; 369 private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 19; 370 private static final int MSG_INDICATE_SYSTEM_READY = 20; 371 private static final int MSG_ACCESSORY_PLUG_MEDIA_UNMUTE = 21; 372 private static final int MSG_NOTIFY_VOL_EVENT = 22; 373 private static final int MSG_DISPATCH_AUDIO_SERVER_STATE = 23; 374 private static final int MSG_ENABLE_SURROUND_FORMATS = 24; 375 private static final int MSG_UPDATE_RINGER_MODE = 25; 376 private static final int MSG_SET_DEVICE_STREAM_VOLUME = 26; 377 private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27; 378 private static final int MSG_HDMI_VOLUME_CHECK = 28; 379 private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29; 380 private static final int MSG_BROADCAST_MICROPHONE_MUTE = 30; 381 private static final int MSG_CHECK_MODE_FOR_UID = 31; 382 private static final int MSG_STREAM_DEVICES_CHANGED = 32; 383 private static final int MSG_UPDATE_VOLUME_STATES_FOR_DEVICE = 33; 384 private static final int MSG_REINIT_VOLUMES = 34; 385 private static final int MSG_UPDATE_A11Y_SERVICE_UIDS = 35; 386 private static final int MSG_UPDATE_AUDIO_MODE = 36; 387 private static final int MSG_RECORDING_CONFIG_CHANGE = 37; 388 private static final int MSG_BT_DEV_CHANGED = 38; 389 390 private static final int MSG_DISPATCH_AUDIO_MODE = 40; 391 private static final int MSG_ROUTING_UPDATED = 41; 392 private static final int MSG_INIT_HEADTRACKING_SENSORS = 42; 393 private static final int MSG_ADD_ASSISTANT_SERVICE_UID = 44; 394 private static final int MSG_REMOVE_ASSISTANT_SERVICE_UID = 45; 395 private static final int MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID = 46; 396 private static final int MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR = 47; 397 private static final int MSG_ROTATION_UPDATE = 48; 398 private static final int MSG_FOLD_UPDATE = 49; 399 private static final int MSG_RESET_SPATIALIZER = 50; 400 private static final int MSG_NO_LOG_FOR_PLAYER_I = 51; 401 private static final int MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES = 52; 402 private static final int MSG_LOWER_VOLUME_TO_RS1 = 53; 403 private static final int MSG_CONFIGURATION_CHANGED = 54; 404 405 /** Messages handled by the {@link SoundDoseHelper}. */ 406 /*package*/ static final int SAFE_MEDIA_VOLUME_MSG_START = 1000; 407 408 // start of messages handled under wakelock 409 // these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(), 410 // and not with sendMsg(..., ..., SENDMSG_QUEUE, ...) 411 private static final int MSG_DISABLE_AUDIO_FOR_UID = 100; 412 private static final int MSG_INIT_STREAMS_VOLUMES = 101; 413 private static final int MSG_INIT_SPATIALIZER = 102; 414 private static final int MSG_INIT_ADI_DEVICE_STATES = 103; 415 416 // end of messages handled under wakelock 417 418 // retry delay in case of failure to indicate system ready to AudioFlinger 419 private static final int INDICATE_SYSTEM_READY_RETRY_DELAY_MS = 1000; 420 421 // List of empty UIDs used to reset the active assistant list 422 private static final int[] NO_ACTIVE_ASSISTANT_SERVICE_UIDS = new int[0]; 423 424 // check playback or record activity every 6 seconds for UIDs owning mode IN_COMMUNICATION 425 private static final int CHECK_MODE_FOR_UID_PERIOD_MS = 6000; 426 427 /** @see AudioSystemThread */ 428 private AudioSystemThread mAudioSystemThread; 429 /** @see AudioHandler */ 430 private AudioHandler mAudioHandler; 431 /** @see VolumeStreamState */ 432 private VolumeStreamState[] mStreamStates; 433 getVssVolumeForDevice(int stream, int device)434 /*package*/ int getVssVolumeForDevice(int stream, int device) { 435 return mStreamStates[stream].getIndex(device); 436 } 437 getVssVolumeForStream(int stream)438 /*package*/ VolumeStreamState getVssVolumeForStream(int stream) { 439 return mStreamStates[stream]; 440 } 441 getMaxVssVolumeForStream(int stream)442 /*package*/ int getMaxVssVolumeForStream(int stream) { 443 return mStreamStates[stream].getMaxIndex(); 444 } 445 446 private SettingsObserver mSettingsObserver; 447 448 private AtomicInteger mMode = new AtomicInteger(AudioSystem.MODE_NORMAL); 449 450 // protects mRingerMode 451 private final Object mSettingsLock = new Object(); 452 453 /** Maximum volume index values for audio streams */ 454 protected static int[] MAX_STREAM_VOLUME = new int[] { 455 5, // STREAM_VOICE_CALL 456 7, // STREAM_SYSTEM 457 7, // STREAM_RING // configured by config_audio_ring_vol_steps 458 15, // STREAM_MUSIC 459 7, // STREAM_ALARM 460 7, // STREAM_NOTIFICATION // configured by config_audio_notif_vol_steps 461 15, // STREAM_BLUETOOTH_SCO 462 7, // STREAM_SYSTEM_ENFORCED 463 15, // STREAM_DTMF 464 15, // STREAM_TTS 465 15, // STREAM_ACCESSIBILITY 466 15 // STREAM_ASSISTANT 467 }; 468 469 /** Minimum volume index values for audio streams */ 470 protected static int[] MIN_STREAM_VOLUME = new int[] { 471 1, // STREAM_VOICE_CALL 472 0, // STREAM_SYSTEM 473 0, // STREAM_RING 474 0, // STREAM_MUSIC 475 1, // STREAM_ALARM 476 0, // STREAM_NOTIFICATION 477 0, // STREAM_BLUETOOTH_SCO 478 0, // STREAM_SYSTEM_ENFORCED 479 0, // STREAM_DTMF 480 0, // STREAM_TTS 481 1, // STREAM_ACCESSIBILITY 482 0 // STREAM_ASSISTANT 483 }; 484 485 /* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings 486 * of another stream: This avoids multiplying the volume settings for hidden 487 * stream types that follow other stream behavior for volume settings 488 * NOTE: do not create loops in aliases! 489 * Some streams alias to different streams according to device category (phone or tablet) or 490 * use case (in call vs off call...). See updateStreamVolumeAlias() for more details. 491 * mStreamVolumeAlias contains STREAM_VOLUME_ALIAS_VOICE aliases for a voice capable device 492 * (phone), STREAM_VOLUME_ALIAS_TELEVISION for a television or set-top box and 493 * STREAM_VOLUME_ALIAS_DEFAULT for other devices (e.g. tablets).*/ 494 private final int[] STREAM_VOLUME_ALIAS_VOICE = new int[] { 495 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 496 AudioSystem.STREAM_RING, // STREAM_SYSTEM 497 AudioSystem.STREAM_RING, // STREAM_RING 498 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 499 AudioSystem.STREAM_ALARM, // STREAM_ALARM 500 AudioSystem.STREAM_RING, // STREAM_NOTIFICATION 501 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 502 AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED 503 AudioSystem.STREAM_RING, // STREAM_DTMF 504 AudioSystem.STREAM_MUSIC, // STREAM_TTS 505 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 506 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 507 }; 508 private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] { 509 AudioSystem.STREAM_MUSIC, // STREAM_VOICE_CALL 510 AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM 511 AudioSystem.STREAM_MUSIC, // STREAM_RING 512 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 513 AudioSystem.STREAM_MUSIC, // STREAM_ALARM 514 AudioSystem.STREAM_MUSIC, // STREAM_NOTIFICATION 515 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 516 AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM_ENFORCED 517 AudioSystem.STREAM_MUSIC, // STREAM_DTMF 518 AudioSystem.STREAM_MUSIC, // STREAM_TTS 519 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 520 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 521 }; 522 /** 523 * Using Volume groups configuration allows to control volume per attributes 524 * and group definition may differ from stream aliases. 525 * So, do not alias any stream on one another when using volume groups. 526 * TODO(b/181140246): volume group definition hosting alias definition. 527 */ 528 private final int[] STREAM_VOLUME_ALIAS_NONE = new int[] { 529 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 530 AudioSystem.STREAM_SYSTEM, // STREAM_SYSTEM 531 AudioSystem.STREAM_RING, // STREAM_RING 532 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 533 AudioSystem.STREAM_ALARM, // STREAM_ALARM 534 AudioSystem.STREAM_NOTIFICATION, // STREAM_NOTIFICATION 535 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 536 AudioSystem.STREAM_SYSTEM_ENFORCED, // STREAM_SYSTEM_ENFORCED 537 AudioSystem.STREAM_DTMF, // STREAM_DTMF 538 AudioSystem.STREAM_TTS, // STREAM_TTS 539 AudioSystem.STREAM_ACCESSIBILITY, // STREAM_ACCESSIBILITY 540 AudioSystem.STREAM_ASSISTANT // STREAM_ASSISTANT 541 }; 542 private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] { 543 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 544 AudioSystem.STREAM_RING, // STREAM_SYSTEM 545 AudioSystem.STREAM_RING, // STREAM_RING 546 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 547 AudioSystem.STREAM_ALARM, // STREAM_ALARM 548 AudioSystem.STREAM_RING, // STREAM_NOTIFICATION 549 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 550 AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED 551 AudioSystem.STREAM_RING, // STREAM_DTMF 552 AudioSystem.STREAM_MUSIC, // STREAM_TTS 553 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 554 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 555 }; 556 protected static int[] mStreamVolumeAlias; 557 private static final int UNSET_INDEX = -1; 558 559 /** 560 * Map AudioSystem.STREAM_* constants to app ops. This should be used 561 * after mapping through mStreamVolumeAlias. 562 */ 563 private static final int[] STREAM_VOLUME_OPS = new int[] { 564 AppOpsManager.OP_AUDIO_VOICE_VOLUME, // STREAM_VOICE_CALL 565 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_SYSTEM 566 AppOpsManager.OP_AUDIO_RING_VOLUME, // STREAM_RING 567 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_MUSIC 568 AppOpsManager.OP_AUDIO_ALARM_VOLUME, // STREAM_ALARM 569 AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME, // STREAM_NOTIFICATION 570 AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME, // STREAM_BLUETOOTH_SCO 571 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_SYSTEM_ENFORCED 572 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_DTMF 573 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_TTS 574 AppOpsManager.OP_AUDIO_ACCESSIBILITY_VOLUME, // STREAM_ACCESSIBILITY 575 AppOpsManager.OP_AUDIO_MEDIA_VOLUME // STREAM_ASSISTANT 576 }; 577 578 private final boolean mUseFixedVolume; 579 private final boolean mUseVolumeGroupAliases; 580 581 // If absolute volume is supported in AVRCP device 582 private volatile boolean mAvrcpAbsVolSupported = false; 583 584 /** 585 * Default stream type used for volume control in the absence of playback 586 * e.g. user on homescreen, no app playing anything, presses hardware volume buttons, this 587 * stream type is controlled. 588 */ 589 protected static final int DEFAULT_VOL_STREAM_NO_PLAYBACK = AudioSystem.STREAM_MUSIC; 590 591 private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() { 592 public void onError(int error) { 593 switch (error) { 594 case AudioSystem.AUDIO_STATUS_SERVER_DIED: 595 // check for null in case error callback is called during instance creation 596 if (mRecordMonitor != null) { 597 mRecordMonitor.onAudioServerDied(); 598 } 599 // Notify the playback monitor that the audio server has died 600 if (mPlaybackMonitor != null) { 601 mPlaybackMonitor.onAudioServerDied(); 602 } 603 sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, 604 SENDMSG_NOOP, 0, 0, null, 0); 605 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE, 606 SENDMSG_QUEUE, 0, 0, null, 0); 607 break; 608 default: 609 break; 610 } 611 } 612 }; 613 614 /** 615 * Current ringer mode from one of {@link AudioManager#RINGER_MODE_NORMAL}, 616 * {@link AudioManager#RINGER_MODE_SILENT}, or 617 * {@link AudioManager#RINGER_MODE_VIBRATE}. 618 */ 619 @GuardedBy("mSettingsLock") 620 private int mRingerMode; // internal ringer mode, affects muting of underlying streams 621 @GuardedBy("mSettingsLock") 622 private int mRingerModeExternal = -1; // reported ringer mode to outside clients (AudioManager) 623 624 /** @see System#MODE_RINGER_STREAMS_AFFECTED */ 625 private int mRingerModeAffectedStreams = 0; 626 627 private int mZenModeAffectedStreams = 0; 628 629 // Streams currently muted by ringer mode and dnd 630 protected static volatile int sRingerAndZenModeMutedStreams; 631 632 /** Streams that can be muted. Do not resolve to aliases when checking. 633 * @see System#MUTE_STREAMS_AFFECTED */ 634 private int mMuteAffectedStreams; 635 636 @NonNull 637 private SoundEffectsHelper mSfxHelper; 638 639 /** 640 * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated. 641 * mVibrateSetting is just maintained during deprecation period but vibration policy is 642 * now only controlled by mHasVibrator and mRingerMode 643 */ 644 private int mVibrateSetting; 645 646 // Is there a vibrator 647 private final boolean mHasVibrator; 648 // Used to play vibrations 649 private Vibrator mVibrator; 650 private static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES = 651 VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH); 652 653 // Broadcast receiver for device connections intent broadcasts 654 private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver(); 655 656 private IMediaProjectionManager mProjectionService; // to validate projection token 657 658 /** Interface for UserManagerService. */ 659 private final UserManagerInternal mUserManagerInternal; 660 private final ActivityManagerInternal mActivityManagerInternal; 661 private final SensorPrivacyManagerInternal mSensorPrivacyManagerInternal; 662 663 private final UserRestrictionsListener mUserRestrictionsListener = 664 new AudioServiceUserRestrictionsListener(); 665 666 // List of binder death handlers for setMode() client processes. 667 // The last process to have called setMode() is at the top of the list. 668 // package-private so it can be accessed in AudioDeviceBroker.getSetModeDeathHandlers 669 //TODO candidate to be moved to separate class that handles synchronization 670 @GuardedBy("mDeviceBroker.mSetModeLock") 671 /*package*/ final ArrayList<SetModeDeathHandler> mSetModeDeathHandlers = 672 new ArrayList<SetModeDeathHandler>(); 673 674 // true if boot sequence has been completed 675 private boolean mSystemReady; 676 // true if Intent.ACTION_USER_SWITCHED has ever been received 677 private boolean mUserSwitchedReceived; 678 // previous volume adjustment direction received by checkForRingerModeChange() 679 private int mPrevVolDirection = AudioManager.ADJUST_SAME; 680 // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume 681 // is controlled by Vol keys. 682 private int mVolumeControlStream = -1; 683 // interpretation of whether the volume stream has been selected by the user by clicking on a 684 // volume slider to change which volume is controlled by the volume keys. Is false 685 // when mVolumeControlStream is -1. 686 private boolean mUserSelectedVolumeControlStream = false; 687 private final Object mForceControlStreamLock = new Object(); 688 // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system 689 // server process so in theory it is not necessary to monitor the client death. 690 // However it is good to be ready for future evolutions. 691 private ForceControlStreamClient mForceControlStreamClient = null; 692 // Used to play ringtones outside system_server 693 private volatile IRingtonePlayer mRingtonePlayer; 694 695 // Devices for which the volume is fixed (volume is either max or muted) 696 Set<Integer> mFixedVolumeDevices = new HashSet<>(Arrays.asList( 697 AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, 698 AudioSystem.DEVICE_OUT_AUX_LINE)); 699 // Devices for which the volume is always max, no volume panel 700 Set<Integer> mFullVolumeDevices = new HashSet<>(Arrays.asList( 701 AudioSystem.DEVICE_OUT_HDMI_ARC, 702 AudioSystem.DEVICE_OUT_HDMI_EARC 703 )); 704 705 // Devices where the framework sends a full scale audio signal, and controls the volume of 706 // the external audio system separately. 707 // For possible volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}. 708 Map<Integer, AbsoluteVolumeDeviceInfo> mAbsoluteVolumeDeviceInfoMap = new ArrayMap<>(); 709 710 /** 711 * Stores information about a device using absolute volume behavior. 712 */ 713 private static final class AbsoluteVolumeDeviceInfo { 714 private final AudioDeviceAttributes mDevice; 715 private final List<VolumeInfo> mVolumeInfos; 716 private final IAudioDeviceVolumeDispatcher mCallback; 717 private final boolean mHandlesVolumeAdjustment; 718 private @AudioManager.AbsoluteDeviceVolumeBehavior int mDeviceVolumeBehavior; 719 AbsoluteVolumeDeviceInfo( AudioDeviceAttributes device, List<VolumeInfo> volumeInfos, IAudioDeviceVolumeDispatcher callback, boolean handlesVolumeAdjustment, @AudioManager.AbsoluteDeviceVolumeBehavior int behavior)720 private AbsoluteVolumeDeviceInfo( 721 AudioDeviceAttributes device, 722 List<VolumeInfo> volumeInfos, 723 IAudioDeviceVolumeDispatcher callback, 724 boolean handlesVolumeAdjustment, 725 @AudioManager.AbsoluteDeviceVolumeBehavior int behavior) { 726 this.mDevice = device; 727 this.mVolumeInfos = volumeInfos; 728 this.mCallback = callback; 729 this.mHandlesVolumeAdjustment = handlesVolumeAdjustment; 730 this.mDeviceVolumeBehavior = behavior; 731 } 732 733 /** 734 * Given a stream type, returns a matching VolumeInfo. 735 */ 736 @Nullable getMatchingVolumeInfoForStream(int streamType)737 private VolumeInfo getMatchingVolumeInfoForStream(int streamType) { 738 for (VolumeInfo volumeInfo : mVolumeInfos) { 739 boolean streamTypeMatches = volumeInfo.hasStreamType() 740 && volumeInfo.getStreamType() == streamType; 741 boolean volumeGroupMatches = volumeInfo.hasVolumeGroup() 742 && Arrays.stream(volumeInfo.getVolumeGroup().getLegacyStreamTypes()) 743 .anyMatch(s -> s == streamType); 744 if (streamTypeMatches || volumeGroupMatches) { 745 return volumeInfo; 746 } 747 } 748 return null; 749 } 750 } 751 752 // Devices for the which use the "absolute volume" concept (framework sends audio signal 753 // full scale, and volume control separately) and can be used for multiple use cases reflected 754 // by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL). 755 Set<Integer> mAbsVolumeMultiModeCaseDevices = new HashSet<>( 756 Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID)); 757 758 private final boolean mMonitorRotation; 759 760 private boolean mDockAudioMediaEnabled = true; 761 762 /** 763 * RestorableParameters is a thread-safe class used to store a 764 * first-in first-out history of parameters for replay / restoration. 765 * 766 * The idealized implementation of restoration would have a list of setting methods and 767 * values to be called for restoration. Explicitly managing such setters and 768 * values would be tedious - a simpler method is to store the values and the 769 * method implicitly by lambda capture (the values must be immutable or synchronization 770 * needs to be taken). 771 * 772 * We provide queueRestoreWithRemovalIfTrue() to allow 773 * the caller to provide a BooleanSupplier lambda, which conveniently packages 774 * the setter and its parameters needed for restoration. If during restoration, 775 * the BooleanSupplier returns true, e.g. on error, it is removed from the mMap 776 * so as not to be called on a subsequent restore. 777 * 778 * We provide a setParameters() method as an example helper method. 779 */ 780 private static class RestorableParameters { 781 /** 782 * Sets a parameter and queues for restoration if successful. 783 * 784 * @param id a string handle associated with this parameter. 785 * @param parameter the actual parameter string. 786 * @return the result of AudioSystem.setParameters 787 */ setParameters(@onNull String id, @NonNull String parameter)788 public int setParameters(@NonNull String id, @NonNull String parameter) { 789 Objects.requireNonNull(id, "id must not be null"); 790 Objects.requireNonNull(parameter, "parameter must not be null"); 791 synchronized (mMap) { 792 final int status = AudioSystem.setParameters(parameter); 793 if (status == AudioSystem.AUDIO_STATUS_OK) { // Java uses recursive mutexes. 794 queueRestoreWithRemovalIfTrue(id, () -> { // remove me if set fails. 795 return AudioSystem.setParameters(parameter) != AudioSystem.AUDIO_STATUS_OK; 796 }); 797 } 798 // Implementation detail: We do not mMap.remove(id); on failure. 799 return status; 800 } 801 } 802 803 /** 804 * Queues a restore method which is executed on restoreAll(). 805 * 806 * If the supplier null, the id is removed from the restore map. 807 * 808 * Note: When the BooleanSupplier restore method is executed 809 * during restoreAll, if it returns true, it is removed from the 810 * restore map. 811 * 812 * @param id a unique tag associated with the restore method. 813 * @param supplier is a BooleanSupplier lambda. 814 */ queueRestoreWithRemovalIfTrue( @onNull String id, @Nullable BooleanSupplier supplier)815 public void queueRestoreWithRemovalIfTrue( 816 @NonNull String id, @Nullable BooleanSupplier supplier) { 817 Objects.requireNonNull(id, "id must not be null"); 818 synchronized (mMap) { 819 if (supplier != null) { 820 mMap.put(id, supplier); 821 } else { 822 mMap.remove(id); 823 } 824 } 825 } 826 827 /** 828 * Restore all parameters 829 * 830 * During restoration after audioserver death, any BooleanSupplier that returns 831 * true, for example on parameter restoration error, will be removed from mMap 832 * so as not to be executed on a subsequent restoreAll(). 833 */ restoreAll()834 public void restoreAll() { 835 synchronized (mMap) { 836 // Note: removing from values() also removes from the backing map. 837 // TODO: Consider catching exceptions? 838 mMap.values().removeIf(v -> { 839 return v.getAsBoolean(); // this iterates the setters(). 840 }); 841 } 842 } 843 844 /** 845 * mMap is a LinkedHashMap<Key, Value> of parameters restored by restore(). 846 * The Key is a unique id tag for identification. 847 * The Value is a lambda expression which returns true if the entry is to 848 * be removed. 849 * 850 * 1) For memory limitation purposes, mMap keeps the latest MAX_ENTRIES 851 * accessed in the map. 852 * 2) Parameters are restored in order of queuing, first in first out, 853 * from earliest to latest. 854 */ 855 @GuardedBy("mMap") 856 private Map</* @NonNull */ String, /* @NonNull */ BooleanSupplier> mMap = 857 new LinkedHashMap<>() { 858 // TODO: do we need this memory limitation? 859 private static final int MAX_ENTRIES = 1000; // limit our memory for now. 860 @Override 861 protected boolean removeEldestEntry(Map.Entry eldest) { 862 if (size() <= MAX_ENTRIES) return false; 863 Log.w(TAG, "Parameter map exceeds " 864 + MAX_ENTRIES + " removing " + eldest.getKey()); // don't silently remove. 865 return true; 866 } 867 }; 868 } 869 870 // We currently have one instance for mRestorableParameters used for 871 // setAdditionalOutputDeviceDelay(). Other methods requiring restoration could share this 872 // or use their own instance. 873 private RestorableParameters mRestorableParameters = new RestorableParameters(); 874 875 private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; 876 877 private PowerManager.WakeLock mAudioEventWakeLock; 878 879 private final MediaFocusControl mMediaFocusControl; 880 881 // Pre-scale for Bluetooth Absolute Volume 882 private float[] mPrescaleAbsoluteVolume = new float[] { 883 0.6f, // Pre-scale for index 1 884 0.8f, // Pre-scale for index 2 885 0.9f, // Pre-scale for index 3 886 }; 887 888 private NotificationManager mNm; 889 private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate; 890 private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT; 891 private long mLoweredFromNormalToVibrateTime; 892 893 // Array of Uids of valid assistant services to check if caller is one of them 894 @GuardedBy("mSettingsLock") 895 private final ArraySet<Integer> mAssistantUids = new ArraySet<>(); 896 @GuardedBy("mSettingsLock") 897 private int mPrimaryAssistantUid = INVALID_UID; 898 899 // Array of Uids of valid active assistant service to check if caller is one of them 900 @GuardedBy("mSettingsLock") 901 private int[] mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS; 902 903 // Array of Uids of valid accessibility services to check if caller is one of them 904 private final Object mAccessibilityServiceUidsLock = new Object(); 905 @GuardedBy("mAccessibilityServiceUidsLock") 906 private int[] mAccessibilityServiceUids; 907 908 // Uid of the active input method service to check if caller is the one or not. 909 private int mInputMethodServiceUid = android.os.Process.INVALID_UID; 910 private final Object mInputMethodServiceUidLock = new Object(); 911 912 private int mEncodedSurroundMode; 913 private String mEnabledSurroundFormats; 914 private boolean mSurroundModeChanged; 915 916 private boolean mSupportsMicPrivacyToggle; 917 918 private boolean mMicMuteFromSwitch; 919 private boolean mMicMuteFromApi; 920 private boolean mMicMuteFromRestrictions; 921 private boolean mMicMuteFromPrivacyToggle; 922 // caches the value returned by AudioSystem.isMicrophoneMuted() 923 private boolean mMicMuteFromSystemCached; 924 925 private boolean mNavigationRepeatSoundEffectsEnabled; 926 private boolean mHomeSoundEffectEnabled; 927 928 private final SoundDoseHelper mSoundDoseHelper; 929 930 private final Object mSupportedSystemUsagesLock = new Object(); 931 @GuardedBy("mSupportedSystemUsagesLock") 932 private @AttributeSystemUsage int[] mSupportedSystemUsages = 933 new int[]{AudioAttributes.USAGE_CALL_ASSISTANT}; 934 935 // Defines the format for the connection "address" for ALSA devices makeAlsaAddressString(int card, int device)936 public static String makeAlsaAddressString(int card, int device) { 937 return "card=" + card + ";device=" + device; 938 } 939 940 public static final class Lifecycle extends SystemService { 941 private AudioService mService; 942 Lifecycle(Context context)943 public Lifecycle(Context context) { 944 super(context); 945 mService = new AudioService(context, 946 AudioSystemAdapter.getDefaultAdapter(), 947 SystemServerAdapter.getDefaultAdapter(context), 948 SettingsAdapter.getDefaultAdapter(), 949 new DefaultAudioPolicyFacade(), 950 null); 951 952 } 953 954 @Override onStart()955 public void onStart() { 956 publishBinderService(Context.AUDIO_SERVICE, mService); 957 } 958 959 @Override onBootPhase(int phase)960 public void onBootPhase(int phase) { 961 if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { 962 mService.systemReady(); 963 } 964 } 965 } 966 967 final private IUidObserver mUidObserver = new UidObserver() { 968 @Override public void onUidGone(int uid, boolean disabled) { 969 // Once the uid is no longer running, no need to keep trying to disable its audio. 970 disableAudioForUid(false, uid); 971 } 972 973 @Override public void onUidCachedChanged(int uid, boolean cached) { 974 disableAudioForUid(cached, uid); 975 } 976 977 private void disableAudioForUid(boolean disable, int uid) { 978 queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID, 979 disable ? 1 : 0 /* arg1 */, uid /* arg2 */, 980 null /* obj */, 0 /* delay */); 981 } 982 }; 983 984 @GuardedBy("mSettingsLock") 985 private boolean mRttEnabled = false; 986 987 /////////////////////////////////////////////////////////////////////////// 988 // Construction 989 /////////////////////////////////////////////////////////////////////////// 990 991 992 /** 993 * @param context 994 * @param audioSystem Adapter for {@link AudioSystem} 995 * @param systemServer Adapter for privilieged functionality for system server components 996 * @param settings Adapter for {@link Settings} 997 * @param looper Looper to use for the service's message handler. If this is null, an 998 * {@link AudioSystemThread} is created as the messaging thread instead. 999 */ AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer, SettingsAdapter settings, AudioPolicyFacade audioPolicy, @Nullable Looper looper)1000 public AudioService(Context context, AudioSystemAdapter audioSystem, 1001 SystemServerAdapter systemServer, SettingsAdapter settings, 1002 AudioPolicyFacade audioPolicy, @Nullable Looper looper) { 1003 this (context, audioSystem, systemServer, settings, audioPolicy, looper, 1004 context.getSystemService(AppOpsManager.class), 1005 PermissionEnforcer.fromContext(context)); 1006 } 1007 1008 /** 1009 * @param context 1010 * @param audioSystem Adapter for {@link AudioSystem} 1011 * @param systemServer Adapter for privilieged functionality for system server components 1012 * @param settings Adapter for {@link Settings} 1013 * @param looper Looper to use for the service's message handler. If this is null, an 1014 * {@link AudioSystemThread} is created as the messaging thread instead. 1015 */ 1016 @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer, SettingsAdapter settings, AudioPolicyFacade audioPolicy, @Nullable Looper looper, AppOpsManager appOps, @NonNull PermissionEnforcer enforcer)1017 public AudioService(Context context, AudioSystemAdapter audioSystem, 1018 SystemServerAdapter systemServer, SettingsAdapter settings, 1019 AudioPolicyFacade audioPolicy, @Nullable Looper looper, AppOpsManager appOps, 1020 @NonNull PermissionEnforcer enforcer) { 1021 super(enforcer); 1022 sLifecycleLogger.enqueue(new EventLogger.StringEvent("AudioService()")); 1023 mContext = context; 1024 mContentResolver = context.getContentResolver(); 1025 mAppOps = appOps; 1026 1027 mAudioSystem = audioSystem; 1028 mSystemServer = systemServer; 1029 mSettings = settings; 1030 mAudioPolicy = audioPolicy; 1031 mPlatformType = AudioSystem.getPlatformType(context); 1032 1033 mDeviceBroker = new AudioDeviceBroker(mContext, this, mAudioSystem); 1034 1035 mIsSingleVolume = AudioSystem.isSingleVolume(context); 1036 1037 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 1038 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); 1039 mSensorPrivacyManagerInternal = 1040 LocalServices.getService(SensorPrivacyManagerInternal.class); 1041 1042 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 1043 mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent"); 1044 1045 mSfxHelper = new SoundEffectsHelper(mContext, playerBase -> ignorePlayerLogs(playerBase)); 1046 1047 boolean binauralEnabledDefault = SystemProperties.getBoolean( 1048 "ro.audio.spatializer_binaural_enabled_default", true); 1049 boolean transauralEnabledDefault = SystemProperties.getBoolean( 1050 "ro.audio.spatializer_transaural_enabled_default", true); 1051 boolean headTrackingEnabledDefault = mContext.getResources().getBoolean( 1052 com.android.internal.R.bool.config_spatial_audio_head_tracking_enabled_default); 1053 1054 mSpatializerHelper = new SpatializerHelper(this, mAudioSystem, mDeviceBroker, 1055 binauralEnabledDefault, transauralEnabledDefault, headTrackingEnabledDefault); 1056 1057 mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); 1058 mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator(); 1059 1060 mSupportsMicPrivacyToggle = context.getSystemService(SensorPrivacyManager.class) 1061 .supportsSensorToggle(SensorPrivacyManager.Sensors.MICROPHONE); 1062 1063 mUseVolumeGroupAliases = mContext.getResources().getBoolean( 1064 com.android.internal.R.bool.config_handleVolumeAliasesUsingVolumeGroups); 1065 1066 // Initialize volume 1067 // Priority 1 - Android Property 1068 // Priority 2 - Audio Policy Service 1069 // Priority 3 - Default Value 1070 if (AudioProductStrategy.getAudioProductStrategies().size() > 0) { 1071 int numStreamTypes = AudioSystem.getNumStreamTypes(); 1072 1073 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 1074 AudioAttributes attr = 1075 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType( 1076 streamType); 1077 int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr); 1078 if (maxVolume != -1) { 1079 MAX_STREAM_VOLUME[streamType] = maxVolume; 1080 } 1081 int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr); 1082 if (minVolume != -1) { 1083 MIN_STREAM_VOLUME[streamType] = minVolume; 1084 } 1085 } 1086 if (mUseVolumeGroupAliases) { 1087 // Set all default to uninitialized. 1088 for (int stream = 0; stream < AudioSystem.DEFAULT_STREAM_VOLUME.length; stream++) { 1089 AudioSystem.DEFAULT_STREAM_VOLUME[stream] = UNSET_INDEX; 1090 } 1091 } 1092 } 1093 1094 int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1); 1095 if (maxCallVolume != -1) { 1096 MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume; 1097 } 1098 1099 int defaultCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_default", -1); 1100 if (defaultCallVolume != -1 && 1101 defaultCallVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] && 1102 defaultCallVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) { 1103 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume; 1104 } else { 1105 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = 1106 (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4; 1107 } 1108 1109 int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1); 1110 if (maxMusicVolume != -1) { 1111 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume; 1112 } 1113 1114 int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1); 1115 if (defaultMusicVolume != -1 && 1116 defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] && 1117 defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) { 1118 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume; 1119 } else { 1120 if (isPlatformTelevision()) { 1121 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = 1122 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4; 1123 } else { 1124 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = 1125 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3; 1126 } 1127 } 1128 1129 int maxAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_steps", -1); 1130 if (maxAlarmVolume != -1) { 1131 MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = maxAlarmVolume; 1132 } 1133 1134 int defaultAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_default", -1); 1135 if (defaultAlarmVolume != -1 && 1136 defaultAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) { 1137 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = defaultAlarmVolume; 1138 } else { 1139 // Default is 6 out of 7 (default maximum), so scale accordingly. 1140 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = 1141 6 * MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] / 7; 1142 } 1143 1144 int maxSystemVolume = SystemProperties.getInt("ro.config.system_vol_steps", -1); 1145 if (maxSystemVolume != -1) { 1146 MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = maxSystemVolume; 1147 } 1148 1149 int defaultSystemVolume = SystemProperties.getInt("ro.config.system_vol_default", -1); 1150 if (defaultSystemVolume != -1 && 1151 defaultSystemVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]) { 1152 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = defaultSystemVolume; 1153 } else { 1154 // Default is to use maximum. 1155 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = 1156 MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]; 1157 } 1158 1159 int minAssistantVolume = SystemProperties.getInt("ro.config.assistant_vol_min", -1); 1160 if (minAssistantVolume != -1) { 1161 MIN_STREAM_VOLUME[AudioSystem.STREAM_ASSISTANT] = minAssistantVolume; 1162 } 1163 1164 // Read following properties to configure max volume (number of steps) and default volume 1165 // for STREAM_NOTIFICATION and STREAM_RING: 1166 // config_audio_notif_vol_default 1167 // config_audio_notif_vol_steps 1168 // config_audio_ring_vol_default 1169 // config_audio_ring_vol_steps 1170 int[] streams = { AudioSystem.STREAM_NOTIFICATION, AudioSystem.STREAM_RING }; 1171 int[] stepsResId = { com.android.internal.R.integer.config_audio_notif_vol_steps, 1172 com.android.internal.R.integer.config_audio_ring_vol_steps }; 1173 int[] defaultResId = { com.android.internal.R.integer.config_audio_notif_vol_default, 1174 com.android.internal.R.integer.config_audio_ring_vol_default }; 1175 for (int s = 0; s < streams.length; s++) { 1176 try { 1177 final int maxVol = mContext.getResources().getInteger(stepsResId[s]); 1178 if (maxVol <= 0) { 1179 throw new IllegalArgumentException("Invalid negative max volume for stream " 1180 + streams[s]); 1181 } 1182 Log.i(TAG, "Stream " + streams[s] + ": using max vol of " + maxVol); 1183 MAX_STREAM_VOLUME[streams[s]] = maxVol; 1184 } catch (Resources.NotFoundException e) { 1185 Log.e(TAG, "Error querying max vol for stream type " + streams[s], e); 1186 } 1187 try { 1188 final int defaultVol = mContext.getResources().getInteger(defaultResId[s]); 1189 if (defaultVol > MAX_STREAM_VOLUME[streams[s]]) { 1190 throw new IllegalArgumentException("Invalid default volume (" + defaultVol 1191 + ") for stream " + streams[s] + ", greater than max volume of " 1192 + MAX_STREAM_VOLUME[streams[s]]); 1193 } 1194 if (defaultVol < MIN_STREAM_VOLUME[streams[s]]) { 1195 throw new IllegalArgumentException("Invalid default volume (" + defaultVol 1196 + ") for stream " + streams[s] + ", lower than min volume of " 1197 + MIN_STREAM_VOLUME[streams[s]]); 1198 } 1199 Log.i(TAG, "Stream " + streams[s] + ": using default vol of " + defaultVol); 1200 AudioSystem.DEFAULT_STREAM_VOLUME[streams[s]] = defaultVol; 1201 } catch (Resources.NotFoundException e) { 1202 Log.e(TAG, "Error querying default vol for stream type " + streams[s], e); 1203 } 1204 } 1205 1206 if (looper == null) { 1207 createAudioSystemThread(); 1208 } else { 1209 mAudioHandler = new AudioHandler(looper); 1210 } 1211 1212 mSoundDoseHelper = new SoundDoseHelper(this, mContext, mAudioHandler, mSettings, 1213 mVolumeController); 1214 1215 AudioSystem.setErrorCallback(mAudioSystemCallback); 1216 1217 updateAudioHalPids(); 1218 1219 mUseFixedVolume = mContext.getResources().getBoolean( 1220 com.android.internal.R.bool.config_useFixedVolume); 1221 1222 mRecordMonitor = new RecordingActivityMonitor(mContext); 1223 mRecordMonitor.registerRecordingCallback(mVoiceRecordingActivityMonitor, true); 1224 1225 // must be called before readPersistedSettings() which needs a valid mStreamVolumeAlias[] 1226 // array initialized by updateStreamVolumeAlias() 1227 updateStreamVolumeAlias(false /*updateVolumes*/, TAG); 1228 readPersistedSettings(); 1229 readUserRestrictions(); 1230 1231 mPlaybackMonitor = 1232 new PlaybackActivityMonitor(context, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM], 1233 device -> onMuteAwaitConnectionTimeout(device)); 1234 mPlaybackMonitor.registerPlaybackCallback(mPlaybackActivityMonitor, true); 1235 1236 mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor); 1237 1238 readAndSetLowRamDevice(); 1239 1240 mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported(); 1241 1242 if (mSystemServer.isPrivileged()) { 1243 LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal()); 1244 1245 mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener); 1246 1247 mRecordMonitor.initMonitor(); 1248 } 1249 1250 mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false); 1251 1252 mHasSpatializerEffect = SystemProperties.getBoolean("ro.audio.spatializer_enabled", false); 1253 1254 // monitor routing updates coming from native 1255 mAudioSystem.setRoutingListener(this); 1256 // monitor requests for volume range initialization coming from native (typically when 1257 // errors are found by AudioPolicyManager 1258 mAudioSystem.setVolRangeInitReqListener(this); 1259 1260 // done with service initialization, continue additional work in our Handler thread 1261 queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES, 1262 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */); 1263 queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_ADI_DEVICE_STATES, 1264 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */); 1265 queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_SPATIALIZER, 1266 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */); 1267 } 1268 initVolumeStreamStates()1269 private void initVolumeStreamStates() { 1270 int numStreamTypes = AudioSystem.getNumStreamTypes(); 1271 synchronized (VolumeStreamState.class) { 1272 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 1273 VolumeStreamState streamState = mStreamStates[streamType]; 1274 int groupId = getVolumeGroupForStreamType(streamType); 1275 if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP 1276 && sVolumeGroupStates.indexOfKey(groupId) >= 0) { 1277 streamState.setVolumeGroupState(sVolumeGroupStates.get(groupId)); 1278 } 1279 } 1280 } 1281 } 1282 1283 /** 1284 * Called by handling of MSG_INIT_STREAMS_VOLUMES 1285 */ onInitStreamsAndVolumes()1286 private void onInitStreamsAndVolumes() { 1287 synchronized (mSettingsLock) { 1288 mCameraSoundForced = readCameraSoundForced(); 1289 sendMsg(mAudioHandler, 1290 MSG_SET_FORCE_USE, 1291 SENDMSG_QUEUE, 1292 AudioSystem.FOR_SYSTEM, 1293 mCameraSoundForced 1294 ? AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE, 1295 new String("AudioService ctor"), 1296 0); 1297 } 1298 1299 createStreamStates(); 1300 1301 // must be called after createStreamStates() as it uses MUSIC volume as default if no 1302 // persistent data 1303 initVolumeGroupStates(); 1304 1305 mSoundDoseHelper.initSafeMediaVolumeIndex(); 1306 // Link VGS on VSS 1307 initVolumeStreamStates(); 1308 1309 // Call setRingerModeInt() to apply correct mute 1310 // state on streams affected by ringer mode. 1311 sRingerAndZenModeMutedStreams = 0; 1312 sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent( 1313 sRingerAndZenModeMutedStreams, "onInitStreamsAndVolumes")); 1314 setRingerModeInt(getRingerModeInternal(), false); 1315 1316 final float[] preScale = new float[3]; 1317 preScale[0] = mContext.getResources().getFraction( 1318 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1, 1319 1, 1); 1320 preScale[1] = mContext.getResources().getFraction( 1321 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index2, 1322 1, 1); 1323 preScale[2] = mContext.getResources().getFraction( 1324 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index3, 1325 1, 1); 1326 for (int i = 0; i < preScale.length; i++) { 1327 if (0.0f <= preScale[i] && preScale[i] <= 1.0f) { 1328 mPrescaleAbsoluteVolume[i] = preScale[i]; 1329 } 1330 } 1331 1332 initExternalEventReceivers(); 1333 1334 // check on volume initialization 1335 checkVolumeRangeInitialization("AudioService()"); 1336 1337 } 1338 1339 private SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionChangedListener = 1340 new SubscriptionManager.OnSubscriptionsChangedListener() { 1341 @Override 1342 public void onSubscriptionsChanged() { 1343 Log.i(TAG, "onSubscriptionsChanged()"); 1344 sendMsg(mAudioHandler, MSG_CONFIGURATION_CHANGED, SENDMSG_REPLACE, 1345 0, 0, null, 0); 1346 } 1347 }; 1348 1349 /** 1350 * Initialize intent receives and settings observers for this service. 1351 * Must be called after createStreamStates() as the handling of some events 1352 * may affect or need volumes, e.g. BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED 1353 * (for intent receiver), or Settings.Global.ZEN_MODE (for settings observer) 1354 */ initExternalEventReceivers()1355 private void initExternalEventReceivers() { 1356 mSettingsObserver = new SettingsObserver(); 1357 1358 // Register for device connection intent broadcasts. 1359 IntentFilter intentFilter = 1360 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); 1361 intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED); 1362 intentFilter.addAction(Intent.ACTION_DOCK_EVENT); 1363 intentFilter.addAction(Intent.ACTION_SCREEN_ON); 1364 intentFilter.addAction(Intent.ACTION_SCREEN_OFF); 1365 intentFilter.addAction(Intent.ACTION_USER_SWITCHED); 1366 intentFilter.addAction(Intent.ACTION_USER_BACKGROUND); 1367 intentFilter.addAction(Intent.ACTION_USER_FOREGROUND); 1368 intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); 1369 intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED); 1370 1371 intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); 1372 if (mMonitorRotation) { 1373 RotationHelper.init(mContext, mAudioHandler, 1374 rotation -> onRotationUpdate(rotation), 1375 foldState -> onFoldStateUpdate(foldState)); 1376 } 1377 1378 intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION); 1379 intentFilter.addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION); 1380 intentFilter.addAction(ACTION_CHECK_MUSIC_ACTIVE); 1381 intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); 1382 1383 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null, 1384 Context.RECEIVER_EXPORTED); 1385 1386 SubscriptionManager subscriptionManager = mContext.getSystemService( 1387 SubscriptionManager.class); 1388 if (subscriptionManager == null) { 1389 Log.e(TAG, "initExternalEventReceivers cannot create SubscriptionManager!"); 1390 } else { 1391 subscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionChangedListener); 1392 } 1393 } 1394 systemReady()1395 public void systemReady() { 1396 sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE, 1397 0, 0, null, 0); 1398 if (false) { 1399 // This is turned off for now, because it is racy and thus causes apps to break. 1400 // Currently banning a uid means that if an app tries to start playing an audio 1401 // stream, that will be preventing, and unbanning it will not allow that stream 1402 // to resume. However these changes in uid state are racy with what the app is doing, 1403 // so that after taking a process out of the cached state we can't guarantee that 1404 // we will unban the uid before the app actually tries to start playing audio. 1405 // (To do that, the activity manager would need to wait until it knows for sure 1406 // that the ban has been removed, before telling the app to do whatever it is 1407 // supposed to do that caused it to go out of the cached state.) 1408 try { 1409 ActivityManager.getService().registerUidObserver(mUidObserver, 1410 ActivityManager.UID_OBSERVER_CACHED | ActivityManager.UID_OBSERVER_GONE, 1411 ActivityManager.PROCESS_STATE_UNKNOWN, null); 1412 } catch (RemoteException e) { 1413 // ignored; both services live in system_server 1414 } 1415 } 1416 } 1417 updateVibratorInfos()1418 private void updateVibratorInfos() { 1419 VibratorManager vibratorManager = mContext.getSystemService(VibratorManager.class); 1420 if (vibratorManager == null) { 1421 Slog.e(TAG, "Vibrator manager is not found"); 1422 return; 1423 } 1424 int[] vibratorIds = vibratorManager.getVibratorIds(); 1425 if (vibratorIds.length == 0) { 1426 Slog.d(TAG, "No vibrator found"); 1427 return; 1428 } 1429 List<Vibrator> vibrators = new ArrayList<>(vibratorIds.length); 1430 for (int id : vibratorIds) { 1431 Vibrator vibrator = vibratorManager.getVibrator(id); 1432 if (vibrator != null) { 1433 vibrators.add(vibrator); 1434 } else { 1435 Slog.w(TAG, "Vibrator(" + id + ") is not found"); 1436 } 1437 } 1438 if (vibrators.isEmpty()) { 1439 Slog.w(TAG, "Cannot find any available vibrator"); 1440 return; 1441 } 1442 AudioSystem.setVibratorInfos(vibrators); 1443 } 1444 onSystemReady()1445 public void onSystemReady() { 1446 mSystemReady = true; 1447 scheduleLoadSoundEffects(); 1448 1449 mDeviceBroker.onSystemReady(); 1450 1451 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) { 1452 synchronized (mHdmiClientLock) { 1453 mHdmiManager = mContext.getSystemService(HdmiControlManager.class); 1454 if (mHdmiManager != null) { 1455 mHdmiManager.addHdmiControlStatusChangeListener( 1456 mHdmiControlStatusChangeListenerCallback); 1457 mHdmiManager.addHdmiCecVolumeControlFeatureListener(mContext.getMainExecutor(), 1458 mMyHdmiCecVolumeControlFeatureListener); 1459 } 1460 mHdmiTvClient = mHdmiManager.getTvClient(); 1461 if (mHdmiTvClient != null) { 1462 mFixedVolumeDevices.removeAll( 1463 AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET); 1464 } 1465 mHdmiPlaybackClient = mHdmiManager.getPlaybackClient(); 1466 mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient(); 1467 } 1468 } 1469 1470 if (mSupportsMicPrivacyToggle) { 1471 mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers( 1472 SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> { 1473 if (userId == getCurrentUserId()) { 1474 mMicMuteFromPrivacyToggle = enabled; 1475 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); 1476 } 1477 }); 1478 } 1479 1480 mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 1481 1482 mSoundDoseHelper.configureSafeMedia(/*forced=*/true, TAG); 1483 1484 initA11yMonitoring(); 1485 1486 mRoleObserver = new RoleObserver(); 1487 mRoleObserver.register(); 1488 1489 onIndicateSystemReady(); 1490 1491 mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted(); 1492 setMicMuteFromSwitchInput(); 1493 1494 initMinStreamVolumeWithoutModifyAudioSettings(); 1495 1496 updateVibratorInfos(); 1497 1498 synchronized (mSupportedSystemUsagesLock) { 1499 AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages); 1500 } 1501 } 1502 1503 //----------------------------------------------------------------- 1504 // routing monitoring from AudioSystemAdapter 1505 @Override onRoutingUpdatedFromNative()1506 public void onRoutingUpdatedFromNative() { 1507 sendMsg(mAudioHandler, 1508 MSG_ROUTING_UPDATED, 1509 SENDMSG_REPLACE, 0, 0, null, 1510 /*delay*/ 0); 1511 } 1512 1513 /** 1514 * called when handling MSG_ROUTING_UPDATED 1515 */ onRoutingUpdatedFromAudioThread()1516 void onRoutingUpdatedFromAudioThread() { 1517 if (mHasSpatializerEffect) { 1518 mSpatializerHelper.onRoutingUpdated(); 1519 } 1520 checkMuteAwaitConnection(); 1521 } 1522 1523 //----------------------------------------------------------------- 1524 // rotation/fold updates coming from RotationHelper onRotationUpdate(Integer rotation)1525 void onRotationUpdate(Integer rotation) { 1526 mSpatializerHelper.setDisplayOrientation((float) (rotation * Math.PI / 180.)); 1527 // use REPLACE as only the last rotation matters 1528 final String rotationParameter = "rotation=" + rotation; 1529 sendMsg(mAudioHandler, MSG_ROTATION_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0, 1530 /*obj*/ rotationParameter, /*delay*/ 0); 1531 } 1532 onFoldStateUpdate(Boolean foldState)1533 void onFoldStateUpdate(Boolean foldState) { 1534 mSpatializerHelper.setFoldState(foldState); 1535 // use REPLACE as only the last fold state matters 1536 final String foldStateParameter = "device_folded=" + (foldState ? "on" : "off"); 1537 sendMsg(mAudioHandler, MSG_FOLD_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0, 1538 /*obj*/ foldStateParameter, /*delay*/ 0); 1539 } 1540 1541 //----------------------------------------------------------------- 1542 // Communicate to PlayackActivityMonitor whether to log or not 1543 // the sound FX activity (useful for removing touch sounds in the activity logs) ignorePlayerLogs(@onNull PlayerBase playerToIgnore)1544 void ignorePlayerLogs(@NonNull PlayerBase playerToIgnore) { 1545 if (DEBUG_LOG_SOUND_FX) { 1546 return; 1547 } 1548 sendMsg(mAudioHandler, MSG_NO_LOG_FOR_PLAYER_I, SENDMSG_REPLACE, 1549 /*arg1, piid of the player*/ playerToIgnore.getPlayerIId(), 1550 /*arg2 ignored*/ 0, /*obj ignored*/ null, /*delay*/ 0); 1551 } 1552 1553 //----------------------------------------------------------------- 1554 // monitoring requests for volume range initialization 1555 @Override // AudioSystemAdapter.OnVolRangeInitRequestListener onVolumeRangeInitRequestFromNative()1556 public void onVolumeRangeInitRequestFromNative() { 1557 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_REPLACE, 0, 0, 1558 "onVolumeRangeInitRequestFromNative" /*obj: caller, for dumpsys*/, /*delay*/ 0); 1559 } 1560 1561 //----------------------------------------------------------------- 1562 RoleObserver mRoleObserver; 1563 1564 class RoleObserver implements OnRoleHoldersChangedListener { 1565 private RoleManager mRm; 1566 private final Executor mExecutor; 1567 RoleObserver()1568 RoleObserver() { 1569 mExecutor = mContext.getMainExecutor(); 1570 } 1571 register()1572 public void register() { 1573 mRm = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE); 1574 if (mRm != null) { 1575 mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL); 1576 synchronized (mSettingsLock) { 1577 updateAssistantUIdLocked(/* forceUpdate= */ true); 1578 } 1579 } 1580 } 1581 1582 @Override onRoleHoldersChanged(@onNull String roleName, @NonNull UserHandle user)1583 public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) { 1584 if (RoleManager.ROLE_ASSISTANT.equals(roleName)) { 1585 synchronized (mSettingsLock) { 1586 updateAssistantUIdLocked(/* forceUpdate= */ false); 1587 } 1588 } 1589 } 1590 getAssistantRoleHolder()1591 public String getAssistantRoleHolder() { 1592 String assitantPackage = ""; 1593 if (mRm != null) { 1594 List<String> assistants = mRm.getRoleHolders(RoleManager.ROLE_ASSISTANT); 1595 assitantPackage = assistants.size() == 0 ? "" : assistants.get(0); 1596 } 1597 return assitantPackage; 1598 } 1599 } 1600 onIndicateSystemReady()1601 void onIndicateSystemReady() { 1602 if (AudioSystem.systemReady() == AudioSystem.SUCCESS) { 1603 return; 1604 } 1605 sendMsg(mAudioHandler, 1606 MSG_INDICATE_SYSTEM_READY, 1607 SENDMSG_REPLACE, 1608 0, 1609 0, 1610 null, 1611 INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 1612 } 1613 onAudioServerDied()1614 public void onAudioServerDied() { 1615 if (!mSystemReady || 1616 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) { 1617 Log.e(TAG, "Audioserver died."); 1618 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 1619 "onAudioServerDied() audioserver died")); 1620 sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0, 1621 null, 500); 1622 return; 1623 } 1624 Log.i(TAG, "Audioserver started."); 1625 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 1626 "onAudioServerDied() audioserver started")); 1627 1628 updateAudioHalPids(); 1629 1630 // indicate to audio HAL that we start the reconfiguration phase after a media 1631 // server crash 1632 // Note that we only execute this when the media server 1633 // process restarts after a crash, not the first time it is started. 1634 AudioSystem.setParameters("restarting=true"); 1635 1636 readAndSetLowRamDevice(); 1637 1638 mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported(); 1639 1640 // Restore device connection states, BT state 1641 mDeviceBroker.onAudioServerDied(); 1642 1643 // Restore call state 1644 synchronized (mDeviceBroker.mSetModeLock) { 1645 onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(), 1646 mContext.getPackageName(), true /*force*/); 1647 } 1648 final int forSys; 1649 synchronized (mSettingsLock) { 1650 forSys = mCameraSoundForced ? 1651 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE; 1652 } 1653 1654 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, forSys, "onAudioServerDied"); 1655 1656 // Restore stream volumes 1657 onReinitVolumes("after audioserver restart"); 1658 1659 // Restore audio volume groups 1660 restoreVolumeGroups(); 1661 1662 // Restore mono mode 1663 updateMasterMono(mContentResolver); 1664 1665 // Restore audio balance 1666 updateMasterBalance(mContentResolver); 1667 1668 // Restore ringer mode 1669 setRingerModeInt(getRingerModeInternal(), false); 1670 1671 // Reset device rotation (if monitored for this device) 1672 if (mMonitorRotation) { 1673 RotationHelper.updateOrientation(); 1674 } 1675 1676 // Restore setParameters and other queued setters. 1677 mRestorableParameters.restoreAll(); 1678 1679 synchronized (mSettingsLock) { 1680 final int forDock = mDockAudioMediaEnabled ? 1681 AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE; 1682 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, forDock, "onAudioServerDied"); 1683 sendEncodedSurroundMode(mContentResolver, "onAudioServerDied"); 1684 sendEnabledSurroundFormats(mContentResolver, true); 1685 AudioSystem.setRttEnabled(mRttEnabled); 1686 resetAssistantServicesUidsLocked(); 1687 } 1688 1689 synchronized (mAccessibilityServiceUidsLock) { 1690 AudioSystem.setA11yServicesUids(mAccessibilityServiceUids); 1691 } 1692 synchronized (mInputMethodServiceUidLock) { 1693 mAudioSystem.setCurrentImeUid(mInputMethodServiceUid); 1694 } 1695 synchronized (mHdmiClientLock) { 1696 if (mHdmiManager != null && mHdmiTvClient != null) { 1697 setHdmiSystemAudioSupported(mHdmiSystemAudioSupported); 1698 } 1699 } 1700 1701 synchronized (mSupportedSystemUsagesLock) { 1702 AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages); 1703 } 1704 1705 synchronized (mAudioPolicies) { 1706 ArrayList<AudioPolicyProxy> invalidProxies = new ArrayList<>(); 1707 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 1708 final int status = policy.connectMixes(); 1709 if (status != AudioSystem.SUCCESS) { 1710 // note that PERMISSION_DENIED may also indicate trouble getting to APService 1711 Log.e(TAG, "onAudioServerDied: error " 1712 + AudioSystem.audioSystemErrorToString(status) 1713 + " when connecting mixes for policy " + policy.toLogFriendlyString()); 1714 invalidProxies.add(policy); 1715 } else { 1716 final int deviceAffinitiesStatus = policy.setupDeviceAffinities(); 1717 if (deviceAffinitiesStatus != AudioSystem.SUCCESS) { 1718 Log.e(TAG, "onAudioServerDied: error " 1719 + AudioSystem.audioSystemErrorToString(deviceAffinitiesStatus) 1720 + " when connecting device affinities for policy " 1721 + policy.toLogFriendlyString()); 1722 invalidProxies.add(policy); 1723 } 1724 } 1725 } 1726 invalidProxies.forEach((policy) -> policy.release()); 1727 1728 } 1729 1730 // Restore capture policies 1731 synchronized (mPlaybackMonitor) { 1732 HashMap<Integer, Integer> allowedCapturePolicies = 1733 mPlaybackMonitor.getAllAllowedCapturePolicies(); 1734 for (HashMap.Entry<Integer, Integer> entry : allowedCapturePolicies.entrySet()) { 1735 int result = mAudioSystem.setAllowedCapturePolicy( 1736 entry.getKey(), 1737 AudioAttributes.capturePolicyToFlags(entry.getValue(), 0x0)); 1738 if (result != AudioSystem.AUDIO_STATUS_OK) { 1739 Log.e(TAG, "Failed to restore capture policy, uid: " 1740 + entry.getKey() + ", capture policy: " + entry.getValue() 1741 + ", result: " + result); 1742 // When restoring capture policy failed, set the capture policy as 1743 // ALLOW_CAPTURE_BY_ALL, which will result in removing the cached 1744 // capture policy in PlaybackActivityMonitor. 1745 mPlaybackMonitor.setAllowedCapturePolicy( 1746 entry.getKey(), AudioAttributes.ALLOW_CAPTURE_BY_ALL); 1747 } 1748 } 1749 } 1750 1751 mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect); 1752 mSoundDoseHelper.reset(); 1753 1754 // Restore rotation information. 1755 if (mMonitorRotation) { 1756 RotationHelper.forceUpdate(); 1757 } 1758 1759 onIndicateSystemReady(); 1760 // indicate the end of reconfiguration phase to audio HAL 1761 AudioSystem.setParameters("restarting=false"); 1762 1763 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE, 1764 SENDMSG_QUEUE, 1, 0, null, 0); 1765 1766 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); // will also update the mic mute cache 1767 setMicMuteFromSwitchInput(); 1768 1769 // Restore vibrator info 1770 updateVibratorInfos(); 1771 } 1772 onRemoveAssistantServiceUids(int[] uids)1773 private void onRemoveAssistantServiceUids(int[] uids) { 1774 synchronized (mSettingsLock) { 1775 removeAssistantServiceUidsLocked(uids); 1776 } 1777 } 1778 1779 @GuardedBy("mSettingsLock") removeAssistantServiceUidsLocked(int[] uids)1780 private void removeAssistantServiceUidsLocked(int[] uids) { 1781 boolean changed = false; 1782 for (int index = 0; index < uids.length; index++) { 1783 if (!mAssistantUids.remove(uids[index])) { 1784 Slog.e(TAG, TextUtils.formatSimple( 1785 "Cannot remove assistant service, uid(%d) not present", uids[index])); 1786 continue; 1787 } 1788 changed = true; 1789 } 1790 if (changed) { 1791 updateAssistantServicesUidsLocked(); 1792 } 1793 } 1794 onAddAssistantServiceUids(int[] uids)1795 private void onAddAssistantServiceUids(int[] uids) { 1796 synchronized (mSettingsLock) { 1797 addAssistantServiceUidsLocked(uids); 1798 } 1799 } 1800 1801 @GuardedBy("mSettingsLock") addAssistantServiceUidsLocked(int[] uids)1802 private void addAssistantServiceUidsLocked(int[] uids) { 1803 boolean changed = false; 1804 for (int index = 0; index < uids.length; index++) { 1805 if (uids[index] == INVALID_UID) { 1806 continue; 1807 } 1808 if (!mAssistantUids.add(uids[index])) { 1809 Slog.e(TAG, TextUtils.formatSimple( 1810 "Cannot add assistant service, uid(%d) already present", 1811 uids[index])); 1812 continue; 1813 } 1814 changed = true; 1815 } 1816 if (changed) { 1817 updateAssistantServicesUidsLocked(); 1818 } 1819 } 1820 1821 @GuardedBy("mSettingsLock") resetAssistantServicesUidsLocked()1822 private void resetAssistantServicesUidsLocked() { 1823 mAssistantUids.clear(); 1824 updateAssistantUIdLocked(/* forceUpdate= */ true); 1825 } 1826 1827 @GuardedBy("mSettingsLock") updateAssistantServicesUidsLocked()1828 private void updateAssistantServicesUidsLocked() { 1829 int[] assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray(); 1830 AudioSystem.setAssistantServicesUids(assistantUids); 1831 } 1832 updateActiveAssistantServiceUids()1833 private void updateActiveAssistantServiceUids() { 1834 int [] activeAssistantServiceUids; 1835 synchronized (mSettingsLock) { 1836 activeAssistantServiceUids = mActiveAssistantServiceUids; 1837 } 1838 AudioSystem.setActiveAssistantServicesUids(activeAssistantServiceUids); 1839 } 1840 onReinitVolumes(@onNull String caller)1841 private void onReinitVolumes(@NonNull String caller) { 1842 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 1843 // keep track of any error during stream volume initialization 1844 int status = AudioSystem.AUDIO_STATUS_OK; 1845 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 1846 VolumeStreamState streamState = mStreamStates[streamType]; 1847 final int res = AudioSystem.initStreamVolume( 1848 streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10); 1849 if (res != AudioSystem.AUDIO_STATUS_OK) { 1850 status = res; 1851 Log.e(TAG, "Failed to initStreamVolume (" + res + ") for stream " + streamType); 1852 // stream volume initialization failed, no need to try the others, it will be 1853 // attempted again when MSG_REINIT_VOLUMES is handled 1854 break; 1855 } 1856 streamState.applyAllVolumes(); 1857 } 1858 1859 // did it work? check based on status 1860 if (status != AudioSystem.AUDIO_STATUS_OK) { 1861 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 1862 caller + ": initStreamVolume failed with " + status + " will retry") 1863 .printLog(ALOGE, TAG)); 1864 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 1865 caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 1866 return; 1867 } 1868 1869 // did it work? check based on min/max values of some basic streams 1870 if (!checkVolumeRangeInitialization(caller)) { 1871 return; 1872 } 1873 1874 // success 1875 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 1876 caller + ": initStreamVolume succeeded").printLog(ALOGI, TAG)); 1877 } 1878 1879 /** 1880 * Check volume ranges were properly initialized 1881 * @return true if volume ranges were successfully initialized 1882 */ checkVolumeRangeInitialization(String caller)1883 private boolean checkVolumeRangeInitialization(String caller) { 1884 boolean success = true; 1885 final int[] basicStreams = { AudioSystem.STREAM_ALARM, AudioSystem.STREAM_RING, 1886 AudioSystem.STREAM_MUSIC, AudioSystem.STREAM_VOICE_CALL, 1887 AudioSystem.STREAM_ACCESSIBILITY }; 1888 for (int streamType : basicStreams) { 1889 final AudioAttributes aa = new AudioAttributes.Builder() 1890 .setInternalLegacyStreamType(streamType).build(); 1891 if (AudioSystem.getMaxVolumeIndexForAttributes(aa) < 0 1892 || AudioSystem.getMinVolumeIndexForAttributes(aa) < 0) { 1893 success = false; 1894 break; 1895 } 1896 } 1897 if (!success) { 1898 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 1899 caller + ": initStreamVolume succeeded but invalid mix/max levels, will retry") 1900 .printLog(ALOGW, TAG)); 1901 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 1902 caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 1903 } 1904 return success; 1905 } 1906 onDispatchAudioServerStateChange(boolean state)1907 private void onDispatchAudioServerStateChange(boolean state) { 1908 synchronized (mAudioServerStateListeners) { 1909 for (AsdProxy asdp : mAudioServerStateListeners.values()) { 1910 try { 1911 asdp.callback().dispatchAudioServerStateChange(state); 1912 } catch (RemoteException e) { 1913 Log.w(TAG, "Could not call dispatchAudioServerStateChange()", e); 1914 } 1915 } 1916 } 1917 } 1918 createAudioSystemThread()1919 private void createAudioSystemThread() { 1920 mAudioSystemThread = new AudioSystemThread(); 1921 mAudioSystemThread.start(); 1922 waitForAudioHandlerCreation(); 1923 } 1924 1925 /** Waits for the volume handler to be created by the other thread. */ waitForAudioHandlerCreation()1926 private void waitForAudioHandlerCreation() { 1927 synchronized(this) { 1928 while (mAudioHandler == null) { 1929 try { 1930 // Wait for mAudioHandler to be set by the other thread 1931 wait(); 1932 } catch (InterruptedException e) { 1933 Log.e(TAG, "Interrupted while waiting on volume handler."); 1934 } 1935 } 1936 } 1937 } 1938 1939 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 1940 /** 1941 * @see AudioManager#setSupportedSystemUsages(int[]) 1942 */ setSupportedSystemUsages(@onNull @ttributeSystemUsage int[] systemUsages)1943 public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) { 1944 super.setSupportedSystemUsages_enforcePermission(); 1945 1946 verifySystemUsages(systemUsages); 1947 1948 synchronized (mSupportedSystemUsagesLock) { 1949 AudioSystem.setSupportedSystemUsages(systemUsages); 1950 mSupportedSystemUsages = systemUsages; 1951 } 1952 } 1953 1954 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 1955 /** 1956 * @see AudioManager#getSupportedSystemUsages() 1957 */ getSupportedSystemUsages()1958 public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() { 1959 super.getSupportedSystemUsages_enforcePermission(); 1960 1961 synchronized (mSupportedSystemUsagesLock) { 1962 return Arrays.copyOf(mSupportedSystemUsages, mSupportedSystemUsages.length); 1963 } 1964 } 1965 verifySystemUsages(@onNull int[] systemUsages)1966 private void verifySystemUsages(@NonNull int[] systemUsages) { 1967 for (int i = 0; i < systemUsages.length; i++) { 1968 if (!AudioAttributes.isSystemUsage(systemUsages[i])) { 1969 throw new IllegalArgumentException("Non-system usage provided: " + systemUsages[i]); 1970 } 1971 } 1972 } 1973 1974 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 1975 /** 1976 * @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the 1977 * platform configuration file. 1978 */ 1979 @NonNull getAudioProductStrategies()1980 public List<AudioProductStrategy> getAudioProductStrategies() { 1981 // verify permissions 1982 super.getAudioProductStrategies_enforcePermission(); 1983 1984 return AudioProductStrategy.getAudioProductStrategies(); 1985 } 1986 1987 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 1988 /** 1989 * @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the 1990 * platform configuration file. 1991 */ 1992 @NonNull getAudioVolumeGroups()1993 public List<AudioVolumeGroup> getAudioVolumeGroups() { 1994 // verify permissions 1995 super.getAudioVolumeGroups_enforcePermission(); 1996 1997 return AudioVolumeGroup.getAudioVolumeGroups(); 1998 } 1999 checkAllAliasStreamVolumes()2000 private void checkAllAliasStreamVolumes() { 2001 synchronized (mSettingsLock) { 2002 synchronized (VolumeStreamState.class) { 2003 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2004 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 2005 mStreamStates[streamType] 2006 .setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]], TAG); 2007 // apply stream volume 2008 if (!mStreamStates[streamType].mIsMuted) { 2009 mStreamStates[streamType].applyAllVolumes(); 2010 } 2011 } 2012 } 2013 } 2014 } 2015 2016 2017 /** 2018 * Called from AudioDeviceBroker when DEVICE_OUT_HDMI is connected or disconnected. 2019 */ postCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2020 /*package*/ void postCheckVolumeCecOnHdmiConnection( 2021 @AudioService.ConnectionState int state, String caller) { 2022 sendMsg(mAudioHandler, MSG_HDMI_VOLUME_CHECK, SENDMSG_REPLACE, 2023 state /*arg1*/, 0 /*arg2 ignored*/, caller /*obj*/, 0 /*delay*/); 2024 } 2025 onCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2026 private void onCheckVolumeCecOnHdmiConnection( 2027 @AudioService.ConnectionState int state, String caller) { 2028 if (state == AudioService.CONNECTION_STATE_CONNECTED) { 2029 // DEVICE_OUT_HDMI is now connected 2030 if (mSoundDoseHelper.safeDevicesContains(AudioSystem.DEVICE_OUT_HDMI)) { 2031 mSoundDoseHelper.scheduleMusicActiveCheck(); 2032 } 2033 2034 if (isPlatformTelevision()) { 2035 synchronized (mHdmiClientLock) { 2036 if (mHdmiManager != null && mHdmiPlaybackClient != null) { 2037 updateHdmiCecSinkLocked( 2038 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)); 2039 } 2040 } 2041 } 2042 sendEnabledSurroundFormats(mContentResolver, true); 2043 } else { 2044 // DEVICE_OUT_HDMI disconnected 2045 if (isPlatformTelevision()) { 2046 synchronized (mHdmiClientLock) { 2047 if (mHdmiManager != null) { 2048 updateHdmiCecSinkLocked( 2049 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)); 2050 } 2051 } 2052 } 2053 } 2054 } 2055 2056 /** 2057 * Asynchronously update volume states for the given device. 2058 * 2059 * @param device a single audio device, ensure that this is not a devices bitmask 2060 * @param caller caller of this method 2061 */ postUpdateVolumeStatesForAudioDevice(int device, String caller)2062 private void postUpdateVolumeStatesForAudioDevice(int device, String caller) { 2063 sendMsg(mAudioHandler, 2064 MSG_UPDATE_VOLUME_STATES_FOR_DEVICE, 2065 SENDMSG_QUEUE, device /*arg1*/, 0 /*arg2*/, caller /*obj*/, 2066 0 /*delay*/); 2067 } 2068 2069 /** 2070 * Update volume states for the given device. 2071 * 2072 * This will initialize the volume index if no volume index is available. 2073 * If the device is the currently routed device, fixed/full volume policies will be applied. 2074 * 2075 * @param device a single audio device, ensure that this is not a devices bitmask 2076 * @param caller caller of this method 2077 */ onUpdateVolumeStatesForAudioDevice(int device, String caller)2078 private void onUpdateVolumeStatesForAudioDevice(int device, String caller) { 2079 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 2080 synchronized (mSettingsLock) { 2081 synchronized (VolumeStreamState.class) { 2082 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 2083 updateVolumeStates(device, streamType, caller); 2084 } 2085 } 2086 } 2087 } 2088 2089 /** 2090 * Update volume states for the given device and given stream. 2091 * 2092 * This will initialize the volume index if no volume index is available. 2093 * If the device is the currently routed device, fixed/full volume policies will be applied. 2094 * 2095 * @param device a single audio device, ensure that this is not a devices bitmask 2096 * @param streamType streamType to be updated 2097 * @param caller caller of this method 2098 */ updateVolumeStates(int device, int streamType, String caller)2099 private void updateVolumeStates(int device, int streamType, String caller) { 2100 // Handle device volume aliasing of SPEAKER_SAFE. 2101 if (device == AudioSystem.DEVICE_OUT_SPEAKER_SAFE) { 2102 device = AudioSystem.DEVICE_OUT_SPEAKER; 2103 } 2104 if (!mStreamStates[streamType].hasIndexForDevice(device)) { 2105 // set the default value, if device is affected by a full/fix/abs volume rule, it 2106 // will taken into account in checkFixedVolumeDevices() 2107 mStreamStates[streamType].setIndex( 2108 mStreamStates[mStreamVolumeAlias[streamType]] 2109 .getIndex(AudioSystem.DEVICE_OUT_DEFAULT), 2110 device, caller, true /*hasModifyAudioSettings*/); 2111 } 2112 2113 // Check if device to be updated is routed for the given audio stream 2114 // This may include devices such as SPEAKER_SAFE. 2115 List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributesInt( 2116 new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build(), 2117 true /* forVolume */); 2118 for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) { 2119 if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType( 2120 device)) { 2121 mStreamStates[streamType].checkFixedVolumeDevices(); 2122 2123 // Unmute streams if required and device is full volume 2124 if (isStreamMute(streamType) && mFullVolumeDevices.contains(device)) { 2125 mStreamStates[streamType].mute(false, "updateVolumeStates(" + caller); 2126 } 2127 } 2128 } 2129 } 2130 checkAllFixedVolumeDevices()2131 private void checkAllFixedVolumeDevices() 2132 { 2133 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2134 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 2135 mStreamStates[streamType].checkFixedVolumeDevices(); 2136 } 2137 } 2138 checkAllFixedVolumeDevices(int streamType)2139 private void checkAllFixedVolumeDevices(int streamType) { 2140 mStreamStates[streamType].checkFixedVolumeDevices(); 2141 } 2142 checkMuteAffectedStreams()2143 private void checkMuteAffectedStreams() { 2144 // any stream with a min level > 0 is not muteable by definition 2145 // STREAM_VOICE_CALL and STREAM_BLUETOOTH_SCO can be muted by applications 2146 // that has the the MODIFY_PHONE_STATE permission. 2147 for (int i = 0; i < mStreamStates.length; i++) { 2148 final VolumeStreamState vss = mStreamStates[i]; 2149 if (vss.mIndexMin > 0 && 2150 (vss.mStreamType != AudioSystem.STREAM_VOICE_CALL && 2151 vss.mStreamType != AudioSystem.STREAM_BLUETOOTH_SCO)) { 2152 mMuteAffectedStreams &= ~(1 << vss.mStreamType); 2153 } 2154 } 2155 } 2156 createStreamStates()2157 private void createStreamStates() { 2158 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2159 VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes]; 2160 2161 for (int i = 0; i < numStreamTypes; i++) { 2162 streams[i] = 2163 new VolumeStreamState(System.VOLUME_SETTINGS_INT[mStreamVolumeAlias[i]], i); 2164 } 2165 2166 checkAllFixedVolumeDevices(); 2167 checkAllAliasStreamVolumes(); 2168 checkMuteAffectedStreams(); 2169 updateDefaultVolumes(); 2170 } 2171 2172 /** 2173 * Update default indexes from aliased streams. Must be called after mStreamStates is created 2174 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for default 2175 * index. Need to make default index configurable and independent of streams. 2176 * Fallback on music stream for default initialization to take benefit of property based default 2177 * initialization. 2178 * For other volume groups not linked to any streams, default music stream index is considered. 2179 */ updateDefaultVolumes()2180 private void updateDefaultVolumes() { 2181 for (int stream = 0; stream < mStreamStates.length; stream++) { 2182 int streamVolumeAlias = mStreamVolumeAlias[stream]; 2183 if (mUseVolumeGroupAliases) { 2184 if (AudioSystem.DEFAULT_STREAM_VOLUME[stream] != UNSET_INDEX) { 2185 // Already initialized through default property based mecanism. 2186 continue; 2187 } 2188 streamVolumeAlias = AudioSystem.STREAM_MUSIC; 2189 int defaultAliasVolume = getUiDefaultRescaledIndex(streamVolumeAlias, stream); 2190 if ((defaultAliasVolume >= MIN_STREAM_VOLUME[stream]) 2191 && (defaultAliasVolume <= MAX_STREAM_VOLUME[stream])) { 2192 AudioSystem.DEFAULT_STREAM_VOLUME[stream] = defaultAliasVolume; 2193 continue; 2194 } 2195 } 2196 if (stream != streamVolumeAlias) { 2197 AudioSystem.DEFAULT_STREAM_VOLUME[stream] = 2198 getUiDefaultRescaledIndex(streamVolumeAlias, stream); 2199 } 2200 } 2201 } 2202 getUiDefaultRescaledIndex(int srcStream, int dstStream)2203 private int getUiDefaultRescaledIndex(int srcStream, int dstStream) { 2204 return (rescaleIndex(AudioSystem.DEFAULT_STREAM_VOLUME[srcStream] * 10, 2205 srcStream, dstStream) + 5) / 10; 2206 } 2207 dumpStreamStates(PrintWriter pw)2208 private void dumpStreamStates(PrintWriter pw) { 2209 pw.println("\nStream volumes (device: index)"); 2210 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2211 for (int i = 0; i < numStreamTypes; i++) { 2212 StringBuilder alias = new StringBuilder(); 2213 if (mStreamVolumeAlias[i] != i) { 2214 alias.append(" (aliased to: ") 2215 .append(AudioSystem.STREAM_NAMES[mStreamVolumeAlias[i]]) 2216 .append(")"); 2217 } 2218 pw.println("- " + AudioSystem.STREAM_NAMES[i] + alias + ":"); 2219 mStreamStates[i].dump(pw); 2220 pw.println(""); 2221 } 2222 pw.print("\n- mute affected streams = 0x"); 2223 pw.println(Integer.toHexString(mMuteAffectedStreams)); 2224 } 2225 updateStreamVolumeAlias(boolean updateVolumes, String caller)2226 private void updateStreamVolumeAlias(boolean updateVolumes, String caller) { 2227 int dtmfStreamAlias; 2228 final int a11yStreamAlias = sIndependentA11yVolume ? 2229 AudioSystem.STREAM_ACCESSIBILITY : AudioSystem.STREAM_MUSIC; 2230 final int assistantStreamAlias = mContext.getResources().getBoolean( 2231 com.android.internal.R.bool.config_useAssistantVolume) ? 2232 AudioSystem.STREAM_ASSISTANT : AudioSystem.STREAM_MUSIC; 2233 2234 if (mIsSingleVolume) { 2235 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION.clone(); 2236 dtmfStreamAlias = AudioSystem.STREAM_MUSIC; 2237 } else if (mUseVolumeGroupAliases) { 2238 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_NONE.clone(); 2239 dtmfStreamAlias = AudioSystem.STREAM_DTMF; 2240 } else { 2241 switch (mPlatformType) { 2242 case AudioSystem.PLATFORM_VOICE: 2243 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_VOICE.clone(); 2244 dtmfStreamAlias = AudioSystem.STREAM_RING; 2245 break; 2246 default: 2247 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_DEFAULT.clone(); 2248 dtmfStreamAlias = AudioSystem.STREAM_MUSIC; 2249 } 2250 if (!mNotifAliasRing) { 2251 mStreamVolumeAlias[AudioSystem.STREAM_NOTIFICATION] = 2252 AudioSystem.STREAM_NOTIFICATION; 2253 } 2254 } 2255 2256 if (mIsSingleVolume) { 2257 mRingerModeAffectedStreams = 0; 2258 } else { 2259 if (isInCommunication()) { 2260 dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL; 2261 mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF); 2262 } else { 2263 mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF); 2264 } 2265 } 2266 2267 mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias; 2268 mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias; 2269 mStreamVolumeAlias[AudioSystem.STREAM_ASSISTANT] = assistantStreamAlias; 2270 2271 if (updateVolumes && mStreamStates != null) { 2272 updateDefaultVolumes(); 2273 2274 synchronized (mSettingsLock) { 2275 synchronized (VolumeStreamState.class) { 2276 mStreamStates[AudioSystem.STREAM_DTMF] 2277 .setAllIndexes(mStreamStates[dtmfStreamAlias], caller); 2278 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setSettingName( 2279 System.VOLUME_SETTINGS_INT[a11yStreamAlias]); 2280 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setAllIndexes( 2281 mStreamStates[a11yStreamAlias], caller); 2282 } 2283 } 2284 if (sIndependentA11yVolume) { 2285 // restore the a11y values from the settings 2286 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].readSettings(); 2287 } 2288 2289 // apply stream mute states according to new value of mRingerModeAffectedStreams 2290 setRingerModeInt(getRingerModeInternal(), false); 2291 sendMsg(mAudioHandler, 2292 MSG_SET_ALL_VOLUMES, 2293 SENDMSG_QUEUE, 2294 0, 2295 0, 2296 mStreamStates[AudioSystem.STREAM_DTMF], 0); 2297 sendMsg(mAudioHandler, 2298 MSG_SET_ALL_VOLUMES, 2299 SENDMSG_QUEUE, 2300 0, 2301 0, 2302 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY], 0); 2303 } 2304 dispatchStreamAliasingUpdate(); 2305 } 2306 readDockAudioSettings(ContentResolver cr)2307 private void readDockAudioSettings(ContentResolver cr) 2308 { 2309 mDockAudioMediaEnabled = mSettings.getGlobalInt( 2310 cr, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED, 0) == 1; 2311 2312 sendMsg(mAudioHandler, 2313 MSG_SET_FORCE_USE, 2314 SENDMSG_QUEUE, 2315 AudioSystem.FOR_DOCK, 2316 mDockAudioMediaEnabled ? 2317 AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE, 2318 new String("readDockAudioSettings"), 2319 0); 2320 2321 } 2322 2323 updateMasterMono(ContentResolver cr)2324 private void updateMasterMono(ContentResolver cr) 2325 { 2326 final boolean masterMono = mSettings.getSystemIntForUser( 2327 cr, System.MASTER_MONO, 0 /* default */, UserHandle.USER_CURRENT) == 1; 2328 if (DEBUG_VOL) { 2329 Log.d(TAG, String.format("Master mono %b", masterMono)); 2330 } 2331 AudioSystem.setMasterMono(masterMono); 2332 } 2333 updateMasterBalance(ContentResolver cr)2334 private void updateMasterBalance(ContentResolver cr) { 2335 final float masterBalance = System.getFloatForUser( 2336 cr, System.MASTER_BALANCE, 0.f /* default */, UserHandle.USER_CURRENT); 2337 if (DEBUG_VOL) { 2338 Log.d(TAG, String.format("Master balance %f", masterBalance)); 2339 } 2340 if (AudioSystem.setMasterBalance(masterBalance) != 0) { 2341 Log.e(TAG, String.format("setMasterBalance failed for %f", masterBalance)); 2342 } 2343 } 2344 sendEncodedSurroundMode(ContentResolver cr, String eventSource)2345 private void sendEncodedSurroundMode(ContentResolver cr, String eventSource) 2346 { 2347 final int encodedSurroundMode = mSettings.getGlobalInt( 2348 cr, Settings.Global.ENCODED_SURROUND_OUTPUT, 2349 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 2350 sendEncodedSurroundMode(encodedSurroundMode, eventSource); 2351 } 2352 sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)2353 private void sendEncodedSurroundMode(int encodedSurroundMode, String eventSource) 2354 { 2355 // initialize to guaranteed bad value 2356 int forceSetting = AudioSystem.NUM_FORCE_CONFIG; 2357 switch (encodedSurroundMode) { 2358 case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO: 2359 forceSetting = AudioSystem.FORCE_NONE; 2360 break; 2361 case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER: 2362 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_NEVER; 2363 break; 2364 case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS: 2365 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_ALWAYS; 2366 break; 2367 case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL: 2368 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_MANUAL; 2369 break; 2370 default: 2371 Log.e(TAG, "updateSurroundSoundSettings: illegal value " 2372 + encodedSurroundMode); 2373 break; 2374 } 2375 if (forceSetting != AudioSystem.NUM_FORCE_CONFIG) { 2376 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_ENCODED_SURROUND, forceSetting, 2377 eventSource); 2378 } 2379 } 2380 2381 @Override // Binder call onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)2382 public void onShellCommand(FileDescriptor in, FileDescriptor out, 2383 FileDescriptor err, String[] args, ShellCallback callback, 2384 ResultReceiver resultReceiver) { 2385 if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_AUDIO_POLICY) 2386 != PackageManager.PERMISSION_GRANTED) { 2387 throw new SecurityException("Missing MANAGE_AUDIO_POLICY permission"); 2388 } 2389 new AudioManagerShellCommand(AudioService.this).exec(this, in, out, err, 2390 args, callback, resultReceiver); 2391 } 2392 2393 /** @see AudioManager#getSurroundFormats() */ 2394 @Override getSurroundFormats()2395 public Map<Integer, Boolean> getSurroundFormats() { 2396 Map<Integer, Boolean> surroundFormats = new HashMap<>(); 2397 int status = AudioSystem.getSurroundFormats(surroundFormats); 2398 if (status != AudioManager.SUCCESS) { 2399 // fail and bail! 2400 Log.e(TAG, "getSurroundFormats failed:" + status); 2401 return new HashMap<>(); // Always return a map. 2402 } 2403 return surroundFormats; 2404 } 2405 2406 /** @see AudioManager#getReportedSurroundFormats() */ 2407 @Override getReportedSurroundFormats()2408 public List<Integer> getReportedSurroundFormats() { 2409 ArrayList<Integer> reportedSurroundFormats = new ArrayList<>(); 2410 int status = AudioSystem.getReportedSurroundFormats(reportedSurroundFormats); 2411 if (status != AudioManager.SUCCESS) { 2412 // fail and bail! 2413 Log.e(TAG, "getReportedSurroundFormats failed:" + status); 2414 return new ArrayList<>(); // Always return a list. 2415 } 2416 return reportedSurroundFormats; 2417 } 2418 2419 /** @see AudioManager#isSurroundFormatEnabled(int) */ 2420 @Override isSurroundFormatEnabled(int audioFormat)2421 public boolean isSurroundFormatEnabled(int audioFormat) { 2422 if (!isSurroundFormat(audioFormat)) { 2423 Log.w(TAG, "audioFormat to enable is not a surround format."); 2424 return false; 2425 } 2426 2427 final long token = Binder.clearCallingIdentity(); 2428 try { 2429 synchronized (mSettingsLock) { 2430 HashSet<Integer> enabledFormats = getEnabledFormats(); 2431 return enabledFormats.contains(audioFormat); 2432 } 2433 } finally { 2434 Binder.restoreCallingIdentity(token); 2435 } 2436 } 2437 2438 /** @see AudioManager#setSurroundFormatEnabled(int, boolean) */ 2439 @Override setSurroundFormatEnabled(int audioFormat, boolean enabled)2440 public boolean setSurroundFormatEnabled(int audioFormat, boolean enabled) { 2441 if (!isSurroundFormat(audioFormat)) { 2442 Log.w(TAG, "audioFormat to enable is not a surround format."); 2443 return false; 2444 } 2445 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS) 2446 != PackageManager.PERMISSION_GRANTED) { 2447 throw new SecurityException("Missing WRITE_SETTINGS permission"); 2448 } 2449 2450 HashSet<Integer> enabledFormats = getEnabledFormats(); 2451 if (enabled) { 2452 enabledFormats.add(audioFormat); 2453 } else { 2454 enabledFormats.remove(audioFormat); 2455 } 2456 final long token = Binder.clearCallingIdentity(); 2457 try { 2458 synchronized (mSettingsLock) { 2459 mSettings.putGlobalString(mContentResolver, 2460 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS, 2461 TextUtils.join(",", enabledFormats)); 2462 } 2463 } finally { 2464 Binder.restoreCallingIdentity(token); 2465 } 2466 return true; 2467 } 2468 2469 /** @see AudioManager#setEncodedSurroundMode(int) */ 2470 @Override setEncodedSurroundMode(@udioManager.EncodedSurroundOutputMode int mode)2471 public boolean setEncodedSurroundMode(@AudioManager.EncodedSurroundOutputMode int mode) { 2472 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS) 2473 != PackageManager.PERMISSION_GRANTED) { 2474 throw new SecurityException("Missing WRITE_SETTINGS permission"); 2475 } 2476 2477 final long token = Binder.clearCallingIdentity(); 2478 try { 2479 synchronized (mSettingsLock) { 2480 mSettings.putGlobalInt(mContentResolver, 2481 Settings.Global.ENCODED_SURROUND_OUTPUT, 2482 toEncodedSurroundSetting(mode)); 2483 } 2484 } finally { 2485 Binder.restoreCallingIdentity(token); 2486 } 2487 return true; 2488 } 2489 2490 /** @see AudioManager#getEncodedSurroundMode() */ 2491 @Override getEncodedSurroundMode(int targetSdkVersion)2492 public int getEncodedSurroundMode(int targetSdkVersion) { 2493 final long token = Binder.clearCallingIdentity(); 2494 try { 2495 synchronized (mSettingsLock) { 2496 int encodedSurroundSetting = mSettings.getGlobalInt(mContentResolver, 2497 Settings.Global.ENCODED_SURROUND_OUTPUT, 2498 AudioManager.ENCODED_SURROUND_OUTPUT_AUTO); 2499 return toEncodedSurroundOutputMode(encodedSurroundSetting, targetSdkVersion); 2500 } 2501 } finally { 2502 Binder.restoreCallingIdentity(token); 2503 } 2504 } 2505 2506 /** @return the formats that are enabled in global settings */ getEnabledFormats()2507 private HashSet<Integer> getEnabledFormats() { 2508 HashSet<Integer> formats = new HashSet<>(); 2509 String enabledFormats = mSettings.getGlobalString(mContentResolver, 2510 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 2511 if (enabledFormats != null) { 2512 try { 2513 Arrays.stream(TextUtils.split(enabledFormats, ",")) 2514 .mapToInt(Integer::parseInt) 2515 .forEach(formats::add); 2516 } catch (NumberFormatException e) { 2517 Log.w(TAG, "ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS misformatted.", e); 2518 } 2519 } 2520 return formats; 2521 } 2522 2523 @SuppressWarnings("AndroidFrameworkCompatChange") 2524 @AudioManager.EncodedSurroundOutputMode toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion)2525 private int toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion) { 2526 if (targetSdkVersion <= Build.VERSION_CODES.S 2527 && encodedSurroundSetting > Settings.Global.ENCODED_SURROUND_SC_MAX) { 2528 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN; 2529 } 2530 switch (encodedSurroundSetting) { 2531 case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO: 2532 return AudioManager.ENCODED_SURROUND_OUTPUT_AUTO; 2533 case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER: 2534 return AudioManager.ENCODED_SURROUND_OUTPUT_NEVER; 2535 case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS: 2536 return AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS; 2537 case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL: 2538 return AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL; 2539 default: 2540 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN; 2541 } 2542 } 2543 toEncodedSurroundSetting( @udioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode)2544 private int toEncodedSurroundSetting( 2545 @AudioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode) { 2546 switch (encodedSurroundOutputMode) { 2547 case AudioManager.ENCODED_SURROUND_OUTPUT_NEVER: 2548 return Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER; 2549 case AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS: 2550 return Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS; 2551 case AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL: 2552 return Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL; 2553 default: 2554 return Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO; 2555 } 2556 } 2557 isSurroundFormat(int audioFormat)2558 private boolean isSurroundFormat(int audioFormat) { 2559 for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) { 2560 if (sf == audioFormat) { 2561 return true; 2562 } 2563 } 2564 return false; 2565 } 2566 sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate)2567 private void sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate) { 2568 if (mEncodedSurroundMode != Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL) { 2569 // Manually enable surround formats only when the setting is in manual mode. 2570 return; 2571 } 2572 String enabledSurroundFormats = mSettings.getGlobalString( 2573 cr, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 2574 if (enabledSurroundFormats == null) { 2575 // Never allow enabledSurroundFormats as a null, which could happen when 2576 // ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS is not appear in settings DB. 2577 enabledSurroundFormats = ""; 2578 } 2579 if (!forceUpdate && TextUtils.equals(enabledSurroundFormats, mEnabledSurroundFormats)) { 2580 // Update enabled surround formats to AudioPolicyManager only when forceUpdate 2581 // is true or enabled surround formats changed. 2582 return; 2583 } 2584 2585 mEnabledSurroundFormats = enabledSurroundFormats; 2586 String[] surroundFormats = TextUtils.split(enabledSurroundFormats, ","); 2587 ArrayList<Integer> formats = new ArrayList<>(); 2588 for (String format : surroundFormats) { 2589 try { 2590 int audioFormat = Integer.valueOf(format); 2591 if (isSurroundFormat(audioFormat) && !formats.contains(audioFormat)) { 2592 formats.add(audioFormat); 2593 } 2594 } catch (Exception e) { 2595 Log.e(TAG, "Invalid enabled surround format:" + format); 2596 } 2597 } 2598 // Set filtered surround formats to settings DB in case 2599 // there are invalid surround formats in original settings. 2600 mSettings.putGlobalString(mContext.getContentResolver(), 2601 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS, 2602 TextUtils.join(",", formats)); 2603 sendMsg(mAudioHandler, MSG_ENABLE_SURROUND_FORMATS, SENDMSG_QUEUE, 0, 0, formats, 0); 2604 } 2605 onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats)2606 private void onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats) { 2607 // Set surround format enabled accordingly. 2608 for (int surroundFormat : AudioFormat.SURROUND_SOUND_ENCODING) { 2609 boolean enabled = enabledSurroundFormats.contains(surroundFormat); 2610 int ret = AudioSystem.setSurroundFormatEnabled(surroundFormat, enabled); 2611 Log.i(TAG, "enable surround format:" + surroundFormat + " " + enabled + " " + ret); 2612 } 2613 } 2614 2615 @GuardedBy("mSettingsLock") updateAssistantUIdLocked(boolean forceUpdate)2616 private void updateAssistantUIdLocked(boolean forceUpdate) { 2617 int assistantUid = INVALID_UID; 2618 // Consider assistants in the following order of priority: 2619 // 1) apk in assistant role 2620 // 2) voice interaction service 2621 // 3) assistant service 2622 2623 String packageName = ""; 2624 if (mRoleObserver != null) { 2625 packageName = mRoleObserver.getAssistantRoleHolder(); 2626 } 2627 if (TextUtils.isEmpty(packageName)) { 2628 String assistantName = mSettings.getSecureStringForUser( 2629 mContentResolver, 2630 Settings.Secure.VOICE_INTERACTION_SERVICE, UserHandle.USER_CURRENT); 2631 if (TextUtils.isEmpty(assistantName)) { 2632 assistantName = mSettings.getSecureStringForUser( 2633 mContentResolver, 2634 Settings.Secure.ASSISTANT, UserHandle.USER_CURRENT); 2635 } 2636 if (!TextUtils.isEmpty(assistantName)) { 2637 ComponentName componentName = ComponentName.unflattenFromString(assistantName); 2638 if (componentName == null) { 2639 Slog.w(TAG, "Invalid service name for " 2640 + Settings.Secure.VOICE_INTERACTION_SERVICE + ": " + assistantName); 2641 return; 2642 } 2643 packageName = componentName.getPackageName(); 2644 } 2645 } 2646 if (!TextUtils.isEmpty(packageName)) { 2647 PackageManager pm = mContext.getPackageManager(); 2648 2649 if (pm.checkPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD, packageName) 2650 == PackageManager.PERMISSION_GRANTED) { 2651 try { 2652 assistantUid = pm.getPackageUidAsUser(packageName, getCurrentUserId()); 2653 } catch (PackageManager.NameNotFoundException e) { 2654 Log.e(TAG, 2655 "updateAssistantUId() could not find UID for package: " + packageName); 2656 } 2657 } 2658 } 2659 if ((mPrimaryAssistantUid != assistantUid) || forceUpdate) { 2660 mAssistantUids.remove(mPrimaryAssistantUid); 2661 mPrimaryAssistantUid = assistantUid; 2662 addAssistantServiceUidsLocked(new int[]{mPrimaryAssistantUid}); 2663 } 2664 } 2665 readPersistedSettings()2666 private void readPersistedSettings() { 2667 if (!mSystemServer.isPrivileged()) { 2668 return; 2669 } 2670 final ContentResolver cr = mContentResolver; 2671 2672 int ringerModeFromSettings = 2673 mSettings.getGlobalInt( 2674 cr, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL); 2675 int ringerMode = ringerModeFromSettings; 2676 // validity check in case the settings are restored from a device with incompatible 2677 // ringer modes 2678 if (!isValidRingerMode(ringerMode)) { 2679 ringerMode = AudioManager.RINGER_MODE_NORMAL; 2680 } 2681 if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { 2682 ringerMode = AudioManager.RINGER_MODE_SILENT; 2683 } 2684 if (ringerMode != ringerModeFromSettings) { 2685 mSettings.putGlobalInt(cr, Settings.Global.MODE_RINGER, ringerMode); 2686 } 2687 if (mUseFixedVolume || mIsSingleVolume) { 2688 ringerMode = AudioManager.RINGER_MODE_NORMAL; 2689 } 2690 synchronized(mSettingsLock) { 2691 mRingerMode = ringerMode; 2692 if (mRingerModeExternal == -1) { 2693 mRingerModeExternal = mRingerMode; 2694 } 2695 2696 // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting 2697 // are still needed while setVibrateSetting() and getVibrateSetting() are being 2698 // deprecated. 2699 mVibrateSetting = AudioSystem.getValueForVibrateSetting(0, 2700 AudioManager.VIBRATE_TYPE_NOTIFICATION, 2701 mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT 2702 : AudioManager.VIBRATE_SETTING_OFF); 2703 mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, 2704 AudioManager.VIBRATE_TYPE_RINGER, 2705 mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT 2706 : AudioManager.VIBRATE_SETTING_OFF); 2707 2708 updateRingerAndZenModeAffectedStreams(); 2709 readDockAudioSettings(cr); 2710 sendEncodedSurroundMode(cr, "readPersistedSettings"); 2711 sendEnabledSurroundFormats(cr, true); 2712 updateAssistantUIdLocked(/* forceUpdate= */ true); 2713 resetActiveAssistantUidsLocked(); 2714 AudioSystem.setRttEnabled(mRttEnabled); 2715 } 2716 2717 mMuteAffectedStreams = mSettings.getSystemIntForUser(cr, 2718 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED, 2719 UserHandle.USER_CURRENT); 2720 2721 updateMasterMono(cr); 2722 2723 updateMasterBalance(cr); 2724 2725 // Each stream will read its own persisted settings 2726 2727 // Broadcast the sticky intents 2728 broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal); 2729 broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode); 2730 2731 // Broadcast vibrate settings 2732 broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER); 2733 broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION); 2734 2735 // Load settings for the volume controller 2736 mVolumeController.loadSettings(cr); 2737 } 2738 2739 @GuardedBy("mSettingsLock") resetActiveAssistantUidsLocked()2740 private void resetActiveAssistantUidsLocked() { 2741 mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS; 2742 updateActiveAssistantServiceUids(); 2743 } 2744 readUserRestrictions()2745 private void readUserRestrictions() { 2746 if (!mSystemServer.isPrivileged()) { 2747 return; 2748 } 2749 final int currentUser = getCurrentUserId(); 2750 2751 // Check the current user restriction. 2752 boolean masterMute = 2753 mUserManagerInternal.getUserRestriction(currentUser, 2754 UserManager.DISALLOW_UNMUTE_DEVICE) 2755 || mUserManagerInternal.getUserRestriction(currentUser, 2756 UserManager.DISALLOW_ADJUST_VOLUME); 2757 if (mUseFixedVolume) { 2758 masterMute = false; 2759 AudioSystem.setMasterVolume(1.0f); 2760 } 2761 if (DEBUG_VOL) { 2762 Log.d(TAG, String.format("Master mute %s, user=%d", masterMute, currentUser)); 2763 } 2764 AudioSystem.setMasterMute(masterMute); 2765 broadcastMasterMuteStatus(masterMute); 2766 2767 mMicMuteFromRestrictions = mUserManagerInternal.getUserRestriction( 2768 currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE); 2769 if (DEBUG_VOL) { 2770 Log.d(TAG, String.format("Mic mute %b, user=%d", mMicMuteFromRestrictions, 2771 currentUser)); 2772 } 2773 setMicrophoneMuteNoCallerCheck(currentUser); 2774 } 2775 getIndexRange(int streamType)2776 private int getIndexRange(int streamType) { 2777 return (mStreamStates[streamType].getMaxIndex() - mStreamStates[streamType].getMinIndex()); 2778 } 2779 rescaleIndex(VolumeInfo volumeInfo, int dstStream)2780 private int rescaleIndex(VolumeInfo volumeInfo, int dstStream) { 2781 if (volumeInfo.getVolumeIndex() == VolumeInfo.INDEX_NOT_SET 2782 || volumeInfo.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET 2783 || volumeInfo.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) { 2784 Log.e(TAG, "rescaleIndex: volumeInfo has invalid index or range"); 2785 return mStreamStates[dstStream].getMinIndex(); 2786 } 2787 return rescaleIndex(volumeInfo.getVolumeIndex(), 2788 volumeInfo.getMinVolumeIndex(), volumeInfo.getMaxVolumeIndex(), 2789 mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex()); 2790 } 2791 rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo)2792 private int rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo) { 2793 int dstMin = dstVolumeInfo.getMinVolumeIndex(); 2794 int dstMax = dstVolumeInfo.getMaxVolumeIndex(); 2795 // Don't rescale index if the VolumeInfo is missing a min or max index 2796 if (dstMin == VolumeInfo.INDEX_NOT_SET || dstMax == VolumeInfo.INDEX_NOT_SET) { 2797 return index; 2798 } 2799 return rescaleIndex(index, 2800 mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(), 2801 dstMin, dstMax); 2802 } 2803 rescaleIndex(int index, int srcStream, int dstStream)2804 private int rescaleIndex(int index, int srcStream, int dstStream) { 2805 return rescaleIndex(index, 2806 mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(), 2807 mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex()); 2808 } 2809 rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax)2810 private int rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax) { 2811 int srcRange = srcMax - srcMin; 2812 int dstRange = dstMax - dstMin; 2813 if (srcRange == 0) { 2814 Log.e(TAG, "rescaleIndex : index range should not be zero"); 2815 return dstMin; 2816 } 2817 return dstMin + ((index - srcMin) * dstRange + srcRange / 2) / srcRange; 2818 } 2819 rescaleStep(int step, int srcStream, int dstStream)2820 private int rescaleStep(int step, int srcStream, int dstStream) { 2821 int srcRange = getIndexRange(srcStream); 2822 int dstRange = getIndexRange(dstStream); 2823 if (srcRange == 0) { 2824 Log.e(TAG, "rescaleStep : index range should not be zero"); 2825 return 0; 2826 } 2827 2828 return ((step * dstRange + srcRange / 2) / srcRange); 2829 } 2830 2831 /////////////////////////////////////////////////////////////////////////// 2832 // IPC methods 2833 /////////////////////////////////////////////////////////////////////////// 2834 /** 2835 * @see AudioManager#setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes) 2836 * @see AudioManager#setPreferredDevicesForStrategy(AudioProductStrategy, 2837 * List<AudioDeviceAttributes>) 2838 */ 2839 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices)2840 public int setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices) { 2841 super.setPreferredDevicesForStrategy_enforcePermission(); 2842 if (devices == null) { 2843 return AudioSystem.ERROR; 2844 } 2845 2846 devices = retrieveBluetoothAddresses(devices); 2847 2848 final String logString = String.format( 2849 "setPreferredDevicesForStrategy u/pid:%d/%d strat:%d dev:%s", 2850 Binder.getCallingUid(), Binder.getCallingPid(), strategy, 2851 devices.stream().map(e -> e.toString()).collect(Collectors.joining(","))); 2852 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 2853 if (devices.stream().anyMatch(device -> 2854 device.getRole() == AudioDeviceAttributes.ROLE_INPUT)) { 2855 Log.e(TAG, "Unsupported input routing in " + logString); 2856 return AudioSystem.ERROR; 2857 } 2858 2859 final int status = mDeviceBroker.setPreferredDevicesForStrategySync(strategy, devices); 2860 if (status != AudioSystem.SUCCESS) { 2861 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 2862 } 2863 2864 return status; 2865 } 2866 2867 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 2868 /** @see AudioManager#removePreferredDeviceForStrategy(AudioProductStrategy) */ removePreferredDevicesForStrategy(int strategy)2869 public int removePreferredDevicesForStrategy(int strategy) { 2870 super.removePreferredDevicesForStrategy_enforcePermission(); 2871 2872 final String logString = 2873 String.format("removePreferredDeviceForStrategy strat:%d", strategy); 2874 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 2875 2876 final int status = mDeviceBroker.removePreferredDevicesForStrategySync(strategy); 2877 if (status != AudioSystem.SUCCESS) { 2878 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 2879 } 2880 return status; 2881 } 2882 2883 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 2884 /** 2885 * @see AudioManager#getPreferredDeviceForStrategy(AudioProductStrategy) 2886 * @see AudioManager#getPreferredDevicesForStrategy(AudioProductStrategy) 2887 */ getPreferredDevicesForStrategy(int strategy)2888 public List<AudioDeviceAttributes> getPreferredDevicesForStrategy(int strategy) { 2889 super.getPreferredDevicesForStrategy_enforcePermission(); 2890 2891 List<AudioDeviceAttributes> devices = new ArrayList<>(); 2892 int status = AudioSystem.SUCCESS; 2893 final long identity = Binder.clearCallingIdentity(); 2894 try { 2895 status = AudioSystem.getDevicesForRoleAndStrategy( 2896 strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices); 2897 } finally { 2898 Binder.restoreCallingIdentity(identity); 2899 } 2900 if (status != AudioSystem.SUCCESS) { 2901 Log.e(TAG, String.format("Error %d in getPreferredDeviceForStrategy(%d)", 2902 status, strategy)); 2903 return new ArrayList<AudioDeviceAttributes>(); 2904 } else { 2905 return anonymizeAudioDeviceAttributesList(devices); 2906 } 2907 } 2908 2909 /** 2910 * @see AudioManager#setDeviceAsNonDefaultForStrategy(AudioProductStrategy, 2911 * AudioDeviceAttributes) 2912 * @see AudioManager#setDeviceAsNonDefaultForStrategy(AudioProductStrategy, 2913 * List<AudioDeviceAttributes>) 2914 */ 2915 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) setDeviceAsNonDefaultForStrategy(int strategy, @NonNull AudioDeviceAttributes device)2916 public int setDeviceAsNonDefaultForStrategy(int strategy, 2917 @NonNull AudioDeviceAttributes device) { 2918 super.setDeviceAsNonDefaultForStrategy_enforcePermission(); 2919 Objects.requireNonNull(device); 2920 2921 device = retrieveBluetoothAddress(device); 2922 2923 final String logString = String.format( 2924 "setDeviceAsNonDefaultForStrategy u/pid:%d/%d strat:%d dev:%s", 2925 Binder.getCallingUid(), Binder.getCallingPid(), strategy, device.toString()); 2926 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 2927 if (device.getRole() == AudioDeviceAttributes.ROLE_INPUT) { 2928 Log.e(TAG, "Unsupported input routing in " + logString); 2929 return AudioSystem.ERROR; 2930 } 2931 2932 final int status = mDeviceBroker.setDeviceAsNonDefaultForStrategySync(strategy, device); 2933 if (status != AudioSystem.SUCCESS) { 2934 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 2935 } 2936 2937 return status; 2938 } 2939 2940 /** 2941 * @see AudioManager#removeDeviceAsNonDefaultForStrategy(AudioProductStrategy, 2942 * AudioDeviceAttributes) 2943 */ 2944 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) removeDeviceAsNonDefaultForStrategy(int strategy, AudioDeviceAttributes device)2945 public int removeDeviceAsNonDefaultForStrategy(int strategy, 2946 AudioDeviceAttributes device) { 2947 super.removeDeviceAsNonDefaultForStrategy_enforcePermission(); 2948 Objects.requireNonNull(device); 2949 2950 device = retrieveBluetoothAddress(device); 2951 2952 final String logString = String.format( 2953 "removeDeviceAsNonDefaultForStrategy strat:%d dev:%s", strategy, device.toString()); 2954 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 2955 if (device.getRole() == AudioDeviceAttributes.ROLE_INPUT) { 2956 Log.e(TAG, "Unsupported input routing in " + logString); 2957 return AudioSystem.ERROR; 2958 } 2959 2960 final int status = mDeviceBroker.removeDeviceAsNonDefaultForStrategySync(strategy, device); 2961 if (status != AudioSystem.SUCCESS) { 2962 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 2963 } 2964 return status; 2965 } 2966 2967 /** 2968 * @see AudioManager#getNonDefaultDevicesForStrategy(AudioProductStrategy) 2969 */ 2970 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) getNonDefaultDevicesForStrategy(int strategy)2971 public List<AudioDeviceAttributes> getNonDefaultDevicesForStrategy(int strategy) { 2972 super.getNonDefaultDevicesForStrategy_enforcePermission(); 2973 List<AudioDeviceAttributes> devices = new ArrayList<>(); 2974 int status = AudioSystem.ERROR; 2975 2976 try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { 2977 status = AudioSystem.getDevicesForRoleAndStrategy( 2978 strategy, AudioSystem.DEVICE_ROLE_DISABLED, devices); 2979 } 2980 2981 if (status != AudioSystem.SUCCESS) { 2982 Log.e(TAG, String.format("Error %d in getNonDefaultDeviceForStrategy(%d)", 2983 status, strategy)); 2984 return new ArrayList<AudioDeviceAttributes>(); 2985 } else { 2986 return anonymizeAudioDeviceAttributesList(devices); 2987 } 2988 } 2989 2990 /** @see AudioManager#addOnPreferredDevicesForStrategyChangedListener( 2991 * Executor, AudioManager.OnPreferredDevicesForStrategyChangedListener) 2992 */ registerStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)2993 public void registerStrategyPreferredDevicesDispatcher( 2994 @Nullable IStrategyPreferredDevicesDispatcher dispatcher) { 2995 if (dispatcher == null) { 2996 return; 2997 } 2998 enforceModifyAudioRoutingPermission(); 2999 mDeviceBroker.registerStrategyPreferredDevicesDispatcher( 3000 dispatcher, isBluetoothPrividged()); 3001 } 3002 3003 /** @see AudioManager#removeOnPreferredDevicesForStrategyChangedListener( 3004 * AudioManager.OnPreferredDevicesForStrategyChangedListener) 3005 */ unregisterStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)3006 public void unregisterStrategyPreferredDevicesDispatcher( 3007 @Nullable IStrategyPreferredDevicesDispatcher dispatcher) { 3008 if (dispatcher == null) { 3009 return; 3010 } 3011 enforceModifyAudioRoutingPermission(); 3012 mDeviceBroker.unregisterStrategyPreferredDevicesDispatcher(dispatcher); 3013 } 3014 3015 /** @see AudioManager#addOnNonDefaultDevicesForStrategyChangedListener( 3016 * Executor, AudioManager.OnNonDefaultDevicesForStrategyChangedListener) 3017 */ registerStrategyNonDefaultDevicesDispatcher( @ullable IStrategyNonDefaultDevicesDispatcher dispatcher)3018 public void registerStrategyNonDefaultDevicesDispatcher( 3019 @Nullable IStrategyNonDefaultDevicesDispatcher dispatcher) { 3020 if (dispatcher == null) { 3021 return; 3022 } 3023 enforceModifyAudioRoutingPermission(); 3024 mDeviceBroker.registerStrategyNonDefaultDevicesDispatcher( 3025 dispatcher, isBluetoothPrividged()); 3026 } 3027 3028 /** @see AudioManager#removeOnNonDefaultDevicesForStrategyChangedListener( 3029 * AudioManager.OnNonDefaultDevicesForStrategyChangedListener) 3030 */ unregisterStrategyNonDefaultDevicesDispatcher( @ullable IStrategyNonDefaultDevicesDispatcher dispatcher)3031 public void unregisterStrategyNonDefaultDevicesDispatcher( 3032 @Nullable IStrategyNonDefaultDevicesDispatcher dispatcher) { 3033 if (dispatcher == null) { 3034 return; 3035 } 3036 enforceModifyAudioRoutingPermission(); 3037 mDeviceBroker.unregisterStrategyNonDefaultDevicesDispatcher(dispatcher); 3038 } 3039 3040 /** 3041 * @see AudioManager#setPreferredDevicesForCapturePreset(int, AudioDeviceAttributes) 3042 */ setPreferredDevicesForCapturePreset( int capturePreset, List<AudioDeviceAttributes> devices)3043 public int setPreferredDevicesForCapturePreset( 3044 int capturePreset, List<AudioDeviceAttributes> devices) { 3045 if (devices == null) { 3046 return AudioSystem.ERROR; 3047 } 3048 enforceModifyAudioRoutingPermission(); 3049 final String logString = String.format( 3050 "setPreferredDevicesForCapturePreset u/pid:%d/%d source:%d dev:%s", 3051 Binder.getCallingUid(), Binder.getCallingPid(), capturePreset, 3052 devices.stream().map(e -> e.toString()).collect(Collectors.joining(","))); 3053 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 3054 if (devices.stream().anyMatch(device -> 3055 device.getRole() == AudioDeviceAttributes.ROLE_OUTPUT)) { 3056 Log.e(TAG, "Unsupported output routing in " + logString); 3057 return AudioSystem.ERROR; 3058 } 3059 3060 devices = retrieveBluetoothAddresses(devices); 3061 3062 final int status = mDeviceBroker.setPreferredDevicesForCapturePresetSync( 3063 capturePreset, devices); 3064 if (status != AudioSystem.SUCCESS) { 3065 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 3066 } 3067 3068 return status; 3069 } 3070 3071 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 3072 /** @see AudioManager#clearPreferredDevicesForCapturePreset(int) */ clearPreferredDevicesForCapturePreset(int capturePreset)3073 public int clearPreferredDevicesForCapturePreset(int capturePreset) { 3074 super.clearPreferredDevicesForCapturePreset_enforcePermission(); 3075 3076 final String logString = String.format( 3077 "removePreferredDeviceForCapturePreset source:%d", capturePreset); 3078 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 3079 3080 final int status = mDeviceBroker.clearPreferredDevicesForCapturePresetSync(capturePreset); 3081 if (status != AudioSystem.SUCCESS) { 3082 Log.e(TAG, String.format("Error %d in %s", status, logString)); 3083 } 3084 return status; 3085 } 3086 3087 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 3088 /** 3089 * @see AudioManager#getPreferredDevicesForCapturePreset(int) 3090 */ getPreferredDevicesForCapturePreset(int capturePreset)3091 public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) { 3092 super.getPreferredDevicesForCapturePreset_enforcePermission(); 3093 3094 List<AudioDeviceAttributes> devices = new ArrayList<>(); 3095 int status = AudioSystem.SUCCESS; 3096 final long identity = Binder.clearCallingIdentity(); 3097 try { 3098 status = AudioSystem.getDevicesForRoleAndCapturePreset( 3099 capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices); 3100 } finally { 3101 Binder.restoreCallingIdentity(identity); 3102 } 3103 if (status != AudioSystem.SUCCESS) { 3104 Log.e(TAG, String.format("Error %d in getPreferredDeviceForCapturePreset(%d)", 3105 status, capturePreset)); 3106 return new ArrayList<AudioDeviceAttributes>(); 3107 } else { 3108 return anonymizeAudioDeviceAttributesList(devices); 3109 } 3110 } 3111 3112 /** 3113 * @see AudioManager#addOnPreferredDevicesForCapturePresetChangedListener( 3114 * Executor, OnPreferredDevicesForCapturePresetChangedListener) 3115 */ registerCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)3116 public void registerCapturePresetDevicesRoleDispatcher( 3117 @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) { 3118 if (dispatcher == null) { 3119 return; 3120 } 3121 enforceModifyAudioRoutingPermission(); 3122 mDeviceBroker.registerCapturePresetDevicesRoleDispatcher( 3123 dispatcher, isBluetoothPrividged()); 3124 } 3125 3126 /** 3127 * @see AudioManager#removeOnPreferredDevicesForCapturePresetChangedListener( 3128 * AudioManager.OnPreferredDevicesForCapturePresetChangedListener) 3129 */ unregisterCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)3130 public void unregisterCapturePresetDevicesRoleDispatcher( 3131 @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) { 3132 if (dispatcher == null) { 3133 return; 3134 } 3135 enforceModifyAudioRoutingPermission(); 3136 mDeviceBroker.unregisterCapturePresetDevicesRoleDispatcher(dispatcher); 3137 } 3138 3139 /** @see AudioManager#getDevicesForAttributes(AudioAttributes) */ getDevicesForAttributes( @onNull AudioAttributes attributes)3140 public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes( 3141 @NonNull AudioAttributes attributes) { 3142 enforceQueryStateOrModifyRoutingPermission(); 3143 3144 return new ArrayList<AudioDeviceAttributes>(anonymizeAudioDeviceAttributesList( 3145 getDevicesForAttributesInt(attributes, false /* forVolume */))); 3146 } 3147 3148 /** @see AudioManager#getAudioDevicesForAttributes(AudioAttributes) 3149 * This method is similar with AudioService#getDevicesForAttributes, 3150 * only it doesn't enforce permissions because it is used by an unprivileged public API 3151 * instead of the system API. 3152 */ getDevicesForAttributesUnprotected( @onNull AudioAttributes attributes)3153 public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesUnprotected( 3154 @NonNull AudioAttributes attributes) { 3155 return new ArrayList<AudioDeviceAttributes>(anonymizeAudioDeviceAttributesList( 3156 getDevicesForAttributesInt(attributes, false /* forVolume */))); 3157 } 3158 3159 /** 3160 * @see AudioManager#isMusicActive() 3161 * @param remotely true if query is for remote playback (cast), false for local playback. 3162 */ isMusicActive(boolean remotely)3163 public boolean isMusicActive(boolean remotely) { 3164 // no permission required 3165 final long token = Binder.clearCallingIdentity(); 3166 try { 3167 if (remotely) { 3168 return AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, 0); 3169 } else { 3170 return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0); 3171 } 3172 } finally { 3173 Binder.restoreCallingIdentity(token); 3174 } 3175 } 3176 getDevicesForAttributesInt( @onNull AudioAttributes attributes, boolean forVolume)3177 protected @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesInt( 3178 @NonNull AudioAttributes attributes, boolean forVolume) { 3179 Objects.requireNonNull(attributes); 3180 return mAudioSystem.getDevicesForAttributes(attributes, forVolume); 3181 } 3182 3183 /** 3184 * @see AudioManager#addOnDevicesForAttributesChangedListener( 3185 * AudioAttributes, Executor, OnDevicesForAttributesChangedListener) 3186 */ addOnDevicesForAttributesChangedListener(AudioAttributes attributes, IDevicesForAttributesCallback callback)3187 public void addOnDevicesForAttributesChangedListener(AudioAttributes attributes, 3188 IDevicesForAttributesCallback callback) { 3189 mAudioSystem.addOnDevicesForAttributesChangedListener( 3190 attributes, false /* forVolume */, callback); 3191 } 3192 3193 /** 3194 * @see AudioManager#removeOnDevicesForAttributesChangedListener( 3195 * OnDevicesForAttributesChangedListener) 3196 */ removeOnDevicesForAttributesChangedListener( IDevicesForAttributesCallback callback)3197 public void removeOnDevicesForAttributesChangedListener( 3198 IDevicesForAttributesCallback callback) { 3199 mAudioSystem.removeOnDevicesForAttributesChangedListener(callback); 3200 } 3201 3202 // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP, 3203 // KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE handleVolumeKey(@onNull KeyEvent event, boolean isOnTv, @NonNull String callingPackage, @NonNull String caller)3204 public void handleVolumeKey(@NonNull KeyEvent event, boolean isOnTv, 3205 @NonNull String callingPackage, @NonNull String caller) { 3206 int keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_NORMAL; 3207 if (isOnTv) { 3208 if (event.getAction() == KeyEvent.ACTION_DOWN) { 3209 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_START; 3210 } else { // may catch more than ACTION_UP, but will end vol adjustement 3211 // the vol key is either released (ACTION_UP), or multiple keys are pressed 3212 // (ACTION_MULTIPLE) and we don't know what to do for volume control on CEC, end 3213 // the repeated volume adjustement 3214 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_END; 3215 } 3216 } else if (event.getAction() != KeyEvent.ACTION_DOWN) { 3217 return; 3218 } 3219 3220 int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND 3221 | AudioManager.FLAG_FROM_KEY; 3222 3223 switch (event.getKeyCode()) { 3224 case KeyEvent.KEYCODE_VOLUME_UP: 3225 adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE, 3226 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 3227 Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode); 3228 break; 3229 case KeyEvent.KEYCODE_VOLUME_DOWN: 3230 adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER, 3231 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 3232 Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode); 3233 break; 3234 case KeyEvent.KEYCODE_VOLUME_MUTE: 3235 if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 3236 adjustSuggestedStreamVolume(AudioManager.ADJUST_TOGGLE_MUTE, 3237 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 3238 Binder.getCallingUid(), Binder.getCallingPid(), 3239 true, AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 3240 } 3241 break; 3242 default: 3243 Log.e(TAG, "Invalid key code " + event.getKeyCode() + " sent by " + callingPackage); 3244 return; // not needed but added if code gets added below this switch statement 3245 } 3246 } 3247 setNavigationRepeatSoundEffectsEnabled(boolean enabled)3248 public void setNavigationRepeatSoundEffectsEnabled(boolean enabled) { 3249 mNavigationRepeatSoundEffectsEnabled = enabled; 3250 } 3251 3252 /** 3253 * @return true if the fast scroll sound effects are enabled 3254 */ areNavigationRepeatSoundEffectsEnabled()3255 public boolean areNavigationRepeatSoundEffectsEnabled() { 3256 return mNavigationRepeatSoundEffectsEnabled; 3257 } 3258 setHomeSoundEffectEnabled(boolean enabled)3259 public void setHomeSoundEffectEnabled(boolean enabled) { 3260 mHomeSoundEffectEnabled = enabled; 3261 } 3262 3263 /** 3264 * @return true if the home sound effect is enabled 3265 */ isHomeSoundEffectEnabled()3266 public boolean isHomeSoundEffectEnabled() { 3267 return mHomeSoundEffectEnabled; 3268 } 3269 3270 /** All callers come from platform apps/system server, so no attribution tag is needed */ adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, String callingPackage, String caller, int uid, int pid, boolean hasModifyAudioSettings, int keyEventMode)3271 private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, 3272 String callingPackage, String caller, int uid, int pid, boolean hasModifyAudioSettings, 3273 int keyEventMode) { 3274 if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType 3275 + ", flags=" + flags + ", caller=" + caller 3276 + ", volControlStream=" + mVolumeControlStream 3277 + ", userSelect=" + mUserSelectedVolumeControlStream); 3278 if (direction != AudioManager.ADJUST_SAME) { 3279 sVolumeLogger.enqueue( 3280 new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType, 3281 direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage) 3282 .append("/").append(caller).append(" uid:").append(uid).toString())); 3283 } 3284 3285 boolean hasExternalVolumeController = notifyExternalVolumeController(direction); 3286 3287 new MediaMetrics.Item(mMetricsId + "adjustSuggestedStreamVolume") 3288 .setUid(Binder.getCallingUid()) 3289 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage) 3290 .set(MediaMetrics.Property.CLIENT_NAME, caller) 3291 .set(MediaMetrics.Property.DIRECTION, direction > 0 3292 ? MediaMetrics.Value.UP : MediaMetrics.Value.DOWN) 3293 .set(MediaMetrics.Property.EXTERNAL, hasExternalVolumeController 3294 ? MediaMetrics.Value.YES : MediaMetrics.Value.NO) 3295 .set(MediaMetrics.Property.FLAGS, flags) 3296 .record(); 3297 3298 if (hasExternalVolumeController) { 3299 return; 3300 } 3301 3302 final int streamType; 3303 synchronized (mForceControlStreamLock) { 3304 // Request lock in case mVolumeControlStream is changed by other thread. 3305 if (mUserSelectedVolumeControlStream) { // implies mVolumeControlStream != -1 3306 streamType = mVolumeControlStream; 3307 } else { 3308 // TODO discard activity on a muted stream? 3309 final int maybeActiveStreamType = getActiveStreamType(suggestedStreamType); 3310 final boolean activeForReal; 3311 if (maybeActiveStreamType == AudioSystem.STREAM_RING 3312 || maybeActiveStreamType == AudioSystem.STREAM_NOTIFICATION) { 3313 activeForReal = wasStreamActiveRecently(maybeActiveStreamType, 0); 3314 } else { 3315 activeForReal = mAudioSystem.isStreamActive(maybeActiveStreamType, 0); 3316 } 3317 if (activeForReal || mVolumeControlStream == -1) { 3318 streamType = maybeActiveStreamType; 3319 } else { 3320 streamType = mVolumeControlStream; 3321 } 3322 } 3323 } 3324 3325 final boolean isMute = isMuteAdjust(direction); 3326 3327 ensureValidStreamType(streamType); 3328 final int resolvedStream = mStreamVolumeAlias[streamType]; 3329 3330 // Play sounds on STREAM_RING only. 3331 if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 && 3332 resolvedStream != AudioSystem.STREAM_RING) { 3333 flags &= ~AudioManager.FLAG_PLAY_SOUND; 3334 } 3335 3336 // For notifications/ring, show the ui before making any adjustments 3337 // Don't suppress mute/unmute requests 3338 // Don't suppress adjustments for single volume device 3339 if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute) 3340 && !mIsSingleVolume) { 3341 direction = 0; 3342 flags &= ~AudioManager.FLAG_PLAY_SOUND; 3343 flags &= ~AudioManager.FLAG_VIBRATE; 3344 if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment"); 3345 } 3346 3347 adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid, pid, 3348 null, hasModifyAudioSettings, keyEventMode); 3349 } 3350 notifyExternalVolumeController(int direction)3351 private boolean notifyExternalVolumeController(int direction) { 3352 final IAudioPolicyCallback externalVolumeController; 3353 synchronized (mExtVolumeControllerLock) { 3354 externalVolumeController = mExtVolumeController; 3355 } 3356 if (externalVolumeController == null) { 3357 return false; 3358 } 3359 3360 sendMsg(mAudioHandler, MSG_NOTIFY_VOL_EVENT, SENDMSG_QUEUE, 3361 direction, 0 /*ignored*/, 3362 externalVolumeController, 0 /*delay*/); 3363 return true; 3364 } 3365 3366 /** Retain API for unsupported app usage */ adjustStreamVolume(int streamType, int direction, int flags, String callingPackage)3367 public void adjustStreamVolume(int streamType, int direction, int flags, 3368 String callingPackage) { 3369 adjustStreamVolumeWithAttribution(streamType, direction, flags, callingPackage, null); 3370 } 3371 3372 /** @see AudioManager#adjustStreamVolume(int, int, int) 3373 * Part of service interface, check permissions here */ adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, String callingPackage, String attributionTag)3374 public void adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, 3375 String callingPackage, String attributionTag) { 3376 if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { 3377 Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without" 3378 + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage); 3379 return; 3380 } 3381 3382 final VolumeEvent evt = new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType, 3383 direction/*val1*/, flags/*val2*/, callingPackage); 3384 sVolumeLogger.enqueue(evt); 3385 // also logging mute/unmute calls to the dedicated logger 3386 if (isMuteAdjust(direction)) { 3387 sMuteLogger.enqueue(evt); 3388 } 3389 adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage, 3390 Binder.getCallingUid(), Binder.getCallingPid(), attributionTag, 3391 callingHasAudioSettingsPermission(), AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 3392 } 3393 adjustStreamVolume(int streamType, int direction, int flags, String callingPackage, String caller, int uid, int pid, String attributionTag, boolean hasModifyAudioSettings, int keyEventMode)3394 protected void adjustStreamVolume(int streamType, int direction, int flags, 3395 String callingPackage, String caller, int uid, int pid, String attributionTag, 3396 boolean hasModifyAudioSettings, int keyEventMode) { 3397 if (mUseFixedVolume) { 3398 return; 3399 } 3400 if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction 3401 + ", flags=" + flags + ", caller=" + caller); 3402 3403 ensureValidDirection(direction); 3404 ensureValidStreamType(streamType); 3405 3406 boolean isMuteAdjust = isMuteAdjust(direction); 3407 3408 if (isMuteAdjust && !isStreamAffectedByMute(streamType)) { 3409 return; 3410 } 3411 3412 // If adjust is mute and the stream is STREAM_VOICE_CALL or STREAM_BLUETOOTH_SCO, make sure 3413 // that the calling app have the MODIFY_PHONE_STATE permission. 3414 if (isMuteAdjust && 3415 (streamType == AudioSystem.STREAM_VOICE_CALL || 3416 streamType == AudioSystem.STREAM_BLUETOOTH_SCO) && 3417 mContext.checkPermission(android.Manifest.permission.MODIFY_PHONE_STATE, pid, uid) 3418 != PackageManager.PERMISSION_GRANTED) { 3419 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: adjustStreamVolume from pid=" 3420 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 3421 return; 3422 } 3423 3424 // If the stream is STREAM_ASSISTANT, 3425 // make sure that the calling app have the MODIFY_AUDIO_ROUTING permission. 3426 if (streamType == AudioSystem.STREAM_ASSISTANT && 3427 mContext.checkPermission( 3428 android.Manifest.permission.MODIFY_AUDIO_ROUTING, pid, uid) 3429 != PackageManager.PERMISSION_GRANTED) { 3430 Log.w(TAG, "MODIFY_AUDIO_ROUTING Permission Denial: adjustStreamVolume from pid=" 3431 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 3432 return; 3433 } 3434 3435 // use stream type alias here so that streams with same alias have the same behavior, 3436 // including with regard to silent mode control (e.g the use of STREAM_RING below and in 3437 // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION) 3438 int streamTypeAlias = mStreamVolumeAlias[streamType]; 3439 3440 VolumeStreamState streamState = mStreamStates[streamTypeAlias]; 3441 3442 final int device = getDeviceForStream(streamTypeAlias); 3443 3444 int aliasIndex = streamState.getIndex(device); 3445 boolean adjustVolume = true; 3446 int step; 3447 3448 // skip a2dp absolute volume control request when the device 3449 // is neither an a2dp device nor BLE device 3450 if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 3451 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device)) 3452 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { 3453 return; 3454 } 3455 3456 // If we are being called by the system (e.g. hardware keys) check for current user 3457 // so we handle user restrictions correctly. 3458 if (uid == android.os.Process.SYSTEM_UID) { 3459 uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); 3460 } 3461 // validate calling package and app op 3462 if (!checkNoteAppOp( 3463 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) { 3464 return; 3465 } 3466 3467 mSoundDoseHelper.invalidatPendingVolumeCommand(); 3468 3469 flags &= ~AudioManager.FLAG_FIXED_VOLUME; 3470 if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) { 3471 flags |= AudioManager.FLAG_FIXED_VOLUME; 3472 3473 // Always toggle between max safe volume and 0 for fixed volume devices where safe 3474 // volume is enforced, and max and 0 for the others. 3475 // This is simulated by stepping by the full allowed volume range 3476 step = mSoundDoseHelper.getSafeMediaVolumeIndex(device); 3477 if (step < 0) { 3478 step = streamState.getMaxIndex(); 3479 } 3480 if (aliasIndex != 0) { 3481 aliasIndex = step; 3482 } 3483 } else { 3484 // convert one UI step (+/-1) into a number of internal units on the stream alias 3485 step = rescaleStep(10, streamType, streamTypeAlias); 3486 } 3487 3488 // If either the client forces allowing ringer modes for this adjustment, 3489 // or stream is used for UI sonification 3490 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 3491 (isUiSoundsStreamType(streamTypeAlias))) { 3492 int ringerMode = getRingerModeInternal(); 3493 // do not vibrate if already in vibrate mode 3494 if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { 3495 flags &= ~AudioManager.FLAG_VIBRATE; 3496 } 3497 // Check if the ringer mode handles this adjustment. If it does we don't 3498 // need to adjust the volume further. 3499 final int result = checkForRingerModeChange(aliasIndex, direction, step, 3500 streamState.mIsMuted, callingPackage, flags); 3501 adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0; 3502 // If suppressing a volume adjustment in silent mode, display the UI hint 3503 if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) { 3504 flags |= AudioManager.FLAG_SHOW_SILENT_HINT; 3505 } 3506 // If suppressing a volume down adjustment in vibrate mode, display the UI hint 3507 if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) { 3508 flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT; 3509 } 3510 } else if (isStreamMutedByRingerOrZenMode(streamTypeAlias) && streamState.mIsMuted) { 3511 // if the stream is currently muted streams by ringer/zen mode 3512 // then it cannot be unmuted (without FLAG_ALLOW_RINGER_MODES) with an unmute or raise 3513 if (direction == AudioManager.ADJUST_TOGGLE_MUTE 3514 || direction == AudioManager.ADJUST_UNMUTE 3515 || direction == AudioManager.ADJUST_RAISE) { 3516 adjustVolume = false; 3517 } 3518 } 3519 3520 // If the ringer mode or zen is muting the stream, do not change stream unless 3521 // it'll cause us to exit dnd 3522 if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) { 3523 adjustVolume = false; 3524 } 3525 int oldIndex = mStreamStates[streamType].getIndex(device); 3526 3527 // Check if the volume adjustment should be handled by an absolute volume controller instead 3528 if (isAbsoluteVolumeDevice(device) 3529 && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) { 3530 AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device); 3531 if (info.mHandlesVolumeAdjustment) { 3532 dispatchAbsoluteVolumeAdjusted(streamType, info, oldIndex, direction, 3533 keyEventMode); 3534 return; 3535 } 3536 } 3537 3538 if (adjustVolume && (direction != AudioManager.ADJUST_SAME) 3539 && (keyEventMode != AudioDeviceVolumeManager.ADJUST_MODE_END)) { 3540 mAudioHandler.removeMessages(MSG_UNMUTE_STREAM); 3541 3542 if (isMuteAdjust && !mFullVolumeDevices.contains(device)) { 3543 boolean state; 3544 if (direction == AudioManager.ADJUST_TOGGLE_MUTE) { 3545 state = !streamState.mIsMuted; 3546 } else { 3547 state = direction == AudioManager.ADJUST_MUTE; 3548 } 3549 muteAliasStreams(streamTypeAlias, state); 3550 } else if ((direction == AudioManager.ADJUST_RAISE) 3551 && mSoundDoseHelper.raiseVolumeDisplaySafeMediaVolume(streamTypeAlias, 3552 aliasIndex + step, device, flags)) { 3553 Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex); 3554 } else if (!isFullVolumeDevice(device) 3555 && (streamState.adjustIndex(direction * step, device, caller, 3556 hasModifyAudioSettings) 3557 || streamState.mIsMuted)) { 3558 // Post message to set system volume (it in turn will post a 3559 // message to persist). 3560 if (streamState.mIsMuted) { 3561 // Unmute the stream if it was previously muted 3562 if (direction == AudioManager.ADJUST_RAISE) { 3563 // unmute immediately for volume up 3564 muteAliasStreams(streamTypeAlias, false); 3565 } else if (direction == AudioManager.ADJUST_LOWER) { 3566 if (mIsSingleVolume) { 3567 sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE, 3568 streamTypeAlias, flags, null, UNMUTE_STREAM_DELAY); 3569 } 3570 } 3571 } 3572 sendMsg(mAudioHandler, 3573 MSG_SET_DEVICE_VOLUME, 3574 SENDMSG_QUEUE, 3575 device, 3576 0, 3577 streamState, 3578 0); 3579 } 3580 3581 int newIndex = mStreamStates[streamType].getIndex(device); 3582 3583 // Check if volume update should be send to AVRCP 3584 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 3585 && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 3586 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 3587 if (DEBUG_VOL) { 3588 Log.d(TAG, "adjustSreamVolume: postSetAvrcpAbsoluteVolumeIndex index=" 3589 + newIndex + "stream=" + streamType); 3590 } 3591 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10); 3592 } else if (isAbsoluteVolumeDevice(device) 3593 && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) { 3594 AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device); 3595 dispatchAbsoluteVolumeChanged(streamType, info, newIndex); 3596 } 3597 3598 if (AudioSystem.isLeAudioDeviceType(device) 3599 && streamType == getBluetoothContextualVolumeStream() 3600 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 3601 if (DEBUG_VOL) { 3602 Log.d(TAG, "adjustSreamVolume postSetLeAudioVolumeIndex index=" 3603 + newIndex + " stream=" + streamType); 3604 } 3605 mDeviceBroker.postSetLeAudioVolumeIndex(newIndex, 3606 mStreamStates[streamType].getMaxIndex(), streamType); 3607 } 3608 3609 // Check if volume update should be send to Hearing Aid 3610 if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 3611 // only modify the hearing aid attenuation when the stream to modify matches 3612 // the one expected by the hearing aid 3613 if (streamType == getBluetoothContextualVolumeStream()) { 3614 if (DEBUG_VOL) { 3615 Log.d(TAG, "adjustSreamVolume postSetHearingAidVolumeIndex index=" 3616 + newIndex + " stream=" + streamType); 3617 } 3618 mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType); 3619 } 3620 } 3621 } 3622 3623 final int newIndex = mStreamStates[streamType].getIndex(device); 3624 3625 if (adjustVolume) { 3626 synchronized (mHdmiClientLock) { 3627 if (mHdmiManager != null) { 3628 // At most one of mHdmiPlaybackClient and mHdmiTvClient should be non-null 3629 HdmiClient fullVolumeHdmiClient = mHdmiPlaybackClient; 3630 if (mHdmiTvClient != null) { 3631 fullVolumeHdmiClient = mHdmiTvClient; 3632 } 3633 3634 if (fullVolumeHdmiClient != null 3635 && mHdmiCecVolumeControlEnabled 3636 && streamTypeAlias == AudioSystem.STREAM_MUSIC 3637 // vol change on a full volume device 3638 && isFullVolumeDevice(device)) { 3639 int keyCode = KeyEvent.KEYCODE_UNKNOWN; 3640 switch (direction) { 3641 case AudioManager.ADJUST_RAISE: 3642 keyCode = KeyEvent.KEYCODE_VOLUME_UP; 3643 break; 3644 case AudioManager.ADJUST_LOWER: 3645 keyCode = KeyEvent.KEYCODE_VOLUME_DOWN; 3646 break; 3647 case AudioManager.ADJUST_TOGGLE_MUTE: 3648 case AudioManager.ADJUST_MUTE: 3649 case AudioManager.ADJUST_UNMUTE: 3650 // Many CEC devices only support toggle mute. Therefore, we send the 3651 // same keycode for all three mute options. 3652 keyCode = KeyEvent.KEYCODE_VOLUME_MUTE; 3653 break; 3654 default: 3655 break; 3656 } 3657 if (keyCode != KeyEvent.KEYCODE_UNKNOWN) { 3658 final long ident = Binder.clearCallingIdentity(); 3659 try { 3660 switch (keyEventMode) { 3661 case AudioDeviceVolumeManager.ADJUST_MODE_NORMAL: 3662 fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, true); 3663 fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, false); 3664 break; 3665 case AudioDeviceVolumeManager.ADJUST_MODE_START: 3666 fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, true); 3667 break; 3668 case AudioDeviceVolumeManager.ADJUST_MODE_END: 3669 fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, false); 3670 break; 3671 default: 3672 Log.e(TAG, "Invalid keyEventMode " + keyEventMode); 3673 } 3674 } finally { 3675 Binder.restoreCallingIdentity(ident); 3676 } 3677 } 3678 } 3679 3680 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 3681 && (oldIndex != newIndex || isMuteAdjust)) { 3682 maybeSendSystemAudioStatusCommand(isMuteAdjust); 3683 } 3684 } 3685 } 3686 } 3687 sendVolumeUpdate(streamType, oldIndex, newIndex, flags, device); 3688 } 3689 3690 /** 3691 * Loops on aliasted stream, update the mute cache attribute of each 3692 * {@see AudioService#VolumeStreamState}, and then apply the change. 3693 * It prevents to unnecessary {@see AudioSystem#setStreamVolume} done for each stream 3694 * and aliases before mute change changed and after. 3695 */ muteAliasStreams(int streamAlias, boolean state)3696 private void muteAliasStreams(int streamAlias, boolean state) { 3697 // Locking mSettingsLock to avoid inversion when calling doMute -> updateVolumeGroupIndex 3698 synchronized (mSettingsLock) { 3699 synchronized (VolumeStreamState.class) { 3700 List<Integer> streamsToMute = new ArrayList<>(); 3701 for (int stream = 0; stream < mStreamStates.length; stream++) { 3702 VolumeStreamState vss = mStreamStates[stream]; 3703 if (streamAlias == mStreamVolumeAlias[stream] && vss.isMutable()) { 3704 if (!(mCameraSoundForced 3705 && (vss.getStreamType() 3706 == AudioSystem.STREAM_SYSTEM_ENFORCED))) { 3707 boolean changed = vss.mute(state, /* apply= */ false, 3708 "muteAliasStreams"); 3709 if (changed) { 3710 streamsToMute.add(stream); 3711 } 3712 } 3713 } 3714 } 3715 streamsToMute.forEach(streamToMute -> { 3716 mStreamStates[streamToMute].doMute(); 3717 broadcastMuteSetting(streamToMute, state); 3718 }); 3719 } 3720 } 3721 } 3722 broadcastMuteSetting(int streamType, boolean isMuted)3723 private void broadcastMuteSetting(int streamType, boolean isMuted) { 3724 // Stream mute changed, fire the intent. 3725 Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION); 3726 intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType); 3727 intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, isMuted); 3728 sendBroadcastToAll(intent, null /* options */); 3729 } 3730 3731 // Called after a delay when volume down is pressed while muted onUnmuteStream(int stream, int flags)3732 private void onUnmuteStream(int stream, int flags) { 3733 boolean wasMuted; 3734 // Locking mSettingsLock to avoid inversion when calling vss.mute -> vss.doMute -> 3735 // vss.updateVolumeGroupIndex 3736 synchronized (mSettingsLock) { 3737 synchronized (VolumeStreamState.class) { 3738 final VolumeStreamState streamState = mStreamStates[stream]; 3739 // if unmuting causes a change, it was muted 3740 wasMuted = streamState.mute(false, "onUnmuteStream"); 3741 3742 final int device = getDeviceForStream(stream); 3743 final int index = streamState.getIndex(device); 3744 sendVolumeUpdate(stream, index, index, flags, device); 3745 } 3746 if (stream == AudioSystem.STREAM_MUSIC && wasMuted) { 3747 synchronized (mHdmiClientLock) { 3748 maybeSendSystemAudioStatusCommand(true); 3749 } 3750 } 3751 } 3752 } 3753 3754 @GuardedBy("mHdmiClientLock") maybeSendSystemAudioStatusCommand(boolean isMuteAdjust)3755 private void maybeSendSystemAudioStatusCommand(boolean isMuteAdjust) { 3756 if (mHdmiAudioSystemClient == null 3757 || !mHdmiSystemAudioSupported 3758 || !mHdmiCecVolumeControlEnabled) { 3759 return; 3760 } 3761 3762 final long identity = Binder.clearCallingIdentity(); 3763 try { 3764 mHdmiAudioSystemClient.sendReportAudioStatusCecCommand( 3765 isMuteAdjust, getStreamVolume(AudioSystem.STREAM_MUSIC), 3766 getStreamMaxVolume(AudioSystem.STREAM_MUSIC), 3767 isStreamMute(AudioSystem.STREAM_MUSIC)); 3768 } finally { 3769 Binder.restoreCallingIdentity(identity); 3770 } 3771 } 3772 getNewRingerMode(int stream, int index, int flags)3773 private int getNewRingerMode(int stream, int index, int flags) { 3774 // setRingerMode does nothing if the device is single volume,so the value would be unchanged 3775 if (mIsSingleVolume) { 3776 return getRingerModeExternal(); 3777 } 3778 3779 // setting volume on ui sounds stream type also controls silent mode 3780 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 3781 (stream == getUiSoundsStreamType())) { 3782 int newRingerMode; 3783 if (index == 0) { 3784 newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE 3785 : mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT 3786 : AudioManager.RINGER_MODE_NORMAL; 3787 } else { 3788 newRingerMode = AudioManager.RINGER_MODE_NORMAL; 3789 } 3790 return newRingerMode; 3791 } 3792 return getRingerModeExternal(); 3793 } 3794 isAndroidNPlus(String caller)3795 private boolean isAndroidNPlus(String caller) { 3796 try { 3797 final ApplicationInfo applicationInfo = 3798 mContext.getPackageManager().getApplicationInfoAsUser( 3799 caller, 0, UserHandle.getUserId(Binder.getCallingUid())); 3800 if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) { 3801 return true; 3802 } 3803 return false; 3804 } catch (PackageManager.NameNotFoundException e) { 3805 return true; 3806 } 3807 } 3808 wouldToggleZenMode(int newMode)3809 private boolean wouldToggleZenMode(int newMode) { 3810 if (getRingerModeExternal() == AudioManager.RINGER_MODE_SILENT 3811 && newMode != AudioManager.RINGER_MODE_SILENT) { 3812 return true; 3813 } else if (getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT 3814 && newMode == AudioManager.RINGER_MODE_SILENT) { 3815 return true; 3816 } 3817 return false; 3818 } 3819 3820 /** 3821 * Update stream volume, ringer mode and mute status after a volume index change 3822 * @param streamType 3823 * @param index 3824 * @param flags 3825 * @param device the device for which the volume is changed 3826 * @param caller 3827 * @param hasModifyAudioSettings 3828 * @param canChangeMute true if the origin of this event is one where the mute state should be 3829 * updated following the change in volume index 3830 */ onSetStreamVolume(int streamType, int index, int flags, int device, String caller, boolean hasModifyAudioSettings, boolean canChangeMute)3831 /*package*/ void onSetStreamVolume(int streamType, int index, int flags, int device, 3832 String caller, boolean hasModifyAudioSettings, boolean canChangeMute) { 3833 final int stream = mStreamVolumeAlias[streamType]; 3834 // setting volume on ui sounds stream type also controls silent mode 3835 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 3836 (stream == getUiSoundsStreamType())) { 3837 setRingerMode(getNewRingerMode(stream, index, flags), 3838 TAG + ".onSetStreamVolume", false /*external*/); 3839 } 3840 setStreamVolumeInt(stream, index, device, false, caller, hasModifyAudioSettings); 3841 // setting non-zero volume for a muted stream unmutes the stream and vice versa 3842 // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements 3843 if ((streamType != AudioSystem.STREAM_BLUETOOTH_SCO) && canChangeMute) { 3844 // As adjustStreamVolume with muteAdjust flags mute/unmutes stream and aliased streams. 3845 muteAliasStreams(stream, index == 0); 3846 } 3847 } 3848 enforceModifyAudioRoutingPermission()3849 private void enforceModifyAudioRoutingPermission() { 3850 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 3851 != PackageManager.PERMISSION_GRANTED) { 3852 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission"); 3853 } 3854 } 3855 enforceAccessUltrasoundPermission()3856 private void enforceAccessUltrasoundPermission() { 3857 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.ACCESS_ULTRASOUND) 3858 != PackageManager.PERMISSION_GRANTED) { 3859 throw new SecurityException("Missing ACCESS_ULTRASOUND permission"); 3860 } 3861 } 3862 enforceQueryStatePermission()3863 private void enforceQueryStatePermission() { 3864 if (mContext.checkCallingOrSelfPermission(Manifest.permission.QUERY_AUDIO_STATE) 3865 != PackageManager.PERMISSION_GRANTED) { 3866 throw new SecurityException("Missing QUERY_AUDIO_STATE permissions"); 3867 } 3868 } 3869 enforceQueryStateOrModifyRoutingPermission()3870 private void enforceQueryStateOrModifyRoutingPermission() { 3871 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 3872 != PackageManager.PERMISSION_GRANTED 3873 && mContext.checkCallingOrSelfPermission(Manifest.permission.QUERY_AUDIO_STATE) 3874 != PackageManager.PERMISSION_GRANTED) { 3875 throw new SecurityException( 3876 "Missing MODIFY_AUDIO_ROUTING or QUERY_AUDIO_STATE permissions"); 3877 } 3878 } 3879 enforceCallAudioInterceptionPermission()3880 private void enforceCallAudioInterceptionPermission() { 3881 if (mContext.checkCallingOrSelfPermission( 3882 android.Manifest.permission.CALL_AUDIO_INTERCEPTION) 3883 != PackageManager.PERMISSION_GRANTED) { 3884 throw new SecurityException("Missing CALL_AUDIO_INTERCEPTION permission"); 3885 } 3886 } 3887 3888 3889 @Override 3890 @android.annotation.EnforcePermission(anyOf = { 3891 MODIFY_AUDIO_SETTINGS_PRIVILEGED, 3892 android.Manifest.permission.MODIFY_AUDIO_ROUTING 3893 }) 3894 /** @see AudioManager#setVolumeGroupVolumeIndex(int, int, int) */ setVolumeGroupVolumeIndex(int groupId, int index, int flags, String callingPackage, String attributionTag)3895 public void setVolumeGroupVolumeIndex(int groupId, int index, int flags, 3896 String callingPackage, String attributionTag) { 3897 super.setVolumeGroupVolumeIndex_enforcePermission(); 3898 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 3899 Log.e(TAG, ": no volume group found for id " + groupId); 3900 return; 3901 } 3902 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 3903 3904 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, vgs.name(), 3905 index, flags, callingPackage + ", user " + getCurrentUserId())); 3906 3907 vgs.setVolumeIndex(index, flags); 3908 3909 // For legacy reason, propagate to all streams associated to this volume group 3910 for (int groupedStream : vgs.getLegacyStreamTypes()) { 3911 try { 3912 ensureValidStreamType(groupedStream); 3913 } catch (IllegalArgumentException e) { 3914 Log.d(TAG, "volume group " + groupId + " has internal streams (" + groupedStream 3915 + "), do not change associated stream volume"); 3916 continue; 3917 } 3918 setStreamVolume(groupedStream, index, flags, /*device*/ null, 3919 callingPackage, callingPackage, 3920 attributionTag, Binder.getCallingUid(), true /*hasModifyAudioSettings*/); 3921 } 3922 } 3923 3924 @Nullable getAudioVolumeGroupById(int volumeGroupId)3925 private AudioVolumeGroup getAudioVolumeGroupById(int volumeGroupId) { 3926 for (AudioVolumeGroup avg : AudioVolumeGroup.getAudioVolumeGroups()) { 3927 if (avg.getId() == volumeGroupId) { 3928 return avg; 3929 } 3930 } 3931 3932 Log.e(TAG, ": invalid volume group id: " + volumeGroupId + " requested"); 3933 return null; 3934 } 3935 3936 @Override 3937 @android.annotation.EnforcePermission(anyOf = { 3938 MODIFY_AUDIO_SETTINGS_PRIVILEGED, 3939 android.Manifest.permission.MODIFY_AUDIO_ROUTING 3940 }) 3941 /** @see AudioManager#getVolumeGroupVolumeIndex(int) */ getVolumeGroupVolumeIndex(int groupId)3942 public int getVolumeGroupVolumeIndex(int groupId) { 3943 super.getVolumeGroupVolumeIndex_enforcePermission(); 3944 synchronized (VolumeStreamState.class) { 3945 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 3946 throw new IllegalArgumentException("No volume group for id " + groupId); 3947 } 3948 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 3949 // Return 0 when muted, not min index since for e.g. Voice Call, it has a non zero 3950 // min but it mutable on permission condition. 3951 return vgs.isMuted() ? 0 : vgs.getVolumeIndex(); 3952 } 3953 } 3954 3955 /** @see AudioManager#getVolumeGroupMaxVolumeIndex(int) */ 3956 @android.annotation.EnforcePermission(anyOf = { 3957 MODIFY_AUDIO_SETTINGS_PRIVILEGED, 3958 android.Manifest.permission.MODIFY_AUDIO_ROUTING 3959 }) getVolumeGroupMaxVolumeIndex(int groupId)3960 public int getVolumeGroupMaxVolumeIndex(int groupId) { 3961 super.getVolumeGroupMaxVolumeIndex_enforcePermission(); 3962 synchronized (VolumeStreamState.class) { 3963 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 3964 throw new IllegalArgumentException("No volume group for id " + groupId); 3965 } 3966 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 3967 return vgs.getMaxIndex(); 3968 } 3969 } 3970 3971 /** @see AudioManager#getVolumeGroupMinVolumeIndex(int) */ 3972 @android.annotation.EnforcePermission(anyOf = { 3973 MODIFY_AUDIO_SETTINGS_PRIVILEGED, 3974 android.Manifest.permission.MODIFY_AUDIO_ROUTING 3975 }) getVolumeGroupMinVolumeIndex(int groupId)3976 public int getVolumeGroupMinVolumeIndex(int groupId) { 3977 super.getVolumeGroupMinVolumeIndex_enforcePermission(); 3978 synchronized (VolumeStreamState.class) { 3979 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 3980 throw new IllegalArgumentException("No volume group for id " + groupId); 3981 } 3982 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 3983 return vgs.getMinIndex(); 3984 } 3985 } 3986 3987 @Override 3988 @android.annotation.EnforcePermission(anyOf = { 3989 android.Manifest.permission.MODIFY_AUDIO_ROUTING, 3990 android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED 3991 }) 3992 /** @see AudioDeviceVolumeManager#setDeviceVolume(VolumeInfo, AudioDeviceAttributes) 3993 * Part of service interface, check permissions and parameters here 3994 * Note calling package is for logging purposes only, not to be trusted 3995 */ setDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)3996 public void setDeviceVolume(@NonNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, 3997 @NonNull String callingPackage) { 3998 super.setDeviceVolume_enforcePermission(); 3999 Objects.requireNonNull(vi); 4000 Objects.requireNonNull(ada); 4001 Objects.requireNonNull(callingPackage); 4002 4003 if (!vi.hasStreamType()) { 4004 Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception()); 4005 return; 4006 } 4007 4008 int index = vi.getVolumeIndex(); 4009 if (index == VolumeInfo.INDEX_NOT_SET && !vi.hasMuteCommand()) { 4010 throw new IllegalArgumentException( 4011 "changing device volume requires a volume index or mute command"); 4012 } 4013 4014 // force a cache clear to force reevaluating stream type to audio device selection 4015 // that can interfere with the sending of the VOLUME_CHANGED_ACTION intent 4016 mAudioSystem.clearRoutingCache(); 4017 4018 // log the current device that will be used when evaluating the sending of the 4019 // VOLUME_CHANGED_ACTION intent to see if the current device is the one being modified 4020 final int currDev = getDeviceForStream(vi.getStreamType()); 4021 4022 final boolean skipping = (currDev == ada.getInternalType()); 4023 4024 AudioService.sVolumeLogger.enqueue(new DeviceVolumeEvent(vi.getStreamType(), index, ada, 4025 currDev, callingPackage, skipping)); 4026 4027 if (skipping) { 4028 // setDeviceVolume was called on a device currently being used 4029 return; 4030 } 4031 4032 // TODO handle unmuting of current audio device 4033 // if a stream is not muted but the VolumeInfo is for muting, set the volume index 4034 // for the device to min volume 4035 if (vi.hasMuteCommand() && vi.isMuted() && !isStreamMute(vi.getStreamType())) { 4036 setStreamVolumeWithAttributionInt(vi.getStreamType(), 4037 mStreamStates[vi.getStreamType()].getMinIndex(), 4038 /*flags*/ 0, 4039 ada, callingPackage, null); 4040 return; 4041 } 4042 4043 AudioService.sVolumeLogger.enqueueAndLog("setDeviceVolume" + " from:" + callingPackage 4044 + " " + vi + " " + ada, EventLogger.Event.ALOGI, TAG); 4045 4046 if (vi.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET 4047 || vi.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) { 4048 // assume index meant to be in stream type range, validate 4049 if ((index * 10) < mStreamStates[vi.getStreamType()].getMinIndex() 4050 || (index * 10) > mStreamStates[vi.getStreamType()].getMaxIndex()) { 4051 throw new IllegalArgumentException("invalid volume index " + index 4052 + " not between min/max for stream " + vi.getStreamType()); 4053 } 4054 } else { 4055 // check if index needs to be rescaled 4056 final int min = (mStreamStates[vi.getStreamType()].getMinIndex() + 5) / 10; 4057 final int max = (mStreamStates[vi.getStreamType()].getMaxIndex() + 5) / 10; 4058 if (vi.getMinVolumeIndex() != min || vi.getMaxVolumeIndex() != max) { 4059 index = rescaleIndex(index, 4060 /*srcMin*/ vi.getMinVolumeIndex(), /*srcMax*/ vi.getMaxVolumeIndex(), 4061 /*dstMin*/ min, /*dstMax*/ max); 4062 } 4063 } 4064 setStreamVolumeWithAttributionInt(vi.getStreamType(), index, /*flags*/ 0, 4065 ada, callingPackage, null); 4066 } 4067 4068 /** Retain API for unsupported app usage */ setStreamVolume(int streamType, int index, int flags, String callingPackage)4069 public void setStreamVolume(int streamType, int index, int flags, String callingPackage) { 4070 setStreamVolumeWithAttribution(streamType, index, flags, 4071 callingPackage, /*attributionTag*/ null); 4072 } 4073 4074 /** @see AudioManager#adjustVolumeGroupVolume(int, int, int) */ adjustVolumeGroupVolume(int groupId, int direction, int flags, String callingPackage)4075 public void adjustVolumeGroupVolume(int groupId, int direction, int flags, 4076 String callingPackage) { 4077 ensureValidDirection(direction); 4078 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4079 Log.e(TAG, ": no volume group found for id " + groupId); 4080 return; 4081 } 4082 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4083 // For compatibility reason, use stream API if group linked to a valid stream 4084 boolean fallbackOnStream = false; 4085 for (int stream : vgs.getLegacyStreamTypes()) { 4086 try { 4087 ensureValidStreamType(stream); 4088 } catch (IllegalArgumentException e) { 4089 Log.d(TAG, "volume group " + groupId + " has internal streams (" + stream 4090 + "), do not change associated stream volume"); 4091 continue; 4092 } 4093 // Note: Group and Stream does not share same convention, 0 is mute for stream, 4094 // min index is acting as mute for Groups 4095 if (vgs.isVssMuteBijective(stream)) { 4096 adjustStreamVolume(stream, direction, flags, callingPackage); 4097 if (isMuteAdjust(direction)) { 4098 // will be propagated to all aliased streams 4099 return; 4100 } 4101 fallbackOnStream = true; 4102 } 4103 } 4104 if (fallbackOnStream) { 4105 // Handled by at least one stream, will be propagated to group, bailing out. 4106 return; 4107 } 4108 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_GROUP_VOL, vgs.name(), 4109 direction, flags, callingPackage)); 4110 vgs.adjustVolume(direction, flags); 4111 } 4112 4113 /** @see AudioManager#getLastAudibleVolumeForVolumeGroup(int) */ 4114 @android.annotation.EnforcePermission(android.Manifest.permission.QUERY_AUDIO_STATE) getLastAudibleVolumeForVolumeGroup(int groupId)4115 public int getLastAudibleVolumeForVolumeGroup(int groupId) { 4116 super.getLastAudibleVolumeForVolumeGroup_enforcePermission(); 4117 synchronized (VolumeStreamState.class) { 4118 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4119 Log.e(TAG, ": no volume group found for id " + groupId); 4120 return 0; 4121 } 4122 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4123 return vgs.getVolumeIndex(); 4124 } 4125 } 4126 4127 /** @see AudioManager#isVolumeGroupMuted(int) */ isVolumeGroupMuted(int groupId)4128 public boolean isVolumeGroupMuted(int groupId) { 4129 synchronized (VolumeStreamState.class) { 4130 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4131 Log.e(TAG, ": no volume group found for id " + groupId); 4132 return false; 4133 } 4134 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4135 return vgs.isMuted(); 4136 } 4137 } 4138 4139 /** @see AudioManager#setStreamVolume(int, int, int) 4140 * Part of service interface, check permissions here */ setStreamVolumeWithAttribution(int streamType, int index, int flags, String callingPackage, String attributionTag)4141 public void setStreamVolumeWithAttribution(int streamType, int index, int flags, 4142 String callingPackage, String attributionTag) { 4143 setStreamVolumeWithAttributionInt(streamType, index, flags, /*device*/ null, 4144 callingPackage, attributionTag); 4145 } 4146 4147 /** 4148 * Internal method for a stream type volume change. Can be used to change the volume on a 4149 * given device only 4150 * @param streamType the stream type whose volume is to be changed 4151 * @param index the volume index 4152 * @param flags options for volume handling 4153 * @param device null when controlling volume for the current routing, otherwise the device 4154 * for which volume is being changed 4155 * @param callingPackage client side-provided package name of caller, not to be trusted 4156 * @param attributionTag client side-provided attribution name, not to be trusted 4157 */ setStreamVolumeWithAttributionInt(int streamType, int index, int flags, @Nullable AudioDeviceAttributes device, String callingPackage, String attributionTag)4158 protected void setStreamVolumeWithAttributionInt(int streamType, int index, int flags, 4159 @Nullable AudioDeviceAttributes device, 4160 String callingPackage, String attributionTag) { 4161 if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { 4162 Log.w(TAG, "Trying to call setStreamVolume() for a11y without" 4163 + " CHANGE_ACCESSIBILITY_VOLUME callingPackage=" + callingPackage); 4164 return; 4165 } 4166 if ((streamType == AudioManager.STREAM_VOICE_CALL) && (index == 0) 4167 && (mContext.checkCallingOrSelfPermission( 4168 android.Manifest.permission.MODIFY_PHONE_STATE) 4169 != PackageManager.PERMISSION_GRANTED)) { 4170 Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL and index 0 without" 4171 + " MODIFY_PHONE_STATE callingPackage=" + callingPackage); 4172 return; 4173 } 4174 if ((streamType == AudioManager.STREAM_ASSISTANT) 4175 && (mContext.checkCallingOrSelfPermission( 4176 android.Manifest.permission.MODIFY_AUDIO_ROUTING) 4177 != PackageManager.PERMISSION_GRANTED)) { 4178 Log.w(TAG, "Trying to call setStreamVolume() for STREAM_ASSISTANT without" 4179 + " MODIFY_AUDIO_ROUTING callingPackage=" + callingPackage); 4180 return; 4181 } 4182 4183 if (device == null) { 4184 // call was already logged in setDeviceVolume() 4185 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType, 4186 index/*val1*/, flags/*val2*/, callingPackage)); 4187 } 4188 setStreamVolume(streamType, index, flags, device, 4189 callingPackage, callingPackage, attributionTag, 4190 Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission()); 4191 } 4192 4193 @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_ULTRASOUND) 4194 /** @see AudioManager#isUltrasoundSupported() */ isUltrasoundSupported()4195 public boolean isUltrasoundSupported() { 4196 super.isUltrasoundSupported_enforcePermission(); 4197 4198 return AudioSystem.isUltrasoundSupported(); 4199 } 4200 4201 /** @see AudioManager#isHotwordStreamSupported() */ 4202 @android.annotation.EnforcePermission(android.Manifest.permission.CAPTURE_AUDIO_HOTWORD) isHotwordStreamSupported(boolean lookbackAudio)4203 public boolean isHotwordStreamSupported(boolean lookbackAudio) { 4204 super.isHotwordStreamSupported_enforcePermission(); 4205 try { 4206 return mAudioPolicy.isHotwordStreamSupported(lookbackAudio); 4207 } catch (IllegalStateException e) { 4208 // Suppress connection failure to APM, since the method is purely informative 4209 Log.e(TAG, "Suppressing exception calling into AudioPolicy", e); 4210 return false; 4211 } 4212 } 4213 4214 canChangeAccessibilityVolume()4215 private boolean canChangeAccessibilityVolume() { 4216 synchronized (mAccessibilityServiceUidsLock) { 4217 if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 4218 android.Manifest.permission.CHANGE_ACCESSIBILITY_VOLUME)) { 4219 return true; 4220 } 4221 if (mAccessibilityServiceUids != null) { 4222 int callingUid = Binder.getCallingUid(); 4223 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 4224 if (mAccessibilityServiceUids[i] == callingUid) { 4225 return true; 4226 } 4227 } 4228 } 4229 return false; 4230 } 4231 } 4232 getBluetoothContextualVolumeStream()4233 /*package*/ int getBluetoothContextualVolumeStream() { 4234 return getBluetoothContextualVolumeStream(mMode.get()); 4235 } 4236 getBluetoothContextualVolumeStream(int mode)4237 private int getBluetoothContextualVolumeStream(int mode) { 4238 switch (mode) { 4239 case AudioSystem.MODE_IN_COMMUNICATION: 4240 case AudioSystem.MODE_IN_CALL: 4241 return AudioSystem.STREAM_VOICE_CALL; 4242 case AudioSystem.MODE_NORMAL: 4243 default: 4244 // other conditions will influence the stream type choice, read on... 4245 break; 4246 } 4247 if (mVoicePlaybackActive.get()) { 4248 return AudioSystem.STREAM_VOICE_CALL; 4249 } 4250 return AudioSystem.STREAM_MUSIC; 4251 } 4252 4253 private AtomicBoolean mVoicePlaybackActive = new AtomicBoolean(false); 4254 private AtomicBoolean mMediaPlaybackActive = new AtomicBoolean(false); 4255 4256 private final IPlaybackConfigDispatcher mPlaybackActivityMonitor = 4257 new IPlaybackConfigDispatcher.Stub() { 4258 @Override 4259 public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs, 4260 boolean flush) { 4261 sendMsg(mAudioHandler, MSG_PLAYBACK_CONFIG_CHANGE, SENDMSG_REPLACE, 4262 0 /*arg1 ignored*/, 0 /*arg2 ignored*/, 4263 configs /*obj*/, 0 /*delay*/); 4264 } 4265 }; 4266 onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs)4267 private void onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) { 4268 boolean voiceActive = false; 4269 boolean mediaActive = false; 4270 for (AudioPlaybackConfiguration config : configs) { 4271 final int usage = config.getAudioAttributes().getUsage(); 4272 if (!config.isActive()) { 4273 continue; 4274 } 4275 if (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION 4276 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) { 4277 voiceActive = true; 4278 } 4279 if (usage == AudioAttributes.USAGE_MEDIA || usage == AudioAttributes.USAGE_GAME) { 4280 mediaActive = true; 4281 } 4282 } 4283 if (mVoicePlaybackActive.getAndSet(voiceActive) != voiceActive) { 4284 updateHearingAidVolumeOnVoiceActivityUpdate(); 4285 } 4286 if (mMediaPlaybackActive.getAndSet(mediaActive) != mediaActive && mediaActive) { 4287 mSoundDoseHelper.scheduleMusicActiveCheck(); 4288 } 4289 // Update playback active state for all apps in audio mode stack. 4290 // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE 4291 // and request an audio mode update immediately. Upon any other change, queue the message 4292 // and request an audio mode update after a grace period. 4293 updateAudioModeHandlers( 4294 configs /* playbackConfigs */, null /* recordConfigs */); 4295 mDeviceBroker.updateCommunicationRouteClientsActivity( 4296 configs /* playbackConfigs */, null /* recordConfigs */); 4297 } 4298 updateAudioModeHandlers(List<AudioPlaybackConfiguration> playbackConfigs, List<AudioRecordingConfiguration> recordConfigs)4299 void updateAudioModeHandlers(List<AudioPlaybackConfiguration> playbackConfigs, 4300 List<AudioRecordingConfiguration> recordConfigs) { 4301 synchronized (mDeviceBroker.mSetModeLock) { 4302 boolean updateAudioMode = false; 4303 int existingMsgPolicy = SENDMSG_QUEUE; 4304 int delay = CHECK_MODE_FOR_UID_PERIOD_MS; 4305 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 4306 boolean wasActive = h.isActive(); 4307 if (playbackConfigs != null) { 4308 h.setPlaybackActive(false); 4309 for (AudioPlaybackConfiguration config : playbackConfigs) { 4310 final int usage = config.getAudioAttributes().getUsage(); 4311 if (config.getClientUid() == h.getUid() 4312 && (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION 4313 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) 4314 && config.isActive()) { 4315 h.setPlaybackActive(true); 4316 break; 4317 } 4318 } 4319 } 4320 if (recordConfigs != null) { 4321 h.setRecordingActive(false); 4322 for (AudioRecordingConfiguration config : recordConfigs) { 4323 if (config.getClientUid() == h.getUid() && !config.isClientSilenced() 4324 && config.getAudioSource() == AudioSource.VOICE_COMMUNICATION) { 4325 h.setRecordingActive(true); 4326 break; 4327 } 4328 } 4329 } 4330 if (wasActive != h.isActive()) { 4331 updateAudioMode = true; 4332 if (h.isActive() && h == getAudioModeOwnerHandler()) { 4333 existingMsgPolicy = SENDMSG_REPLACE; 4334 delay = 0; 4335 } 4336 } 4337 } 4338 if (updateAudioMode) { 4339 sendMsg(mAudioHandler, 4340 MSG_UPDATE_AUDIO_MODE, 4341 existingMsgPolicy, 4342 AudioSystem.MODE_CURRENT, 4343 android.os.Process.myPid(), 4344 mContext.getPackageName(), 4345 delay); 4346 } 4347 } 4348 } 4349 4350 private final IRecordingConfigDispatcher mVoiceRecordingActivityMonitor = 4351 new IRecordingConfigDispatcher.Stub() { 4352 @Override 4353 public void dispatchRecordingConfigChange(List<AudioRecordingConfiguration> configs) { 4354 sendMsg(mAudioHandler, MSG_RECORDING_CONFIG_CHANGE, SENDMSG_REPLACE, 4355 0 /*arg1 ignored*/, 0 /*arg2 ignored*/, 4356 configs /*obj*/, 0 /*delay*/); 4357 } 4358 }; 4359 onRecordingConfigChange(List<AudioRecordingConfiguration> configs)4360 private void onRecordingConfigChange(List<AudioRecordingConfiguration> configs) { 4361 // Update recording active state for all apps in audio mode stack. 4362 // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE 4363 // and request an audio mode update immediately. Upon any other change, queue the message 4364 // and request an audio mode update after a grace period. 4365 updateAudioModeHandlers( 4366 null /* playbackConfigs */, configs /* recordConfigs */); 4367 mDeviceBroker.updateCommunicationRouteClientsActivity( 4368 null /* playbackConfigs */, configs /* recordConfigs */); 4369 } 4370 dumpAudioMode(PrintWriter pw)4371 private void dumpAudioMode(PrintWriter pw) { 4372 pw.println("\nAudio mode: "); 4373 pw.println("- Requested mode = " + AudioSystem.modeToString(getMode())); 4374 pw.println("- Actual mode = " + AudioSystem.modeToString(mMode.get())); 4375 pw.println("- Mode owner: "); 4376 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 4377 if (hdlr != null) { 4378 hdlr.dump(pw, -1); 4379 } else { 4380 pw.println(" None"); 4381 } 4382 pw.println("- Mode owner stack: "); 4383 if (mSetModeDeathHandlers.isEmpty()) { 4384 pw.println(" Empty"); 4385 } else { 4386 for (int i = 0; i < mSetModeDeathHandlers.size(); i++) { 4387 mSetModeDeathHandlers.get(i).dump(pw, i); 4388 } 4389 } 4390 } 4391 updateHearingAidVolumeOnVoiceActivityUpdate()4392 private void updateHearingAidVolumeOnVoiceActivityUpdate() { 4393 final int streamType = getBluetoothContextualVolumeStream(); 4394 final int index = getStreamVolume(streamType); 4395 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_HEARING_AID, 4396 mVoicePlaybackActive.get(), streamType, index)); 4397 mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType); 4398 4399 } 4400 4401 /** 4402 * Manage an audio mode change for audio devices that use an "absolute volume" model, 4403 * i.e. the framework sends the full scale signal, and the actual volume for the use case 4404 * is communicated separately. 4405 */ updateAbsVolumeMultiModeDevices(int oldMode, int newMode)4406 void updateAbsVolumeMultiModeDevices(int oldMode, int newMode) { 4407 if (oldMode == newMode) { 4408 return; 4409 } 4410 switch (newMode) { 4411 case AudioSystem.MODE_IN_COMMUNICATION: 4412 case AudioSystem.MODE_IN_CALL: 4413 case AudioSystem.MODE_NORMAL: 4414 case AudioSystem.MODE_CALL_SCREENING: 4415 case AudioSystem.MODE_CALL_REDIRECT: 4416 case AudioSystem.MODE_COMMUNICATION_REDIRECT: 4417 break; 4418 default: 4419 // no-op is enough for all other values 4420 return; 4421 } 4422 4423 int streamType = getBluetoothContextualVolumeStream(newMode); 4424 4425 final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType); 4426 final Set<Integer> absVolumeMultiModeCaseDevices = AudioSystem.intersectionAudioDeviceTypes( 4427 mAbsVolumeMultiModeCaseDevices, deviceTypes); 4428 if (absVolumeMultiModeCaseDevices.isEmpty()) { 4429 return; 4430 } 4431 4432 // handling of specific interfaces goes here: 4433 if (AudioSystem.isSingleAudioDeviceType( 4434 absVolumeMultiModeCaseDevices, AudioSystem.DEVICE_OUT_HEARING_AID)) { 4435 final int index = getStreamVolume(streamType); 4436 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID, 4437 newMode, streamType, index)); 4438 mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType); 4439 } 4440 } 4441 setLeAudioVolumeOnModeUpdate(int mode, int device, int streamType, int index, int maxIndex)4442 private void setLeAudioVolumeOnModeUpdate(int mode, int device, int streamType, int index, 4443 int maxIndex) { 4444 switch (mode) { 4445 case AudioSystem.MODE_IN_COMMUNICATION: 4446 case AudioSystem.MODE_IN_CALL: 4447 case AudioSystem.MODE_NORMAL: 4448 case AudioSystem.MODE_CALL_SCREENING: 4449 case AudioSystem.MODE_CALL_REDIRECT: 4450 case AudioSystem.MODE_COMMUNICATION_REDIRECT: 4451 break; 4452 default: 4453 // no-op is enough for all other values 4454 return; 4455 } 4456 4457 // In some cases (like the outgoing or rejected call) the value of 'device' is not 4458 // DEVICE_OUT_BLE_* even when BLE is connected. Changing the volume level in such case 4459 // may cuase the other devices volume level leaking into the LeAudio device settings. 4460 if (!AudioSystem.isLeAudioDeviceType(device)) { 4461 Log.w(TAG, "setLeAudioVolumeOnModeUpdate ignoring invalid device=" 4462 + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex 4463 + " streamType=" + streamType); 4464 return; 4465 } 4466 4467 if (DEBUG_VOL) { 4468 Log.d(TAG, "setLeAudioVolumeOnModeUpdate postSetLeAudioVolumeIndex device=" 4469 + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex 4470 + " streamType=" + streamType); 4471 } 4472 mDeviceBroker.postSetLeAudioVolumeIndex(index, maxIndex, streamType); 4473 mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "setLeAudioVolumeOnModeUpdate"); 4474 } 4475 setStreamVolume(int streamType, int index, int flags, @Nullable AudioDeviceAttributes ada, String callingPackage, String caller, String attributionTag, int uid, boolean hasModifyAudioSettings)4476 private void setStreamVolume(int streamType, int index, int flags, 4477 @Nullable AudioDeviceAttributes ada, 4478 String callingPackage, String caller, String attributionTag, int uid, 4479 boolean hasModifyAudioSettings) { 4480 if (DEBUG_VOL) { 4481 Log.d(TAG, "setStreamVolume(stream=" + streamType+", index=" + index 4482 + ", dev=" + ada 4483 + ", calling=" + callingPackage + ")"); 4484 } 4485 if (mUseFixedVolume) { 4486 return; 4487 } 4488 4489 ensureValidStreamType(streamType); 4490 int streamTypeAlias = mStreamVolumeAlias[streamType]; 4491 VolumeStreamState streamState = mStreamStates[streamTypeAlias]; 4492 4493 final int device = (ada == null) 4494 ? getDeviceForStream(streamType) 4495 : ada.getInternalType(); 4496 int oldIndex; 4497 4498 // skip a2dp absolute volume control request when the device 4499 // is neither an a2dp device nor BLE device 4500 if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 4501 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device)) 4502 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { 4503 return; 4504 } 4505 // If we are being called by the system (e.g. hardware keys) check for current user 4506 // so we handle user restrictions correctly. 4507 if (uid == android.os.Process.SYSTEM_UID) { 4508 uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); 4509 } 4510 if (!checkNoteAppOp( 4511 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) { 4512 return; 4513 } 4514 4515 if (isAndroidNPlus(callingPackage) 4516 && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags)) 4517 && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) { 4518 throw new SecurityException("Not allowed to change Do Not Disturb state"); 4519 } 4520 4521 if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) { 4522 return; 4523 } 4524 4525 mSoundDoseHelper.invalidatPendingVolumeCommand(); 4526 4527 oldIndex = streamState.getIndex(device); 4528 4529 index = rescaleIndex(index * 10, streamType, streamTypeAlias); 4530 4531 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 4532 && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 4533 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 4534 if (DEBUG_VOL) { 4535 Log.d(TAG, "setStreamVolume postSetAvrcpAbsoluteVolumeIndex index=" + index 4536 + "stream=" + streamType); 4537 } 4538 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10); 4539 } else if (isAbsoluteVolumeDevice(device) 4540 && ((flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0)) { 4541 AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device); 4542 4543 dispatchAbsoluteVolumeChanged(streamType, info, index); 4544 } 4545 4546 if (AudioSystem.isLeAudioDeviceType(device) 4547 && streamType == getBluetoothContextualVolumeStream() 4548 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 4549 if (DEBUG_VOL) { 4550 Log.d(TAG, "adjustSreamVolume postSetLeAudioVolumeIndex index=" 4551 + index + " stream=" + streamType); 4552 } 4553 mDeviceBroker.postSetLeAudioVolumeIndex(index, mStreamStates[streamType].getMaxIndex(), 4554 streamType); 4555 } 4556 4557 if (device == AudioSystem.DEVICE_OUT_HEARING_AID 4558 && streamType == getBluetoothContextualVolumeStream()) { 4559 Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index 4560 + " stream=" + streamType); 4561 mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType); 4562 } 4563 4564 flags &= ~AudioManager.FLAG_FIXED_VOLUME; 4565 if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) { 4566 flags |= AudioManager.FLAG_FIXED_VOLUME; 4567 4568 // volume is either 0 or max allowed for fixed volume devices 4569 if (index != 0) { 4570 index = mSoundDoseHelper.getSafeMediaVolumeIndex(device); 4571 if (index < 0) { 4572 index = streamState.getMaxIndex(); 4573 } 4574 } 4575 } 4576 4577 if (!mSoundDoseHelper.willDisplayWarningAfterCheckVolume(streamType, index, device, 4578 flags)) { 4579 onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings, 4580 // ada is non-null when called from setDeviceVolume, 4581 // which shouldn't update the mute state 4582 ada == null /*canChangeMute*/); 4583 index = mStreamStates[streamType].getIndex(device); 4584 } 4585 4586 synchronized (mHdmiClientLock) { 4587 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 4588 && (oldIndex != index)) { 4589 maybeSendSystemAudioStatusCommand(false); 4590 } 4591 } 4592 if (ada == null) { 4593 // only non-null when coming here from setDeviceVolume 4594 // TODO change test to check early if device is current device or not 4595 sendVolumeUpdate(streamType, oldIndex, index, flags, device); 4596 } 4597 } 4598 dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index)4599 private void dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, 4600 int index) { 4601 VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType); 4602 if (volumeInfo != null) { 4603 try { 4604 deviceInfo.mCallback.dispatchDeviceVolumeChanged(deviceInfo.mDevice, 4605 new VolumeInfo.Builder(volumeInfo) 4606 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo)) 4607 .build()); 4608 } catch (RemoteException e) { 4609 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume change"); 4610 } 4611 } 4612 } 4613 dispatchAbsoluteVolumeAdjusted(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode)4614 private void dispatchAbsoluteVolumeAdjusted(int streamType, 4615 AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode) { 4616 VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType); 4617 if (volumeInfo != null) { 4618 try { 4619 deviceInfo.mCallback.dispatchDeviceVolumeAdjusted(deviceInfo.mDevice, 4620 new VolumeInfo.Builder(volumeInfo) 4621 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo)) 4622 .build(), 4623 direction, 4624 mode); 4625 } catch (RemoteException e) { 4626 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume adjustment"); 4627 } 4628 } 4629 } 4630 4631 // No ringer or zen muted stream volumes can be changed unless it'll exit dnd volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags)4632 private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) { 4633 switch (mNm.getZenMode()) { 4634 case Settings.Global.ZEN_MODE_OFF: 4635 return true; 4636 case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: 4637 case Settings.Global.ZEN_MODE_ALARMS: 4638 case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: 4639 return !isStreamMutedByRingerOrZenMode(streamTypeAlias) 4640 || isUiSoundsStreamType(streamTypeAlias) 4641 || (flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0; 4642 } 4643 4644 return true; 4645 } 4646 4647 /** @see AudioManager#forceVolumeControlStream(int) */ forceVolumeControlStream(int streamType, IBinder cb)4648 public void forceVolumeControlStream(int streamType, IBinder cb) { 4649 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) 4650 != PackageManager.PERMISSION_GRANTED) { 4651 return; 4652 } 4653 if (DEBUG_VOL) { Log.d(TAG, String.format("forceVolumeControlStream(%d)", streamType)); } 4654 synchronized(mForceControlStreamLock) { 4655 if (mVolumeControlStream != -1 && streamType != -1) { 4656 mUserSelectedVolumeControlStream = true; 4657 } 4658 mVolumeControlStream = streamType; 4659 if (mVolumeControlStream == -1) { 4660 if (mForceControlStreamClient != null) { 4661 mForceControlStreamClient.release(); 4662 mForceControlStreamClient = null; 4663 } 4664 mUserSelectedVolumeControlStream = false; 4665 } else { 4666 if (null == mForceControlStreamClient) { 4667 mForceControlStreamClient = new ForceControlStreamClient(cb); 4668 } else { 4669 if (mForceControlStreamClient.getBinder() == cb) { 4670 Log.d(TAG, "forceVolumeControlStream cb:" + cb + " is already linked."); 4671 } else { 4672 mForceControlStreamClient.release(); 4673 mForceControlStreamClient = new ForceControlStreamClient(cb); 4674 } 4675 } 4676 } 4677 } 4678 } 4679 4680 private class ForceControlStreamClient implements IBinder.DeathRecipient { 4681 private IBinder mCb; // To be notified of client's death 4682 ForceControlStreamClient(IBinder cb)4683 ForceControlStreamClient(IBinder cb) { 4684 if (cb != null) { 4685 try { 4686 cb.linkToDeath(this, 0); 4687 } catch (RemoteException e) { 4688 // Client has died! 4689 Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death"); 4690 cb = null; 4691 } 4692 } 4693 mCb = cb; 4694 } 4695 binderDied()4696 public void binderDied() { 4697 synchronized(mForceControlStreamLock) { 4698 Log.w(TAG, "SCO client died"); 4699 if (mForceControlStreamClient != this) { 4700 Log.w(TAG, "unregistered control stream client died"); 4701 } else { 4702 mForceControlStreamClient = null; 4703 mVolumeControlStream = -1; 4704 mUserSelectedVolumeControlStream = false; 4705 } 4706 } 4707 } 4708 release()4709 public void release() { 4710 if (mCb != null) { 4711 mCb.unlinkToDeath(this, 0); 4712 mCb = null; 4713 } 4714 } 4715 getBinder()4716 public IBinder getBinder() { 4717 return mCb; 4718 } 4719 } 4720 sendBroadcastToAll(Intent intent, Bundle options)4721 private void sendBroadcastToAll(Intent intent, Bundle options) { 4722 if (!mSystemServer.isPrivileged()) { 4723 return; 4724 } 4725 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 4726 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 4727 final long ident = Binder.clearCallingIdentity(); 4728 try { 4729 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 4730 null /* receiverPermission */, options); 4731 } finally { 4732 Binder.restoreCallingIdentity(ident); 4733 } 4734 } 4735 sendStickyBroadcastToAll(Intent intent)4736 private void sendStickyBroadcastToAll(Intent intent) { 4737 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 4738 final long ident = Binder.clearCallingIdentity(); 4739 try { 4740 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 4741 } finally { 4742 Binder.restoreCallingIdentity(ident); 4743 } 4744 } 4745 getCurrentUserId()4746 private int getCurrentUserId() { 4747 final long ident = Binder.clearCallingIdentity(); 4748 try { 4749 UserInfo currentUser = ActivityManager.getService().getCurrentUser(); 4750 return currentUser.id; 4751 } catch (RemoteException e) { 4752 // Activity manager not running, nothing we can do assume user 0. 4753 } finally { 4754 Binder.restoreCallingIdentity(ident); 4755 } 4756 return UserHandle.USER_SYSTEM; 4757 } 4758 4759 // UI update and Broadcast Intent sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)4760 protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device) 4761 { 4762 streamType = mStreamVolumeAlias[streamType]; 4763 4764 if (streamType == AudioSystem.STREAM_MUSIC && isFullVolumeDevice(device)) { 4765 flags &= ~AudioManager.FLAG_SHOW_UI; 4766 } 4767 mVolumeController.postVolumeChanged(streamType, flags); 4768 } 4769 4770 // Don't show volume UI when: 4771 // - Hdmi-CEC system audio mode is on and we are a TV panel updateFlagsForTvPlatform(int flags)4772 private int updateFlagsForTvPlatform(int flags) { 4773 synchronized (mHdmiClientLock) { 4774 if (mHdmiTvClient != null && mHdmiSystemAudioSupported 4775 && mHdmiCecVolumeControlEnabled) { 4776 flags &= ~AudioManager.FLAG_SHOW_UI; 4777 } 4778 } 4779 return flags; 4780 } 4781 // UI update and Broadcast Intent sendMasterMuteUpdate(boolean muted, int flags)4782 private void sendMasterMuteUpdate(boolean muted, int flags) { 4783 mVolumeController.postMasterMuteChanged(updateFlagsForTvPlatform(flags)); 4784 broadcastMasterMuteStatus(muted); 4785 } 4786 broadcastMasterMuteStatus(boolean muted)4787 private void broadcastMasterMuteStatus(boolean muted) { 4788 Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION); 4789 intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, muted); 4790 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 4791 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 4792 sendStickyBroadcastToAll(intent); 4793 } 4794 4795 /** 4796 * Sets the stream state's index, and posts a message to set system volume. 4797 * This will not call out to the UI. Assumes a valid stream type. 4798 * 4799 * @param streamType Type of the stream 4800 * @param index Desired volume index of the stream 4801 * @param device the device whose volume must be changed 4802 * @param force If true, set the volume even if the desired volume is same 4803 * @param caller 4804 * @param hasModifyAudioSettings true if the caller is granted MODIFY_AUDIO_SETTINGS or 4805 * MODIFY_AUDIO_ROUTING permission 4806 * as the current volume. 4807 */ setStreamVolumeInt(int streamType, int index, int device, boolean force, String caller, boolean hasModifyAudioSettings)4808 private void setStreamVolumeInt(int streamType, 4809 int index, 4810 int device, 4811 boolean force, 4812 String caller, boolean hasModifyAudioSettings) { 4813 if (isFullVolumeDevice(device)) { 4814 return; 4815 } 4816 VolumeStreamState streamState = mStreamStates[streamType]; 4817 4818 if (streamState.setIndex(index, device, caller, hasModifyAudioSettings) || force) { 4819 // Post message to set system volume (it in turn will post a message 4820 // to persist). 4821 sendMsg(mAudioHandler, 4822 MSG_SET_DEVICE_VOLUME, 4823 SENDMSG_QUEUE, 4824 device, 4825 0, 4826 streamState, 4827 0); 4828 } 4829 } 4830 4831 /** get stream mute state. */ isStreamMute(int streamType)4832 public boolean isStreamMute(int streamType) { 4833 if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 4834 streamType = getActiveStreamType(streamType); 4835 } 4836 synchronized (VolumeStreamState.class) { 4837 ensureValidStreamType(streamType); 4838 return mStreamStates[streamType].mIsMuted; 4839 } 4840 } 4841 4842 private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient { 4843 private IBinder mICallback; // To be notified of client's death 4844 RmtSbmxFullVolDeathHandler(IBinder cb)4845 RmtSbmxFullVolDeathHandler(IBinder cb) { 4846 mICallback = cb; 4847 try { 4848 cb.linkToDeath(this, 0/*flags*/); 4849 } catch (RemoteException e) { 4850 Log.e(TAG, "can't link to death", e); 4851 } 4852 } 4853 isHandlerFor(IBinder cb)4854 boolean isHandlerFor(IBinder cb) { 4855 return mICallback.equals(cb); 4856 } 4857 forget()4858 void forget() { 4859 try { 4860 mICallback.unlinkToDeath(this, 0/*flags*/); 4861 } catch (NoSuchElementException e) { 4862 Log.e(TAG, "error unlinking to death", e); 4863 } 4864 } 4865 binderDied()4866 public void binderDied() { 4867 Log.w(TAG, "Recorder with remote submix at full volume died " + mICallback); 4868 forceRemoteSubmixFullVolume(false, mICallback); 4869 } 4870 } 4871 4872 /** 4873 * call must be synchronized on mRmtSbmxFullVolDeathHandlers 4874 * @return true if there is a registered death handler, false otherwise */ discardRmtSbmxFullVolDeathHandlerFor(IBinder cb)4875 private boolean discardRmtSbmxFullVolDeathHandlerFor(IBinder cb) { 4876 Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator(); 4877 while (it.hasNext()) { 4878 final RmtSbmxFullVolDeathHandler handler = it.next(); 4879 if (handler.isHandlerFor(cb)) { 4880 handler.forget(); 4881 mRmtSbmxFullVolDeathHandlers.remove(handler); 4882 return true; 4883 } 4884 } 4885 return false; 4886 } 4887 4888 /** call synchronized on mRmtSbmxFullVolDeathHandlers */ hasRmtSbmxFullVolDeathHandlerFor(IBinder cb)4889 private boolean hasRmtSbmxFullVolDeathHandlerFor(IBinder cb) { 4890 Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator(); 4891 while (it.hasNext()) { 4892 if (it.next().isHandlerFor(cb)) { 4893 return true; 4894 } 4895 } 4896 return false; 4897 } 4898 4899 private int mRmtSbmxFullVolRefCount = 0; 4900 private final ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers = 4901 new ArrayList<RmtSbmxFullVolDeathHandler>(); 4902 forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb)4903 public void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb) { 4904 if (cb == null) { 4905 return; 4906 } 4907 if ((PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 4908 android.Manifest.permission.CAPTURE_AUDIO_OUTPUT))) { 4909 Log.w(TAG, "Trying to call forceRemoteSubmixFullVolume() without CAPTURE_AUDIO_OUTPUT"); 4910 return; 4911 } 4912 synchronized(mRmtSbmxFullVolDeathHandlers) { 4913 boolean applyRequired = false; 4914 if (startForcing) { 4915 if (!hasRmtSbmxFullVolDeathHandlerFor(cb)) { 4916 mRmtSbmxFullVolDeathHandlers.add(new RmtSbmxFullVolDeathHandler(cb)); 4917 if (mRmtSbmxFullVolRefCount == 0) { 4918 mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 4919 mFixedVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 4920 applyRequired = true; 4921 } 4922 mRmtSbmxFullVolRefCount++; 4923 } 4924 } else { 4925 if (discardRmtSbmxFullVolDeathHandlerFor(cb) && (mRmtSbmxFullVolRefCount > 0)) { 4926 mRmtSbmxFullVolRefCount--; 4927 if (mRmtSbmxFullVolRefCount == 0) { 4928 mFullVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 4929 mFixedVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 4930 applyRequired = true; 4931 } 4932 } 4933 } 4934 if (applyRequired) { 4935 // Assumes only STREAM_MUSIC going through DEVICE_OUT_REMOTE_SUBMIX 4936 checkAllFixedVolumeDevices(AudioSystem.STREAM_MUSIC); 4937 mStreamStates[AudioSystem.STREAM_MUSIC].applyAllVolumes(); 4938 } 4939 } 4940 } 4941 setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, int userId, int pid, String attributionTag)4942 private void setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, 4943 int userId, int pid, String attributionTag) { 4944 // If we are being called by the system check for user we are going to change 4945 // so we handle user restrictions correctly. 4946 if (uid == android.os.Process.SYSTEM_UID) { 4947 uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 4948 } 4949 // If OP_AUDIO_MASTER_VOLUME is set, disallow unmuting. 4950 if (!mute && !checkNoteAppOp( 4951 AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage, attributionTag)) { 4952 return; 4953 } 4954 if (userId != UserHandle.getCallingUserId() && 4955 mContext.checkPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4956 pid, uid) 4957 != PackageManager.PERMISSION_GRANTED) { 4958 return; 4959 } 4960 setMasterMuteInternalNoCallerCheck(mute, flags, userId); 4961 } 4962 setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId)4963 private void setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId) { 4964 if (DEBUG_VOL) { 4965 Log.d(TAG, String.format("Master mute %s, %d, user=%d", mute, flags, userId)); 4966 } 4967 if (!isPlatformAutomotive() && mUseFixedVolume) { 4968 // If using fixed volume, we don't mute. 4969 // TODO: remove the isPlatformAutomotive check here. 4970 // The isPlatformAutomotive check is added for safety but may not be necessary. 4971 return; 4972 } 4973 // For automotive, 4974 // - the car service is always running as system user 4975 // - foreground users are non-system users 4976 // Car service is in charge of dispatching the key event include global mute to Android. 4977 // Therefore, the getCurrentUser() is always different to the foreground user. 4978 if ((isPlatformAutomotive() && userId == UserHandle.USER_SYSTEM) 4979 || (getCurrentUserId() == userId)) { 4980 if (mute != AudioSystem.getMasterMute()) { 4981 AudioSystem.setMasterMute(mute); 4982 sendMasterMuteUpdate(mute, flags); 4983 } 4984 } 4985 } 4986 4987 /** get global mute state. */ isMasterMute()4988 public boolean isMasterMute() { 4989 return AudioSystem.getMasterMute(); 4990 } 4991 4992 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 4993 /** @see AudioManager#setMasterMute(boolean, int) */ setMasterMute(boolean mute, int flags, String callingPackage, int userId, String attributionTag)4994 public void setMasterMute(boolean mute, int flags, String callingPackage, int userId, 4995 String attributionTag) { 4996 super.setMasterMute_enforcePermission(); 4997 4998 setMasterMuteInternal(mute, flags, callingPackage, 4999 Binder.getCallingUid(), userId, Binder.getCallingPid(), attributionTag); 5000 } 5001 5002 /** @see AudioManager#getStreamVolume(int) */ getStreamVolume(int streamType)5003 public int getStreamVolume(int streamType) { 5004 ensureValidStreamType(streamType); 5005 int device = getDeviceForStream(streamType); 5006 synchronized (VolumeStreamState.class) { 5007 int index = mStreamStates[streamType].getIndex(device); 5008 5009 // by convention getStreamVolume() returns 0 when a stream is muted. 5010 if (mStreamStates[streamType].mIsMuted) { 5011 index = 0; 5012 } 5013 if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) && 5014 isFixedVolumeDevice(device)) { 5015 index = mStreamStates[streamType].getMaxIndex(); 5016 } 5017 return (index + 5) / 10; 5018 } 5019 } 5020 5021 @Override 5022 @android.annotation.EnforcePermission(anyOf = { 5023 android.Manifest.permission.MODIFY_AUDIO_ROUTING, 5024 android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED 5025 }) 5026 /** 5027 * @see AudioDeviceVolumeManager#getDeviceVolume(VolumeInfo, AudioDeviceAttributes) 5028 */ getDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)5029 public @NonNull VolumeInfo getDeviceVolume(@NonNull VolumeInfo vi, 5030 @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage) { 5031 super.getDeviceVolume_enforcePermission(); 5032 Objects.requireNonNull(vi); 5033 Objects.requireNonNull(ada); 5034 Objects.requireNonNull(callingPackage); 5035 if (!vi.hasStreamType()) { 5036 Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception()); 5037 return getDefaultVolumeInfo(); 5038 } 5039 5040 int streamType = vi.getStreamType(); 5041 final VolumeInfo.Builder vib = new VolumeInfo.Builder(vi); 5042 vib.setMinVolumeIndex((mStreamStates[streamType].mIndexMin + 5) / 10); 5043 vib.setMaxVolumeIndex((mStreamStates[streamType].mIndexMax + 5) / 10); 5044 synchronized (VolumeStreamState.class) { 5045 final int index; 5046 if (isFixedVolumeDevice(ada.getInternalType())) { 5047 index = (mStreamStates[streamType].mIndexMax + 5) / 10; 5048 } else { 5049 index = (mStreamStates[streamType].getIndex(ada.getInternalType()) + 5) / 10; 5050 } 5051 vib.setVolumeIndex(index); 5052 // only set as a mute command if stream muted 5053 if (mStreamStates[streamType].mIsMuted) { 5054 vib.setMuted(true); 5055 } 5056 return vib.build(); 5057 } 5058 } 5059 5060 /** @see AudioManager#getStreamMaxVolume(int) */ getStreamMaxVolume(int streamType)5061 public int getStreamMaxVolume(int streamType) { 5062 ensureValidStreamType(streamType); 5063 return (mStreamStates[streamType].getMaxIndex() + 5) / 10; 5064 } 5065 5066 /** @see AudioManager#getStreamMinVolumeInt(int) 5067 * Part of service interface, check permissions here */ getStreamMinVolume(int streamType)5068 public int getStreamMinVolume(int streamType) { 5069 ensureValidStreamType(streamType); 5070 final boolean isPrivileged = 5071 Binder.getCallingUid() == Process.SYSTEM_UID 5072 || callingHasAudioSettingsPermission() 5073 || (mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_ROUTING) 5074 == PackageManager.PERMISSION_GRANTED); 5075 return (mStreamStates[streamType].getMinIndex(isPrivileged) + 5) / 10; 5076 } 5077 5078 @android.annotation.EnforcePermission(android.Manifest.permission.QUERY_AUDIO_STATE) 5079 /** Get last audible volume before stream was muted. */ getLastAudibleStreamVolume(int streamType)5080 public int getLastAudibleStreamVolume(int streamType) { 5081 super.getLastAudibleStreamVolume_enforcePermission(); 5082 5083 ensureValidStreamType(streamType); 5084 int device = getDeviceForStream(streamType); 5085 return (mStreamStates[streamType].getIndex(device) + 5) / 10; 5086 } 5087 5088 /** 5089 * Default VolumeInfo returned by {@link VolumeInfo#getDefaultVolumeInfo()} 5090 * Lazily initialized in {@link #getDefaultVolumeInfo()} 5091 */ 5092 static VolumeInfo sDefaultVolumeInfo; 5093 5094 /** @see VolumeInfo#getDefaultVolumeInfo() */ getDefaultVolumeInfo()5095 public VolumeInfo getDefaultVolumeInfo() { 5096 if (sDefaultVolumeInfo == null) { 5097 sDefaultVolumeInfo = new VolumeInfo.Builder(AudioSystem.STREAM_MUSIC) 5098 .setMinVolumeIndex(getStreamMinVolume(AudioSystem.STREAM_MUSIC)) 5099 .setMaxVolumeIndex(getStreamMaxVolume(AudioSystem.STREAM_MUSIC)) 5100 .build(); 5101 } 5102 return sDefaultVolumeInfo; 5103 } 5104 5105 /** 5106 * list of callback dispatchers for stream aliasing updates 5107 */ 5108 final RemoteCallbackList<IStreamAliasingDispatcher> mStreamAliasingDispatchers = 5109 new RemoteCallbackList<IStreamAliasingDispatcher>(); 5110 5111 /** 5112 * Register/unregister a callback for stream aliasing updates 5113 * @param isad the callback dispatcher 5114 * @param register whether this for a registration or unregistration 5115 * @see AudioManager#addOnStreamAliasingChangedListener(Executor, Runnable) 5116 * @see AudioManager#removeOnStreamAliasingChangedListener(Runnable) 5117 */ 5118 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) registerStreamAliasingDispatcher(IStreamAliasingDispatcher isad, boolean register)5119 public void registerStreamAliasingDispatcher(IStreamAliasingDispatcher isad, boolean register) { 5120 super.registerStreamAliasingDispatcher_enforcePermission(); 5121 Objects.requireNonNull(isad); 5122 5123 if (register) { 5124 mStreamAliasingDispatchers.register(isad); 5125 } else { 5126 mStreamAliasingDispatchers.unregister(isad); 5127 } 5128 } 5129 dispatchStreamAliasingUpdate()5130 protected void dispatchStreamAliasingUpdate() { 5131 final int nbDispatchers = mStreamAliasingDispatchers.beginBroadcast(); 5132 for (int i = 0; i < nbDispatchers; i++) { 5133 try { 5134 mStreamAliasingDispatchers.getBroadcastItem(i).dispatchStreamAliasingChanged(); 5135 } catch (RemoteException e) { 5136 Log.e(TAG, "Error on stream alias update dispatch", e); 5137 } 5138 } 5139 mStreamAliasingDispatchers.finishBroadcast(); 5140 } 5141 5142 /** 5143 * @see AudioManager#getIndependentStreamTypes() 5144 * @return the list of non-aliased stream types 5145 */ 5146 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) getIndependentStreamTypes()5147 public ArrayList<Integer> getIndependentStreamTypes() { 5148 super.getIndependentStreamTypes_enforcePermission(); 5149 5150 if (mUseVolumeGroupAliases) { 5151 return new ArrayList<>(Arrays.stream(AudioManager.getPublicStreamTypes()) 5152 .boxed().toList()); 5153 } 5154 ArrayList<Integer> res = new ArrayList(1); 5155 for (int stream : mStreamVolumeAlias) { 5156 if (!res.contains(stream)) { 5157 res.add(stream); 5158 } 5159 } 5160 return res; 5161 } 5162 5163 /** 5164 * @see AudioManager#getStreamTypeAlias(int) 5165 * @param sourceStreamType the stream type for which the alias is queried 5166 * @return the stream alias 5167 */ 5168 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) 5169 public @AudioManager.PublicStreamTypes getStreamTypeAlias(@udioManager.PublicStreamTypes int sourceStreamType)5170 int getStreamTypeAlias(@AudioManager.PublicStreamTypes int sourceStreamType) { 5171 super.getStreamTypeAlias_enforcePermission(); 5172 // verify parameters 5173 ensureValidStreamType(sourceStreamType); 5174 5175 return mStreamVolumeAlias[sourceStreamType]; 5176 } 5177 5178 /** 5179 * @see AudioManager#isVolumeControlUsingVolumeGroups() 5180 * @return true when volume control is performed through volume groups, false if it uses 5181 * stream types. 5182 */ 5183 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isVolumeControlUsingVolumeGroups()5184 public boolean isVolumeControlUsingVolumeGroups() { 5185 super.isVolumeControlUsingVolumeGroups_enforcePermission(); 5186 5187 return mUseVolumeGroupAliases; 5188 } 5189 5190 /** @see AudioManager#getUiSoundsStreamType() 5191 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for 5192 * UI Sounds identification. 5193 * Fallback on Voice configuration to ensure correct behavior of DnD feature. 5194 */ getUiSoundsStreamType()5195 public int getUiSoundsStreamType() { 5196 return mUseVolumeGroupAliases ? STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM] 5197 : mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM]; 5198 } 5199 5200 /** 5201 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for 5202 * UI Sounds identification. 5203 * Fallback on Voice configuration to ensure correct behavior of DnD feature. 5204 */ isUiSoundsStreamType(int aliasStreamType)5205 private boolean isUiSoundsStreamType(int aliasStreamType) { 5206 return mUseVolumeGroupAliases 5207 ? STREAM_VOLUME_ALIAS_VOICE[aliasStreamType] 5208 == STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM] 5209 : aliasStreamType == mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM]; 5210 } 5211 5212 /** @see AudioManager#setMicrophoneMute(boolean) */ 5213 @Override setMicrophoneMute(boolean on, String callingPackage, int userId, String attributionTag)5214 public void setMicrophoneMute(boolean on, String callingPackage, int userId, 5215 String attributionTag) { 5216 // If we are being called by the system check for user we are going to change 5217 // so we handle user restrictions correctly. 5218 int uid = Binder.getCallingUid(); 5219 if (uid == android.os.Process.SYSTEM_UID) { 5220 uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 5221 } 5222 MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 5223 .setUid(uid) 5224 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage) 5225 .set(MediaMetrics.Property.EVENT, "setMicrophoneMute") 5226 .set(MediaMetrics.Property.REQUEST, on 5227 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE); 5228 5229 // If OP_MUTE_MICROPHONE is set, disallow unmuting. 5230 if (!on && !checkNoteAppOp( 5231 AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage, attributionTag)) { 5232 mmi.set(MediaMetrics.Property.EARLY_RETURN, "disallow unmuting").record(); 5233 return; 5234 } 5235 if (!checkAudioSettingsPermission("setMicrophoneMute()")) { 5236 mmi.set(MediaMetrics.Property.EARLY_RETURN, "!checkAudioSettingsPermission").record(); 5237 return; 5238 } 5239 if (userId != UserHandle.getCallingUserId() && 5240 mContext.checkCallingOrSelfPermission( 5241 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 5242 != PackageManager.PERMISSION_GRANTED) { 5243 mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission").record(); 5244 return; 5245 } 5246 mMicMuteFromApi = on; 5247 mmi.record(); // record now, the no caller check will set the mute state. 5248 setMicrophoneMuteNoCallerCheck(userId); 5249 } 5250 5251 /** @see AudioManager#setMicrophoneMuteFromSwitch(boolean) */ setMicrophoneMuteFromSwitch(boolean on)5252 public void setMicrophoneMuteFromSwitch(boolean on) { 5253 int userId = Binder.getCallingUid(); 5254 if (userId != android.os.Process.SYSTEM_UID) { 5255 Log.e(TAG, "setMicrophoneMuteFromSwitch() called from non system user!"); 5256 return; 5257 } 5258 mMicMuteFromSwitch = on; 5259 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 5260 .setUid(userId) 5261 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteFromSwitch") 5262 .set(MediaMetrics.Property.REQUEST, on 5263 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE) 5264 .record(); 5265 setMicrophoneMuteNoCallerCheck(userId); 5266 } 5267 setMicMuteFromSwitchInput()5268 private void setMicMuteFromSwitchInput() { 5269 InputManager im = mContext.getSystemService(InputManager.class); 5270 final int isMicMuted = im.isMicMuted(); 5271 if (isMicMuted != InputManager.SWITCH_STATE_UNKNOWN) { 5272 setMicrophoneMuteFromSwitch(im.isMicMuted() != InputManager.SWITCH_STATE_OFF); 5273 } 5274 } 5275 5276 /** 5277 * Returns the microphone mute state as seen from the native audio system 5278 * @return true if microphone is reported as muted by primary HAL 5279 */ isMicrophoneMuted()5280 public boolean isMicrophoneMuted() { 5281 return mMicMuteFromSystemCached 5282 && (!mMicMuteFromPrivacyToggle 5283 || mMicMuteFromApi || mMicMuteFromRestrictions || mMicMuteFromSwitch); 5284 } 5285 isMicrophoneSupposedToBeMuted()5286 private boolean isMicrophoneSupposedToBeMuted() { 5287 return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi 5288 || mMicMuteFromPrivacyToggle; 5289 } 5290 setMicrophoneMuteNoCallerCheck(int userId)5291 private void setMicrophoneMuteNoCallerCheck(int userId) { 5292 final boolean muted = isMicrophoneSupposedToBeMuted(); 5293 if (DEBUG_VOL) { 5294 Log.d(TAG, String.format("Mic mute %b, user=%d", muted, userId)); 5295 } 5296 // only mute for the current user 5297 if (getCurrentUserId() == userId || userId == android.os.Process.SYSTEM_UID) { 5298 final boolean currentMute = mAudioSystem.isMicrophoneMuted(); 5299 final long identity = Binder.clearCallingIdentity(); 5300 try { 5301 final int ret = mAudioSystem.muteMicrophone(muted); 5302 5303 // update cache with the real state independently from what was set 5304 mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted(); 5305 if (ret != AudioSystem.AUDIO_STATUS_OK) { 5306 Log.e(TAG, "Error changing mic mute state to " + muted + " current:" 5307 + mMicMuteFromSystemCached); 5308 } 5309 5310 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 5311 .setUid(userId) 5312 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteNoCallerCheck") 5313 .set(MediaMetrics.Property.MUTE, mMicMuteFromSystemCached 5314 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 5315 .set(MediaMetrics.Property.REQUEST, muted 5316 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE) 5317 .set(MediaMetrics.Property.STATUS, ret) 5318 .record(); 5319 5320 // send the intent even if there was a failure to change the actual mute state: 5321 // the AudioManager.setMicrophoneMute API doesn't have a return value to 5322 // indicate if the call failed to successfully change the mute state, and receiving 5323 // the intent may be the only time an application can resynchronize its mic mute 5324 // state with the actual system mic mute state 5325 if (muted != currentMute) { 5326 sendMsg(mAudioHandler, MSG_BROADCAST_MICROPHONE_MUTE, 5327 SENDMSG_NOOP, 0, 0, null, 0); 5328 } 5329 } finally { 5330 Binder.restoreCallingIdentity(identity); 5331 } 5332 } 5333 } 5334 5335 @Override getRingerModeExternal()5336 public int getRingerModeExternal() { 5337 synchronized(mSettingsLock) { 5338 return mRingerModeExternal; 5339 } 5340 } 5341 5342 @Override getRingerModeInternal()5343 public int getRingerModeInternal() { 5344 synchronized(mSettingsLock) { 5345 return mRingerMode; 5346 } 5347 } 5348 ensureValidRingerMode(int ringerMode)5349 private void ensureValidRingerMode(int ringerMode) { 5350 if (!isValidRingerMode(ringerMode)) { 5351 throw new IllegalArgumentException("Bad ringer mode " + ringerMode); 5352 } 5353 } 5354 5355 /** @see AudioManager#isValidRingerMode(int) */ isValidRingerMode(int ringerMode)5356 public boolean isValidRingerMode(int ringerMode) { 5357 return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX; 5358 } 5359 setRingerModeExternal(int ringerMode, String caller)5360 public void setRingerModeExternal(int ringerMode, String caller) { 5361 if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode) 5362 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)) { 5363 throw new SecurityException("Not allowed to change Do Not Disturb state"); 5364 } 5365 5366 setRingerMode(ringerMode, caller, true /*external*/); 5367 } 5368 setRingerModeInternal(int ringerMode, String caller)5369 public void setRingerModeInternal(int ringerMode, String caller) { 5370 enforceVolumeController("setRingerModeInternal"); 5371 setRingerMode(ringerMode, caller, false /*external*/); 5372 } 5373 silenceRingerModeInternal(String reason)5374 public void silenceRingerModeInternal(String reason) { 5375 VibrationEffect effect = null; 5376 int ringerMode = AudioManager.RINGER_MODE_SILENT; 5377 int toastText = 0; 5378 5379 int silenceRingerSetting = Settings.Secure.VOLUME_HUSH_OFF; 5380 if (mContext.getResources() 5381 .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) { 5382 silenceRingerSetting = mSettings.getSecureIntForUser(mContentResolver, 5383 Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF, 5384 UserHandle.USER_CURRENT); 5385 } 5386 5387 switch(silenceRingerSetting) { 5388 case VOLUME_HUSH_MUTE: 5389 effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK); 5390 ringerMode = AudioManager.RINGER_MODE_SILENT; 5391 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent; 5392 break; 5393 case VOLUME_HUSH_VIBRATE: 5394 effect = VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK); 5395 ringerMode = AudioManager.RINGER_MODE_VIBRATE; 5396 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate; 5397 break; 5398 } 5399 maybeVibrate(effect, reason); 5400 setRingerModeInternal(ringerMode, reason); 5401 Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT).show(); 5402 } 5403 maybeVibrate(VibrationEffect effect, String reason)5404 private boolean maybeVibrate(VibrationEffect effect, String reason) { 5405 if (!mHasVibrator) { 5406 return false; 5407 } 5408 if (effect == null) { 5409 return false; 5410 } 5411 mVibrator.vibrate(Binder.getCallingUid(), mContext.getOpPackageName(), effect, 5412 reason, TOUCH_VIBRATION_ATTRIBUTES); 5413 return true; 5414 } 5415 setRingerMode(int ringerMode, String caller, boolean external)5416 private void setRingerMode(int ringerMode, String caller, boolean external) { 5417 if (mUseFixedVolume || mIsSingleVolume || mUseVolumeGroupAliases) { 5418 return; 5419 } 5420 if (caller == null || caller.length() == 0) { 5421 throw new IllegalArgumentException("Bad caller: " + caller); 5422 } 5423 ensureValidRingerMode(ringerMode); 5424 if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { 5425 ringerMode = AudioManager.RINGER_MODE_SILENT; 5426 } 5427 final long identity = Binder.clearCallingIdentity(); 5428 try { 5429 synchronized (mSettingsLock) { 5430 final int ringerModeInternal = getRingerModeInternal(); 5431 final int ringerModeExternal = getRingerModeExternal(); 5432 if (external) { 5433 setRingerModeExt(ringerMode); 5434 if (mRingerModeDelegate != null) { 5435 ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal, 5436 ringerMode, caller, ringerModeInternal, mVolumePolicy); 5437 } 5438 if (ringerMode != ringerModeInternal) { 5439 setRingerModeInt(ringerMode, true /*persist*/); 5440 } 5441 } else /*internal*/ { 5442 if (ringerMode != ringerModeInternal) { 5443 setRingerModeInt(ringerMode, true /*persist*/); 5444 } 5445 if (mRingerModeDelegate != null) { 5446 ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal, 5447 ringerMode, caller, ringerModeExternal, mVolumePolicy); 5448 } 5449 setRingerModeExt(ringerMode); 5450 } 5451 } 5452 } finally { 5453 Binder.restoreCallingIdentity(identity); 5454 } 5455 } 5456 setRingerModeExt(int ringerMode)5457 private void setRingerModeExt(int ringerMode) { 5458 synchronized(mSettingsLock) { 5459 if (ringerMode == mRingerModeExternal) return; 5460 mRingerModeExternal = ringerMode; 5461 } 5462 // Send sticky broadcast 5463 broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode); 5464 } 5465 5466 @GuardedBy("mSettingsLock") muteRingerModeStreams()5467 private void muteRingerModeStreams() { 5468 // Mute stream if not previously muted by ringer mode and (ringer mode 5469 // is not RINGER_MODE_NORMAL OR stream is zen muted) and stream is affected by ringer mode. 5470 // Unmute stream if previously muted by ringer/zen mode and ringer mode 5471 // is RINGER_MODE_NORMAL or stream is not affected by ringer mode. 5472 int numStreamTypes = AudioSystem.getNumStreamTypes(); 5473 5474 if (mNm == null) { 5475 mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 5476 } 5477 5478 final int ringerMode = mRingerMode; // Read ringer mode as reading primitives is atomic 5479 final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE 5480 || ringerMode == AudioManager.RINGER_MODE_SILENT; 5481 final boolean shouldRingSco = ringerMode == AudioManager.RINGER_MODE_VIBRATE 5482 && mDeviceBroker.isBluetoothScoActive(); 5483 // Ask audio policy engine to force use Bluetooth SCO channel if needed 5484 final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid() 5485 + "/" + Binder.getCallingPid(); 5486 sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, AudioSystem.FOR_VIBRATE_RINGING, 5487 shouldRingSco ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE, eventSource, 0); 5488 5489 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 5490 final boolean isMuted = isStreamMutedByRingerOrZenMode(streamType); 5491 final boolean muteAllowedBySco = 5492 !(shouldRingSco && streamType == AudioSystem.STREAM_RING); 5493 final boolean shouldZenMute = shouldZenMuteStream(streamType); 5494 final boolean shouldMute = shouldZenMute || (ringerModeMute 5495 && isStreamAffectedByRingerMode(streamType) && muteAllowedBySco); 5496 if (isMuted == shouldMute) continue; 5497 if (!shouldMute) { 5498 // unmute 5499 // ring and notifications volume should never be 0 when not silenced 5500 if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING 5501 || mStreamVolumeAlias[streamType] == AudioSystem.STREAM_NOTIFICATION) { 5502 synchronized (VolumeStreamState.class) { 5503 final VolumeStreamState vss = mStreamStates[streamType]; 5504 for (int i = 0; i < vss.mIndexMap.size(); i++) { 5505 int device = vss.mIndexMap.keyAt(i); 5506 int value = vss.mIndexMap.valueAt(i); 5507 if (value == 0) { 5508 vss.setIndex(10, device, TAG, true /*hasModifyAudioSettings*/); 5509 } 5510 } 5511 // Persist volume for stream ring when it is changed here 5512 final int device = getDeviceForStream(streamType); 5513 sendMsg(mAudioHandler, 5514 MSG_PERSIST_VOLUME, 5515 SENDMSG_QUEUE, 5516 device, 5517 0, 5518 mStreamStates[streamType], 5519 PERSIST_DELAY); 5520 } 5521 } 5522 sRingerAndZenModeMutedStreams &= ~(1 << streamType); 5523 sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent( 5524 sRingerAndZenModeMutedStreams, "muteRingerModeStreams")); 5525 mStreamStates[streamType].mute(false, "muteRingerModeStreams"); 5526 } else { 5527 // mute 5528 sRingerAndZenModeMutedStreams |= (1 << streamType); 5529 sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent( 5530 sRingerAndZenModeMutedStreams, "muteRingerModeStreams")); 5531 mStreamStates[streamType].mute(true, "muteRingerModeStreams"); 5532 } 5533 } 5534 } 5535 isAlarm(int streamType)5536 private boolean isAlarm(int streamType) { 5537 return streamType == AudioSystem.STREAM_ALARM; 5538 } 5539 isNotificationOrRinger(int streamType)5540 private boolean isNotificationOrRinger(int streamType) { 5541 return streamType == AudioSystem.STREAM_NOTIFICATION 5542 || streamType == AudioSystem.STREAM_RING; 5543 } 5544 isMedia(int streamType)5545 private boolean isMedia(int streamType) { 5546 return streamType == AudioSystem.STREAM_MUSIC; 5547 } 5548 5549 isSystem(int streamType)5550 private boolean isSystem(int streamType) { 5551 return streamType == AudioSystem.STREAM_SYSTEM; 5552 } 5553 setRingerModeInt(int ringerMode, boolean persist)5554 private void setRingerModeInt(int ringerMode, boolean persist) { 5555 final boolean change; 5556 synchronized(mSettingsLock) { 5557 change = mRingerMode != ringerMode; 5558 mRingerMode = ringerMode; 5559 muteRingerModeStreams(); 5560 } 5561 5562 // Post a persist ringer mode msg 5563 if (persist) { 5564 sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE, 5565 SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY); 5566 } 5567 if (change) { 5568 // Send sticky broadcast 5569 broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, ringerMode); 5570 } 5571 } 5572 postUpdateRingerModeServiceInt()5573 /*package*/ void postUpdateRingerModeServiceInt() { 5574 sendMsg(mAudioHandler, MSG_UPDATE_RINGER_MODE, SENDMSG_QUEUE, 0, 0, null, 0); 5575 } 5576 onUpdateRingerModeServiceInt()5577 private void onUpdateRingerModeServiceInt() { 5578 setRingerModeInt(getRingerModeInternal(), false); 5579 } 5580 5581 /** @see AudioManager#shouldVibrate(int) */ shouldVibrate(int vibrateType)5582 public boolean shouldVibrate(int vibrateType) { 5583 if (!mHasVibrator) return false; 5584 5585 switch (getVibrateSetting(vibrateType)) { 5586 5587 case AudioManager.VIBRATE_SETTING_ON: 5588 return getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT; 5589 5590 case AudioManager.VIBRATE_SETTING_ONLY_SILENT: 5591 return getRingerModeExternal() == AudioManager.RINGER_MODE_VIBRATE; 5592 5593 case AudioManager.VIBRATE_SETTING_OFF: 5594 // return false, even for incoming calls 5595 return false; 5596 5597 default: 5598 return false; 5599 } 5600 } 5601 5602 /** @see AudioManager#getVibrateSetting(int) */ getVibrateSetting(int vibrateType)5603 public int getVibrateSetting(int vibrateType) { 5604 if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF; 5605 return (mVibrateSetting >> (vibrateType * 2)) & 3; 5606 } 5607 5608 /** @see AudioManager#setVibrateSetting(int, int) */ setVibrateSetting(int vibrateType, int vibrateSetting)5609 public void setVibrateSetting(int vibrateType, int vibrateSetting) { 5610 5611 if (!mHasVibrator) return; 5612 5613 mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, vibrateType, 5614 vibrateSetting); 5615 5616 // Broadcast change 5617 broadcastVibrateSetting(vibrateType); 5618 5619 } 5620 5621 private class SetModeDeathHandler implements IBinder.DeathRecipient { 5622 private final IBinder mCb; // To be notified of client's death 5623 private final int mPid; 5624 private final int mUid; 5625 private final boolean mIsPrivileged; 5626 private final String mPackage; 5627 private int mMode; 5628 private long mUpdateTime; 5629 private boolean mPlaybackActive = false; 5630 private boolean mRecordingActive = false; 5631 SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, String caller, int mode)5632 SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, 5633 String caller, int mode) { 5634 mMode = mode; 5635 mCb = cb; 5636 mPid = pid; 5637 mUid = uid; 5638 mPackage = caller; 5639 mIsPrivileged = isPrivileged; 5640 mUpdateTime = java.lang.System.currentTimeMillis(); 5641 } 5642 binderDied()5643 public void binderDied() { 5644 synchronized (mDeviceBroker.mSetModeLock) { 5645 Log.w(TAG, "SetModeDeathHandler client died"); 5646 int index = mSetModeDeathHandlers.indexOf(this); 5647 if (index < 0) { 5648 Log.w(TAG, "unregistered SetModeDeathHandler client died"); 5649 } else { 5650 SetModeDeathHandler h = mSetModeDeathHandlers.get(index); 5651 mSetModeDeathHandlers.remove(index); 5652 sendMsg(mAudioHandler, 5653 MSG_UPDATE_AUDIO_MODE, 5654 SENDMSG_QUEUE, 5655 AudioSystem.MODE_CURRENT, 5656 android.os.Process.myPid(), 5657 mContext.getPackageName(), 5658 0); 5659 } 5660 } 5661 } 5662 getPid()5663 public int getPid() { 5664 return mPid; 5665 } 5666 setMode(int mode)5667 public void setMode(int mode) { 5668 mMode = mode; 5669 mUpdateTime = java.lang.System.currentTimeMillis(); 5670 } 5671 getMode()5672 public int getMode() { 5673 return mMode; 5674 } 5675 getBinder()5676 public IBinder getBinder() { 5677 return mCb; 5678 } 5679 getUid()5680 public int getUid() { 5681 return mUid; 5682 } 5683 getPackage()5684 public String getPackage() { 5685 return mPackage; 5686 } 5687 isPrivileged()5688 public boolean isPrivileged() { 5689 return mIsPrivileged; 5690 } 5691 getUpdateTime()5692 public long getUpdateTime() { 5693 return mUpdateTime; 5694 } 5695 setPlaybackActive(boolean active)5696 public void setPlaybackActive(boolean active) { 5697 mPlaybackActive = active; 5698 } 5699 setRecordingActive(boolean active)5700 public void setRecordingActive(boolean active) { 5701 mRecordingActive = active; 5702 } 5703 5704 /** 5705 * An app is considered active if: 5706 * - It is privileged (has MODIFY_PHONE_STATE permission) 5707 * or 5708 * - It requests mode MODE_IN_COMMUNICATION, and it is either playing 5709 * or recording for VOICE_COMMUNICATION. 5710 * or 5711 * - It requests a mode different from MODE_IN_COMMUNICATION or MODE_NORMAL 5712 * Note: only privileged apps can request MODE_IN_CALL, MODE_CALL_REDIRECT 5713 * or MODE_COMMUNICATION_REDIRECT. 5714 */ isActive()5715 public boolean isActive() { 5716 return mIsPrivileged 5717 || ((mMode == AudioSystem.MODE_IN_COMMUNICATION) 5718 && (mRecordingActive || mPlaybackActive)) 5719 || mMode == AudioSystem.MODE_RINGTONE 5720 || mMode == AudioSystem.MODE_CALL_SCREENING; 5721 } 5722 dump(PrintWriter pw, int index)5723 public void dump(PrintWriter pw, int index) { 5724 SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss:SSS"); 5725 5726 if (index >= 0) { 5727 pw.println(" Requester # " + (index + 1) + ":"); 5728 } 5729 pw.println(" - Mode: " + AudioSystem.modeToString(mMode)); 5730 pw.println(" - Binder: " + mCb); 5731 pw.println(" - Pid: " + mPid); 5732 pw.println(" - Uid: " + mUid); 5733 pw.println(" - Package: " + mPackage); 5734 pw.println(" - Privileged: " + mIsPrivileged); 5735 pw.println(" - Active: " + isActive()); 5736 pw.println(" Playback active: " + mPlaybackActive); 5737 pw.println(" Recording active: " + mRecordingActive); 5738 pw.println(" - update time: " + format.format(new Date(mUpdateTime))); 5739 } 5740 } 5741 5742 @GuardedBy("mDeviceBroker.mSetModeLock") getAudioModeOwnerHandler()5743 private SetModeDeathHandler getAudioModeOwnerHandler() { 5744 // The Audio mode owner is: 5745 // 1) the most recent privileged app in the stack 5746 // 2) the most recent active app in the tack 5747 SetModeDeathHandler modeOwner = null; 5748 SetModeDeathHandler privilegedModeOwner = null; 5749 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 5750 if (h.isActive()) { 5751 // privileged apps are always active 5752 if (h.isPrivileged()) { 5753 if (privilegedModeOwner == null 5754 || h.getUpdateTime() > privilegedModeOwner.getUpdateTime()) { 5755 privilegedModeOwner = h; 5756 } 5757 } else { 5758 if (modeOwner == null 5759 || h.getUpdateTime() > modeOwner.getUpdateTime()) { 5760 modeOwner = h; 5761 } 5762 } 5763 } 5764 } 5765 return privilegedModeOwner != null ? privilegedModeOwner : modeOwner; 5766 } 5767 5768 /** 5769 * Return information on the current audio mode owner 5770 * @return 0 if nobody owns the mode 5771 */ 5772 @GuardedBy("mDeviceBroker.mSetModeLock") getAudioModeOwner()5773 /*package*/ AudioDeviceBroker.AudioModeInfo getAudioModeOwner() { 5774 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 5775 if (hdlr != null) { 5776 return new AudioDeviceBroker.AudioModeInfo( 5777 hdlr.getMode(), hdlr.getPid(), hdlr.getUid()); 5778 } 5779 return new AudioDeviceBroker.AudioModeInfo(AudioSystem.MODE_NORMAL, 0 , 0); 5780 } 5781 5782 /** 5783 * Return the uid of the current audio mode owner 5784 * @return 0 if nobody owns the mode 5785 */ 5786 @GuardedBy("mDeviceBroker.mSetModeLock") getModeOwnerUid()5787 /*package*/ int getModeOwnerUid() { 5788 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 5789 if (hdlr != null) { 5790 return hdlr.getUid(); 5791 } 5792 return 0; 5793 } 5794 5795 /** @see AudioManager#setMode(int) */ setMode(int mode, IBinder cb, String callingPackage)5796 public void setMode(int mode, IBinder cb, String callingPackage) { 5797 int pid = Binder.getCallingPid(); 5798 int uid = Binder.getCallingUid(); 5799 if (DEBUG_MODE) { 5800 Log.v(TAG, "setMode(mode=" + mode + ", pid=" + pid 5801 + ", uid=" + uid + ", caller=" + callingPackage + ")"); 5802 } 5803 if (!checkAudioSettingsPermission("setMode()")) { 5804 return; 5805 } 5806 if (cb == null) { 5807 Log.e(TAG, "setMode() called with null binder"); 5808 return; 5809 } 5810 if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) { 5811 Log.w(TAG, "setMode() invalid mode: " + mode); 5812 return; 5813 } 5814 5815 if (mode == AudioSystem.MODE_CURRENT) { 5816 mode = getMode(); 5817 } 5818 5819 if (mode == AudioSystem.MODE_CALL_SCREENING && !mIsCallScreeningModeSupported) { 5820 Log.w(TAG, "setMode(MODE_CALL_SCREENING) not permitted " 5821 + "when call screening is not supported"); 5822 return; 5823 } 5824 5825 final boolean hasModifyPhoneStatePermission = mContext.checkCallingOrSelfPermission( 5826 android.Manifest.permission.MODIFY_PHONE_STATE) 5827 == PackageManager.PERMISSION_GRANTED; 5828 if ((mode == AudioSystem.MODE_IN_CALL 5829 || mode == AudioSystem.MODE_CALL_REDIRECT 5830 || mode == AudioSystem.MODE_COMMUNICATION_REDIRECT) 5831 && !hasModifyPhoneStatePermission) { 5832 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setMode(" 5833 + AudioSystem.modeToString(mode) + ") from pid=" + pid 5834 + ", uid=" + Binder.getCallingUid()); 5835 return; 5836 } 5837 5838 SetModeDeathHandler currentModeHandler = null; 5839 synchronized (mDeviceBroker.mSetModeLock) { 5840 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 5841 if (h.getPid() == pid) { 5842 currentModeHandler = h; 5843 break; 5844 } 5845 } 5846 5847 if (mode == AudioSystem.MODE_NORMAL) { 5848 if (currentModeHandler != null) { 5849 if (!currentModeHandler.isPrivileged() 5850 && currentModeHandler.getMode() == AudioSystem.MODE_IN_COMMUNICATION) { 5851 mAudioHandler.removeEqualMessages( 5852 MSG_CHECK_MODE_FOR_UID, currentModeHandler); 5853 } 5854 mSetModeDeathHandlers.remove(currentModeHandler); 5855 if (DEBUG_MODE) { 5856 Log.v(TAG, "setMode(" + mode + ") removing hldr for pid: " + pid); 5857 } 5858 try { 5859 currentModeHandler.getBinder().unlinkToDeath(currentModeHandler, 0); 5860 } catch (NoSuchElementException e) { 5861 Log.w(TAG, "setMode link does not exist ..."); 5862 } 5863 } 5864 } else { 5865 if (currentModeHandler != null) { 5866 currentModeHandler.setMode(mode); 5867 if (DEBUG_MODE) { 5868 Log.v(TAG, "setMode(" + mode + ") updating hldr for pid: " + pid); 5869 } 5870 } else { 5871 currentModeHandler = new SetModeDeathHandler(cb, pid, uid, 5872 hasModifyPhoneStatePermission, callingPackage, mode); 5873 // Register for client death notification 5874 try { 5875 cb.linkToDeath(currentModeHandler, 0); 5876 } catch (RemoteException e) { 5877 // Client has died! 5878 Log.w(TAG, "setMode() could not link to " + cb + " binder death"); 5879 return; 5880 } 5881 mSetModeDeathHandlers.add(currentModeHandler); 5882 if (DEBUG_MODE) { 5883 Log.v(TAG, "setMode(" + mode + ") adding handler for pid=" + pid); 5884 } 5885 } 5886 if (mode == AudioSystem.MODE_IN_COMMUNICATION) { 5887 // Force active state when entering/updating the stack to avoid glitches when 5888 // an app starts playing/recording after settng the audio mode, 5889 // and send a reminder to check activity after a grace period. 5890 if (!currentModeHandler.isPrivileged()) { 5891 currentModeHandler.setPlaybackActive(true); 5892 currentModeHandler.setRecordingActive(true); 5893 sendMsg(mAudioHandler, 5894 MSG_CHECK_MODE_FOR_UID, 5895 SENDMSG_QUEUE, 5896 0, 5897 0, 5898 currentModeHandler, 5899 CHECK_MODE_FOR_UID_PERIOD_MS); 5900 } 5901 } 5902 } 5903 5904 sendMsg(mAudioHandler, 5905 MSG_UPDATE_AUDIO_MODE, 5906 SENDMSG_REPLACE, 5907 mode, 5908 pid, 5909 callingPackage, 5910 0); 5911 } 5912 } 5913 5914 @GuardedBy("mDeviceBroker.mSetModeLock") onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, boolean force)5915 void onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, 5916 boolean force) { 5917 if (requestedMode == AudioSystem.MODE_CURRENT) { 5918 requestedMode = getMode(); 5919 } 5920 int mode = AudioSystem.MODE_NORMAL; 5921 int uid = 0; 5922 int pid = 0; 5923 SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler(); 5924 if (currentModeHandler != null) { 5925 mode = currentModeHandler.getMode(); 5926 uid = currentModeHandler.getUid(); 5927 pid = currentModeHandler.getPid(); 5928 } 5929 if (DEBUG_MODE) { 5930 Log.v(TAG, "onUpdateAudioMode() new mode: " + mode + ", current mode: " 5931 + mMode.get() + " requested mode: " + requestedMode); 5932 } 5933 if (mode != mMode.get() || force) { 5934 int status = AudioSystem.SUCCESS; 5935 final long identity = Binder.clearCallingIdentity(); 5936 try { 5937 status = mAudioSystem.setPhoneState(mode, uid); 5938 } finally { 5939 Binder.restoreCallingIdentity(identity); 5940 } 5941 if (status == AudioSystem.AUDIO_STATUS_OK) { 5942 if (DEBUG_MODE) { 5943 Log.v(TAG, "onUpdateAudioMode: mode successfully set to " + mode); 5944 } 5945 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_MODE, SENDMSG_REPLACE, mode, 0, 5946 /*obj*/ null, /*delay*/ 0); 5947 int previousMode = mMode.getAndSet(mode); 5948 // Note: newModeOwnerPid is always 0 when actualMode is MODE_NORMAL 5949 mModeLogger.enqueue(new PhoneStateEvent(requesterPackage, requesterPid, 5950 requestedMode, pid, mode)); 5951 5952 final int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE); 5953 final int device = getDeviceForStream(streamType); 5954 final int streamAlias = mStreamVolumeAlias[streamType]; 5955 5956 if (DEBUG_MODE) { 5957 Log.v(TAG, "onUpdateAudioMode: streamType=" + streamType 5958 + ", streamAlias=" + streamAlias); 5959 } 5960 5961 final int index = mStreamStates[streamAlias].getIndex(device); 5962 final int maxIndex = mStreamStates[streamAlias].getMaxIndex(); 5963 setStreamVolumeInt(streamAlias, index, device, true, 5964 requesterPackage, true /*hasModifyAudioSettings*/); 5965 5966 updateStreamVolumeAlias(true /*updateVolumes*/, requesterPackage); 5967 5968 // change of mode may require volume to be re-applied on some devices 5969 updateAbsVolumeMultiModeDevices(previousMode, mode); 5970 5971 setLeAudioVolumeOnModeUpdate(mode, device, streamAlias, index, maxIndex); 5972 5973 // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO 5974 // connections not started by the application changing the mode when pid changes 5975 mDeviceBroker.postSetModeOwner(mode, pid, uid); 5976 } else { 5977 Log.w(TAG, "onUpdateAudioMode: failed to set audio mode to: " + mode); 5978 } 5979 } 5980 } 5981 5982 /** @see AudioManager#getMode() */ getMode()5983 public int getMode() { 5984 synchronized (mDeviceBroker.mSetModeLock) { 5985 SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler(); 5986 if (currentModeHandler != null) { 5987 return currentModeHandler.getMode(); 5988 } 5989 return AudioSystem.MODE_NORMAL; 5990 } 5991 } 5992 5993 /** cached value read from audiopolicy manager after initialization. */ 5994 private boolean mIsCallScreeningModeSupported = false; 5995 5996 /** @see AudioManager#isCallScreeningModeSupported() */ isCallScreeningModeSupported()5997 public boolean isCallScreeningModeSupported() { 5998 return mIsCallScreeningModeSupported; 5999 } 6000 dispatchMode(int mode)6001 protected void dispatchMode(int mode) { 6002 final int nbDispatchers = mModeDispatchers.beginBroadcast(); 6003 for (int i = 0; i < nbDispatchers; i++) { 6004 try { 6005 mModeDispatchers.getBroadcastItem(i).dispatchAudioModeChanged(mode); 6006 } catch (RemoteException e) { 6007 } 6008 } 6009 mModeDispatchers.finishBroadcast(); 6010 } 6011 6012 final RemoteCallbackList<IAudioModeDispatcher> mModeDispatchers = 6013 new RemoteCallbackList<IAudioModeDispatcher>(); 6014 6015 /** 6016 * @see {@link AudioManager#addOnModeChangedListener(Executor, AudioManager.OnModeChangedListener)} 6017 * @param dispatcher 6018 */ registerModeDispatcher( @onNull IAudioModeDispatcher dispatcher)6019 public void registerModeDispatcher( 6020 @NonNull IAudioModeDispatcher dispatcher) { 6021 mModeDispatchers.register(dispatcher); 6022 } 6023 6024 /** 6025 * @see {@link AudioManager#removeOnModeChangedListener(AudioManager.OnModeChangedListener)} 6026 * @param dispatcher 6027 */ unregisterModeDispatcher( @onNull IAudioModeDispatcher dispatcher)6028 public void unregisterModeDispatcher( 6029 @NonNull IAudioModeDispatcher dispatcher) { 6030 mModeDispatchers.unregister(dispatcher); 6031 } 6032 6033 @android.annotation.EnforcePermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION) 6034 /** @see AudioManager#isPstnCallAudioInterceptable() */ isPstnCallAudioInterceptable()6035 public boolean isPstnCallAudioInterceptable() { 6036 6037 super.isPstnCallAudioInterceptable_enforcePermission(); 6038 6039 boolean uplinkDeviceFound = false; 6040 boolean downlinkDeviceFound = false; 6041 AudioDeviceInfo[] devices = AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_ALL); 6042 for (AudioDeviceInfo device : devices) { 6043 if (device.getInternalType() == AudioSystem.DEVICE_OUT_TELEPHONY_TX) { 6044 uplinkDeviceFound = true; 6045 } else if (device.getInternalType() == AudioSystem.DEVICE_IN_TELEPHONY_RX) { 6046 downlinkDeviceFound = true; 6047 } 6048 if (uplinkDeviceFound && downlinkDeviceFound) { 6049 return true; 6050 } 6051 } 6052 return false; 6053 } 6054 6055 /** @see AudioManager#setRttEnabled() */ 6056 @Override setRttEnabled(boolean rttEnabled)6057 public void setRttEnabled(boolean rttEnabled) { 6058 if (mContext.checkCallingOrSelfPermission( 6059 android.Manifest.permission.MODIFY_PHONE_STATE) 6060 != PackageManager.PERMISSION_GRANTED) { 6061 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setRttEnabled from pid=" 6062 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 6063 return; 6064 } 6065 synchronized (mSettingsLock) { 6066 mRttEnabled = rttEnabled; 6067 final long identity = Binder.clearCallingIdentity(); 6068 try { 6069 AudioSystem.setRttEnabled(rttEnabled); 6070 } finally { 6071 Binder.restoreCallingIdentity(identity); 6072 } 6073 } 6074 } 6075 6076 /** @see AudioManager#adjustSuggestedStreamVolumeForUid(int, int, int, String, int, int, int) */ 6077 @Override adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6078 public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, 6079 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 6080 int targetSdkVersion) { 6081 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 6082 throw new SecurityException("Should only be called from system process"); 6083 } 6084 6085 // direction and stream type swap here because the public 6086 // adjustSuggested has a different order than the other methods. 6087 adjustSuggestedStreamVolume(direction, streamType, flags, packageName, packageName, 6088 uid, pid, hasAudioSettingsPermission(uid, pid), 6089 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 6090 } 6091 6092 /** @see AudioManager#adjustStreamVolumeForUid(int, int, int, String, int, int, int) */ 6093 @Override adjustStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6094 public void adjustStreamVolumeForUid(int streamType, int direction, int flags, 6095 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 6096 int targetSdkVersion) { 6097 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 6098 throw new SecurityException("Should only be called from system process"); 6099 } 6100 6101 if (direction != AudioManager.ADJUST_SAME) { 6102 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType, 6103 direction/*val1*/, flags/*val2*/, 6104 new StringBuilder(packageName).append(" uid:").append(uid) 6105 .toString())); 6106 } 6107 6108 adjustStreamVolume(streamType, direction, flags, packageName, packageName, uid, pid, 6109 null, hasAudioSettingsPermission(uid, pid), 6110 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 6111 } 6112 6113 /** @see AudioManager#setStreamVolumeForUid(int, int, int, String, int, int, int) */ 6114 @Override setStreamVolumeForUid(int streamType, int index, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6115 public void setStreamVolumeForUid(int streamType, int index, int flags, 6116 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 6117 int targetSdkVersion) { 6118 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 6119 throw new SecurityException("Should only be called from system process"); 6120 } 6121 6122 setStreamVolume(streamType, index, flags, /*device*/ null, 6123 packageName, packageName, null, uid, 6124 hasAudioSettingsPermission(uid, pid)); 6125 } 6126 6127 //========================================================================================== 6128 // Sound Effects 6129 //========================================================================================== 6130 private static final class LoadSoundEffectReply 6131 implements SoundEffectsHelper.OnEffectsLoadCompleteHandler { 6132 private static final int SOUND_EFFECTS_LOADING = 1; 6133 private static final int SOUND_EFFECTS_LOADED = 0; 6134 private static final int SOUND_EFFECTS_ERROR = -1; 6135 private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000; 6136 6137 private int mStatus = SOUND_EFFECTS_LOADING; 6138 6139 @Override run(boolean success)6140 public synchronized void run(boolean success) { 6141 mStatus = success ? SOUND_EFFECTS_LOADED : SOUND_EFFECTS_ERROR; 6142 notify(); 6143 } 6144 waitForLoaded(int attempts)6145 public synchronized boolean waitForLoaded(int attempts) { 6146 while ((mStatus == SOUND_EFFECTS_LOADING) && (attempts-- > 0)) { 6147 try { 6148 wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS); 6149 } catch (InterruptedException e) { 6150 Log.w(TAG, "Interrupted while waiting sound pool loaded."); 6151 } 6152 } 6153 return mStatus == SOUND_EFFECTS_LOADED; 6154 } 6155 } 6156 6157 /** @see AudioManager#playSoundEffect(int, int) */ playSoundEffect(int effectType, int userId)6158 public void playSoundEffect(int effectType, int userId) { 6159 if (querySoundEffectsEnabled(userId)) { 6160 playSoundEffectVolume(effectType, -1.0f); 6161 } 6162 } 6163 6164 /** 6165 * Settings has an in memory cache, so this is fast. 6166 */ querySoundEffectsEnabled(int user)6167 private boolean querySoundEffectsEnabled(int user) { 6168 return mSettings.getSystemIntForUser(getContentResolver(), 6169 Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0; 6170 } 6171 6172 /** @see AudioManager#playSoundEffect(int, float) */ playSoundEffectVolume(int effectType, float volume)6173 public void playSoundEffectVolume(int effectType, float volume) { 6174 // do not try to play the sound effect if the system stream is muted 6175 if (isStreamMute(STREAM_SYSTEM)) { 6176 return; 6177 } 6178 6179 if (effectType >= AudioManager.NUM_SOUND_EFFECTS || effectType < 0) { 6180 Log.w(TAG, "AudioService effectType value " + effectType + " out of range"); 6181 return; 6182 } 6183 6184 sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE, 6185 effectType, (int) (volume * 1000), null, 0); 6186 } 6187 6188 /** 6189 * Loads samples into the soundpool. 6190 * This method must be called at first when sound effects are enabled 6191 */ loadSoundEffects()6192 public boolean loadSoundEffects() { 6193 LoadSoundEffectReply reply = new LoadSoundEffectReply(); 6194 sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0); 6195 return reply.waitForLoaded(3 /*attempts*/); 6196 } 6197 6198 /** 6199 * Schedule loading samples into the soundpool. 6200 * This method can be overridden to schedule loading at a later time. 6201 */ scheduleLoadSoundEffects()6202 protected void scheduleLoadSoundEffects() { 6203 sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0); 6204 } 6205 6206 /** 6207 * Unloads samples from the sound pool. 6208 * This method can be called to free some memory when 6209 * sound effects are disabled. 6210 */ unloadSoundEffects()6211 public void unloadSoundEffects() { 6212 sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0); 6213 } 6214 6215 /** @see AudioManager#reloadAudioSettings() */ reloadAudioSettings()6216 public void reloadAudioSettings() { 6217 readAudioSettings(false /*userSwitch*/); 6218 } 6219 readAudioSettings(boolean userSwitch)6220 private void readAudioSettings(boolean userSwitch) { 6221 // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings 6222 readPersistedSettings(); 6223 readUserRestrictions(); 6224 6225 // restore volume settings 6226 int numStreamTypes = AudioSystem.getNumStreamTypes(); 6227 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 6228 VolumeStreamState streamState = mStreamStates[streamType]; 6229 6230 if (userSwitch && mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) { 6231 continue; 6232 } 6233 6234 streamState.readSettings(); 6235 synchronized (VolumeStreamState.class) { 6236 // unmute stream that was muted but is not affect by mute anymore 6237 if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) && 6238 !isStreamMutedByRingerOrZenMode(streamType)) || mUseFixedVolume)) { 6239 streamState.mIsMuted = false; 6240 } 6241 } 6242 } 6243 6244 readVolumeGroupsSettings(userSwitch); 6245 6246 // apply new ringer mode before checking volume for alias streams so that streams 6247 // muted by ringer mode have the correct volume 6248 setRingerModeInt(getRingerModeInternal(), false); 6249 6250 checkAllFixedVolumeDevices(); 6251 checkAllAliasStreamVolumes(); 6252 checkMuteAffectedStreams(); 6253 6254 mSoundDoseHelper.restoreMusicActiveMs(); 6255 mSoundDoseHelper.enforceSafeMediaVolumeIfActive(TAG); 6256 6257 if (DEBUG_VOL) { 6258 Log.d(TAG, "Restoring device volume behavior"); 6259 } 6260 restoreDeviceVolumeBehavior(); 6261 } 6262 6263 /** @see AudioManager#getAvailableCommunicationDevices(int) */ getAvailableCommunicationDeviceIds()6264 public int[] getAvailableCommunicationDeviceIds() { 6265 List<AudioDeviceInfo> commDevices = AudioDeviceBroker.getAvailableCommunicationDevices(); 6266 return commDevices.stream().mapToInt(AudioDeviceInfo::getId).toArray(); 6267 } 6268 6269 /** 6270 * @see AudioManager#setCommunicationDevice(int) 6271 * @see AudioManager#clearCommunicationDevice() 6272 */ setCommunicationDevice(IBinder cb, int portId)6273 public boolean setCommunicationDevice(IBinder cb, int portId) { 6274 final int uid = Binder.getCallingUid(); 6275 final int pid = Binder.getCallingPid(); 6276 6277 AudioDeviceInfo device = null; 6278 if (portId != 0) { 6279 device = AudioManager.getDeviceForPortId(portId, AudioManager.GET_DEVICES_OUTPUTS); 6280 if (device == null) { 6281 Log.w(TAG, "setCommunicationDevice: invalid portID " + portId); 6282 return false; 6283 } 6284 if (!AudioDeviceBroker.isValidCommunicationDevice(device)) { 6285 if (!device.isSink()) { 6286 throw new IllegalArgumentException("device must have sink role"); 6287 } else { 6288 throw new IllegalArgumentException("invalid device type: " + device.getType()); 6289 } 6290 } 6291 } 6292 final String eventSource = new StringBuilder() 6293 .append(device == null ? "clearCommunicationDevice(" : "setCommunicationDevice(") 6294 .append(") from u/pid:").append(uid).append("/") 6295 .append(pid).toString(); 6296 6297 int deviceType = AudioSystem.DEVICE_OUT_DEFAULT; 6298 String deviceAddress = null; 6299 if (device != null) { 6300 deviceType = device.getPort().type(); 6301 deviceAddress = device.getAddress(); 6302 } else { 6303 AudioDeviceInfo curDevice = mDeviceBroker.getCommunicationDevice(); 6304 if (curDevice != null) { 6305 deviceType = curDevice.getPort().type(); 6306 deviceAddress = curDevice.getAddress(); 6307 } 6308 } 6309 // do not log metrics if clearing communication device while no communication device 6310 // was selected 6311 if (deviceType != AudioSystem.DEVICE_OUT_DEFAULT) { 6312 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 6313 + MediaMetrics.SEPARATOR + "setCommunicationDevice") 6314 .set(MediaMetrics.Property.DEVICE, 6315 AudioSystem.getDeviceName(deviceType)) 6316 .set(MediaMetrics.Property.ADDRESS, deviceAddress) 6317 .set(MediaMetrics.Property.STATE, device != null 6318 ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED) 6319 .record(); 6320 } 6321 final boolean isPrivileged = mContext.checkCallingOrSelfPermission( 6322 android.Manifest.permission.MODIFY_PHONE_STATE) 6323 == PackageManager.PERMISSION_GRANTED; 6324 final long ident = Binder.clearCallingIdentity(); 6325 try { 6326 return mDeviceBroker.setCommunicationDevice(cb, uid, device, isPrivileged, eventSource); 6327 } finally { 6328 Binder.restoreCallingIdentity(ident); 6329 } 6330 } 6331 6332 /** @see AudioManager#getCommunicationDevice() */ getCommunicationDevice()6333 public int getCommunicationDevice() { 6334 int deviceId = 0; 6335 final long ident = Binder.clearCallingIdentity(); 6336 try { 6337 AudioDeviceInfo device = mDeviceBroker.getCommunicationDevice(); 6338 deviceId = device != null ? device.getId() : 0; 6339 } finally { 6340 Binder.restoreCallingIdentity(ident); 6341 } 6342 return deviceId; 6343 } 6344 6345 /** @see AudioManager#addOnCommunicationDeviceChangedListener( 6346 * Executor, AudioManager.OnCommunicationDeviceChangedListener) 6347 */ registerCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)6348 public void registerCommunicationDeviceDispatcher( 6349 @Nullable ICommunicationDeviceDispatcher dispatcher) { 6350 if (dispatcher == null) { 6351 return; 6352 } 6353 mDeviceBroker.registerCommunicationDeviceDispatcher(dispatcher); 6354 } 6355 6356 /** @see AudioManager#removeOnCommunicationDeviceChangedListener( 6357 * AudioManager.OnCommunicationDeviceChangedListener) 6358 */ unregisterCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)6359 public void unregisterCommunicationDeviceDispatcher( 6360 @Nullable ICommunicationDeviceDispatcher dispatcher) { 6361 if (dispatcher == null) { 6362 return; 6363 } 6364 mDeviceBroker.unregisterCommunicationDeviceDispatcher(dispatcher); 6365 } 6366 6367 /** @see AudioManager#setSpeakerphoneOn(boolean) */ setSpeakerphoneOn(IBinder cb, boolean on)6368 public void setSpeakerphoneOn(IBinder cb, boolean on) { 6369 if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) { 6370 return; 6371 } 6372 final boolean isPrivileged = mContext.checkCallingOrSelfPermission( 6373 android.Manifest.permission.MODIFY_PHONE_STATE) 6374 == PackageManager.PERMISSION_GRANTED; 6375 6376 // for logging only 6377 final int uid = Binder.getCallingUid(); 6378 final int pid = Binder.getCallingPid(); 6379 6380 final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on) 6381 .append(") from u/pid:").append(uid).append("/") 6382 .append(pid).toString(); 6383 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 6384 + MediaMetrics.SEPARATOR + "setSpeakerphoneOn") 6385 .setUid(uid) 6386 .setPid(pid) 6387 .set(MediaMetrics.Property.STATE, on 6388 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 6389 .record(); 6390 6391 final long ident = Binder.clearCallingIdentity(); 6392 try { 6393 mDeviceBroker.setSpeakerphoneOn(cb, uid, on, isPrivileged, eventSource); 6394 } finally { 6395 Binder.restoreCallingIdentity(ident); 6396 } 6397 } 6398 6399 /** @see AudioManager#isSpeakerphoneOn() */ isSpeakerphoneOn()6400 public boolean isSpeakerphoneOn() { 6401 return mDeviceBroker.isSpeakerphoneOn(); 6402 } 6403 6404 6405 /** BT SCO audio state seen by apps using the deprecated API setBluetoothScoOn(). 6406 * @see isBluetoothScoOn() */ 6407 private boolean mBtScoOnByApp; 6408 6409 /** @see AudioManager#setBluetoothScoOn(boolean) */ setBluetoothScoOn(boolean on)6410 public void setBluetoothScoOn(boolean on) { 6411 if (!checkAudioSettingsPermission("setBluetoothScoOn()")) { 6412 return; 6413 } 6414 6415 // Only enable calls from system components 6416 if (UserHandle.getCallingAppId() >= FIRST_APPLICATION_UID) { 6417 mBtScoOnByApp = on; 6418 return; 6419 } 6420 6421 // for logging only 6422 final int uid = Binder.getCallingUid(); 6423 final int pid = Binder.getCallingPid(); 6424 final String eventSource = new StringBuilder("setBluetoothScoOn(").append(on) 6425 .append(") from u/pid:").append(uid).append("/").append(pid).toString(); 6426 6427 //bt sco 6428 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 6429 + MediaMetrics.SEPARATOR + "setBluetoothScoOn") 6430 .setUid(uid) 6431 .setPid(pid) 6432 .set(MediaMetrics.Property.STATE, on 6433 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 6434 .record(); 6435 6436 mDeviceBroker.setBluetoothScoOn(on, eventSource); 6437 } 6438 6439 /** @see AudioManager#setA2dpSuspended(boolean) */ 6440 @android.annotation.EnforcePermission(android.Manifest.permission.BLUETOOTH_STACK) setA2dpSuspended(boolean enable)6441 public void setA2dpSuspended(boolean enable) { 6442 super.setA2dpSuspended_enforcePermission(); 6443 final String eventSource = new StringBuilder("setA2dpSuspended(").append(enable) 6444 .append(") from u/pid:").append(Binder.getCallingUid()).append("/") 6445 .append(Binder.getCallingPid()).toString(); 6446 mDeviceBroker.setA2dpSuspended(enable, false /*internal*/, eventSource); 6447 } 6448 6449 /** @see AudioManager#setA2dpSuspended(boolean) */ 6450 @android.annotation.EnforcePermission(android.Manifest.permission.BLUETOOTH_STACK) setLeAudioSuspended(boolean enable)6451 public void setLeAudioSuspended(boolean enable) { 6452 super.setLeAudioSuspended_enforcePermission(); 6453 final String eventSource = new StringBuilder("setLeAudioSuspended(").append(enable) 6454 .append(") from u/pid:").append(Binder.getCallingUid()).append("/") 6455 .append(Binder.getCallingPid()).toString(); 6456 mDeviceBroker.setLeAudioSuspended(enable, false /*internal*/, eventSource); 6457 } 6458 6459 /** @see AudioManager#isBluetoothScoOn() 6460 * Note that it doesn't report internal state, but state seen by apps (which may have 6461 * called setBluetoothScoOn() */ isBluetoothScoOn()6462 public boolean isBluetoothScoOn() { 6463 return mBtScoOnByApp || mDeviceBroker.isBluetoothScoOn(); 6464 } 6465 6466 // TODO investigate internal users due to deprecation of SDK API 6467 /** @see AudioManager#setBluetoothA2dpOn(boolean) */ setBluetoothA2dpOn(boolean on)6468 public void setBluetoothA2dpOn(boolean on) { 6469 if (!checkAudioSettingsPermission("setBluetoothA2dpOn()")) { 6470 return; 6471 } 6472 6473 // for logging only 6474 final int uid = Binder.getCallingUid(); 6475 final int pid = Binder.getCallingPid(); 6476 final String eventSource = new StringBuilder("setBluetoothA2dpOn(").append(on) 6477 .append(") from u/pid:").append(uid).append("/") 6478 .append(pid).toString(); 6479 6480 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 6481 + MediaMetrics.SEPARATOR + "setBluetoothA2dpOn") 6482 .setUid(uid) 6483 .setPid(pid) 6484 .set(MediaMetrics.Property.STATE, on 6485 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 6486 .record(); 6487 6488 mDeviceBroker.setBluetoothA2dpOn_Async(on, eventSource); 6489 } 6490 6491 /** @see AudioManager#isBluetoothA2dpOn() */ isBluetoothA2dpOn()6492 public boolean isBluetoothA2dpOn() { 6493 return mDeviceBroker.isBluetoothA2dpOn(); 6494 } 6495 6496 /** @see AudioManager#startBluetoothSco() */ startBluetoothSco(IBinder cb, int targetSdkVersion)6497 public void startBluetoothSco(IBinder cb, int targetSdkVersion) { 6498 if (!checkAudioSettingsPermission("startBluetoothSco()")) { 6499 return; 6500 } 6501 6502 final int uid = Binder.getCallingUid(); 6503 final int pid = Binder.getCallingPid(); 6504 final int scoAudioMode = 6505 (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ? 6506 BtHelper.SCO_MODE_VIRTUAL_CALL : BtHelper.SCO_MODE_UNDEFINED; 6507 final String eventSource = new StringBuilder("startBluetoothSco()") 6508 .append(") from u/pid:").append(uid).append("/") 6509 .append(pid).toString(); 6510 6511 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 6512 .setUid(uid) 6513 .setPid(pid) 6514 .set(MediaMetrics.Property.EVENT, "startBluetoothSco") 6515 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 6516 BtHelper.scoAudioModeToString(scoAudioMode)) 6517 .record(); 6518 startBluetoothScoInt(cb, uid, scoAudioMode, eventSource); 6519 6520 } 6521 6522 /** @see AudioManager#startBluetoothScoVirtualCall() */ startBluetoothScoVirtualCall(IBinder cb)6523 public void startBluetoothScoVirtualCall(IBinder cb) { 6524 if (!checkAudioSettingsPermission("startBluetoothScoVirtualCall()")) { 6525 return; 6526 } 6527 6528 final int uid = Binder.getCallingUid(); 6529 final int pid = Binder.getCallingPid(); 6530 final String eventSource = new StringBuilder("startBluetoothScoVirtualCall()") 6531 .append(") from u/pid:").append(uid).append("/") 6532 .append(pid).toString(); 6533 6534 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 6535 .setUid(uid) 6536 .setPid(pid) 6537 .set(MediaMetrics.Property.EVENT, "startBluetoothScoVirtualCall") 6538 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 6539 BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_VIRTUAL_CALL)) 6540 .record(); 6541 startBluetoothScoInt(cb, uid, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource); 6542 } 6543 startBluetoothScoInt(IBinder cb, int uid, int scoAudioMode, @NonNull String eventSource)6544 void startBluetoothScoInt(IBinder cb, int uid, int scoAudioMode, @NonNull String eventSource) { 6545 MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 6546 .set(MediaMetrics.Property.EVENT, "startBluetoothScoInt") 6547 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 6548 BtHelper.scoAudioModeToString(scoAudioMode)); 6549 6550 if (!checkAudioSettingsPermission("startBluetoothSco()") || 6551 !mSystemReady) { 6552 mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission or systemReady").record(); 6553 return; 6554 } 6555 final boolean isPrivileged = mContext.checkCallingOrSelfPermission( 6556 android.Manifest.permission.MODIFY_PHONE_STATE) 6557 == PackageManager.PERMISSION_GRANTED; 6558 final long ident = Binder.clearCallingIdentity(); 6559 try { 6560 mDeviceBroker.startBluetoothScoForClient( 6561 cb, uid, scoAudioMode, isPrivileged, eventSource); 6562 } finally { 6563 Binder.restoreCallingIdentity(ident); 6564 } 6565 mmi.record(); 6566 } 6567 6568 /** @see AudioManager#stopBluetoothSco() */ stopBluetoothSco(IBinder cb)6569 public void stopBluetoothSco(IBinder cb){ 6570 if (!checkAudioSettingsPermission("stopBluetoothSco()") || 6571 !mSystemReady) { 6572 return; 6573 } 6574 final int uid = Binder.getCallingUid(); 6575 final int pid = Binder.getCallingPid(); 6576 final String eventSource = new StringBuilder("stopBluetoothSco()") 6577 .append(") from u/pid:").append(uid).append("/") 6578 .append(pid).toString(); 6579 final boolean isPrivileged = mContext.checkCallingOrSelfPermission( 6580 android.Manifest.permission.MODIFY_PHONE_STATE) 6581 == PackageManager.PERMISSION_GRANTED; 6582 final long ident = Binder.clearCallingIdentity(); 6583 try { 6584 mDeviceBroker.stopBluetoothScoForClient(cb, uid, isPrivileged, eventSource); 6585 } finally { 6586 Binder.restoreCallingIdentity(ident); 6587 } 6588 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 6589 .setUid(uid) 6590 .setPid(pid) 6591 .set(MediaMetrics.Property.EVENT, "stopBluetoothSco") 6592 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 6593 BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_UNDEFINED)) 6594 .record(); 6595 } 6596 6597 getContentResolver()6598 /*package*/ ContentResolver getContentResolver() { 6599 return mContentResolver; 6600 } 6601 getSettings()6602 /*package*/ SettingsAdapter getSettings() { 6603 return mSettings; 6604 } 6605 6606 /////////////////////////////////////////////////////////////////////////// 6607 // Internal methods 6608 /////////////////////////////////////////////////////////////////////////// 6609 6610 /** 6611 * Checks if the adjustment should change ringer mode instead of just 6612 * adjusting volume. If so, this will set the proper ringer mode and volume 6613 * indices on the stream states. 6614 */ checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, String caller, int flags)6615 private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, 6616 String caller, int flags) { 6617 int result = FLAG_ADJUST_VOLUME; 6618 if (isPlatformTelevision() || mIsSingleVolume) { 6619 return result; 6620 } 6621 6622 int ringerMode = getRingerModeInternal(); 6623 6624 switch (ringerMode) { 6625 case RINGER_MODE_NORMAL: 6626 if (direction == AudioManager.ADJUST_LOWER) { 6627 if (mHasVibrator) { 6628 // "step" is the delta in internal index units corresponding to a 6629 // change of 1 in UI index units. 6630 // Because of rounding when rescaling from one stream index range to its alias 6631 // index range, we cannot simply test oldIndex == step: 6632 // (step <= oldIndex < 2 * step) is equivalent to: (old UI index == 1) 6633 if (step <= oldIndex && oldIndex < 2 * step) { 6634 ringerMode = RINGER_MODE_VIBRATE; 6635 mLoweredFromNormalToVibrateTime = SystemClock.uptimeMillis(); 6636 } 6637 } else { 6638 if (oldIndex == step && mVolumePolicy.volumeDownToEnterSilent) { 6639 ringerMode = RINGER_MODE_SILENT; 6640 } 6641 } 6642 } else if (mIsSingleVolume && (direction == AudioManager.ADJUST_TOGGLE_MUTE 6643 || direction == AudioManager.ADJUST_MUTE)) { 6644 if (mHasVibrator) { 6645 ringerMode = RINGER_MODE_VIBRATE; 6646 } else { 6647 ringerMode = RINGER_MODE_SILENT; 6648 } 6649 // Setting the ringer mode will toggle mute 6650 result &= ~FLAG_ADJUST_VOLUME; 6651 } 6652 break; 6653 case RINGER_MODE_VIBRATE: 6654 if (!mHasVibrator) { 6655 Log.e(TAG, "checkForRingerModeChange() current ringer mode is vibrate" + 6656 "but no vibrator is present"); 6657 break; 6658 } 6659 if ((direction == AudioManager.ADJUST_LOWER)) { 6660 // This is the case we were muted with the volume turned up 6661 if (mIsSingleVolume && oldIndex >= 2 * step && isMuted) { 6662 ringerMode = RINGER_MODE_NORMAL; 6663 } else if (mPrevVolDirection != AudioManager.ADJUST_LOWER) { 6664 if (mVolumePolicy.volumeDownToEnterSilent) { 6665 final long diff = SystemClock.uptimeMillis() 6666 - mLoweredFromNormalToVibrateTime; 6667 if (diff > mVolumePolicy.vibrateToSilentDebounce 6668 && mRingerModeDelegate.canVolumeDownEnterSilent()) { 6669 ringerMode = RINGER_MODE_SILENT; 6670 } 6671 } else { 6672 result |= AudioManager.FLAG_SHOW_VIBRATE_HINT; 6673 } 6674 } 6675 } else if (direction == AudioManager.ADJUST_RAISE 6676 || direction == AudioManager.ADJUST_TOGGLE_MUTE 6677 || direction == AudioManager.ADJUST_UNMUTE) { 6678 ringerMode = RINGER_MODE_NORMAL; 6679 } 6680 result &= ~FLAG_ADJUST_VOLUME; 6681 break; 6682 case RINGER_MODE_SILENT: 6683 if (mIsSingleVolume && direction == AudioManager.ADJUST_LOWER && oldIndex >= 2 * step && isMuted) { 6684 // This is the case we were muted with the volume turned up 6685 ringerMode = RINGER_MODE_NORMAL; 6686 } else if (direction == AudioManager.ADJUST_RAISE 6687 || direction == AudioManager.ADJUST_TOGGLE_MUTE 6688 || direction == AudioManager.ADJUST_UNMUTE) { 6689 if (!mVolumePolicy.volumeUpToExitSilent) { 6690 result |= AudioManager.FLAG_SHOW_SILENT_HINT; 6691 } else { 6692 if (mHasVibrator && direction == AudioManager.ADJUST_RAISE) { 6693 ringerMode = RINGER_MODE_VIBRATE; 6694 } else { 6695 // If we don't have a vibrator or they were toggling mute 6696 // go straight back to normal. 6697 ringerMode = RINGER_MODE_NORMAL; 6698 } 6699 } 6700 } 6701 result &= ~FLAG_ADJUST_VOLUME; 6702 break; 6703 default: 6704 Log.e(TAG, "checkForRingerModeChange() wrong ringer mode: "+ringerMode); 6705 break; 6706 } 6707 6708 if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode) 6709 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller) 6710 && (flags & AudioManager.FLAG_FROM_KEY) == 0) { 6711 throw new SecurityException("Not allowed to change Do Not Disturb state"); 6712 } 6713 6714 setRingerMode(ringerMode, TAG + ".checkForRingerModeChange", false /*external*/); 6715 6716 mPrevVolDirection = direction; 6717 6718 return result; 6719 } 6720 6721 @Override isStreamAffectedByRingerMode(int streamType)6722 public boolean isStreamAffectedByRingerMode(int streamType) { 6723 return (mRingerModeAffectedStreams & (1 << streamType)) != 0; 6724 } 6725 shouldZenMuteStream(int streamType)6726 private boolean shouldZenMuteStream(int streamType) { 6727 if (mNm.getZenMode() != Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { 6728 return false; 6729 } 6730 6731 NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy(); 6732 final boolean muteAlarms = (zenPolicy.priorityCategories 6733 & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0; 6734 final boolean muteMedia = (zenPolicy.priorityCategories 6735 & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0; 6736 final boolean muteSystem = (zenPolicy.priorityCategories 6737 & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0; 6738 final boolean muteNotificationAndRing = ZenModeConfig 6739 .areAllPriorityOnlyRingerSoundsMuted(zenPolicy); 6740 return muteAlarms && isAlarm(streamType) 6741 || muteMedia && isMedia(streamType) 6742 || muteSystem && isSystem(streamType) 6743 || muteNotificationAndRing && isNotificationOrRinger(streamType); 6744 } 6745 isStreamMutedByRingerOrZenMode(int streamType)6746 private boolean isStreamMutedByRingerOrZenMode(int streamType) { 6747 return (sRingerAndZenModeMutedStreams & (1 << streamType)) != 0; 6748 } 6749 6750 /** 6751 * Notifications, ringer and system sounds are controlled by the ringer: 6752 * {@link ZenModeHelper.RingerModeDelegate#getRingerModeAffectedStreams(int)} but can 6753 * also be muted by DND based on the DND mode: 6754 * DND total silence: media and alarms streams can be muted by DND 6755 * DND alarms only: no streams additionally controlled by DND 6756 * DND priority only: alarms, media, system, ringer and notification streams can be muted by 6757 * DND. The current applied zenPolicy determines which streams will be muted by DND. 6758 * @return true if changed, else false 6759 */ updateZenModeAffectedStreams()6760 private boolean updateZenModeAffectedStreams() { 6761 if (!mSystemReady) { 6762 return false; 6763 } 6764 6765 int zenModeAffectedStreams = 0; 6766 final int zenMode = mNm.getZenMode(); 6767 6768 if (zenMode == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS) { 6769 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM; 6770 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC; 6771 } else if (zenMode == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { 6772 NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy(); 6773 if ((zenPolicy.priorityCategories 6774 & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0) { 6775 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM; 6776 } 6777 6778 if ((zenPolicy.priorityCategories 6779 & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0) { 6780 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC; 6781 } 6782 6783 // even if zen isn't muting the system stream, the ringer mode can still mute 6784 // the system stream 6785 if ((zenPolicy.priorityCategories 6786 & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) { 6787 zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM; 6788 } 6789 6790 if (ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(zenPolicy)) { 6791 zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION; 6792 zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING; 6793 } 6794 } 6795 6796 if (mZenModeAffectedStreams != zenModeAffectedStreams) { 6797 mZenModeAffectedStreams = zenModeAffectedStreams; 6798 return true; 6799 } 6800 6801 return false; 6802 } 6803 6804 @GuardedBy("mSettingsLock") updateRingerAndZenModeAffectedStreams()6805 private boolean updateRingerAndZenModeAffectedStreams() { 6806 boolean updatedZenModeAffectedStreams = updateZenModeAffectedStreams(); 6807 int ringerModeAffectedStreams = mSettings.getSystemIntForUser(mContentResolver, 6808 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 6809 ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)| 6810 (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)), 6811 UserHandle.USER_CURRENT); 6812 6813 if (mIsSingleVolume) { 6814 ringerModeAffectedStreams = 0; 6815 } else if (mRingerModeDelegate != null) { 6816 ringerModeAffectedStreams = mRingerModeDelegate 6817 .getRingerModeAffectedStreams(ringerModeAffectedStreams); 6818 } 6819 if (mCameraSoundForced) { 6820 ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 6821 } else { 6822 ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 6823 } 6824 if (mStreamVolumeAlias[AudioSystem.STREAM_DTMF] == AudioSystem.STREAM_RING) { 6825 ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF); 6826 } else { 6827 ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF); 6828 } 6829 6830 if (ringerModeAffectedStreams != mRingerModeAffectedStreams) { 6831 mSettings.putSystemIntForUser(mContentResolver, 6832 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 6833 ringerModeAffectedStreams, 6834 UserHandle.USER_CURRENT); 6835 mRingerModeAffectedStreams = ringerModeAffectedStreams; 6836 return true; 6837 } 6838 return updatedZenModeAffectedStreams; 6839 } 6840 6841 @Override isStreamAffectedByMute(int streamType)6842 public boolean isStreamAffectedByMute(int streamType) { 6843 return (mMuteAffectedStreams & (1 << streamType)) != 0; 6844 } 6845 ensureValidDirection(int direction)6846 private void ensureValidDirection(int direction) { 6847 switch (direction) { 6848 case AudioManager.ADJUST_LOWER: 6849 case AudioManager.ADJUST_RAISE: 6850 case AudioManager.ADJUST_SAME: 6851 case AudioManager.ADJUST_MUTE: 6852 case AudioManager.ADJUST_UNMUTE: 6853 case AudioManager.ADJUST_TOGGLE_MUTE: 6854 break; 6855 default: 6856 throw new IllegalArgumentException("Bad direction " + direction); 6857 } 6858 } 6859 ensureValidStreamType(int streamType)6860 private void ensureValidStreamType(int streamType) { 6861 if (streamType < 0 || streamType >= mStreamStates.length) { 6862 throw new IllegalArgumentException("Bad stream type " + streamType); 6863 } 6864 } 6865 isMuteAdjust(int adjust)6866 private boolean isMuteAdjust(int adjust) { 6867 return adjust == AudioManager.ADJUST_MUTE || adjust == AudioManager.ADJUST_UNMUTE 6868 || adjust == AudioManager.ADJUST_TOGGLE_MUTE; 6869 } 6870 6871 /** only public for mocking/spying, do not call outside of AudioService */ 6872 @VisibleForTesting isInCommunication()6873 public boolean isInCommunication() { 6874 boolean IsInCall = false; 6875 6876 TelecomManager telecomManager = 6877 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 6878 6879 final long ident = Binder.clearCallingIdentity(); 6880 try { 6881 IsInCall = telecomManager.isInCall(); 6882 } finally { 6883 Binder.restoreCallingIdentity(ident); 6884 } 6885 6886 int mode = mMode.get(); 6887 return (IsInCall 6888 || mode == AudioManager.MODE_IN_COMMUNICATION 6889 || mode == AudioManager.MODE_IN_CALL); 6890 } 6891 6892 /** 6893 * For code clarity for getActiveStreamType(int) 6894 * @param delay_ms max time since last stream activity to consider 6895 * @return true if stream is active in streams handled by AudioFlinger now or 6896 * in the last "delay_ms" ms. 6897 */ wasStreamActiveRecently(int stream, int delay_ms)6898 private boolean wasStreamActiveRecently(int stream, int delay_ms) { 6899 return mAudioSystem.isStreamActive(stream, delay_ms) 6900 || mAudioSystem.isStreamActiveRemotely(stream, delay_ms); 6901 } 6902 getActiveStreamType(int suggestedStreamType)6903 private int getActiveStreamType(int suggestedStreamType) { 6904 if (mIsSingleVolume 6905 && suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 6906 return AudioSystem.STREAM_MUSIC; 6907 } 6908 6909 switch (mPlatformType) { 6910 case AudioSystem.PLATFORM_VOICE: 6911 if (isInCommunication()) { 6912 if (mDeviceBroker.isBluetoothScoActive()) { 6913 // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO..."); 6914 return AudioSystem.STREAM_BLUETOOTH_SCO; 6915 } else { 6916 // Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL..."); 6917 return AudioSystem.STREAM_VOICE_CALL; 6918 } 6919 } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 6920 if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 6921 if (DEBUG_VOL) 6922 Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active"); 6923 return AudioSystem.STREAM_RING; 6924 } else if (wasStreamActiveRecently( 6925 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 6926 if (DEBUG_VOL) { 6927 Log.v( 6928 TAG, 6929 "getActiveStreamType: Forcing STREAM_NOTIFICATION stream" 6930 + " active"); 6931 } 6932 return AudioSystem.STREAM_NOTIFICATION; 6933 } else { 6934 if (DEBUG_VOL) { 6935 Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK(" 6936 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default"); 6937 } 6938 return DEFAULT_VOL_STREAM_NO_PLAYBACK; 6939 } 6940 } else if ( 6941 wasStreamActiveRecently(AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 6942 if (DEBUG_VOL) 6943 Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active"); 6944 return AudioSystem.STREAM_NOTIFICATION; 6945 } else if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 6946 if (DEBUG_VOL) 6947 Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active"); 6948 return AudioSystem.STREAM_RING; 6949 } 6950 default: 6951 if (isInCommunication()) { 6952 if (mDeviceBroker.isBluetoothScoActive()) { 6953 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO"); 6954 return AudioSystem.STREAM_BLUETOOTH_SCO; 6955 } else { 6956 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL"); 6957 return AudioSystem.STREAM_VOICE_CALL; 6958 } 6959 } else if (mAudioSystem.isStreamActive( 6960 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 6961 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION"); 6962 return AudioSystem.STREAM_NOTIFICATION; 6963 } else if (mAudioSystem.isStreamActive( 6964 AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 6965 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING"); 6966 return AudioSystem.STREAM_RING; 6967 } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 6968 if (mAudioSystem.isStreamActive( 6969 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 6970 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION"); 6971 return AudioSystem.STREAM_NOTIFICATION; 6972 } 6973 if (mAudioSystem.isStreamActive( 6974 AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 6975 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING"); 6976 return AudioSystem.STREAM_RING; 6977 } 6978 if (DEBUG_VOL) { 6979 Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK(" 6980 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default"); 6981 } 6982 return DEFAULT_VOL_STREAM_NO_PLAYBACK; 6983 } 6984 break; 6985 } 6986 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Returning suggested type " 6987 + suggestedStreamType); 6988 return suggestedStreamType; 6989 } 6990 broadcastRingerMode(String action, int ringerMode)6991 private void broadcastRingerMode(String action, int ringerMode) { 6992 if (!mSystemServer.isPrivileged()) { 6993 return; 6994 } 6995 // Send sticky broadcast 6996 Intent broadcast = new Intent(action); 6997 broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, ringerMode); 6998 broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 6999 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 7000 sendStickyBroadcastToAll(broadcast); 7001 } 7002 broadcastVibrateSetting(int vibrateType)7003 private void broadcastVibrateSetting(int vibrateType) { 7004 if (!mSystemServer.isPrivileged()) { 7005 return; 7006 } 7007 // Send broadcast 7008 if (mActivityManagerInternal.isSystemReady()) { 7009 Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION); 7010 broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType); 7011 broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType)); 7012 sendBroadcastToAll(broadcast, null /* options */); 7013 } 7014 } 7015 7016 // Message helper methods 7017 /** 7018 * Queue a message on the given handler's message queue, after acquiring the service wake lock. 7019 * Note that the wake lock needs to be released after the message has been handled. 7020 */ queueMsgUnderWakeLock(Handler handler, int msg, int arg1, int arg2, Object obj, int delay)7021 private void queueMsgUnderWakeLock(Handler handler, int msg, 7022 int arg1, int arg2, Object obj, int delay) { 7023 final long ident = Binder.clearCallingIdentity(); 7024 try { 7025 // Always acquire the wake lock as AudioService because it is released by the 7026 // message handler. 7027 mAudioEventWakeLock.acquire(); 7028 } finally { 7029 Binder.restoreCallingIdentity(ident); 7030 } 7031 sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay); 7032 } 7033 sendMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, int delay)7034 private static void sendMsg(Handler handler, int msg, 7035 int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) { 7036 if (existingMsgPolicy == SENDMSG_REPLACE) { 7037 handler.removeMessages(msg); 7038 } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) { 7039 return; 7040 } 7041 7042 final long time = SystemClock.uptimeMillis() + delay; 7043 handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time); 7044 } 7045 sendBundleMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, Bundle bundle, int delay)7046 private static void sendBundleMsg(Handler handler, int msg, 7047 int existingMsgPolicy, int arg1, int arg2, Object obj, Bundle bundle, int delay) { 7048 if (existingMsgPolicy == SENDMSG_REPLACE) { 7049 handler.removeMessages(msg); 7050 } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) { 7051 return; 7052 } 7053 7054 final long time = SystemClock.uptimeMillis() + delay; 7055 Message message = handler.obtainMessage(msg, arg1, arg2, obj); 7056 message.setData(bundle); 7057 handler.sendMessageAtTime(message, time); 7058 } 7059 checkAudioSettingsPermission(String method)7060 boolean checkAudioSettingsPermission(String method) { 7061 if (callingOrSelfHasAudioSettingsPermission()) { 7062 return true; 7063 } 7064 String msg = "Audio Settings Permission Denial: " + method + " from pid=" 7065 + Binder.getCallingPid() 7066 + ", uid=" + Binder.getCallingUid(); 7067 Log.w(TAG, msg); 7068 return false; 7069 } 7070 callingOrSelfHasAudioSettingsPermission()7071 private boolean callingOrSelfHasAudioSettingsPermission() { 7072 return mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS) 7073 == PackageManager.PERMISSION_GRANTED; 7074 } 7075 callingHasAudioSettingsPermission()7076 private boolean callingHasAudioSettingsPermission() { 7077 return mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS) 7078 == PackageManager.PERMISSION_GRANTED; 7079 } 7080 hasAudioSettingsPermission(int uid, int pid)7081 private boolean hasAudioSettingsPermission(int uid, int pid) { 7082 return mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid) 7083 == PackageManager.PERMISSION_GRANTED; 7084 } 7085 7086 /** 7087 * Minimum attenuation that can be set for alarms over speaker by an application that 7088 * doesn't have the MODIFY_AUDIO_SETTINGS permission. 7089 */ 7090 protected static final float MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB = -36.0f; 7091 7092 /** 7093 * Configures the VolumeStreamState instances for minimum stream index that can be accessed 7094 * without MODIFY_AUDIO_SETTINGS permission. 7095 * Can only be done successfully once audio policy has finished reading its configuration files 7096 * for the volume curves. If not, getStreamVolumeDB will return NaN, and the min value will 7097 * remain at the stream min index value. 7098 */ initMinStreamVolumeWithoutModifyAudioSettings()7099 protected void initMinStreamVolumeWithoutModifyAudioSettings() { 7100 int idx; 7101 int deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER_SAFE; 7102 if (Float.isNaN(AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, 7103 MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM], deviceForAlarm))) { 7104 deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER; 7105 } 7106 for (idx = MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; 7107 idx >= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; idx--) { 7108 if (AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, idx, deviceForAlarm) 7109 < MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB) { 7110 break; 7111 } 7112 } 7113 final int safeIndex = idx <= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM] 7114 ? MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM] 7115 : Math.min(idx + 1, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]); 7116 // update the VolumeStreamState for STREAM_ALARM and its aliases 7117 for (int stream : mStreamVolumeAlias) { 7118 if (mStreamVolumeAlias[stream] == AudioSystem.STREAM_ALARM) { 7119 mStreamStates[stream].updateNoPermMinIndex(safeIndex); 7120 } 7121 } 7122 } 7123 7124 /** 7125 * Returns device associated with the stream volume. 7126 * 7127 * Only public for mocking/spying, do not call outside of AudioService. 7128 * Device volume aliasing means DEVICE_OUT_SPEAKER may be returned for 7129 * DEVICE_OUT_SPEAKER_SAFE. 7130 */ 7131 @VisibleForTesting getDeviceForStream(int stream)7132 public int getDeviceForStream(int stream) { 7133 return selectOneAudioDevice(getDeviceSetForStream(stream)); 7134 } 7135 7136 /* 7137 * Must match native apm_extract_one_audio_device() used in getDeviceForVolume() 7138 * or the wrong device volume may be adjusted. 7139 */ selectOneAudioDevice(Set<Integer> deviceSet)7140 private int selectOneAudioDevice(Set<Integer> deviceSet) { 7141 if (deviceSet.isEmpty()) { 7142 return AudioSystem.DEVICE_NONE; 7143 } else if (deviceSet.size() == 1) { 7144 return deviceSet.iterator().next(); 7145 } else { 7146 // Multiple device selection is either: 7147 // - dock + one other device: give priority to dock in this case. 7148 // - speaker + one other device: give priority to speaker in this case. 7149 // - one A2DP device + another device: happens with duplicated output. In this case 7150 // retain the device on the A2DP output as the other must not correspond to an active 7151 // selection if not the speaker. 7152 // - HDMI-CEC system audio mode only output: give priority to available item in order. 7153 7154 if (deviceSet.contains(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET)) { 7155 return AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET; 7156 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER)) { 7157 return AudioSystem.DEVICE_OUT_SPEAKER; 7158 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER_SAFE)) { 7159 // Note: DEVICE_OUT_SPEAKER_SAFE not present in getDeviceSetForStreamDirect 7160 return AudioSystem.DEVICE_OUT_SPEAKER_SAFE; 7161 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_ARC)) { 7162 return AudioSystem.DEVICE_OUT_HDMI_ARC; 7163 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_EARC)) { 7164 return AudioSystem.DEVICE_OUT_HDMI_EARC; 7165 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_AUX_LINE)) { 7166 return AudioSystem.DEVICE_OUT_AUX_LINE; 7167 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPDIF)) { 7168 return AudioSystem.DEVICE_OUT_SPDIF; 7169 } else { 7170 // At this point, deviceSet should contain exactly one A2DP device; 7171 // regardless, return the first A2DP device in numeric order. 7172 // If there is no A2DP device, this falls through to log an error. 7173 for (int deviceType : deviceSet) { 7174 if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType)) { 7175 return deviceType; 7176 } 7177 } 7178 } 7179 } 7180 Log.w(TAG, "selectOneAudioDevice returning DEVICE_NONE from invalid device combination " 7181 + AudioSystem.deviceSetToString(deviceSet)); 7182 return AudioSystem.DEVICE_NONE; 7183 } 7184 7185 /** 7186 * @see AudioManager#getDevicesForStream(int) 7187 * @deprecated on {@link android.os.Build.VERSION_CODES#T} as new devices 7188 * will have multi-bit device types since S. 7189 * Use {@link #getDevicesForAttributes()} instead. 7190 */ 7191 @Override 7192 @Deprecated getDeviceMaskForStream(int streamType)7193 public int getDeviceMaskForStream(int streamType) { 7194 ensureValidStreamType(streamType); 7195 // no permission required 7196 final long token = Binder.clearCallingIdentity(); 7197 try { 7198 return AudioSystem.getDeviceMaskFromSet( 7199 getDeviceSetForStreamDirect(streamType)); 7200 } finally { 7201 Binder.restoreCallingIdentity(token); 7202 } 7203 } 7204 7205 /** 7206 * Returns the devices associated with a stream type. 7207 * 7208 * SPEAKER_SAFE will alias to SPEAKER. 7209 */ 7210 @NonNull getDeviceSetForStreamDirect(int stream)7211 private Set<Integer> getDeviceSetForStreamDirect(int stream) { 7212 final AudioAttributes attr = 7213 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream); 7214 Set<Integer> deviceSet = 7215 AudioSystem.generateAudioDeviceTypesSet( 7216 getDevicesForAttributesInt(attr, true /* forVolume */)); 7217 return deviceSet; 7218 } 7219 7220 /** 7221 * Returns a reference to the list of devices for the stream, do not modify. 7222 * 7223 * The device returned may be aliased to the actual device whose volume curve 7224 * will be used. For example DEVICE_OUT_SPEAKER_SAFE aliases to DEVICE_OUT_SPEAKER. 7225 */ 7226 @NonNull getDeviceSetForStream(int stream)7227 public Set<Integer> getDeviceSetForStream(int stream) { 7228 ensureValidStreamType(stream); 7229 synchronized (VolumeStreamState.class) { 7230 return mStreamStates[stream].observeDevicesForStream_syncVSS(true); 7231 } 7232 } 7233 onObserveDevicesForAllStreams(int skipStream)7234 private void onObserveDevicesForAllStreams(int skipStream) { 7235 synchronized (mSettingsLock) { 7236 synchronized (VolumeStreamState.class) { 7237 for (int stream = 0; stream < mStreamStates.length; stream++) { 7238 if (stream != skipStream) { 7239 Set<Integer> deviceSet = 7240 mStreamStates[stream].observeDevicesForStream_syncVSS( 7241 false /*checkOthers*/); 7242 for (Integer device : deviceSet) { 7243 // Update volume states for devices routed for the stream 7244 updateVolumeStates(device, stream, 7245 "AudioService#onObserveDevicesForAllStreams"); 7246 } 7247 } 7248 } 7249 } 7250 } 7251 } 7252 7253 /** only public for mocking/spying, do not call outside of AudioService */ 7254 @VisibleForTesting postObserveDevicesForAllStreams()7255 public void postObserveDevicesForAllStreams() { 7256 postObserveDevicesForAllStreams(-1); 7257 } 7258 7259 /** only public for mocking/spying, do not call outside of AudioService */ 7260 @VisibleForTesting postObserveDevicesForAllStreams(int skipStream)7261 public void postObserveDevicesForAllStreams(int skipStream) { 7262 sendMsg(mAudioHandler, 7263 MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS, 7264 SENDMSG_QUEUE, skipStream /*arg1*/, 0 /*arg2*/, null /*obj*/, 7265 0 /*delay*/); 7266 } 7267 7268 /** 7269 * @see AudioDeviceVolumeManager#setDeviceAbsoluteMultiVolumeBehavior 7270 * 7271 * @param register Whether the listener is to be registered or unregistered. If false, the 7272 * device adopts variable volume behavior. 7273 */ 7274 @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING, 7275 android.Manifest.permission.BLUETOOTH_PRIVILEGED }) registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register, IAudioDeviceVolumeDispatcher cb, String packageName, AudioDeviceAttributes device, List<VolumeInfo> volumes, boolean handlesVolumeAdjustment, @AudioManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior)7276 public void registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register, 7277 IAudioDeviceVolumeDispatcher cb, String packageName, 7278 AudioDeviceAttributes device, List<VolumeInfo> volumes, 7279 boolean handlesVolumeAdjustment, 7280 @AudioManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior) { 7281 // verify permissions 7282 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 7283 != PackageManager.PERMISSION_GRANTED 7284 && mContext.checkCallingOrSelfPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) 7285 != PackageManager.PERMISSION_GRANTED) { 7286 throw new SecurityException( 7287 "Missing MODIFY_AUDIO_ROUTING or BLUETOOTH_PRIVILEGED permissions"); 7288 } 7289 // verify arguments 7290 Objects.requireNonNull(device); 7291 Objects.requireNonNull(volumes); 7292 7293 int deviceOut = device.getInternalType(); 7294 if (register) { 7295 AbsoluteVolumeDeviceInfo info = new AbsoluteVolumeDeviceInfo( 7296 device, volumes, cb, handlesVolumeAdjustment, deviceVolumeBehavior); 7297 AbsoluteVolumeDeviceInfo oldInfo = mAbsoluteVolumeDeviceInfoMap.get(deviceOut); 7298 boolean volumeBehaviorChanged = (oldInfo == null) 7299 || (oldInfo.mDeviceVolumeBehavior != deviceVolumeBehavior); 7300 if (volumeBehaviorChanged) { 7301 removeAudioSystemDeviceOutFromFullVolumeDevices(deviceOut); 7302 removeAudioSystemDeviceOutFromFixedVolumeDevices(deviceOut); 7303 addAudioSystemDeviceOutToAbsVolumeDevices(deviceOut, info); 7304 7305 dispatchDeviceVolumeBehavior(device, deviceVolumeBehavior); 7306 } 7307 // Update stream volumes to the given device, if specified in a VolumeInfo. 7308 // Mute state is not updated because it is stream-wide - the only way to mute a 7309 // stream's output to a particular device is to set the volume index to zero. 7310 for (VolumeInfo volumeInfo : volumes) { 7311 if (volumeInfo.getVolumeIndex() != VolumeInfo.INDEX_NOT_SET 7312 && volumeInfo.getMinVolumeIndex() != VolumeInfo.INDEX_NOT_SET 7313 && volumeInfo.getMaxVolumeIndex() != VolumeInfo.INDEX_NOT_SET) { 7314 if (volumeInfo.hasStreamType()) { 7315 setStreamVolumeInt(volumeInfo.getStreamType(), 7316 rescaleIndex(volumeInfo, volumeInfo.getStreamType()), 7317 deviceOut, false /*force*/, packageName, 7318 true /*hasModifyAudioSettings*/); 7319 } else { 7320 for (int streamType : volumeInfo.getVolumeGroup().getLegacyStreamTypes()) { 7321 setStreamVolumeInt(streamType, rescaleIndex(volumeInfo, streamType), 7322 deviceOut, false /*force*/, packageName, 7323 true /*hasModifyAudioSettings*/); 7324 } 7325 } 7326 } 7327 } 7328 } else { 7329 boolean wasAbsVol = removeAudioSystemDeviceOutFromAbsVolumeDevices(deviceOut) != null; 7330 if (wasAbsVol) { 7331 dispatchDeviceVolumeBehavior(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE); 7332 } 7333 } 7334 } 7335 7336 /** 7337 * @see AudioManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int) 7338 * @param device the audio device to be affected 7339 * @param deviceVolumeBehavior one of the device behaviors 7340 */ 7341 @android.annotation.EnforcePermission(anyOf = { 7342 android.Manifest.permission.MODIFY_AUDIO_ROUTING, 7343 android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED 7344 }) setDeviceVolumeBehavior(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName)7345 public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device, 7346 @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName) { 7347 // verify permissions 7348 super.setDeviceVolumeBehavior_enforcePermission(); 7349 // verify arguments 7350 Objects.requireNonNull(device); 7351 AudioManager.enforceValidVolumeBehavior(deviceVolumeBehavior); 7352 7353 device = retrieveBluetoothAddress(device); 7354 7355 sVolumeLogger.enqueue(new EventLogger.StringEvent("setDeviceVolumeBehavior: dev:" 7356 + AudioSystem.getOutputDeviceName(device.getInternalType()) + " addr:" 7357 + device.getAddress() + " behavior:" 7358 + AudioDeviceVolumeManager.volumeBehaviorName(deviceVolumeBehavior) 7359 + " pack:" + pkgName).printLog(TAG)); 7360 if (pkgName == null) { 7361 pkgName = ""; 7362 } 7363 if (device.getType() == TYPE_BLUETOOTH_A2DP) { 7364 avrcpSupportsAbsoluteVolume(device.getAddress(), 7365 deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE); 7366 return; 7367 } 7368 7369 setDeviceVolumeBehaviorInternal(device, deviceVolumeBehavior, pkgName); 7370 persistDeviceVolumeBehavior(device.getInternalType(), deviceVolumeBehavior); 7371 } 7372 setDeviceVolumeBehaviorInternal(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller)7373 private void setDeviceVolumeBehaviorInternal(@NonNull AudioDeviceAttributes device, 7374 @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller) { 7375 int audioSystemDeviceOut = device.getInternalType(); 7376 boolean volumeBehaviorChanged = false; 7377 // update device masks based on volume behavior 7378 switch (deviceVolumeBehavior) { 7379 case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE: 7380 volumeBehaviorChanged |= 7381 removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut) 7382 | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut) 7383 | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut) 7384 != null); 7385 break; 7386 case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED: 7387 volumeBehaviorChanged |= 7388 removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut) 7389 | addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut) 7390 | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut) 7391 != null); 7392 break; 7393 case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL: 7394 volumeBehaviorChanged |= 7395 addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut) 7396 | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut) 7397 | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut) 7398 != null); 7399 break; 7400 case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE: 7401 case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY: 7402 case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE: 7403 throw new IllegalArgumentException("Absolute volume unsupported for now"); 7404 } 7405 7406 if (volumeBehaviorChanged) { 7407 sendMsg(mAudioHandler, MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR, SENDMSG_QUEUE, 7408 deviceVolumeBehavior, 0, device, /*delay*/ 0); 7409 } 7410 7411 // log event and caller 7412 sDeviceLogger.enqueue(new EventLogger.StringEvent( 7413 "Volume behavior " + deviceVolumeBehavior + " for dev=0x" 7414 + Integer.toHexString(audioSystemDeviceOut) + " from:" + caller)); 7415 // make sure we have a volume entry for this device, and that volume is updated according 7416 // to volume behavior 7417 postUpdateVolumeStatesForAudioDevice(audioSystemDeviceOut, 7418 "setDeviceVolumeBehavior:" + caller); 7419 } 7420 7421 /** 7422 * @see AudioManager#getDeviceVolumeBehavior(AudioDeviceAttributes) 7423 * @param device the audio output device type 7424 * @return the volume behavior for the device 7425 */ 7426 @android.annotation.EnforcePermission(anyOf = { 7427 android.Manifest.permission.MODIFY_AUDIO_ROUTING, 7428 android.Manifest.permission.QUERY_AUDIO_STATE, 7429 android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED 7430 }) 7431 public @AudioManager.DeviceVolumeBehavior getDeviceVolumeBehavior(@onNull AudioDeviceAttributes device)7432 int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) { 7433 // verify permissions 7434 super.getDeviceVolumeBehavior_enforcePermission(); 7435 // verify parameters 7436 Objects.requireNonNull(device); 7437 7438 device = retrieveBluetoothAddress(device); 7439 7440 return getDeviceVolumeBehaviorInt(device); 7441 } 7442 7443 private @AudioManager.DeviceVolumeBehavior getDeviceVolumeBehaviorInt(@onNull AudioDeviceAttributes device)7444 int getDeviceVolumeBehaviorInt(@NonNull AudioDeviceAttributes device) { 7445 // Get the internal type set by the AudioDeviceAttributes constructor which is always more 7446 // exact (avoids double conversions) than a conversion from SDK type via 7447 // AudioDeviceInfo.convertDeviceTypeToInternalDevice() 7448 final int audioSystemDeviceOut = device.getInternalType(); 7449 7450 // setDeviceVolumeBehavior has not been explicitly called for the device type. Deduce the 7451 // current volume behavior. 7452 if (mFullVolumeDevices.contains(audioSystemDeviceOut)) { 7453 return AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL; 7454 } 7455 if (mFixedVolumeDevices.contains(audioSystemDeviceOut)) { 7456 return AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED; 7457 } 7458 if (mAbsVolumeMultiModeCaseDevices.contains(audioSystemDeviceOut)) { 7459 return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE; 7460 } 7461 if (mAbsoluteVolumeDeviceInfoMap.containsKey(audioSystemDeviceOut)) { 7462 return mAbsoluteVolumeDeviceInfoMap.get(audioSystemDeviceOut).mDeviceVolumeBehavior; 7463 } 7464 7465 if (isA2dpAbsoluteVolumeDevice(audioSystemDeviceOut) 7466 || AudioSystem.isLeAudioDeviceType(audioSystemDeviceOut)) { 7467 return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE; 7468 } 7469 return AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE; 7470 } 7471 7472 /** 7473 * @see AudioManager#isVolumeFixed() 7474 * Note there are no permission checks on this operation, as this is part of API 21 7475 * @return true if the current device's volume behavior for media is 7476 * DEVICE_VOLUME_BEHAVIOR_FIXED 7477 */ isVolumeFixed()7478 public boolean isVolumeFixed() { 7479 if (mUseFixedVolume) { 7480 return true; 7481 } 7482 final AudioAttributes attributes = new AudioAttributes.Builder() 7483 .setUsage(AudioAttributes.USAGE_MEDIA) 7484 .build(); 7485 // calling getDevice*Int to bypass permission check 7486 final List<AudioDeviceAttributes> devices = 7487 getDevicesForAttributesInt(attributes, true /* forVolume */); 7488 for (AudioDeviceAttributes device : devices) { 7489 if (getDeviceVolumeBehaviorInt(device) == AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED) { 7490 return true; 7491 } 7492 } 7493 return false; 7494 } 7495 7496 /*package*/ static final int CONNECTION_STATE_DISCONNECTED = 0; 7497 /*package*/ static final int CONNECTION_STATE_CONNECTED = 1; 7498 /** 7499 * The states that can be used with AudioService.setWiredDeviceConnectionState() 7500 * Attention: those values differ from those in BluetoothProfile, follow annotations to 7501 * distinguish between @ConnectionState and @BtProfileConnectionState 7502 */ 7503 @IntDef({ 7504 CONNECTION_STATE_DISCONNECTED, 7505 CONNECTION_STATE_CONNECTED, 7506 }) 7507 @Retention(RetentionPolicy.SOURCE) 7508 public @interface ConnectionState {} 7509 7510 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 7511 /** 7512 * see AudioManager.setWiredDeviceConnectionState() 7513 */ setWiredDeviceConnectionState(@onNull AudioDeviceAttributes attributes, @ConnectionState int state, String caller)7514 public void setWiredDeviceConnectionState(@NonNull AudioDeviceAttributes attributes, 7515 @ConnectionState int state, String caller) { 7516 super.setWiredDeviceConnectionState_enforcePermission(); 7517 Objects.requireNonNull(attributes); 7518 7519 attributes = retrieveBluetoothAddress(attributes); 7520 7521 if (state != CONNECTION_STATE_CONNECTED 7522 && state != CONNECTION_STATE_DISCONNECTED) { 7523 throw new IllegalArgumentException("Invalid state " + state); 7524 } 7525 new MediaMetrics.Item(mMetricsId + "setWiredDeviceConnectionState") 7526 .set(MediaMetrics.Property.ADDRESS, attributes.getAddress()) 7527 .set(MediaMetrics.Property.CLIENT_NAME, caller) 7528 .set(MediaMetrics.Property.DEVICE, 7529 AudioSystem.getDeviceName(attributes.getInternalType())) 7530 .set(MediaMetrics.Property.NAME, attributes.getName()) 7531 .set(MediaMetrics.Property.STATE, 7532 state == CONNECTION_STATE_CONNECTED ? "connected" : "disconnected") 7533 .record(); 7534 mDeviceBroker.setWiredDeviceConnectionState(attributes, state, caller); 7535 // The Dynamic Soundbar mode feature introduces dynamic presence for an HDMI Audio System 7536 // Client. For example, the device can start with the Audio System Client unavailable. 7537 // When the feature is activated the client becomes available, therefore Audio Service 7538 // requests a new HDMI Audio System Client instance when the ARC status is changed. 7539 if (attributes.getInternalType() == AudioSystem.DEVICE_IN_HDMI_ARC) { 7540 updateHdmiAudioSystemClient(); 7541 } 7542 } 7543 7544 /** 7545 * Replace the current HDMI Audio System Client. 7546 * See {@link #setWiredDeviceConnectionState(AudioDeviceAttributes, int, String)}. 7547 */ updateHdmiAudioSystemClient()7548 private void updateHdmiAudioSystemClient() { 7549 Slog.d(TAG, "Hdmi Audio System Client is updated"); 7550 synchronized (mHdmiClientLock) { 7551 mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient(); 7552 } 7553 } 7554 7555 /** @see AudioManager#setTestDeviceConnectionState(AudioDeviceAttributes, boolean) */ setTestDeviceConnectionState(@onNull AudioDeviceAttributes device, boolean connected)7556 public void setTestDeviceConnectionState(@NonNull AudioDeviceAttributes device, 7557 boolean connected) { 7558 Objects.requireNonNull(device); 7559 enforceModifyAudioRoutingPermission(); 7560 7561 device = retrieveBluetoothAddress(device); 7562 7563 mDeviceBroker.setTestDeviceConnectionState(device, 7564 connected ? CONNECTION_STATE_CONNECTED : CONNECTION_STATE_DISCONNECTED); 7565 // simulate a routing update from native 7566 sendMsg(mAudioHandler, 7567 MSG_ROUTING_UPDATED, 7568 SENDMSG_REPLACE, 0, 0, null, 7569 /*delay*/ 0); 7570 } 7571 7572 /** 7573 * @hide 7574 * The states that can be used with AudioService.setBluetoothHearingAidDeviceConnectionState() 7575 * and AudioService.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent() 7576 */ 7577 @IntDef({ 7578 BluetoothProfile.STATE_DISCONNECTED, 7579 BluetoothProfile.STATE_CONNECTED, 7580 }) 7581 @Retention(RetentionPolicy.SOURCE) 7582 public @interface BtProfileConnectionState {} 7583 7584 /** 7585 * @hide 7586 * The profiles that can be used with AudioService.handleBluetoothActiveDeviceChanged() 7587 */ 7588 @IntDef({ 7589 BluetoothProfile.HEARING_AID, 7590 BluetoothProfile.A2DP, 7591 BluetoothProfile.A2DP_SINK, 7592 BluetoothProfile.LE_AUDIO, 7593 BluetoothProfile.LE_AUDIO_BROADCAST, 7594 }) 7595 @Retention(RetentionPolicy.SOURCE) 7596 public @interface BtProfile {} 7597 7598 7599 /** 7600 * See AudioManager.handleBluetoothActiveDeviceChanged(...) 7601 */ handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice, BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info)7602 public void handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice, 7603 BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info) { 7604 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.BLUETOOTH_STACK) 7605 != PackageManager.PERMISSION_GRANTED) { 7606 throw new SecurityException("Bluetooth is the only caller allowed"); 7607 } 7608 if (info == null) { 7609 throw new IllegalArgumentException("Illegal null BluetoothProfileConnectionInfo for" 7610 + " device " + previousDevice + " -> " + newDevice); 7611 } 7612 final int profile = info.getProfile(); 7613 if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK 7614 && profile != BluetoothProfile.LE_AUDIO 7615 && profile != BluetoothProfile.LE_AUDIO_BROADCAST 7616 && profile != BluetoothProfile.HEARING_AID) { 7617 throw new IllegalArgumentException("Illegal BluetoothProfile profile for device " 7618 + previousDevice + " -> " + newDevice + ". Got: " + profile); 7619 } 7620 7621 sDeviceLogger.enqueue(new EventLogger.StringEvent("BlutoothActiveDeviceChanged for " 7622 + BluetoothProfile.getProfileName(profile) + ", device update " + previousDevice 7623 + " -> " + newDevice)); 7624 AudioDeviceBroker.BtDeviceChangedData data = 7625 new AudioDeviceBroker.BtDeviceChangedData(newDevice, previousDevice, info, 7626 "AudioService"); 7627 sendMsg(mAudioHandler, MSG_BT_DEV_CHANGED, SENDMSG_QUEUE, 0, 0, 7628 /*obj*/ data, /*delay*/ 0); 7629 } 7630 7631 /** only public for mocking/spying, do not call outside of AudioService */ 7632 @VisibleForTesting setMusicMute(boolean mute)7633 public void setMusicMute(boolean mute) { 7634 mStreamStates[AudioSystem.STREAM_MUSIC].muteInternally(mute); 7635 } 7636 7637 private static final Set<Integer> DEVICE_MEDIA_UNMUTED_ON_PLUG_SET; 7638 static { 7639 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET = new HashSet<>(); 7640 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADSET); 7641 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE); 7642 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_LINE); 7643 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_A2DP_SET); 7644 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_BLE_SET); 7645 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_USB_SET); 7646 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_HDMI); 7647 } 7648 7649 /** only public for mocking/spying, do not call outside of AudioService */ 7650 @VisibleForTesting postAccessoryPlugMediaUnmute(int newDevice)7651 public void postAccessoryPlugMediaUnmute(int newDevice) { 7652 sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE, 7653 newDevice, 0, null, 0); 7654 } 7655 onAccessoryPlugMediaUnmute(int newDevice)7656 private void onAccessoryPlugMediaUnmute(int newDevice) { 7657 if (DEBUG_VOL) { 7658 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute newDevice=%d [%s]", 7659 newDevice, AudioSystem.getOutputDeviceName(newDevice))); 7660 } 7661 7662 if (mNm.getZenMode() != Settings.Global.ZEN_MODE_NO_INTERRUPTIONS 7663 && !isStreamMutedByRingerOrZenMode(AudioSystem.STREAM_MUSIC) 7664 && DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.contains(newDevice) 7665 && mStreamStates[AudioSystem.STREAM_MUSIC].mIsMuted 7666 && mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(newDevice) != 0 7667 && getDeviceSetForStreamDirect(AudioSystem.STREAM_MUSIC).contains(newDevice)) { 7668 if (DEBUG_VOL) { 7669 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute unmuting device=%d [%s]", 7670 newDevice, AudioSystem.getOutputDeviceName(newDevice))); 7671 } 7672 // Locking mSettingsLock to avoid inversion when calling vss.mute -> vss.doMute -> 7673 // vss.updateVolumeGroupIndex 7674 synchronized (mSettingsLock) { 7675 mStreamStates[AudioSystem.STREAM_MUSIC].mute(false, "onAccessoryPlugMediaUnmute"); 7676 } 7677 } 7678 } 7679 7680 /** 7681 * See AudioManager.hasHapticChannels(Context, Uri). 7682 */ hasHapticChannels(Uri uri)7683 public boolean hasHapticChannels(Uri uri) { 7684 return AudioManager.hasHapticChannelsImpl(mContext, uri); 7685 } 7686 7687 /////////////////////////////////////////////////////////////////////////// 7688 // Inner classes 7689 /////////////////////////////////////////////////////////////////////////// 7690 /** 7691 * Key is the AudioManager VolumeGroupId 7692 * Value is the VolumeGroupState 7693 */ 7694 private static final SparseArray<VolumeGroupState> sVolumeGroupStates = new SparseArray<>(); 7695 initVolumeGroupStates()7696 private void initVolumeGroupStates() { 7697 for (final AudioVolumeGroup avg : getAudioVolumeGroups()) { 7698 try { 7699 // if no valid attributes, this volume group is not controllable, throw exception 7700 ensureValidAttributes(avg); 7701 sVolumeGroupStates.append(avg.getId(), new VolumeGroupState(avg)); 7702 } catch (IllegalArgumentException e) { 7703 // Volume Groups without attributes are not controllable through set/get volume 7704 // using attributes. Do not append them. 7705 if (DEBUG_VOL) { 7706 Log.d(TAG, "volume group " + avg.name() + " for internal policy needs"); 7707 } 7708 continue; 7709 } 7710 } 7711 7712 // need mSettingsLock for vgs.applyAllVolumes -> vss.setIndex which grabs this lock after 7713 // VSS.class. Locking order needs to be preserved 7714 synchronized (mSettingsLock) { 7715 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 7716 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 7717 vgs.applyAllVolumes(/* userSwitch= */ false); 7718 } 7719 } 7720 } 7721 ensureValidAttributes(AudioVolumeGroup avg)7722 private void ensureValidAttributes(AudioVolumeGroup avg) { 7723 boolean hasAtLeastOneValidAudioAttributes = avg.getAudioAttributes().stream() 7724 .anyMatch(aa -> !aa.equals(AudioProductStrategy.getDefaultAttributes())); 7725 if (!hasAtLeastOneValidAudioAttributes) { 7726 throw new IllegalArgumentException("Volume Group " + avg.name() 7727 + " has no valid audio attributes"); 7728 } 7729 } 7730 readVolumeGroupsSettings(boolean userSwitch)7731 private void readVolumeGroupsSettings(boolean userSwitch) { 7732 synchronized (mSettingsLock) { 7733 synchronized (VolumeStreamState.class) { 7734 if (DEBUG_VOL) { 7735 Log.d(TAG, "readVolumeGroupsSettings userSwitch=" + userSwitch); 7736 } 7737 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 7738 VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 7739 // as for STREAM_MUSIC, preserve volume from one user to the next. 7740 if (!(userSwitch && vgs.isMusic())) { 7741 vgs.clearIndexCache(); 7742 vgs.readSettings(); 7743 } 7744 vgs.applyAllVolumes(userSwitch); 7745 } 7746 } 7747 } 7748 } 7749 7750 // Called upon crash of AudioServer restoreVolumeGroups()7751 private void restoreVolumeGroups() { 7752 if (DEBUG_VOL) { 7753 Log.v(TAG, "restoreVolumeGroups"); 7754 } 7755 7756 // need mSettingsLock for vgs.applyAllVolumes -> vss.setIndex which grabs this lock after 7757 // VSS.class. Locking order needs to be preserved 7758 synchronized (mSettingsLock) { 7759 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 7760 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 7761 vgs.applyAllVolumes(false/*userSwitch*/); 7762 } 7763 } 7764 } 7765 dumpVolumeGroups(PrintWriter pw)7766 private void dumpVolumeGroups(PrintWriter pw) { 7767 pw.println("\nVolume Groups (device: index)"); 7768 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 7769 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 7770 vgs.dump(pw); 7771 pw.println(""); 7772 } 7773 } 7774 isCallStream(int stream)7775 private static boolean isCallStream(int stream) { 7776 return stream == AudioSystem.STREAM_VOICE_CALL 7777 || stream == AudioSystem.STREAM_BLUETOOTH_SCO; 7778 } 7779 getVolumeGroupForStreamType(int stream)7780 private static int getVolumeGroupForStreamType(int stream) { 7781 AudioAttributes attributes = 7782 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream); 7783 if (attributes.equals(new AudioAttributes.Builder().build())) { 7784 return AudioVolumeGroup.DEFAULT_VOLUME_GROUP; 7785 } 7786 return AudioProductStrategy.getVolumeGroupIdForAudioAttributes( 7787 attributes, /* fallbackOnDefault= */ false); 7788 } 7789 7790 // NOTE: Locking order for synchronized objects related to volume management: 7791 // 1 mSettingsLock 7792 // 2 VolumeStreamState.class 7793 private class VolumeGroupState { 7794 private final AudioVolumeGroup mAudioVolumeGroup; 7795 private final SparseIntArray mIndexMap = new SparseIntArray(8); 7796 private int mIndexMin; 7797 private int mIndexMax; 7798 private boolean mHasValidStreamType = false; 7799 private int mPublicStreamType = AudioSystem.STREAM_MUSIC; 7800 private AudioAttributes mAudioAttributes = AudioProductStrategy.getDefaultAttributes(); 7801 private boolean mIsMuted = false; 7802 private String mSettingName; 7803 7804 // No API in AudioSystem to get a device from strategy or from attributes. 7805 // Need a valid public stream type to use current API getDeviceForStream getDeviceForVolume()7806 private int getDeviceForVolume() { 7807 return getDeviceForStream(mPublicStreamType); 7808 } 7809 VolumeGroupState(AudioVolumeGroup avg)7810 private VolumeGroupState(AudioVolumeGroup avg) { 7811 mAudioVolumeGroup = avg; 7812 if (DEBUG_VOL) { 7813 Log.v(TAG, "VolumeGroupState for " + avg.toString()); 7814 } 7815 // mAudioAttributes is the default at this point 7816 for (AudioAttributes aa : avg.getAudioAttributes()) { 7817 if (!aa.equals(mAudioAttributes)) { 7818 mAudioAttributes = aa; 7819 break; 7820 } 7821 } 7822 int[] streamTypes = mAudioVolumeGroup.getLegacyStreamTypes(); 7823 String streamSettingName = ""; 7824 if (streamTypes.length != 0) { 7825 // Uses already initialized MIN / MAX if a stream type is attached to group 7826 for (int streamType : streamTypes) { 7827 if (streamType != AudioSystem.STREAM_DEFAULT 7828 && streamType < AudioSystem.getNumStreamTypes()) { 7829 mPublicStreamType = streamType; 7830 mHasValidStreamType = true; 7831 streamSettingName = System.VOLUME_SETTINGS_INT[mPublicStreamType]; 7832 break; 7833 } 7834 } 7835 mIndexMin = MIN_STREAM_VOLUME[mPublicStreamType]; 7836 mIndexMax = MAX_STREAM_VOLUME[mPublicStreamType]; 7837 } else if (!avg.getAudioAttributes().isEmpty()) { 7838 mIndexMin = AudioSystem.getMinVolumeIndexForAttributes(mAudioAttributes); 7839 mIndexMax = AudioSystem.getMaxVolumeIndexForAttributes(mAudioAttributes); 7840 } else { 7841 throw new IllegalArgumentException("volume group: " + mAudioVolumeGroup.name() 7842 + " has neither valid attributes nor valid stream types assigned"); 7843 } 7844 mSettingName = !streamSettingName.isEmpty() ? streamSettingName : ("volume_" + name()); 7845 // Load volume indexes from data base 7846 readSettings(); 7847 } 7848 getLegacyStreamTypes()7849 public @NonNull int[] getLegacyStreamTypes() { 7850 return mAudioVolumeGroup.getLegacyStreamTypes(); 7851 } 7852 name()7853 public String name() { 7854 return mAudioVolumeGroup.name(); 7855 } 7856 7857 /** 7858 * Volume group with non null minimum index are considered as non mutable, thus 7859 * bijectivity is broken with potential associated stream type. 7860 * VOICE_CALL stream has minVolumeIndex > 0 but can be muted directly by an 7861 * app that has MODIFY_PHONE_STATE permission. 7862 */ isVssMuteBijective(int stream)7863 private boolean isVssMuteBijective(int stream) { 7864 return isStreamAffectedByMute(stream) 7865 && (getMinIndex() == (mStreamStates[stream].mIndexMin + 5) / 10) 7866 && (getMinIndex() == 0 || isCallStream(stream)); 7867 } 7868 isMutable()7869 private boolean isMutable() { 7870 return mIndexMin == 0 || (mHasValidStreamType && isVssMuteBijective(mPublicStreamType)); 7871 } 7872 /** 7873 * Mute/unmute the volume group 7874 * @param muted the new mute state 7875 */ 7876 @GuardedBy("AudioService.VolumeStreamState.class") mute(boolean muted)7877 public boolean mute(boolean muted) { 7878 if (!isMutable()) { 7879 // Non mutable volume group 7880 if (DEBUG_VOL) { 7881 Log.d(TAG, "invalid mute on unmutable volume group " + name()); 7882 } 7883 return false; 7884 } 7885 boolean changed = (mIsMuted != muted); 7886 // As for VSS, mute shall apply minIndex to all devices found in IndexMap and default. 7887 if (changed) { 7888 mIsMuted = muted; 7889 applyAllVolumes(false /*userSwitch*/); 7890 } 7891 return changed; 7892 } 7893 isMuted()7894 public boolean isMuted() { 7895 return mIsMuted; 7896 } 7897 adjustVolume(int direction, int flags)7898 public void adjustVolume(int direction, int flags) { 7899 synchronized (mSettingsLock) { 7900 synchronized (AudioService.VolumeStreamState.class) { 7901 int device = getDeviceForVolume(); 7902 int previousIndex = getIndex(device); 7903 if (isMuteAdjust(direction) && !isMutable()) { 7904 // Non mutable volume group 7905 if (DEBUG_VOL) { 7906 Log.d(TAG, "invalid mute on unmutable volume group " + name()); 7907 } 7908 return; 7909 } 7910 switch (direction) { 7911 case AudioManager.ADJUST_TOGGLE_MUTE: { 7912 // Note: If muted by volume 0, unmute will restore volume 0. 7913 mute(!mIsMuted); 7914 break; 7915 } 7916 case AudioManager.ADJUST_UNMUTE: 7917 // Note: If muted by volume 0, unmute will restore volume 0. 7918 mute(false); 7919 break; 7920 case AudioManager.ADJUST_MUTE: 7921 // May be already muted by setvolume 0, prevent from setting same value 7922 if (previousIndex != 0) { 7923 // bypass persist 7924 mute(true); 7925 } 7926 mIsMuted = true; 7927 break; 7928 case AudioManager.ADJUST_RAISE: 7929 // As for stream, RAISE during mute will increment the index 7930 setVolumeIndex(Math.min(previousIndex + 1, mIndexMax), device, flags); 7931 break; 7932 case AudioManager.ADJUST_LOWER: 7933 // For stream, ADJUST_LOWER on a muted VSS is a no-op 7934 // If we decide to unmute on ADJUST_LOWER, cannot fallback on 7935 // adjustStreamVolume for group associated to legacy stream type 7936 if (isMuted() && previousIndex != 0) { 7937 mute(false); 7938 } else { 7939 int newIndex = Math.max(previousIndex - 1, mIndexMin); 7940 setVolumeIndex(newIndex, device, flags); 7941 } 7942 break; 7943 } 7944 } 7945 } 7946 } 7947 getVolumeIndex()7948 public int getVolumeIndex() { 7949 synchronized (AudioService.VolumeStreamState.class) { 7950 return getIndex(getDeviceForVolume()); 7951 } 7952 } 7953 setVolumeIndex(int index, int flags)7954 public void setVolumeIndex(int index, int flags) { 7955 synchronized (mSettingsLock) { 7956 synchronized (AudioService.VolumeStreamState.class) { 7957 if (mUseFixedVolume) { 7958 return; 7959 } 7960 setVolumeIndex(index, getDeviceForVolume(), flags); 7961 } 7962 } 7963 } 7964 7965 @GuardedBy("AudioService.VolumeStreamState.class") setVolumeIndex(int index, int device, int flags)7966 private void setVolumeIndex(int index, int device, int flags) { 7967 // Update cache & persist (muted by volume 0 shall be persisted) 7968 updateVolumeIndex(index, device); 7969 // setting non-zero volume for a muted stream unmutes the stream and vice versa, 7970 boolean changed = mute(index == 0); 7971 if (!changed) { 7972 // Set the volume index only if mute operation is a no-op 7973 index = getValidIndex(index); 7974 setVolumeIndexInt(index, device, flags); 7975 } 7976 } 7977 7978 @GuardedBy("AudioService.VolumeStreamState.class") updateVolumeIndex(int index, int device)7979 public void updateVolumeIndex(int index, int device) { 7980 // Filter persistency if already exist and the index has not changed 7981 if (mIndexMap.indexOfKey(device) < 0 || mIndexMap.get(device) != index) { 7982 // Update local cache 7983 mIndexMap.put(device, getValidIndex(index)); 7984 7985 // update data base - post a persist volume group msg 7986 sendMsg(mAudioHandler, 7987 MSG_PERSIST_VOLUME_GROUP, 7988 SENDMSG_QUEUE, 7989 device, 7990 0, 7991 this, 7992 PERSIST_DELAY); 7993 } 7994 } 7995 7996 @GuardedBy("AudioService.VolumeStreamState.class") setVolumeIndexInt(int index, int device, int flags)7997 private void setVolumeIndexInt(int index, int device, int flags) { 7998 // Reflect mute state of corresponding stream by forcing index to 0 if muted 7999 // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted. 8000 // This allows RX path muting by the audio HAL only when explicitly muted but not when 8001 // index is just set to 0 to repect BT requirements 8002 if (mHasValidStreamType && isVssMuteBijective(mPublicStreamType) 8003 && mStreamStates[mPublicStreamType].isFullyMuted()) { 8004 index = 0; 8005 } else if (mPublicStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0) { 8006 index = 1; 8007 } 8008 // Set the volume index 8009 AudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, device); 8010 } 8011 8012 @GuardedBy("AudioService.VolumeStreamState.class") getIndex(int device)8013 private int getIndex(int device) { 8014 int index = mIndexMap.get(device, -1); 8015 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT 8016 return (index != -1) ? index : mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); 8017 } 8018 8019 @GuardedBy("AudioService.VolumeStreamState.class") hasIndexForDevice(int device)8020 private boolean hasIndexForDevice(int device) { 8021 return (mIndexMap.get(device, -1) != -1); 8022 } 8023 getMaxIndex()8024 public int getMaxIndex() { 8025 return mIndexMax; 8026 } 8027 getMinIndex()8028 public int getMinIndex() { 8029 return mIndexMin; 8030 } 8031 isValidStream(int stream)8032 private boolean isValidStream(int stream) { 8033 return (stream != AudioSystem.STREAM_DEFAULT) && (stream < mStreamStates.length); 8034 } 8035 isMusic()8036 public boolean isMusic() { 8037 return mHasValidStreamType && mPublicStreamType == AudioSystem.STREAM_MUSIC; 8038 } 8039 applyAllVolumes(boolean userSwitch)8040 public void applyAllVolumes(boolean userSwitch) { 8041 String caller = "from vgs"; 8042 synchronized (AudioService.VolumeStreamState.class) { 8043 // apply device specific volumes first 8044 for (int i = 0; i < mIndexMap.size(); i++) { 8045 int device = mIndexMap.keyAt(i); 8046 int index = mIndexMap.valueAt(i); 8047 boolean synced = false; 8048 if (device != AudioSystem.DEVICE_OUT_DEFAULT) { 8049 for (int stream : getLegacyStreamTypes()) { 8050 if (isValidStream(stream)) { 8051 boolean streamMuted = mStreamStates[stream].mIsMuted; 8052 int deviceForStream = getDeviceForStream(stream); 8053 int indexForStream = 8054 (mStreamStates[stream].getIndex(deviceForStream) + 5) / 10; 8055 if (device == deviceForStream) { 8056 if (indexForStream == index && (isMuted() == streamMuted) 8057 && isVssMuteBijective(stream)) { 8058 synced = true; 8059 continue; 8060 } 8061 if (indexForStream != index) { 8062 mStreamStates[stream].setIndex(index * 10, device, caller, 8063 true /*hasModifyAudioSettings*/); 8064 } 8065 if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) { 8066 mStreamStates[stream].mute(isMuted(), 8067 "VGS.applyAllVolumes#1"); 8068 } 8069 } 8070 } 8071 } 8072 if (!synced) { 8073 if (DEBUG_VOL) { 8074 Log.d(TAG, "applyAllVolumes: apply index " + index + ", group " 8075 + mAudioVolumeGroup.name() + " and device " 8076 + AudioSystem.getOutputDeviceName(device)); 8077 } 8078 setVolumeIndexInt(isMuted() ? 0 : index, device, 0 /*flags*/); 8079 } 8080 } 8081 } 8082 // apply default volume last: by convention , default device volume will be used 8083 // by audio policy manager if no explicit volume is present for a given device type 8084 int index = getIndex(AudioSystem.DEVICE_OUT_DEFAULT); 8085 boolean synced = false; 8086 int deviceForVolume = getDeviceForVolume(); 8087 boolean forceDeviceSync = userSwitch && (mIndexMap.indexOfKey(deviceForVolume) < 0); 8088 for (int stream : getLegacyStreamTypes()) { 8089 if (isValidStream(stream)) { 8090 boolean streamMuted = mStreamStates[stream].mIsMuted; 8091 int defaultStreamIndex = (mStreamStates[stream].getIndex( 8092 AudioSystem.DEVICE_OUT_DEFAULT) + 5) / 10; 8093 if (forceDeviceSync) { 8094 mStreamStates[stream].setIndex(index * 10, deviceForVolume, caller, 8095 true /*hasModifyAudioSettings*/); 8096 } 8097 if (defaultStreamIndex == index && (isMuted() == streamMuted) 8098 && isVssMuteBijective(stream)) { 8099 synced = true; 8100 continue; 8101 } 8102 if (defaultStreamIndex != index) { 8103 mStreamStates[stream].setIndex( 8104 index * 10, AudioSystem.DEVICE_OUT_DEFAULT, caller, 8105 true /*hasModifyAudioSettings*/); 8106 } 8107 if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) { 8108 mStreamStates[stream].mute(isMuted(), "VGS.applyAllVolumes#2"); 8109 } 8110 } 8111 } 8112 if (!synced) { 8113 if (DEBUG_VOL) { 8114 Log.d(TAG, "applyAllVolumes: apply default device index " + index 8115 + ", group " + mAudioVolumeGroup.name()); 8116 } 8117 setVolumeIndexInt( 8118 isMuted() ? 0 : index, AudioSystem.DEVICE_OUT_DEFAULT, 0 /*flags*/); 8119 } 8120 if (forceDeviceSync) { 8121 if (DEBUG_VOL) { 8122 Log.d(TAG, "applyAllVolumes: forceDeviceSync index " + index 8123 + ", device " + AudioSystem.getOutputDeviceName(deviceForVolume) 8124 + ", group " + mAudioVolumeGroup.name()); 8125 } 8126 setVolumeIndexInt(isMuted() ? 0 : index, deviceForVolume, 0); 8127 } 8128 } 8129 } 8130 clearIndexCache()8131 public void clearIndexCache() { 8132 mIndexMap.clear(); 8133 } 8134 persistVolumeGroup(int device)8135 private void persistVolumeGroup(int device) { 8136 // No need to persist the index if the volume group is backed up 8137 // by a public stream type as this is redundant 8138 if (mUseFixedVolume || mHasValidStreamType) { 8139 return; 8140 } 8141 if (DEBUG_VOL) { 8142 Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) + " for group " 8143 + mAudioVolumeGroup.name() 8144 + ", device " + AudioSystem.getOutputDeviceName(device) 8145 + " and User=" + getCurrentUserId() 8146 + " mSettingName: " + mSettingName); 8147 } 8148 8149 boolean success = mSettings.putSystemIntForUser(mContentResolver, 8150 getSettingNameForDevice(device), 8151 getIndex(device), 8152 isMusic() ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT); 8153 if (!success) { 8154 Log.e(TAG, "persistVolumeGroup failed for group " + mAudioVolumeGroup.name()); 8155 } 8156 } 8157 readSettings()8158 public void readSettings() { 8159 synchronized (AudioService.VolumeStreamState.class) { 8160 // force maximum volume on all streams if fixed volume property is set 8161 if (mUseFixedVolume) { 8162 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax); 8163 return; 8164 } 8165 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 8166 // retrieve current volume for device 8167 // if no volume stored for current volume group and device, use default volume 8168 // if default device, continue otherwise 8169 int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) 8170 ? AudioSystem.DEFAULT_STREAM_VOLUME[mPublicStreamType] : -1; 8171 int index; 8172 String name = getSettingNameForDevice(device); 8173 index = mSettings.getSystemIntForUser( 8174 mContentResolver, name, defaultIndex, 8175 isMusic() ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT); 8176 if (index == -1) { 8177 continue; 8178 } 8179 if (mPublicStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED 8180 && mCameraSoundForced) { 8181 index = mIndexMax; 8182 } 8183 if (DEBUG_VOL) { 8184 Log.v(TAG, "readSettings: found stored index " + getValidIndex(index) 8185 + " for group " + mAudioVolumeGroup.name() + ", device: " + name 8186 + ", User=" + getCurrentUserId()); 8187 } 8188 mIndexMap.put(device, getValidIndex(index)); 8189 } 8190 } 8191 } 8192 8193 @GuardedBy("AudioService.VolumeStreamState.class") getValidIndex(int index)8194 private int getValidIndex(int index) { 8195 if (index < mIndexMin) { 8196 return mIndexMin; 8197 } else if (mUseFixedVolume || index > mIndexMax) { 8198 return mIndexMax; 8199 } 8200 return index; 8201 } 8202 getSettingNameForDevice(int device)8203 public @NonNull String getSettingNameForDevice(int device) { 8204 String suffix = AudioSystem.getOutputDeviceName(device); 8205 if (suffix.isEmpty()) { 8206 return mSettingName; 8207 } 8208 return mSettingName + "_" + AudioSystem.getOutputDeviceName(device); 8209 } 8210 setSettingName(String settingName)8211 void setSettingName(String settingName) { 8212 mSettingName = settingName; 8213 } 8214 getSettingName()8215 String getSettingName() { 8216 return mSettingName; 8217 } 8218 dump(PrintWriter pw)8219 private void dump(PrintWriter pw) { 8220 pw.println("- VOLUME GROUP " + mAudioVolumeGroup.name() + ":"); 8221 pw.print(" Muted: "); 8222 pw.println(mIsMuted); 8223 pw.print(" Min: "); 8224 pw.println(mIndexMin); 8225 pw.print(" Max: "); 8226 pw.println(mIndexMax); 8227 pw.print(" Current: "); 8228 for (int i = 0; i < mIndexMap.size(); i++) { 8229 if (i > 0) { 8230 pw.print(", "); 8231 } 8232 int device = mIndexMap.keyAt(i); 8233 pw.print(Integer.toHexString(device)); 8234 String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 8235 : AudioSystem.getOutputDeviceName(device); 8236 if (!deviceName.isEmpty()) { 8237 pw.print(" ("); 8238 pw.print(deviceName); 8239 pw.print(")"); 8240 } 8241 pw.print(": "); 8242 pw.print(mIndexMap.valueAt(i)); 8243 } 8244 pw.println(); 8245 pw.print(" Devices: "); 8246 int n = 0; 8247 int devices = getDeviceForVolume(); 8248 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 8249 if ((devices & device) == device) { 8250 if (n++ > 0) { 8251 pw.print(", "); 8252 } 8253 pw.print(AudioSystem.getOutputDeviceName(device)); 8254 } 8255 } 8256 pw.println(); 8257 pw.print(" Streams: "); 8258 Arrays.stream(getLegacyStreamTypes()) 8259 .forEach(stream -> pw.print(AudioSystem.streamToString(stream) + " ")); 8260 } 8261 } 8262 8263 8264 // NOTE: Locking order for synchronized objects related to volume or ringer mode management: 8265 // 1 mScoclient OR mSafeMediaVolumeState 8266 // 2 mSetModeLock 8267 // 3 mSettingsLock 8268 // 4 VolumeStreamState.class 8269 /*package*/ class VolumeStreamState { 8270 private final int mStreamType; 8271 private VolumeGroupState mVolumeGroupState = null; 8272 private int mIndexMin; 8273 // min index when user doesn't have permission to change audio settings 8274 private int mIndexMinNoPerm; 8275 private int mIndexMax; 8276 8277 private boolean mIsMuted = false; 8278 private boolean mIsMutedInternally = false; 8279 private String mVolumeIndexSettingName; 8280 @NonNull private Set<Integer> mObservedDeviceSet = new TreeSet<>(); 8281 8282 private final SparseIntArray mIndexMap = new SparseIntArray(8) { 8283 @Override 8284 public void put(int key, int value) { 8285 super.put(key, value); 8286 record("put", key, value); 8287 } 8288 @Override 8289 public void setValueAt(int index, int value) { 8290 super.setValueAt(index, value); 8291 record("setValueAt", keyAt(index), value); 8292 } 8293 8294 // Record all changes in the VolumeStreamState 8295 private void record(String event, int key, int value) { 8296 final String device = key == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 8297 : AudioSystem.getOutputDeviceName(key); 8298 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME + MediaMetrics.SEPARATOR 8299 + AudioSystem.streamToString(mStreamType) 8300 + "." + device) 8301 .set(MediaMetrics.Property.EVENT, event) 8302 .set(MediaMetrics.Property.INDEX, value) 8303 .set(MediaMetrics.Property.MIN_INDEX, mIndexMin) 8304 .set(MediaMetrics.Property.MAX_INDEX, mIndexMax) 8305 .record(); 8306 } 8307 }; 8308 private final Intent mVolumeChanged; 8309 private final Bundle mVolumeChangedOptions; 8310 private final Intent mStreamDevicesChanged; 8311 private final Bundle mStreamDevicesChangedOptions; 8312 VolumeStreamState(String settingName, int streamType)8313 private VolumeStreamState(String settingName, int streamType) { 8314 mVolumeIndexSettingName = settingName; 8315 8316 mStreamType = streamType; 8317 mIndexMin = MIN_STREAM_VOLUME[streamType] * 10; 8318 mIndexMinNoPerm = mIndexMin; // may be overwritten later in updateNoPermMinIndex() 8319 mIndexMax = MAX_STREAM_VOLUME[streamType] * 10; 8320 final int status = AudioSystem.initStreamVolume( 8321 streamType, mIndexMin / 10, mIndexMax / 10); 8322 if (status != AudioSystem.AUDIO_STATUS_OK) { 8323 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 8324 "VSS() stream:" + streamType + " initStreamVolume=" + status) 8325 .printLog(ALOGE, TAG)); 8326 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 8327 "VSS()" /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 8328 } 8329 8330 readSettings(); 8331 mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION); 8332 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 8333 final BroadcastOptions volumeChangedOptions = BroadcastOptions.makeBasic(); 8334 // This allows us to discard older broadcasts still waiting to be delivered 8335 // which have the same namespace (VOLUME_CHANGED_ACTION) and key (mStreamType). 8336 volumeChangedOptions.setDeliveryGroupPolicy(DELIVERY_GROUP_POLICY_MOST_RECENT); 8337 volumeChangedOptions.setDeliveryGroupMatchingKey( 8338 AudioManager.VOLUME_CHANGED_ACTION, String.valueOf(mStreamType)); 8339 volumeChangedOptions.setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE); 8340 mVolumeChangedOptions = volumeChangedOptions.toBundle(); 8341 8342 mStreamDevicesChanged = new Intent(AudioManager.STREAM_DEVICES_CHANGED_ACTION); 8343 mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 8344 final BroadcastOptions streamDevicesChangedOptions = BroadcastOptions.makeBasic(); 8345 streamDevicesChangedOptions.setDeliveryGroupPolicy(DELIVERY_GROUP_POLICY_MOST_RECENT); 8346 streamDevicesChangedOptions.setDeliveryGroupMatchingKey( 8347 AudioManager.STREAM_DEVICES_CHANGED_ACTION, String.valueOf(mStreamType)); 8348 streamDevicesChangedOptions.setDeferralPolicy( 8349 BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE); 8350 mStreamDevicesChangedOptions = streamDevicesChangedOptions.toBundle(); 8351 } 8352 8353 /** 8354 * Associate a {@link volumeGroupState} on the {@link VolumeStreamState}. 8355 * <p> It helps to synchronize the index, mute attributes on the maching 8356 * {@link volumeGroupState} 8357 * @param volumeGroupState matching the {@link VolumeStreamState} 8358 */ setVolumeGroupState(VolumeGroupState volumeGroupState)8359 public void setVolumeGroupState(VolumeGroupState volumeGroupState) { 8360 mVolumeGroupState = volumeGroupState; 8361 if (mVolumeGroupState != null) { 8362 mVolumeGroupState.setSettingName(mVolumeIndexSettingName); 8363 } 8364 } 8365 /** 8366 * Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission 8367 * @param index minimum index expressed in "UI units", i.e. no 10x factor 8368 */ updateNoPermMinIndex(int index)8369 public void updateNoPermMinIndex(int index) { 8370 mIndexMinNoPerm = index * 10; 8371 if (mIndexMinNoPerm < mIndexMin) { 8372 Log.e(TAG, "Invalid mIndexMinNoPerm for stream " + mStreamType); 8373 mIndexMinNoPerm = mIndexMin; 8374 } 8375 } 8376 8377 /** 8378 * Returns a list of devices associated with the stream type. 8379 * 8380 * This is a reference to the local list, do not modify. 8381 */ 8382 @GuardedBy("VolumeStreamState.class") 8383 @NonNull observeDevicesForStream_syncVSS( boolean checkOthers)8384 public Set<Integer> observeDevicesForStream_syncVSS( 8385 boolean checkOthers) { 8386 if (!mSystemServer.isPrivileged()) { 8387 return new TreeSet<Integer>(); 8388 } 8389 final Set<Integer> deviceSet = 8390 getDeviceSetForStreamDirect(mStreamType); 8391 if (deviceSet.equals(mObservedDeviceSet)) { 8392 return mObservedDeviceSet; 8393 } 8394 8395 // Use legacy bit masks for message signalling. 8396 // TODO(b/185386781): message needs update since it uses devices bit-mask. 8397 final int devices = AudioSystem.getDeviceMaskFromSet(deviceSet); 8398 final int prevDevices = AudioSystem.getDeviceMaskFromSet(mObservedDeviceSet); 8399 8400 mObservedDeviceSet = deviceSet; 8401 if (checkOthers) { 8402 // one stream's devices have changed, check the others 8403 postObserveDevicesForAllStreams(mStreamType); 8404 } 8405 // log base stream changes to the event log 8406 if (mStreamVolumeAlias[mStreamType] == mStreamType) { 8407 EventLogTags.writeStreamDevicesChanged(mStreamType, prevDevices, devices); 8408 } 8409 // send STREAM_DEVICES_CHANGED_ACTION on the message handler so it is scheduled after 8410 // the postObserveDevicesForStreams is handled 8411 final SomeArgs args = SomeArgs.obtain(); 8412 args.arg1 = mStreamDevicesChanged; 8413 args.arg2 = mStreamDevicesChangedOptions; 8414 sendMsg(mAudioHandler, 8415 MSG_STREAM_DEVICES_CHANGED, 8416 SENDMSG_QUEUE, prevDevices /*arg1*/, devices /*arg2*/, 8417 // ok to send reference to this object, it is final 8418 args /*obj*/, 0 /*delay*/); 8419 return mObservedDeviceSet; 8420 } 8421 getSettingNameForDevice(int device)8422 public @Nullable String getSettingNameForDevice(int device) { 8423 if (!hasValidSettingsName()) { 8424 return null; 8425 } 8426 final String suffix = AudioSystem.getOutputDeviceName(device); 8427 if (suffix.isEmpty()) { 8428 return mVolumeIndexSettingName; 8429 } 8430 return mVolumeIndexSettingName + "_" + suffix; 8431 } 8432 hasValidSettingsName()8433 private boolean hasValidSettingsName() { 8434 return (mVolumeIndexSettingName != null && !mVolumeIndexSettingName.isEmpty()); 8435 } 8436 setSettingName(String settingName)8437 void setSettingName(String settingName) { 8438 mVolumeIndexSettingName = settingName; 8439 if (mVolumeGroupState != null) { 8440 mVolumeGroupState.setSettingName(mVolumeIndexSettingName); 8441 } 8442 } 8443 getSettingName()8444 String getSettingName() { 8445 return mVolumeIndexSettingName; 8446 } 8447 readSettings()8448 public void readSettings() { 8449 synchronized (mSettingsLock) { 8450 synchronized (VolumeStreamState.class) { 8451 // force maximum volume on all streams if fixed volume property is set 8452 if (mUseFixedVolume) { 8453 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax); 8454 return; 8455 } 8456 // do not read system stream volume from settings: this stream is always aliased 8457 // to another stream type and its volume is never persisted. Values in settings can 8458 // only be stale values 8459 if ((mStreamType == AudioSystem.STREAM_SYSTEM) || 8460 (mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)) { 8461 int index = 10 * AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType]; 8462 if (mCameraSoundForced) { 8463 index = mIndexMax; 8464 } 8465 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, index); 8466 return; 8467 } 8468 } 8469 } 8470 synchronized (VolumeStreamState.class) { 8471 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 8472 8473 // retrieve current volume for device 8474 // if no volume stored for current stream and device, use default volume if default 8475 // device, continue otherwise 8476 int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ? 8477 AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType] : -1; 8478 int index; 8479 if (!hasValidSettingsName()) { 8480 index = defaultIndex; 8481 } else { 8482 String name = getSettingNameForDevice(device); 8483 index = mSettings.getSystemIntForUser( 8484 mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT); 8485 } 8486 if (index == -1) { 8487 continue; 8488 } 8489 8490 mIndexMap.put(device, getValidIndex(10 * index, 8491 true /*hasModifyAudioSettings*/)); 8492 } 8493 } 8494 } 8495 getAbsoluteVolumeIndex(int index)8496 private int getAbsoluteVolumeIndex(int index) { 8497 /* Special handling for Bluetooth Absolute Volume scenario 8498 * If we send full audio gain, some accessories are too loud even at its lowest 8499 * volume. We are not able to enumerate all such accessories, so here is the 8500 * workaround from phone side. 8501 * Pre-scale volume at lowest volume steps 1 2 and 3. 8502 * For volume step 0, set audio gain to 0 as some accessories won't mute on their end. 8503 */ 8504 if (index == 0) { 8505 // 0% for volume 0 8506 index = 0; 8507 } else if (index > 0 && index <= 3) { 8508 // Pre-scale for volume steps 1 2 and 3 8509 index = (int) (mIndexMax * mPrescaleAbsoluteVolume[index - 1]) / 10; 8510 } else { 8511 // otherwise, full gain 8512 index = (mIndexMax + 5) / 10; 8513 } 8514 return index; 8515 } 8516 setStreamVolumeIndex(int index, int device)8517 private void setStreamVolumeIndex(int index, int device) { 8518 // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted. 8519 // This allows RX path muting by the audio HAL only when explicitly muted but not when 8520 // index is just set to 0 to repect BT requirements 8521 if (mStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0 8522 && !isFullyMuted()) { 8523 index = 1; 8524 } 8525 mAudioSystem.setStreamVolumeIndexAS(mStreamType, index, device); 8526 } 8527 8528 // must be called while synchronized VolumeStreamState.class applyDeviceVolume_syncVSS(int device)8529 /*package*/ void applyDeviceVolume_syncVSS(int device) { 8530 int index; 8531 if (isFullyMuted()) { 8532 index = 0; 8533 } else if (isAbsoluteVolumeDevice(device) 8534 || isA2dpAbsoluteVolumeDevice(device) 8535 || AudioSystem.isLeAudioDeviceType(device)) { 8536 index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10); 8537 } else if (isFullVolumeDevice(device)) { 8538 index = (mIndexMax + 5)/10; 8539 } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 8540 index = (mIndexMax + 5)/10; 8541 } else { 8542 index = (getIndex(device) + 5)/10; 8543 } 8544 setStreamVolumeIndex(index, device); 8545 } 8546 applyAllVolumes()8547 public void applyAllVolumes() { 8548 synchronized (VolumeStreamState.class) { 8549 // apply device specific volumes first 8550 int index; 8551 boolean isAbsoluteVolume = false; 8552 for (int i = 0; i < mIndexMap.size(); i++) { 8553 final int device = mIndexMap.keyAt(i); 8554 if (device != AudioSystem.DEVICE_OUT_DEFAULT) { 8555 if (isFullyMuted()) { 8556 index = 0; 8557 } else if (isAbsoluteVolumeDevice(device) 8558 || isA2dpAbsoluteVolumeDevice(device) 8559 || AudioSystem.isLeAudioDeviceType(device)) { 8560 isAbsoluteVolume = true; 8561 index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10); 8562 } else if (isFullVolumeDevice(device)) { 8563 index = (mIndexMax + 5)/10; 8564 } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 8565 index = (mIndexMax + 5)/10; 8566 } else { 8567 index = (mIndexMap.valueAt(i) + 5)/10; 8568 } 8569 8570 sendMsg(mAudioHandler, SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION, 8571 SENDMSG_REPLACE, device, isAbsoluteVolume ? 1 : 0, this, 8572 /*delay=*/0); 8573 8574 setStreamVolumeIndex(index, device); 8575 } 8576 } 8577 // apply default volume last: by convention , default device volume will be used 8578 // by audio policy manager if no explicit volume is present for a given device type 8579 if (isFullyMuted()) { 8580 index = 0; 8581 } else { 8582 index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10; 8583 } 8584 setStreamVolumeIndex(index, AudioSystem.DEVICE_OUT_DEFAULT); 8585 } 8586 } 8587 adjustIndex(int deltaIndex, int device, String caller, boolean hasModifyAudioSettings)8588 public boolean adjustIndex(int deltaIndex, int device, String caller, 8589 boolean hasModifyAudioSettings) { 8590 return setIndex(getIndex(device) + deltaIndex, device, caller, 8591 hasModifyAudioSettings); 8592 } 8593 setIndex(int index, int device, String caller, boolean hasModifyAudioSettings)8594 public boolean setIndex(int index, int device, String caller, 8595 boolean hasModifyAudioSettings) { 8596 boolean changed; 8597 int oldIndex; 8598 final boolean isCurrentDevice; 8599 synchronized (mSettingsLock) { 8600 synchronized (VolumeStreamState.class) { 8601 oldIndex = getIndex(device); 8602 index = getValidIndex(index, hasModifyAudioSettings); 8603 if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) && mCameraSoundForced) { 8604 index = mIndexMax; 8605 } 8606 mIndexMap.put(device, index); 8607 8608 changed = oldIndex != index; 8609 // Apply change to all streams using this one as alias if: 8610 // - the index actually changed OR 8611 // - there is no volume index stored for this device on alias stream. 8612 // If changing volume of current device, also change volume of current 8613 // device on aliased stream 8614 isCurrentDevice = (device == getDeviceForStream(mStreamType)); 8615 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 8616 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 8617 final VolumeStreamState aliasStreamState = mStreamStates[streamType]; 8618 if (streamType != mStreamType && 8619 mStreamVolumeAlias[streamType] == mStreamType && 8620 (changed || !aliasStreamState.hasIndexForDevice(device))) { 8621 final int scaledIndex = rescaleIndex(index, mStreamType, streamType); 8622 aliasStreamState.setIndex(scaledIndex, device, caller, 8623 hasModifyAudioSettings); 8624 if (isCurrentDevice) { 8625 aliasStreamState.setIndex(scaledIndex, 8626 getDeviceForStream(streamType), caller, 8627 hasModifyAudioSettings); 8628 } 8629 } 8630 } 8631 // Mirror changes in SPEAKER ringtone volume on SCO when 8632 if (changed && mStreamType == AudioSystem.STREAM_RING 8633 && device == AudioSystem.DEVICE_OUT_SPEAKER) { 8634 for (int i = 0; i < mIndexMap.size(); i++) { 8635 int otherDevice = mIndexMap.keyAt(i); 8636 if (AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(otherDevice)) { 8637 mIndexMap.put(otherDevice, index); 8638 } 8639 } 8640 } 8641 } 8642 } 8643 if (changed) { 8644 // If associated to volume group, update group cache 8645 updateVolumeGroupIndex(device, /* forceMuteState= */ false); 8646 8647 oldIndex = (oldIndex + 5) / 10; 8648 index = (index + 5) / 10; 8649 // log base stream changes to the event log 8650 if (mStreamVolumeAlias[mStreamType] == mStreamType) { 8651 if (caller == null) { 8652 Log.w(TAG, "No caller for volume_changed event", new Throwable()); 8653 } 8654 EventLogTags.writeVolumeChanged(mStreamType, oldIndex, index, mIndexMax / 10, 8655 caller); 8656 } 8657 // fire changed intents for all streams, but only when the device it changed on 8658 // is the current device 8659 if ((index != oldIndex) && isCurrentDevice) { 8660 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index); 8661 mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex); 8662 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS, 8663 mStreamVolumeAlias[mStreamType]); 8664 AudioService.sVolumeLogger.enqueue(new VolChangedBroadcastEvent( 8665 mStreamType, mStreamVolumeAlias[mStreamType], index)); 8666 sendBroadcastToAll(mVolumeChanged, mVolumeChangedOptions); 8667 } 8668 } 8669 return changed; 8670 } 8671 getIndex(int device)8672 public int getIndex(int device) { 8673 synchronized (VolumeStreamState.class) { 8674 int index = mIndexMap.get(device, -1); 8675 if (index == -1) { 8676 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT 8677 index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); 8678 } 8679 return index; 8680 } 8681 } 8682 getVolumeInfo(int device)8683 public @NonNull VolumeInfo getVolumeInfo(int device) { 8684 synchronized (VolumeStreamState.class) { 8685 int index = mIndexMap.get(device, -1); 8686 if (index == -1) { 8687 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT 8688 index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); 8689 } 8690 final VolumeInfo vi = new VolumeInfo.Builder(mStreamType) 8691 .setMinVolumeIndex(mIndexMin) 8692 .setMaxVolumeIndex(mIndexMax) 8693 .setVolumeIndex(index) 8694 .setMuted(isFullyMuted()) 8695 .build(); 8696 return vi; 8697 } 8698 } 8699 hasIndexForDevice(int device)8700 public boolean hasIndexForDevice(int device) { 8701 synchronized (VolumeStreamState.class) { 8702 return (mIndexMap.get(device, -1) != -1); 8703 } 8704 } 8705 getMaxIndex()8706 public int getMaxIndex() { 8707 return mIndexMax; 8708 } 8709 8710 /** 8711 * @return the lowest index regardless of permissions 8712 */ getMinIndex()8713 public int getMinIndex() { 8714 return mIndexMin; 8715 } 8716 8717 /** 8718 * @param isPrivileged true if the caller is privileged and not subject to minimum 8719 * volume index thresholds 8720 * @return the lowest index that this caller can set or adjust to 8721 */ getMinIndex(boolean isPrivileged)8722 public int getMinIndex(boolean isPrivileged) { 8723 return isPrivileged ? mIndexMin : mIndexMinNoPerm; 8724 } 8725 8726 /** 8727 * Copies all device/index pairs from the given VolumeStreamState after initializing 8728 * them with the volume for DEVICE_OUT_DEFAULT. No-op if the source VolumeStreamState 8729 * has the same stream type as this instance. 8730 * @param srcStream 8731 * @param caller 8732 */ 8733 // must be sync'd on mSettingsLock before VolumeStreamState.class 8734 @GuardedBy("VolumeStreamState.class") setAllIndexes(VolumeStreamState srcStream, String caller)8735 public void setAllIndexes(VolumeStreamState srcStream, String caller) { 8736 if (mStreamType == srcStream.mStreamType) { 8737 return; 8738 } 8739 int srcStreamType = srcStream.getStreamType(); 8740 // apply default device volume from source stream to all devices first in case 8741 // some devices are present in this stream state but not in source stream state 8742 int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT); 8743 index = rescaleIndex(index, srcStreamType, mStreamType); 8744 for (int i = 0; i < mIndexMap.size(); i++) { 8745 mIndexMap.put(mIndexMap.keyAt(i), index); 8746 } 8747 // Now apply actual volume for devices in source stream state 8748 SparseIntArray srcMap = srcStream.mIndexMap; 8749 for (int i = 0; i < srcMap.size(); i++) { 8750 int device = srcMap.keyAt(i); 8751 index = srcMap.valueAt(i); 8752 index = rescaleIndex(index, srcStreamType, mStreamType); 8753 8754 setIndex(index, device, caller, true /*hasModifyAudioSettings*/); 8755 } 8756 } 8757 8758 // must be sync'd on mSettingsLock before VolumeStreamState.class 8759 @GuardedBy("VolumeStreamState.class") setAllIndexesToMax()8760 public void setAllIndexesToMax() { 8761 for (int i = 0; i < mIndexMap.size(); i++) { 8762 mIndexMap.put(mIndexMap.keyAt(i), mIndexMax); 8763 } 8764 } 8765 8766 // If associated to volume group, update group cache updateVolumeGroupIndex(int device, boolean forceMuteState)8767 private void updateVolumeGroupIndex(int device, boolean forceMuteState) { 8768 // need mSettingsLock when called from setIndex for vgs.mute -> vgs.applyAllVolumes -> 8769 // vss.setIndex which grabs this lock after VSS.class. Locking order needs to be 8770 // preserved 8771 synchronized (mSettingsLock) { 8772 synchronized (VolumeStreamState.class) { 8773 if (mVolumeGroupState != null) { 8774 int groupIndex = (getIndex(device) + 5) / 10; 8775 if (DEBUG_VOL) { 8776 Log.d(TAG, "updateVolumeGroupIndex for stream " + mStreamType 8777 + ", muted=" + mIsMuted + ", device=" + device + ", index=" 8778 + getIndex(device) + ", group " + mVolumeGroupState.name() 8779 + " Muted=" + mVolumeGroupState.isMuted() + ", Index=" 8780 + groupIndex + ", forceMuteState=" + forceMuteState); 8781 } 8782 mVolumeGroupState.updateVolumeIndex(groupIndex, device); 8783 // Only propage mute of stream when applicable 8784 if (isMutable()) { 8785 // For call stream, align mute only when muted, not when index is set to 8786 // 0 8787 mVolumeGroupState.mute( 8788 forceMuteState ? mIsMuted : 8789 (groupIndex == 0 && !isCallStream(mStreamType)) 8790 || mIsMuted); 8791 } 8792 } 8793 } 8794 } 8795 } 8796 8797 /** 8798 * Mute/unmute the stream 8799 * @param state the new mute state 8800 * @return true if the mute state was changed 8801 */ mute(boolean state, String source)8802 public boolean mute(boolean state, String source) { 8803 boolean changed = false; 8804 synchronized (VolumeStreamState.class) { 8805 changed = mute(state, true, source); 8806 } 8807 if (changed) { 8808 broadcastMuteSetting(mStreamType, state); 8809 } 8810 return changed; 8811 } 8812 8813 /** 8814 * Mute/unmute the stream by AudioService 8815 * @param state the new mute state 8816 * @return true if the mute state was changed 8817 */ muteInternally(boolean state)8818 public boolean muteInternally(boolean state) { 8819 boolean changed = false; 8820 synchronized (VolumeStreamState.class) { 8821 if (state != mIsMutedInternally) { 8822 changed = true; 8823 mIsMutedInternally = state; 8824 // mute immediately to avoid delay and preemption when using a message. 8825 applyAllVolumes(); 8826 } 8827 } 8828 if (changed) { 8829 sVolumeLogger.enqueue(new VolumeEvent( 8830 VolumeEvent.VOL_MUTE_STREAM_INT, mStreamType, state)); 8831 } 8832 return changed; 8833 } 8834 8835 @GuardedBy("VolumeStreamState.class") isFullyMuted()8836 public boolean isFullyMuted() { 8837 return mIsMuted || mIsMutedInternally; 8838 } 8839 8840 isMutable()8841 private boolean isMutable() { 8842 return isStreamAffectedByMute(mStreamType) 8843 && (mIndexMin == 0 || isCallStream(mStreamType)); 8844 } 8845 8846 /** 8847 * Mute/unmute the stream 8848 * @param state the new mute state 8849 * @param apply true to propagate to HW, or false just to update the cache. May be needed 8850 * to mute a stream and its aliases as applyAllVolume will force settings to aliases. 8851 * It prevents unnecessary calls to {@see AudioSystem#setStreamVolume} 8852 * @return true if the mute state was changed 8853 */ mute(boolean state, boolean apply, String src)8854 public boolean mute(boolean state, boolean apply, String src) { 8855 synchronized (VolumeStreamState.class) { 8856 boolean changed = state != mIsMuted; 8857 if (changed) { 8858 sMuteLogger.enqueue( 8859 new AudioServiceEvents.StreamMuteEvent(mStreamType, state, src)); 8860 // check to see if unmuting should not have happened due to ringer muted streams 8861 if (!state && isStreamMutedByRingerOrZenMode(mStreamType)) { 8862 Log.e(TAG, "Unmuting stream " + mStreamType 8863 + " despite ringer-zen muted stream 0x" 8864 + Integer.toHexString(AudioService.sRingerAndZenModeMutedStreams), 8865 new Exception()); // this will put a stack trace in the logs 8866 sMuteLogger.enqueue(new AudioServiceEvents.StreamUnmuteErrorEvent( 8867 mStreamType, AudioService.sRingerAndZenModeMutedStreams)); 8868 } 8869 mIsMuted = state; 8870 if (apply) { 8871 doMute(); 8872 } 8873 } 8874 return changed; 8875 } 8876 } 8877 doMute()8878 public void doMute() { 8879 synchronized (VolumeStreamState.class) { 8880 // If associated to volume group, update group cache 8881 updateVolumeGroupIndex(getDeviceForStream(mStreamType), /* forceMuteState= */ true); 8882 8883 // Set the new mute volume. This propagates the values to 8884 // the audio system, otherwise the volume won't be changed 8885 // at the lower level. 8886 sendMsg(mAudioHandler, 8887 MSG_SET_ALL_VOLUMES, 8888 SENDMSG_QUEUE, 8889 0, 8890 0, 8891 this, 0); 8892 } 8893 } 8894 getStreamType()8895 public int getStreamType() { 8896 return mStreamType; 8897 } 8898 checkFixedVolumeDevices()8899 public void checkFixedVolumeDevices() { 8900 synchronized (VolumeStreamState.class) { 8901 // ignore settings for fixed volume devices: volume should always be at max or 0 8902 if (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_MUSIC) { 8903 for (int i = 0; i < mIndexMap.size(); i++) { 8904 int device = mIndexMap.keyAt(i); 8905 int index = mIndexMap.valueAt(i); 8906 if (isFullVolumeDevice(device) 8907 || (isFixedVolumeDevice(device) && index != 0)) { 8908 mIndexMap.put(device, mIndexMax); 8909 } 8910 applyDeviceVolume_syncVSS(device); 8911 } 8912 } 8913 } 8914 } 8915 getValidIndex(int index, boolean hasModifyAudioSettings)8916 private int getValidIndex(int index, boolean hasModifyAudioSettings) { 8917 final int indexMin = hasModifyAudioSettings ? mIndexMin : mIndexMinNoPerm; 8918 if (index < indexMin) { 8919 return indexMin; 8920 } else if (mUseFixedVolume || index > mIndexMax) { 8921 return mIndexMax; 8922 } 8923 8924 return index; 8925 } 8926 dump(PrintWriter pw)8927 private void dump(PrintWriter pw) { 8928 pw.print(" Muted: "); 8929 pw.println(mIsMuted); 8930 pw.print(" Muted Internally: "); 8931 pw.println(mIsMutedInternally); 8932 pw.print(" Min: "); 8933 pw.print((mIndexMin + 5) / 10); 8934 if (mIndexMin != mIndexMinNoPerm) { 8935 pw.print(" w/o perm:"); 8936 pw.println((mIndexMinNoPerm + 5) / 10); 8937 } else { 8938 pw.println(); 8939 } 8940 pw.print(" Max: "); 8941 pw.println((mIndexMax + 5) / 10); 8942 pw.print(" streamVolume:"); pw.println(getStreamVolume(mStreamType)); 8943 pw.print(" Current: "); 8944 for (int i = 0; i < mIndexMap.size(); i++) { 8945 if (i > 0) { 8946 pw.print(", "); 8947 } 8948 final int device = mIndexMap.keyAt(i); 8949 pw.print(Integer.toHexString(device)); 8950 final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 8951 : AudioSystem.getOutputDeviceName(device); 8952 if (!deviceName.isEmpty()) { 8953 pw.print(" ("); 8954 pw.print(deviceName); 8955 pw.print(")"); 8956 } 8957 pw.print(": "); 8958 final int index = (mIndexMap.valueAt(i) + 5) / 10; 8959 pw.print(index); 8960 } 8961 pw.println(); 8962 pw.print(" Devices: "); 8963 pw.print(AudioSystem.deviceSetToString(getDeviceSetForStream(mStreamType))); 8964 pw.println(); 8965 pw.print(" Volume Group: "); 8966 pw.println(mVolumeGroupState != null ? mVolumeGroupState.name() : "n/a"); 8967 } 8968 } 8969 8970 /** Thread that handles native AudioSystem control. */ 8971 private class AudioSystemThread extends Thread { AudioSystemThread()8972 AudioSystemThread() { 8973 super("AudioService"); 8974 } 8975 8976 @Override run()8977 public void run() { 8978 // Set this thread up so the handler will work on it 8979 Looper.prepare(); 8980 8981 synchronized(AudioService.this) { 8982 mAudioHandler = new AudioHandler(); 8983 8984 // Notify that the handler has been created 8985 AudioService.this.notify(); 8986 } 8987 8988 // Listen for volume change requests that are set by VolumePanel 8989 Looper.loop(); 8990 } 8991 } 8992 8993 private static final class DeviceVolumeUpdate { 8994 final int mStreamType; 8995 final int mDevice; 8996 final @NonNull String mCaller; 8997 private static final int NO_NEW_INDEX = -2049; 8998 private final int mVssVolIndex; 8999 9000 // Constructor with volume index, meant to cause this volume to be set and applied for the 9001 // given stream type on the given device DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller)9002 DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller) { 9003 mStreamType = streamType; 9004 mVssVolIndex = vssVolIndex; 9005 mDevice = device; 9006 mCaller = caller; 9007 } 9008 9009 // Constructor with no volume index, meant to cause re-apply of volume for the given 9010 // stream type on the given device DeviceVolumeUpdate(int streamType, int device, @NonNull String caller)9011 DeviceVolumeUpdate(int streamType, int device, @NonNull String caller) { 9012 mStreamType = streamType; 9013 mVssVolIndex = NO_NEW_INDEX; 9014 mDevice = device; 9015 mCaller = caller; 9016 } 9017 hasVolumeIndex()9018 boolean hasVolumeIndex() { 9019 return mVssVolIndex != NO_NEW_INDEX; 9020 } 9021 getVolumeIndex()9022 int getVolumeIndex() throws IllegalStateException { 9023 Preconditions.checkState(mVssVolIndex != NO_NEW_INDEX); 9024 return mVssVolIndex; 9025 } 9026 } 9027 9028 /** only public for mocking/spying, do not call outside of AudioService */ 9029 @VisibleForTesting postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, String caller)9030 public void postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, 9031 String caller) { 9032 sendMsg(mAudioHandler, 9033 MSG_SET_DEVICE_STREAM_VOLUME, 9034 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/, 9035 new DeviceVolumeUpdate(streamType, vssVolIndex, device, caller), 9036 0 /*delay*/); 9037 } 9038 postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller)9039 /*package*/ void postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller) { 9040 sendMsg(mAudioHandler, 9041 MSG_SET_DEVICE_STREAM_VOLUME, 9042 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/, 9043 new DeviceVolumeUpdate(streamType, device, caller), 9044 0 /*delay*/); 9045 } 9046 onSetVolumeIndexOnDevice(@onNull DeviceVolumeUpdate update)9047 private void onSetVolumeIndexOnDevice(@NonNull DeviceVolumeUpdate update) { 9048 final VolumeStreamState streamState = mStreamStates[update.mStreamType]; 9049 if (update.hasVolumeIndex()) { 9050 int index = update.getVolumeIndex(); 9051 if (mSoundDoseHelper.checkSafeMediaVolume(update.mStreamType, index, update.mDevice)) { 9052 index = mSoundDoseHelper.safeMediaVolumeIndex(update.mDevice); 9053 } 9054 streamState.setIndex(index, update.mDevice, update.mCaller, 9055 // trusted as index is always validated before message is posted 9056 true /*hasModifyAudioSettings*/); 9057 sVolumeLogger.enqueue(new EventLogger.StringEvent(update.mCaller + " dev:0x" 9058 + Integer.toHexString(update.mDevice) + " volIdx:" + index)); 9059 } else { 9060 sVolumeLogger.enqueue(new EventLogger.StringEvent(update.mCaller 9061 + " update vol on dev:0x" + Integer.toHexString(update.mDevice))); 9062 } 9063 setDeviceVolume(streamState, update.mDevice); 9064 } 9065 setDeviceVolume(VolumeStreamState streamState, int device)9066 /*package*/ void setDeviceVolume(VolumeStreamState streamState, int device) { 9067 9068 synchronized (VolumeStreamState.class) { 9069 sendMsg(mAudioHandler, SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION, SENDMSG_REPLACE, 9070 device, (isAbsoluteVolumeDevice(device) || isA2dpAbsoluteVolumeDevice(device) 9071 || AudioSystem.isLeAudioDeviceType(device) ? 1 : 0), 9072 streamState, /*delay=*/0); 9073 // Apply volume 9074 streamState.applyDeviceVolume_syncVSS(device); 9075 9076 // Apply change to all streams using this one as alias 9077 int numStreamTypes = AudioSystem.getNumStreamTypes(); 9078 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 9079 if (streamType != streamState.mStreamType && 9080 mStreamVolumeAlias[streamType] == streamState.mStreamType) { 9081 // Make sure volume is also maxed out on A2DP device for aliased stream 9082 // that may have a different device selected 9083 int streamDevice = getDeviceForStream(streamType); 9084 if ((device != streamDevice) 9085 && (isAbsoluteVolumeDevice(device) 9086 || isA2dpAbsoluteVolumeDevice(device) 9087 || AudioSystem.isLeAudioDeviceType(device))) { 9088 mStreamStates[streamType].applyDeviceVolume_syncVSS(device); 9089 } 9090 mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice); 9091 } 9092 } 9093 } 9094 // Post a persist volume msg 9095 sendMsg(mAudioHandler, 9096 MSG_PERSIST_VOLUME, 9097 SENDMSG_QUEUE, 9098 device, 9099 0, 9100 streamState, 9101 PERSIST_DELAY); 9102 9103 } 9104 9105 /** Handles internal volume messages in separate volume thread. */ 9106 /*package*/ class AudioHandler extends Handler { 9107 AudioHandler()9108 AudioHandler() { 9109 super(); 9110 } 9111 AudioHandler(Looper looper)9112 AudioHandler(Looper looper) { 9113 super(looper); 9114 } 9115 setAllVolumes(VolumeStreamState streamState)9116 private void setAllVolumes(VolumeStreamState streamState) { 9117 9118 // Apply volume 9119 streamState.applyAllVolumes(); 9120 9121 // Apply change to all streams using this one as alias 9122 int numStreamTypes = AudioSystem.getNumStreamTypes(); 9123 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 9124 if (streamType != streamState.mStreamType && 9125 mStreamVolumeAlias[streamType] == streamState.mStreamType) { 9126 mStreamStates[streamType].applyAllVolumes(); 9127 } 9128 } 9129 } 9130 persistVolume(VolumeStreamState streamState, int device)9131 private void persistVolume(VolumeStreamState streamState, int device) { 9132 if (mUseFixedVolume) { 9133 return; 9134 } 9135 if (mIsSingleVolume && (streamState.mStreamType != AudioSystem.STREAM_MUSIC)) { 9136 return; 9137 } 9138 if (streamState.hasValidSettingsName()) { 9139 mSettings.putSystemIntForUser(mContentResolver, 9140 streamState.getSettingNameForDevice(device), 9141 (streamState.getIndex(device) + 5) / 10, 9142 UserHandle.USER_CURRENT); 9143 } 9144 } 9145 persistRingerMode(int ringerMode)9146 private void persistRingerMode(int ringerMode) { 9147 if (mUseFixedVolume) { 9148 return; 9149 } 9150 mSettings.putGlobalInt(mContentResolver, Settings.Global.MODE_RINGER, ringerMode); 9151 } 9152 onNotifyVolumeEvent(@onNull IAudioPolicyCallback apc, @AudioManager.VolumeAdjustment int direction)9153 private void onNotifyVolumeEvent(@NonNull IAudioPolicyCallback apc, 9154 @AudioManager.VolumeAdjustment int direction) { 9155 try { 9156 apc.notifyVolumeAdjust(direction); 9157 } catch(Exception e) { 9158 // nothing we can do about this. Do not log error, too much potential for spam 9159 } 9160 } 9161 9162 @Override handleMessage(Message msg)9163 public void handleMessage(Message msg) { 9164 switch (msg.what) { 9165 9166 case MSG_SET_DEVICE_VOLUME: 9167 setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1); 9168 break; 9169 9170 case MSG_SET_ALL_VOLUMES: 9171 setAllVolumes((VolumeStreamState) msg.obj); 9172 break; 9173 9174 case MSG_PERSIST_VOLUME: 9175 persistVolume((VolumeStreamState) msg.obj, msg.arg1); 9176 break; 9177 9178 case MSG_PERSIST_VOLUME_GROUP: 9179 final VolumeGroupState vgs = (VolumeGroupState) msg.obj; 9180 vgs.persistVolumeGroup(msg.arg1); 9181 break; 9182 9183 case MSG_PERSIST_RINGER_MODE: 9184 // note that the value persisted is the current ringer mode, not the 9185 // value of ringer mode as of the time the request was made to persist 9186 persistRingerMode(getRingerModeInternal()); 9187 break; 9188 9189 case MSG_AUDIO_SERVER_DIED: 9190 onAudioServerDied(); 9191 break; 9192 9193 case MSG_DISPATCH_AUDIO_SERVER_STATE: 9194 onDispatchAudioServerStateChange(msg.arg1 == 1); 9195 break; 9196 9197 case MSG_UNLOAD_SOUND_EFFECTS: 9198 mSfxHelper.unloadSoundEffects(); 9199 break; 9200 9201 case MSG_LOAD_SOUND_EFFECTS: 9202 { 9203 LoadSoundEffectReply reply = (LoadSoundEffectReply) msg.obj; 9204 if (mSystemReady) { 9205 mSfxHelper.loadSoundEffects(reply); 9206 } else { 9207 Log.w(TAG, "[schedule]loadSoundEffects() called before boot complete"); 9208 if (reply != null) { 9209 reply.run(false); 9210 } 9211 } 9212 } 9213 break; 9214 9215 case MSG_PLAY_SOUND_EFFECT: 9216 mSfxHelper.playSoundEffect(msg.arg1, msg.arg2); 9217 break; 9218 9219 case MSG_SET_FORCE_USE: 9220 { 9221 final String eventSource = (String) msg.obj; 9222 final int useCase = msg.arg1; 9223 final int config = msg.arg2; 9224 if (useCase == AudioSystem.FOR_MEDIA) { 9225 Log.wtf(TAG, "Invalid force use FOR_MEDIA in AudioService from " 9226 + eventSource); 9227 break; 9228 } 9229 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE 9230 + MediaMetrics.SEPARATOR + AudioSystem.forceUseUsageToString(useCase)) 9231 .set(MediaMetrics.Property.EVENT, "setForceUse") 9232 .set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource) 9233 .set(MediaMetrics.Property.FORCE_USE_MODE, 9234 AudioSystem.forceUseConfigToString(config)) 9235 .record(); 9236 sForceUseLogger.enqueue( 9237 new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource)); 9238 mAudioSystem.setForceUse(useCase, config); 9239 } 9240 break; 9241 9242 case MSG_DISABLE_AUDIO_FOR_UID: 9243 mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */, 9244 msg.arg2 /* uid */); 9245 mAudioEventWakeLock.release(); 9246 break; 9247 9248 case MSG_INIT_STREAMS_VOLUMES: 9249 onInitStreamsAndVolumes(); 9250 mAudioEventWakeLock.release(); 9251 break; 9252 9253 case MSG_INIT_ADI_DEVICE_STATES: 9254 onInitAdiDeviceStates(); 9255 mAudioEventWakeLock.release(); 9256 break; 9257 9258 case MSG_INIT_SPATIALIZER: 9259 onInitSpatializer(); 9260 mAudioEventWakeLock.release(); 9261 break; 9262 9263 case MSG_INIT_HEADTRACKING_SENSORS: 9264 mSpatializerHelper.onInitSensors(); 9265 break; 9266 9267 case MSG_RESET_SPATIALIZER: 9268 mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect); 9269 break; 9270 9271 case MSG_SYSTEM_READY: 9272 onSystemReady(); 9273 break; 9274 9275 case MSG_INDICATE_SYSTEM_READY: 9276 onIndicateSystemReady(); 9277 break; 9278 9279 case MSG_ACCESSORY_PLUG_MEDIA_UNMUTE: 9280 onAccessoryPlugMediaUnmute(msg.arg1); 9281 break; 9282 9283 case MSG_UNMUTE_STREAM: 9284 onUnmuteStream(msg.arg1, msg.arg2); 9285 break; 9286 9287 case MSG_DYN_POLICY_MIX_STATE_UPDATE: 9288 onDynPolicyMixStateUpdate((String) msg.obj, msg.arg1); 9289 break; 9290 9291 case MSG_NOTIFY_VOL_EVENT: 9292 onNotifyVolumeEvent((IAudioPolicyCallback) msg.obj, msg.arg1); 9293 break; 9294 9295 case MSG_ENABLE_SURROUND_FORMATS: 9296 onEnableSurroundFormats((ArrayList<Integer>) msg.obj); 9297 break; 9298 9299 case MSG_UPDATE_RINGER_MODE: 9300 onUpdateRingerModeServiceInt(); 9301 break; 9302 9303 case MSG_SET_DEVICE_STREAM_VOLUME: 9304 onSetVolumeIndexOnDevice((DeviceVolumeUpdate) msg.obj); 9305 break; 9306 9307 case MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS: 9308 onObserveDevicesForAllStreams(/*skipStream*/ msg.arg1); 9309 break; 9310 9311 case MSG_HDMI_VOLUME_CHECK: 9312 onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj); 9313 break; 9314 9315 case MSG_PLAYBACK_CONFIG_CHANGE: 9316 onPlaybackConfigChange((List<AudioPlaybackConfiguration>) msg.obj); 9317 break; 9318 case MSG_RECORDING_CONFIG_CHANGE: 9319 onRecordingConfigChange((List<AudioRecordingConfiguration>) msg.obj); 9320 break; 9321 9322 case MSG_BROADCAST_MICROPHONE_MUTE: 9323 mSystemServer.sendMicrophoneMuteChangedIntent(); 9324 break; 9325 9326 case MSG_CHECK_MODE_FOR_UID: 9327 synchronized (mDeviceBroker.mSetModeLock) { 9328 if (msg.obj == null) { 9329 break; 9330 } 9331 // Update active playback/recording for apps requesting IN_COMMUNICATION 9332 // mode after a grace period following the mode change 9333 SetModeDeathHandler h = (SetModeDeathHandler) msg.obj; 9334 if (mSetModeDeathHandlers.indexOf(h) < 0) { 9335 break; 9336 } 9337 boolean wasActive = h.isActive(); 9338 h.setPlaybackActive(isPlaybackActiveForUid(h.getUid())); 9339 h.setRecordingActive(isRecordingActiveForUid(h.getUid())); 9340 if (wasActive != h.isActive()) { 9341 onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(), 9342 mContext.getPackageName(), false /*force*/); 9343 } 9344 } 9345 break; 9346 9347 case MSG_STREAM_DEVICES_CHANGED: 9348 final SomeArgs args = (SomeArgs) msg.obj; 9349 final Intent intent = (Intent) args.arg1; 9350 final Bundle options = (Bundle) args.arg2; 9351 args.recycle(); 9352 sendBroadcastToAll(intent 9353 .putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_DEVICES, msg.arg1) 9354 .putExtra(AudioManager.EXTRA_VOLUME_STREAM_DEVICES, msg.arg2), 9355 options); 9356 break; 9357 9358 case MSG_UPDATE_VOLUME_STATES_FOR_DEVICE: 9359 onUpdateVolumeStatesForAudioDevice(msg.arg1, (String) msg.obj); 9360 break; 9361 9362 case MSG_REINIT_VOLUMES: 9363 onReinitVolumes((String) msg.obj); 9364 break; 9365 9366 case MSG_UPDATE_A11Y_SERVICE_UIDS: 9367 onUpdateAccessibilityServiceUids(); 9368 break; 9369 9370 case MSG_UPDATE_AUDIO_MODE: 9371 synchronized (mDeviceBroker.mSetModeLock) { 9372 onUpdateAudioMode(msg.arg1, msg.arg2, (String) msg.obj, false /*force*/); 9373 } 9374 break; 9375 9376 case MSG_BT_DEV_CHANGED: 9377 mDeviceBroker.queueOnBluetoothActiveDeviceChanged( 9378 (AudioDeviceBroker.BtDeviceChangedData) msg.obj); 9379 break; 9380 9381 case MSG_DISPATCH_AUDIO_MODE: 9382 dispatchMode(msg.arg1); 9383 break; 9384 9385 case MSG_ROUTING_UPDATED: 9386 onRoutingUpdatedFromAudioThread(); 9387 break; 9388 9389 case MSG_ADD_ASSISTANT_SERVICE_UID: 9390 onAddAssistantServiceUids(new int[]{msg.arg1}); 9391 break; 9392 9393 case MSG_REMOVE_ASSISTANT_SERVICE_UID: 9394 onRemoveAssistantServiceUids(new int[]{msg.arg1}); 9395 break; 9396 case MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID: 9397 updateActiveAssistantServiceUids(); 9398 break; 9399 9400 case MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR: 9401 dispatchDeviceVolumeBehavior((AudioDeviceAttributes) msg.obj, msg.arg1); 9402 break; 9403 9404 case MSG_ROTATION_UPDATE: 9405 // rotation parameter format: "rotation=x" where x is one of 0, 90, 180, 270 9406 mAudioSystem.setParameters((String) msg.obj); 9407 break; 9408 9409 case MSG_FOLD_UPDATE: 9410 // fold parameter format: "device_folded=x" where x is one of on, off 9411 mAudioSystem.setParameters((String) msg.obj); 9412 break; 9413 9414 case MSG_NO_LOG_FOR_PLAYER_I: 9415 mPlaybackMonitor.ignorePlayerIId(msg.arg1); 9416 break; 9417 9418 case MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES: 9419 onDispatchPreferredMixerAttributesChanged(msg.getData(), msg.arg1); 9420 break; 9421 9422 case MSG_LOWER_VOLUME_TO_RS1: 9423 onLowerVolumeToRs1(); 9424 break; 9425 9426 case MSG_CONFIGURATION_CHANGED: 9427 onConfigurationChanged(); 9428 break; 9429 9430 default: 9431 if (msg.what >= SAFE_MEDIA_VOLUME_MSG_START) { 9432 // msg could be for the SoundDoseHelper 9433 mSoundDoseHelper.handleMessage(msg); 9434 } 9435 } 9436 } 9437 } 9438 9439 private class SettingsObserver extends ContentObserver { 9440 SettingsObserver()9441 SettingsObserver() { 9442 super(new Handler()); 9443 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9444 Settings.Global.ZEN_MODE), false, this); 9445 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9446 Settings.Global.ZEN_MODE_CONFIG_ETAG), false, this); 9447 mContentResolver.registerContentObserver(Settings.System.getUriFor( 9448 Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this); 9449 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9450 Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this); 9451 mContentResolver.registerContentObserver(Settings.System.getUriFor( 9452 Settings.System.MASTER_MONO), false, this); 9453 mContentResolver.registerContentObserver(Settings.System.getUriFor( 9454 Settings.System.MASTER_BALANCE), false, this); 9455 9456 mEncodedSurroundMode = mSettings.getGlobalInt( 9457 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT, 9458 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 9459 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9460 Settings.Global.ENCODED_SURROUND_OUTPUT), false, this); 9461 mEnabledSurroundFormats = mSettings.getGlobalString( 9462 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 9463 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9464 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS), false, this); 9465 9466 mContentResolver.registerContentObserver(Settings.Secure.getUriFor( 9467 Settings.Secure.VOICE_INTERACTION_SERVICE), false, this); 9468 } 9469 9470 @Override onChange(boolean selfChange)9471 public void onChange(boolean selfChange) { 9472 super.onChange(selfChange); 9473 // FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode. 9474 // However there appear to be some missing locks around sRingerAndZenModeMutedStreams 9475 // and mRingerModeAffectedStreams, so will leave this synchronized for now. 9476 // sRingerAndZenModeMutedStreams and mMuteAffectedStreams are safe (only accessed once). 9477 synchronized (mSettingsLock) { 9478 if (updateRingerAndZenModeAffectedStreams()) { 9479 /* 9480 * Ensure all stream types that should be affected by ringer mode 9481 * are in the proper state. 9482 */ 9483 setRingerModeInt(getRingerModeInternal(), false); 9484 } 9485 readDockAudioSettings(mContentResolver); 9486 updateMasterMono(mContentResolver); 9487 updateMasterBalance(mContentResolver); 9488 updateEncodedSurroundOutput(); 9489 sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged); 9490 updateAssistantUIdLocked(/* forceUpdate= */ false); 9491 } 9492 } 9493 updateEncodedSurroundOutput()9494 private void updateEncodedSurroundOutput() { 9495 int newSurroundMode = mSettings.getGlobalInt( 9496 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT, 9497 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 9498 // Did it change? 9499 if (mEncodedSurroundMode != newSurroundMode) { 9500 // Send to AudioPolicyManager 9501 sendEncodedSurroundMode(newSurroundMode, "SettingsObserver"); 9502 mDeviceBroker.toggleHdmiIfConnected_Async(); 9503 mEncodedSurroundMode = newSurroundMode; 9504 mSurroundModeChanged = true; 9505 } else { 9506 mSurroundModeChanged = false; 9507 } 9508 } 9509 } 9510 avrcpSupportsAbsoluteVolume(String address, boolean support)9511 private void avrcpSupportsAbsoluteVolume(String address, boolean support) { 9512 // address is not used for now, but may be used when multiple a2dp devices are supported 9513 sVolumeLogger.enqueue(new EventLogger.StringEvent("avrcpSupportsAbsoluteVolume addr=" 9514 + address + " support=" + support).printLog(TAG)); 9515 mDeviceBroker.setAvrcpAbsoluteVolumeSupported(support); 9516 setAvrcpAbsoluteVolumeSupported(support); 9517 } 9518 setAvrcpAbsoluteVolumeSupported(boolean support)9519 /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean support) { 9520 mAvrcpAbsVolSupported = support; 9521 sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE, 9522 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, 9523 mStreamStates[AudioSystem.STREAM_MUSIC], 0); 9524 } 9525 9526 /** 9527 * @return true if there is currently a registered dynamic mixing policy that affects media 9528 * and is not a render + loopback policy 9529 */ 9530 // only public for mocking/spying 9531 @VisibleForTesting hasMediaDynamicPolicy()9532 public boolean hasMediaDynamicPolicy() { 9533 synchronized (mAudioPolicies) { 9534 if (mAudioPolicies.isEmpty()) { 9535 return false; 9536 } 9537 final Collection<AudioPolicyProxy> appColl = mAudioPolicies.values(); 9538 for (AudioPolicyProxy app : appColl) { 9539 if (app.hasMixAffectingUsage(AudioAttributes.USAGE_MEDIA, 9540 AudioMix.ROUTE_FLAG_LOOP_BACK_RENDER)) { 9541 return true; 9542 } 9543 } 9544 return false; 9545 } 9546 } 9547 9548 /** only public for mocking/spying, do not call outside of AudioService */ 9549 @VisibleForTesting checkMusicActive(int deviceType, String caller)9550 public void checkMusicActive(int deviceType, String caller) { 9551 if (mSoundDoseHelper.safeDevicesContains(deviceType)) { 9552 mSoundDoseHelper.scheduleMusicActiveCheck(); 9553 } 9554 } 9555 9556 /** 9557 * Receiver for misc intent broadcasts the Phone app cares about. 9558 */ 9559 private class AudioServiceBroadcastReceiver extends BroadcastReceiver { 9560 @Override onReceive(Context context, Intent intent)9561 public void onReceive(Context context, Intent intent) { 9562 final String action = intent.getAction(); 9563 int outDevice; 9564 int inDevice; 9565 int state; 9566 9567 if (action.equals(Intent.ACTION_DOCK_EVENT)) { 9568 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 9569 Intent.EXTRA_DOCK_STATE_UNDOCKED); 9570 int config; 9571 switch (dockState) { 9572 case Intent.EXTRA_DOCK_STATE_DESK: 9573 config = AudioSystem.FORCE_BT_DESK_DOCK; 9574 break; 9575 case Intent.EXTRA_DOCK_STATE_CAR: 9576 config = AudioSystem.FORCE_BT_CAR_DOCK; 9577 break; 9578 case Intent.EXTRA_DOCK_STATE_LE_DESK: 9579 config = AudioSystem.FORCE_ANALOG_DOCK; 9580 break; 9581 case Intent.EXTRA_DOCK_STATE_HE_DESK: 9582 config = AudioSystem.FORCE_DIGITAL_DOCK; 9583 break; 9584 case Intent.EXTRA_DOCK_STATE_UNDOCKED: 9585 default: 9586 config = AudioSystem.FORCE_NONE; 9587 } 9588 // Low end docks have a menu to enable or disable audio 9589 // (see mDockAudioMediaEnabled) 9590 if (!((dockState == Intent.EXTRA_DOCK_STATE_LE_DESK) 9591 || ((dockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) 9592 && (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK)))) { 9593 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, config, 9594 "ACTION_DOCK_EVENT intent"); 9595 } 9596 mDockState = dockState; 9597 } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED) 9598 || action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { 9599 mDeviceBroker.postReceiveBtEvent(intent); 9600 } else if (action.equals(Intent.ACTION_SCREEN_ON)) { 9601 if (mMonitorRotation) { 9602 RotationHelper.enable(); 9603 } 9604 AudioSystem.setParameters("screen_state=on"); 9605 } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { 9606 if (mMonitorRotation) { 9607 //reduce wakeups (save current) by only listening when display is on 9608 RotationHelper.disable(); 9609 } 9610 AudioSystem.setParameters("screen_state=off"); 9611 } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) { 9612 sendMsg(mAudioHandler, 9613 MSG_CONFIGURATION_CHANGED, 9614 SENDMSG_REPLACE, 9615 0, 9616 0, 9617 null, 0); 9618 } else if (action.equals(Intent.ACTION_USER_SWITCHED)) { 9619 if (mUserSwitchedReceived) { 9620 // attempt to stop music playback for background user except on first user 9621 // switch (i.e. first boot) 9622 mDeviceBroker.postBroadcastBecomingNoisy(); 9623 } 9624 mUserSwitchedReceived = true; 9625 // the current audio focus owner is no longer valid 9626 mMediaFocusControl.discardAudioFocusOwner(); 9627 9628 if (mSupportsMicPrivacyToggle) { 9629 mMicMuteFromPrivacyToggle = mSensorPrivacyManagerInternal 9630 .isSensorPrivacyEnabled(getCurrentUserId(), 9631 SensorPrivacyManager.Sensors.MICROPHONE); 9632 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); 9633 } 9634 9635 // load volume settings for new user 9636 readAudioSettings(true /*userSwitch*/); 9637 // preserve STREAM_MUSIC volume from one user to the next. 9638 sendMsg(mAudioHandler, 9639 MSG_SET_ALL_VOLUMES, 9640 SENDMSG_QUEUE, 9641 0, 9642 0, 9643 mStreamStates[AudioSystem.STREAM_MUSIC], 0); 9644 } else if (action.equals(Intent.ACTION_USER_BACKGROUND)) { 9645 // Disable audio recording for the background user/profile 9646 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 9647 if (userId >= 0) { 9648 // TODO Kill recording streams instead of killing processes holding permission 9649 UserInfo userInfo = UserManagerService.getInstance().getUserInfo(userId); 9650 killBackgroundUserProcessesWithRecordAudioPermission(userInfo); 9651 } 9652 try { 9653 UserManagerService.getInstance().setUserRestriction( 9654 UserManager.DISALLOW_RECORD_AUDIO, true, userId); 9655 } catch (IllegalArgumentException e) { 9656 Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e); 9657 } 9658 } else if (action.equals(Intent.ACTION_USER_FOREGROUND)) { 9659 // Enable audio recording for foreground user/profile 9660 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 9661 try { 9662 UserManagerService.getInstance().setUserRestriction( 9663 UserManager.DISALLOW_RECORD_AUDIO, false, userId); 9664 } catch (IllegalArgumentException e) { 9665 Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e); 9666 } 9667 } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) || 9668 action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) { 9669 handleAudioEffectBroadcast(context, intent); 9670 } else if (action.equals(Intent.ACTION_PACKAGES_SUSPENDED)) { 9671 final int[] suspendedUids = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST); 9672 final String[] suspendedPackages = 9673 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 9674 if (suspendedPackages == null || suspendedUids == null 9675 || suspendedPackages.length != suspendedUids.length) { 9676 return; 9677 } 9678 for (int i = 0; i < suspendedUids.length; i++) { 9679 if (!TextUtils.isEmpty(suspendedPackages[i])) { 9680 mMediaFocusControl.noFocusForSuspendedApp( 9681 suspendedPackages[i], suspendedUids[i]); 9682 } 9683 } 9684 } else if (action.equals(ACTION_CHECK_MUSIC_ACTIVE)) { 9685 mSoundDoseHelper.onCheckMusicActive(ACTION_CHECK_MUSIC_ACTIVE, 9686 mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)); 9687 } 9688 } 9689 } // end class AudioServiceBroadcastReceiver 9690 9691 private class AudioServiceUserRestrictionsListener implements UserRestrictionsListener { 9692 9693 @Override onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions)9694 public void onUserRestrictionsChanged(int userId, Bundle newRestrictions, 9695 Bundle prevRestrictions) { 9696 // Update mic mute state. 9697 { 9698 final boolean wasRestricted = 9699 prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE); 9700 final boolean isRestricted = 9701 newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE); 9702 if (wasRestricted != isRestricted) { 9703 mMicMuteFromRestrictions = isRestricted; 9704 setMicrophoneMuteNoCallerCheck(userId); 9705 } 9706 } 9707 9708 // Update speaker mute state. 9709 { 9710 final boolean wasRestricted = 9711 prevRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME) 9712 || prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE); 9713 final boolean isRestricted = 9714 newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME) 9715 || newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE); 9716 if (wasRestricted != isRestricted) { 9717 setMasterMuteInternalNoCallerCheck(isRestricted, /* flags =*/ 0, userId); 9718 } 9719 } 9720 } 9721 } // end class AudioServiceUserRestrictionsListener 9722 handleAudioEffectBroadcast(Context context, Intent intent)9723 private void handleAudioEffectBroadcast(Context context, Intent intent) { 9724 String target = intent.getPackage(); 9725 if (target != null) { 9726 Log.w(TAG, "effect broadcast already targeted to " + target); 9727 return; 9728 } 9729 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 9730 // TODO this should target a user-selected panel 9731 List<ResolveInfo> ril = context.getPackageManager().queryBroadcastReceivers( 9732 intent, 0 /* flags */); 9733 if (ril != null && ril.size() != 0) { 9734 ResolveInfo ri = ril.get(0); 9735 if (ri != null && ri.activityInfo != null && ri.activityInfo.packageName != null) { 9736 intent.setPackage(ri.activityInfo.packageName); 9737 context.sendBroadcastAsUser(intent, UserHandle.ALL); 9738 return; 9739 } 9740 } 9741 Log.w(TAG, "couldn't find receiver package for effect intent"); 9742 } 9743 killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser)9744 private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) { 9745 PackageManager pm = mContext.getPackageManager(); 9746 // Find the home activity of the user. It should not be killed to avoid expensive restart, 9747 // when the user switches back. For managed profiles, we should kill all recording apps 9748 ComponentName homeActivityName = null; 9749 if (!oldUser.isManagedProfile()) { 9750 homeActivityName = LocalServices.getService( 9751 ActivityTaskManagerInternal.class).getHomeActivityForUser(oldUser.id); 9752 } 9753 final String[] permissions = { Manifest.permission.RECORD_AUDIO }; 9754 List<PackageInfo> packages; 9755 try { 9756 packages = AppGlobals.getPackageManager() 9757 .getPackagesHoldingPermissions(permissions, 0, oldUser.id).getList(); 9758 } catch (RemoteException e) { 9759 throw new AndroidRuntimeException(e); 9760 } 9761 for (int j = packages.size() - 1; j >= 0; j--) { 9762 PackageInfo pkg = packages.get(j); 9763 // Skip system processes 9764 if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) { 9765 continue; 9766 } 9767 // Skip packages that have permission to interact across users 9768 if (pm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS, pkg.packageName) 9769 == PackageManager.PERMISSION_GRANTED) { 9770 continue; 9771 } 9772 if (homeActivityName != null 9773 && pkg.packageName.equals(homeActivityName.getPackageName()) 9774 && pkg.applicationInfo.isSystemApp()) { 9775 continue; 9776 } 9777 try { 9778 final int uid = pkg.applicationInfo.uid; 9779 ActivityManager.getService().killUid(UserHandle.getAppId(uid), 9780 UserHandle.getUserId(uid), 9781 "killBackgroundUserProcessesWithAudioRecordPermission"); 9782 } catch (RemoteException e) { 9783 Log.w(TAG, "Error calling killUid", e); 9784 } 9785 } 9786 } 9787 9788 9789 //========================================================================================== 9790 // Audio Focus 9791 //========================================================================================== 9792 /** 9793 * Returns whether a focus request is eligible to force ducking. 9794 * Will return true if: 9795 * - the AudioAttributes have a usage of USAGE_ASSISTANCE_ACCESSIBILITY, 9796 * - the focus request is AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 9797 * - the associated Bundle has KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING set to true, 9798 * - the uid of the requester is a known accessibility service or root. 9799 * @param aa AudioAttributes of the focus request 9800 * @param uid uid of the focus requester 9801 * @return true if ducking is to be forced 9802 */ forceFocusDuckingForAccessibility(@ullable AudioAttributes aa, int request, int uid)9803 private boolean forceFocusDuckingForAccessibility(@Nullable AudioAttributes aa, 9804 int request, int uid) { 9805 if (aa == null || aa.getUsage() != AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY 9806 || request != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) { 9807 return false; 9808 } 9809 final Bundle extraInfo = aa.getBundle(); 9810 if (extraInfo == null || 9811 !extraInfo.getBoolean(AudioFocusRequest.KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING)) { 9812 return false; 9813 } 9814 if (uid == 0) { 9815 return true; 9816 } 9817 synchronized (mAccessibilityServiceUidsLock) { 9818 if (mAccessibilityServiceUids != null) { 9819 int callingUid = Binder.getCallingUid(); 9820 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 9821 if (mAccessibilityServiceUids[i] == callingUid) { 9822 return true; 9823 } 9824 } 9825 } 9826 } 9827 return false; 9828 } 9829 isSupportedSystemUsage(@udioAttributes.AttributeUsage int usage)9830 private boolean isSupportedSystemUsage(@AudioAttributes.AttributeUsage int usage) { 9831 synchronized (mSupportedSystemUsagesLock) { 9832 for (int i = 0; i < mSupportedSystemUsages.length; i++) { 9833 if (mSupportedSystemUsages[i] == usage) { 9834 return true; 9835 } 9836 } 9837 return false; 9838 } 9839 } 9840 validateAudioAttributesUsage(@onNull AudioAttributes audioAttributes)9841 private void validateAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) { 9842 @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage(); 9843 if (AudioAttributes.isSystemUsage(usage)) { 9844 if ((usage == AudioAttributes.USAGE_CALL_ASSISTANT 9845 && (audioAttributes.getAllFlags() & AudioAttributes.FLAG_CALL_REDIRECTION) != 0 9846 && callerHasPermission(Manifest.permission.CALL_AUDIO_INTERCEPTION)) 9847 || callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)) { 9848 if (!isSupportedSystemUsage(usage)) { 9849 throw new IllegalArgumentException( 9850 "Unsupported usage " + AudioAttributes.usageToString(usage)); 9851 } 9852 } else { 9853 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission"); 9854 } 9855 } 9856 } 9857 isValidAudioAttributesUsage(@onNull AudioAttributes audioAttributes)9858 private boolean isValidAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) { 9859 @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage(); 9860 if (AudioAttributes.isSystemUsage(usage)) { 9861 return isSupportedSystemUsage(usage) 9862 && ((usage == AudioAttributes.USAGE_CALL_ASSISTANT 9863 && (audioAttributes.getAllFlags() 9864 & AudioAttributes.FLAG_CALL_REDIRECTION) != 0 9865 && callerHasPermission(Manifest.permission.CALL_AUDIO_INTERCEPTION)) 9866 || callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)); 9867 } 9868 return true; 9869 } 9870 requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk)9871 public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, 9872 IAudioFocusDispatcher fd, String clientId, String callingPackageName, 9873 String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk) { 9874 if ((flags & AudioManager.AUDIOFOCUS_FLAG_TEST) != 0) { 9875 throw new IllegalArgumentException("Invalid test flag"); 9876 } 9877 final int uid = Binder.getCallingUid(); 9878 MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus") 9879 .setUid(uid) 9880 //.putInt("durationHint", durationHint) 9881 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) 9882 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 9883 .set(MediaMetrics.Property.EVENT, "requestAudioFocus") 9884 .set(MediaMetrics.Property.FLAGS, flags); 9885 9886 // permission checks 9887 if (aa != null && !isValidAudioAttributesUsage(aa)) { 9888 final String reason = "Request using unsupported usage"; 9889 Log.w(TAG, reason); 9890 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 9891 .record(); 9892 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9893 } 9894 if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) { 9895 if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) { 9896 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 9897 android.Manifest.permission.MODIFY_PHONE_STATE)) { 9898 final String reason = "Invalid permission to (un)lock audio focus"; 9899 Log.e(TAG, reason, new Exception()); 9900 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 9901 .record(); 9902 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9903 } 9904 } else { 9905 // only a registered audio policy can be used to lock focus 9906 synchronized (mAudioPolicies) { 9907 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 9908 final String reason = 9909 "Invalid unregistered AudioPolicy to (un)lock audio focus"; 9910 Log.e(TAG, reason); 9911 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 9912 .record(); 9913 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9914 } 9915 } 9916 } 9917 } 9918 9919 if (callingPackageName == null || clientId == null || aa == null) { 9920 final String reason = "Invalid null parameter to request audio focus"; 9921 Log.e(TAG, reason); 9922 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 9923 .record(); 9924 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9925 } 9926 mmi.record(); 9927 return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd, 9928 clientId, callingPackageName, attributionTag, flags, sdk, 9929 forceFocusDuckingForAccessibility(aa, durationHint, uid), -1 /*testUid, ignored*/); 9930 } 9931 9932 /** see {@link AudioManager#requestAudioFocusForTest(AudioFocusRequest, String, int, int)} */ requestAudioFocusForTest(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags, int fakeUid, int sdk)9933 public int requestAudioFocusForTest(AudioAttributes aa, int durationHint, IBinder cb, 9934 IAudioFocusDispatcher fd, String clientId, String callingPackageName, 9935 int flags, int fakeUid, int sdk) { 9936 if (!enforceQueryAudioStateForTest("focus request")) { 9937 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9938 } 9939 if (callingPackageName == null || clientId == null || aa == null) { 9940 final String reason = "Invalid null parameter to request audio focus"; 9941 Log.e(TAG, reason); 9942 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9943 } 9944 return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd, 9945 clientId, callingPackageName, null, flags, 9946 sdk, false /*forceDuck*/, fakeUid); 9947 } 9948 abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)9949 public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, 9950 String callingPackageName) { 9951 MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus") 9952 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) 9953 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 9954 .set(MediaMetrics.Property.EVENT, "abandonAudioFocus"); 9955 9956 if (aa != null && !isValidAudioAttributesUsage(aa)) { 9957 Log.w(TAG, "Request using unsupported usage."); 9958 mmi.set(MediaMetrics.Property.EARLY_RETURN, "unsupported usage").record(); 9959 9960 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9961 } 9962 mmi.record(); 9963 return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName); 9964 } 9965 9966 /** see {@link AudioManager#abandonAudioFocusForTest(AudioFocusRequest, String)} */ abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)9967 public int abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, 9968 AudioAttributes aa, String callingPackageName) { 9969 if (!enforceQueryAudioStateForTest("focus abandon")) { 9970 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9971 } 9972 return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName); 9973 } 9974 unregisterAudioFocusClient(String clientId)9975 public void unregisterAudioFocusClient(String clientId) { 9976 new MediaMetrics.Item(mMetricsId + "focus") 9977 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 9978 .set(MediaMetrics.Property.EVENT, "unregisterAudioFocusClient") 9979 .record(); 9980 mMediaFocusControl.unregisterAudioFocusClient(clientId); 9981 } 9982 getCurrentAudioFocus()9983 public int getCurrentAudioFocus() { 9984 return mMediaFocusControl.getCurrentAudioFocus(); 9985 } 9986 getFocusRampTimeMs(int focusGain, AudioAttributes attr)9987 public int getFocusRampTimeMs(int focusGain, AudioAttributes attr) { 9988 return mMediaFocusControl.getFocusRampTimeMs(focusGain, attr); 9989 } 9990 9991 /** only public for mocking/spying, do not call outside of AudioService */ 9992 @VisibleForTesting hasAudioFocusUsers()9993 public boolean hasAudioFocusUsers() { 9994 return mMediaFocusControl.hasAudioFocusUsers(); 9995 } 9996 9997 /** see {@link AudioManager#getFadeOutDurationOnFocusLossMillis(AudioAttributes)} */ getFadeOutDurationOnFocusLossMillis(AudioAttributes aa)9998 public long getFadeOutDurationOnFocusLossMillis(AudioAttributes aa) { 9999 if (!enforceQueryAudioStateForTest("fade out duration")) { 10000 return 0; 10001 } 10002 return mMediaFocusControl.getFadeOutDurationOnFocusLossMillis(aa); 10003 } 10004 enforceQueryAudioStateForTest(String mssg)10005 private boolean enforceQueryAudioStateForTest(String mssg) { 10006 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 10007 Manifest.permission.QUERY_AUDIO_STATE)) { 10008 final String reason = "Doesn't have QUERY_AUDIO_STATE permission for " 10009 + mssg + " test API"; 10010 Log.e(TAG, reason, new Exception()); 10011 return false; 10012 } 10013 return true; 10014 } 10015 10016 //========================================================================================== 10017 private final @NonNull SpatializerHelper mSpatializerHelper; 10018 /** 10019 * Initialized from property ro.audio.spatializer_enabled 10020 * Should only be 1 when the device ships with a Spatializer effect 10021 */ 10022 private final boolean mHasSpatializerEffect; 10023 /** 10024 * Default value for the spatial audio feature 10025 */ 10026 private static final boolean SPATIAL_AUDIO_ENABLED_DEFAULT = true; 10027 enforceModifyDefaultAudioEffectsPermission()10028 private void enforceModifyDefaultAudioEffectsPermission() { 10029 if (mContext.checkCallingOrSelfPermission( 10030 android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10031 != PackageManager.PERMISSION_GRANTED) { 10032 throw new SecurityException("Missing MODIFY_DEFAULT_AUDIO_EFFECTS permission"); 10033 } 10034 } 10035 10036 /** 10037 * Returns the immersive audio level that the platform is capable of 10038 * @see Spatializer#getImmersiveAudioLevel() 10039 */ getSpatializerImmersiveAudioLevel()10040 public int getSpatializerImmersiveAudioLevel() { 10041 return mSpatializerHelper.getCapableImmersiveAudioLevel(); 10042 } 10043 10044 /** @see Spatializer#isEnabled() */ isSpatializerEnabled()10045 public boolean isSpatializerEnabled() { 10046 return mSpatializerHelper.isEnabled(); 10047 } 10048 10049 /** @see Spatializer#isAvailable() */ isSpatializerAvailable()10050 public boolean isSpatializerAvailable() { 10051 return mSpatializerHelper.isAvailable(); 10052 } 10053 10054 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10055 /** @see Spatializer#isAvailableForDevice(AudioDeviceAttributes) */ isSpatializerAvailableForDevice(@onNull AudioDeviceAttributes device)10056 public boolean isSpatializerAvailableForDevice(@NonNull AudioDeviceAttributes device) { 10057 super.isSpatializerAvailableForDevice_enforcePermission(); 10058 10059 return mSpatializerHelper.isAvailableForDevice(Objects.requireNonNull(device)); 10060 } 10061 10062 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10063 /** @see Spatializer#hasHeadTracker(AudioDeviceAttributes) */ hasHeadTracker(@onNull AudioDeviceAttributes device)10064 public boolean hasHeadTracker(@NonNull AudioDeviceAttributes device) { 10065 super.hasHeadTracker_enforcePermission(); 10066 10067 return mSpatializerHelper.hasHeadTracker(Objects.requireNonNull(device)); 10068 } 10069 10070 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10071 /** @see Spatializer#setHeadTrackerEnabled(boolean, AudioDeviceAttributes) */ setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device)10072 public void setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device) { 10073 super.setHeadTrackerEnabled_enforcePermission(); 10074 10075 mSpatializerHelper.setHeadTrackerEnabled(enabled, Objects.requireNonNull(device)); 10076 } 10077 10078 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10079 /** @see Spatializer#isHeadTrackerEnabled(AudioDeviceAttributes) */ isHeadTrackerEnabled(@onNull AudioDeviceAttributes device)10080 public boolean isHeadTrackerEnabled(@NonNull AudioDeviceAttributes device) { 10081 super.isHeadTrackerEnabled_enforcePermission(); 10082 10083 return mSpatializerHelper.isHeadTrackerEnabled(Objects.requireNonNull(device)); 10084 } 10085 10086 /** @see Spatializer#isHeadTrackerAvailable() */ isHeadTrackerAvailable()10087 public boolean isHeadTrackerAvailable() { 10088 return mSpatializerHelper.isHeadTrackerAvailable(); 10089 } 10090 10091 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10092 /** @see Spatializer#setSpatializerEnabled(boolean) */ setSpatializerEnabled(boolean enabled)10093 public void setSpatializerEnabled(boolean enabled) { 10094 super.setSpatializerEnabled_enforcePermission(); 10095 10096 mSpatializerHelper.setFeatureEnabled(enabled); 10097 } 10098 10099 /** @see Spatializer#canBeSpatialized() */ canBeSpatialized( @onNull AudioAttributes attributes, @NonNull AudioFormat format)10100 public boolean canBeSpatialized( 10101 @NonNull AudioAttributes attributes, @NonNull AudioFormat format) { 10102 Objects.requireNonNull(attributes); 10103 Objects.requireNonNull(format); 10104 return mSpatializerHelper.canBeSpatialized(attributes, format); 10105 } 10106 10107 /** @see Spatializer.SpatializerInfoDispatcherStub */ registerSpatializerCallback( @onNull ISpatializerCallback cb)10108 public void registerSpatializerCallback( 10109 @NonNull ISpatializerCallback cb) { 10110 Objects.requireNonNull(cb); 10111 mSpatializerHelper.registerStateCallback(cb); 10112 } 10113 10114 /** @see Spatializer.SpatializerInfoDispatcherStub */ unregisterSpatializerCallback( @onNull ISpatializerCallback cb)10115 public void unregisterSpatializerCallback( 10116 @NonNull ISpatializerCallback cb) { 10117 Objects.requireNonNull(cb); 10118 mSpatializerHelper.unregisterStateCallback(cb); 10119 } 10120 10121 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10122 /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */ registerSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)10123 public void registerSpatializerHeadTrackingCallback( 10124 @NonNull ISpatializerHeadTrackingModeCallback cb) { 10125 super.registerSpatializerHeadTrackingCallback_enforcePermission(); 10126 10127 Objects.requireNonNull(cb); 10128 mSpatializerHelper.registerHeadTrackingModeCallback(cb); 10129 } 10130 10131 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10132 /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */ unregisterSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)10133 public void unregisterSpatializerHeadTrackingCallback( 10134 @NonNull ISpatializerHeadTrackingModeCallback cb) { 10135 super.unregisterSpatializerHeadTrackingCallback_enforcePermission(); 10136 10137 Objects.requireNonNull(cb); 10138 mSpatializerHelper.unregisterHeadTrackingModeCallback(cb); 10139 } 10140 10141 /** @see Spatializer.SpatializerHeadTrackerAvailableDispatcherStub */ registerSpatializerHeadTrackerAvailableCallback( @onNull ISpatializerHeadTrackerAvailableCallback cb, boolean register)10142 public void registerSpatializerHeadTrackerAvailableCallback( 10143 @NonNull ISpatializerHeadTrackerAvailableCallback cb, boolean register) { 10144 Objects.requireNonNull(cb); 10145 mSpatializerHelper.registerHeadTrackerAvailableCallback(cb, register); 10146 } 10147 10148 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10149 /** @see Spatializer#setOnHeadToSoundstagePoseUpdatedListener */ registerHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)10150 public void registerHeadToSoundstagePoseCallback( 10151 @NonNull ISpatializerHeadToSoundStagePoseCallback cb) { 10152 super.registerHeadToSoundstagePoseCallback_enforcePermission(); 10153 10154 Objects.requireNonNull(cb); 10155 mSpatializerHelper.registerHeadToSoundstagePoseCallback(cb); 10156 } 10157 10158 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10159 /** @see Spatializer#clearOnHeadToSoundstagePoseUpdatedListener */ unregisterHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)10160 public void unregisterHeadToSoundstagePoseCallback( 10161 @NonNull ISpatializerHeadToSoundStagePoseCallback cb) { 10162 super.unregisterHeadToSoundstagePoseCallback_enforcePermission(); 10163 10164 Objects.requireNonNull(cb); 10165 mSpatializerHelper.unregisterHeadToSoundstagePoseCallback(cb); 10166 } 10167 10168 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10169 /** @see Spatializer#getSpatializerCompatibleAudioDevices() */ getSpatializerCompatibleAudioDevices()10170 public @NonNull List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices() { 10171 super.getSpatializerCompatibleAudioDevices_enforcePermission(); 10172 10173 return mSpatializerHelper.getCompatibleAudioDevices(); 10174 } 10175 10176 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10177 /** @see Spatializer#addSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */ addSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)10178 public void addSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { 10179 super.addSpatializerCompatibleAudioDevice_enforcePermission(); 10180 10181 Objects.requireNonNull(ada); 10182 mSpatializerHelper.addCompatibleAudioDevice(ada); 10183 } 10184 10185 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10186 /** @see Spatializer#removeSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */ removeSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)10187 public void removeSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { 10188 super.removeSpatializerCompatibleAudioDevice_enforcePermission(); 10189 10190 Objects.requireNonNull(ada); 10191 mSpatializerHelper.removeCompatibleAudioDevice(ada); 10192 } 10193 10194 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10195 /** @see Spatializer#getSupportedHeadTrackingModes() */ getSupportedHeadTrackingModes()10196 public int[] getSupportedHeadTrackingModes() { 10197 super.getSupportedHeadTrackingModes_enforcePermission(); 10198 10199 return mSpatializerHelper.getSupportedHeadTrackingModes(); 10200 } 10201 10202 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10203 /** @see Spatializer#getHeadTrackingMode() */ getActualHeadTrackingMode()10204 public int getActualHeadTrackingMode() { 10205 super.getActualHeadTrackingMode_enforcePermission(); 10206 10207 return mSpatializerHelper.getActualHeadTrackingMode(); 10208 } 10209 10210 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10211 /** @see Spatializer#getDesiredHeadTrackingMode() */ getDesiredHeadTrackingMode()10212 public int getDesiredHeadTrackingMode() { 10213 super.getDesiredHeadTrackingMode_enforcePermission(); 10214 10215 return mSpatializerHelper.getDesiredHeadTrackingMode(); 10216 } 10217 10218 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10219 /** @see Spatializer#setGlobalTransform */ setSpatializerGlobalTransform(@onNull float[] transform)10220 public void setSpatializerGlobalTransform(@NonNull float[] transform) { 10221 super.setSpatializerGlobalTransform_enforcePermission(); 10222 10223 Objects.requireNonNull(transform); 10224 mSpatializerHelper.setGlobalTransform(transform); 10225 } 10226 10227 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10228 /** @see Spatializer#recenterHeadTracker() */ recenterHeadTracker()10229 public void recenterHeadTracker() { 10230 super.recenterHeadTracker_enforcePermission(); 10231 10232 mSpatializerHelper.recenterHeadTracker(); 10233 } 10234 10235 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10236 /** @see Spatializer#setDesiredHeadTrackingMode */ setDesiredHeadTrackingMode(@patializer.HeadTrackingModeSet int mode)10237 public void setDesiredHeadTrackingMode(@Spatializer.HeadTrackingModeSet int mode) { 10238 super.setDesiredHeadTrackingMode_enforcePermission(); 10239 10240 switch(mode) { 10241 case Spatializer.HEAD_TRACKING_MODE_DISABLED: 10242 case Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD: 10243 case Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE: 10244 break; 10245 default: 10246 return; 10247 } 10248 mSpatializerHelper.setDesiredHeadTrackingMode(mode); 10249 } 10250 10251 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10252 /** @see Spatializer#setEffectParameter */ setSpatializerParameter(int key, @NonNull byte[] value)10253 public void setSpatializerParameter(int key, @NonNull byte[] value) { 10254 super.setSpatializerParameter_enforcePermission(); 10255 10256 Objects.requireNonNull(value); 10257 mSpatializerHelper.setEffectParameter(key, value); 10258 } 10259 10260 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10261 /** @see Spatializer#getEffectParameter */ getSpatializerParameter(int key, @NonNull byte[] value)10262 public void getSpatializerParameter(int key, @NonNull byte[] value) { 10263 super.getSpatializerParameter_enforcePermission(); 10264 10265 Objects.requireNonNull(value); 10266 mSpatializerHelper.getEffectParameter(key, value); 10267 } 10268 10269 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10270 /** @see Spatializer#getOutput */ getSpatializerOutput()10271 public int getSpatializerOutput() { 10272 super.getSpatializerOutput_enforcePermission(); 10273 10274 return mSpatializerHelper.getOutput(); 10275 } 10276 10277 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10278 /** @see Spatializer#setOnSpatializerOutputChangedListener */ registerSpatializerOutputCallback(ISpatializerOutputCallback cb)10279 public void registerSpatializerOutputCallback(ISpatializerOutputCallback cb) { 10280 super.registerSpatializerOutputCallback_enforcePermission(); 10281 10282 Objects.requireNonNull(cb); 10283 mSpatializerHelper.registerSpatializerOutputCallback(cb); 10284 } 10285 10286 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10287 /** @see Spatializer#clearOnSpatializerOutputChangedListener */ unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb)10288 public void unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb) { 10289 super.unregisterSpatializerOutputCallback_enforcePermission(); 10290 10291 Objects.requireNonNull(cb); 10292 mSpatializerHelper.unregisterSpatializerOutputCallback(cb); 10293 } 10294 10295 /** 10296 * post a message to schedule init/release of head tracking sensors 10297 * whether to initialize or release sensors is based on the state of spatializer 10298 */ postInitSpatializerHeadTrackingSensors()10299 void postInitSpatializerHeadTrackingSensors() { 10300 sendMsg(mAudioHandler, 10301 MSG_INIT_HEADTRACKING_SENSORS, 10302 SENDMSG_REPLACE, 10303 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0); 10304 } 10305 10306 /** 10307 * post a message to schedule a reset of the spatializer state 10308 */ postResetSpatializer()10309 void postResetSpatializer() { 10310 sendMsg(mAudioHandler, 10311 MSG_RESET_SPATIALIZER, 10312 SENDMSG_REPLACE, 10313 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0); 10314 } 10315 onInitAdiDeviceStates()10316 void onInitAdiDeviceStates() { 10317 mDeviceBroker.onReadAudioDeviceSettings(); 10318 mSoundDoseHelper.initCachedAudioDeviceCategories( 10319 mDeviceBroker.getImmutableDeviceInventory()); 10320 } 10321 onInitSpatializer()10322 void onInitSpatializer() { 10323 mSpatializerHelper.init(/*effectExpected*/ mHasSpatializerEffect); 10324 mSpatializerHelper.setFeatureEnabled(mHasSpatializerEffect); 10325 } 10326 isBluetoothPrividged()10327 private boolean isBluetoothPrividged() { 10328 return PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 10329 android.Manifest.permission.BLUETOOTH_CONNECT) 10330 || Binder.getCallingUid() == Process.SYSTEM_UID; 10331 } 10332 retrieveBluetoothAddresses(List<AudioDeviceAttributes> devices)10333 List<AudioDeviceAttributes> retrieveBluetoothAddresses(List<AudioDeviceAttributes> devices) { 10334 if (isBluetoothPrividged()) { 10335 return devices; 10336 } 10337 10338 List<AudioDeviceAttributes> checkedDevices = new ArrayList<AudioDeviceAttributes>(); 10339 for (AudioDeviceAttributes ada : devices) { 10340 if (ada == null) { 10341 continue; 10342 } 10343 checkedDevices.add(retrieveBluetoothAddressUncheked(ada)); 10344 } 10345 return checkedDevices; 10346 } 10347 retrieveBluetoothAddress(@onNull AudioDeviceAttributes ada)10348 AudioDeviceAttributes retrieveBluetoothAddress(@NonNull AudioDeviceAttributes ada) { 10349 if (isBluetoothPrividged()) { 10350 return ada; 10351 } 10352 return retrieveBluetoothAddressUncheked(ada); 10353 } 10354 retrieveBluetoothAddressUncheked(@onNull AudioDeviceAttributes ada)10355 AudioDeviceAttributes retrieveBluetoothAddressUncheked(@NonNull AudioDeviceAttributes ada) { 10356 Objects.requireNonNull(ada); 10357 if (AudioSystem.isBluetoothDevice(ada.getInternalType())) { 10358 String anonymizedAddress = anonymizeBluetoothAddress(ada.getAddress()); 10359 for (AdiDeviceState ads : mDeviceBroker.getImmutableDeviceInventory()) { 10360 if (!(AudioSystem.isBluetoothDevice(ads.getInternalDeviceType()) 10361 && (ada.getInternalType() == ads.getInternalDeviceType()) 10362 && anonymizedAddress.equals(anonymizeBluetoothAddress( 10363 ads.getDeviceAddress())))) { 10364 continue; 10365 } 10366 ada.setAddress(ads.getDeviceAddress()); 10367 break; 10368 } 10369 } 10370 return ada; 10371 } 10372 10373 /** 10374 * Convert a Bluetooth MAC address to an anonymized one when exposed to a non privileged app 10375 * Must match the implementation of BluetoothUtils.toAnonymizedAddress() 10376 * @param address Mac address to be anonymized 10377 * @return anonymized mac address 10378 */ anonymizeBluetoothAddress(String address)10379 static String anonymizeBluetoothAddress(String address) { 10380 if (address == null || address.length() != "AA:BB:CC:DD:EE:FF".length()) { 10381 return null; 10382 } 10383 return "XX:XX:XX:XX" + address.substring("XX:XX:XX:XX".length()); 10384 } 10385 anonymizeAudioDeviceAttributesList( List<AudioDeviceAttributes> devices)10386 private List<AudioDeviceAttributes> anonymizeAudioDeviceAttributesList( 10387 List<AudioDeviceAttributes> devices) { 10388 if (isBluetoothPrividged()) { 10389 return devices; 10390 } 10391 return anonymizeAudioDeviceAttributesListUnchecked(devices); 10392 } 10393 anonymizeAudioDeviceAttributesListUnchecked( List<AudioDeviceAttributes> devices)10394 /* package */ List<AudioDeviceAttributes> anonymizeAudioDeviceAttributesListUnchecked( 10395 List<AudioDeviceAttributes> devices) { 10396 List<AudioDeviceAttributes> anonymizedDevices = new ArrayList<AudioDeviceAttributes>(); 10397 for (AudioDeviceAttributes ada : devices) { 10398 anonymizedDevices.add(anonymizeAudioDeviceAttributesUnchecked(ada)); 10399 } 10400 return anonymizedDevices; 10401 } 10402 anonymizeAudioDeviceAttributesUnchecked( AudioDeviceAttributes ada)10403 private AudioDeviceAttributes anonymizeAudioDeviceAttributesUnchecked( 10404 AudioDeviceAttributes ada) { 10405 if (!AudioSystem.isBluetoothDevice(ada.getInternalType())) { 10406 return ada; 10407 } 10408 AudioDeviceAttributes res = new AudioDeviceAttributes(ada); 10409 res.setAddress(anonymizeBluetoothAddress(ada.getAddress())); 10410 return res; 10411 } 10412 anonymizeAudioDeviceAttributes(AudioDeviceAttributes ada)10413 private AudioDeviceAttributes anonymizeAudioDeviceAttributes(AudioDeviceAttributes ada) { 10414 if (isBluetoothPrividged()) { 10415 return ada; 10416 } 10417 10418 return anonymizeAudioDeviceAttributesUnchecked(ada); 10419 } 10420 10421 //========================================================================================== 10422 10423 // camera sound is forced if any of the resources corresponding to one active SIM 10424 // demands it. readCameraSoundForced()10425 private boolean readCameraSoundForced() { 10426 if (SystemProperties.getBoolean("audio.camerasound.force", false) 10427 || mContext.getResources().getBoolean( 10428 com.android.internal.R.bool.config_camera_sound_forced)) { 10429 return true; 10430 } 10431 10432 SubscriptionManager subscriptionManager = mContext.getSystemService( 10433 SubscriptionManager.class); 10434 if (subscriptionManager == null) { 10435 Log.e(TAG, "readCameraSoundForced cannot create SubscriptionManager!"); 10436 return false; 10437 } 10438 int[] subscriptionIds = subscriptionManager.getActiveSubscriptionIdList(false); 10439 for (int subId : subscriptionIds) { 10440 if (SubscriptionManager.getResourcesForSubId(mContext, subId).getBoolean( 10441 com.android.internal.R.bool.config_camera_sound_forced)) { 10442 return true; 10443 } 10444 } 10445 return false; 10446 } 10447 10448 //========================================================================================== 10449 private final Object mMuteAwaitConnectionLock = new Object(); 10450 10451 /** 10452 * The device that is expected to be connected soon, and causes players to be muted until 10453 * its connection, or it times out. 10454 * Null when no active muting command, or it has timed out. 10455 */ 10456 @GuardedBy("mMuteAwaitConnectionLock") 10457 private AudioDeviceAttributes mMutingExpectedDevice; 10458 @GuardedBy("mMuteAwaitConnectionLock") 10459 private @Nullable int[] mMutedUsagesAwaitingConnection; 10460 10461 /** @see AudioManager#muteAwaitConnection */ 10462 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection muteAwaitConnection(@onNull int[] usages, @NonNull AudioDeviceAttributes device, long timeOutMs)10463 public void muteAwaitConnection(@NonNull int[] usages, 10464 @NonNull AudioDeviceAttributes device, long timeOutMs) { 10465 Objects.requireNonNull(usages); 10466 Objects.requireNonNull(device); 10467 enforceModifyAudioRoutingPermission(); 10468 10469 final AudioDeviceAttributes ada = retrieveBluetoothAddress(device); 10470 10471 if (timeOutMs <= 0 || usages.length == 0) { 10472 throw new IllegalArgumentException("Invalid timeOutMs/usagesToMute"); 10473 } 10474 Log.i(TAG, "muteAwaitConnection dev:" + device + " timeOutMs:" + timeOutMs 10475 + " usages:" + Arrays.toString(usages)); 10476 10477 if (mDeviceBroker.isDeviceConnected(ada)) { 10478 // not throwing an exception as there could be a race between a connection (server-side, 10479 // notification of connection in flight) and a mute operation (client-side) 10480 Log.i(TAG, "muteAwaitConnection ignored, device (" + device + ") already connected"); 10481 return; 10482 } 10483 synchronized (mMuteAwaitConnectionLock) { 10484 if (mMutingExpectedDevice != null) { 10485 Log.e(TAG, "muteAwaitConnection ignored, another in progress for device:" 10486 + mMutingExpectedDevice); 10487 throw new IllegalStateException("muteAwaitConnection already in progress"); 10488 } 10489 mMutingExpectedDevice = ada; 10490 mMutedUsagesAwaitingConnection = usages; 10491 mPlaybackMonitor.muteAwaitConnection(usages, ada, timeOutMs); 10492 } 10493 dispatchMuteAwaitConnection((cb, isPrivileged) -> { 10494 try { 10495 AudioDeviceAttributes dev = ada; 10496 if (!isPrivileged) { 10497 dev = anonymizeAudioDeviceAttributesUnchecked(ada); 10498 } 10499 cb.dispatchOnMutedUntilConnection(dev, usages); 10500 } catch (RemoteException e) { } 10501 }); 10502 } 10503 10504 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 10505 /** @see AudioManager#getMutingExpectedDevice */ getMutingExpectedDevice()10506 public @Nullable AudioDeviceAttributes getMutingExpectedDevice() { 10507 super.getMutingExpectedDevice_enforcePermission(); 10508 10509 synchronized (mMuteAwaitConnectionLock) { 10510 return anonymizeAudioDeviceAttributes(mMutingExpectedDevice); 10511 } 10512 } 10513 10514 /** @see AudioManager#cancelMuteAwaitConnection */ 10515 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection cancelMuteAwaitConnection(@onNull AudioDeviceAttributes device)10516 public void cancelMuteAwaitConnection(@NonNull AudioDeviceAttributes device) { 10517 Objects.requireNonNull(device); 10518 enforceModifyAudioRoutingPermission(); 10519 10520 final AudioDeviceAttributes ada = retrieveBluetoothAddress(device); 10521 10522 Log.i(TAG, "cancelMuteAwaitConnection for device:" + device); 10523 final int[] mutedUsages; 10524 synchronized (mMuteAwaitConnectionLock) { 10525 if (mMutingExpectedDevice == null) { 10526 // not throwing an exception as there could be a race between a timeout 10527 // (server-side) and a cancel operation (client-side) 10528 Log.i(TAG, "cancelMuteAwaitConnection ignored, no expected device"); 10529 return; 10530 } 10531 if (!ada.equalTypeAddress(mMutingExpectedDevice)) { 10532 Log.e(TAG, "cancelMuteAwaitConnection ignored, got " + device 10533 + "] but expected device is" + mMutingExpectedDevice); 10534 throw new IllegalStateException("cancelMuteAwaitConnection for wrong device"); 10535 } 10536 mutedUsages = mMutedUsagesAwaitingConnection; 10537 mMutingExpectedDevice = null; 10538 mMutedUsagesAwaitingConnection = null; 10539 mPlaybackMonitor.cancelMuteAwaitConnection("cancelMuteAwaitConnection dev:" + device); 10540 } 10541 dispatchMuteAwaitConnection((cb, isPrivileged) -> { 10542 try { 10543 AudioDeviceAttributes dev = ada; 10544 if (!isPrivileged) { 10545 dev = anonymizeAudioDeviceAttributesUnchecked(ada); 10546 } 10547 cb.dispatchOnUnmutedEvent( 10548 AudioManager.MuteAwaitConnectionCallback.EVENT_CANCEL, dev, mutedUsages); 10549 } catch (RemoteException e) { } }); 10550 } 10551 10552 final RemoteCallbackList<IMuteAwaitConnectionCallback> mMuteAwaitConnectionDispatchers = 10553 new RemoteCallbackList<IMuteAwaitConnectionCallback>(); 10554 10555 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 10556 /** @see AudioManager#registerMuteAwaitConnectionCallback */ registerMuteAwaitConnectionDispatcher(@onNull IMuteAwaitConnectionCallback cb, boolean register)10557 public void registerMuteAwaitConnectionDispatcher(@NonNull IMuteAwaitConnectionCallback cb, 10558 boolean register) { 10559 super.registerMuteAwaitConnectionDispatcher_enforcePermission(); 10560 10561 if (register) { 10562 mMuteAwaitConnectionDispatchers.register(cb, isBluetoothPrividged()); 10563 } else { 10564 mMuteAwaitConnectionDispatchers.unregister(cb); 10565 } 10566 } 10567 10568 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection checkMuteAwaitConnection()10569 void checkMuteAwaitConnection() { 10570 final AudioDeviceAttributes device; 10571 final int[] mutedUsages; 10572 synchronized (mMuteAwaitConnectionLock) { 10573 if (mMutingExpectedDevice == null) { 10574 return; 10575 } 10576 device = mMutingExpectedDevice; 10577 mutedUsages = mMutedUsagesAwaitingConnection; 10578 if (!mDeviceBroker.isDeviceConnected(device)) { 10579 return; 10580 } 10581 mMutingExpectedDevice = null; 10582 mMutedUsagesAwaitingConnection = null; 10583 mPlaybackMonitor.cancelMuteAwaitConnection( 10584 "checkMuteAwaitConnection device " + device + " connected, unmuting"); 10585 } 10586 dispatchMuteAwaitConnection((cb, isPrivileged) -> { 10587 try { 10588 AudioDeviceAttributes ada = device; 10589 if (!isPrivileged) { 10590 ada = anonymizeAudioDeviceAttributesUnchecked(device); 10591 } 10592 cb.dispatchOnUnmutedEvent(AudioManager.MuteAwaitConnectionCallback.EVENT_CONNECTION, 10593 ada, mutedUsages); 10594 } catch (RemoteException e) { } }); 10595 } 10596 10597 /** 10598 * Called by PlaybackActivityMonitor when the timeout hit for the mute on device connection 10599 */ 10600 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection onMuteAwaitConnectionTimeout(@onNull AudioDeviceAttributes timedOutDevice)10601 void onMuteAwaitConnectionTimeout(@NonNull AudioDeviceAttributes timedOutDevice) { 10602 final int[] mutedUsages; 10603 synchronized (mMuteAwaitConnectionLock) { 10604 if (!timedOutDevice.equals(mMutingExpectedDevice)) { 10605 return; 10606 } 10607 Log.i(TAG, "muteAwaitConnection timeout, clearing expected device " 10608 + mMutingExpectedDevice); 10609 mutedUsages = mMutedUsagesAwaitingConnection; 10610 mMutingExpectedDevice = null; 10611 mMutedUsagesAwaitingConnection = null; 10612 } 10613 dispatchMuteAwaitConnection((cb, isPrivileged) -> { 10614 try { 10615 cb.dispatchOnUnmutedEvent( 10616 AudioManager.MuteAwaitConnectionCallback.EVENT_TIMEOUT, 10617 timedOutDevice, mutedUsages); 10618 } catch (RemoteException e) { } }); 10619 } 10620 dispatchMuteAwaitConnection( java.util.function.BiConsumer<IMuteAwaitConnectionCallback, Boolean> callback)10621 private void dispatchMuteAwaitConnection( 10622 java.util.function.BiConsumer<IMuteAwaitConnectionCallback, Boolean> callback) { 10623 final int nbDispatchers = mMuteAwaitConnectionDispatchers.beginBroadcast(); 10624 // lazy initialization as errors unlikely 10625 ArrayList<IMuteAwaitConnectionCallback> errorList = null; 10626 for (int i = 0; i < nbDispatchers; i++) { 10627 try { 10628 callback.accept(mMuteAwaitConnectionDispatchers.getBroadcastItem(i), 10629 (Boolean) mMuteAwaitConnectionDispatchers.getBroadcastCookie(i)); 10630 } catch (Exception e) { 10631 if (errorList == null) { 10632 errorList = new ArrayList<>(1); 10633 } 10634 errorList.add(mMuteAwaitConnectionDispatchers.getBroadcastItem(i)); 10635 } 10636 } 10637 if (errorList != null) { 10638 for (IMuteAwaitConnectionCallback errorItem : errorList) { 10639 mMuteAwaitConnectionDispatchers.unregister(errorItem); 10640 } 10641 } 10642 mMuteAwaitConnectionDispatchers.finishBroadcast(); 10643 } 10644 10645 final RemoteCallbackList<IDeviceVolumeBehaviorDispatcher> mDeviceVolumeBehaviorDispatchers = 10646 new RemoteCallbackList<IDeviceVolumeBehaviorDispatcher>(); 10647 10648 /** 10649 * @see AudioDeviceVolumeManager#addOnDeviceVolumeBehaviorChangedListener and 10650 * AudioDeviceVolumeManager#removeOnDeviceVolumeBehaviorChangedListener 10651 */ registerDeviceVolumeBehaviorDispatcher(boolean register, @NonNull IDeviceVolumeBehaviorDispatcher dispatcher)10652 public void registerDeviceVolumeBehaviorDispatcher(boolean register, 10653 @NonNull IDeviceVolumeBehaviorDispatcher dispatcher) { 10654 enforceQueryStateOrModifyRoutingPermission(); 10655 Objects.requireNonNull(dispatcher); 10656 if (register) { 10657 mDeviceVolumeBehaviorDispatchers.register(dispatcher); 10658 } else { 10659 mDeviceVolumeBehaviorDispatchers.unregister(dispatcher); 10660 } 10661 } 10662 dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior)10663 private void dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior) { 10664 final int dispatchers = mDeviceVolumeBehaviorDispatchers.beginBroadcast(); 10665 for (int i = 0; i < dispatchers; i++) { 10666 try { 10667 mDeviceVolumeBehaviorDispatchers.getBroadcastItem(i) 10668 .dispatchDeviceVolumeBehaviorChanged(device, volumeBehavior); 10669 } catch (RemoteException e) { 10670 } 10671 } 10672 mDeviceVolumeBehaviorDispatchers.finishBroadcast(); 10673 } 10674 10675 //========================================================================================== 10676 // Device orientation 10677 //========================================================================================== 10678 /** 10679 * Handles device configuration changes that may map to a change in rotation. 10680 * Monitoring rotation is optional, and is defined by the definition and value 10681 * of the "ro.audio.monitorRotation" system property. 10682 */ onConfigurationChanged()10683 private void onConfigurationChanged() { 10684 try { 10685 // reading new configuration "safely" (i.e. under try catch) in case anything 10686 // goes wrong. 10687 Configuration config = mContext.getResources().getConfiguration(); 10688 mSoundDoseHelper.configureSafeMedia(/*forced*/false, TAG); 10689 10690 boolean cameraSoundForced = readCameraSoundForced(); 10691 synchronized (mSettingsLock) { 10692 final boolean cameraSoundForcedChanged = (cameraSoundForced != mCameraSoundForced); 10693 mCameraSoundForced = cameraSoundForced; 10694 if (cameraSoundForcedChanged) { 10695 if (!mIsSingleVolume) { 10696 synchronized (VolumeStreamState.class) { 10697 VolumeStreamState s = mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED]; 10698 if (cameraSoundForced) { 10699 s.setAllIndexesToMax(); 10700 mRingerModeAffectedStreams &= 10701 ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 10702 } else { 10703 s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM], TAG); 10704 mRingerModeAffectedStreams |= 10705 (1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 10706 } 10707 } 10708 // take new state into account for streams muted by ringer mode 10709 setRingerModeInt(getRingerModeInternal(), false); 10710 } 10711 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, 10712 cameraSoundForced ? 10713 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE, 10714 "onConfigurationChanged"); 10715 sendMsg(mAudioHandler, 10716 MSG_SET_ALL_VOLUMES, 10717 SENDMSG_QUEUE, 10718 0, 10719 0, 10720 mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED], 0); 10721 10722 } 10723 } 10724 mVolumeController.setLayoutDirection(config.getLayoutDirection()); 10725 } catch (Exception e) { 10726 Log.e(TAG, "Error handling configuration change: ", e); 10727 } 10728 } 10729 10730 @Override setRingtonePlayer(IRingtonePlayer player)10731 public void setRingtonePlayer(IRingtonePlayer player) { 10732 mContext.enforceCallingOrSelfPermission(REMOTE_AUDIO_PLAYBACK, null); 10733 mRingtonePlayer = player; 10734 } 10735 10736 @Override getRingtonePlayer()10737 public IRingtonePlayer getRingtonePlayer() { 10738 return mRingtonePlayer; 10739 } 10740 10741 @Override startWatchingRoutes(IAudioRoutesObserver observer)10742 public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) { 10743 return mDeviceBroker.startWatchingRoutes(observer); 10744 } 10745 10746 @Override disableSafeMediaVolume(String callingPackage)10747 public void disableSafeMediaVolume(String callingPackage) { 10748 enforceVolumeController("disable the safe media volume"); 10749 mSoundDoseHelper.disableSafeMediaVolume(callingPackage); 10750 } 10751 10752 @Override lowerVolumeToRs1(String callingPackage)10753 public void lowerVolumeToRs1(String callingPackage) { 10754 enforceVolumeController("lowerVolumeToRs1"); 10755 postLowerVolumeToRs1(); 10756 } 10757 postLowerVolumeToRs1()10758 /*package*/ void postLowerVolumeToRs1() { 10759 sendMsg(mAudioHandler, MSG_LOWER_VOLUME_TO_RS1, SENDMSG_QUEUE, 10760 // no params, no delay 10761 0, 0, null, 0); 10762 } 10763 10764 /** 10765 * Called when handling MSG_LOWER_VOLUME_TO_RS1 10766 */ onLowerVolumeToRs1()10767 private void onLowerVolumeToRs1() { 10768 final ArrayList<AudioDeviceAttributes> devices = getDevicesForAttributesInt( 10769 new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(), true); 10770 final int nativeDeviceType; 10771 final AudioDeviceAttributes ada; 10772 if (!devices.isEmpty()) { 10773 ada = devices.get(0); 10774 nativeDeviceType = ada.getInternalType(); 10775 } else { 10776 nativeDeviceType = AudioSystem.DEVICE_OUT_USB_HEADSET; 10777 ada = new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_USB_HEADSET, ""); 10778 } 10779 final int index = mSoundDoseHelper.safeMediaVolumeIndex(nativeDeviceType); 10780 setStreamVolumeWithAttributionInt(STREAM_MUSIC, index, /*flags*/ 0, ada, 10781 "com.android.server.audio", "AudioService"); 10782 } 10783 10784 @Override 10785 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) getOutputRs2UpperBound()10786 public float getOutputRs2UpperBound() { 10787 super.getOutputRs2UpperBound_enforcePermission(); 10788 return mSoundDoseHelper.getOutputRs2UpperBound(); 10789 } 10790 10791 @Override 10792 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setOutputRs2UpperBound(float rs2Value)10793 public void setOutputRs2UpperBound(float rs2Value) { 10794 super.setOutputRs2UpperBound_enforcePermission(); 10795 mSoundDoseHelper.setOutputRs2UpperBound(rs2Value); 10796 } 10797 10798 @Override 10799 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) getCsd()10800 public float getCsd() { 10801 super.getCsd_enforcePermission(); 10802 return mSoundDoseHelper.getCsd(); 10803 } 10804 10805 @Override 10806 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setCsd(float csd)10807 public void setCsd(float csd) { 10808 super.setCsd_enforcePermission(); 10809 if (csd < 0.0f) { 10810 mSoundDoseHelper.resetCsdTimeouts(); 10811 } else { 10812 mSoundDoseHelper.setCsd(csd); 10813 } 10814 } 10815 10816 @Override 10817 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) forceUseFrameworkMel(boolean useFrameworkMel)10818 public void forceUseFrameworkMel(boolean useFrameworkMel) { 10819 super.forceUseFrameworkMel_enforcePermission(); 10820 mSoundDoseHelper.forceUseFrameworkMel(useFrameworkMel); 10821 } 10822 10823 @Override 10824 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices)10825 public void forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices) { 10826 super.forceComputeCsdOnAllDevices_enforcePermission(); 10827 mSoundDoseHelper.forceComputeCsdOnAllDevices(computeCsdOnAllDevices); 10828 } 10829 10830 @Override 10831 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isCsdEnabled()10832 public boolean isCsdEnabled() { 10833 super.isCsdEnabled_enforcePermission(); 10834 return mSoundDoseHelper.isCsdEnabled(); 10835 } 10836 10837 @Override 10838 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isCsdAsAFeatureAvailable()10839 public boolean isCsdAsAFeatureAvailable() { 10840 super.isCsdAsAFeatureAvailable_enforcePermission(); 10841 return mSoundDoseHelper.isCsdAsAFeatureAvailable(); 10842 } 10843 10844 @Override 10845 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isCsdAsAFeatureEnabled()10846 public boolean isCsdAsAFeatureEnabled() { 10847 super.isCsdAsAFeatureEnabled_enforcePermission(); 10848 return mSoundDoseHelper.isCsdAsAFeatureEnabled(); 10849 } 10850 10851 @Override 10852 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setCsdAsAFeatureEnabled(boolean csdToggleValue)10853 public void setCsdAsAFeatureEnabled(boolean csdToggleValue) { 10854 super.setCsdAsAFeatureEnabled_enforcePermission(); 10855 mSoundDoseHelper.setCsdAsAFeatureEnabled(csdToggleValue); 10856 } 10857 10858 @Override 10859 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setBluetoothAudioDeviceCategory(@onNull String address, boolean isBle, @AudioDeviceCategory int btAudioDeviceCategory)10860 public void setBluetoothAudioDeviceCategory(@NonNull String address, boolean isBle, 10861 @AudioDeviceCategory int btAudioDeviceCategory) { 10862 super.setBluetoothAudioDeviceCategory_enforcePermission(); 10863 10864 final String addr = Objects.requireNonNull(address); 10865 10866 AdiDeviceState deviceState = mDeviceBroker.findBtDeviceStateForAddress(addr, isBle); 10867 10868 int internalType = !isBle ? DEVICE_OUT_BLUETOOTH_A2DP 10869 : ((btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES) 10870 ? DEVICE_OUT_BLE_HEADSET : DEVICE_OUT_BLE_SPEAKER); 10871 int deviceType = !isBle ? TYPE_BLUETOOTH_A2DP 10872 : ((btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES) ? TYPE_BLE_HEADSET 10873 : TYPE_BLE_SPEAKER); 10874 10875 if (deviceState == null) { 10876 deviceState = new AdiDeviceState(deviceType, internalType, addr); 10877 } 10878 10879 deviceState.setAudioDeviceCategory(btAudioDeviceCategory); 10880 10881 mDeviceBroker.addOrUpdateBtAudioDeviceCategoryInInventory(deviceState); 10882 mDeviceBroker.persistAudioDeviceSettings(); 10883 10884 mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes()); 10885 mSoundDoseHelper.setAudioDeviceCategory(addr, internalType, 10886 btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES); 10887 } 10888 10889 @Override 10890 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) 10891 @AudioDeviceCategory getBluetoothAudioDeviceCategory(@onNull String address, boolean isBle)10892 public int getBluetoothAudioDeviceCategory(@NonNull String address, boolean isBle) { 10893 super.getBluetoothAudioDeviceCategory_enforcePermission(); 10894 10895 final AdiDeviceState deviceState = mDeviceBroker.findBtDeviceStateForAddress( 10896 Objects.requireNonNull(address), isBle); 10897 if (deviceState == null) { 10898 return AUDIO_DEVICE_CATEGORY_UNKNOWN; 10899 } 10900 10901 return deviceState.getAudioDeviceCategory(); 10902 } 10903 10904 //========================================================================================== 10905 // Hdmi CEC: 10906 // - System audio mode: 10907 // If Hdmi Cec's system audio mode is on, audio service should send the volume change 10908 // to HdmiControlService so that the audio receiver can handle it. 10909 // - CEC sink: 10910 // OUT_HDMI becomes a "full volume device", i.e. output is always at maximum level 10911 // and volume changes won't be taken into account on this device. Volume adjustments 10912 // are transformed into key events for the HDMI playback client. 10913 //========================================================================================== 10914 10915 @GuardedBy("mHdmiClientLock") updateHdmiCecSinkLocked(boolean hdmiCecSink)10916 private void updateHdmiCecSinkLocked(boolean hdmiCecSink) { 10917 if (!hasDeviceVolumeBehavior(AudioSystem.DEVICE_OUT_HDMI)) { 10918 if (hdmiCecSink) { 10919 if (DEBUG_VOL) { 10920 Log.d(TAG, "CEC sink: setting HDMI as full vol device"); 10921 } 10922 setDeviceVolumeBehaviorInternal( 10923 new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""), 10924 AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL, 10925 "AudioService.updateHdmiCecSinkLocked()"); 10926 } else { 10927 if (DEBUG_VOL) { 10928 Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device"); 10929 } 10930 // Android TV devices without CEC service apply software volume on 10931 // HDMI output 10932 setDeviceVolumeBehaviorInternal( 10933 new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""), 10934 AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE, 10935 "AudioService.updateHdmiCecSinkLocked()"); 10936 } 10937 postUpdateVolumeStatesForAudioDevice(AudioSystem.DEVICE_OUT_HDMI, 10938 "HdmiPlaybackClient.DisplayStatusCallback"); 10939 } 10940 } 10941 10942 private class MyHdmiControlStatusChangeListenerCallback 10943 implements HdmiControlManager.HdmiControlStatusChangeListener { onStatusChange(@dmiControlManager.HdmiCecControl int isCecEnabled, boolean isCecAvailable)10944 public void onStatusChange(@HdmiControlManager.HdmiCecControl int isCecEnabled, 10945 boolean isCecAvailable) { 10946 synchronized (mHdmiClientLock) { 10947 if (mHdmiManager == null) return; 10948 boolean cecEnabled = isCecEnabled == HdmiControlManager.HDMI_CEC_CONTROL_ENABLED; 10949 updateHdmiCecSinkLocked(cecEnabled ? isCecAvailable : false); 10950 } 10951 } 10952 }; 10953 10954 private class MyHdmiCecVolumeControlFeatureListener 10955 implements HdmiControlManager.HdmiCecVolumeControlFeatureListener { onHdmiCecVolumeControlFeature( @dmiControlManager.VolumeControl int hdmiCecVolumeControl)10956 public void onHdmiCecVolumeControlFeature( 10957 @HdmiControlManager.VolumeControl int hdmiCecVolumeControl) { 10958 synchronized (mHdmiClientLock) { 10959 if (mHdmiManager == null) return; 10960 mHdmiCecVolumeControlEnabled = 10961 hdmiCecVolumeControl == HdmiControlManager.VOLUME_CONTROL_ENABLED; 10962 } 10963 } 10964 }; 10965 10966 private final Object mHdmiClientLock = new Object(); 10967 10968 // If HDMI-CEC system audio is supported 10969 // Note that for CEC volume commands mHdmiCecVolumeControlEnabled will play a role on volume 10970 // commands 10971 private boolean mHdmiSystemAudioSupported = false; 10972 // Set only when device is tv. 10973 @GuardedBy("mHdmiClientLock") 10974 private HdmiTvClient mHdmiTvClient; 10975 // true if the device has system feature PackageManager.FEATURE_LEANBACK. 10976 // cached HdmiControlManager interface 10977 @GuardedBy("mHdmiClientLock") 10978 private HdmiControlManager mHdmiManager; 10979 // Set only when device is a set-top box. 10980 @GuardedBy("mHdmiClientLock") 10981 private HdmiPlaybackClient mHdmiPlaybackClient; 10982 // Set only when device is an audio system. 10983 @GuardedBy("mHdmiClientLock") 10984 private HdmiAudioSystemClient mHdmiAudioSystemClient; 10985 // True when volume control over HDMI CEC is used when CEC is enabled (meaningless otherwise) 10986 @GuardedBy("mHdmiClientLock") 10987 private boolean mHdmiCecVolumeControlEnabled; 10988 10989 private MyHdmiControlStatusChangeListenerCallback mHdmiControlStatusChangeListenerCallback = 10990 new MyHdmiControlStatusChangeListenerCallback(); 10991 10992 private MyHdmiCecVolumeControlFeatureListener mMyHdmiCecVolumeControlFeatureListener = 10993 new MyHdmiCecVolumeControlFeatureListener(); 10994 10995 @Override setHdmiSystemAudioSupported(boolean on)10996 public int setHdmiSystemAudioSupported(boolean on) { 10997 int device = AudioSystem.DEVICE_NONE; 10998 synchronized (mHdmiClientLock) { 10999 if (mHdmiManager != null) { 11000 if (mHdmiTvClient == null && mHdmiAudioSystemClient == null) { 11001 Log.w(TAG, "Only Hdmi-Cec enabled TV or audio system device supports" 11002 + "system audio mode."); 11003 return device; 11004 } 11005 if (mHdmiSystemAudioSupported != on) { 11006 mHdmiSystemAudioSupported = on; 11007 final int config = on ? AudioSystem.FORCE_HDMI_SYSTEM_AUDIO_ENFORCED : 11008 AudioSystem.FORCE_NONE; 11009 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_HDMI_SYSTEM_AUDIO, config, 11010 "setHdmiSystemAudioSupported"); 11011 } 11012 // TODO(b/185386781): Update AudioManager API to use device list. 11013 // So far, this value appears to be advisory for debug log. 11014 device = getDeviceMaskForStream(AudioSystem.STREAM_MUSIC); 11015 } 11016 } 11017 return device; 11018 } 11019 11020 @Override isHdmiSystemAudioSupported()11021 public boolean isHdmiSystemAudioSupported() { 11022 return mHdmiSystemAudioSupported; 11023 } 11024 11025 //========================================================================================== 11026 // Accessibility 11027 initA11yMonitoring()11028 private void initA11yMonitoring() { 11029 final AccessibilityManager accessibilityManager = 11030 (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); 11031 updateDefaultStreamOverrideDelay(accessibilityManager.isTouchExplorationEnabled()); 11032 updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive()); 11033 accessibilityManager.addTouchExplorationStateChangeListener(this, null); 11034 accessibilityManager.addAccessibilityServicesStateChangeListener(this); 11035 } 11036 11037 //--------------------------------------------------------------------------------- 11038 // A11y: taking touch exploration into account for selecting the default 11039 // stream override timeout when adjusting volume 11040 //--------------------------------------------------------------------------------- 11041 11042 // - STREAM_NOTIFICATION on tablets during this period after a notification stopped 11043 // - STREAM_RING on phones during this period after a notification stopped 11044 // - STREAM_MUSIC otherwise 11045 11046 private static final int DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS = 0; 11047 private static final int TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS = 1000; 11048 11049 private static int sStreamOverrideDelayMs; 11050 11051 @Override onTouchExplorationStateChanged(boolean enabled)11052 public void onTouchExplorationStateChanged(boolean enabled) { 11053 updateDefaultStreamOverrideDelay(enabled); 11054 } 11055 updateDefaultStreamOverrideDelay(boolean touchExploreEnabled)11056 private void updateDefaultStreamOverrideDelay(boolean touchExploreEnabled) { 11057 if (touchExploreEnabled) { 11058 sStreamOverrideDelayMs = TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS; 11059 } else { 11060 sStreamOverrideDelayMs = DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS; 11061 } 11062 if (DEBUG_VOL) Log.d(TAG, "Touch exploration enabled=" + touchExploreEnabled 11063 + " stream override delay is now " + sStreamOverrideDelayMs + " ms"); 11064 } 11065 11066 //--------------------------------------------------------------------------------- 11067 // A11y: taking a11y state into account for the handling of a11y prompts volume 11068 //--------------------------------------------------------------------------------- 11069 11070 private static boolean sIndependentA11yVolume = false; 11071 11072 // implementation of AccessibilityServicesStateChangeListener 11073 @Override onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager)11074 public void onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager) { 11075 updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive()); 11076 } 11077 updateA11yVolumeAlias(boolean a11VolEnabled)11078 private void updateA11yVolumeAlias(boolean a11VolEnabled) { 11079 if (DEBUG_VOL) Log.d(TAG, "Accessibility volume enabled = " + a11VolEnabled); 11080 if (sIndependentA11yVolume != a11VolEnabled) { 11081 sIndependentA11yVolume = a11VolEnabled; 11082 // update the volume mapping scheme 11083 updateStreamVolumeAlias(true /*updateVolumes*/, TAG); 11084 // update the volume controller behavior 11085 mVolumeController.setA11yMode(sIndependentA11yVolume ? 11086 VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME : 11087 VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME); 11088 mVolumeController.postVolumeChanged(AudioManager.STREAM_ACCESSIBILITY, 0); 11089 } 11090 } 11091 11092 //========================================================================================== 11093 // Camera shutter sound policy. 11094 // config_camera_sound_forced configuration option in config.xml defines if the camera shutter 11095 // sound is forced (sound even if the device is in silent mode) or not. This option is false by 11096 // default and can be overridden by country specific overlay in values-mccXXX/config.xml. 11097 //========================================================================================== 11098 11099 // cached value of com.android.internal.R.bool.config_camera_sound_forced 11100 @GuardedBy("mSettingsLock") 11101 private boolean mCameraSoundForced; 11102 11103 // called by android.hardware.Camera to populate CameraInfo.canDisableShutterSound isCameraSoundForced()11104 public boolean isCameraSoundForced() { 11105 synchronized (mSettingsLock) { 11106 return mCameraSoundForced; 11107 } 11108 } 11109 11110 //========================================================================================== 11111 // AudioService logging and dumpsys 11112 //========================================================================================== 11113 static final int LOG_NB_EVENTS_LIFECYCLE = 20; 11114 static final int LOG_NB_EVENTS_PHONE_STATE = 20; 11115 static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 50; 11116 static final int LOG_NB_EVENTS_FORCE_USE = 20; 11117 static final int LOG_NB_EVENTS_VOLUME = 100; 11118 static final int LOG_NB_EVENTS_DYN_POLICY = 10; 11119 static final int LOG_NB_EVENTS_SPATIAL = 30; 11120 static final int LOG_NB_EVENTS_SOUND_DOSE = 30; 11121 11122 static final EventLogger 11123 sLifecycleLogger = new EventLogger(LOG_NB_EVENTS_LIFECYCLE, 11124 "audio services lifecycle"); 11125 11126 static final EventLogger sMuteLogger = new EventLogger(30, 11127 "mute commands"); 11128 11129 final private EventLogger 11130 mModeLogger = new EventLogger(LOG_NB_EVENTS_PHONE_STATE, 11131 "phone state (logged after successful call to AudioSystem.setPhoneState(int, int))"); 11132 11133 // logs for wired + A2DP device connections: 11134 // - wired: logged before onSetWiredDeviceConnectionState() is executed 11135 // - A2DP: logged at reception of method call 11136 /*package*/ static final EventLogger 11137 sDeviceLogger = new EventLogger( 11138 LOG_NB_EVENTS_DEVICE_CONNECTION, "wired/A2DP/hearing aid device connection"); 11139 11140 static final EventLogger 11141 sForceUseLogger = new EventLogger( 11142 LOG_NB_EVENTS_FORCE_USE, 11143 "force use (logged before setForceUse() is executed)"); 11144 11145 static final EventLogger 11146 sVolumeLogger = new EventLogger(LOG_NB_EVENTS_VOLUME, 11147 "volume changes (logged when command received by AudioService)"); 11148 11149 static final EventLogger 11150 sSpatialLogger = new EventLogger(LOG_NB_EVENTS_SPATIAL, 11151 "spatial audio"); 11152 11153 final private EventLogger 11154 mDynPolicyLogger = new EventLogger(LOG_NB_EVENTS_DYN_POLICY, 11155 "dynamic policy events (logged when command received by AudioService)"); 11156 11157 private static final String[] RINGER_MODE_NAMES = new String[] { 11158 "SILENT", 11159 "VIBRATE", 11160 "NORMAL" 11161 }; 11162 dumpRingerMode(PrintWriter pw)11163 private void dumpRingerMode(PrintWriter pw) { 11164 pw.println("\nRinger mode: "); 11165 pw.println("- mode (internal) = " + RINGER_MODE_NAMES[mRingerMode]); 11166 pw.println("- mode (external) = " + RINGER_MODE_NAMES[mRingerModeExternal]); 11167 pw.println("- zen mode:" + Settings.Global.zenModeToString(mNm.getZenMode())); 11168 dumpRingerModeStreams(pw, "affected", mRingerModeAffectedStreams); 11169 dumpRingerModeStreams(pw, "muted", sRingerAndZenModeMutedStreams); 11170 pw.print("- delegate = "); pw.println(mRingerModeDelegate); 11171 } 11172 dumpRingerModeStreams(PrintWriter pw, String type, int streams)11173 private void dumpRingerModeStreams(PrintWriter pw, String type, int streams) { 11174 pw.print("- ringer mode "); pw.print(type); pw.print(" streams = 0x"); 11175 pw.print(Integer.toHexString(streams)); 11176 if (streams != 0) { 11177 pw.print(" ("); 11178 boolean first = true; 11179 for (int i = 0; i < AudioSystem.STREAM_NAMES.length; i++) { 11180 final int stream = (1 << i); 11181 if ((streams & stream) != 0) { 11182 if (!first) pw.print(','); 11183 pw.print(AudioSystem.STREAM_NAMES[i]); 11184 streams &= ~stream; 11185 first = false; 11186 } 11187 } 11188 if (streams != 0) { 11189 if (!first) pw.print(','); 11190 pw.print(streams); 11191 } 11192 pw.print(')'); 11193 } 11194 pw.println(); 11195 } 11196 getAbsoluteVolumeDevicesWithBehavior(int behavior)11197 private Set<Integer> getAbsoluteVolumeDevicesWithBehavior(int behavior) { 11198 return mAbsoluteVolumeDeviceInfoMap.entrySet().stream() 11199 .filter(entry -> entry.getValue().mDeviceVolumeBehavior == behavior) 11200 .map(Map.Entry::getKey) 11201 .collect(Collectors.toSet()); 11202 } 11203 dumpDeviceTypes(@onNull Set<Integer> deviceTypes)11204 private String dumpDeviceTypes(@NonNull Set<Integer> deviceTypes) { 11205 Iterator<Integer> it = deviceTypes.iterator(); 11206 if (!it.hasNext()) { 11207 return ""; 11208 } 11209 final StringBuilder sb = new StringBuilder(); 11210 sb.append("0x" + Integer.toHexString(it.next())); 11211 while (it.hasNext()) { 11212 sb.append("," + "0x" + Integer.toHexString(it.next())); 11213 } 11214 return sb.toString(); 11215 } 11216 11217 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)11218 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11219 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 11220 11221 sLifecycleLogger.dump(pw); 11222 if (mAudioHandler != null) { 11223 pw.println("\nMessage handler (watch for unhandled messages):"); 11224 mAudioHandler.dump(new PrintWriterPrinter(pw), " "); 11225 } else { 11226 pw.println("\nMessage handler is null"); 11227 } 11228 mMediaFocusControl.dump(pw); 11229 dumpStreamStates(pw); 11230 dumpVolumeGroups(pw); 11231 dumpRingerMode(pw); 11232 dumpAudioMode(pw); 11233 pw.println("\nAudio routes:"); 11234 pw.print(" mMainType=0x"); pw.println(Integer.toHexString( 11235 mDeviceBroker.getCurAudioRoutes().mainType)); 11236 pw.print(" mBluetoothName="); pw.println(mDeviceBroker.getCurAudioRoutes().bluetoothName); 11237 11238 pw.println("\nOther state:"); 11239 pw.print(" mUseVolumeGroupAliases="); pw.println(mUseVolumeGroupAliases); 11240 pw.print(" mVolumeController="); pw.println(mVolumeController); 11241 mSoundDoseHelper.dump(pw); 11242 pw.print(" sIndependentA11yVolume="); pw.println(sIndependentA11yVolume); 11243 pw.print(" mCameraSoundForced="); pw.println(isCameraSoundForced()); 11244 pw.print(" mHasVibrator="); pw.println(mHasVibrator); 11245 pw.print(" mVolumePolicy="); pw.println(mVolumePolicy); 11246 pw.print(" mAvrcpAbsVolSupported="); pw.println(mAvrcpAbsVolSupported); 11247 pw.print(" mBtScoOnByApp="); pw.println(mBtScoOnByApp); 11248 pw.print(" mIsSingleVolume="); pw.println(mIsSingleVolume); 11249 pw.print(" mUseFixedVolume="); pw.println(mUseFixedVolume); 11250 pw.print(" mNotifAliasRing="); pw.println(mNotifAliasRing); 11251 pw.print(" mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices)); 11252 pw.print(" mFullVolumeDevices="); pw.println(dumpDeviceTypes(mFullVolumeDevices)); 11253 pw.print(" absolute volume devices="); pw.println(dumpDeviceTypes( 11254 getAbsoluteVolumeDevicesWithBehavior( 11255 AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE))); 11256 pw.print(" adjust-only absolute volume devices="); pw.println(dumpDeviceTypes( 11257 getAbsoluteVolumeDevicesWithBehavior( 11258 AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY))); 11259 pw.print(" mExtVolumeController="); pw.println(mExtVolumeController); 11260 pw.print(" mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient); 11261 pw.print(" mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient); 11262 pw.print(" mHdmiTvClient="); pw.println(mHdmiTvClient); 11263 pw.print(" mHdmiSystemAudioSupported="); pw.println(mHdmiSystemAudioSupported); 11264 synchronized (mHdmiClientLock) { 11265 pw.print(" mHdmiCecVolumeControlEnabled="); pw.println(mHdmiCecVolumeControlEnabled); 11266 } 11267 pw.print(" mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported); 11268 pw.print(" mic mute FromSwitch=" + mMicMuteFromSwitch 11269 + " FromRestrictions=" + mMicMuteFromRestrictions 11270 + " FromApi=" + mMicMuteFromApi 11271 + " from system=" + mMicMuteFromSystemCached); 11272 dumpAccessibilityServiceUids(pw); 11273 dumpAssistantServicesUids(pw); 11274 11275 pw.print(" supportsBluetoothVariableLatency="); 11276 pw.println(AudioSystem.supportsBluetoothVariableLatency()); 11277 pw.print(" isBluetoothVariableLatencyEnabled="); 11278 pw.println(AudioSystem.isBluetoothVariableLatencyEnabled()); 11279 11280 dumpAudioPolicies(pw); 11281 mDynPolicyLogger.dump(pw); 11282 mPlaybackMonitor.dump(pw); 11283 mRecordMonitor.dump(pw); 11284 11285 pw.println("\nAudioDeviceBroker:"); 11286 mDeviceBroker.dump(pw, " "); 11287 pw.println("\nSoundEffects:"); 11288 mSfxHelper.dump(pw, " "); 11289 11290 pw.println("\n"); 11291 pw.println("\nEvent logs:"); 11292 mModeLogger.dump(pw); 11293 pw.println("\n"); 11294 sDeviceLogger.dump(pw); 11295 pw.println("\n"); 11296 sForceUseLogger.dump(pw); 11297 pw.println("\n"); 11298 sVolumeLogger.dump(pw); 11299 pw.println("\n"); 11300 sMuteLogger.dump(pw); 11301 pw.println("\n"); 11302 dumpSupportedSystemUsage(pw); 11303 11304 pw.println("\n"); 11305 pw.println("\nSpatial audio:"); 11306 pw.println("mHasSpatializerEffect:" + mHasSpatializerEffect + " (effect present)"); 11307 pw.println("isSpatializerEnabled:" + isSpatializerEnabled() + " (routing dependent)"); 11308 mSpatializerHelper.dump(pw); 11309 sSpatialLogger.dump(pw); 11310 11311 mAudioSystem.dump(pw); 11312 } 11313 dumpSupportedSystemUsage(PrintWriter pw)11314 private void dumpSupportedSystemUsage(PrintWriter pw) { 11315 pw.println("Supported System Usages:"); 11316 synchronized (mSupportedSystemUsagesLock) { 11317 for (int i = 0; i < mSupportedSystemUsages.length; i++) { 11318 pw.printf("\t%s\n", AudioAttributes.usageToString(mSupportedSystemUsages[i])); 11319 } 11320 } 11321 } 11322 dumpAssistantServicesUids(PrintWriter pw)11323 private void dumpAssistantServicesUids(PrintWriter pw) { 11324 synchronized (mSettingsLock) { 11325 if (mAssistantUids.size() > 0) { 11326 pw.println(" Assistant service UIDs:"); 11327 for (int uid : mAssistantUids) { 11328 pw.println(" - " + uid); 11329 } 11330 } else { 11331 pw.println(" No Assistant service Uids."); 11332 } 11333 } 11334 } 11335 dumpAccessibilityServiceUids(PrintWriter pw)11336 private void dumpAccessibilityServiceUids(PrintWriter pw) { 11337 synchronized (mSupportedSystemUsagesLock) { 11338 if (mAccessibilityServiceUids != null && mAccessibilityServiceUids.length > 0) { 11339 pw.println(" Accessibility service Uids:"); 11340 for (int uid : mAccessibilityServiceUids) { 11341 pw.println(" - " + uid); 11342 } 11343 } else { 11344 pw.println(" No accessibility service Uids."); 11345 } 11346 } 11347 } 11348 11349 /** 11350 * Audio Analytics ids. 11351 */ 11352 private static final String mMetricsId = MediaMetrics.Name.AUDIO_SERVICE 11353 + MediaMetrics.SEPARATOR; 11354 11355 // Inform AudioFlinger of our device's low RAM attribute readAndSetLowRamDevice()11356 private static void readAndSetLowRamDevice() 11357 { 11358 boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic(); 11359 long totalMemory = 1024 * 1024 * 1024; // 1GB is the default if ActivityManager fails. 11360 11361 try { 11362 final ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo(); 11363 ActivityManager.getService().getMemoryInfo(info); 11364 totalMemory = info.totalMem; 11365 } catch (RemoteException e) { 11366 Log.w(TAG, "Cannot obtain MemoryInfo from ActivityManager, assume low memory device"); 11367 isLowRamDevice = true; 11368 } 11369 11370 final int status = AudioSystem.setLowRamDevice(isLowRamDevice, totalMemory); 11371 if (status != 0) { 11372 Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status); 11373 } 11374 } 11375 enforceVolumeController(String action)11376 private void enforceVolumeController(String action) { 11377 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE, 11378 "Only SystemUI can " + action); 11379 } 11380 11381 @Override setVolumeController(final IVolumeController controller)11382 public void setVolumeController(final IVolumeController controller) { 11383 enforceVolumeController("set the volume controller"); 11384 11385 // return early if things are not actually changing 11386 if (mVolumeController.isSameBinder(controller)) { 11387 return; 11388 } 11389 11390 // dismiss the old volume controller 11391 mVolumeController.postDismiss(); 11392 if (controller != null) { 11393 // we are about to register a new controller, listen for its death 11394 try { 11395 controller.asBinder().linkToDeath(new DeathRecipient() { 11396 @Override 11397 public void binderDied() { 11398 if (mVolumeController.isSameBinder(controller)) { 11399 Log.w(TAG, "Current remote volume controller died, unregistering"); 11400 setVolumeController(null); 11401 } 11402 } 11403 }, 0); 11404 } catch (RemoteException e) { 11405 // noop 11406 } 11407 } 11408 mVolumeController.setController(controller); 11409 if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController); 11410 } 11411 11412 @Override 11413 @Nullable getVolumeController()11414 public IVolumeController getVolumeController() { 11415 enforceVolumeController("get the volume controller"); 11416 if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController); 11417 11418 return mVolumeController.getController(); 11419 } 11420 11421 @Override notifyVolumeControllerVisible(final IVolumeController controller, boolean visible)11422 public void notifyVolumeControllerVisible(final IVolumeController controller, boolean visible) { 11423 enforceVolumeController("notify about volume controller visibility"); 11424 11425 // return early if the controller is not current 11426 if (!mVolumeController.isSameBinder(controller)) { 11427 return; 11428 } 11429 11430 mVolumeController.setVisible(visible); 11431 if (DEBUG_VOL) Log.d(TAG, "Volume controller visible: " + visible); 11432 } 11433 11434 @Override setVolumePolicy(VolumePolicy policy)11435 public void setVolumePolicy(VolumePolicy policy) { 11436 enforceVolumeController("set volume policy"); 11437 if (policy != null && !policy.equals(mVolumePolicy)) { 11438 mVolumePolicy = policy; 11439 if (DEBUG_VOL) Log.d(TAG, "Volume policy changed: " + mVolumePolicy); 11440 } 11441 } 11442 11443 /** Interface used for enforcing the safe hearing standard. */ 11444 public interface ISafeHearingVolumeController { 11445 /** Displays an instructional safeguard as required by the safe hearing standard. */ postDisplaySafeVolumeWarning(int flags)11446 void postDisplaySafeVolumeWarning(int flags); 11447 11448 /** Displays a warning about transient exposure to high level playback */ postDisplayCsdWarning(@udioManager.CsdWarning int csdEvent, int displayDurationMs)11449 void postDisplayCsdWarning(@AudioManager.CsdWarning int csdEvent, int displayDurationMs); 11450 } 11451 11452 /** Wrapper which encapsulates the {@link IVolumeController} functionality. */ 11453 public class VolumeController implements ISafeHearingVolumeController { 11454 private static final String TAG = "VolumeController"; 11455 11456 private IVolumeController mController; 11457 private boolean mVisible; 11458 private long mNextLongPress; 11459 private int mLongPressTimeout; 11460 setController(IVolumeController controller)11461 public void setController(IVolumeController controller) { 11462 mController = controller; 11463 mVisible = false; 11464 } 11465 getController()11466 public IVolumeController getController() { 11467 return mController; 11468 } 11469 loadSettings(ContentResolver cr)11470 public void loadSettings(ContentResolver cr) { 11471 mLongPressTimeout = mSettings.getSecureIntForUser(cr, 11472 Settings.Secure.LONG_PRESS_TIMEOUT, 500, UserHandle.USER_CURRENT); 11473 } 11474 suppressAdjustment(int resolvedStream, int flags, boolean isMute)11475 public boolean suppressAdjustment(int resolvedStream, int flags, boolean isMute) { 11476 if (isMute) { 11477 return false; 11478 } 11479 boolean suppress = false; 11480 // Intended behavior: 11481 // 1/ if the stream is not the default UI stream, do not suppress (as it is not involved 11482 // in bringing up the UI) 11483 // 2/ if the resolved and default stream is MUSIC, and media is playing, do not suppress 11484 // 3/ otherwise suppress the first adjustments that occur during the "long press 11485 // timeout" interval. Note this is true regardless of whether this is a "real long 11486 // press" (where the user keeps pressing on the volume button), or repeated single 11487 // presses (here we don't know if we are in a real long press, or repeated fast 11488 // button presses). 11489 // Once the long press timeout occurs (mNextLongPress reset to 0), do not suppress. 11490 // Example: for a default and resolved stream of MUSIC, this allows modifying rapidly 11491 // the volume when media is playing (whether by long press or repeated individual 11492 // presses), or to bring up the volume UI when media is not playing, in order to make 11493 // another change (e.g. switch ringer modes) without changing media volume. 11494 if (resolvedStream == DEFAULT_VOL_STREAM_NO_PLAYBACK && mController != null) { 11495 // never suppress media vol adjustement during media playback 11496 if (resolvedStream == AudioSystem.STREAM_MUSIC 11497 && mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, mLongPressTimeout)) 11498 { 11499 // media is playing, adjust the volume right away 11500 return false; 11501 } 11502 11503 final long now = SystemClock.uptimeMillis(); 11504 if ((flags & AudioManager.FLAG_SHOW_UI) != 0 && !mVisible) { 11505 // UI is not visible yet, adjustment is ignored 11506 if (mNextLongPress < now) { 11507 mNextLongPress = now + mLongPressTimeout; 11508 } 11509 suppress = true; 11510 } else if (mNextLongPress > 0) { // in a long-press 11511 if (now > mNextLongPress) { 11512 // long press triggered, no more suppression 11513 mNextLongPress = 0; 11514 } else { 11515 // keep suppressing until the long press triggers 11516 suppress = true; 11517 } 11518 } 11519 } 11520 return suppress; 11521 } 11522 setVisible(boolean visible)11523 public void setVisible(boolean visible) { 11524 mVisible = visible; 11525 } 11526 isSameBinder(IVolumeController controller)11527 public boolean isSameBinder(IVolumeController controller) { 11528 return Objects.equals(asBinder(), binder(controller)); 11529 } 11530 asBinder()11531 public IBinder asBinder() { 11532 return binder(mController); 11533 } 11534 binder(IVolumeController controller)11535 private IBinder binder(IVolumeController controller) { 11536 return controller == null ? null : controller.asBinder(); 11537 } 11538 11539 @Override toString()11540 public String toString() { 11541 return "VolumeController(" + asBinder() + ",mVisible=" + mVisible + ")"; 11542 } 11543 11544 @Override postDisplaySafeVolumeWarning(int flags)11545 public void postDisplaySafeVolumeWarning(int flags) { 11546 if (mController == null) 11547 return; 11548 flags = flags | AudioManager.FLAG_SHOW_UI; 11549 try { 11550 mController.displaySafeVolumeWarning(flags); 11551 } catch (RemoteException e) { 11552 Log.w(TAG, "Error calling displaySafeVolumeWarning", e); 11553 } 11554 } 11555 11556 @Override postDisplayCsdWarning( @udioManager.CsdWarning int csdWarning, int displayDurationMs)11557 public void postDisplayCsdWarning( 11558 @AudioManager.CsdWarning int csdWarning, int displayDurationMs) { 11559 if (mController == null) { 11560 Log.e(TAG, "Unable to display CSD warning, no controller"); 11561 return; 11562 } 11563 try { 11564 mController.displayCsdWarning(csdWarning, displayDurationMs); 11565 } catch (RemoteException e) { 11566 Log.w(TAG, "Error calling displayCsdWarning for warning " + csdWarning, e); 11567 } 11568 } 11569 postVolumeChanged(int streamType, int flags)11570 public void postVolumeChanged(int streamType, int flags) { 11571 if (mController == null) 11572 return; 11573 try { 11574 mController.volumeChanged(streamType, flags); 11575 } catch (RemoteException e) { 11576 Log.w(TAG, "Error calling volumeChanged", e); 11577 } 11578 } 11579 postMasterMuteChanged(int flags)11580 public void postMasterMuteChanged(int flags) { 11581 if (mController == null) 11582 return; 11583 try { 11584 mController.masterMuteChanged(flags); 11585 } catch (RemoteException e) { 11586 Log.w(TAG, "Error calling masterMuteChanged", e); 11587 } 11588 } 11589 setLayoutDirection(int layoutDirection)11590 public void setLayoutDirection(int layoutDirection) { 11591 if (mController == null) 11592 return; 11593 try { 11594 mController.setLayoutDirection(layoutDirection); 11595 } catch (RemoteException e) { 11596 Log.w(TAG, "Error calling setLayoutDirection", e); 11597 } 11598 } 11599 postDismiss()11600 public void postDismiss() { 11601 if (mController == null) 11602 return; 11603 try { 11604 mController.dismiss(); 11605 } catch (RemoteException e) { 11606 Log.w(TAG, "Error calling dismiss", e); 11607 } 11608 } 11609 setA11yMode(int a11yMode)11610 public void setA11yMode(int a11yMode) { 11611 if (mController == null) 11612 return; 11613 try { 11614 mController.setA11yMode(a11yMode); 11615 } catch (RemoteException e) { 11616 Log.w(TAG, "Error calling setA11Mode", e); 11617 } 11618 } 11619 } 11620 11621 /** 11622 * Interface for system components to get some extra functionality through 11623 * LocalServices. 11624 */ 11625 final class AudioServiceInternal extends AudioManagerInternal { 11626 @Override setRingerModeDelegate(RingerModeDelegate delegate)11627 public void setRingerModeDelegate(RingerModeDelegate delegate) { 11628 mRingerModeDelegate = delegate; 11629 if (mRingerModeDelegate != null) { 11630 synchronized (mSettingsLock) { 11631 updateRingerAndZenModeAffectedStreams(); 11632 } 11633 setRingerModeInternal(getRingerModeInternal(), TAG + ".setRingerModeDelegate"); 11634 } 11635 } 11636 11637 @Override getRingerModeInternal()11638 public int getRingerModeInternal() { 11639 return AudioService.this.getRingerModeInternal(); 11640 } 11641 11642 @Override setRingerModeInternal(int ringerMode, String caller)11643 public void setRingerModeInternal(int ringerMode, String caller) { 11644 AudioService.this.setRingerModeInternal(ringerMode, caller); 11645 } 11646 11647 @Override silenceRingerModeInternal(String caller)11648 public void silenceRingerModeInternal(String caller) { 11649 AudioService.this.silenceRingerModeInternal(caller); 11650 } 11651 11652 @Override updateRingerModeAffectedStreamsInternal()11653 public void updateRingerModeAffectedStreamsInternal() { 11654 synchronized (mSettingsLock) { 11655 if (updateRingerAndZenModeAffectedStreams()) { 11656 setRingerModeInt(getRingerModeInternal(), false); 11657 } 11658 } 11659 } 11660 11661 @Override addAssistantServiceUid(int uid)11662 public void addAssistantServiceUid(int uid) { 11663 sendMsg(mAudioHandler, MSG_ADD_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE, 11664 uid, 0, null, 0); 11665 } 11666 11667 @Override removeAssistantServiceUid(int uid)11668 public void removeAssistantServiceUid(int uid) { 11669 sendMsg(mAudioHandler, MSG_REMOVE_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE, 11670 uid, 0, null, 0); 11671 } 11672 11673 @Override setActiveAssistantServicesUids(IntArray activeUids)11674 public void setActiveAssistantServicesUids(IntArray activeUids) { 11675 synchronized (mSettingsLock) { 11676 if (activeUids.size() == 0) { 11677 mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS; 11678 } else { 11679 boolean changed = (mActiveAssistantServiceUids == null) 11680 || (mActiveAssistantServiceUids.length != activeUids.size()); 11681 if (!changed) { 11682 for (int i = 0; i < mActiveAssistantServiceUids.length; i++) { 11683 if (activeUids.get(i) != mActiveAssistantServiceUids[i]) { 11684 changed = true; 11685 break; 11686 } 11687 } 11688 } 11689 if (changed) { 11690 mActiveAssistantServiceUids = activeUids.toArray(); 11691 } 11692 } 11693 } 11694 sendMsg(mAudioHandler, MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID, SENDMSG_REPLACE, 11695 0, 0, null, 0); 11696 } 11697 11698 @Override setAccessibilityServiceUids(IntArray uids)11699 public void setAccessibilityServiceUids(IntArray uids) { 11700 // TODO(b/233287010): Fix voice interaction and a11y concurrency in audio policy service 11701 if (isPlatformAutomotive()) { 11702 return; 11703 } 11704 11705 synchronized (mAccessibilityServiceUidsLock) { 11706 if (uids.size() == 0) { 11707 mAccessibilityServiceUids = null; 11708 } else { 11709 boolean changed = (mAccessibilityServiceUids == null) 11710 || (mAccessibilityServiceUids.length != uids.size()); 11711 if (!changed) { 11712 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 11713 if (uids.get(i) != mAccessibilityServiceUids[i]) { 11714 changed = true; 11715 break; 11716 } 11717 } 11718 } 11719 if (changed) { 11720 mAccessibilityServiceUids = uids.toArray(); 11721 } 11722 } 11723 sendMsg(mAudioHandler, MSG_UPDATE_A11Y_SERVICE_UIDS, SENDMSG_REPLACE, 11724 0, 0, null, 0); 11725 } 11726 } 11727 11728 /** 11729 * {@inheritDoc} 11730 */ 11731 @Override setInputMethodServiceUid(int uid)11732 public void setInputMethodServiceUid(int uid) { 11733 synchronized (mInputMethodServiceUidLock) { 11734 if (mInputMethodServiceUid != uid) { 11735 mAudioSystem.setCurrentImeUid(uid); 11736 mInputMethodServiceUid = uid; 11737 } 11738 } 11739 } 11740 } 11741 onUpdateAccessibilityServiceUids()11742 private void onUpdateAccessibilityServiceUids() { 11743 int[] accessibilityServiceUids; 11744 synchronized (mAccessibilityServiceUidsLock) { 11745 accessibilityServiceUids = mAccessibilityServiceUids; 11746 } 11747 AudioSystem.setA11yServicesUids(accessibilityServiceUids); 11748 } 11749 11750 //========================================================================================== 11751 // Audio policy management 11752 //========================================================================================== registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)11753 public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, 11754 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, 11755 boolean isVolumeController, IMediaProjection projection) { 11756 AudioSystem.setDynamicPolicyCallback(mDynPolicyCallback); 11757 11758 if (!isPolicyRegisterAllowed(policyConfig, 11759 isFocusPolicy || isTestFocusPolicy || hasFocusListener, 11760 isVolumeController, 11761 projection)) { 11762 Slog.w(TAG, "Permission denied to register audio policy for pid " 11763 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid() 11764 + ", need system permission or a MediaProjection that can project audio"); 11765 return null; 11766 } 11767 11768 String regId = null; 11769 synchronized (mAudioPolicies) { 11770 if (mAudioPolicies.containsKey(pcb.asBinder())) { 11771 Slog.e(TAG, "Cannot re-register policy"); 11772 return null; 11773 } 11774 try { 11775 AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, pcb, hasFocusListener, 11776 isFocusPolicy, isTestFocusPolicy, isVolumeController, projection); 11777 pcb.asBinder().linkToDeath(app, 0/*flags*/); 11778 11779 // logging after registration so we have the registration id 11780 mDynPolicyLogger.enqueue((new EventLogger.StringEvent("registerAudioPolicy for " 11781 + pcb.asBinder() + " u/pid:" + Binder.getCallingUid() + "/" 11782 + Binder.getCallingPid() + " with config:" + app.toCompactLogString())) 11783 .printLog(TAG)); 11784 11785 regId = app.getRegistrationId(); 11786 mAudioPolicies.put(pcb.asBinder(), app); 11787 } catch (RemoteException e) { 11788 // audio policy owner has already died! 11789 Slog.w(TAG, "Audio policy registration failed, could not link to " + pcb + 11790 " binder death", e); 11791 return null; 11792 } catch (IllegalStateException e) { 11793 Slog.w(TAG, "Audio policy registration failed for binder " + pcb, e); 11794 return null; 11795 } 11796 } 11797 return regId; 11798 } 11799 11800 /** 11801 * Called by an AudioPolicyProxy when the client dies. 11802 * Checks if an active playback for media use case is currently routed to one of the 11803 * remote submix devices owned by this dynamic policy and broadcasts a becoming noisy 11804 * intend in this case. 11805 * @param addresses list of remote submix device addresses to check. 11806 */ onPolicyClientDeath(List<String> addresses)11807 private void onPolicyClientDeath(List<String> addresses) { 11808 for (String address : addresses) { 11809 if (mPlaybackMonitor.hasActiveMediaPlaybackOnSubmixWithAddress(address)) { 11810 mDeviceBroker.postBroadcastBecomingNoisy(); 11811 return; 11812 } 11813 } 11814 } 11815 /** 11816 * Apps with MODIFY_AUDIO_ROUTING can register any policy. 11817 * Apps with an audio capable MediaProjection are allowed to register a RENDER|LOOPBACK policy 11818 * as those policy do not modify the audio routing. 11819 */ isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, boolean hasFocusAccess, boolean isVolumeController, IMediaProjection projection)11820 private boolean isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, 11821 boolean hasFocusAccess, 11822 boolean isVolumeController, 11823 IMediaProjection projection) { 11824 11825 boolean requireValidProjection = false; 11826 boolean requireCaptureAudioOrMediaOutputPerm = false; 11827 boolean requireModifyRouting = false; 11828 boolean requireCallAudioInterception = false; 11829 ArrayList<AudioMix> voiceCommunicationCaptureMixes = null; 11830 11831 11832 if (hasFocusAccess || isVolumeController) { 11833 requireModifyRouting |= true; 11834 } else if (policyConfig.getMixes().isEmpty()) { 11835 // An empty policy could be used to lock the focus or add mixes later 11836 requireModifyRouting |= true; 11837 } 11838 for (AudioMix mix : policyConfig.getMixes()) { 11839 // If mix is requesting privileged capture 11840 if (mix.getRule().allowPrivilegedMediaPlaybackCapture()) { 11841 // then its format must be low quality enough 11842 String privilegedMediaCaptureError = 11843 mix.canBeUsedForPrivilegedMediaCapture(mix.getFormat()); 11844 if (privilegedMediaCaptureError != null) { 11845 Log.e(TAG, privilegedMediaCaptureError); 11846 return false; 11847 } 11848 // and it must have CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT permission 11849 requireCaptureAudioOrMediaOutputPerm |= true; 11850 11851 } 11852 // If mix is trying to explicitly capture USAGE_VOICE_COMMUNICATION 11853 if (mix.containsMatchAttributeRuleForUsage( 11854 AudioAttributes.USAGE_VOICE_COMMUNICATION) 11855 && (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER)) { 11856 // It must have CAPTURE_USAGE_VOICE_COMMUNICATION_OUTPUT permission 11857 // Note that for UID, USERID or EXCLDUE rules, the capture will be silenced 11858 // in AudioPolicyMix 11859 if (voiceCommunicationCaptureMixes == null) { 11860 voiceCommunicationCaptureMixes = new ArrayList<AudioMix>(); 11861 } 11862 voiceCommunicationCaptureMixes.add(mix); 11863 } 11864 11865 // If mix is RENDER|LOOPBACK, then an audio MediaProjection is enough 11866 // otherwise MODIFY_AUDIO_ROUTING permission is required 11867 if (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER && projection != null) { 11868 requireValidProjection |= true; 11869 } else if (mix.isForCallRedirection()) { 11870 requireCallAudioInterception |= true; 11871 } else if (mix.containsMatchAttributeRuleForUsage( 11872 AudioAttributes.USAGE_VOICE_COMMUNICATION)) { 11873 requireModifyRouting |= true; 11874 } 11875 } 11876 11877 if (requireCaptureAudioOrMediaOutputPerm 11878 && !callerHasPermission(android.Manifest.permission.CAPTURE_MEDIA_OUTPUT) 11879 && !callerHasPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT)) { 11880 Log.e(TAG, "Privileged audio capture requires CAPTURE_MEDIA_OUTPUT or " 11881 + "CAPTURE_AUDIO_OUTPUT system permission"); 11882 return false; 11883 } 11884 11885 if (voiceCommunicationCaptureMixes != null && voiceCommunicationCaptureMixes.size() > 0) { 11886 if (!callerHasPermission( 11887 android.Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT)) { 11888 Log.e(TAG, "Audio capture for voice communication requires " 11889 + "CAPTURE_VOICE_COMMUNICATION_OUTPUT system permission"); 11890 return false; 11891 } 11892 11893 // If permission check succeeded, we set the flag in each of the mixing rules 11894 for (AudioMix mix : voiceCommunicationCaptureMixes) { 11895 mix.getRule().setVoiceCommunicationCaptureAllowed(true); 11896 } 11897 } 11898 11899 if (requireValidProjection && !canProjectAudio(projection)) { 11900 return false; 11901 } 11902 11903 if (requireModifyRouting 11904 && !callerHasPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)) { 11905 Log.e(TAG, "Can not capture audio without MODIFY_AUDIO_ROUTING"); 11906 return false; 11907 } 11908 11909 if (requireCallAudioInterception 11910 && !callerHasPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION)) { 11911 Log.e(TAG, "Can not capture audio without CALL_AUDIO_INTERCEPTION"); 11912 return false; 11913 } 11914 11915 return true; 11916 } 11917 callerHasPermission(String permission)11918 private boolean callerHasPermission(String permission) { 11919 return mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED; 11920 } 11921 11922 /** @return true if projection is a valid MediaProjection that can project audio. */ canProjectAudio(IMediaProjection projection)11923 private boolean canProjectAudio(IMediaProjection projection) { 11924 if (projection == null) { 11925 Log.e(TAG, "MediaProjection is null"); 11926 return false; 11927 } 11928 11929 IMediaProjectionManager projectionService = getProjectionService(); 11930 if (projectionService == null) { 11931 Log.e(TAG, "Can't get service IMediaProjectionManager"); 11932 return false; 11933 } 11934 11935 final long token = Binder.clearCallingIdentity(); 11936 try { 11937 if (!projectionService.isCurrentProjection(projection)) { 11938 Log.w(TAG, "App passed invalid MediaProjection token"); 11939 return false; 11940 } 11941 } catch (RemoteException e) { 11942 Log.e(TAG, "Can't call .isCurrentProjection() on IMediaProjectionManager" 11943 + projectionService.asBinder(), e); 11944 return false; 11945 } finally { 11946 Binder.restoreCallingIdentity(token); 11947 } 11948 11949 try { 11950 if (!projection.canProjectAudio()) { 11951 Log.w(TAG, "App passed MediaProjection that can not project audio"); 11952 return false; 11953 } 11954 } catch (RemoteException e) { 11955 Log.e(TAG, "Can't call .canProjectAudio() on valid IMediaProjection" 11956 + projection.asBinder(), e); 11957 return false; 11958 } 11959 11960 return true; 11961 } 11962 getProjectionService()11963 private IMediaProjectionManager getProjectionService() { 11964 if (mProjectionService == null) { 11965 IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE); 11966 mProjectionService = IMediaProjectionManager.Stub.asInterface(b); 11967 } 11968 return mProjectionService; 11969 } 11970 11971 /** 11972 * See {@link AudioManager#unregisterAudioPolicyAsync(AudioPolicy)} 11973 * Declared oneway 11974 * @param pcb nullable because on service interface 11975 */ unregisterAudioPolicyAsync(@ullable IAudioPolicyCallback pcb)11976 public void unregisterAudioPolicyAsync(@Nullable IAudioPolicyCallback pcb) { 11977 if (pcb == null) { 11978 return; 11979 } 11980 unregisterAudioPolicyInt(pcb, "unregisterAudioPolicyAsync"); 11981 } 11982 11983 /** 11984 * See {@link AudioManager#unregisterAudioPolicy(AudioPolicy)} 11985 * @param pcb nullable because on service interface 11986 */ unregisterAudioPolicy(@ullable IAudioPolicyCallback pcb)11987 public void unregisterAudioPolicy(@Nullable IAudioPolicyCallback pcb) { 11988 if (pcb == null) { 11989 return; 11990 } 11991 unregisterAudioPolicyInt(pcb, "unregisterAudioPolicy"); 11992 } 11993 11994 unregisterAudioPolicyInt(@onNull IAudioPolicyCallback pcb, String operationName)11995 private void unregisterAudioPolicyInt(@NonNull IAudioPolicyCallback pcb, String operationName) { 11996 mDynPolicyLogger.enqueue((new EventLogger.StringEvent(operationName + " for " 11997 + pcb.asBinder()).printLog(TAG))); 11998 synchronized (mAudioPolicies) { 11999 AudioPolicyProxy app = mAudioPolicies.remove(pcb.asBinder()); 12000 if (app == null) { 12001 Slog.w(TAG, "Trying to unregister unknown audio policy for pid " 12002 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()); 12003 return; 12004 } else { 12005 pcb.asBinder().unlinkToDeath(app, 0/*flags*/); 12006 } 12007 app.release(); 12008 } 12009 // TODO implement clearing mix attribute matching info in native audio policy 12010 } 12011 12012 /** 12013 * Checks whether caller has MODIFY_AUDIO_ROUTING permission, and the policy is registered. 12014 * @param errorMsg log warning if permission check failed. 12015 * @return null if the operation on the audio mixes should be cancelled. 12016 */ 12017 @GuardedBy("mAudioPolicies") checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg)12018 private AudioPolicyProxy checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg) { 12019 // permission check 12020 final boolean hasPermissionForPolicy = 12021 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 12022 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 12023 if (!hasPermissionForPolicy) { 12024 Slog.w(TAG, errorMsg + " for pid " + 12025 + Binder.getCallingPid() + " / uid " 12026 + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING"); 12027 return null; 12028 } 12029 // policy registered? 12030 final AudioPolicyProxy app = mAudioPolicies.get(pcb.asBinder()); 12031 if (app == null) { 12032 Slog.w(TAG, errorMsg + " for pid " + 12033 + Binder.getCallingPid() + " / uid " 12034 + Binder.getCallingUid() + ", unregistered policy"); 12035 return null; 12036 } 12037 return app; 12038 } 12039 addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)12040 public int addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) { 12041 if (DEBUG_AP) { Log.d(TAG, "addMixForPolicy for " + pcb.asBinder() 12042 + " with config:" + policyConfig); } 12043 synchronized (mAudioPolicies) { 12044 final AudioPolicyProxy app = 12045 checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy"); 12046 if (app == null){ 12047 return AudioManager.ERROR; 12048 } 12049 return app.addMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS 12050 ? AudioManager.SUCCESS : AudioManager.ERROR; 12051 } 12052 } 12053 removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)12054 public int removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) { 12055 if (DEBUG_AP) { Log.d(TAG, "removeMixForPolicy for " + pcb.asBinder() 12056 + " with config:" + policyConfig); } 12057 synchronized (mAudioPolicies) { 12058 final AudioPolicyProxy app = 12059 checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy"); 12060 if (app == null) { 12061 return AudioManager.ERROR; 12062 } 12063 return app.removeMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS 12064 ? AudioManager.SUCCESS : AudioManager.ERROR; 12065 } 12066 } 12067 12068 /** see AudioPolicy.setUidDeviceAffinity() */ setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)12069 public int setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, 12070 @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) { 12071 if (DEBUG_AP) { 12072 Log.d(TAG, "setUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid); 12073 } 12074 synchronized (mAudioPolicies) { 12075 final AudioPolicyProxy app = 12076 checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy"); 12077 if (app == null) { 12078 return AudioManager.ERROR; 12079 } 12080 if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) { 12081 return AudioManager.ERROR; 12082 } 12083 return app.setUidDeviceAffinities(uid, deviceTypes, deviceAddresses); 12084 } 12085 } 12086 12087 /** see AudioPolicy.setUserIdDeviceAffinity() */ setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)12088 public int setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, 12089 @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) { 12090 if (DEBUG_AP) { 12091 Log.d(TAG, "setUserIdDeviceAffinity for " + pcb.asBinder() + " user:" + userId); 12092 } 12093 12094 synchronized (mAudioPolicies) { 12095 final AudioPolicyProxy app = 12096 checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy"); 12097 if (app == null) { 12098 return AudioManager.ERROR; 12099 } 12100 if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) { 12101 return AudioManager.ERROR; 12102 } 12103 return app.setUserIdDeviceAffinities(userId, deviceTypes, deviceAddresses); 12104 } 12105 } 12106 12107 /** see AudioPolicy.removeUidDeviceAffinity() */ removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid)12108 public int removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid) { 12109 if (DEBUG_AP) { 12110 Log.d(TAG, "removeUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid); 12111 } 12112 synchronized (mAudioPolicies) { 12113 final AudioPolicyProxy app = 12114 checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy"); 12115 if (app == null) { 12116 return AudioManager.ERROR; 12117 } 12118 return app.removeUidDeviceAffinities(uid); 12119 } 12120 } 12121 12122 /** see AudioPolicy.removeUserIdDeviceAffinity() */ removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId)12123 public int removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId) { 12124 if (DEBUG_AP) { 12125 Log.d(TAG, "removeUserIdDeviceAffinity for " + pcb.asBinder() 12126 + " userId:" + userId); 12127 } 12128 synchronized (mAudioPolicies) { 12129 final AudioPolicyProxy app = 12130 checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy"); 12131 if (app == null) { 12132 return AudioManager.ERROR; 12133 } 12134 return app.removeUserIdDeviceAffinities(userId); 12135 } 12136 } 12137 setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb)12138 public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) { 12139 if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior 12140 + " policy " + pcb.asBinder()); 12141 synchronized (mAudioPolicies) { 12142 final AudioPolicyProxy app = 12143 checkUpdateForPolicy(pcb, "Cannot change audio policy focus properties"); 12144 if (app == null){ 12145 return AudioManager.ERROR; 12146 } 12147 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 12148 Slog.e(TAG, "Cannot change audio policy focus properties, unregistered policy"); 12149 return AudioManager.ERROR; 12150 } 12151 if (duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 12152 // is there already one policy managing ducking? 12153 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 12154 if (policy.mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 12155 Slog.e(TAG, "Cannot change audio policy ducking behavior, already handled"); 12156 return AudioManager.ERROR; 12157 } 12158 } 12159 } 12160 app.mFocusDuckBehavior = duckingBehavior; 12161 mMediaFocusControl.setDuckingInExtPolicyAvailable( 12162 duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY); 12163 } 12164 return AudioManager.SUCCESS; 12165 } 12166 12167 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 12168 /** @see AudioPolicy#getFocusStack() */ getFocusStack()12169 public List<AudioFocusInfo> getFocusStack() { 12170 super.getFocusStack_enforcePermission(); 12171 12172 return mMediaFocusControl.getFocusStack(); 12173 } 12174 12175 /** @see AudioPolicy#sendFocusLoss */ sendFocusLoss(@onNull AudioFocusInfo focusLoser, @NonNull IAudioPolicyCallback apcb)12176 public boolean sendFocusLoss(@NonNull AudioFocusInfo focusLoser, 12177 @NonNull IAudioPolicyCallback apcb) { 12178 Objects.requireNonNull(focusLoser); 12179 Objects.requireNonNull(apcb); 12180 enforceModifyAudioRoutingPermission(); 12181 if (!mAudioPolicies.containsKey(apcb.asBinder())) { 12182 throw new IllegalStateException("Only registered AudioPolicy can change focus"); 12183 } 12184 if (!mAudioPolicies.get(apcb.asBinder()).mHasFocusListener) { 12185 throw new IllegalStateException("AudioPolicy must have focus listener to change focus"); 12186 } 12187 return mMediaFocusControl.sendFocusLoss(focusLoser); 12188 } 12189 12190 /** 12191 * @see AudioManager#getHalVersion 12192 */ getHalVersion()12193 public @Nullable AudioHalVersionInfo getHalVersion() { 12194 for (AudioHalVersionInfo version : AudioHalVersionInfo.VERSIONS) { 12195 try { 12196 // TODO: check AIDL service. 12197 String versionStr = version.getMajorVersion() + "." + version.getMinorVersion(); 12198 HwBinder.getService( 12199 String.format("android.hardware.audio@%s::IDevicesFactory", versionStr), 12200 "default"); 12201 return version; 12202 } catch (NoSuchElementException e) { 12203 // Ignore, the specified HAL interface is not found. 12204 } catch (RemoteException re) { 12205 Log.e(TAG, "Remote exception when getting hardware audio service:", re); 12206 } 12207 } 12208 return null; 12209 } 12210 12211 /** see AudioManager.hasRegisteredDynamicPolicy */ hasRegisteredDynamicPolicy()12212 public boolean hasRegisteredDynamicPolicy() { 12213 synchronized (mAudioPolicies) { 12214 return !mAudioPolicies.isEmpty(); 12215 } 12216 } 12217 12218 /** 12219 * @see AudioManager#setPreferredMixerAttributes( 12220 * AudioAttributes, AudioDeviceInfo, AudioMixerAttributes) 12221 */ setPreferredMixerAttributes(AudioAttributes attributes, int portId, AudioMixerAttributes mixerAttributes)12222 public int setPreferredMixerAttributes(AudioAttributes attributes, 12223 int portId, AudioMixerAttributes mixerAttributes) { 12224 Objects.requireNonNull(attributes); 12225 Objects.requireNonNull(mixerAttributes); 12226 if (!checkAudioSettingsPermission("setPreferredMixerAttributes()")) { 12227 return AudioSystem.PERMISSION_DENIED; 12228 } 12229 final int uid = Binder.getCallingUid(); 12230 final int pid = Binder.getCallingPid(); 12231 int status = AudioSystem.SUCCESS; 12232 final long token = Binder.clearCallingIdentity(); 12233 try { 12234 final String logString = TextUtils.formatSimple( 12235 "setPreferredMixerAttributes u/pid:%d/%d attr:%s mixerAttributes:%s portId:%d", 12236 uid, pid, attributes.toString(), mixerAttributes.toString(), portId); 12237 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 12238 12239 status = mAudioSystem.setPreferredMixerAttributes( 12240 attributes, portId, uid, mixerAttributes); 12241 if (status == AudioSystem.SUCCESS) { 12242 dispatchPreferredMixerAttributesChanged(attributes, portId, mixerAttributes); 12243 } else { 12244 Log.e(TAG, TextUtils.formatSimple("Error %d in %s)", status, logString)); 12245 } 12246 } finally { 12247 Binder.restoreCallingIdentity(token); 12248 } 12249 return status; 12250 } 12251 12252 /** 12253 * @see AudioManager#clearPreferredMixerAttributes(AudioAttributes, AudioDeviceInfo) 12254 */ clearPreferredMixerAttributes(AudioAttributes attributes, int portId)12255 public int clearPreferredMixerAttributes(AudioAttributes attributes, int portId) { 12256 Objects.requireNonNull(attributes); 12257 if (!checkAudioSettingsPermission("clearPreferredMixerAttributes()")) { 12258 return AudioSystem.PERMISSION_DENIED; 12259 } 12260 final int uid = Binder.getCallingUid(); 12261 final int pid = Binder.getCallingPid(); 12262 int status = AudioSystem.SUCCESS; 12263 final long token = Binder.clearCallingIdentity(); 12264 try { 12265 final String logString = TextUtils.formatSimple( 12266 "clearPreferredMixerAttributes u/pid:%d/%d attr:%s", 12267 uid, pid, attributes.toString()); 12268 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 12269 12270 status = mAudioSystem.clearPreferredMixerAttributes(attributes, portId, uid); 12271 if (status == AudioSystem.SUCCESS) { 12272 dispatchPreferredMixerAttributesChanged(attributes, portId, null /*mixerAttr*/); 12273 } else { 12274 Log.e(TAG, TextUtils.formatSimple("Error %d in %s)", status, logString)); 12275 } 12276 } finally { 12277 Binder.restoreCallingIdentity(token); 12278 } 12279 return status; 12280 } 12281 dispatchPreferredMixerAttributesChanged( AudioAttributes attr, int deviceId, AudioMixerAttributes mixerAttr)12282 void dispatchPreferredMixerAttributesChanged( 12283 AudioAttributes attr, int deviceId, AudioMixerAttributes mixerAttr) { 12284 Bundle bundle = new Bundle(); 12285 bundle.putParcelable(KEY_AUDIO_ATTRIBUTES, attr); 12286 bundle.putParcelable(KEY_AUDIO_MIXER_ATTRIBUTES, mixerAttr); 12287 sendBundleMsg(mAudioHandler, MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES, SENDMSG_QUEUE, 12288 deviceId, 0, null, bundle, 0); 12289 } 12290 12291 final RemoteCallbackList<IPreferredMixerAttributesDispatcher> mPrefMixerAttrDispatcher = 12292 new RemoteCallbackList<IPreferredMixerAttributesDispatcher>(); 12293 private static final String KEY_AUDIO_ATTRIBUTES = "audio_attributes"; 12294 private static final String KEY_AUDIO_MIXER_ATTRIBUTES = "audio_mixer_attributes"; 12295 12296 /** @see AudioManager#addOnPreferredMixerAttributesChangedListener( 12297 * Executor, AudioManager.OnPreferredMixerAttributesChangedListener) 12298 */ registerPreferredMixerAttributesDispatcher( @ullable IPreferredMixerAttributesDispatcher dispatcher)12299 public void registerPreferredMixerAttributesDispatcher( 12300 @Nullable IPreferredMixerAttributesDispatcher dispatcher) { 12301 if (dispatcher == null) { 12302 return; 12303 } 12304 mPrefMixerAttrDispatcher.register(dispatcher); 12305 } 12306 12307 /** @see AudioManager#removeOnPreferredMixerAttributesChangedListener( 12308 * AudioManager.OnPreferredMixerAttributesChangedListener) 12309 */ unregisterPreferredMixerAttributesDispatcher( @ullable IPreferredMixerAttributesDispatcher dispatcher)12310 public void unregisterPreferredMixerAttributesDispatcher( 12311 @Nullable IPreferredMixerAttributesDispatcher dispatcher) { 12312 if (dispatcher == null) { 12313 return; 12314 } 12315 mPrefMixerAttrDispatcher.unregister(dispatcher); 12316 } 12317 onDispatchPreferredMixerAttributesChanged(Bundle data, int deviceId)12318 protected void onDispatchPreferredMixerAttributesChanged(Bundle data, int deviceId) { 12319 final int nbDispathers = mPrefMixerAttrDispatcher.beginBroadcast(); 12320 final AudioAttributes attr = data.getParcelable( 12321 KEY_AUDIO_ATTRIBUTES, AudioAttributes.class); 12322 final AudioMixerAttributes mixerAttr = data.getParcelable( 12323 KEY_AUDIO_MIXER_ATTRIBUTES, AudioMixerAttributes.class); 12324 for (int i = 0; i < nbDispathers; i++) { 12325 try { 12326 mPrefMixerAttrDispatcher.getBroadcastItem(i) 12327 .dispatchPrefMixerAttributesChanged(attr, deviceId, mixerAttr); 12328 } catch (RemoteException e) { 12329 Log.e(TAG, "Can't call dispatchPrefMixerAttributesChanged() " 12330 + "IPreferredMixerAttributesDispatcher " 12331 + mPrefMixerAttrDispatcher.getBroadcastItem(i).asBinder(), e); 12332 } 12333 } 12334 mPrefMixerAttrDispatcher.finishBroadcast(); 12335 } 12336 12337 12338 /** @see AudioManager#supportsBluetoothVariableLatency() */ 12339 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) supportsBluetoothVariableLatency()12340 public boolean supportsBluetoothVariableLatency() { 12341 super.supportsBluetoothVariableLatency_enforcePermission(); 12342 try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { 12343 return AudioSystem.supportsBluetoothVariableLatency(); 12344 } 12345 } 12346 12347 /** @see AudioManager#setBluetoothVariableLatencyEnabled(boolean) */ 12348 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) setBluetoothVariableLatencyEnabled(boolean enabled)12349 public void setBluetoothVariableLatencyEnabled(boolean enabled) { 12350 super.setBluetoothVariableLatencyEnabled_enforcePermission(); 12351 try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { 12352 AudioSystem.setBluetoothVariableLatencyEnabled(enabled); 12353 } 12354 } 12355 12356 /** @see AudioManager#isBluetoothVariableLatencyEnabled(boolean) */ 12357 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) isBluetoothVariableLatencyEnabled()12358 public boolean isBluetoothVariableLatencyEnabled() { 12359 super.isBluetoothVariableLatencyEnabled_enforcePermission(); 12360 try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { 12361 return AudioSystem.isBluetoothVariableLatencyEnabled(); 12362 } 12363 } 12364 12365 private final Object mExtVolumeControllerLock = new Object(); 12366 private IAudioPolicyCallback mExtVolumeController; setExtVolumeController(IAudioPolicyCallback apc)12367 private void setExtVolumeController(IAudioPolicyCallback apc) { 12368 if (!mContext.getResources().getBoolean( 12369 com.android.internal.R.bool.config_handleVolumeKeysInWindowManager)) { 12370 Log.e(TAG, "Cannot set external volume controller: device not set for volume keys" + 12371 " handled in PhoneWindowManager"); 12372 return; 12373 } 12374 synchronized (mExtVolumeControllerLock) { 12375 if (mExtVolumeController != null && !mExtVolumeController.asBinder().pingBinder()) { 12376 Log.e(TAG, "Cannot set external volume controller: existing controller"); 12377 } 12378 mExtVolumeController = apc; 12379 } 12380 } 12381 dumpAudioPolicies(PrintWriter pw)12382 private void dumpAudioPolicies(PrintWriter pw) { 12383 pw.println("\nAudio policies:"); 12384 synchronized (mAudioPolicies) { 12385 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 12386 pw.println(policy.toLogFriendlyString()); 12387 } 12388 } 12389 } 12390 12391 //====================== 12392 // Audio policy callbacks from AudioSystem for dynamic policies 12393 //====================== 12394 private final AudioSystem.DynamicPolicyCallback mDynPolicyCallback = 12395 new AudioSystem.DynamicPolicyCallback() { 12396 public void onDynamicPolicyMixStateUpdate(String regId, int state) { 12397 if (!TextUtils.isEmpty(regId)) { 12398 sendMsg(mAudioHandler, MSG_DYN_POLICY_MIX_STATE_UPDATE, SENDMSG_QUEUE, 12399 state /*arg1*/, 0 /*arg2 ignored*/, regId /*obj*/, 0 /*delay*/); 12400 } 12401 } 12402 }; 12403 onDynPolicyMixStateUpdate(String regId, int state)12404 private void onDynPolicyMixStateUpdate(String regId, int state) { 12405 if (DEBUG_AP) Log.d(TAG, "onDynamicPolicyMixStateUpdate("+ regId + ", " + state +")"); 12406 synchronized (mAudioPolicies) { 12407 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 12408 for (AudioMix mix : policy.getMixes()) { 12409 if (mix.getRegistration().equals(regId)) { 12410 try { 12411 policy.mPolicyCallback.notifyMixStateUpdate(regId, state); 12412 } catch (RemoteException e) { 12413 Log.e(TAG, "Can't call notifyMixStateUpdate() on IAudioPolicyCallback " 12414 + policy.mPolicyCallback.asBinder(), e); 12415 } 12416 return; 12417 } 12418 } 12419 } 12420 } 12421 } 12422 12423 //====================== 12424 // Audio policy callbacks from AudioSystem for recording configuration updates 12425 //====================== 12426 private final RecordingActivityMonitor mRecordMonitor; 12427 registerRecordingCallback(IRecordingConfigDispatcher rcdb)12428 public void registerRecordingCallback(IRecordingConfigDispatcher rcdb) { 12429 final boolean isPrivileged = 12430 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 12431 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 12432 mRecordMonitor.registerRecordingCallback(rcdb, isPrivileged); 12433 } 12434 unregisterRecordingCallback(IRecordingConfigDispatcher rcdb)12435 public void unregisterRecordingCallback(IRecordingConfigDispatcher rcdb) { 12436 mRecordMonitor.unregisterRecordingCallback(rcdb); 12437 } 12438 getActiveRecordingConfigurations()12439 public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() { 12440 final boolean isPrivileged = Binder.getCallingUid() == Process.SYSTEM_UID 12441 || (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 12442 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 12443 return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged); 12444 } 12445 12446 //====================== 12447 // Audio recording state notification from clients 12448 //====================== 12449 /** 12450 * Track a recorder provided by the client 12451 */ trackRecorder(IBinder recorder)12452 public int trackRecorder(IBinder recorder) { 12453 return mRecordMonitor.trackRecorder(recorder); 12454 } 12455 12456 /** 12457 * Receive an event from the client about a tracked recorder 12458 */ recorderEvent(int riid, int event)12459 public void recorderEvent(int riid, int event) { 12460 mRecordMonitor.recorderEvent(riid, event); 12461 } 12462 12463 /** 12464 * Stop tracking the recorder 12465 */ releaseRecorder(int riid)12466 public void releaseRecorder(int riid) { 12467 mRecordMonitor.releaseRecorder(riid); 12468 } 12469 12470 //====================== 12471 // Audio playback notification 12472 //====================== 12473 private final PlaybackActivityMonitor mPlaybackMonitor; 12474 registerPlaybackCallback(IPlaybackConfigDispatcher pcdb)12475 public void registerPlaybackCallback(IPlaybackConfigDispatcher pcdb) { 12476 final boolean isPrivileged = 12477 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 12478 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 12479 mPlaybackMonitor.registerPlaybackCallback(pcdb, isPrivileged); 12480 } 12481 unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb)12482 public void unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb) { 12483 mPlaybackMonitor.unregisterPlaybackCallback(pcdb); 12484 } 12485 getActivePlaybackConfigurations()12486 public List<AudioPlaybackConfiguration> getActivePlaybackConfigurations() { 12487 final boolean isPrivileged = 12488 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 12489 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 12490 return mPlaybackMonitor.getActivePlaybackConfigurations(isPrivileged); 12491 } 12492 trackPlayer(PlayerBase.PlayerIdCard pic)12493 public int trackPlayer(PlayerBase.PlayerIdCard pic) { 12494 if (pic != null && pic.mAttributes != null) { 12495 validateAudioAttributesUsage(pic.mAttributes); 12496 } 12497 return mPlaybackMonitor.trackPlayer(pic); 12498 } 12499 playerAttributes(int piid, AudioAttributes attr)12500 public void playerAttributes(int piid, AudioAttributes attr) { 12501 if (attr != null) { 12502 validateAudioAttributesUsage(attr); 12503 } 12504 mPlaybackMonitor.playerAttributes(piid, attr, Binder.getCallingUid()); 12505 } 12506 12507 /** 12508 * Update player session ID 12509 * @param piid Player id to update 12510 * @param sessionId The new audio session ID 12511 */ playerSessionId(int piid, int sessionId)12512 public void playerSessionId(int piid, int sessionId) { 12513 if (sessionId <= AudioSystem.AUDIO_SESSION_ALLOCATE) { 12514 throw new IllegalArgumentException("invalid session Id " + sessionId); 12515 } 12516 mPlaybackMonitor.playerSessionId(piid, sessionId, Binder.getCallingUid()); 12517 } 12518 12519 /** 12520 * Update player event 12521 * @param piid Player id to update 12522 * @param event The new player event 12523 * @param eventValue The value associated with this event 12524 */ playerEvent(int piid, int event, int eventValue)12525 public void playerEvent(int piid, int event, int eventValue) { 12526 mPlaybackMonitor.playerEvent(piid, event, eventValue, Binder.getCallingUid()); 12527 } 12528 12529 /** 12530 * Update event for port id 12531 * @param portId Port id to update 12532 * @param event The new event for the given port 12533 * @param extras Bundle of extra values to describe the event 12534 */ portEvent(int portId, int event, @Nullable PersistableBundle extras)12535 public void portEvent(int portId, int event, @Nullable PersistableBundle extras) { 12536 mPlaybackMonitor.portEvent(portId, event, extras, Binder.getCallingUid()); 12537 } 12538 playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio)12539 public void playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio) { 12540 mPlaybackMonitor.playerHasOpPlayAudio(piid, hasOpPlayAudio, Binder.getCallingUid()); 12541 } 12542 releasePlayer(int piid)12543 public void releasePlayer(int piid) { 12544 mPlaybackMonitor.releasePlayer(piid, Binder.getCallingUid()); 12545 } 12546 12547 /** 12548 * Specifies whether the audio played by this app may or may not be captured by other apps or 12549 * the system. 12550 * 12551 * @param capturePolicy one of 12552 * {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}, 12553 * {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM}, 12554 * {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}. 12555 * @return AudioSystem.AUDIO_STATUS_OK if set allowed capture policy succeed. 12556 * @throws IllegalArgumentException if the argument is not a valid value. 12557 */ setAllowedCapturePolicy(int capturePolicy)12558 public int setAllowedCapturePolicy(int capturePolicy) { 12559 int callingUid = Binder.getCallingUid(); 12560 int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0); 12561 final long identity = Binder.clearCallingIdentity(); 12562 try { 12563 synchronized (mPlaybackMonitor) { 12564 int result = mAudioSystem.setAllowedCapturePolicy(callingUid, flags); 12565 if (result == AudioSystem.AUDIO_STATUS_OK) { 12566 mPlaybackMonitor.setAllowedCapturePolicy(callingUid, capturePolicy); 12567 } 12568 return result; 12569 } 12570 } finally { 12571 Binder.restoreCallingIdentity(identity); 12572 } 12573 } 12574 12575 /** 12576 * Return the capture policy. 12577 * @return the cached capture policy for the calling uid. 12578 */ getAllowedCapturePolicy()12579 public int getAllowedCapturePolicy() { 12580 int callingUid = Binder.getCallingUid(); 12581 final long identity = Binder.clearCallingIdentity(); 12582 try { 12583 return mPlaybackMonitor.getAllowedCapturePolicy(callingUid); 12584 } finally { 12585 Binder.restoreCallingIdentity(identity); 12586 } 12587 } 12588 12589 /* package */ isPlaybackActiveForUid(int uid)12590 boolean isPlaybackActiveForUid(int uid) { 12591 return mPlaybackMonitor.isPlaybackActiveForUid(uid); 12592 } 12593 12594 /* package */ isRecordingActiveForUid(int uid)12595 boolean isRecordingActiveForUid(int uid) { 12596 return mRecordMonitor.isRecordingActiveForUid(uid); 12597 } 12598 12599 //====================== 12600 // Audio device management 12601 //====================== 12602 private final AudioDeviceBroker mDeviceBroker; 12603 12604 //====================== 12605 // Audio policy proxy 12606 //====================== 12607 private static final class AudioDeviceArray { 12608 final @NonNull int[] mDeviceTypes; 12609 final @NonNull String[] mDeviceAddresses; AudioDeviceArray(@onNull int[] types, @NonNull String[] addresses)12610 AudioDeviceArray(@NonNull int[] types, @NonNull String[] addresses) { 12611 mDeviceTypes = types; 12612 mDeviceAddresses = addresses; 12613 } 12614 } 12615 12616 /** 12617 * This internal class inherits from AudioPolicyConfig, each instance contains all the 12618 * mixes of an AudioPolicy and their configurations. 12619 */ 12620 public class AudioPolicyProxy extends AudioPolicyConfig implements IBinder.DeathRecipient { 12621 private static final String TAG = "AudioPolicyProxy"; 12622 final IAudioPolicyCallback mPolicyCallback; 12623 final boolean mHasFocusListener; 12624 final boolean mIsVolumeController; 12625 final HashMap<Integer, AudioDeviceArray> mUidDeviceAffinities = 12626 new HashMap<Integer, AudioDeviceArray>(); 12627 12628 final HashMap<Integer, AudioDeviceArray> mUserIdDeviceAffinities = 12629 new HashMap<>(); 12630 12631 final IMediaProjection mProjection; 12632 private final class UnregisterOnStopCallback extends IMediaProjectionCallback.Stub { onStop()12633 public void onStop() { 12634 unregisterAudioPolicyAsync(mPolicyCallback); 12635 } 12636 12637 @Override onCapturedContentResize(int width, int height)12638 public void onCapturedContentResize(int width, int height) { 12639 // Ignore resize of the captured content. 12640 } 12641 12642 @Override onCapturedContentVisibilityChanged(boolean isVisible)12643 public void onCapturedContentVisibilityChanged(boolean isVisible) { 12644 // Ignore visibility changes of the captured content. 12645 } 12646 }; 12647 UnregisterOnStopCallback mProjectionCallback; 12648 12649 /** 12650 * Audio focus ducking behavior for an audio policy. 12651 * This variable reflects the value that was successfully set in 12652 * {@link AudioService#setFocusPropertiesForPolicy(int, IAudioPolicyCallback)}. This 12653 * implies that a value of FOCUS_POLICY_DUCKING_IN_POLICY means the corresponding policy 12654 * is handling ducking for audio focus. 12655 */ 12656 int mFocusDuckBehavior = AudioPolicy.FOCUS_POLICY_DUCKING_DEFAULT; 12657 boolean mIsFocusPolicy = false; 12658 boolean mIsTestFocusPolicy = false; 12659 AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)12660 AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, 12661 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, 12662 boolean isVolumeController, IMediaProjection projection) { 12663 super(config); 12664 setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++)); 12665 mPolicyCallback = token; 12666 mHasFocusListener = hasFocusListener; 12667 mIsVolumeController = isVolumeController; 12668 mProjection = projection; 12669 if (mHasFocusListener) { 12670 mMediaFocusControl.addFocusFollower(mPolicyCallback); 12671 // can only ever be true if there is a focus listener 12672 if (isFocusPolicy) { 12673 mIsFocusPolicy = true; 12674 mIsTestFocusPolicy = isTestFocusPolicy; 12675 mMediaFocusControl.setFocusPolicy(mPolicyCallback, mIsTestFocusPolicy); 12676 } 12677 } 12678 if (mIsVolumeController) { 12679 setExtVolumeController(mPolicyCallback); 12680 } 12681 if (mProjection != null) { 12682 mProjectionCallback = new UnregisterOnStopCallback(); 12683 try { 12684 mProjection.registerCallback(mProjectionCallback); 12685 } catch (RemoteException e) { 12686 release(); 12687 throw new IllegalStateException("MediaProjection callback registration failed, " 12688 + "could not link to " + projection + " binder death", e); 12689 } 12690 } 12691 int status = connectMixes(); 12692 if (status != AudioSystem.SUCCESS) { 12693 release(); 12694 throw new IllegalStateException("Could not connect mix, error: " + status); 12695 } 12696 } 12697 binderDied()12698 public void binderDied() { 12699 mDynPolicyLogger.enqueue((new EventLogger.StringEvent("AudioPolicy " 12700 + mPolicyCallback.asBinder() + " died").printLog(TAG))); 12701 12702 List<String> addresses = new ArrayList<>(); 12703 for (AudioMix mix : mMixes) { 12704 addresses.add(mix.getRegistration()); 12705 } 12706 onPolicyClientDeath(addresses); 12707 12708 release(); 12709 } 12710 getRegistrationId()12711 String getRegistrationId() { 12712 return getRegistration(); 12713 } 12714 release()12715 void release() { 12716 if (mIsFocusPolicy) { 12717 mMediaFocusControl.unsetFocusPolicy(mPolicyCallback, mIsTestFocusPolicy); 12718 } 12719 if (mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 12720 mMediaFocusControl.setDuckingInExtPolicyAvailable(false); 12721 } 12722 if (mHasFocusListener) { 12723 mMediaFocusControl.removeFocusFollower(mPolicyCallback); 12724 } 12725 if (mProjectionCallback != null) { 12726 try { 12727 mProjection.unregisterCallback(mProjectionCallback); 12728 } catch (RemoteException e) { 12729 Log.e(TAG, "Fail to unregister Audiopolicy callback from MediaProjection"); 12730 } 12731 } 12732 if (mIsVolumeController) { 12733 synchronized (mExtVolumeControllerLock) { 12734 mExtVolumeController = null; 12735 } 12736 } 12737 final long identity = Binder.clearCallingIdentity(); 12738 try { 12739 mAudioSystem.registerPolicyMixes(mMixes, false); 12740 } finally { 12741 Binder.restoreCallingIdentity(identity); 12742 } 12743 synchronized (mAudioPolicies) { 12744 mAudioPolicies.remove(mPolicyCallback.asBinder()); 12745 } 12746 try { 12747 mPolicyCallback.notifyUnregistration(); 12748 } catch (RemoteException e) { } 12749 } 12750 hasMixAffectingUsage(int usage, int excludedFlags)12751 boolean hasMixAffectingUsage(int usage, int excludedFlags) { 12752 for (AudioMix mix : mMixes) { 12753 if (mix.isAffectingUsage(usage) 12754 && ((mix.getRouteFlags() & excludedFlags) != excludedFlags)) { 12755 return true; 12756 } 12757 } 12758 return false; 12759 } 12760 12761 // Verify all the devices in the array are served by mixes defined in this policy hasMixRoutedToDevices(@onNull int[] deviceTypes, @NonNull String[] deviceAddresses)12762 boolean hasMixRoutedToDevices(@NonNull int[] deviceTypes, 12763 @NonNull String[] deviceAddresses) { 12764 for (int i = 0; i < deviceTypes.length; i++) { 12765 boolean hasDevice = false; 12766 for (AudioMix mix : mMixes) { 12767 // this will check both that the mix has ROUTE_FLAG_RENDER and the device 12768 // is reached by this mix 12769 if (mix.isRoutedToDevice(deviceTypes[i], deviceAddresses[i])) { 12770 hasDevice = true; 12771 break; 12772 } 12773 } 12774 if (!hasDevice) { 12775 return false; 12776 } 12777 } 12778 return true; 12779 } 12780 addMixes(@onNull ArrayList<AudioMix> mixes)12781 int addMixes(@NonNull ArrayList<AudioMix> mixes) { 12782 synchronized (mMixes) { 12783 this.add(mixes); 12784 return mAudioSystem.registerPolicyMixes(mixes, true); 12785 } 12786 } 12787 removeMixes(@onNull ArrayList<AudioMix> mixes)12788 int removeMixes(@NonNull ArrayList<AudioMix> mixes) { 12789 synchronized (mMixes) { 12790 this.remove(mixes); 12791 return mAudioSystem.registerPolicyMixes(mixes, false); 12792 } 12793 } 12794 connectMixes()12795 @AudioSystem.AudioSystemError int connectMixes() { 12796 final long identity = Binder.clearCallingIdentity(); 12797 try { 12798 return mAudioSystem.registerPolicyMixes(mMixes, true); 12799 } finally { 12800 Binder.restoreCallingIdentity(identity); 12801 } 12802 12803 } 12804 setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses)12805 int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) { 12806 final Integer Uid = new Integer(uid); 12807 if (mUidDeviceAffinities.remove(Uid) != null) { 12808 if (removeUidDeviceAffinitiesFromSystem(uid) != AudioSystem.SUCCESS) { 12809 Log.e(TAG, "AudioSystem. removeUidDeviceAffinities(" + uid + ") failed, " 12810 + " cannot call AudioSystem.setUidDeviceAffinities"); 12811 return AudioManager.ERROR; 12812 } 12813 } 12814 AudioDeviceArray deviceArray = new AudioDeviceArray(types, addresses); 12815 if (setUidDeviceAffinitiesOnSystem(uid, deviceArray) == AudioSystem.SUCCESS) { 12816 mUidDeviceAffinities.put(Uid, deviceArray); 12817 return AudioManager.SUCCESS; 12818 } 12819 Log.e(TAG, "AudioSystem. setUidDeviceAffinities(" + uid + ") failed"); 12820 return AudioManager.ERROR; 12821 } 12822 removeUidDeviceAffinities(int uid)12823 int removeUidDeviceAffinities(int uid) { 12824 if (mUidDeviceAffinities.remove(new Integer(uid)) != null) { 12825 if (removeUidDeviceAffinitiesFromSystem(uid) == AudioSystem.SUCCESS) { 12826 return AudioManager.SUCCESS; 12827 } 12828 } 12829 Log.e(TAG, "AudioSystem. removeUidDeviceAffinities failed"); 12830 return AudioManager.ERROR; 12831 } 12832 removeUidDeviceAffinitiesFromSystem(int uid)12833 @AudioSystem.AudioSystemError private int removeUidDeviceAffinitiesFromSystem(int uid) { 12834 final long identity = Binder.clearCallingIdentity(); 12835 try { 12836 return mAudioSystem.removeUidDeviceAffinities(uid); 12837 } finally { 12838 Binder.restoreCallingIdentity(identity); 12839 } 12840 } 12841 setUidDeviceAffinitiesOnSystem(int uid, AudioDeviceArray deviceArray)12842 @AudioSystem.AudioSystemError private int setUidDeviceAffinitiesOnSystem(int uid, 12843 AudioDeviceArray deviceArray) { 12844 final long identity = Binder.clearCallingIdentity(); 12845 try { 12846 return mAudioSystem.setUidDeviceAffinities(uid, deviceArray.mDeviceTypes, 12847 deviceArray.mDeviceAddresses); 12848 } finally { 12849 Binder.restoreCallingIdentity(identity); 12850 } 12851 } 12852 setUserIdDeviceAffinities(int userId, @NonNull int[] types, @NonNull String[] addresses)12853 int setUserIdDeviceAffinities(int userId, 12854 @NonNull int[] types, @NonNull String[] addresses) { 12855 final Integer UserId = new Integer(userId); 12856 if (mUserIdDeviceAffinities.remove(UserId) != null) { 12857 if (removeUserIdDeviceAffinitiesFromSystem(userId) != AudioSystem.SUCCESS) { 12858 Log.e(TAG, "AudioSystem. removeUserIdDeviceAffinities(" 12859 + UserId + ") failed, " 12860 + " cannot call AudioSystem.setUserIdDeviceAffinities"); 12861 return AudioManager.ERROR; 12862 } 12863 } 12864 AudioDeviceArray audioDeviceArray = new AudioDeviceArray(types, addresses); 12865 if (setUserIdDeviceAffinitiesOnSystem(userId, audioDeviceArray) 12866 == AudioSystem.SUCCESS) { 12867 mUserIdDeviceAffinities.put(UserId, audioDeviceArray); 12868 return AudioManager.SUCCESS; 12869 } 12870 Log.e(TAG, "AudioSystem.setUserIdDeviceAffinities(" + userId + ") failed"); 12871 return AudioManager.ERROR; 12872 } 12873 removeUserIdDeviceAffinities(int userId)12874 int removeUserIdDeviceAffinities(int userId) { 12875 if (mUserIdDeviceAffinities.remove(new Integer(userId)) != null) { 12876 if (removeUserIdDeviceAffinitiesFromSystem(userId) == AudioSystem.SUCCESS) { 12877 return AudioManager.SUCCESS; 12878 } 12879 } 12880 Log.e(TAG, "AudioSystem.removeUserIdDeviceAffinities failed"); 12881 return AudioManager.ERROR; 12882 } 12883 removeUserIdDeviceAffinitiesFromSystem( @serIdInt int userId)12884 @AudioSystem.AudioSystemError private int removeUserIdDeviceAffinitiesFromSystem( 12885 @UserIdInt int userId) { 12886 final long identity = Binder.clearCallingIdentity(); 12887 try { 12888 return mAudioSystem.removeUserIdDeviceAffinities(userId); 12889 } finally { 12890 Binder.restoreCallingIdentity(identity); 12891 } 12892 } 12893 setUserIdDeviceAffinitiesOnSystem( @serIdInt int userId, AudioDeviceArray deviceArray)12894 @AudioSystem.AudioSystemError private int setUserIdDeviceAffinitiesOnSystem( 12895 @UserIdInt int userId, AudioDeviceArray deviceArray) { 12896 final long identity = Binder.clearCallingIdentity(); 12897 try { 12898 return mAudioSystem.setUserIdDeviceAffinities(userId, deviceArray.mDeviceTypes, 12899 deviceArray.mDeviceAddresses); 12900 } finally { 12901 Binder.restoreCallingIdentity(identity); 12902 } 12903 } 12904 setupDeviceAffinities()12905 @AudioSystem.AudioSystemError int setupDeviceAffinities() { 12906 for (Map.Entry<Integer, AudioDeviceArray> uidEntry : mUidDeviceAffinities.entrySet()) { 12907 int uidStatus = removeUidDeviceAffinitiesFromSystem(uidEntry.getKey()); 12908 if (uidStatus != AudioSystem.SUCCESS) { 12909 Log.e(TAG, 12910 "setupDeviceAffinities failed to remove device affinity for uid " 12911 + uidEntry.getKey()); 12912 return uidStatus; 12913 } 12914 uidStatus = setUidDeviceAffinitiesOnSystem(uidEntry.getKey(), uidEntry.getValue()); 12915 if (uidStatus != AudioSystem.SUCCESS) { 12916 Log.e(TAG, 12917 "setupDeviceAffinities failed to set device affinity for uid " 12918 + uidEntry.getKey()); 12919 return uidStatus; 12920 } 12921 } 12922 12923 for (Map.Entry<Integer, AudioDeviceArray> userIdEntry : 12924 mUserIdDeviceAffinities.entrySet()) { 12925 int userIdStatus = removeUserIdDeviceAffinitiesFromSystem(userIdEntry.getKey()); 12926 if (userIdStatus != AudioSystem.SUCCESS) { 12927 Log.e(TAG, 12928 "setupDeviceAffinities failed to remove device affinity for userId " 12929 + userIdEntry.getKey()); 12930 return userIdStatus; 12931 } 12932 userIdStatus = setUserIdDeviceAffinitiesOnSystem(userIdEntry.getKey(), 12933 userIdEntry.getValue()); 12934 if (userIdStatus != AudioSystem.SUCCESS) { 12935 Log.e(TAG, 12936 "setupDeviceAffinities failed to set device affinity for userId " 12937 + userIdEntry.getKey()); 12938 return userIdStatus; 12939 } 12940 } 12941 return AudioSystem.SUCCESS; 12942 } 12943 12944 /** @return human readable debug informations summarizing the state of the object. */ toLogFriendlyString()12945 public String toLogFriendlyString() { 12946 String textDump = super.toLogFriendlyString(); 12947 textDump += " Uid Device Affinities:\n"; 12948 String spacer = " "; 12949 textDump += logFriendlyAttributeDeviceArrayMap("Uid", 12950 mUidDeviceAffinities, spacer); 12951 textDump += " UserId Device Affinities:\n"; 12952 textDump += logFriendlyAttributeDeviceArrayMap("UserId", 12953 mUserIdDeviceAffinities, spacer); 12954 textDump += " Proxy:\n"; 12955 textDump += " is focus policy= " + mIsFocusPolicy + "\n"; 12956 if (mIsFocusPolicy) { 12957 textDump += " focus duck behaviour= " + mFocusDuckBehavior + "\n"; 12958 textDump += " is test focus policy= " + mIsTestFocusPolicy + "\n"; 12959 textDump += " has focus listener= " + mHasFocusListener + "\n"; 12960 } 12961 textDump += " media projection= " + mProjection + "\n"; 12962 return textDump; 12963 } 12964 logFriendlyAttributeDeviceArrayMap(String attribute, Map<Integer, AudioDeviceArray> map, String spacer)12965 private String logFriendlyAttributeDeviceArrayMap(String attribute, 12966 Map<Integer, AudioDeviceArray> map, String spacer) { 12967 final StringBuilder stringBuilder = new StringBuilder(); 12968 for (Map.Entry<Integer, AudioDeviceArray> mapEntry : map.entrySet()) { 12969 stringBuilder.append(spacer).append(attribute).append(": ") 12970 .append(mapEntry.getKey()).append("\n"); 12971 AudioDeviceArray deviceArray = mapEntry.getValue(); 12972 String deviceSpacer = spacer + " "; 12973 for (int i = 0; i < deviceArray.mDeviceTypes.length; i++) { 12974 stringBuilder.append(deviceSpacer).append("Type: 0x") 12975 .append(Integer.toHexString(deviceArray.mDeviceTypes[i])) 12976 .append(" Address: ").append(deviceArray.mDeviceAddresses[i]) 12977 .append("\n"); 12978 } 12979 } 12980 return stringBuilder.toString(); 12981 } 12982 }; 12983 12984 //====================== 12985 // Audio policy: focus 12986 //====================== 12987 /** */ dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb)12988 public int dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb) { 12989 if (afi == null) { 12990 throw new IllegalArgumentException("Illegal null AudioFocusInfo"); 12991 } 12992 if (pcb == null) { 12993 throw new IllegalArgumentException("Illegal null AudioPolicy callback"); 12994 } 12995 synchronized (mAudioPolicies) { 12996 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 12997 throw new IllegalStateException("Unregistered AudioPolicy for focus dispatch"); 12998 } 12999 return mMediaFocusControl.dispatchFocusChange(afi, focusChange); 13000 } 13001 } 13002 setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, IAudioPolicyCallback pcb)13003 public void setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, 13004 IAudioPolicyCallback pcb) { 13005 if (afi == null) { 13006 throw new IllegalArgumentException("Illegal null AudioFocusInfo"); 13007 } 13008 if (pcb == null) { 13009 throw new IllegalArgumentException("Illegal null AudioPolicy callback"); 13010 } 13011 synchronized (mAudioPolicies) { 13012 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 13013 throw new IllegalStateException("Unregistered AudioPolicy for external focus"); 13014 } 13015 mMediaFocusControl.setFocusRequestResultFromExtPolicy(afi, requestResult); 13016 } 13017 } 13018 13019 13020 //====================== 13021 // Audioserver state dispatch 13022 //====================== 13023 private class AsdProxy implements IBinder.DeathRecipient { 13024 private final IAudioServerStateDispatcher mAsd; 13025 AsdProxy(IAudioServerStateDispatcher asd)13026 AsdProxy(IAudioServerStateDispatcher asd) { 13027 mAsd = asd; 13028 } 13029 binderDied()13030 public void binderDied() { 13031 synchronized (mAudioServerStateListeners) { 13032 mAudioServerStateListeners.remove(mAsd.asBinder()); 13033 } 13034 } 13035 callback()13036 IAudioServerStateDispatcher callback() { 13037 return mAsd; 13038 } 13039 } 13040 13041 private final HashMap<IBinder, AsdProxy> mAudioServerStateListeners = 13042 new HashMap<IBinder, AsdProxy>(); 13043 checkMonitorAudioServerStatePermission()13044 private void checkMonitorAudioServerStatePermission() { 13045 if (!(mContext.checkCallingOrSelfPermission( 13046 android.Manifest.permission.MODIFY_PHONE_STATE) == 13047 PackageManager.PERMISSION_GRANTED || 13048 mContext.checkCallingOrSelfPermission( 13049 android.Manifest.permission.MODIFY_AUDIO_ROUTING) == 13050 PackageManager.PERMISSION_GRANTED)) { 13051 throw new SecurityException("Not allowed to monitor audioserver state"); 13052 } 13053 } 13054 registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd)13055 public void registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd) { 13056 checkMonitorAudioServerStatePermission(); 13057 synchronized (mAudioServerStateListeners) { 13058 if (mAudioServerStateListeners.containsKey(asd.asBinder())) { 13059 Slog.w(TAG, "Cannot re-register audio server state dispatcher"); 13060 return; 13061 } 13062 AsdProxy asdp = new AsdProxy(asd); 13063 try { 13064 asd.asBinder().linkToDeath(asdp, 0/*flags*/); 13065 } catch (RemoteException e) { 13066 13067 } 13068 mAudioServerStateListeners.put(asd.asBinder(), asdp); 13069 } 13070 } 13071 unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd)13072 public void unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd) { 13073 checkMonitorAudioServerStatePermission(); 13074 synchronized (mAudioServerStateListeners) { 13075 AsdProxy asdp = mAudioServerStateListeners.remove(asd.asBinder()); 13076 if (asdp == null) { 13077 Slog.w(TAG, "Trying to unregister unknown audioserver state dispatcher for pid " 13078 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()); 13079 return; 13080 } else { 13081 asd.asBinder().unlinkToDeath(asdp, 0/*flags*/); 13082 } 13083 } 13084 } 13085 isAudioServerRunning()13086 public boolean isAudioServerRunning() { 13087 checkMonitorAudioServerStatePermission(); 13088 return (AudioSystem.checkAudioFlinger() == AudioSystem.AUDIO_STATUS_OK); 13089 } 13090 13091 //====================== 13092 // Audio HAL process dump 13093 //====================== 13094 13095 private static final String AUDIO_HAL_SERVICE_PREFIX = "android.hardware.audio"; 13096 getAudioAidlHalPids(HashSet<Integer> pids)13097 private void getAudioAidlHalPids(HashSet<Integer> pids) { 13098 try { 13099 ServiceDebugInfo[] infos = ServiceManager.getServiceDebugInfo(); 13100 if (infos == null) return; 13101 for (ServiceDebugInfo info : infos) { 13102 if (info.debugPid > 0 && info.name.startsWith(AUDIO_HAL_SERVICE_PREFIX)) { 13103 pids.add(info.debugPid); 13104 } 13105 } 13106 } catch (RuntimeException e) { 13107 // ignored, pid hashset does not change 13108 } 13109 } 13110 getAudioHalHidlPids(HashSet<Integer> pids)13111 private void getAudioHalHidlPids(HashSet<Integer> pids) { 13112 try { 13113 IServiceManager serviceManager = IServiceManager.getService(); 13114 ArrayList<IServiceManager.InstanceDebugInfo> dump = 13115 serviceManager.debugDump(); 13116 for (IServiceManager.InstanceDebugInfo info : dump) { 13117 if (info.pid != IServiceManager.PidConstant.NO_PID 13118 && info.interfaceName != null 13119 && info.interfaceName.startsWith(AUDIO_HAL_SERVICE_PREFIX)) { 13120 pids.add(info.pid); 13121 } 13122 } 13123 } catch (RemoteException | RuntimeException e) { 13124 // ignored, pid hashset does not change 13125 } 13126 } 13127 getAudioHalPids()13128 private Set<Integer> getAudioHalPids() { 13129 HashSet<Integer> pids = new HashSet<>(); 13130 getAudioAidlHalPids(pids); 13131 getAudioHalHidlPids(pids); 13132 return pids; 13133 } 13134 updateAudioHalPids()13135 private void updateAudioHalPids() { 13136 Set<Integer> pidsSet = getAudioHalPids(); 13137 if (pidsSet.isEmpty()) { 13138 Slog.w(TAG, "Could not retrieve audio HAL service pids"); 13139 return; 13140 } 13141 int[] pidsArray = pidsSet.stream().mapToInt(Integer::intValue).toArray(); 13142 AudioSystem.setAudioHalPids(pidsArray); 13143 } 13144 13145 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 13146 //====================== 13147 // Multi Audio Focus 13148 //====================== setMultiAudioFocusEnabled(boolean enabled)13149 public void setMultiAudioFocusEnabled(boolean enabled) { 13150 super.setMultiAudioFocusEnabled_enforcePermission(); 13151 13152 if (mMediaFocusControl != null) { 13153 boolean mafEnabled = mMediaFocusControl.getMultiAudioFocusEnabled(); 13154 if (mafEnabled != enabled) { 13155 mMediaFocusControl.updateMultiAudioFocus(enabled); 13156 if (!enabled) { 13157 mDeviceBroker.postBroadcastBecomingNoisy(); 13158 } 13159 } 13160 } 13161 } 13162 13163 /** 13164 * @hide 13165 * Sets an additional audio output device delay in milliseconds. 13166 * 13167 * The additional output delay is a request to the output device to 13168 * delay audio presentation (generally with respect to video presentation for better 13169 * synchronization). 13170 * It may not be supported by all output devices, 13171 * and typically increases the audio latency by the amount of additional 13172 * audio delay requested. 13173 * 13174 * If additional audio delay is supported by an audio output device, 13175 * it is expected to be supported for all output streams (and configurations) 13176 * opened on that device. 13177 * 13178 * @param deviceType 13179 * @param address 13180 * @param delayMillis delay in milliseconds desired. This should be in range of {@code 0} 13181 * to the value returned by {@link #getMaxAdditionalOutputDeviceDelay()}. 13182 * @return true if successful, false if the device does not support output device delay 13183 * or the delay is not in range of {@link #getMaxAdditionalOutputDeviceDelay()}. 13184 */ 13185 @Override 13186 //@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) setAdditionalOutputDeviceDelay( @onNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis)13187 public boolean setAdditionalOutputDeviceDelay( 13188 @NonNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis) { 13189 Objects.requireNonNull(device, "device must not be null"); 13190 enforceModifyAudioRoutingPermission(); 13191 13192 device = retrieveBluetoothAddress(device); 13193 13194 final String getterKey = "additional_output_device_delay=" 13195 + device.getInternalType() + "," + device.getAddress(); // "getter" key as an id. 13196 final String setterKey = getterKey + "," + delayMillis; // append the delay for setter 13197 return mRestorableParameters.setParameters(getterKey, setterKey) 13198 == AudioSystem.AUDIO_STATUS_OK; 13199 } 13200 13201 /** 13202 * @hide 13203 * Returns the current additional audio output device delay in milliseconds. 13204 * 13205 * @param deviceType 13206 * @param address 13207 * @return the additional output device delay. This is a non-negative number. 13208 * {@code 0} is returned if unsupported. 13209 */ 13210 @Override 13211 @IntRange(from = 0) getAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)13212 public long getAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) { 13213 Objects.requireNonNull(device, "device must not be null"); 13214 13215 device = retrieveBluetoothAddress(device); 13216 13217 final String key = "additional_output_device_delay"; 13218 final String reply = AudioSystem.getParameters( 13219 key + "=" + device.getInternalType() + "," + device.getAddress()); 13220 long delayMillis; 13221 try { 13222 delayMillis = Long.parseLong(reply.substring(key.length() + 1)); 13223 } catch (NullPointerException e) { 13224 delayMillis = 0; 13225 } 13226 return delayMillis; 13227 } 13228 13229 /** 13230 * @hide 13231 * Returns the maximum additional audio output device delay in milliseconds. 13232 * 13233 * @param deviceType 13234 * @param address 13235 * @return the maximum output device delay in milliseconds that can be set. 13236 * This is a non-negative number 13237 * representing the additional audio delay supported for the device. 13238 * {@code 0} is returned if unsupported. 13239 */ 13240 @Override 13241 @IntRange(from = 0) getMaxAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)13242 public long getMaxAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) { 13243 Objects.requireNonNull(device, "device must not be null"); 13244 13245 device = retrieveBluetoothAddress(device); 13246 13247 final String key = "max_additional_output_device_delay"; 13248 final String reply = AudioSystem.getParameters( 13249 key + "=" + device.getInternalType() + "," + device.getAddress()); 13250 long delayMillis; 13251 try { 13252 delayMillis = Long.parseLong(reply.substring(key.length() + 1)); 13253 } catch (NullPointerException e) { 13254 delayMillis = 0; 13255 } 13256 return delayMillis; 13257 } 13258 13259 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 13260 /** @see AudioManager#addAssistantServicesUids(int []) */ 13261 @Override addAssistantServicesUids(int [] assistantUids)13262 public void addAssistantServicesUids(int [] assistantUids) { 13263 super.addAssistantServicesUids_enforcePermission(); 13264 13265 Objects.requireNonNull(assistantUids); 13266 13267 synchronized (mSettingsLock) { 13268 addAssistantServiceUidsLocked(assistantUids); 13269 } 13270 } 13271 13272 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 13273 /** @see AudioManager#removeAssistantServicesUids(int []) */ 13274 @Override removeAssistantServicesUids(int [] assistantUids)13275 public void removeAssistantServicesUids(int [] assistantUids) { 13276 super.removeAssistantServicesUids_enforcePermission(); 13277 13278 Objects.requireNonNull(assistantUids); 13279 synchronized (mSettingsLock) { 13280 removeAssistantServiceUidsLocked(assistantUids); 13281 } 13282 } 13283 13284 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 13285 /** @see AudioManager#getAssistantServicesUids() */ 13286 @Override getAssistantServicesUids()13287 public int[] getAssistantServicesUids() { 13288 super.getAssistantServicesUids_enforcePermission(); 13289 13290 int [] assistantUids; 13291 synchronized (mSettingsLock) { 13292 assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray(); 13293 } 13294 return assistantUids; 13295 } 13296 13297 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 13298 /** @see AudioManager#setActiveAssistantServiceUids(int []) */ 13299 @Override setActiveAssistantServiceUids(int [] activeAssistantUids)13300 public void setActiveAssistantServiceUids(int [] activeAssistantUids) { 13301 super.setActiveAssistantServiceUids_enforcePermission(); 13302 13303 Objects.requireNonNull(activeAssistantUids); 13304 synchronized (mSettingsLock) { 13305 mActiveAssistantServiceUids = activeAssistantUids; 13306 } 13307 updateActiveAssistantServiceUids(); 13308 } 13309 13310 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 13311 /** @see AudioManager#getActiveAssistantServiceUids() */ 13312 @Override getActiveAssistantServiceUids()13313 public int[] getActiveAssistantServiceUids() { 13314 super.getActiveAssistantServiceUids_enforcePermission(); 13315 13316 int [] activeAssistantUids; 13317 synchronized (mSettingsLock) { 13318 activeAssistantUids = mActiveAssistantServiceUids.clone(); 13319 } 13320 return activeAssistantUids; 13321 } 13322 getDeviceSensorUuid(AudioDeviceAttributes device)13323 UUID getDeviceSensorUuid(AudioDeviceAttributes device) { 13324 return mDeviceBroker.getDeviceSensorUuid(device); 13325 } 13326 13327 //====================== 13328 // misc 13329 //====================== 13330 private final HashMap<IBinder, AudioPolicyProxy> mAudioPolicies = 13331 new HashMap<IBinder, AudioPolicyProxy>(); 13332 @GuardedBy("mAudioPolicies") 13333 private int mAudioPolicyCounter = 0; 13334 13335 //====================== 13336 // Helper functions for full and fixed volume device 13337 //====================== isFixedVolumeDevice(int deviceType)13338 private boolean isFixedVolumeDevice(int deviceType) { 13339 if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX 13340 && mRecordMonitor.isLegacyRemoteSubmixActive()) { 13341 return false; 13342 } 13343 return mFixedVolumeDevices.contains(deviceType); 13344 } 13345 isFullVolumeDevice(int deviceType)13346 private boolean isFullVolumeDevice(int deviceType) { 13347 if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX 13348 && mRecordMonitor.isLegacyRemoteSubmixActive()) { 13349 return false; 13350 } 13351 return mFullVolumeDevices.contains(deviceType); 13352 } 13353 13354 /** 13355 * Returns whether the input device uses absolute volume behavior, including its variants. 13356 * For included volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}. 13357 * 13358 * This is distinct from Bluetooth A2DP absolute volume behavior 13359 * ({@link #isA2dpAbsoluteVolumeDevice}). 13360 */ isAbsoluteVolumeDevice(int deviceType)13361 private boolean isAbsoluteVolumeDevice(int deviceType) { 13362 return mAbsoluteVolumeDeviceInfoMap.containsKey(deviceType); 13363 } 13364 13365 /** 13366 * Returns whether the input device is a Bluetooth A2dp device that uses absolute volume 13367 * behavior. This is distinct from the general implementation of absolute volume behavior 13368 * ({@link #isAbsoluteVolumeDevice}). 13369 */ isA2dpAbsoluteVolumeDevice(int deviceType)13370 private boolean isA2dpAbsoluteVolumeDevice(int deviceType) { 13371 return mAvrcpAbsVolSupported && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType); 13372 } 13373 13374 //==================== 13375 // Helper functions for {set,get}DeviceVolumeBehavior 13376 //==================== getSettingsNameForDeviceVolumeBehavior(int deviceType)13377 private static String getSettingsNameForDeviceVolumeBehavior(int deviceType) { 13378 return "AudioService_DeviceVolumeBehavior_" + AudioSystem.getOutputDeviceName(deviceType); 13379 } 13380 persistDeviceVolumeBehavior(int deviceType, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior)13381 private void persistDeviceVolumeBehavior(int deviceType, 13382 @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) { 13383 if (DEBUG_VOL) { 13384 Log.d(TAG, "Persisting Volume Behavior for DeviceType: " + deviceType); 13385 } 13386 final long callingIdentity = Binder.clearCallingIdentity(); 13387 try { 13388 mSettings.putSystemIntForUser(mContentResolver, 13389 getSettingsNameForDeviceVolumeBehavior(deviceType), 13390 deviceVolumeBehavior, 13391 UserHandle.USER_CURRENT); 13392 } finally { 13393 Binder.restoreCallingIdentity(callingIdentity); 13394 } 13395 } 13396 13397 @AudioManager.DeviceVolumeBehaviorState retrieveStoredDeviceVolumeBehavior(int deviceType)13398 private int retrieveStoredDeviceVolumeBehavior(int deviceType) { 13399 return mSettings.getSystemIntForUser(mContentResolver, 13400 getSettingsNameForDeviceVolumeBehavior(deviceType), 13401 AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET, 13402 UserHandle.USER_CURRENT); 13403 } 13404 restoreDeviceVolumeBehavior()13405 private void restoreDeviceVolumeBehavior() { 13406 for (int deviceType : AudioSystem.DEVICE_OUT_ALL_SET) { 13407 if (DEBUG_VOL) { 13408 Log.d(TAG, "Retrieving Volume Behavior for DeviceType: " + deviceType); 13409 } 13410 int deviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(deviceType); 13411 if (deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) { 13412 if (DEBUG_VOL) { 13413 Log.d(TAG, "Skipping Setting Volume Behavior for DeviceType: " + deviceType); 13414 } 13415 continue; 13416 } 13417 13418 setDeviceVolumeBehaviorInternal(new AudioDeviceAttributes(deviceType, ""), 13419 deviceVolumeBehavior, "AudioService.restoreDeviceVolumeBehavior()"); 13420 } 13421 } 13422 13423 /** 13424 * @param audioSystemDeviceOut one of AudioSystem.DEVICE_OUT_* 13425 * @return whether {@code audioSystemDeviceOut} has previously been set to a specific volume 13426 * behavior 13427 */ hasDeviceVolumeBehavior( int audioSystemDeviceOut)13428 private boolean hasDeviceVolumeBehavior( 13429 int audioSystemDeviceOut) { 13430 return retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut) 13431 != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET; 13432 } 13433 addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut)13434 private boolean addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut) { 13435 if (DEBUG_VOL) { 13436 Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 13437 + " to mFixedVolumeDevices"); 13438 } 13439 return mFixedVolumeDevices.add(audioSystemDeviceOut); 13440 } 13441 removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut)13442 private boolean removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut) { 13443 if (DEBUG_VOL) { 13444 Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 13445 + " from mFixedVolumeDevices"); 13446 } 13447 return mFixedVolumeDevices.remove(audioSystemDeviceOut); 13448 } 13449 addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut)13450 private boolean addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut) { 13451 if (DEBUG_VOL) { 13452 Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 13453 + " to mFullVolumeDevices"); 13454 } 13455 return mFullVolumeDevices.add(audioSystemDeviceOut); 13456 } 13457 removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut)13458 private boolean removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut) { 13459 if (DEBUG_VOL) { 13460 Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 13461 + " from mFullVolumeDevices"); 13462 } 13463 return mFullVolumeDevices.remove(audioSystemDeviceOut); 13464 } 13465 addAudioSystemDeviceOutToAbsVolumeDevices(int audioSystemDeviceOut, AbsoluteVolumeDeviceInfo info)13466 private void addAudioSystemDeviceOutToAbsVolumeDevices(int audioSystemDeviceOut, 13467 AbsoluteVolumeDeviceInfo info) { 13468 if (DEBUG_VOL) { 13469 Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 13470 + " to mAbsoluteVolumeDeviceInfoMap with behavior " 13471 + AudioDeviceVolumeManager.volumeBehaviorName(info.mDeviceVolumeBehavior) 13472 ); 13473 } 13474 mAbsoluteVolumeDeviceInfoMap.put(audioSystemDeviceOut, info); 13475 } 13476 removeAudioSystemDeviceOutFromAbsVolumeDevices( int audioSystemDeviceOut)13477 private AbsoluteVolumeDeviceInfo removeAudioSystemDeviceOutFromAbsVolumeDevices( 13478 int audioSystemDeviceOut) { 13479 if (DEBUG_VOL) { 13480 Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 13481 + " from mAbsoluteVolumeDeviceInfoMap"); 13482 } 13483 return mAbsoluteVolumeDeviceInfoMap.remove(audioSystemDeviceOut); 13484 } 13485 13486 //==================== 13487 // Helper functions for app ops 13488 //==================== 13489 /** 13490 * Validates, and notes an app op for a given uid and package name. 13491 * Validation comes from exception catching: a security exception indicates the package 13492 * doesn't exist, an IAE indicates the uid and package don't match. The code only checks 13493 * if exception was thrown for robustness to code changes in op validation 13494 * @param op the app op to check 13495 * @param uid the uid of the caller 13496 * @param packageName the package to check 13497 * @return true if the origin of the call is valid (no uid / package mismatch) and the caller 13498 * is allowed to perform the operation 13499 */ checkNoteAppOp(int op, int uid, String packageName, String attributionTag)13500 private boolean checkNoteAppOp(int op, int uid, String packageName, String attributionTag) { 13501 try { 13502 if (mAppOps.noteOp(op, uid, packageName, attributionTag, null) 13503 != AppOpsManager.MODE_ALLOWED) { 13504 return false; 13505 } 13506 } catch (Exception e) { 13507 Log.e(TAG, "Error noting op:" + op + " on uid:" + uid + " for package:" 13508 + packageName, e); 13509 return false; 13510 } 13511 return true; 13512 } 13513 } 13514