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.BLUETOOTH_PRIVILEGED; 20 import static android.Manifest.permission.BLUETOOTH_STACK; 21 import static android.Manifest.permission.CALL_AUDIO_INTERCEPTION; 22 import static android.Manifest.permission.CAPTURE_AUDIO_HOTWORD; 23 import static android.Manifest.permission.CAPTURE_AUDIO_OUTPUT; 24 import static android.Manifest.permission.CAPTURE_MEDIA_OUTPUT; 25 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 26 import static android.Manifest.permission.MODIFY_AUDIO_ROUTING; 27 import static android.Manifest.permission.MODIFY_AUDIO_SETTINGS; 28 import static android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED; 29 import static android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS; 30 import static android.Manifest.permission.MODIFY_PHONE_STATE; 31 import static android.Manifest.permission.QUERY_AUDIO_STATE; 32 import static android.Manifest.permission.WRITE_SETTINGS; 33 import static android.app.BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT; 34 import static android.content.Intent.ACTION_PACKAGE_ADDED; 35 import static android.content.Intent.ACTION_PACKAGE_REMOVED; 36 import static android.content.Intent.EXTRA_ARCHIVAL; 37 import static android.content.Intent.EXTRA_REPLACING; 38 import static android.media.AudioDeviceInfo.TYPE_BLE_HEADSET; 39 import static android.media.AudioDeviceInfo.TYPE_BLE_SPEAKER; 40 import static android.media.AudioDeviceInfo.TYPE_BLUETOOTH_A2DP; 41 import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES; 42 import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_UNKNOWN; 43 import static android.media.AudioManager.DEVICE_OUT_BLE_HEADSET; 44 import static android.media.AudioManager.DEVICE_OUT_BLE_SPEAKER; 45 import static android.media.AudioManager.DEVICE_OUT_BLUETOOTH_A2DP; 46 import static android.media.AudioManager.RINGER_MODE_NORMAL; 47 import static android.media.AudioManager.RINGER_MODE_SILENT; 48 import static android.media.AudioManager.RINGER_MODE_VIBRATE; 49 import static android.media.AudioManager.STREAM_SYSTEM; 50 import static android.media.audio.Flags.autoPublicVolumeApiHardening; 51 import static android.media.audio.Flags.automaticBtDeviceType; 52 import static android.media.audio.Flags.featureSpatialAudioHeadtrackingLowLatency; 53 import static android.media.audio.Flags.focusFreezeTestApi; 54 import static android.media.audio.Flags.roForegroundAudioControl; 55 import static android.media.audio.Flags.scoManagedByAudio; 56 import static android.media.audiopolicy.Flags.enableFadeManagerConfiguration; 57 import static android.os.Process.FIRST_APPLICATION_UID; 58 import static android.os.Process.INVALID_UID; 59 import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE; 60 import static android.provider.Settings.Secure.VOLUME_HUSH_OFF; 61 import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE; 62 63 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; 64 import static com.android.media.audio.Flags.absVolumeIndexFix; 65 import static com.android.media.audio.Flags.alarmMinVolumeZero; 66 import static com.android.media.audio.Flags.audioserverPermissions; 67 import static com.android.media.audio.Flags.disablePrescaleAbsoluteVolume; 68 import static com.android.media.audio.Flags.ringerModeAffectsAlarm; 69 import static com.android.media.audio.Flags.setStreamVolumeOrder; 70 import static com.android.media.audio.Flags.vgsVssSyncMuteOrder; 71 import static com.android.server.audio.SoundDoseHelper.ACTION_CHECK_MUSIC_ACTIVE; 72 import static com.android.server.utils.EventLogger.Event.ALOGE; 73 import static com.android.server.utils.EventLogger.Event.ALOGI; 74 import static com.android.server.utils.EventLogger.Event.ALOGW; 75 76 import android.Manifest; 77 import android.annotation.EnforcePermission; 78 import android.annotation.IntDef; 79 import android.annotation.IntRange; 80 import android.annotation.NonNull; 81 import android.annotation.Nullable; 82 import android.annotation.RequiresPermission; 83 import android.annotation.SuppressLint; 84 import android.annotation.UserIdInt; 85 import android.app.ActivityManager; 86 import android.app.ActivityManagerInternal; 87 import android.app.AppGlobals; 88 import android.app.AppOpsManager; 89 import android.app.BroadcastOptions; 90 import android.app.IUidObserver; 91 import android.app.NotificationManager; 92 import android.app.UidObserver; 93 import android.app.role.OnRoleHoldersChangedListener; 94 import android.app.role.RoleManager; 95 import android.bluetooth.BluetoothDevice; 96 import android.bluetooth.BluetoothHeadset; 97 import android.bluetooth.BluetoothProfile; 98 import android.content.AttributionSource; 99 import android.content.BroadcastReceiver; 100 import android.content.ComponentName; 101 import android.content.ContentResolver; 102 import android.content.Context; 103 import android.content.Intent; 104 import android.content.IntentFilter; 105 import android.content.pm.ApplicationInfo; 106 import android.content.pm.PackageInfo; 107 import android.content.pm.PackageManager; 108 import android.content.pm.UserInfo; 109 import android.content.res.Configuration; 110 import android.content.res.Resources; 111 import android.database.ContentObserver; 112 import android.hardware.SensorPrivacyManager; 113 import android.hardware.SensorPrivacyManagerInternal; 114 import android.hardware.display.DisplayManager; 115 import android.hardware.display.DisplayManager.DisplayListener; 116 import android.hardware.hdmi.HdmiAudioSystemClient; 117 import android.hardware.hdmi.HdmiClient; 118 import android.hardware.hdmi.HdmiControlManager; 119 import android.hardware.hdmi.HdmiPlaybackClient; 120 import android.hardware.hdmi.HdmiTvClient; 121 import android.hardware.input.InputManager; 122 import android.hardware.usb.UsbManager; 123 import android.hidl.manager.V1_0.IServiceManager; 124 import android.media.AudioAttributes; 125 import android.media.AudioAttributes.AttributeSystemUsage; 126 import android.media.AudioDescriptor; 127 import android.media.AudioDeviceAttributes; 128 import android.media.AudioDeviceInfo; 129 import android.media.AudioDeviceVolumeManager; 130 import android.media.AudioFocusInfo; 131 import android.media.AudioFocusRequest; 132 import android.media.AudioFormat; 133 import android.media.AudioHalVersionInfo; 134 import android.media.AudioManager; 135 import android.media.AudioManager.AudioDeviceCategory; 136 import android.media.AudioManagerInternal; 137 import android.media.AudioMixerAttributes; 138 import android.media.AudioPlaybackConfiguration; 139 import android.media.AudioProfile; 140 import android.media.AudioRecordingConfiguration; 141 import android.media.AudioRoutesInfo; 142 import android.media.AudioSystem; 143 import android.media.BluetoothProfileConnectionInfo; 144 import android.media.FadeManagerConfiguration; 145 import android.media.IAudioDeviceVolumeDispatcher; 146 import android.media.IAudioFocusDispatcher; 147 import android.media.IAudioModeDispatcher; 148 import android.media.IAudioRoutesObserver; 149 import android.media.IAudioServerStateDispatcher; 150 import android.media.IAudioService; 151 import android.media.ICapturePresetDevicesRoleDispatcher; 152 import android.media.ICommunicationDeviceDispatcher; 153 import android.media.IDeviceVolumeBehaviorDispatcher; 154 import android.media.IDevicesForAttributesCallback; 155 import android.media.ILoudnessCodecUpdatesDispatcher; 156 import android.media.IMuteAwaitConnectionCallback; 157 import android.media.IPlaybackConfigDispatcher; 158 import android.media.IPreferredMixerAttributesDispatcher; 159 import android.media.IRecordingConfigDispatcher; 160 import android.media.IRingtonePlayer; 161 import android.media.ISpatializerCallback; 162 import android.media.ISpatializerHeadToSoundStagePoseCallback; 163 import android.media.ISpatializerHeadTrackerAvailableCallback; 164 import android.media.ISpatializerHeadTrackingModeCallback; 165 import android.media.ISpatializerOutputCallback; 166 import android.media.IStrategyNonDefaultDevicesDispatcher; 167 import android.media.IStrategyPreferredDevicesDispatcher; 168 import android.media.IStreamAliasingDispatcher; 169 import android.media.IVolumeController; 170 import android.media.LoudnessCodecController; 171 import android.media.LoudnessCodecInfo; 172 import android.media.MediaCodec; 173 import android.media.MediaMetrics; 174 import android.media.MediaRecorder.AudioSource; 175 import android.media.PlayerBase; 176 import android.media.Spatializer; 177 import android.media.Utils; 178 import android.media.VolumeInfo; 179 import android.media.VolumePolicy; 180 import android.media.audiofx.AudioEffect; 181 import android.media.audiopolicy.AudioMix; 182 import android.media.audiopolicy.AudioMixingRule; 183 import android.media.audiopolicy.AudioPolicy; 184 import android.media.audiopolicy.AudioPolicyConfig; 185 import android.media.audiopolicy.AudioProductStrategy; 186 import android.media.audiopolicy.AudioVolumeGroup; 187 import android.media.audiopolicy.IAudioPolicyCallback; 188 import android.media.permission.ClearCallingIdentityContext; 189 import android.media.permission.SafeCloseable; 190 import android.media.projection.IMediaProjection; 191 import android.media.projection.IMediaProjectionCallback; 192 import android.media.projection.IMediaProjectionManager; 193 import android.media.session.MediaSessionManager; 194 import android.net.Uri; 195 import android.os.Binder; 196 import android.os.Build; 197 import android.os.Bundle; 198 import android.os.Handler; 199 import android.os.HandlerThread; 200 import android.os.HwBinder; 201 import android.os.IBinder; 202 import android.os.Looper; 203 import android.os.Message; 204 import android.os.PermissionEnforcer; 205 import android.os.PersistableBundle; 206 import android.os.PowerManager; 207 import android.os.Process; 208 import android.os.RemoteCallbackList; 209 import android.os.RemoteException; 210 import android.os.ResultReceiver; 211 import android.os.ServiceDebugInfo; 212 import android.os.ServiceManager; 213 import android.os.ShellCallback; 214 import android.os.SystemClock; 215 import android.os.SystemProperties; 216 import android.os.UserHandle; 217 import android.os.UserManager; 218 import android.os.VibrationAttributes; 219 import android.os.VibrationEffect; 220 import android.os.Vibrator; 221 import android.os.VibratorManager; 222 import android.permission.PermissionManager; 223 import android.provider.Settings; 224 import android.provider.Settings.System; 225 import android.service.notification.ZenModeConfig; 226 import android.telecom.TelecomManager; 227 import android.telephony.SubscriptionManager; 228 import android.text.TextUtils; 229 import android.util.AndroidRuntimeException; 230 import android.util.ArrayMap; 231 import android.util.ArraySet; 232 import android.util.IntArray; 233 import android.util.Log; 234 import android.util.PrintWriterPrinter; 235 import android.util.Slog; 236 import android.util.SparseArray; 237 import android.util.SparseIntArray; 238 import android.view.Display; 239 import android.view.KeyEvent; 240 import android.view.accessibility.AccessibilityManager; 241 import android.widget.Toast; 242 243 import com.android.internal.annotations.GuardedBy; 244 import com.android.internal.annotations.VisibleForTesting; 245 import com.android.internal.os.SomeArgs; 246 import com.android.internal.util.DumpUtils; 247 import com.android.internal.util.Preconditions; 248 import com.android.server.EventLogTags; 249 import com.android.server.LocalManagerRegistry; 250 import com.android.server.LocalServices; 251 import com.android.server.SystemService; 252 import com.android.server.audio.AudioServiceEvents.DeviceVolumeEvent; 253 import com.android.server.audio.AudioServiceEvents.PhoneStateEvent; 254 import com.android.server.audio.AudioServiceEvents.VolChangedBroadcastEvent; 255 import com.android.server.audio.AudioServiceEvents.VolumeEvent; 256 import com.android.server.pm.PackageManagerLocal; 257 import com.android.server.pm.UserManagerInternal; 258 import com.android.server.pm.UserManagerInternal.UserRestrictionsListener; 259 import com.android.server.pm.UserManagerService; 260 import com.android.server.pm.permission.PermissionManagerServiceInternal; 261 import com.android.server.pm.pkg.PackageState; 262 import com.android.server.utils.EventLogger; 263 import com.android.server.wm.ActivityTaskManagerInternal; 264 265 import java.io.FileDescriptor; 266 import java.io.PrintWriter; 267 import java.lang.annotation.Retention; 268 import java.lang.annotation.RetentionPolicy; 269 import java.text.SimpleDateFormat; 270 import java.util.ArrayList; 271 import java.util.Arrays; 272 import java.util.Collection; 273 import java.util.Collections; 274 import java.util.Date; 275 import java.util.HashMap; 276 import java.util.HashSet; 277 import java.util.Iterator; 278 import java.util.LinkedHashMap; 279 import java.util.List; 280 import java.util.Map; 281 import java.util.NoSuchElementException; 282 import java.util.Objects; 283 import java.util.Set; 284 import java.util.TreeSet; 285 import java.util.concurrent.Executor; 286 import java.util.concurrent.Executors; 287 import java.util.concurrent.atomic.AtomicBoolean; 288 import java.util.concurrent.atomic.AtomicInteger; 289 import java.util.concurrent.atomic.AtomicLong; 290 import java.util.concurrent.atomic.AtomicReference; 291 import java.util.function.BooleanSupplier; 292 import java.util.stream.Collectors; 293 294 /** 295 * The implementation of the audio service for volume, audio focus, device management... 296 * <p> 297 * This implementation focuses on delivering a responsive UI. Most methods are 298 * asynchronous to external calls. For example, the task of setting a volume 299 * will update our internal state, but in a separate thread will set the system 300 * volume and later persist to the database. Similarly, setting the ringer mode 301 * will update the state and broadcast a change and in a separate thread later 302 * persist the ringer mode. 303 * 304 * @hide 305 */ 306 public class AudioService extends IAudioService.Stub 307 implements AccessibilityManager.TouchExplorationStateChangeListener, 308 AccessibilityManager.AccessibilityServicesStateChangeListener, 309 AudioSystemAdapter.OnRoutingUpdatedListener, 310 AudioSystemAdapter.OnVolRangeInitRequestListener { 311 312 private static final String TAG = "AS.AudioService"; 313 314 private final AudioSystemAdapter mAudioSystem; 315 private final SystemServerAdapter mSystemServer; 316 private final SettingsAdapter mSettings; 317 private final AudioPolicyFacade mAudioPolicy; 318 319 private final AudioServerPermissionProvider mPermissionProvider; 320 321 private final MusicFxHelper mMusicFxHelper; 322 323 /** Debug audio mode */ 324 protected static final boolean DEBUG_MODE = false; 325 326 /** Debug audio policy feature */ 327 protected static final boolean DEBUG_AP = false; 328 329 /** Debug volumes */ 330 protected static final boolean DEBUG_VOL = false; 331 332 /** debug calls to devices APIs */ 333 protected static final boolean DEBUG_DEVICES = false; 334 335 /** Debug communication route */ 336 protected static final boolean DEBUG_COMM_RTE = false; 337 338 /** Debug log sound fx (touchsounds...) in dumpsys */ 339 protected static final boolean DEBUG_LOG_SOUND_FX = false; 340 341 /** How long to delay before persisting a change in volume/ringer mode. */ 342 private static final int PERSIST_DELAY = 500; 343 344 /** How long to delay after a volume down event before unmuting a stream */ 345 private static final int UNMUTE_STREAM_DELAY = 350; 346 347 /** 348 * Delay before disconnecting a device that would cause BECOMING_NOISY intent to be sent, 349 * to give a chance to applications to pause. 350 */ 351 @VisibleForTesting 352 public static final int BECOMING_NOISY_DELAY_MS = 1000; 353 354 /** 355 * Only used in the result from {@link #checkForRingerModeChange(int, int, int)} 356 */ 357 private static final int FLAG_ADJUST_VOLUME = 1; 358 359 final Context mContext; 360 private final ContentResolver mContentResolver; 361 private final AppOpsManager mAppOps; 362 363 /** do not use directly, use getMediaSessionManager() which handles lazy initialization */ 364 @Nullable private volatile MediaSessionManager mMediaSessionManager; 365 366 // the platform type affects volume and silent mode behavior 367 private final int mPlatformType; 368 369 // indicates whether the system maps all streams to a single stream. 370 private final boolean mIsSingleVolume; 371 372 /** 373 * indicates whether STREAM_NOTIFICATION is aliased to STREAM_RING 374 * not final due to test method, see {@link #setNotifAliasRingForTest(boolean)}. 375 */ 376 private boolean mNotifAliasRing = false; 377 378 /** 379 * Test method to temporarily override whether STREAM_NOTIFICATION is aliased to STREAM_RING, 380 * volumes will be updated in case of a change. 381 * @param alias if true, STREAM_NOTIFICATION is aliased to STREAM_RING 382 */ 383 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setNotifAliasRingForTest(boolean alias)384 public void setNotifAliasRingForTest(boolean alias) { 385 super.setNotifAliasRingForTest_enforcePermission(); 386 boolean update = (mNotifAliasRing != alias); 387 mNotifAliasRing = alias; 388 if (update) { 389 updateStreamVolumeAlias(true, "AudioServiceTest"); 390 } 391 } 392 isPlatformVoice()393 /*package*/ boolean isPlatformVoice() { 394 return mPlatformType == AudioSystem.PLATFORM_VOICE; 395 } 396 isPlatformTelevision()397 /*package*/ boolean isPlatformTelevision() { 398 return mPlatformType == AudioSystem.PLATFORM_TELEVISION; 399 } 400 isPlatformAutomotive()401 /*package*/ boolean isPlatformAutomotive() { 402 return mPlatformType == AudioSystem.PLATFORM_AUTOMOTIVE; 403 } 404 405 /** The controller for the volume UI. */ 406 private final VolumeController mVolumeController = new VolumeController(); 407 408 // sendMsg() flags 409 /** If the msg is already queued, replace it with this one. */ 410 private static final int SENDMSG_REPLACE = 0; 411 /** If the msg is already queued, ignore this one and leave the old. */ 412 private static final int SENDMSG_NOOP = 1; 413 /** If the msg is already queued, queue this one and leave the old. */ 414 private static final int SENDMSG_QUEUE = 2; 415 416 // AudioHandler messages 417 /*package*/ static final int MSG_SET_DEVICE_VOLUME = 0; 418 private static final int MSG_PERSIST_VOLUME = 1; 419 private static final int MSG_PERSIST_VOLUME_GROUP = 2; 420 private static final int MSG_PERSIST_RINGER_MODE = 3; 421 private static final int MSG_AUDIO_SERVER_DIED = 4; 422 private static final int MSG_PLAY_SOUND_EFFECT = 5; 423 private static final int MSG_LOAD_SOUND_EFFECTS = 7; 424 private static final int MSG_SET_FORCE_USE = 8; 425 private static final int MSG_SET_ALL_VOLUMES = 10; 426 private static final int MSG_UNLOAD_SOUND_EFFECTS = 15; 427 private static final int MSG_SYSTEM_READY = 16; 428 private static final int MSG_UNMUTE_STREAM_ON_SINGLE_VOL_DEVICE = 18; 429 private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 19; 430 private static final int MSG_INDICATE_SYSTEM_READY = 20; 431 private static final int MSG_ACCESSORY_PLUG_MEDIA_UNMUTE = 21; 432 private static final int MSG_NOTIFY_VOL_EVENT = 22; 433 private static final int MSG_DISPATCH_AUDIO_SERVER_STATE = 23; 434 private static final int MSG_ENABLE_SURROUND_FORMATS = 24; 435 private static final int MSG_UPDATE_RINGER_MODE = 25; 436 private static final int MSG_SET_DEVICE_STREAM_VOLUME = 26; 437 private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27; 438 private static final int MSG_HDMI_VOLUME_CHECK = 28; 439 private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29; 440 private static final int MSG_BROADCAST_MICROPHONE_MUTE = 30; 441 private static final int MSG_CHECK_MODE_FOR_UID = 31; 442 private static final int MSG_STREAM_DEVICES_CHANGED = 32; 443 private static final int MSG_UPDATE_VOLUME_STATES_FOR_DEVICE = 33; 444 private static final int MSG_REINIT_VOLUMES = 34; 445 private static final int MSG_UPDATE_A11Y_SERVICE_UIDS = 35; 446 private static final int MSG_UPDATE_AUDIO_MODE = 36; 447 private static final int MSG_RECORDING_CONFIG_CHANGE = 37; 448 private static final int MSG_BT_DEV_CHANGED = 38; 449 450 private static final int MSG_DISPATCH_AUDIO_MODE = 40; 451 private static final int MSG_ROUTING_UPDATED = 41; 452 private static final int MSG_INIT_HEADTRACKING_SENSORS = 42; 453 private static final int MSG_ADD_ASSISTANT_SERVICE_UID = 44; 454 private static final int MSG_REMOVE_ASSISTANT_SERVICE_UID = 45; 455 private static final int MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID = 46; 456 private static final int MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR = 47; 457 private static final int MSG_ROTATION_UPDATE = 48; 458 private static final int MSG_FOLD_UPDATE = 49; 459 private static final int MSG_RESET_SPATIALIZER = 50; 460 private static final int MSG_NO_LOG_FOR_PLAYER_I = 51; 461 private static final int MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES = 52; 462 private static final int MSG_CONFIGURATION_CHANGED = 54; 463 private static final int MSG_BROADCAST_MASTER_MUTE = 55; 464 465 /** 466 * Messages handled by the {@link SoundDoseHelper}, do not exceed 467 * {@link MUSICFX_HELPER_MSG_START}. 468 */ 469 /*package*/ static final int SAFE_MEDIA_VOLUME_MSG_START = 1000; 470 471 /** Messages handled by the {@link MusicFxHelper}. */ 472 /*package*/ static final int MUSICFX_HELPER_MSG_START = 1100; 473 474 // start of messages handled under wakelock 475 // these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(), 476 // and not with sendMsg(..., ..., SENDMSG_QUEUE, ...) 477 private static final int MSG_DISABLE_AUDIO_FOR_UID = 100; 478 private static final int MSG_INIT_STREAMS_VOLUMES = 101; 479 private static final int MSG_INIT_SPATIALIZER = 102; 480 private static final int MSG_INIT_ADI_DEVICE_STATES = 103; 481 482 // end of messages handled under wakelock 483 484 // retry delay in case of failure to indicate system ready to AudioFlinger 485 private static final int INDICATE_SYSTEM_READY_RETRY_DELAY_MS = 1000; 486 487 // List of empty UIDs used to reset the active assistant list 488 private static final int[] NO_ACTIVE_ASSISTANT_SERVICE_UIDS = new int[0]; 489 490 // check playback or record activity every 6 seconds for UIDs owning mode IN_COMMUNICATION 491 private static final int CHECK_MODE_FOR_UID_PERIOD_MS = 6000; 492 493 /** @see AudioSystemThread */ 494 private AudioSystemThread mAudioSystemThread; 495 /** @see AudioHandler */ 496 private AudioHandler mAudioHandler; 497 /** @see VolumeStreamState */ 498 private VolumeStreamState[] mStreamStates; 499 getVssVolumeForDevice(int stream, int device)500 /*package*/ int getVssVolumeForDevice(int stream, int device) { 501 return mStreamStates[stream].getIndex(device); 502 } 503 getVssVolumeForStream(int stream)504 /*package*/ VolumeStreamState getVssVolumeForStream(int stream) { 505 return mStreamStates[stream]; 506 } 507 getMaxVssVolumeForStream(int stream)508 /*package*/ int getMaxVssVolumeForStream(int stream) { 509 return mStreamStates[stream].getMaxIndex(); 510 } 511 512 private SettingsObserver mSettingsObserver; 513 514 private AtomicInteger mMode = new AtomicInteger(AudioSystem.MODE_NORMAL); 515 516 // protects mRingerMode 517 private final Object mSettingsLock = new Object(); 518 519 /** Maximum volume index values for audio streams */ 520 protected static int[] MAX_STREAM_VOLUME = new int[] { 521 5, // STREAM_VOICE_CALL 522 7, // STREAM_SYSTEM 523 7, // STREAM_RING // configured by config_audio_ring_vol_steps 524 15, // STREAM_MUSIC 525 7, // STREAM_ALARM 526 7, // STREAM_NOTIFICATION // configured by config_audio_notif_vol_steps 527 15, // STREAM_BLUETOOTH_SCO 528 7, // STREAM_SYSTEM_ENFORCED 529 15, // STREAM_DTMF 530 15, // STREAM_TTS 531 15, // STREAM_ACCESSIBILITY 532 15 // STREAM_ASSISTANT 533 }; 534 535 /** Minimum volume index values for audio streams */ 536 protected static int[] MIN_STREAM_VOLUME = new int[] { 537 1, // STREAM_VOICE_CALL 538 0, // STREAM_SYSTEM 539 0, // STREAM_RING 540 0, // STREAM_MUSIC 541 1, // STREAM_ALARM 542 0, // STREAM_NOTIFICATION 543 0, // STREAM_BLUETOOTH_SCO 544 0, // STREAM_SYSTEM_ENFORCED 545 0, // STREAM_DTMF 546 0, // STREAM_TTS 547 1, // STREAM_ACCESSIBILITY 548 0 // STREAM_ASSISTANT 549 }; 550 551 /* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings 552 * of another stream: This avoids multiplying the volume settings for hidden 553 * stream types that follow other stream behavior for volume settings 554 * NOTE: do not create loops in aliases! 555 * Some streams alias to different streams according to device category (phone or tablet) or 556 * use case (in call vs off call...). See updateStreamVolumeAlias() for more details. 557 * mStreamVolumeAlias contains STREAM_VOLUME_ALIAS_VOICE aliases for a voice capable device 558 * (phone), STREAM_VOLUME_ALIAS_TELEVISION for a television or set-top box and 559 * STREAM_VOLUME_ALIAS_DEFAULT for other devices (e.g. tablets).*/ 560 private final int[] STREAM_VOLUME_ALIAS_VOICE = new int[] { 561 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 562 AudioSystem.STREAM_RING, // STREAM_SYSTEM 563 AudioSystem.STREAM_RING, // STREAM_RING 564 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 565 AudioSystem.STREAM_ALARM, // STREAM_ALARM 566 AudioSystem.STREAM_RING, // STREAM_NOTIFICATION 567 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 568 AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED 569 AudioSystem.STREAM_RING, // STREAM_DTMF 570 AudioSystem.STREAM_MUSIC, // STREAM_TTS 571 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 572 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 573 }; 574 private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] { 575 AudioSystem.STREAM_MUSIC, // STREAM_VOICE_CALL 576 AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM 577 AudioSystem.STREAM_MUSIC, // STREAM_RING 578 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 579 AudioSystem.STREAM_MUSIC, // STREAM_ALARM 580 AudioSystem.STREAM_MUSIC, // STREAM_NOTIFICATION 581 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 582 AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM_ENFORCED 583 AudioSystem.STREAM_MUSIC, // STREAM_DTMF 584 AudioSystem.STREAM_MUSIC, // STREAM_TTS 585 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 586 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 587 }; 588 /** 589 * Using Volume groups configuration allows to control volume per attributes 590 * and group definition may differ from stream aliases. 591 * So, do not alias any stream on one another when using volume groups. 592 * TODO(b/181140246): volume group definition hosting alias definition. 593 */ 594 private final int[] STREAM_VOLUME_ALIAS_NONE = new int[] { 595 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 596 AudioSystem.STREAM_SYSTEM, // STREAM_SYSTEM 597 AudioSystem.STREAM_RING, // STREAM_RING 598 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 599 AudioSystem.STREAM_ALARM, // STREAM_ALARM 600 AudioSystem.STREAM_NOTIFICATION, // STREAM_NOTIFICATION 601 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 602 AudioSystem.STREAM_SYSTEM_ENFORCED, // STREAM_SYSTEM_ENFORCED 603 AudioSystem.STREAM_DTMF, // STREAM_DTMF 604 AudioSystem.STREAM_TTS, // STREAM_TTS 605 AudioSystem.STREAM_ACCESSIBILITY, // STREAM_ACCESSIBILITY 606 AudioSystem.STREAM_ASSISTANT // STREAM_ASSISTANT 607 }; 608 private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] { 609 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 610 AudioSystem.STREAM_RING, // STREAM_SYSTEM 611 AudioSystem.STREAM_RING, // STREAM_RING 612 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 613 AudioSystem.STREAM_ALARM, // STREAM_ALARM 614 AudioSystem.STREAM_RING, // STREAM_NOTIFICATION 615 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 616 AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED 617 AudioSystem.STREAM_RING, // STREAM_DTMF 618 AudioSystem.STREAM_MUSIC, // STREAM_TTS 619 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 620 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 621 }; 622 protected static int[] mStreamVolumeAlias; 623 private static final int UNSET_INDEX = -1; 624 625 /** 626 * Map AudioSystem.STREAM_* constants to app ops. This should be used 627 * after mapping through mStreamVolumeAlias. 628 */ 629 private static final int[] STREAM_VOLUME_OPS = new int[] { 630 AppOpsManager.OP_AUDIO_VOICE_VOLUME, // STREAM_VOICE_CALL 631 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_SYSTEM 632 AppOpsManager.OP_AUDIO_RING_VOLUME, // STREAM_RING 633 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_MUSIC 634 AppOpsManager.OP_AUDIO_ALARM_VOLUME, // STREAM_ALARM 635 AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME, // STREAM_NOTIFICATION 636 AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME, // STREAM_BLUETOOTH_SCO 637 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_SYSTEM_ENFORCED 638 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_DTMF 639 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_TTS 640 AppOpsManager.OP_AUDIO_ACCESSIBILITY_VOLUME, // STREAM_ACCESSIBILITY 641 AppOpsManager.OP_AUDIO_MEDIA_VOLUME // STREAM_ASSISTANT 642 }; 643 644 private final boolean mUseFixedVolume; 645 private final boolean mRingerModeAffectsAlarm; 646 private final boolean mUseVolumeGroupAliases; 647 648 // If absolute volume is supported in AVRCP device 649 private volatile boolean mAvrcpAbsVolSupported = false; 650 651 private final Object mCachedAbsVolDrivingStreamsLock = new Object(); 652 // Contains for all the device types which support absolute volume the current streams that 653 // are driving the volume changes 654 @GuardedBy("mCachedAbsVolDrivingStreamsLock") 655 private final HashMap<Integer, Integer> mCachedAbsVolDrivingStreams = new HashMap<>( 656 Map.of(AudioSystem.DEVICE_OUT_BLE_HEADSET, AudioSystem.STREAM_MUSIC, 657 AudioSystem.DEVICE_OUT_BLE_SPEAKER, AudioSystem.STREAM_MUSIC, 658 AudioSystem.DEVICE_OUT_BLE_BROADCAST, AudioSystem.STREAM_MUSIC, 659 AudioSystem.DEVICE_OUT_HEARING_AID, AudioSystem.STREAM_MUSIC 660 )); 661 662 /** 663 * Default stream type used for volume control in the absence of playback 664 * e.g. user on homescreen, no app playing anything, presses hardware volume buttons, this 665 * stream type is controlled. 666 */ 667 protected static final int DEFAULT_VOL_STREAM_NO_PLAYBACK = AudioSystem.STREAM_MUSIC; 668 669 private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() { 670 public void onError(int error) { 671 switch (error) { 672 case AudioSystem.AUDIO_STATUS_SERVER_DIED: 673 // check for null in case error callback is called during instance creation 674 if (mRecordMonitor != null) { 675 mRecordMonitor.onAudioServerDied(); 676 } 677 // Notify the playback monitor that the audio server has died 678 if (mPlaybackMonitor != null) { 679 mPlaybackMonitor.onAudioServerDied(); 680 } 681 sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, 682 SENDMSG_NOOP, 0, 0, null, 0); 683 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE, 684 SENDMSG_QUEUE, 0, 0, null, 0); 685 break; 686 default: 687 break; 688 } 689 } 690 }; 691 692 /** 693 * Current ringer mode from one of {@link AudioManager#RINGER_MODE_NORMAL}, 694 * {@link AudioManager#RINGER_MODE_SILENT}, or 695 * {@link AudioManager#RINGER_MODE_VIBRATE}. 696 */ 697 @GuardedBy("mSettingsLock") 698 private int mRingerMode; // internal ringer mode, affects muting of underlying streams 699 @GuardedBy("mSettingsLock") 700 private int mRingerModeExternal = -1; // reported ringer mode to outside clients (AudioManager) 701 702 /** @see System#MODE_RINGER_STREAMS_AFFECTED */ 703 private int mRingerModeAffectedStreams = 0; 704 705 private int mZenModeAffectedStreams = 0; 706 707 // Streams currently muted by ringer mode and dnd 708 protected static volatile int sRingerAndZenModeMutedStreams; 709 710 /** Streams that can be muted by system. Do not resolve to aliases when checking. 711 * @see System#MUTE_STREAMS_AFFECTED */ 712 private int mMuteAffectedStreams; 713 714 /** Streams that can be muted by user. Do not resolve to aliases when checking. 715 * @see System#MUTE_STREAMS_AFFECTED */ 716 private int mUserMutableStreams; 717 718 @NonNull 719 private SoundEffectsHelper mSfxHelper; 720 721 /** 722 * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated. 723 * mVibrateSetting is just maintained during deprecation period but vibration policy is 724 * now only controlled by mHasVibrator and mRingerMode 725 */ 726 private int mVibrateSetting; 727 728 // Is there a vibrator 729 private final boolean mHasVibrator; 730 // Used to play vibrations 731 private Vibrator mVibrator; 732 private static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES = 733 VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH); 734 735 // Handler for broadcast receiver 736 // TODO(b/335513647) combine handlers 737 private final HandlerThread mBroadcastHandlerThread; 738 // Broadcast receiver for device connections intent broadcasts 739 private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver(); 740 741 private IMediaProjectionManager mProjectionService; // to validate projection token 742 743 /** Interface for UserManagerService. */ 744 private final UserManagerInternal mUserManagerInternal; 745 private final ActivityManagerInternal mActivityManagerInternal; 746 private final SensorPrivacyManagerInternal mSensorPrivacyManagerInternal; 747 748 private final UserRestrictionsListener mUserRestrictionsListener = 749 new AudioServiceUserRestrictionsListener(); 750 751 // List of binder death handlers for setMode() client processes. 752 // The last process to have called setMode() is at the top of the list. 753 // package-private so it can be accessed in AudioDeviceBroker.getSetModeDeathHandlers 754 //TODO candidate to be moved to separate class that handles synchronization 755 @GuardedBy("mDeviceBroker.mSetModeLock") 756 /*package*/ final ArrayList<SetModeDeathHandler> mSetModeDeathHandlers = 757 new ArrayList<SetModeDeathHandler>(); 758 759 // true if boot sequence has been completed 760 private boolean mSystemReady; 761 // true if Intent.ACTION_USER_SWITCHED has ever been received 762 private boolean mUserSwitchedReceived; 763 // previous volume adjustment direction received by checkForRingerModeChange() 764 private int mPrevVolDirection = AudioManager.ADJUST_SAME; 765 // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume 766 // is controlled by Vol keys. 767 private int mVolumeControlStream = -1; 768 // interpretation of whether the volume stream has been selected by the user by clicking on a 769 // volume slider to change which volume is controlled by the volume keys. Is false 770 // when mVolumeControlStream is -1. 771 private boolean mUserSelectedVolumeControlStream = false; 772 private final Object mForceControlStreamLock = new Object(); 773 // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system 774 // server process so in theory it is not necessary to monitor the client death. 775 // However it is good to be ready for future evolutions. 776 private ForceControlStreamClient mForceControlStreamClient = null; 777 // Used to play ringtones outside system_server 778 private volatile IRingtonePlayer mRingtonePlayer; 779 780 // Devices for which the volume is fixed (volume is either max or muted) 781 Set<Integer> mFixedVolumeDevices = new HashSet<>(Arrays.asList( 782 AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, 783 AudioSystem.DEVICE_OUT_AUX_LINE)); 784 // Devices for which the volume is always max, no volume panel 785 Set<Integer> mFullVolumeDevices = new HashSet<>(Arrays.asList( 786 AudioSystem.DEVICE_OUT_HDMI_ARC, 787 AudioSystem.DEVICE_OUT_HDMI_EARC 788 )); 789 790 // Devices where the framework sends a full scale audio signal, and controls the volume of 791 // the external audio system separately. 792 // For possible volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}. 793 Map<Integer, AbsoluteVolumeDeviceInfo> mAbsoluteVolumeDeviceInfoMap = new ArrayMap<>(); 794 795 /** 796 * Stores information about a device using absolute volume behavior. 797 */ 798 private static final class AbsoluteVolumeDeviceInfo { 799 private final AudioDeviceAttributes mDevice; 800 private final List<VolumeInfo> mVolumeInfos; 801 private final IAudioDeviceVolumeDispatcher mCallback; 802 private final boolean mHandlesVolumeAdjustment; 803 private @AudioManager.AbsoluteDeviceVolumeBehavior int mDeviceVolumeBehavior; 804 AbsoluteVolumeDeviceInfo( AudioDeviceAttributes device, List<VolumeInfo> volumeInfos, IAudioDeviceVolumeDispatcher callback, boolean handlesVolumeAdjustment, @AudioManager.AbsoluteDeviceVolumeBehavior int behavior)805 private AbsoluteVolumeDeviceInfo( 806 AudioDeviceAttributes device, 807 List<VolumeInfo> volumeInfos, 808 IAudioDeviceVolumeDispatcher callback, 809 boolean handlesVolumeAdjustment, 810 @AudioManager.AbsoluteDeviceVolumeBehavior int behavior) { 811 this.mDevice = device; 812 this.mVolumeInfos = volumeInfos; 813 this.mCallback = callback; 814 this.mHandlesVolumeAdjustment = handlesVolumeAdjustment; 815 this.mDeviceVolumeBehavior = behavior; 816 } 817 818 /** 819 * Given a stream type, returns a matching VolumeInfo. 820 */ 821 @Nullable getMatchingVolumeInfoForStream(int streamType)822 private VolumeInfo getMatchingVolumeInfoForStream(int streamType) { 823 for (VolumeInfo volumeInfo : mVolumeInfos) { 824 boolean streamTypeMatches = volumeInfo.hasStreamType() 825 && volumeInfo.getStreamType() == streamType; 826 boolean volumeGroupMatches = volumeInfo.hasVolumeGroup() 827 && Arrays.stream(volumeInfo.getVolumeGroup().getLegacyStreamTypes()) 828 .anyMatch(s -> s == streamType); 829 if (streamTypeMatches || volumeGroupMatches) { 830 return volumeInfo; 831 } 832 } 833 return null; 834 } 835 } 836 837 // Devices for the which use the "absolute volume" concept (framework sends audio signal 838 // full scale, and volume control separately) and can be used for multiple use cases reflected 839 // by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL). 840 Set<Integer> mAbsVolumeMultiModeCaseDevices = new HashSet<>( 841 Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID)); 842 843 private final boolean mMonitorRotation; 844 845 private boolean mDockAudioMediaEnabled = true; 846 847 /** 848 * RestorableParameters is a thread-safe class used to store a 849 * first-in first-out history of parameters for replay / restoration. 850 * 851 * The idealized implementation of restoration would have a list of setting methods and 852 * values to be called for restoration. Explicitly managing such setters and 853 * values would be tedious - a simpler method is to store the values and the 854 * method implicitly by lambda capture (the values must be immutable or synchronization 855 * needs to be taken). 856 * 857 * We provide queueRestoreWithRemovalIfTrue() to allow 858 * the caller to provide a BooleanSupplier lambda, which conveniently packages 859 * the setter and its parameters needed for restoration. If during restoration, 860 * the BooleanSupplier returns true, e.g. on error, it is removed from the mMap 861 * so as not to be called on a subsequent restore. 862 * 863 * We provide a setParameters() method as an example helper method. 864 */ 865 private static class RestorableParameters { 866 /** 867 * Sets a parameter and queues for restoration if successful. 868 * 869 * @param id a string handle associated with this parameter. 870 * @param parameter the actual parameter string. 871 * @return the result of AudioSystem.setParameters 872 */ setParameters(@onNull String id, @NonNull String parameter)873 public int setParameters(@NonNull String id, @NonNull String parameter) { 874 Objects.requireNonNull(id, "id must not be null"); 875 Objects.requireNonNull(parameter, "parameter must not be null"); 876 synchronized (mMap) { 877 final int status = AudioSystem.setParameters(parameter); 878 if (status == AudioSystem.AUDIO_STATUS_OK) { // Java uses recursive mutexes. 879 queueRestoreWithRemovalIfTrue(id, () -> { // remove me if set fails. 880 return AudioSystem.setParameters(parameter) != AudioSystem.AUDIO_STATUS_OK; 881 }); 882 } 883 // Implementation detail: We do not mMap.remove(id); on failure. 884 return status; 885 } 886 } 887 888 /** 889 * Queues a restore method which is executed on restoreAll(). 890 * 891 * If the supplier null, the id is removed from the restore map. 892 * 893 * Note: When the BooleanSupplier restore method is executed 894 * during restoreAll, if it returns true, it is removed from the 895 * restore map. 896 * 897 * @param id a unique tag associated with the restore method. 898 * @param supplier is a BooleanSupplier lambda. 899 */ queueRestoreWithRemovalIfTrue( @onNull String id, @Nullable BooleanSupplier supplier)900 public void queueRestoreWithRemovalIfTrue( 901 @NonNull String id, @Nullable BooleanSupplier supplier) { 902 Objects.requireNonNull(id, "id must not be null"); 903 synchronized (mMap) { 904 if (supplier != null) { 905 mMap.put(id, supplier); 906 } else { 907 mMap.remove(id); 908 } 909 } 910 } 911 912 /** 913 * Restore all parameters 914 * 915 * During restoration after audioserver death, any BooleanSupplier that returns 916 * true, for example on parameter restoration error, will be removed from mMap 917 * so as not to be executed on a subsequent restoreAll(). 918 */ restoreAll()919 public void restoreAll() { 920 synchronized (mMap) { 921 // Note: removing from values() also removes from the backing map. 922 // TODO: Consider catching exceptions? 923 mMap.values().removeIf(v -> { 924 return v.getAsBoolean(); // this iterates the setters(). 925 }); 926 } 927 } 928 929 /** 930 * mMap is a LinkedHashMap<Key, Value> of parameters restored by restore(). 931 * The Key is a unique id tag for identification. 932 * The Value is a lambda expression which returns true if the entry is to 933 * be removed. 934 * 935 * 1) For memory limitation purposes, mMap keeps the latest MAX_ENTRIES 936 * accessed in the map. 937 * 2) Parameters are restored in order of queuing, first in first out, 938 * from earliest to latest. 939 */ 940 @GuardedBy("mMap") 941 private Map</* @NonNull */ String, /* @NonNull */ BooleanSupplier> mMap = 942 new LinkedHashMap<>() { 943 // TODO: do we need this memory limitation? 944 private static final int MAX_ENTRIES = 1000; // limit our memory for now. 945 @Override 946 protected boolean removeEldestEntry(Map.Entry eldest) { 947 if (size() <= MAX_ENTRIES) return false; 948 Log.w(TAG, "Parameter map exceeds " 949 + MAX_ENTRIES + " removing " + eldest.getKey()); // don't silently remove. 950 return true; 951 } 952 }; 953 } 954 955 // We currently have one instance for mRestorableParameters used for 956 // setAdditionalOutputDeviceDelay(). Other methods requiring restoration could share this 957 // or use their own instance. 958 private RestorableParameters mRestorableParameters = new RestorableParameters(); 959 960 private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; 961 962 private PowerManager.WakeLock mAudioEventWakeLock; 963 964 private final MediaFocusControl mMediaFocusControl; 965 966 // Pre-scale for Bluetooth Absolute Volume 967 private float[] mPrescaleAbsoluteVolume = new float[] { 968 0.6f, // Pre-scale for index 1 969 0.8f, // Pre-scale for index 2 970 0.9f, // Pre-scale for index 3 971 }; 972 973 private NotificationManager mNm; 974 private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate; 975 private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT; 976 private long mLoweredFromNormalToVibrateTime; 977 978 // Array of Uids of valid assistant services to check if caller is one of them 979 @GuardedBy("mSettingsLock") 980 private final ArraySet<Integer> mAssistantUids = new ArraySet<>(); 981 @GuardedBy("mSettingsLock") 982 private int mPrimaryAssistantUid = INVALID_UID; 983 984 // Array of Uids of valid active assistant service to check if caller is one of them 985 @GuardedBy("mSettingsLock") 986 private int[] mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS; 987 988 // Array of Uids of valid accessibility services to check if caller is one of them 989 private final Object mAccessibilityServiceUidsLock = new Object(); 990 @GuardedBy("mAccessibilityServiceUidsLock") 991 private int[] mAccessibilityServiceUids; 992 993 // Uid of the active input method service to check if caller is the one or not. 994 private int mInputMethodServiceUid = android.os.Process.INVALID_UID; 995 private final Object mInputMethodServiceUidLock = new Object(); 996 997 private int mEncodedSurroundMode; 998 private String mEnabledSurroundFormats; 999 private boolean mSurroundModeChanged; 1000 1001 private boolean mSupportsMicPrivacyToggle; 1002 1003 private boolean mMicMuteFromSwitch; 1004 private boolean mMicMuteFromApi; 1005 private boolean mMicMuteFromRestrictions; 1006 private boolean mMicMuteFromPrivacyToggle; 1007 // caches the value returned by AudioSystem.isMicrophoneMuted() 1008 private boolean mMicMuteFromSystemCached; 1009 1010 private boolean mNavigationRepeatSoundEffectsEnabled; 1011 private boolean mHomeSoundEffectEnabled; 1012 1013 private final SoundDoseHelper mSoundDoseHelper; 1014 1015 private final LoudnessCodecHelper mLoudnessCodecHelper; 1016 1017 private final HardeningEnforcer mHardeningEnforcer; 1018 1019 private final AudioVolumeGroupHelperBase mAudioVolumeGroupHelper; 1020 1021 private final Object mSupportedSystemUsagesLock = new Object(); 1022 @GuardedBy("mSupportedSystemUsagesLock") 1023 private @AttributeSystemUsage int[] mSupportedSystemUsages = 1024 new int[]{AudioAttributes.USAGE_CALL_ASSISTANT}; 1025 1026 // Defines the format for the connection "address" for ALSA devices makeAlsaAddressString(int card, int device)1027 public static String makeAlsaAddressString(int card, int device) { 1028 return "card=" + card + ";device=" + device; 1029 } 1030 1031 private static class AudioVolumeGroupHelper extends AudioVolumeGroupHelperBase { 1032 @Override getAudioVolumeGroups()1033 public List<AudioVolumeGroup> getAudioVolumeGroups() { 1034 return AudioVolumeGroup.getAudioVolumeGroups(); 1035 } 1036 } 1037 1038 public static final class Lifecycle extends SystemService { 1039 private AudioService mService; 1040 Lifecycle(Context context)1041 public Lifecycle(Context context) { 1042 super(context); 1043 var audioserverLifecycleExecutor = Executors.newSingleThreadExecutor(); 1044 var audioPolicyFacade = new DefaultAudioPolicyFacade(audioserverLifecycleExecutor); 1045 mService = new AudioService(context, 1046 AudioSystemAdapter.getDefaultAdapter(), 1047 SystemServerAdapter.getDefaultAdapter(context), 1048 SettingsAdapter.getDefaultAdapter(), 1049 new AudioVolumeGroupHelper(), 1050 audioPolicyFacade, 1051 null, 1052 context.getSystemService(AppOpsManager.class), 1053 PermissionEnforcer.fromContext(context), 1054 audioserverPermissions() ? 1055 initializeAudioServerPermissionProvider( 1056 context, audioPolicyFacade, audioserverLifecycleExecutor) : 1057 null 1058 ); 1059 } 1060 1061 @Override onStart()1062 public void onStart() { 1063 publishBinderService(Context.AUDIO_SERVICE, mService); 1064 } 1065 1066 @Override onBootPhase(int phase)1067 public void onBootPhase(int phase) { 1068 if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { 1069 mService.systemReady(); 1070 } 1071 } 1072 } 1073 1074 final private IUidObserver mUidObserver = new UidObserver() { 1075 @Override public void onUidGone(int uid, boolean disabled) { 1076 // Once the uid is no longer running, no need to keep trying to disable its audio. 1077 disableAudioForUid(false, uid); 1078 } 1079 1080 @Override public void onUidCachedChanged(int uid, boolean cached) { 1081 disableAudioForUid(cached, uid); 1082 } 1083 1084 private void disableAudioForUid(boolean disable, int uid) { 1085 queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID, 1086 disable ? 1 : 0 /* arg1 */, uid /* arg2 */, 1087 null /* obj */, 0 /* delay */); 1088 } 1089 }; 1090 1091 @GuardedBy("mSettingsLock") 1092 private boolean mRttEnabled = false; 1093 1094 private AtomicBoolean mMasterMute = new AtomicBoolean(false); 1095 1096 private DisplayManager mDisplayManager; 1097 1098 private DisplayListener mDisplayListener = 1099 new DisplayListener() { 1100 @Override 1101 public void onDisplayAdded(int displayId) {} 1102 1103 @Override 1104 public void onDisplayRemoved(int displayId) {} 1105 1106 @Override 1107 public void onDisplayChanged(int displayId) { 1108 if (displayId != Display.DEFAULT_DISPLAY) { 1109 return; 1110 } 1111 int displayState = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY).getState(); 1112 if (displayState == Display.STATE_ON) { 1113 if (mMonitorRotation) { 1114 RotationHelper.enable(); 1115 } 1116 AudioSystem.setParameters("screen_state=on"); 1117 } else { 1118 if (mMonitorRotation) { 1119 //reduce wakeups (save current) by only listening when display is on 1120 RotationHelper.disable(); 1121 } 1122 AudioSystem.setParameters("screen_state=off"); 1123 } 1124 } 1125 }; 1126 1127 /////////////////////////////////////////////////////////////////////////// 1128 // Construction 1129 /////////////////////////////////////////////////////////////////////////// 1130 1131 1132 /** 1133 * @param context 1134 * @param audioSystem Adapter for {@link AudioSystem} 1135 * @param systemServer Adapter for privilieged functionality for system server components 1136 * @param settings Adapter for {@link Settings} 1137 * @param audioVolumeGroupHelper Adapter for {@link AudioVolumeGroup} 1138 * @param audioPolicy Interface of a facade to IAudioPolicyManager 1139 * @param looper Looper to use for the service's message handler. If this is null, an 1140 * {@link AudioSystemThread} is created as the messaging thread instead. 1141 * @param appOps {@link AppOpsManager} system service 1142 * @param enforcer Used for permission enforcing 1143 */ 1144 @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer, SettingsAdapter settings, AudioVolumeGroupHelperBase audioVolumeGroupHelper, AudioPolicyFacade audioPolicy, @Nullable Looper looper, AppOpsManager appOps, @NonNull PermissionEnforcer enforcer, AudioServerPermissionProvider permissionProvider)1145 public AudioService(Context context, AudioSystemAdapter audioSystem, 1146 SystemServerAdapter systemServer, SettingsAdapter settings, 1147 AudioVolumeGroupHelperBase audioVolumeGroupHelper, AudioPolicyFacade audioPolicy, 1148 @Nullable Looper looper, AppOpsManager appOps, @NonNull PermissionEnforcer enforcer, 1149 /* @NonNull */ AudioServerPermissionProvider permissionProvider) { 1150 super(enforcer); 1151 sLifecycleLogger.enqueue(new EventLogger.StringEvent("AudioService()")); 1152 mContext = context; 1153 mContentResolver = context.getContentResolver(); 1154 mAppOps = appOps; 1155 1156 mPermissionProvider = permissionProvider; 1157 1158 mAudioSystem = audioSystem; 1159 mSystemServer = systemServer; 1160 mAudioVolumeGroupHelper = audioVolumeGroupHelper; 1161 mSettings = settings; 1162 mAudioPolicy = audioPolicy; 1163 mPlatformType = AudioSystem.getPlatformType(context); 1164 1165 mBroadcastHandlerThread = new HandlerThread("AudioService Broadcast"); 1166 mBroadcastHandlerThread.start(); 1167 1168 mDeviceBroker = new AudioDeviceBroker(mContext, this, mAudioSystem); 1169 1170 mIsSingleVolume = AudioSystem.isSingleVolume(context); 1171 1172 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 1173 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); 1174 mSensorPrivacyManagerInternal = 1175 LocalServices.getService(SensorPrivacyManagerInternal.class); 1176 1177 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 1178 mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent"); 1179 1180 mSfxHelper = new SoundEffectsHelper(mContext, playerBase -> ignorePlayerLogs(playerBase)); 1181 1182 boolean binauralEnabledDefault = SystemProperties.getBoolean( 1183 "ro.audio.spatializer_binaural_enabled_default", true); 1184 boolean transauralEnabledDefault = SystemProperties.getBoolean( 1185 "ro.audio.spatializer_transaural_enabled_default", true); 1186 boolean headTrackingEnabledDefault = mContext.getResources().getBoolean( 1187 com.android.internal.R.bool.config_spatial_audio_head_tracking_enabled_default); 1188 1189 mSpatializerHelper = new SpatializerHelper(this, mAudioSystem, mDeviceBroker, 1190 binauralEnabledDefault, transauralEnabledDefault, headTrackingEnabledDefault); 1191 1192 mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); 1193 mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator(); 1194 1195 mSupportsMicPrivacyToggle = context.getSystemService(SensorPrivacyManager.class) 1196 .supportsSensorToggle(SensorPrivacyManager.Sensors.MICROPHONE); 1197 1198 mUseVolumeGroupAliases = mContext.getResources().getBoolean( 1199 com.android.internal.R.bool.config_handleVolumeAliasesUsingVolumeGroups); 1200 1201 // Initialize volume 1202 // Priority 1 - Android Property 1203 // Priority 2 - Audio Policy Service 1204 // Priority 3 - Default Value 1205 if (AudioProductStrategy.getAudioProductStrategies().size() > 0) { 1206 int numStreamTypes = AudioSystem.getNumStreamTypes(); 1207 1208 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 1209 AudioAttributes attr = 1210 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType( 1211 streamType); 1212 int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr); 1213 if (maxVolume != -1) { 1214 MAX_STREAM_VOLUME[streamType] = maxVolume; 1215 } 1216 int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr); 1217 if (minVolume != -1) { 1218 MIN_STREAM_VOLUME[streamType] = minVolume; 1219 } 1220 } 1221 if (mUseVolumeGroupAliases) { 1222 // Set all default to uninitialized. 1223 for (int stream = 0; stream < AudioSystem.DEFAULT_STREAM_VOLUME.length; stream++) { 1224 AudioSystem.DEFAULT_STREAM_VOLUME[stream] = UNSET_INDEX; 1225 } 1226 } 1227 } 1228 1229 int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1); 1230 if (maxCallVolume != -1) { 1231 MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume; 1232 } 1233 1234 int defaultCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_default", -1); 1235 if (defaultCallVolume != -1 && 1236 defaultCallVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] && 1237 defaultCallVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) { 1238 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume; 1239 } else { 1240 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = 1241 (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4; 1242 } 1243 1244 int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1); 1245 if (maxMusicVolume != -1) { 1246 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume; 1247 } 1248 1249 int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1); 1250 if (defaultMusicVolume != -1 && 1251 defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] && 1252 defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) { 1253 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume; 1254 } else { 1255 if (isPlatformTelevision()) { 1256 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = 1257 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4; 1258 } else { 1259 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = 1260 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3; 1261 } 1262 } 1263 1264 int maxAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_steps", -1); 1265 if (maxAlarmVolume != -1) { 1266 MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = maxAlarmVolume; 1267 } 1268 1269 if (alarmMinVolumeZero()) { 1270 try { 1271 int minAlarmVolume = mContext.getResources().getInteger( 1272 com.android.internal.R.integer.config_audio_alarm_min_vol); 1273 if (minAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) { 1274 MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = minAlarmVolume; 1275 } else { 1276 Log.e(TAG, "Error min alarm volume greater than max alarm volume"); 1277 } 1278 } catch (Resources.NotFoundException e) { 1279 Log.e(TAG, "Error querying for alarm min volume ", e); 1280 } 1281 } 1282 int defaultAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_default", -1); 1283 if (defaultAlarmVolume != -1 && 1284 defaultAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) { 1285 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = defaultAlarmVolume; 1286 } else { 1287 // Default is 6 out of 7 (default maximum), so scale accordingly. 1288 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = 1289 6 * MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] / 7; 1290 } 1291 1292 int maxSystemVolume = SystemProperties.getInt("ro.config.system_vol_steps", -1); 1293 if (maxSystemVolume != -1) { 1294 MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = maxSystemVolume; 1295 } 1296 1297 int defaultSystemVolume = SystemProperties.getInt("ro.config.system_vol_default", -1); 1298 if (defaultSystemVolume != -1 && 1299 defaultSystemVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]) { 1300 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = defaultSystemVolume; 1301 } else { 1302 // Default is to use maximum. 1303 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = 1304 MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]; 1305 } 1306 1307 int minAssistantVolume = SystemProperties.getInt("ro.config.assistant_vol_min", -1); 1308 if (minAssistantVolume != -1) { 1309 MIN_STREAM_VOLUME[AudioSystem.STREAM_ASSISTANT] = minAssistantVolume; 1310 } 1311 1312 // Read following properties to configure max volume (number of steps) and default volume 1313 // for STREAM_NOTIFICATION and STREAM_RING: 1314 // config_audio_notif_vol_default 1315 // config_audio_notif_vol_steps 1316 // config_audio_ring_vol_default 1317 // config_audio_ring_vol_steps 1318 int[] streams = { AudioSystem.STREAM_NOTIFICATION, AudioSystem.STREAM_RING }; 1319 int[] stepsResId = { com.android.internal.R.integer.config_audio_notif_vol_steps, 1320 com.android.internal.R.integer.config_audio_ring_vol_steps }; 1321 int[] defaultResId = { com.android.internal.R.integer.config_audio_notif_vol_default, 1322 com.android.internal.R.integer.config_audio_ring_vol_default }; 1323 for (int s = 0; s < streams.length; s++) { 1324 try { 1325 final int maxVol = mContext.getResources().getInteger(stepsResId[s]); 1326 if (maxVol <= 0) { 1327 throw new IllegalArgumentException("Invalid negative max volume for stream " 1328 + streams[s]); 1329 } 1330 Log.i(TAG, "Stream " + streams[s] + ": using max vol of " + maxVol); 1331 MAX_STREAM_VOLUME[streams[s]] = maxVol; 1332 } catch (Resources.NotFoundException e) { 1333 Log.e(TAG, "Error querying max vol for stream type " + streams[s], e); 1334 } 1335 try { 1336 final int defaultVol = mContext.getResources().getInteger(defaultResId[s]); 1337 if (defaultVol > MAX_STREAM_VOLUME[streams[s]]) { 1338 throw new IllegalArgumentException("Invalid default volume (" + defaultVol 1339 + ") for stream " + streams[s] + ", greater than max volume of " 1340 + MAX_STREAM_VOLUME[streams[s]]); 1341 } 1342 if (defaultVol < MIN_STREAM_VOLUME[streams[s]]) { 1343 throw new IllegalArgumentException("Invalid default volume (" + defaultVol 1344 + ") for stream " + streams[s] + ", lower than min volume of " 1345 + MIN_STREAM_VOLUME[streams[s]]); 1346 } 1347 Log.i(TAG, "Stream " + streams[s] + ": using default vol of " + defaultVol); 1348 AudioSystem.DEFAULT_STREAM_VOLUME[streams[s]] = defaultVol; 1349 } catch (Resources.NotFoundException e) { 1350 Log.e(TAG, "Error querying default vol for stream type " + streams[s], e); 1351 } 1352 } 1353 1354 if (looper == null) { 1355 createAudioSystemThread(); 1356 } else { 1357 mAudioHandler = new AudioHandler(looper); 1358 } 1359 1360 mSoundDoseHelper = new SoundDoseHelper(this, mContext, mAudioHandler, mSettings, 1361 mVolumeController); 1362 1363 AudioSystem.setErrorCallback(mAudioSystemCallback); 1364 1365 updateAudioHalPids(); 1366 1367 mUseFixedVolume = mContext.getResources().getBoolean( 1368 com.android.internal.R.bool.config_useFixedVolume); 1369 1370 mRingerModeAffectsAlarm = mContext.getResources().getBoolean( 1371 com.android.internal.R.bool.config_audio_ringer_mode_affects_alarm_stream); 1372 1373 mRecordMonitor = new RecordingActivityMonitor(mContext); 1374 mRecordMonitor.registerRecordingCallback(mVoiceRecordingActivityMonitor, true); 1375 1376 // must be called before readPersistedSettings() which needs a valid mStreamVolumeAlias[] 1377 // array initialized by updateStreamVolumeAlias() 1378 updateStreamVolumeAlias(false /*updateVolumes*/, TAG); 1379 readPersistedSettings(); 1380 readUserRestrictions(); 1381 1382 mLoudnessCodecHelper = new LoudnessCodecHelper(this); 1383 1384 mPlaybackMonitor = 1385 new PlaybackActivityMonitor(context, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM], 1386 device -> onMuteAwaitConnectionTimeout(device)); 1387 mPlaybackMonitor.registerPlaybackCallback(mPlaybackActivityMonitor, true); 1388 1389 mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor); 1390 1391 readAndSetLowRamDevice(); 1392 1393 mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported(); 1394 1395 if (mSystemServer.isPrivileged()) { 1396 LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal()); 1397 1398 mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener); 1399 1400 mRecordMonitor.initMonitor(); 1401 } 1402 1403 mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false); 1404 1405 mHasSpatializerEffect = SystemProperties.getBoolean("ro.audio.spatializer_enabled", false); 1406 1407 // monitor routing updates coming from native 1408 mAudioSystem.setRoutingListener(this); 1409 // monitor requests for volume range initialization coming from native (typically when 1410 // errors are found by AudioPolicyManager 1411 mAudioSystem.setVolRangeInitReqListener(this); 1412 1413 // done with service initialization, continue additional work in our Handler thread 1414 queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES, 1415 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */); 1416 queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_ADI_DEVICE_STATES, 1417 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */); 1418 queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_SPATIALIZER, 1419 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */); 1420 1421 mDisplayManager = context.getSystemService(DisplayManager.class); 1422 1423 mMusicFxHelper = new MusicFxHelper(mContext, mAudioHandler); 1424 1425 mHardeningEnforcer = new HardeningEnforcer(mContext, isPlatformAutomotive(), mAppOps, 1426 context.getPackageManager()); 1427 } 1428 initVolumeStreamStates()1429 private void initVolumeStreamStates() { 1430 int numStreamTypes = AudioSystem.getNumStreamTypes(); 1431 synchronized (VolumeStreamState.class) { 1432 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 1433 VolumeStreamState streamState = mStreamStates[streamType]; 1434 int groupId = getVolumeGroupForStreamType(streamType); 1435 if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP 1436 && sVolumeGroupStates.indexOfKey(groupId) >= 0) { 1437 streamState.setVolumeGroupState(sVolumeGroupStates.get(groupId)); 1438 } 1439 } 1440 } 1441 } 1442 1443 /** 1444 * Called by handling of MSG_INIT_STREAMS_VOLUMES 1445 */ onInitStreamsAndVolumes()1446 private void onInitStreamsAndVolumes() { 1447 synchronized (mSettingsLock) { 1448 mCameraSoundForced = readCameraSoundForced(); 1449 sendMsg(mAudioHandler, 1450 MSG_SET_FORCE_USE, 1451 SENDMSG_QUEUE, 1452 AudioSystem.FOR_SYSTEM, 1453 mCameraSoundForced 1454 ? AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE, 1455 new String("AudioService ctor"), 1456 0); 1457 } 1458 1459 createStreamStates(); 1460 1461 // must be called after createStreamStates() as it uses MUSIC volume as default if no 1462 // persistent data 1463 initVolumeGroupStates(); 1464 1465 mSoundDoseHelper.initSafeMediaVolumeIndex(); 1466 // Link VGS on VSS 1467 initVolumeStreamStates(); 1468 1469 // Call setRingerModeInt() to apply correct mute 1470 // state on streams affected by ringer mode. 1471 sRingerAndZenModeMutedStreams = 0; 1472 sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent( 1473 sRingerAndZenModeMutedStreams, "onInitStreamsAndVolumes")); 1474 setRingerModeInt(getRingerModeInternal(), false); 1475 1476 if (!disablePrescaleAbsoluteVolume()) { 1477 final float[] preScale = new float[3]; 1478 preScale[0] = mContext.getResources().getFraction( 1479 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1, 1480 1, 1); 1481 preScale[1] = mContext.getResources().getFraction( 1482 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index2, 1483 1, 1); 1484 preScale[2] = mContext.getResources().getFraction( 1485 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index3, 1486 1, 1); 1487 for (int i = 0; i < preScale.length; i++) { 1488 if (0.0f <= preScale[i] && preScale[i] <= 1.0f) { 1489 mPrescaleAbsoluteVolume[i] = preScale[i]; 1490 } 1491 } 1492 } 1493 1494 initExternalEventReceivers(); 1495 1496 // check on volume initialization 1497 checkVolumeRangeInitialization("AudioService()"); 1498 1499 synchronized (mCachedAbsVolDrivingStreamsLock) { 1500 mCachedAbsVolDrivingStreams.forEach((dev, stream) -> { 1501 mAudioSystem.setDeviceAbsoluteVolumeEnabled(dev, /*address=*/"", /*enabled=*/true, 1502 stream); 1503 }); 1504 } 1505 } 1506 1507 private SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionChangedListener = 1508 new SubscriptionManager.OnSubscriptionsChangedListener() { 1509 @Override 1510 public void onSubscriptionsChanged() { 1511 Log.i(TAG, "onSubscriptionsChanged()"); 1512 sendMsg(mAudioHandler, MSG_CONFIGURATION_CHANGED, SENDMSG_REPLACE, 1513 0, 0, null, 0); 1514 } 1515 }; 1516 getMediaSessionManager()1517 private MediaSessionManager getMediaSessionManager() { 1518 if (mMediaSessionManager == null) { 1519 mMediaSessionManager = (MediaSessionManager) mContext 1520 .getSystemService(Context.MEDIA_SESSION_SERVICE); 1521 } 1522 return mMediaSessionManager; 1523 } 1524 1525 /** 1526 * Initialize intent receives and settings observers for this service. 1527 * Must be called after createStreamStates() as the handling of some events 1528 * may affect or need volumes, e.g. BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED 1529 * (for intent receiver), or Settings.Global.ZEN_MODE (for settings observer) 1530 */ initExternalEventReceivers()1531 private void initExternalEventReceivers() { 1532 mSettingsObserver = new SettingsObserver(); 1533 1534 // Register for device connection intent broadcasts. 1535 IntentFilter intentFilter = 1536 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); 1537 if (!mDeviceBroker.isScoManagedByAudio()) { 1538 intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED); 1539 } 1540 intentFilter.addAction(Intent.ACTION_DOCK_EVENT); 1541 if (mDisplayManager == null) { 1542 intentFilter.addAction(Intent.ACTION_SCREEN_ON); 1543 intentFilter.addAction(Intent.ACTION_SCREEN_OFF); 1544 } 1545 intentFilter.addAction(Intent.ACTION_USER_SWITCHED); 1546 intentFilter.addAction(Intent.ACTION_USER_BACKGROUND); 1547 intentFilter.addAction(Intent.ACTION_USER_FOREGROUND); 1548 intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); 1549 intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED); 1550 1551 intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); 1552 if (mMonitorRotation) { 1553 RotationHelper.init(mContext, mAudioHandler, 1554 rotation -> onRotationUpdate(rotation), 1555 foldState -> onFoldStateUpdate(foldState)); 1556 } 1557 1558 intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION); 1559 intentFilter.addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION); 1560 intentFilter.addAction(ACTION_CHECK_MUSIC_ACTIVE); 1561 intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); 1562 1563 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, 1564 mBroadcastHandlerThread.getThreadHandler(), 1565 Context.RECEIVER_EXPORTED); 1566 1567 SubscriptionManager subscriptionManager = mContext.getSystemService( 1568 SubscriptionManager.class); 1569 if (subscriptionManager == null) { 1570 Log.e(TAG, "initExternalEventReceivers cannot create SubscriptionManager!"); 1571 } else { 1572 subscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionChangedListener); 1573 } 1574 1575 if (mDisplayManager != null) { 1576 mDisplayManager.registerDisplayListener(mDisplayListener, mAudioHandler); 1577 } 1578 } 1579 systemReady()1580 public void systemReady() { 1581 sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE, 1582 0, 0, null, 0); 1583 if (false) { 1584 // This is turned off for now, because it is racy and thus causes apps to break. 1585 // Currently banning a uid means that if an app tries to start playing an audio 1586 // stream, that will be preventing, and unbanning it will not allow that stream 1587 // to resume. However these changes in uid state are racy with what the app is doing, 1588 // so that after taking a process out of the cached state we can't guarantee that 1589 // we will unban the uid before the app actually tries to start playing audio. 1590 // (To do that, the activity manager would need to wait until it knows for sure 1591 // that the ban has been removed, before telling the app to do whatever it is 1592 // supposed to do that caused it to go out of the cached state.) 1593 try { 1594 ActivityManager.getService().registerUidObserver(mUidObserver, 1595 ActivityManager.UID_OBSERVER_CACHED | ActivityManager.UID_OBSERVER_GONE, 1596 ActivityManager.PROCESS_STATE_UNKNOWN, null); 1597 } catch (RemoteException e) { 1598 // ignored; both services live in system_server 1599 } 1600 } 1601 } 1602 updateVibratorInfos()1603 private void updateVibratorInfos() { 1604 VibratorManager vibratorManager = mContext.getSystemService(VibratorManager.class); 1605 if (vibratorManager == null) { 1606 Slog.e(TAG, "Vibrator manager is not found"); 1607 return; 1608 } 1609 int[] vibratorIds = vibratorManager.getVibratorIds(); 1610 if (vibratorIds.length == 0) { 1611 Slog.d(TAG, "No vibrator found"); 1612 return; 1613 } 1614 List<Vibrator> vibrators = new ArrayList<>(vibratorIds.length); 1615 for (int id : vibratorIds) { 1616 Vibrator vibrator = vibratorManager.getVibrator(id); 1617 if (vibrator != null) { 1618 vibrators.add(vibrator); 1619 } else { 1620 Slog.w(TAG, "Vibrator(" + id + ") is not found"); 1621 } 1622 } 1623 if (vibrators.isEmpty()) { 1624 Slog.w(TAG, "Cannot find any available vibrator"); 1625 return; 1626 } 1627 AudioSystem.setVibratorInfos(vibrators); 1628 } 1629 onSystemReady()1630 public void onSystemReady() { 1631 mSystemReady = true; 1632 scheduleLoadSoundEffects(); 1633 1634 mDeviceBroker.onSystemReady(); 1635 1636 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) { 1637 synchronized (mHdmiClientLock) { 1638 mHdmiManager = mContext.getSystemService(HdmiControlManager.class); 1639 if (mHdmiManager != null) { 1640 mHdmiManager.addHdmiControlStatusChangeListener( 1641 mHdmiControlStatusChangeListenerCallback); 1642 mHdmiManager.addHdmiCecVolumeControlFeatureListener(mContext.getMainExecutor(), 1643 mMyHdmiCecVolumeControlFeatureListener); 1644 } 1645 mHdmiTvClient = mHdmiManager.getTvClient(); 1646 if (mHdmiTvClient != null) { 1647 mFixedVolumeDevices.removeAll( 1648 AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET); 1649 } 1650 mHdmiPlaybackClient = mHdmiManager.getPlaybackClient(); 1651 mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient(); 1652 } 1653 } 1654 1655 if (mSupportsMicPrivacyToggle) { 1656 mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers( 1657 SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> { 1658 if (userId == getCurrentUserId()) { 1659 mMicMuteFromPrivacyToggle = enabled; 1660 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); 1661 } 1662 }); 1663 } 1664 1665 mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 1666 1667 mSoundDoseHelper.configureSafeMedia(/*forced=*/true, TAG); 1668 1669 initA11yMonitoring(); 1670 1671 mRoleObserver = new RoleObserver(); 1672 mRoleObserver.register(); 1673 1674 onIndicateSystemReady(); 1675 1676 mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted(); 1677 setMicMuteFromSwitchInput(); 1678 1679 initMinStreamVolumeWithoutModifyAudioSettings(); 1680 1681 updateVibratorInfos(); 1682 1683 synchronized (mSupportedSystemUsagesLock) { 1684 AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages); 1685 } 1686 } 1687 1688 //----------------------------------------------------------------- 1689 // routing monitoring from AudioSystemAdapter 1690 @Override onRoutingUpdatedFromNative()1691 public void onRoutingUpdatedFromNative() { 1692 sendMsg(mAudioHandler, 1693 MSG_ROUTING_UPDATED, 1694 SENDMSG_REPLACE, 0, 0, null, 1695 /*delay*/ 0); 1696 } 1697 1698 /** 1699 * called when handling MSG_ROUTING_UPDATED 1700 */ onRoutingUpdatedFromAudioThread()1701 void onRoutingUpdatedFromAudioThread() { 1702 if (mHasSpatializerEffect) { 1703 mSpatializerHelper.onRoutingUpdated(); 1704 } 1705 checkMuteAwaitConnection(); 1706 } 1707 1708 //----------------------------------------------------------------- 1709 // rotation/fold updates coming from RotationHelper onRotationUpdate(Integer rotation)1710 void onRotationUpdate(Integer rotation) { 1711 mSpatializerHelper.setDisplayOrientation((float) (rotation * Math.PI / 180.)); 1712 // use REPLACE as only the last rotation matters 1713 final String rotationParameter = "rotation=" + rotation; 1714 sendMsg(mAudioHandler, MSG_ROTATION_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0, 1715 /*obj*/ rotationParameter, /*delay*/ 0); 1716 } 1717 onFoldStateUpdate(Boolean foldState)1718 void onFoldStateUpdate(Boolean foldState) { 1719 mSpatializerHelper.setFoldState(foldState); 1720 // use REPLACE as only the last fold state matters 1721 final String foldStateParameter = "device_folded=" + (foldState ? "on" : "off"); 1722 sendMsg(mAudioHandler, MSG_FOLD_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0, 1723 /*obj*/ foldStateParameter, /*delay*/ 0); 1724 } 1725 1726 //----------------------------------------------------------------- 1727 // Communicate to PlayackActivityMonitor whether to log or not 1728 // the sound FX activity (useful for removing touch sounds in the activity logs) ignorePlayerLogs(@onNull PlayerBase playerToIgnore)1729 void ignorePlayerLogs(@NonNull PlayerBase playerToIgnore) { 1730 if (DEBUG_LOG_SOUND_FX) { 1731 return; 1732 } 1733 sendMsg(mAudioHandler, MSG_NO_LOG_FOR_PLAYER_I, SENDMSG_REPLACE, 1734 /*arg1, piid of the player*/ playerToIgnore.getPlayerIId(), 1735 /*arg2 ignored*/ 0, /*obj ignored*/ null, /*delay*/ 0); 1736 } 1737 1738 //----------------------------------------------------------------- 1739 // monitoring requests for volume range initialization 1740 @Override // AudioSystemAdapter.OnVolRangeInitRequestListener onVolumeRangeInitRequestFromNative()1741 public void onVolumeRangeInitRequestFromNative() { 1742 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_REPLACE, 0, 0, 1743 "onVolumeRangeInitRequestFromNative" /*obj: caller, for dumpsys*/, /*delay*/ 0); 1744 } 1745 1746 //----------------------------------------------------------------- 1747 RoleObserver mRoleObserver; 1748 1749 class RoleObserver implements OnRoleHoldersChangedListener { 1750 private RoleManager mRm; 1751 private final Executor mExecutor; 1752 RoleObserver()1753 RoleObserver() { 1754 mExecutor = mContext.getMainExecutor(); 1755 } 1756 register()1757 public void register() { 1758 mRm = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE); 1759 if (mRm != null) { 1760 mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL); 1761 synchronized (mSettingsLock) { 1762 updateAssistantUIdLocked(/* forceUpdate= */ true); 1763 } 1764 } 1765 } 1766 1767 @Override onRoleHoldersChanged(@onNull String roleName, @NonNull UserHandle user)1768 public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) { 1769 if (RoleManager.ROLE_ASSISTANT.equals(roleName)) { 1770 synchronized (mSettingsLock) { 1771 updateAssistantUIdLocked(/* forceUpdate= */ false); 1772 } 1773 } 1774 } 1775 getAssistantRoleHolder()1776 public String getAssistantRoleHolder() { 1777 String assitantPackage = ""; 1778 if (mRm != null) { 1779 List<String> assistants = mRm.getRoleHolders(RoleManager.ROLE_ASSISTANT); 1780 assitantPackage = assistants.size() == 0 ? "" : assistants.get(0); 1781 } 1782 return assitantPackage; 1783 } 1784 } 1785 onIndicateSystemReady()1786 void onIndicateSystemReady() { 1787 if (AudioSystem.systemReady() == AudioSystem.SUCCESS) { 1788 return; 1789 } 1790 sendMsg(mAudioHandler, 1791 MSG_INDICATE_SYSTEM_READY, 1792 SENDMSG_REPLACE, 1793 0, 1794 0, 1795 null, 1796 INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 1797 } 1798 onAudioServerDied()1799 public void onAudioServerDied() { 1800 if (!mSystemReady || 1801 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) { 1802 Log.e(TAG, "Audioserver died."); 1803 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 1804 "onAudioServerDied() audioserver died")); 1805 sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0, 1806 null, 500); 1807 return; 1808 } 1809 Log.i(TAG, "Audioserver started."); 1810 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 1811 "onAudioServerDied() audioserver started")); 1812 1813 updateAudioHalPids(); 1814 1815 // indicate to audio HAL that we start the reconfiguration phase after a media 1816 // server crash 1817 // Note that we only execute this when the media server 1818 // process restarts after a crash, not the first time it is started. 1819 AudioSystem.setParameters("restarting=true"); 1820 1821 readAndSetLowRamDevice(); 1822 1823 mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported(); 1824 1825 // Restore device connection states, BT state 1826 mDeviceBroker.onAudioServerDied(); 1827 1828 // Restore call state 1829 synchronized (mDeviceBroker.mSetModeLock) { 1830 onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(), 1831 mContext.getPackageName(), true /*force*/); 1832 } 1833 final int forSys; 1834 synchronized (mSettingsLock) { 1835 forSys = mCameraSoundForced ? 1836 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE; 1837 } 1838 1839 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, forSys, "onAudioServerDied"); 1840 1841 // Restore stream volumes 1842 onReinitVolumes("after audioserver restart"); 1843 1844 // Restore audio volume groups 1845 restoreVolumeGroups(); 1846 1847 // Restore mono mode 1848 updateMasterMono(mContentResolver); 1849 1850 // Restore audio balance 1851 updateMasterBalance(mContentResolver); 1852 1853 // Restore ringer mode 1854 setRingerModeInt(getRingerModeInternal(), false); 1855 1856 // Reset device rotation (if monitored for this device) 1857 if (mMonitorRotation) { 1858 RotationHelper.updateOrientation(); 1859 } 1860 1861 // Restore setParameters and other queued setters. 1862 mRestorableParameters.restoreAll(); 1863 1864 synchronized (mSettingsLock) { 1865 final int forDock = mDockAudioMediaEnabled ? 1866 AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE; 1867 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, forDock, "onAudioServerDied"); 1868 sendEncodedSurroundMode(mContentResolver, "onAudioServerDied"); 1869 sendEnabledSurroundFormats(mContentResolver, true); 1870 AudioSystem.setRttEnabled(mRttEnabled); 1871 resetAssistantServicesUidsLocked(); 1872 } 1873 1874 synchronized (mAccessibilityServiceUidsLock) { 1875 AudioSystem.setA11yServicesUids(mAccessibilityServiceUids); 1876 } 1877 synchronized (mInputMethodServiceUidLock) { 1878 mAudioSystem.setCurrentImeUid(mInputMethodServiceUid); 1879 } 1880 synchronized (mHdmiClientLock) { 1881 if (mHdmiManager != null && mHdmiTvClient != null) { 1882 setHdmiSystemAudioSupported(mHdmiSystemAudioSupported); 1883 } 1884 } 1885 1886 synchronized (mSupportedSystemUsagesLock) { 1887 AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages); 1888 } 1889 1890 synchronized (mAudioPolicies) { 1891 ArrayList<AudioPolicyProxy> invalidProxies = new ArrayList<>(); 1892 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 1893 final int status = policy.connectMixes(); 1894 if (status != AudioSystem.SUCCESS) { 1895 // note that PERMISSION_DENIED may also indicate trouble getting to APService 1896 Log.e(TAG, "onAudioServerDied: error " 1897 + AudioSystem.audioSystemErrorToString(status) 1898 + " when connecting mixes for policy " + policy.toLogFriendlyString()); 1899 invalidProxies.add(policy); 1900 } else { 1901 final int deviceAffinitiesStatus = policy.setupDeviceAffinities(); 1902 if (deviceAffinitiesStatus != AudioSystem.SUCCESS) { 1903 Log.e(TAG, "onAudioServerDied: error " 1904 + AudioSystem.audioSystemErrorToString(deviceAffinitiesStatus) 1905 + " when connecting device affinities for policy " 1906 + policy.toLogFriendlyString()); 1907 invalidProxies.add(policy); 1908 } 1909 } 1910 } 1911 invalidProxies.forEach((policy) -> policy.release()); 1912 1913 } 1914 1915 // Restore capture policies 1916 synchronized (mPlaybackMonitor) { 1917 HashMap<Integer, Integer> allowedCapturePolicies = 1918 mPlaybackMonitor.getAllAllowedCapturePolicies(); 1919 for (HashMap.Entry<Integer, Integer> entry : allowedCapturePolicies.entrySet()) { 1920 int result = mAudioSystem.setAllowedCapturePolicy( 1921 entry.getKey(), 1922 AudioAttributes.capturePolicyToFlags(entry.getValue(), 0x0)); 1923 if (result != AudioSystem.AUDIO_STATUS_OK) { 1924 Log.e(TAG, "Failed to restore capture policy, uid: " 1925 + entry.getKey() + ", capture policy: " + entry.getValue() 1926 + ", result: " + result); 1927 // When restoring capture policy failed, set the capture policy as 1928 // ALLOW_CAPTURE_BY_ALL, which will result in removing the cached 1929 // capture policy in PlaybackActivityMonitor. 1930 mPlaybackMonitor.setAllowedCapturePolicy( 1931 entry.getKey(), AudioAttributes.ALLOW_CAPTURE_BY_ALL); 1932 } 1933 } 1934 } 1935 1936 mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect); 1937 1938 // Restore rotation information. 1939 if (mMonitorRotation) { 1940 RotationHelper.forceUpdate(); 1941 } 1942 1943 onIndicateSystemReady(); 1944 1945 synchronized (mCachedAbsVolDrivingStreamsLock) { 1946 mCachedAbsVolDrivingStreams.forEach((dev, stream) -> { 1947 mAudioSystem.setDeviceAbsoluteVolumeEnabled(dev, /*address=*/"", /*enabled=*/true, 1948 stream); 1949 }); 1950 } 1951 1952 // indicate the end of reconfiguration phase to audio HAL 1953 AudioSystem.setParameters("restarting=false"); 1954 1955 mSoundDoseHelper.reset(/*resetISoundDose=*/true); 1956 1957 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE, 1958 SENDMSG_QUEUE, 1, 0, null, 0); 1959 1960 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); // will also update the mic mute cache 1961 setMicMuteFromSwitchInput(); 1962 1963 // Restore vibrator info 1964 updateVibratorInfos(); 1965 } 1966 onRemoveAssistantServiceUids(int[] uids)1967 private void onRemoveAssistantServiceUids(int[] uids) { 1968 synchronized (mSettingsLock) { 1969 removeAssistantServiceUidsLocked(uids); 1970 } 1971 } 1972 1973 @GuardedBy("mSettingsLock") removeAssistantServiceUidsLocked(int[] uids)1974 private void removeAssistantServiceUidsLocked(int[] uids) { 1975 boolean changed = false; 1976 for (int index = 0; index < uids.length; index++) { 1977 if (!mAssistantUids.remove(uids[index])) { 1978 Slog.e(TAG, TextUtils.formatSimple( 1979 "Cannot remove assistant service, uid(%d) not present", uids[index])); 1980 continue; 1981 } 1982 changed = true; 1983 } 1984 if (changed) { 1985 updateAssistantServicesUidsLocked(); 1986 } 1987 } 1988 onAddAssistantServiceUids(int[] uids)1989 private void onAddAssistantServiceUids(int[] uids) { 1990 synchronized (mSettingsLock) { 1991 addAssistantServiceUidsLocked(uids); 1992 } 1993 } 1994 1995 @GuardedBy("mSettingsLock") addAssistantServiceUidsLocked(int[] uids)1996 private void addAssistantServiceUidsLocked(int[] uids) { 1997 boolean changed = false; 1998 for (int index = 0; index < uids.length; index++) { 1999 if (uids[index] == INVALID_UID) { 2000 continue; 2001 } 2002 if (!mAssistantUids.add(uids[index])) { 2003 Slog.e(TAG, TextUtils.formatSimple( 2004 "Cannot add assistant service, uid(%d) already present", 2005 uids[index])); 2006 continue; 2007 } 2008 changed = true; 2009 } 2010 if (changed) { 2011 updateAssistantServicesUidsLocked(); 2012 } 2013 } 2014 2015 @GuardedBy("mSettingsLock") resetAssistantServicesUidsLocked()2016 private void resetAssistantServicesUidsLocked() { 2017 mAssistantUids.clear(); 2018 updateAssistantUIdLocked(/* forceUpdate= */ true); 2019 } 2020 2021 @GuardedBy("mSettingsLock") updateAssistantServicesUidsLocked()2022 private void updateAssistantServicesUidsLocked() { 2023 int[] assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray(); 2024 AudioSystem.setAssistantServicesUids(assistantUids); 2025 } 2026 updateActiveAssistantServiceUids()2027 private void updateActiveAssistantServiceUids() { 2028 int [] activeAssistantServiceUids; 2029 synchronized (mSettingsLock) { 2030 activeAssistantServiceUids = mActiveAssistantServiceUids; 2031 } 2032 AudioSystem.setActiveAssistantServicesUids(activeAssistantServiceUids); 2033 } 2034 onReinitVolumes(@onNull String caller)2035 private void onReinitVolumes(@NonNull String caller) { 2036 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 2037 // keep track of any error during stream volume initialization 2038 int status = AudioSystem.AUDIO_STATUS_OK; 2039 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 2040 VolumeStreamState streamState = mStreamStates[streamType]; 2041 final int res = AudioSystem.initStreamVolume( 2042 streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10); 2043 if (res != AudioSystem.AUDIO_STATUS_OK) { 2044 status = res; 2045 Log.e(TAG, "Failed to initStreamVolume (" + res + ") for stream " + streamType); 2046 // stream volume initialization failed, no need to try the others, it will be 2047 // attempted again when MSG_REINIT_VOLUMES is handled 2048 break; 2049 } 2050 streamState.applyAllVolumes(); 2051 } 2052 2053 // did it work? check based on status 2054 if (status != AudioSystem.AUDIO_STATUS_OK) { 2055 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 2056 caller + ": initStreamVolume failed with " + status + " will retry") 2057 .printLog(ALOGE, TAG)); 2058 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 2059 caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 2060 return; 2061 } 2062 2063 // did it work? check based on min/max values of some basic streams 2064 if (!checkVolumeRangeInitialization(caller)) { 2065 return; 2066 } 2067 2068 // success 2069 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 2070 caller + ": initStreamVolume succeeded").printLog(ALOGI, TAG)); 2071 } 2072 2073 /** 2074 * Check volume ranges were properly initialized 2075 * @return true if volume ranges were successfully initialized 2076 */ checkVolumeRangeInitialization(String caller)2077 private boolean checkVolumeRangeInitialization(String caller) { 2078 boolean success = true; 2079 final int[] basicStreams = { AudioSystem.STREAM_ALARM, AudioSystem.STREAM_RING, 2080 AudioSystem.STREAM_MUSIC, AudioSystem.STREAM_VOICE_CALL, 2081 AudioSystem.STREAM_ACCESSIBILITY }; 2082 for (int streamType : basicStreams) { 2083 final AudioAttributes aa = new AudioAttributes.Builder() 2084 .setInternalLegacyStreamType(streamType).build(); 2085 if (AudioSystem.getMaxVolumeIndexForAttributes(aa) < 0 2086 || AudioSystem.getMinVolumeIndexForAttributes(aa) < 0) { 2087 success = false; 2088 break; 2089 } 2090 } 2091 if (!success) { 2092 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 2093 caller + ": initStreamVolume succeeded but invalid mix/max levels, will retry") 2094 .printLog(ALOGW, TAG)); 2095 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 2096 caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 2097 } 2098 return success; 2099 } 2100 onDispatchAudioServerStateChange(boolean state)2101 private void onDispatchAudioServerStateChange(boolean state) { 2102 synchronized (mAudioServerStateListeners) { 2103 for (AsdProxy asdp : mAudioServerStateListeners.values()) { 2104 try { 2105 asdp.callback().dispatchAudioServerStateChange(state); 2106 } catch (RemoteException e) { 2107 Log.w(TAG, "Could not call dispatchAudioServerStateChange()", e); 2108 } 2109 } 2110 } 2111 } 2112 createAudioSystemThread()2113 private void createAudioSystemThread() { 2114 mAudioSystemThread = new AudioSystemThread(); 2115 mAudioSystemThread.start(); 2116 waitForAudioHandlerCreation(); 2117 } 2118 2119 /** Waits for the volume handler to be created by the other thread. */ waitForAudioHandlerCreation()2120 private void waitForAudioHandlerCreation() { 2121 synchronized(this) { 2122 while (mAudioHandler == null) { 2123 try { 2124 // Wait for mAudioHandler to be set by the other thread 2125 wait(); 2126 } catch (InterruptedException e) { 2127 Log.e(TAG, "Interrupted while waiting on volume handler."); 2128 } 2129 } 2130 } 2131 } 2132 2133 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 2134 /** 2135 * @see AudioManager#setSupportedSystemUsages(int[]) 2136 */ setSupportedSystemUsages(@onNull @ttributeSystemUsage int[] systemUsages)2137 public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) { 2138 super.setSupportedSystemUsages_enforcePermission(); 2139 2140 verifySystemUsages(systemUsages); 2141 2142 synchronized (mSupportedSystemUsagesLock) { 2143 AudioSystem.setSupportedSystemUsages(systemUsages); 2144 mSupportedSystemUsages = systemUsages; 2145 } 2146 } 2147 2148 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 2149 /** 2150 * @see AudioManager#getSupportedSystemUsages() 2151 */ getSupportedSystemUsages()2152 public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() { 2153 super.getSupportedSystemUsages_enforcePermission(); 2154 2155 synchronized (mSupportedSystemUsagesLock) { 2156 return Arrays.copyOf(mSupportedSystemUsages, mSupportedSystemUsages.length); 2157 } 2158 } 2159 verifySystemUsages(@onNull int[] systemUsages)2160 private void verifySystemUsages(@NonNull int[] systemUsages) { 2161 for (int i = 0; i < systemUsages.length; i++) { 2162 if (!AudioAttributes.isSystemUsage(systemUsages[i])) { 2163 throw new IllegalArgumentException("Non-system usage provided: " + systemUsages[i]); 2164 } 2165 } 2166 } 2167 2168 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 2169 /** 2170 * @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the 2171 * platform configuration file. 2172 */ 2173 @NonNull getAudioProductStrategies()2174 public List<AudioProductStrategy> getAudioProductStrategies() { 2175 // verify permissions 2176 super.getAudioProductStrategies_enforcePermission(); 2177 2178 return AudioProductStrategy.getAudioProductStrategies(); 2179 } 2180 2181 @android.annotation.EnforcePermission(anyOf = { 2182 MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING }) 2183 /** 2184 * @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the 2185 * platform configuration file. 2186 */ 2187 @NonNull getAudioVolumeGroups()2188 public List<AudioVolumeGroup> getAudioVolumeGroups() { 2189 // verify permissions 2190 super.getAudioVolumeGroups_enforcePermission(); 2191 2192 return mAudioVolumeGroupHelper.getAudioVolumeGroups(); 2193 } 2194 checkAllAliasStreamVolumes()2195 private void checkAllAliasStreamVolumes() { 2196 synchronized (mSettingsLock) { 2197 synchronized (VolumeStreamState.class) { 2198 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2199 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 2200 mStreamStates[streamType] 2201 .setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]], TAG); 2202 // apply stream volume 2203 if (!mStreamStates[streamType].mIsMuted) { 2204 mStreamStates[streamType].applyAllVolumes(); 2205 } 2206 } 2207 } 2208 } 2209 } 2210 2211 2212 /** 2213 * Called from AudioDeviceBroker when DEVICE_OUT_HDMI is connected or disconnected. 2214 */ postCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2215 /*package*/ void postCheckVolumeCecOnHdmiConnection( 2216 @AudioService.ConnectionState int state, String caller) { 2217 sendMsg(mAudioHandler, MSG_HDMI_VOLUME_CHECK, SENDMSG_REPLACE, 2218 state /*arg1*/, 0 /*arg2 ignored*/, caller /*obj*/, 0 /*delay*/); 2219 } 2220 onCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2221 private void onCheckVolumeCecOnHdmiConnection( 2222 @AudioService.ConnectionState int state, String caller) { 2223 if (state == AudioService.CONNECTION_STATE_CONNECTED) { 2224 // DEVICE_OUT_HDMI is now connected 2225 if (mSoundDoseHelper.safeDevicesContains(AudioSystem.DEVICE_OUT_HDMI)) { 2226 mSoundDoseHelper.scheduleMusicActiveCheck(); 2227 } 2228 2229 if (isPlatformTelevision()) { 2230 synchronized (mHdmiClientLock) { 2231 if (mHdmiManager != null && mHdmiPlaybackClient != null) { 2232 updateHdmiCecSinkLocked( 2233 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)); 2234 } 2235 } 2236 } 2237 sendEnabledSurroundFormats(mContentResolver, true); 2238 } else { 2239 // DEVICE_OUT_HDMI disconnected 2240 if (isPlatformTelevision()) { 2241 synchronized (mHdmiClientLock) { 2242 if (mHdmiManager != null) { 2243 updateHdmiCecSinkLocked( 2244 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)); 2245 } 2246 } 2247 } 2248 } 2249 } 2250 2251 /** 2252 * Asynchronously update volume states for the given device. 2253 * 2254 * @param device a single audio device, ensure that this is not a devices bitmask 2255 * @param caller caller of this method 2256 */ postUpdateVolumeStatesForAudioDevice(int device, String caller)2257 private void postUpdateVolumeStatesForAudioDevice(int device, String caller) { 2258 sendMsg(mAudioHandler, 2259 MSG_UPDATE_VOLUME_STATES_FOR_DEVICE, 2260 SENDMSG_QUEUE, device /*arg1*/, 0 /*arg2*/, caller /*obj*/, 2261 0 /*delay*/); 2262 } 2263 2264 /** 2265 * Update volume states for the given device. 2266 * 2267 * This will initialize the volume index if no volume index is available. 2268 * If the device is the currently routed device, fixed/full volume policies will be applied. 2269 * 2270 * @param device a single audio device, ensure that this is not a devices bitmask 2271 * @param caller caller of this method 2272 */ onUpdateVolumeStatesForAudioDevice(int device, String caller)2273 private void onUpdateVolumeStatesForAudioDevice(int device, String caller) { 2274 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 2275 synchronized (mSettingsLock) { 2276 synchronized (VolumeStreamState.class) { 2277 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 2278 updateVolumeStates(device, streamType, caller); 2279 } 2280 } 2281 } 2282 } 2283 2284 /** 2285 * Update volume states for the given device and given stream. 2286 * 2287 * This will initialize the volume index if no volume index is available. 2288 * If the device is the currently routed device, fixed/full volume policies will be applied. 2289 * 2290 * @param device a single audio device, ensure that this is not a devices bitmask 2291 * @param streamType streamType to be updated 2292 * @param caller caller of this method 2293 */ updateVolumeStates(int device, int streamType, String caller)2294 private void updateVolumeStates(int device, int streamType, String caller) { 2295 // Handle device volume aliasing of SPEAKER_SAFE. 2296 if (device == AudioSystem.DEVICE_OUT_SPEAKER_SAFE) { 2297 device = AudioSystem.DEVICE_OUT_SPEAKER; 2298 } 2299 if (!mStreamStates[streamType].hasIndexForDevice(device)) { 2300 // set the default value, if device is affected by a full/fix/abs volume rule, it 2301 // will taken into account in checkFixedVolumeDevices() 2302 mStreamStates[streamType].setIndex( 2303 mStreamStates[mStreamVolumeAlias[streamType]] 2304 .getIndex(AudioSystem.DEVICE_OUT_DEFAULT), 2305 device, caller, true /*hasModifyAudioSettings*/); 2306 } 2307 2308 // Check if device to be updated is routed for the given audio stream 2309 // This may include devices such as SPEAKER_SAFE. 2310 List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributesInt( 2311 new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build(), 2312 true /* forVolume */); 2313 for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) { 2314 if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType( 2315 device)) { 2316 mStreamStates[streamType].checkFixedVolumeDevices(); 2317 2318 // Unmute streams if required and device is full volume 2319 if (isStreamMute(streamType) && mFullVolumeDevices.contains(device)) { 2320 mStreamStates[streamType].mute(false, "updateVolumeStates(" + caller); 2321 } 2322 } 2323 } 2324 } 2325 checkAllFixedVolumeDevices()2326 private void checkAllFixedVolumeDevices() 2327 { 2328 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2329 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 2330 mStreamStates[streamType].checkFixedVolumeDevices(); 2331 } 2332 } 2333 checkAllFixedVolumeDevices(int streamType)2334 private void checkAllFixedVolumeDevices(int streamType) { 2335 mStreamStates[streamType].checkFixedVolumeDevices(); 2336 } 2337 checkMuteAffectedStreams()2338 private void checkMuteAffectedStreams() { 2339 // any stream with a min level > 0 is not muteable by definition 2340 // STREAM_VOICE_CALL and STREAM_BLUETOOTH_SCO can be muted by applications 2341 // that has the the MODIFY_PHONE_STATE permission. 2342 for (int i = 0; i < mStreamStates.length; i++) { 2343 final VolumeStreamState vss = mStreamStates[i]; 2344 if (vss.mIndexMin > 0 && 2345 (vss.mStreamType != AudioSystem.STREAM_VOICE_CALL && 2346 vss.mStreamType != AudioSystem.STREAM_BLUETOOTH_SCO)) { 2347 mMuteAffectedStreams &= ~(1 << vss.mStreamType); 2348 } 2349 } 2350 updateUserMutableStreams(); 2351 } 2352 createStreamStates()2353 private void createStreamStates() { 2354 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2355 VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes]; 2356 2357 for (int i = 0; i < numStreamTypes; i++) { 2358 streams[i] = 2359 new VolumeStreamState(System.VOLUME_SETTINGS_INT[mStreamVolumeAlias[i]], i); 2360 } 2361 2362 checkAllFixedVolumeDevices(); 2363 checkAllAliasStreamVolumes(); 2364 checkMuteAffectedStreams(); 2365 updateDefaultVolumes(); 2366 } 2367 2368 /** 2369 * Update default indexes from aliased streams. Must be called after mStreamStates is created 2370 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for default 2371 * index. Need to make default index configurable and independent of streams. 2372 * Fallback on music stream for default initialization to take benefit of property based default 2373 * initialization. 2374 * For other volume groups not linked to any streams, default music stream index is considered. 2375 */ updateDefaultVolumes()2376 private void updateDefaultVolumes() { 2377 for (int stream = 0; stream < mStreamStates.length; stream++) { 2378 int streamVolumeAlias = mStreamVolumeAlias[stream]; 2379 if (mUseVolumeGroupAliases) { 2380 if (AudioSystem.DEFAULT_STREAM_VOLUME[stream] != UNSET_INDEX) { 2381 // Already initialized through default property based mecanism. 2382 continue; 2383 } 2384 streamVolumeAlias = AudioSystem.STREAM_MUSIC; 2385 int defaultAliasVolume = getUiDefaultRescaledIndex(streamVolumeAlias, stream); 2386 if ((defaultAliasVolume >= MIN_STREAM_VOLUME[stream]) 2387 && (defaultAliasVolume <= MAX_STREAM_VOLUME[stream])) { 2388 AudioSystem.DEFAULT_STREAM_VOLUME[stream] = defaultAliasVolume; 2389 continue; 2390 } 2391 } 2392 if (stream != streamVolumeAlias) { 2393 AudioSystem.DEFAULT_STREAM_VOLUME[stream] = 2394 getUiDefaultRescaledIndex(streamVolumeAlias, stream); 2395 } 2396 } 2397 } 2398 getUiDefaultRescaledIndex(int srcStream, int dstStream)2399 private int getUiDefaultRescaledIndex(int srcStream, int dstStream) { 2400 return (rescaleIndex(AudioSystem.DEFAULT_STREAM_VOLUME[srcStream] * 10, 2401 srcStream, dstStream) + 5) / 10; 2402 } 2403 dumpStreamStates(PrintWriter pw)2404 private void dumpStreamStates(PrintWriter pw) { 2405 pw.println("\nStream volumes (device: index)"); 2406 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2407 for (int i = 0; i < numStreamTypes; i++) { 2408 StringBuilder alias = new StringBuilder(); 2409 if (mStreamVolumeAlias[i] != i) { 2410 alias.append(" (aliased to: ") 2411 .append(AudioSystem.STREAM_NAMES[mStreamVolumeAlias[i]]) 2412 .append(")"); 2413 } 2414 pw.println("- " + AudioSystem.STREAM_NAMES[i] + alias + ":"); 2415 mStreamStates[i].dump(pw); 2416 pw.println(""); 2417 } 2418 pw.print("\n- mute affected streams = 0x"); 2419 pw.println(Integer.toHexString(mMuteAffectedStreams)); 2420 pw.print("\n- user mutable streams = 0x"); 2421 pw.println(Integer.toHexString(mUserMutableStreams)); 2422 } 2423 updateStreamVolumeAlias(boolean updateVolumes, String caller)2424 private void updateStreamVolumeAlias(boolean updateVolumes, String caller) { 2425 int dtmfStreamAlias; 2426 final int a11yStreamAlias = sIndependentA11yVolume ? 2427 AudioSystem.STREAM_ACCESSIBILITY : AudioSystem.STREAM_MUSIC; 2428 final int assistantStreamAlias = mContext.getResources().getBoolean( 2429 com.android.internal.R.bool.config_useAssistantVolume) ? 2430 AudioSystem.STREAM_ASSISTANT : AudioSystem.STREAM_MUSIC; 2431 2432 if (mIsSingleVolume) { 2433 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION.clone(); 2434 dtmfStreamAlias = AudioSystem.STREAM_MUSIC; 2435 } else if (mUseVolumeGroupAliases) { 2436 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_NONE.clone(); 2437 dtmfStreamAlias = AudioSystem.STREAM_DTMF; 2438 } else { 2439 switch (mPlatformType) { 2440 case AudioSystem.PLATFORM_VOICE: 2441 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_VOICE.clone(); 2442 dtmfStreamAlias = AudioSystem.STREAM_RING; 2443 break; 2444 default: 2445 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_DEFAULT.clone(); 2446 dtmfStreamAlias = AudioSystem.STREAM_MUSIC; 2447 } 2448 if (!mNotifAliasRing) { 2449 mStreamVolumeAlias[AudioSystem.STREAM_NOTIFICATION] = 2450 AudioSystem.STREAM_NOTIFICATION; 2451 } 2452 } 2453 2454 if (mIsSingleVolume) { 2455 mRingerModeAffectedStreams = 0; 2456 } else { 2457 if (isInCommunication()) { 2458 dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL; 2459 mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF); 2460 } else { 2461 mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF); 2462 } 2463 } 2464 2465 mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias; 2466 mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias; 2467 mStreamVolumeAlias[AudioSystem.STREAM_ASSISTANT] = assistantStreamAlias; 2468 2469 if (updateVolumes && mStreamStates != null) { 2470 updateDefaultVolumes(); 2471 2472 synchronized (mSettingsLock) { 2473 synchronized (VolumeStreamState.class) { 2474 mStreamStates[AudioSystem.STREAM_DTMF] 2475 .setAllIndexes(mStreamStates[dtmfStreamAlias], caller); 2476 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setSettingName( 2477 System.VOLUME_SETTINGS_INT[a11yStreamAlias]); 2478 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setAllIndexes( 2479 mStreamStates[a11yStreamAlias], caller); 2480 } 2481 } 2482 if (sIndependentA11yVolume) { 2483 // restore the a11y values from the settings 2484 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].readSettings(); 2485 } 2486 2487 // apply stream mute states according to new value of mRingerModeAffectedStreams 2488 setRingerModeInt(getRingerModeInternal(), false); 2489 sendMsg(mAudioHandler, 2490 MSG_SET_ALL_VOLUMES, 2491 SENDMSG_QUEUE, 2492 0, 2493 0, 2494 mStreamStates[AudioSystem.STREAM_DTMF], 0); 2495 sendMsg(mAudioHandler, 2496 MSG_SET_ALL_VOLUMES, 2497 SENDMSG_QUEUE, 2498 0, 2499 0, 2500 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY], 0); 2501 } 2502 dispatchStreamAliasingUpdate(); 2503 } 2504 readDockAudioSettings(ContentResolver cr)2505 private void readDockAudioSettings(ContentResolver cr) 2506 { 2507 mDockAudioMediaEnabled = mSettings.getGlobalInt( 2508 cr, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED, 0) == 1; 2509 2510 sendMsg(mAudioHandler, 2511 MSG_SET_FORCE_USE, 2512 SENDMSG_QUEUE, 2513 AudioSystem.FOR_DOCK, 2514 mDockAudioMediaEnabled ? 2515 AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE, 2516 new String("readDockAudioSettings"), 2517 0); 2518 2519 } 2520 2521 updateMasterMono(ContentResolver cr)2522 private void updateMasterMono(ContentResolver cr) 2523 { 2524 final boolean masterMono = mSettings.getSystemIntForUser( 2525 cr, System.MASTER_MONO, 0 /* default */, UserHandle.USER_CURRENT) == 1; 2526 if (DEBUG_VOL) { 2527 Log.d(TAG, String.format("Master mono %b", masterMono)); 2528 } 2529 AudioSystem.setMasterMono(masterMono); 2530 } 2531 updateMasterBalance(ContentResolver cr)2532 private void updateMasterBalance(ContentResolver cr) { 2533 final float masterBalance = System.getFloatForUser( 2534 cr, System.MASTER_BALANCE, 0.f /* default */, UserHandle.USER_CURRENT); 2535 if (DEBUG_VOL) { 2536 Log.d(TAG, String.format("Master balance %f", masterBalance)); 2537 } 2538 if (AudioSystem.setMasterBalance(masterBalance) != 0) { 2539 Log.e(TAG, String.format("setMasterBalance failed for %f", masterBalance)); 2540 } 2541 } 2542 sendEncodedSurroundMode(ContentResolver cr, String eventSource)2543 private void sendEncodedSurroundMode(ContentResolver cr, String eventSource) 2544 { 2545 final int encodedSurroundMode = mSettings.getGlobalInt( 2546 cr, Settings.Global.ENCODED_SURROUND_OUTPUT, 2547 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 2548 sendEncodedSurroundMode(encodedSurroundMode, eventSource); 2549 } 2550 sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)2551 private void sendEncodedSurroundMode(int encodedSurroundMode, String eventSource) 2552 { 2553 // initialize to guaranteed bad value 2554 int forceSetting = AudioSystem.NUM_FORCE_CONFIG; 2555 switch (encodedSurroundMode) { 2556 case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO: 2557 forceSetting = AudioSystem.FORCE_NONE; 2558 break; 2559 case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER: 2560 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_NEVER; 2561 break; 2562 case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS: 2563 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_ALWAYS; 2564 break; 2565 case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL: 2566 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_MANUAL; 2567 break; 2568 default: 2569 Log.e(TAG, "updateSurroundSoundSettings: illegal value " 2570 + encodedSurroundMode); 2571 break; 2572 } 2573 if (forceSetting != AudioSystem.NUM_FORCE_CONFIG) { 2574 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_ENCODED_SURROUND, forceSetting, 2575 eventSource); 2576 } 2577 } 2578 2579 @Override // Binder call onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)2580 public void onShellCommand(FileDescriptor in, FileDescriptor out, 2581 FileDescriptor err, String[] args, ShellCallback callback, 2582 ResultReceiver resultReceiver) { 2583 if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_AUDIO_POLICY) 2584 != PackageManager.PERMISSION_GRANTED) { 2585 throw new SecurityException("Missing MANAGE_AUDIO_POLICY permission"); 2586 } 2587 new AudioManagerShellCommand(AudioService.this).exec(this, in, out, err, 2588 args, callback, resultReceiver); 2589 } 2590 2591 /** @see AudioManager#getSurroundFormats() */ 2592 @Override getSurroundFormats()2593 public Map<Integer, Boolean> getSurroundFormats() { 2594 Map<Integer, Boolean> surroundFormats = new HashMap<>(); 2595 int status = AudioSystem.getSurroundFormats(surroundFormats); 2596 if (status != AudioManager.SUCCESS) { 2597 // fail and bail! 2598 Log.e(TAG, "getSurroundFormats failed:" + status); 2599 return new HashMap<>(); // Always return a map. 2600 } 2601 return surroundFormats; 2602 } 2603 2604 /** @see AudioManager#getReportedSurroundFormats() */ 2605 @Override getReportedSurroundFormats()2606 public List<Integer> getReportedSurroundFormats() { 2607 ArrayList<Integer> reportedSurroundFormats = new ArrayList<>(); 2608 int status = AudioSystem.getReportedSurroundFormats(reportedSurroundFormats); 2609 if (status != AudioManager.SUCCESS) { 2610 // fail and bail! 2611 Log.e(TAG, "getReportedSurroundFormats failed:" + status); 2612 return new ArrayList<>(); // Always return a list. 2613 } 2614 return reportedSurroundFormats; 2615 } 2616 2617 /** @see AudioManager#isSurroundFormatEnabled(int) */ 2618 @Override isSurroundFormatEnabled(int audioFormat)2619 public boolean isSurroundFormatEnabled(int audioFormat) { 2620 if (!isSurroundFormat(audioFormat)) { 2621 Log.w(TAG, "audioFormat to enable is not a surround format."); 2622 return false; 2623 } 2624 2625 final long token = Binder.clearCallingIdentity(); 2626 try { 2627 synchronized (mSettingsLock) { 2628 HashSet<Integer> enabledFormats = getEnabledFormats(); 2629 return enabledFormats.contains(audioFormat); 2630 } 2631 } finally { 2632 Binder.restoreCallingIdentity(token); 2633 } 2634 } 2635 2636 /** @see AudioManager#setSurroundFormatEnabled(int, boolean) */ 2637 @Override setSurroundFormatEnabled(int audioFormat, boolean enabled)2638 public boolean setSurroundFormatEnabled(int audioFormat, boolean enabled) { 2639 if (!isSurroundFormat(audioFormat)) { 2640 Log.w(TAG, "audioFormat to enable is not a surround format."); 2641 return false; 2642 } 2643 if (mContext.checkCallingOrSelfPermission(WRITE_SETTINGS) 2644 != PackageManager.PERMISSION_GRANTED) { 2645 throw new SecurityException("Missing WRITE_SETTINGS permission"); 2646 } 2647 2648 HashSet<Integer> enabledFormats = getEnabledFormats(); 2649 if (enabled) { 2650 enabledFormats.add(audioFormat); 2651 } else { 2652 enabledFormats.remove(audioFormat); 2653 } 2654 final long token = Binder.clearCallingIdentity(); 2655 try { 2656 synchronized (mSettingsLock) { 2657 mSettings.putGlobalString(mContentResolver, 2658 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS, 2659 TextUtils.join(",", enabledFormats)); 2660 } 2661 } finally { 2662 Binder.restoreCallingIdentity(token); 2663 } 2664 return true; 2665 } 2666 2667 @android.annotation.EnforcePermission(WRITE_SETTINGS) 2668 /** @see AudioManager#setEncodedSurroundMode(int) */ 2669 @Override setEncodedSurroundMode(@udioManager.EncodedSurroundOutputMode int mode)2670 public boolean setEncodedSurroundMode(@AudioManager.EncodedSurroundOutputMode int mode) { 2671 setEncodedSurroundMode_enforcePermission(); 2672 2673 final long token = Binder.clearCallingIdentity(); 2674 try { 2675 synchronized (mSettingsLock) { 2676 mSettings.putGlobalInt(mContentResolver, 2677 Settings.Global.ENCODED_SURROUND_OUTPUT, 2678 toEncodedSurroundSetting(mode)); 2679 } 2680 } finally { 2681 Binder.restoreCallingIdentity(token); 2682 } 2683 return true; 2684 } 2685 2686 /** @see AudioManager#getEncodedSurroundMode() */ 2687 @Override getEncodedSurroundMode(int targetSdkVersion)2688 public int getEncodedSurroundMode(int targetSdkVersion) { 2689 final long token = Binder.clearCallingIdentity(); 2690 try { 2691 synchronized (mSettingsLock) { 2692 int encodedSurroundSetting = mSettings.getGlobalInt(mContentResolver, 2693 Settings.Global.ENCODED_SURROUND_OUTPUT, 2694 AudioManager.ENCODED_SURROUND_OUTPUT_AUTO); 2695 return toEncodedSurroundOutputMode(encodedSurroundSetting, targetSdkVersion); 2696 } 2697 } finally { 2698 Binder.restoreCallingIdentity(token); 2699 } 2700 } 2701 2702 /** @return the formats that are enabled in global settings */ getEnabledFormats()2703 private HashSet<Integer> getEnabledFormats() { 2704 HashSet<Integer> formats = new HashSet<>(); 2705 String enabledFormats = mSettings.getGlobalString(mContentResolver, 2706 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 2707 if (enabledFormats != null) { 2708 try { 2709 Arrays.stream(TextUtils.split(enabledFormats, ",")) 2710 .mapToInt(Integer::parseInt) 2711 .forEach(formats::add); 2712 } catch (NumberFormatException e) { 2713 Log.w(TAG, "ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS misformatted.", e); 2714 } 2715 } 2716 return formats; 2717 } 2718 2719 @SuppressWarnings("AndroidFrameworkCompatChange") 2720 @AudioManager.EncodedSurroundOutputMode toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion)2721 private int toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion) { 2722 if (targetSdkVersion <= Build.VERSION_CODES.S 2723 && encodedSurroundSetting > Settings.Global.ENCODED_SURROUND_SC_MAX) { 2724 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN; 2725 } 2726 switch (encodedSurroundSetting) { 2727 case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO: 2728 return AudioManager.ENCODED_SURROUND_OUTPUT_AUTO; 2729 case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER: 2730 return AudioManager.ENCODED_SURROUND_OUTPUT_NEVER; 2731 case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS: 2732 return AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS; 2733 case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL: 2734 return AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL; 2735 default: 2736 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN; 2737 } 2738 } 2739 toEncodedSurroundSetting( @udioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode)2740 private int toEncodedSurroundSetting( 2741 @AudioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode) { 2742 switch (encodedSurroundOutputMode) { 2743 case AudioManager.ENCODED_SURROUND_OUTPUT_NEVER: 2744 return Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER; 2745 case AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS: 2746 return Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS; 2747 case AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL: 2748 return Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL; 2749 default: 2750 return Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO; 2751 } 2752 } 2753 isSurroundFormat(int audioFormat)2754 private boolean isSurroundFormat(int audioFormat) { 2755 for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) { 2756 if (sf == audioFormat) { 2757 return true; 2758 } 2759 } 2760 return false; 2761 } 2762 sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate)2763 private void sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate) { 2764 if (mEncodedSurroundMode != Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL) { 2765 // Manually enable surround formats only when the setting is in manual mode. 2766 return; 2767 } 2768 String enabledSurroundFormats = mSettings.getGlobalString( 2769 cr, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 2770 if (enabledSurroundFormats == null) { 2771 // Never allow enabledSurroundFormats as a null, which could happen when 2772 // ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS is not appear in settings DB. 2773 enabledSurroundFormats = ""; 2774 } 2775 if (!forceUpdate && TextUtils.equals(enabledSurroundFormats, mEnabledSurroundFormats)) { 2776 // Update enabled surround formats to AudioPolicyManager only when forceUpdate 2777 // is true or enabled surround formats changed. 2778 return; 2779 } 2780 2781 mEnabledSurroundFormats = enabledSurroundFormats; 2782 String[] surroundFormats = TextUtils.split(enabledSurroundFormats, ","); 2783 ArrayList<Integer> formats = new ArrayList<>(); 2784 for (String format : surroundFormats) { 2785 try { 2786 int audioFormat = Integer.valueOf(format); 2787 if (isSurroundFormat(audioFormat) && !formats.contains(audioFormat)) { 2788 formats.add(audioFormat); 2789 } 2790 } catch (Exception e) { 2791 Log.e(TAG, "Invalid enabled surround format:" + format); 2792 } 2793 } 2794 // Set filtered surround formats to settings DB in case 2795 // there are invalid surround formats in original settings. 2796 mSettings.putGlobalString(mContext.getContentResolver(), 2797 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS, 2798 TextUtils.join(",", formats)); 2799 sendMsg(mAudioHandler, MSG_ENABLE_SURROUND_FORMATS, SENDMSG_QUEUE, 0, 0, formats, 0); 2800 } 2801 onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats)2802 private void onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats) { 2803 // Set surround format enabled accordingly. 2804 for (int surroundFormat : AudioFormat.SURROUND_SOUND_ENCODING) { 2805 boolean enabled = enabledSurroundFormats.contains(surroundFormat); 2806 int ret = AudioSystem.setSurroundFormatEnabled(surroundFormat, enabled); 2807 Log.i(TAG, "enable surround format:" + surroundFormat + " " + enabled + " " + ret); 2808 } 2809 } 2810 2811 @GuardedBy("mSettingsLock") updateAssistantUIdLocked(boolean forceUpdate)2812 private void updateAssistantUIdLocked(boolean forceUpdate) { 2813 int assistantUid = INVALID_UID; 2814 // Consider assistants in the following order of priority: 2815 // 1) apk in assistant role 2816 // 2) voice interaction service 2817 // 3) assistant service 2818 2819 String packageName = ""; 2820 if (mRoleObserver != null) { 2821 packageName = mRoleObserver.getAssistantRoleHolder(); 2822 } 2823 if (TextUtils.isEmpty(packageName)) { 2824 String assistantName = mSettings.getSecureStringForUser( 2825 mContentResolver, 2826 Settings.Secure.VOICE_INTERACTION_SERVICE, UserHandle.USER_CURRENT); 2827 if (TextUtils.isEmpty(assistantName)) { 2828 assistantName = mSettings.getSecureStringForUser( 2829 mContentResolver, 2830 Settings.Secure.ASSISTANT, UserHandle.USER_CURRENT); 2831 } 2832 if (!TextUtils.isEmpty(assistantName)) { 2833 ComponentName componentName = ComponentName.unflattenFromString(assistantName); 2834 if (componentName == null) { 2835 Slog.w(TAG, "Invalid service name for " 2836 + Settings.Secure.VOICE_INTERACTION_SERVICE + ": " + assistantName); 2837 return; 2838 } 2839 packageName = componentName.getPackageName(); 2840 } 2841 } 2842 if (!TextUtils.isEmpty(packageName)) { 2843 PackageManager pm = mContext.getPackageManager(); 2844 2845 if (pm.checkPermission(CAPTURE_AUDIO_HOTWORD, packageName) 2846 == PackageManager.PERMISSION_GRANTED) { 2847 try { 2848 assistantUid = pm.getPackageUidAsUser(packageName, getCurrentUserId()); 2849 } catch (PackageManager.NameNotFoundException e) { 2850 Log.e(TAG, 2851 "updateAssistantUId() could not find UID for package: " + packageName); 2852 } 2853 } 2854 } 2855 if ((mPrimaryAssistantUid != assistantUid) || forceUpdate) { 2856 mAssistantUids.remove(mPrimaryAssistantUid); 2857 mPrimaryAssistantUid = assistantUid; 2858 addAssistantServiceUidsLocked(new int[]{mPrimaryAssistantUid}); 2859 } 2860 } 2861 readPersistedSettings()2862 private void readPersistedSettings() { 2863 if (!mSystemServer.isPrivileged()) { 2864 return; 2865 } 2866 final ContentResolver cr = mContentResolver; 2867 2868 int ringerModeFromSettings = 2869 mSettings.getGlobalInt( 2870 cr, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL); 2871 int ringerMode = ringerModeFromSettings; 2872 // validity check in case the settings are restored from a device with incompatible 2873 // ringer modes 2874 if (!isValidRingerMode(ringerMode)) { 2875 ringerMode = AudioManager.RINGER_MODE_NORMAL; 2876 } 2877 if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { 2878 ringerMode = AudioManager.RINGER_MODE_SILENT; 2879 } 2880 if (ringerMode != ringerModeFromSettings) { 2881 mSettings.putGlobalInt(cr, Settings.Global.MODE_RINGER, ringerMode); 2882 } 2883 if (mUseFixedVolume || mIsSingleVolume) { 2884 ringerMode = AudioManager.RINGER_MODE_NORMAL; 2885 } 2886 synchronized(mSettingsLock) { 2887 mRingerMode = ringerMode; 2888 if (mRingerModeExternal == -1) { 2889 mRingerModeExternal = mRingerMode; 2890 } 2891 2892 // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting 2893 // are still needed while setVibrateSetting() and getVibrateSetting() are being 2894 // deprecated. 2895 mVibrateSetting = AudioSystem.getValueForVibrateSetting(0, 2896 AudioManager.VIBRATE_TYPE_NOTIFICATION, 2897 mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT 2898 : AudioManager.VIBRATE_SETTING_OFF); 2899 mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, 2900 AudioManager.VIBRATE_TYPE_RINGER, 2901 mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT 2902 : AudioManager.VIBRATE_SETTING_OFF); 2903 2904 updateRingerAndZenModeAffectedStreams(); 2905 readDockAudioSettings(cr); 2906 sendEncodedSurroundMode(cr, "readPersistedSettings"); 2907 sendEnabledSurroundFormats(cr, true); 2908 updateAssistantUIdLocked(/* forceUpdate= */ true); 2909 resetActiveAssistantUidsLocked(); 2910 AudioSystem.setRttEnabled(mRttEnabled); 2911 } 2912 2913 mMuteAffectedStreams = mSettings.getSystemIntForUser(cr, 2914 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED, 2915 UserHandle.USER_CURRENT); 2916 updateUserMutableStreams(); 2917 2918 updateMasterMono(cr); 2919 2920 updateMasterBalance(cr); 2921 2922 // Each stream will read its own persisted settings 2923 2924 // Broadcast the sticky intents 2925 broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal); 2926 broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode); 2927 2928 // Broadcast vibrate settings 2929 broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER); 2930 broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION); 2931 2932 // Load settings for the volume controller 2933 mVolumeController.loadSettings(cr); 2934 } 2935 updateUserMutableStreams()2936 private void updateUserMutableStreams() { 2937 mUserMutableStreams = mMuteAffectedStreams; 2938 mUserMutableStreams &= ~(1 << AudioSystem.STREAM_VOICE_CALL); 2939 mUserMutableStreams &= ~(1 << AudioSystem.STREAM_BLUETOOTH_SCO); 2940 } 2941 2942 @GuardedBy("mSettingsLock") resetActiveAssistantUidsLocked()2943 private void resetActiveAssistantUidsLocked() { 2944 mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS; 2945 updateActiveAssistantServiceUids(); 2946 } 2947 readUserRestrictions()2948 private void readUserRestrictions() { 2949 if (!mSystemServer.isPrivileged()) { 2950 return; 2951 } 2952 final int currentUser = getCurrentUserId(); 2953 2954 if (mUseFixedVolume) { 2955 AudioSystem.setMasterVolume(1.0f); 2956 } 2957 2958 // Check the current user restriction. 2959 boolean masterMute = 2960 mUserManagerInternal.getUserRestriction(currentUser, 2961 UserManager.DISALLOW_UNMUTE_DEVICE) 2962 || mUserManagerInternal.getUserRestriction(currentUser, 2963 UserManager.DISALLOW_ADJUST_VOLUME); 2964 setMasterMuteInternalNoCallerCheck( 2965 masterMute, /* flags =*/ 0, currentUser, "readUserRestrictions"); 2966 2967 mMicMuteFromRestrictions = mUserManagerInternal.getUserRestriction( 2968 currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE); 2969 if (DEBUG_VOL) { 2970 Log.d(TAG, String.format("Mic mute %b, user=%d", mMicMuteFromRestrictions, 2971 currentUser)); 2972 } 2973 setMicrophoneMuteNoCallerCheck(currentUser); 2974 } 2975 getIndexRange(int streamType)2976 private int getIndexRange(int streamType) { 2977 return (mStreamStates[streamType].getMaxIndex() - mStreamStates[streamType].getMinIndex()); 2978 } 2979 rescaleIndex(VolumeInfo volumeInfo, int dstStream)2980 private int rescaleIndex(VolumeInfo volumeInfo, int dstStream) { 2981 if (volumeInfo.getVolumeIndex() == VolumeInfo.INDEX_NOT_SET 2982 || volumeInfo.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET 2983 || volumeInfo.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) { 2984 Log.e(TAG, "rescaleIndex: volumeInfo has invalid index or range"); 2985 return mStreamStates[dstStream].getMinIndex(); 2986 } 2987 return rescaleIndex(volumeInfo.getVolumeIndex(), 2988 volumeInfo.getMinVolumeIndex(), volumeInfo.getMaxVolumeIndex(), 2989 mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex()); 2990 } 2991 rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo)2992 private int rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo) { 2993 int dstMin = dstVolumeInfo.getMinVolumeIndex(); 2994 int dstMax = dstVolumeInfo.getMaxVolumeIndex(); 2995 // Don't rescale index if the VolumeInfo is missing a min or max index 2996 if (dstMin == VolumeInfo.INDEX_NOT_SET || dstMax == VolumeInfo.INDEX_NOT_SET) { 2997 return index; 2998 } 2999 return rescaleIndex(index, 3000 mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(), 3001 dstMin, dstMax); 3002 } 3003 rescaleIndex(int index, int srcStream, int dstStream)3004 private int rescaleIndex(int index, int srcStream, int dstStream) { 3005 return rescaleIndex(index, 3006 mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(), 3007 mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex()); 3008 } 3009 rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax)3010 private int rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax) { 3011 int srcRange = srcMax - srcMin; 3012 int dstRange = dstMax - dstMin; 3013 if (srcRange == 0) { 3014 Log.e(TAG, "rescaleIndex : index range should not be zero"); 3015 return dstMin; 3016 } 3017 return dstMin + ((index - srcMin) * dstRange + srcRange / 2) / srcRange; 3018 } 3019 rescaleStep(int step, int srcStream, int dstStream)3020 private int rescaleStep(int step, int srcStream, int dstStream) { 3021 int srcRange = getIndexRange(srcStream); 3022 int dstRange = getIndexRange(dstStream); 3023 if (srcRange == 0) { 3024 Log.e(TAG, "rescaleStep : index range should not be zero"); 3025 return 0; 3026 } 3027 3028 return ((step * dstRange + srcRange / 2) / srcRange); 3029 } 3030 3031 /////////////////////////////////////////////////////////////////////////// 3032 // IPC methods 3033 /////////////////////////////////////////////////////////////////////////// 3034 /** 3035 * @see AudioManager#setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes) 3036 * @see AudioManager#setPreferredDevicesForStrategy(AudioProductStrategy, 3037 * List<AudioDeviceAttributes>) 3038 */ 3039 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices)3040 public int setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices) { 3041 super.setPreferredDevicesForStrategy_enforcePermission(); 3042 if (devices == null) { 3043 return AudioSystem.ERROR; 3044 } 3045 3046 devices = retrieveBluetoothAddresses(devices); 3047 3048 final String logString = String.format( 3049 "setPreferredDevicesForStrategy u/pid:%d/%d strat:%d dev:%s", 3050 Binder.getCallingUid(), Binder.getCallingPid(), strategy, 3051 devices.stream().map(e -> e.toString()).collect(Collectors.joining(","))); 3052 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 3053 if (devices.stream().anyMatch(device -> 3054 device.getRole() == AudioDeviceAttributes.ROLE_INPUT)) { 3055 Log.e(TAG, "Unsupported input routing in " + logString); 3056 return AudioSystem.ERROR; 3057 } 3058 3059 final int status = mDeviceBroker.setPreferredDevicesForStrategySync(strategy, devices); 3060 if (status != AudioSystem.SUCCESS) { 3061 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 3062 } 3063 3064 return status; 3065 } 3066 3067 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 3068 /** @see AudioManager#removePreferredDeviceForStrategy(AudioProductStrategy) */ removePreferredDevicesForStrategy(int strategy)3069 public int removePreferredDevicesForStrategy(int strategy) { 3070 super.removePreferredDevicesForStrategy_enforcePermission(); 3071 3072 final String logString = 3073 String.format("removePreferredDevicesForStrategy strat:%d", strategy); 3074 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 3075 3076 final int status = mDeviceBroker.removePreferredDevicesForStrategySync(strategy); 3077 if (status != AudioSystem.SUCCESS && status != AudioSystem.BAD_VALUE) { 3078 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 3079 } 3080 return status; 3081 } 3082 3083 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 3084 /** 3085 * @see AudioManager#getPreferredDeviceForStrategy(AudioProductStrategy) 3086 * @see AudioManager#getPreferredDevicesForStrategy(AudioProductStrategy) 3087 */ getPreferredDevicesForStrategy(int strategy)3088 public List<AudioDeviceAttributes> getPreferredDevicesForStrategy(int strategy) { 3089 super.getPreferredDevicesForStrategy_enforcePermission(); 3090 3091 List<AudioDeviceAttributes> devices = new ArrayList<>(); 3092 int status = AudioSystem.SUCCESS; 3093 final long identity = Binder.clearCallingIdentity(); 3094 try { 3095 status = AudioSystem.getDevicesForRoleAndStrategy( 3096 strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices); 3097 } finally { 3098 Binder.restoreCallingIdentity(identity); 3099 } 3100 if (status != AudioSystem.SUCCESS) { 3101 Log.e(TAG, String.format("Error %d in getPreferredDeviceForStrategy(%d)", 3102 status, strategy)); 3103 return new ArrayList<AudioDeviceAttributes>(); 3104 } else { 3105 return anonymizeAudioDeviceAttributesList(devices); 3106 } 3107 } 3108 3109 /** 3110 * @see AudioManager#setDeviceAsNonDefaultForStrategy(AudioProductStrategy, 3111 * AudioDeviceAttributes) 3112 * @see AudioManager#setDeviceAsNonDefaultForStrategy(AudioProductStrategy, 3113 * List<AudioDeviceAttributes>) 3114 */ 3115 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) setDeviceAsNonDefaultForStrategy(int strategy, @NonNull AudioDeviceAttributes device)3116 public int setDeviceAsNonDefaultForStrategy(int strategy, 3117 @NonNull AudioDeviceAttributes device) { 3118 super.setDeviceAsNonDefaultForStrategy_enforcePermission(); 3119 Objects.requireNonNull(device); 3120 3121 device = retrieveBluetoothAddress(device); 3122 3123 final String logString = String.format( 3124 "setDeviceAsNonDefaultForStrategy u/pid:%d/%d strat:%d dev:%s", 3125 Binder.getCallingUid(), Binder.getCallingPid(), strategy, device.toString()); 3126 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 3127 if (device.getRole() == AudioDeviceAttributes.ROLE_INPUT) { 3128 Log.e(TAG, "Unsupported input routing in " + logString); 3129 return AudioSystem.ERROR; 3130 } 3131 3132 final int status = mDeviceBroker.setDeviceAsNonDefaultForStrategySync(strategy, device); 3133 if (status != AudioSystem.SUCCESS) { 3134 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 3135 } 3136 3137 return status; 3138 } 3139 3140 /** 3141 * @see AudioManager#removeDeviceAsNonDefaultForStrategy(AudioProductStrategy, 3142 * AudioDeviceAttributes) 3143 */ 3144 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) removeDeviceAsNonDefaultForStrategy(int strategy, AudioDeviceAttributes device)3145 public int removeDeviceAsNonDefaultForStrategy(int strategy, 3146 AudioDeviceAttributes device) { 3147 super.removeDeviceAsNonDefaultForStrategy_enforcePermission(); 3148 Objects.requireNonNull(device); 3149 3150 device = retrieveBluetoothAddress(device); 3151 3152 final String logString = String.format( 3153 "removeDeviceAsNonDefaultForStrategy strat:%d dev:%s", strategy, device.toString()); 3154 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 3155 if (device.getRole() == AudioDeviceAttributes.ROLE_INPUT) { 3156 Log.e(TAG, "Unsupported input routing in " + logString); 3157 return AudioSystem.ERROR; 3158 } 3159 3160 final int status = mDeviceBroker.removeDeviceAsNonDefaultForStrategySync(strategy, device); 3161 if (status != AudioSystem.SUCCESS && status != AudioSystem.BAD_VALUE) { 3162 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 3163 } 3164 return status; 3165 } 3166 3167 /** 3168 * @see AudioManager#getNonDefaultDevicesForStrategy(AudioProductStrategy) 3169 */ 3170 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) getNonDefaultDevicesForStrategy(int strategy)3171 public List<AudioDeviceAttributes> getNonDefaultDevicesForStrategy(int strategy) { 3172 super.getNonDefaultDevicesForStrategy_enforcePermission(); 3173 List<AudioDeviceAttributes> devices = new ArrayList<>(); 3174 int status = AudioSystem.ERROR; 3175 3176 try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { 3177 status = AudioSystem.getDevicesForRoleAndStrategy( 3178 strategy, AudioSystem.DEVICE_ROLE_DISABLED, devices); 3179 } 3180 3181 if (status != AudioSystem.SUCCESS) { 3182 Log.e(TAG, String.format("Error %d in getNonDefaultDeviceForStrategy(%d)", 3183 status, strategy)); 3184 return new ArrayList<AudioDeviceAttributes>(); 3185 } else { 3186 return anonymizeAudioDeviceAttributesList(devices); 3187 } 3188 } 3189 3190 /** @see AudioManager#addOnPreferredDevicesForStrategyChangedListener( 3191 * Executor, AudioManager.OnPreferredDevicesForStrategyChangedListener) 3192 */ registerStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)3193 public void registerStrategyPreferredDevicesDispatcher( 3194 @Nullable IStrategyPreferredDevicesDispatcher dispatcher) { 3195 if (dispatcher == null) { 3196 return; 3197 } 3198 enforceModifyAudioRoutingPermission(); 3199 mDeviceBroker.registerStrategyPreferredDevicesDispatcher( 3200 dispatcher, isBluetoothPrividged()); 3201 } 3202 3203 /** @see AudioManager#removeOnPreferredDevicesForStrategyChangedListener( 3204 * AudioManager.OnPreferredDevicesForStrategyChangedListener) 3205 */ unregisterStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)3206 public void unregisterStrategyPreferredDevicesDispatcher( 3207 @Nullable IStrategyPreferredDevicesDispatcher dispatcher) { 3208 if (dispatcher == null) { 3209 return; 3210 } 3211 enforceModifyAudioRoutingPermission(); 3212 mDeviceBroker.unregisterStrategyPreferredDevicesDispatcher(dispatcher); 3213 } 3214 3215 /** @see AudioManager#addOnNonDefaultDevicesForStrategyChangedListener( 3216 * Executor, AudioManager.OnNonDefaultDevicesForStrategyChangedListener) 3217 */ registerStrategyNonDefaultDevicesDispatcher( @ullable IStrategyNonDefaultDevicesDispatcher dispatcher)3218 public void registerStrategyNonDefaultDevicesDispatcher( 3219 @Nullable IStrategyNonDefaultDevicesDispatcher dispatcher) { 3220 if (dispatcher == null) { 3221 return; 3222 } 3223 enforceModifyAudioRoutingPermission(); 3224 mDeviceBroker.registerStrategyNonDefaultDevicesDispatcher( 3225 dispatcher, isBluetoothPrividged()); 3226 } 3227 3228 /** @see AudioManager#removeOnNonDefaultDevicesForStrategyChangedListener( 3229 * AudioManager.OnNonDefaultDevicesForStrategyChangedListener) 3230 */ unregisterStrategyNonDefaultDevicesDispatcher( @ullable IStrategyNonDefaultDevicesDispatcher dispatcher)3231 public void unregisterStrategyNonDefaultDevicesDispatcher( 3232 @Nullable IStrategyNonDefaultDevicesDispatcher dispatcher) { 3233 if (dispatcher == null) { 3234 return; 3235 } 3236 enforceModifyAudioRoutingPermission(); 3237 mDeviceBroker.unregisterStrategyNonDefaultDevicesDispatcher(dispatcher); 3238 } 3239 3240 /** 3241 * @see AudioManager#setPreferredDevicesForCapturePreset(int, AudioDeviceAttributes) 3242 */ setPreferredDevicesForCapturePreset( int capturePreset, List<AudioDeviceAttributes> devices)3243 public int setPreferredDevicesForCapturePreset( 3244 int capturePreset, List<AudioDeviceAttributes> devices) { 3245 if (devices == null) { 3246 return AudioSystem.ERROR; 3247 } 3248 enforceModifyAudioRoutingPermission(); 3249 final String logString = String.format( 3250 "setPreferredDevicesForCapturePreset u/pid:%d/%d source:%d dev:%s", 3251 Binder.getCallingUid(), Binder.getCallingPid(), capturePreset, 3252 devices.stream().map(e -> e.toString()).collect(Collectors.joining(","))); 3253 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 3254 if (devices.stream().anyMatch(device -> 3255 device.getRole() == AudioDeviceAttributes.ROLE_OUTPUT)) { 3256 Log.e(TAG, "Unsupported output routing in " + logString); 3257 return AudioSystem.ERROR; 3258 } 3259 3260 devices = retrieveBluetoothAddresses(devices); 3261 3262 final int status = mDeviceBroker.setPreferredDevicesForCapturePresetSync( 3263 capturePreset, devices); 3264 if (status != AudioSystem.SUCCESS) { 3265 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 3266 } 3267 3268 return status; 3269 } 3270 3271 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 3272 /** @see AudioManager#clearPreferredDevicesForCapturePreset(int) */ clearPreferredDevicesForCapturePreset(int capturePreset)3273 public int clearPreferredDevicesForCapturePreset(int capturePreset) { 3274 super.clearPreferredDevicesForCapturePreset_enforcePermission(); 3275 3276 final String logString = String.format( 3277 "removePreferredDeviceForCapturePreset source:%d", capturePreset); 3278 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 3279 3280 final int status = mDeviceBroker.clearPreferredDevicesForCapturePresetSync(capturePreset); 3281 if (status != AudioSystem.SUCCESS && status != AudioSystem.BAD_VALUE) { 3282 Log.e(TAG, String.format("Error %d in %s", status, logString)); 3283 } 3284 return status; 3285 } 3286 3287 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 3288 /** 3289 * @see AudioManager#getPreferredDevicesForCapturePreset(int) 3290 */ getPreferredDevicesForCapturePreset(int capturePreset)3291 public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) { 3292 super.getPreferredDevicesForCapturePreset_enforcePermission(); 3293 3294 List<AudioDeviceAttributes> devices = new ArrayList<>(); 3295 int status = AudioSystem.SUCCESS; 3296 final long identity = Binder.clearCallingIdentity(); 3297 try { 3298 status = AudioSystem.getDevicesForRoleAndCapturePreset( 3299 capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices); 3300 } finally { 3301 Binder.restoreCallingIdentity(identity); 3302 } 3303 if (status != AudioSystem.SUCCESS) { 3304 Log.e(TAG, String.format("Error %d in getPreferredDeviceForCapturePreset(%d)", 3305 status, capturePreset)); 3306 return new ArrayList<AudioDeviceAttributes>(); 3307 } else { 3308 return anonymizeAudioDeviceAttributesList(devices); 3309 } 3310 } 3311 3312 /** 3313 * @see AudioManager#addOnPreferredDevicesForCapturePresetChangedListener( 3314 * Executor, OnPreferredDevicesForCapturePresetChangedListener) 3315 */ registerCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)3316 public void registerCapturePresetDevicesRoleDispatcher( 3317 @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) { 3318 if (dispatcher == null) { 3319 return; 3320 } 3321 enforceModifyAudioRoutingPermission(); 3322 mDeviceBroker.registerCapturePresetDevicesRoleDispatcher( 3323 dispatcher, isBluetoothPrividged()); 3324 } 3325 3326 /** 3327 * @see AudioManager#removeOnPreferredDevicesForCapturePresetChangedListener( 3328 * AudioManager.OnPreferredDevicesForCapturePresetChangedListener) 3329 */ unregisterCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)3330 public void unregisterCapturePresetDevicesRoleDispatcher( 3331 @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) { 3332 if (dispatcher == null) { 3333 return; 3334 } 3335 enforceModifyAudioRoutingPermission(); 3336 mDeviceBroker.unregisterCapturePresetDevicesRoleDispatcher(dispatcher); 3337 } 3338 3339 /** @see AudioManager#getDevicesForAttributes(AudioAttributes) */ getDevicesForAttributes( @onNull AudioAttributes attributes)3340 public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes( 3341 @NonNull AudioAttributes attributes) { 3342 enforceQueryStateOrModifyRoutingPermission(); 3343 3344 return new ArrayList<AudioDeviceAttributes>(anonymizeAudioDeviceAttributesList( 3345 getDevicesForAttributesInt(attributes, false /* forVolume */))); 3346 } 3347 3348 /** @see AudioManager#getAudioDevicesForAttributes(AudioAttributes) 3349 * This method is similar with AudioService#getDevicesForAttributes, 3350 * only it doesn't enforce permissions because it is used by an unprivileged public API 3351 * instead of the system API. 3352 */ getDevicesForAttributesUnprotected( @onNull AudioAttributes attributes)3353 public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesUnprotected( 3354 @NonNull AudioAttributes attributes) { 3355 return new ArrayList<AudioDeviceAttributes>(anonymizeAudioDeviceAttributesList( 3356 getDevicesForAttributesInt(attributes, false /* forVolume */))); 3357 } 3358 3359 /** 3360 * @see AudioManager#isMusicActive() 3361 * @param remotely true if query is for remote playback (cast), false for local playback. 3362 */ isMusicActive(boolean remotely)3363 public boolean isMusicActive(boolean remotely) { 3364 // no permission required 3365 final long token = Binder.clearCallingIdentity(); 3366 try { 3367 if (remotely) { 3368 return AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, 0); 3369 } else { 3370 return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0); 3371 } 3372 } finally { 3373 Binder.restoreCallingIdentity(token); 3374 } 3375 } 3376 getDevicesForAttributesInt( @onNull AudioAttributes attributes, boolean forVolume)3377 protected @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesInt( 3378 @NonNull AudioAttributes attributes, boolean forVolume) { 3379 Objects.requireNonNull(attributes); 3380 return mAudioSystem.getDevicesForAttributes(attributes, forVolume); 3381 } 3382 3383 /** 3384 * @see AudioManager#addOnDevicesForAttributesChangedListener( 3385 * AudioAttributes, Executor, OnDevicesForAttributesChangedListener) 3386 */ addOnDevicesForAttributesChangedListener(AudioAttributes attributes, IDevicesForAttributesCallback callback)3387 public void addOnDevicesForAttributesChangedListener(AudioAttributes attributes, 3388 IDevicesForAttributesCallback callback) { 3389 mAudioSystem.addOnDevicesForAttributesChangedListener( 3390 attributes, false /* forVolume */, callback); 3391 } 3392 3393 /** 3394 * @see AudioManager#removeOnDevicesForAttributesChangedListener( 3395 * OnDevicesForAttributesChangedListener) 3396 */ removeOnDevicesForAttributesChangedListener( IDevicesForAttributesCallback callback)3397 public void removeOnDevicesForAttributesChangedListener( 3398 IDevicesForAttributesCallback callback) { 3399 mAudioSystem.removeOnDevicesForAttributesChangedListener(callback); 3400 } 3401 3402 // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP, 3403 // KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE handleVolumeKey(@onNull KeyEvent event, boolean isOnTv, @NonNull String callingPackage, @NonNull String caller)3404 public void handleVolumeKey(@NonNull KeyEvent event, boolean isOnTv, 3405 @NonNull String callingPackage, @NonNull String caller) { 3406 int keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_NORMAL; 3407 if (isOnTv) { 3408 if (event.getAction() == KeyEvent.ACTION_DOWN) { 3409 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_START; 3410 } else { // may catch more than ACTION_UP, but will end vol adjustement 3411 // the vol key is either released (ACTION_UP), or multiple keys are pressed 3412 // (ACTION_MULTIPLE) and we don't know what to do for volume control on CEC, end 3413 // the repeated volume adjustement 3414 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_END; 3415 } 3416 } else if (event.getAction() != KeyEvent.ACTION_DOWN) { 3417 return; 3418 } 3419 3420 int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND 3421 | AudioManager.FLAG_FROM_KEY; 3422 3423 switch (event.getKeyCode()) { 3424 case KeyEvent.KEYCODE_VOLUME_UP: 3425 adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE, 3426 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 3427 Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode); 3428 break; 3429 case KeyEvent.KEYCODE_VOLUME_DOWN: 3430 adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER, 3431 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 3432 Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode); 3433 break; 3434 case KeyEvent.KEYCODE_VOLUME_MUTE: 3435 if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 3436 adjustSuggestedStreamVolume(AudioManager.ADJUST_TOGGLE_MUTE, 3437 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 3438 Binder.getCallingUid(), Binder.getCallingPid(), 3439 true, AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 3440 } 3441 break; 3442 default: 3443 Log.e(TAG, "Invalid key code " + event.getKeyCode() + " sent by " + callingPackage); 3444 return; // not needed but added if code gets added below this switch statement 3445 } 3446 } 3447 setNavigationRepeatSoundEffectsEnabled(boolean enabled)3448 public void setNavigationRepeatSoundEffectsEnabled(boolean enabled) { 3449 mNavigationRepeatSoundEffectsEnabled = enabled; 3450 } 3451 3452 /** 3453 * @return true if the fast scroll sound effects are enabled 3454 */ areNavigationRepeatSoundEffectsEnabled()3455 public boolean areNavigationRepeatSoundEffectsEnabled() { 3456 return mNavigationRepeatSoundEffectsEnabled; 3457 } 3458 setHomeSoundEffectEnabled(boolean enabled)3459 public void setHomeSoundEffectEnabled(boolean enabled) { 3460 mHomeSoundEffectEnabled = enabled; 3461 } 3462 3463 /** 3464 * @return true if the home sound effect is enabled 3465 */ isHomeSoundEffectEnabled()3466 public boolean isHomeSoundEffectEnabled() { 3467 return mHomeSoundEffectEnabled; 3468 } 3469 3470 /** 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)3471 private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, 3472 String callingPackage, String caller, int uid, int pid, boolean hasModifyAudioSettings, 3473 int keyEventMode) { 3474 if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType 3475 + ", flags=" + flags + ", caller=" + caller 3476 + ", volControlStream=" + mVolumeControlStream 3477 + ", userSelect=" + mUserSelectedVolumeControlStream); 3478 if (direction != AudioManager.ADJUST_SAME) { 3479 sVolumeLogger.enqueue( 3480 new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType, 3481 direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage) 3482 .append("/").append(caller).append(" uid:").append(uid).toString())); 3483 } 3484 3485 boolean hasExternalVolumeController = notifyExternalVolumeController(direction); 3486 3487 new MediaMetrics.Item(mMetricsId + "adjustSuggestedStreamVolume") 3488 .setUid(Binder.getCallingUid()) 3489 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage) 3490 .set(MediaMetrics.Property.CLIENT_NAME, caller) 3491 .set(MediaMetrics.Property.DIRECTION, direction > 0 3492 ? MediaMetrics.Value.UP : MediaMetrics.Value.DOWN) 3493 .set(MediaMetrics.Property.EXTERNAL, hasExternalVolumeController 3494 ? MediaMetrics.Value.YES : MediaMetrics.Value.NO) 3495 .set(MediaMetrics.Property.FLAGS, flags) 3496 .record(); 3497 3498 if (hasExternalVolumeController) { 3499 return; 3500 } 3501 3502 final int streamType; 3503 synchronized (mForceControlStreamLock) { 3504 // Request lock in case mVolumeControlStream is changed by other thread. 3505 if (mUserSelectedVolumeControlStream) { // implies mVolumeControlStream != -1 3506 streamType = mVolumeControlStream; 3507 } else { 3508 // TODO discard activity on a muted stream? 3509 final int maybeActiveStreamType = getActiveStreamType(suggestedStreamType); 3510 final boolean activeForReal; 3511 if (maybeActiveStreamType == AudioSystem.STREAM_RING 3512 || maybeActiveStreamType == AudioSystem.STREAM_NOTIFICATION) { 3513 activeForReal = wasStreamActiveRecently(maybeActiveStreamType, 0); 3514 } else { 3515 activeForReal = mAudioSystem.isStreamActive(maybeActiveStreamType, 0); 3516 } 3517 if (activeForReal || mVolumeControlStream == -1) { 3518 streamType = maybeActiveStreamType; 3519 } else { 3520 streamType = mVolumeControlStream; 3521 } 3522 } 3523 } 3524 3525 final boolean isMute = isMuteAdjust(direction); 3526 3527 ensureValidStreamType(streamType); 3528 final int resolvedStream = mStreamVolumeAlias[streamType]; 3529 3530 // Play sounds on STREAM_RING only. 3531 if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 && 3532 resolvedStream != AudioSystem.STREAM_RING) { 3533 flags &= ~AudioManager.FLAG_PLAY_SOUND; 3534 } 3535 3536 // For notifications/ring, show the ui before making any adjustments 3537 // Don't suppress mute/unmute requests 3538 // Don't suppress adjustments for single volume device 3539 if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute) 3540 && !mIsSingleVolume) { 3541 direction = 0; 3542 flags &= ~AudioManager.FLAG_PLAY_SOUND; 3543 flags &= ~AudioManager.FLAG_VIBRATE; 3544 if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment"); 3545 } 3546 3547 adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid, pid, 3548 null, hasModifyAudioSettings, keyEventMode); 3549 } 3550 notifyExternalVolumeController(int direction)3551 private boolean notifyExternalVolumeController(int direction) { 3552 final IAudioPolicyCallback externalVolumeController; 3553 synchronized (mExtVolumeControllerLock) { 3554 externalVolumeController = mExtVolumeController; 3555 } 3556 if (externalVolumeController == null) { 3557 return false; 3558 } 3559 3560 sendMsg(mAudioHandler, MSG_NOTIFY_VOL_EVENT, SENDMSG_QUEUE, 3561 direction, 0 /*ignored*/, 3562 externalVolumeController, 0 /*delay*/); 3563 return true; 3564 } 3565 3566 /** Retain API for unsupported app usage */ adjustStreamVolume(int streamType, int direction, int flags, String callingPackage)3567 public void adjustStreamVolume(int streamType, int direction, int flags, 3568 String callingPackage) { 3569 adjustStreamVolumeWithAttribution(streamType, direction, flags, callingPackage, null); 3570 } 3571 3572 /** @see AudioManager#adjustStreamVolume(int, int, int) 3573 * Part of service interface, check permissions here */ adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, String callingPackage, String attributionTag)3574 public void adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, 3575 String callingPackage, String attributionTag) { 3576 if (mHardeningEnforcer.blockVolumeMethod( 3577 HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_STREAM_VOLUME)) { 3578 return; 3579 } 3580 if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { 3581 Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without" 3582 + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage); 3583 return; 3584 } 3585 3586 final VolumeEvent evt = new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType, 3587 direction/*val1*/, flags/*val2*/, callingPackage); 3588 sVolumeLogger.enqueue(evt); 3589 // also logging mute/unmute calls to the dedicated logger 3590 if (isMuteAdjust(direction)) { 3591 sMuteLogger.enqueue(evt); 3592 } 3593 adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage, 3594 Binder.getCallingUid(), Binder.getCallingPid(), attributionTag, 3595 callingHasAudioSettingsPermission(), AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 3596 } 3597 adjustStreamVolume(int streamType, int direction, int flags, String callingPackage, String caller, int uid, int pid, String attributionTag, boolean hasModifyAudioSettings, int keyEventMode)3598 protected void adjustStreamVolume(int streamType, int direction, int flags, 3599 String callingPackage, String caller, int uid, int pid, String attributionTag, 3600 boolean hasModifyAudioSettings, int keyEventMode) { 3601 if (mUseFixedVolume) { 3602 return; 3603 } 3604 if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction 3605 + ", flags=" + flags + ", caller=" + caller); 3606 3607 ensureValidDirection(direction); 3608 ensureValidStreamType(streamType); 3609 3610 boolean isMuteAdjust = isMuteAdjust(direction); 3611 3612 if (isMuteAdjust && !isStreamAffectedByMute(streamType)) { 3613 return; 3614 } 3615 3616 // If adjust is mute and the stream is STREAM_VOICE_CALL or STREAM_BLUETOOTH_SCO, make sure 3617 // that the calling app have the MODIFY_PHONE_STATE permission. 3618 if (isMuteAdjust && 3619 (streamType == AudioSystem.STREAM_VOICE_CALL || 3620 streamType == AudioSystem.STREAM_BLUETOOTH_SCO) && 3621 mContext.checkPermission(MODIFY_PHONE_STATE, pid, uid) 3622 != PackageManager.PERMISSION_GRANTED) { 3623 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: adjustStreamVolume from pid=" 3624 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 3625 return; 3626 } 3627 3628 // If the stream is STREAM_ASSISTANT, 3629 // make sure that the calling app have the MODIFY_AUDIO_ROUTING permission. 3630 if (streamType == AudioSystem.STREAM_ASSISTANT && 3631 mContext.checkPermission( 3632 MODIFY_AUDIO_ROUTING, pid, uid) 3633 != PackageManager.PERMISSION_GRANTED) { 3634 Log.w(TAG, "MODIFY_AUDIO_ROUTING Permission Denial: adjustStreamVolume from pid=" 3635 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 3636 return; 3637 } 3638 3639 // use stream type alias here so that streams with same alias have the same behavior, 3640 // including with regard to silent mode control (e.g the use of STREAM_RING below and in 3641 // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION) 3642 int streamTypeAlias = mStreamVolumeAlias[streamType]; 3643 3644 VolumeStreamState streamState = mStreamStates[streamTypeAlias]; 3645 3646 final int device = getDeviceForStream(streamTypeAlias); 3647 3648 int aliasIndex = streamState.getIndex(device); 3649 boolean adjustVolume = true; 3650 int step; 3651 3652 // skip a2dp absolute volume control request when the device 3653 // is neither an a2dp device nor BLE device 3654 if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 3655 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device)) 3656 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { 3657 return; 3658 } 3659 3660 // If we are being called by the system (e.g. hardware keys) check for current user 3661 // so we handle user restrictions correctly. 3662 if (uid == android.os.Process.SYSTEM_UID) { 3663 uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); 3664 } 3665 // validate calling package and app op 3666 if (!checkNoteAppOp( 3667 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) { 3668 return; 3669 } 3670 3671 mSoundDoseHelper.invalidatePendingVolumeCommand(); 3672 3673 flags &= ~AudioManager.FLAG_FIXED_VOLUME; 3674 if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) { 3675 flags |= AudioManager.FLAG_FIXED_VOLUME; 3676 3677 // Always toggle between max safe volume and 0 for fixed volume devices where safe 3678 // volume is enforced, and max and 0 for the others. 3679 // This is simulated by stepping by the full allowed volume range 3680 step = mSoundDoseHelper.getSafeMediaVolumeIndex(device); 3681 if (step < 0) { 3682 step = streamState.getMaxIndex(); 3683 } 3684 if (aliasIndex != 0) { 3685 aliasIndex = step; 3686 } 3687 } else { 3688 // convert one UI step (+/-1) into a number of internal units on the stream alias 3689 step = rescaleStep(10, streamType, streamTypeAlias); 3690 } 3691 3692 // If either the client forces allowing ringer modes for this adjustment, 3693 // or stream is used for UI sonification 3694 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 3695 (isUiSoundsStreamType(streamTypeAlias))) { 3696 int ringerMode = getRingerModeInternal(); 3697 // do not vibrate if already in vibrate mode 3698 if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { 3699 flags &= ~AudioManager.FLAG_VIBRATE; 3700 } 3701 // Check if the ringer mode handles this adjustment. If it does we don't 3702 // need to adjust the volume further. 3703 final int result = checkForRingerModeChange(aliasIndex, direction, step, 3704 streamState.mIsMuted, callingPackage, flags); 3705 adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0; 3706 // If suppressing a volume adjustment in silent mode, display the UI hint 3707 if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) { 3708 flags |= AudioManager.FLAG_SHOW_SILENT_HINT; 3709 } 3710 // If suppressing a volume down adjustment in vibrate mode, display the UI hint 3711 if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) { 3712 flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT; 3713 } 3714 } else if (isStreamMutedByRingerOrZenMode(streamTypeAlias) && streamState.mIsMuted) { 3715 // if the stream is currently muted streams by ringer/zen mode 3716 // then it cannot be unmuted (without FLAG_ALLOW_RINGER_MODES) with an unmute or raise 3717 if (direction == AudioManager.ADJUST_TOGGLE_MUTE 3718 || direction == AudioManager.ADJUST_UNMUTE 3719 || direction == AudioManager.ADJUST_RAISE) { 3720 adjustVolume = false; 3721 } 3722 } 3723 3724 // If the ringer mode or zen is muting the stream, do not change stream unless 3725 // it'll cause us to exit dnd 3726 if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) { 3727 adjustVolume = false; 3728 } 3729 int oldIndex = mStreamStates[streamType].getIndex(device); 3730 3731 // Check if the volume adjustment should be handled by an absolute volume controller instead 3732 if (isAbsoluteVolumeDevice(device) 3733 && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) { 3734 AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device); 3735 if (info.mHandlesVolumeAdjustment) { 3736 dispatchAbsoluteVolumeAdjusted(streamType, info, oldIndex, direction, 3737 keyEventMode); 3738 return; 3739 } 3740 } 3741 3742 if (adjustVolume && (direction != AudioManager.ADJUST_SAME) 3743 && (keyEventMode != AudioDeviceVolumeManager.ADJUST_MODE_END)) { 3744 mAudioHandler.removeMessages(MSG_UNMUTE_STREAM_ON_SINGLE_VOL_DEVICE); 3745 3746 if (isMuteAdjust && !mFullVolumeDevices.contains(device)) { 3747 boolean state; 3748 if (direction == AudioManager.ADJUST_TOGGLE_MUTE) { 3749 state = !streamState.mIsMuted; 3750 } else { 3751 state = direction == AudioManager.ADJUST_MUTE; 3752 } 3753 muteAliasStreams(streamTypeAlias, state); 3754 } else if ((direction == AudioManager.ADJUST_RAISE) 3755 && mSoundDoseHelper.raiseVolumeDisplaySafeMediaVolume(streamTypeAlias, 3756 aliasIndex + step, device, flags)) { 3757 Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex); 3758 } else if (!isFullVolumeDevice(device) 3759 && (streamState.adjustIndex(direction * step, device, caller, 3760 hasModifyAudioSettings) 3761 || streamState.mIsMuted)) { 3762 // Post message to set system volume (it in turn will post a 3763 // message to persist). 3764 if (streamState.mIsMuted) { 3765 // Unmute the stream if it was previously muted 3766 if (direction == AudioManager.ADJUST_RAISE) { 3767 // unmute immediately for volume up 3768 muteAliasStreams(streamTypeAlias, false); 3769 } else if (direction == AudioManager.ADJUST_LOWER) { 3770 if (mIsSingleVolume) { 3771 sendMsg(mAudioHandler, MSG_UNMUTE_STREAM_ON_SINGLE_VOL_DEVICE, 3772 SENDMSG_QUEUE, streamTypeAlias, flags, null, 3773 UNMUTE_STREAM_DELAY); 3774 } 3775 } 3776 } 3777 sendMsg(mAudioHandler, 3778 MSG_SET_DEVICE_VOLUME, 3779 SENDMSG_QUEUE, 3780 device, 3781 0, 3782 streamState, 3783 0); 3784 } 3785 3786 int newIndex = mStreamStates[streamType].getIndex(device); 3787 3788 int streamToDriveAbsVol = absVolumeIndexFix() ? getBluetoothContextualVolumeStream() : 3789 AudioSystem.STREAM_MUSIC; 3790 // Check if volume update should be send to AVRCP 3791 if (streamTypeAlias == streamToDriveAbsVol 3792 && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 3793 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 3794 if (DEBUG_VOL) { 3795 Log.d(TAG, "adjustStreamVolume: postSetAvrcpAbsoluteVolumeIndex index=" 3796 + newIndex + "stream=" + streamType); 3797 } 3798 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10); 3799 } else if (isAbsoluteVolumeDevice(device) 3800 && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) { 3801 AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device); 3802 dispatchAbsoluteVolumeChanged(streamType, info, newIndex); 3803 } 3804 3805 if (AudioSystem.isLeAudioDeviceType(device) 3806 && streamType == getBluetoothContextualVolumeStream() 3807 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 3808 if (DEBUG_VOL) { 3809 Log.d(TAG, "adjustStreamVolume postSetLeAudioVolumeIndex index=" 3810 + newIndex + " stream=" + streamType); 3811 } 3812 mDeviceBroker.postSetLeAudioVolumeIndex(newIndex, 3813 mStreamStates[streamType].getMaxIndex(), streamType); 3814 } 3815 3816 // Check if volume update should be send to Hearing Aid 3817 if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 3818 // only modify the hearing aid attenuation when the stream to modify matches 3819 // the one expected by the hearing aid 3820 if (streamType == getBluetoothContextualVolumeStream()) { 3821 if (DEBUG_VOL) { 3822 Log.d(TAG, "adjustStreamVolume postSetHearingAidVolumeIndex index=" 3823 + newIndex + " stream=" + streamType); 3824 } 3825 mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType); 3826 } 3827 } 3828 } 3829 3830 final int newIndex = mStreamStates[streamType].getIndex(device); 3831 3832 if (adjustVolume) { 3833 synchronized (mHdmiClientLock) { 3834 if (mHdmiManager != null) { 3835 // At most one of mHdmiPlaybackClient and mHdmiTvClient should be non-null 3836 HdmiClient hdmiClient = mHdmiPlaybackClient; 3837 if (mHdmiTvClient != null) { 3838 hdmiClient = mHdmiTvClient; 3839 } 3840 3841 boolean playbackDeviceConditions = mHdmiPlaybackClient != null 3842 && isFullVolumeDevice(device); 3843 boolean tvConditions = mHdmiTvClient != null 3844 && mHdmiSystemAudioSupported 3845 && !isAbsoluteVolumeDevice(device) 3846 && !isA2dpAbsoluteVolumeDevice(device); 3847 3848 if ((playbackDeviceConditions || tvConditions) 3849 && mHdmiCecVolumeControlEnabled 3850 && streamTypeAlias == AudioSystem.STREAM_MUSIC) { 3851 int keyCode = KeyEvent.KEYCODE_UNKNOWN; 3852 switch (direction) { 3853 case AudioManager.ADJUST_RAISE: 3854 keyCode = KeyEvent.KEYCODE_VOLUME_UP; 3855 break; 3856 case AudioManager.ADJUST_LOWER: 3857 keyCode = KeyEvent.KEYCODE_VOLUME_DOWN; 3858 break; 3859 case AudioManager.ADJUST_TOGGLE_MUTE: 3860 case AudioManager.ADJUST_MUTE: 3861 case AudioManager.ADJUST_UNMUTE: 3862 // Many CEC devices only support toggle mute. Therefore, we send the 3863 // same keycode for all three mute options. 3864 keyCode = KeyEvent.KEYCODE_VOLUME_MUTE; 3865 break; 3866 default: 3867 break; 3868 } 3869 if (keyCode != KeyEvent.KEYCODE_UNKNOWN) { 3870 final long ident = Binder.clearCallingIdentity(); 3871 try { 3872 switch (keyEventMode) { 3873 case AudioDeviceVolumeManager.ADJUST_MODE_NORMAL: 3874 hdmiClient.sendVolumeKeyEvent(keyCode, true); 3875 hdmiClient.sendVolumeKeyEvent(keyCode, false); 3876 break; 3877 case AudioDeviceVolumeManager.ADJUST_MODE_START: 3878 hdmiClient.sendVolumeKeyEvent(keyCode, true); 3879 break; 3880 case AudioDeviceVolumeManager.ADJUST_MODE_END: 3881 hdmiClient.sendVolumeKeyEvent(keyCode, false); 3882 break; 3883 default: 3884 Log.e(TAG, "Invalid keyEventMode " + keyEventMode); 3885 } 3886 } finally { 3887 Binder.restoreCallingIdentity(ident); 3888 } 3889 } 3890 } 3891 3892 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 3893 && (oldIndex != newIndex || isMuteAdjust)) { 3894 maybeSendSystemAudioStatusCommand(isMuteAdjust); 3895 } 3896 } 3897 } 3898 } 3899 sendVolumeUpdate(streamType, oldIndex, newIndex, flags, device); 3900 } 3901 3902 /** 3903 * Loops on aliased stream, update the mute cache attribute of each 3904 * {@see AudioService#VolumeStreamState}, and then apply the change. 3905 * It prevents to unnecessary {@see AudioSystem#setStreamVolume} done for each stream 3906 * and aliases before mute change changed and after. 3907 */ muteAliasStreams(int streamAlias, boolean state)3908 private void muteAliasStreams(int streamAlias, boolean state) { 3909 // Locking mSettingsLock to avoid inversion when calling doMute -> updateVolumeGroupIndex 3910 synchronized (mSettingsLock) { 3911 synchronized (VolumeStreamState.class) { 3912 List<Integer> streamsToMute = new ArrayList<>(); 3913 for (int stream = 0; stream < mStreamStates.length; stream++) { 3914 VolumeStreamState vss = mStreamStates[stream]; 3915 if (streamAlias == mStreamVolumeAlias[stream] && vss.isMutable()) { 3916 if (!(mCameraSoundForced 3917 && (vss.getStreamType() 3918 == AudioSystem.STREAM_SYSTEM_ENFORCED))) { 3919 boolean changed = vss.mute(state, /* apply= */ false, 3920 "muteAliasStreams"); 3921 if (changed) { 3922 streamsToMute.add(stream); 3923 } 3924 } 3925 } 3926 } 3927 streamsToMute.forEach(streamToMute -> { 3928 mStreamStates[streamToMute].doMute(); 3929 broadcastMuteSetting(streamToMute, state); 3930 }); 3931 } 3932 } 3933 } 3934 broadcastMuteSetting(int streamType, boolean isMuted)3935 private void broadcastMuteSetting(int streamType, boolean isMuted) { 3936 // Stream mute changed, fire the intent. 3937 Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION); 3938 intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType); 3939 intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, isMuted); 3940 sendBroadcastToAll(intent, null /* options */); 3941 } 3942 3943 // Called after a delay when volume down is pressed while muted onUnmuteStreamOnSingleVolDevice(int streamAlias, int flags)3944 private void onUnmuteStreamOnSingleVolDevice(int streamAlias, int flags) { 3945 boolean wasMuted; 3946 // Locking mSettingsLock to avoid inversion when calling vss.mute -> vss.doMute -> 3947 // vss.updateVolumeGroupIndex 3948 synchronized (mSettingsLock) { 3949 synchronized (VolumeStreamState.class) { 3950 final VolumeStreamState streamState = mStreamStates[streamAlias]; 3951 // if unmuting causes a change, it was muted 3952 wasMuted = streamState.mute(false, "onUnmuteStreamOnSingleVolDevice"); 3953 if (wasMuted) { 3954 // Unmute all aliasted streams 3955 muteAliasStreams(streamAlias, false); 3956 } 3957 final int device = getDeviceForStream(streamAlias); 3958 final int index = streamState.getIndex(device); 3959 sendVolumeUpdate(streamAlias, index, index, flags, device); 3960 } 3961 if (streamAlias == AudioSystem.STREAM_MUSIC && wasMuted) { 3962 synchronized (mHdmiClientLock) { 3963 maybeSendSystemAudioStatusCommand(true); 3964 } 3965 } 3966 } 3967 } 3968 3969 @GuardedBy("mHdmiClientLock") maybeSendSystemAudioStatusCommand(boolean isMuteAdjust)3970 private void maybeSendSystemAudioStatusCommand(boolean isMuteAdjust) { 3971 if (mHdmiAudioSystemClient == null 3972 || !mHdmiSystemAudioSupported 3973 || !mHdmiCecVolumeControlEnabled) { 3974 return; 3975 } 3976 3977 final long identity = Binder.clearCallingIdentity(); 3978 try { 3979 mHdmiAudioSystemClient.sendReportAudioStatusCecCommand( 3980 isMuteAdjust, getStreamVolume(AudioSystem.STREAM_MUSIC), 3981 getStreamMaxVolume(AudioSystem.STREAM_MUSIC), 3982 isStreamMute(AudioSystem.STREAM_MUSIC)); 3983 } finally { 3984 Binder.restoreCallingIdentity(identity); 3985 } 3986 } 3987 getNewRingerMode(int stream, int index, int flags)3988 private int getNewRingerMode(int stream, int index, int flags) { 3989 // setRingerMode does nothing if the device is single volume,so the value would be unchanged 3990 if (mIsSingleVolume) { 3991 return getRingerModeExternal(); 3992 } 3993 3994 // setting volume on ui sounds stream type also controls silent mode 3995 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 3996 (stream == getUiSoundsStreamType())) { 3997 int newRingerMode; 3998 if (index == 0) { 3999 newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE 4000 : mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT 4001 : AudioManager.RINGER_MODE_NORMAL; 4002 } else { 4003 newRingerMode = AudioManager.RINGER_MODE_NORMAL; 4004 } 4005 return newRingerMode; 4006 } 4007 return getRingerModeExternal(); 4008 } 4009 isAndroidNPlus(String caller)4010 private boolean isAndroidNPlus(String caller) { 4011 try { 4012 final ApplicationInfo applicationInfo = 4013 mContext.getPackageManager().getApplicationInfoAsUser( 4014 caller, 0, UserHandle.getUserId(Binder.getCallingUid())); 4015 if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) { 4016 return true; 4017 } 4018 return false; 4019 } catch (PackageManager.NameNotFoundException e) { 4020 return true; 4021 } 4022 } 4023 wouldToggleZenMode(int newMode)4024 private boolean wouldToggleZenMode(int newMode) { 4025 if (getRingerModeExternal() == AudioManager.RINGER_MODE_SILENT 4026 && newMode != AudioManager.RINGER_MODE_SILENT) { 4027 return true; 4028 } else if (getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT 4029 && newMode == AudioManager.RINGER_MODE_SILENT) { 4030 return true; 4031 } 4032 return false; 4033 } 4034 4035 /** 4036 * Update stream volume, ringer mode and mute status after a volume index change 4037 * @param streamType 4038 * @param index 4039 * @param flags 4040 * @param device the device for which the volume is changed 4041 * @param caller 4042 * @param hasModifyAudioSettings 4043 * @param canChangeMute true if the origin of this event is one where the mute state should be 4044 * updated following the change in volume index 4045 */ onSetStreamVolume(int streamType, int index, int flags, int device, String caller, boolean hasModifyAudioSettings, boolean canChangeMute)4046 /*package*/ void onSetStreamVolume(int streamType, int index, int flags, int device, 4047 String caller, boolean hasModifyAudioSettings, boolean canChangeMute) { 4048 final int stream = mStreamVolumeAlias[streamType]; 4049 // setting volume on ui sounds stream type also controls silent mode 4050 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 4051 (stream == getUiSoundsStreamType())) { 4052 setRingerMode(getNewRingerMode(stream, index, flags), 4053 TAG + ".onSetStreamVolume", false /*external*/); 4054 } 4055 setStreamVolumeInt(stream, index, device, false, caller, hasModifyAudioSettings); 4056 // setting non-zero volume for a muted stream unmutes the stream and vice versa 4057 // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements 4058 if ((streamType != AudioSystem.STREAM_BLUETOOTH_SCO) && canChangeMute) { 4059 // As adjustStreamVolume with muteAdjust flags mute/unmutes stream and aliased streams. 4060 muteAliasStreams(stream, index == 0); 4061 } 4062 } 4063 enforceModifyAudioRoutingPermission()4064 private void enforceModifyAudioRoutingPermission() { 4065 if (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING) 4066 != PackageManager.PERMISSION_GRANTED) { 4067 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission"); 4068 } 4069 } 4070 enforceQueryStateOrModifyRoutingPermission()4071 private void enforceQueryStateOrModifyRoutingPermission() { 4072 if (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING) 4073 != PackageManager.PERMISSION_GRANTED 4074 && mContext.checkCallingOrSelfPermission(QUERY_AUDIO_STATE) 4075 != PackageManager.PERMISSION_GRANTED) { 4076 throw new SecurityException( 4077 "Missing MODIFY_AUDIO_ROUTING or QUERY_AUDIO_STATE permissions"); 4078 } 4079 } 4080 4081 @Override 4082 @android.annotation.EnforcePermission(anyOf = { 4083 MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING }) 4084 /** @see AudioManager#setVolumeGroupVolumeIndex(int, int, int) */ setVolumeGroupVolumeIndex(int groupId, int index, int flags, String callingPackage, String attributionTag)4085 public void setVolumeGroupVolumeIndex(int groupId, int index, int flags, 4086 String callingPackage, String attributionTag) { 4087 super.setVolumeGroupVolumeIndex_enforcePermission(); 4088 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4089 Log.e(TAG, ": no volume group found for id " + groupId); 4090 return; 4091 } 4092 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4093 4094 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, vgs.name(), 4095 index, flags, callingPackage + ", user " + getCurrentUserId())); 4096 4097 vgs.setVolumeIndex(index, flags); 4098 4099 // For legacy reason, propagate to all streams associated to this volume group 4100 for (int groupedStream : vgs.getLegacyStreamTypes()) { 4101 try { 4102 ensureValidStreamType(groupedStream); 4103 } catch (IllegalArgumentException e) { 4104 Log.d(TAG, "volume group " + groupId + " has internal streams (" + groupedStream 4105 + "), do not change associated stream volume"); 4106 continue; 4107 } 4108 setStreamVolume(groupedStream, index, flags, /*device*/ null, 4109 callingPackage, callingPackage, 4110 attributionTag, Binder.getCallingUid(), true /*hasModifyAudioSettings*/, 4111 true /*canChangeMuteAndUpdateController*/); 4112 } 4113 } 4114 4115 @Override 4116 @android.annotation.EnforcePermission(anyOf = { 4117 MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING }) 4118 /** @see AudioManager#getVolumeGroupVolumeIndex(int) */ getVolumeGroupVolumeIndex(int groupId)4119 public int getVolumeGroupVolumeIndex(int groupId) { 4120 super.getVolumeGroupVolumeIndex_enforcePermission(); 4121 synchronized (VolumeStreamState.class) { 4122 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4123 throw new IllegalArgumentException("No volume group for id " + groupId); 4124 } 4125 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4126 // Return 0 when muted, not min index since for e.g. Voice Call, it has a non zero 4127 // min but it mutable on permission condition. 4128 return vgs.isMuted() ? 0 : vgs.getVolumeIndex(); 4129 } 4130 } 4131 4132 /** @see AudioManager#getVolumeGroupMaxVolumeIndex(int) */ 4133 @android.annotation.EnforcePermission(anyOf = { 4134 MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING }) getVolumeGroupMaxVolumeIndex(int groupId)4135 public int getVolumeGroupMaxVolumeIndex(int groupId) { 4136 super.getVolumeGroupMaxVolumeIndex_enforcePermission(); 4137 synchronized (VolumeStreamState.class) { 4138 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4139 throw new IllegalArgumentException("No volume group for id " + groupId); 4140 } 4141 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4142 return vgs.getMaxIndex(); 4143 } 4144 } 4145 4146 /** @see AudioManager#getVolumeGroupMinVolumeIndex(int) */ 4147 @android.annotation.EnforcePermission(anyOf = { 4148 MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING }) getVolumeGroupMinVolumeIndex(int groupId)4149 public int getVolumeGroupMinVolumeIndex(int groupId) { 4150 super.getVolumeGroupMinVolumeIndex_enforcePermission(); 4151 synchronized (VolumeStreamState.class) { 4152 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4153 throw new IllegalArgumentException("No volume group for id " + groupId); 4154 } 4155 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4156 return vgs.getMinIndex(); 4157 } 4158 } 4159 4160 @Override 4161 @android.annotation.EnforcePermission(anyOf = { 4162 MODIFY_AUDIO_ROUTING, MODIFY_AUDIO_SETTINGS_PRIVILEGED }) 4163 /** @see AudioDeviceVolumeManager#setDeviceVolume(VolumeInfo, AudioDeviceAttributes) 4164 * Part of service interface, check permissions and parameters here 4165 * Note calling package is for logging purposes only, not to be trusted 4166 */ setDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)4167 public void setDeviceVolume(@NonNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, 4168 @NonNull String callingPackage) { 4169 super.setDeviceVolume_enforcePermission(); 4170 Objects.requireNonNull(vi); 4171 Objects.requireNonNull(ada); 4172 Objects.requireNonNull(callingPackage); 4173 4174 if (!vi.hasStreamType()) { 4175 Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception()); 4176 return; 4177 } 4178 4179 int index = vi.getVolumeIndex(); 4180 if (index == VolumeInfo.INDEX_NOT_SET && !vi.hasMuteCommand()) { 4181 throw new IllegalArgumentException( 4182 "changing device volume requires a volume index or mute command"); 4183 } 4184 4185 // force a cache clear to force reevaluating stream type to audio device selection 4186 // that can interfere with the sending of the VOLUME_CHANGED_ACTION intent 4187 mAudioSystem.clearRoutingCache(); 4188 4189 // log the current device that will be used when evaluating the sending of the 4190 // VOLUME_CHANGED_ACTION intent to see if the current device is the one being modified 4191 final int currDev = getDeviceForStream(vi.getStreamType()); 4192 4193 final boolean skipping = (currDev == ada.getInternalType()); 4194 4195 AudioService.sVolumeLogger.enqueue(new DeviceVolumeEvent(vi.getStreamType(), index, ada, 4196 currDev, callingPackage, skipping)); 4197 4198 if (skipping) { 4199 // setDeviceVolume was called on a device currently being used 4200 return; 4201 } 4202 4203 // TODO handle unmuting of current audio device 4204 // if a stream is not muted but the VolumeInfo is for muting, set the volume index 4205 // for the device to min volume 4206 if (vi.hasMuteCommand() && vi.isMuted() && !isStreamMute(vi.getStreamType())) { 4207 setStreamVolumeWithAttributionInt(vi.getStreamType(), 4208 mStreamStates[vi.getStreamType()].getMinIndex(), 4209 /*flags*/ 0, 4210 ada, callingPackage, null, 4211 //TODO handle unmuting of current audio device 4212 false /*canChangeMuteAndUpdateController*/); 4213 return; 4214 } 4215 4216 AudioService.sVolumeLogger.enqueueAndLog("setDeviceVolume" + " from:" + callingPackage 4217 + " " + vi + " " + ada, EventLogger.Event.ALOGI, TAG); 4218 4219 if (vi.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET 4220 || vi.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) { 4221 // assume index meant to be in stream type range, validate 4222 if ((index * 10) < mStreamStates[vi.getStreamType()].getMinIndex() 4223 || (index * 10) > mStreamStates[vi.getStreamType()].getMaxIndex()) { 4224 throw new IllegalArgumentException("invalid volume index " + index 4225 + " not between min/max for stream " + vi.getStreamType()); 4226 } 4227 } else { 4228 // check if index needs to be rescaled 4229 final int min = (mStreamStates[vi.getStreamType()].getMinIndex() + 5) / 10; 4230 final int max = (mStreamStates[vi.getStreamType()].getMaxIndex() + 5) / 10; 4231 if (vi.getMinVolumeIndex() != min || vi.getMaxVolumeIndex() != max) { 4232 index = rescaleIndex(index, 4233 /*srcMin*/ vi.getMinVolumeIndex(), /*srcMax*/ vi.getMaxVolumeIndex(), 4234 /*dstMin*/ min, /*dstMax*/ max); 4235 } 4236 } 4237 setStreamVolumeWithAttributionInt(vi.getStreamType(), index, /*flags*/ 0, 4238 ada, callingPackage, null, 4239 false /*canChangeMuteAndUpdateController*/); 4240 } 4241 4242 /** Retain API for unsupported app usage */ setStreamVolume(int streamType, int index, int flags, String callingPackage)4243 public void setStreamVolume(int streamType, int index, int flags, String callingPackage) { 4244 setStreamVolumeWithAttribution(streamType, index, flags, 4245 callingPackage, /*attributionTag*/ null); 4246 } 4247 4248 /** @see AudioManager#adjustVolumeGroupVolume(int, int, int) */ adjustVolumeGroupVolume(int groupId, int direction, int flags, String callingPackage)4249 public void adjustVolumeGroupVolume(int groupId, int direction, int flags, 4250 String callingPackage) { 4251 ensureValidDirection(direction); 4252 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4253 Log.e(TAG, ": no volume group found for id " + groupId); 4254 return; 4255 } 4256 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4257 // For compatibility reason, use stream API if group linked to a valid stream 4258 boolean fallbackOnStream = false; 4259 for (int stream : vgs.getLegacyStreamTypes()) { 4260 try { 4261 ensureValidStreamType(stream); 4262 } catch (IllegalArgumentException e) { 4263 Log.d(TAG, "volume group " + groupId + " has internal streams (" + stream 4264 + "), do not change associated stream volume"); 4265 continue; 4266 } 4267 // Note: Group and Stream does not share same convention, 0 is mute for stream, 4268 // min index is acting as mute for Groups 4269 if (vgs.isVssMuteBijective(stream)) { 4270 adjustStreamVolume(stream, direction, flags, callingPackage); 4271 if (isMuteAdjust(direction)) { 4272 // will be propagated to all aliased streams 4273 return; 4274 } 4275 fallbackOnStream = true; 4276 } 4277 } 4278 if (fallbackOnStream) { 4279 // Handled by at least one stream, will be propagated to group, bailing out. 4280 return; 4281 } 4282 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_GROUP_VOL, vgs.name(), 4283 direction, flags, callingPackage)); 4284 vgs.adjustVolume(direction, flags); 4285 } 4286 4287 /** @see AudioManager#getLastAudibleVolumeForVolumeGroup(int) */ 4288 @android.annotation.EnforcePermission(QUERY_AUDIO_STATE) getLastAudibleVolumeForVolumeGroup(int groupId)4289 public int getLastAudibleVolumeForVolumeGroup(int groupId) { 4290 super.getLastAudibleVolumeForVolumeGroup_enforcePermission(); 4291 synchronized (VolumeStreamState.class) { 4292 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4293 Log.e(TAG, ": no volume group found for id " + groupId); 4294 return 0; 4295 } 4296 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4297 return vgs.getVolumeIndex(); 4298 } 4299 } 4300 4301 /** @see AudioManager#isVolumeGroupMuted(int) */ isVolumeGroupMuted(int groupId)4302 public boolean isVolumeGroupMuted(int groupId) { 4303 synchronized (VolumeStreamState.class) { 4304 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4305 Log.e(TAG, ": no volume group found for id " + groupId); 4306 return false; 4307 } 4308 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4309 return vgs.isMuted(); 4310 } 4311 } 4312 4313 /** @see AudioManager#setStreamVolume(int, int, int) 4314 * Part of service interface, check permissions here */ setStreamVolumeWithAttribution(int streamType, int index, int flags, String callingPackage, String attributionTag)4315 public void setStreamVolumeWithAttribution(int streamType, int index, int flags, 4316 String callingPackage, String attributionTag) { 4317 if (mHardeningEnforcer.blockVolumeMethod( 4318 HardeningEnforcer.METHOD_AUDIO_MANAGER_SET_STREAM_VOLUME)) { 4319 return; 4320 } 4321 setStreamVolumeWithAttributionInt(streamType, index, flags, /*device*/ null, 4322 callingPackage, attributionTag, true /*canChangeMuteAndUpdateController*/); 4323 } 4324 4325 /** 4326 * Internal method for a stream type volume change. Can be used to change the volume on a 4327 * given device only 4328 * @param streamType the stream type whose volume is to be changed 4329 * @param index the volume index 4330 * @param flags options for volume handling 4331 * @param device null when controlling volume for the current routing, otherwise the device 4332 * for which volume is being changed 4333 * @param callingPackage client side-provided package name of caller, not to be trusted 4334 * @param attributionTag client side-provided attribution name, not to be trusted 4335 * @param canChangeMuteAndUpdateController true if the calling method is a path where 4336 * the volume change is allowed to update the mute state as well as update 4337 * the volume controller (the UI). This is intended to be true for a call coming 4338 * from AudioManager.setStreamVolume (which is here 4339 * {@link #setStreamVolumeForUid(int, int, int, String, int, int, UserHandle, int)}, 4340 * and false when coming from AudioDeviceVolumeManager.setDeviceVolume (which is here 4341 * {@link #setDeviceVolume(VolumeInfo, AudioDeviceAttributes, String)} 4342 */ setStreamVolumeWithAttributionInt(int streamType, int index, int flags, @Nullable AudioDeviceAttributes ada, String callingPackage, String attributionTag, boolean canChangeMuteAndUpdateController)4343 protected void setStreamVolumeWithAttributionInt(int streamType, int index, int flags, 4344 @Nullable AudioDeviceAttributes ada, 4345 String callingPackage, String attributionTag, 4346 boolean canChangeMuteAndUpdateController) { 4347 if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { 4348 Log.w(TAG, "Trying to call setStreamVolume() for a11y without" 4349 + " CHANGE_ACCESSIBILITY_VOLUME callingPackage=" + callingPackage); 4350 return; 4351 } 4352 if ((streamType == AudioManager.STREAM_VOICE_CALL) && (index == 0) 4353 && (mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE) 4354 != PackageManager.PERMISSION_GRANTED)) { 4355 Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL and index 0 without" 4356 + " MODIFY_PHONE_STATE callingPackage=" + callingPackage); 4357 return; 4358 } 4359 if ((streamType == AudioManager.STREAM_ASSISTANT) 4360 && (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING) 4361 != PackageManager.PERMISSION_GRANTED)) { 4362 Log.w(TAG, "Trying to call setStreamVolume() for STREAM_ASSISTANT without" 4363 + " MODIFY_AUDIO_ROUTING callingPackage=" + callingPackage); 4364 return; 4365 } 4366 4367 if (ada == null) { 4368 // call was already logged in setDeviceVolume() 4369 final int deviceType = getDeviceForStream(streamType); 4370 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType, 4371 index/*val1*/, flags/*val2*/, getStreamVolume(streamType, deviceType) /*val3*/, 4372 callingPackage)); 4373 ada = new AudioDeviceAttributes(deviceType /*nativeType*/, "" /*address*/); 4374 } 4375 setStreamVolume(streamType, index, flags, ada, 4376 callingPackage, callingPackage, attributionTag, 4377 Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission(), 4378 canChangeMuteAndUpdateController); 4379 } 4380 4381 @android.annotation.EnforcePermission(Manifest.permission.ACCESS_ULTRASOUND) 4382 /** @see AudioManager#isUltrasoundSupported() */ isUltrasoundSupported()4383 public boolean isUltrasoundSupported() { 4384 super.isUltrasoundSupported_enforcePermission(); 4385 4386 return AudioSystem.isUltrasoundSupported(); 4387 } 4388 4389 /** @see AudioManager#isHotwordStreamSupported(boolean) */ 4390 @android.annotation.EnforcePermission(CAPTURE_AUDIO_HOTWORD) isHotwordStreamSupported(boolean lookbackAudio)4391 public boolean isHotwordStreamSupported(boolean lookbackAudio) { 4392 super.isHotwordStreamSupported_enforcePermission(); 4393 try { 4394 return mAudioPolicy.isHotwordStreamSupported(lookbackAudio); 4395 } catch (IllegalStateException e) { 4396 // Suppress connection failure to APM, since the method is purely informative 4397 Log.e(TAG, "Suppressing exception calling into AudioPolicy", e); 4398 return false; 4399 } 4400 } 4401 4402 canChangeAccessibilityVolume()4403 private boolean canChangeAccessibilityVolume() { 4404 synchronized (mAccessibilityServiceUidsLock) { 4405 if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 4406 Manifest.permission.CHANGE_ACCESSIBILITY_VOLUME)) { 4407 return true; 4408 } 4409 if (mAccessibilityServiceUids != null) { 4410 int callingUid = Binder.getCallingUid(); 4411 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 4412 if (mAccessibilityServiceUids[i] == callingUid) { 4413 return true; 4414 } 4415 } 4416 } 4417 return false; 4418 } 4419 } 4420 4421 /** only public for mocking/spying, do not call outside of AudioService */ 4422 @VisibleForTesting getBluetoothContextualVolumeStream()4423 public int getBluetoothContextualVolumeStream() { 4424 return getBluetoothContextualVolumeStream(mMode.get()); 4425 } 4426 getBluetoothContextualVolumeStream(int mode)4427 private int getBluetoothContextualVolumeStream(int mode) { 4428 boolean voiceActivityCanOverride = true; 4429 switch (mode) { 4430 case AudioSystem.MODE_IN_COMMUNICATION: 4431 case AudioSystem.MODE_IN_CALL: 4432 return AudioSystem.STREAM_VOICE_CALL; 4433 case AudioSystem.MODE_CALL_SCREENING: 4434 case AudioSystem.MODE_COMMUNICATION_REDIRECT: 4435 case AudioSystem.MODE_CALL_REDIRECT: 4436 voiceActivityCanOverride = false; 4437 // intended fallthrough 4438 case AudioSystem.MODE_NORMAL: 4439 default: 4440 // other conditions will influence the stream type choice, read on... 4441 break; 4442 } 4443 if (voiceActivityCanOverride 4444 && mVoicePlaybackActive.get()) { 4445 return AudioSystem.STREAM_VOICE_CALL; 4446 } 4447 return AudioSystem.STREAM_MUSIC; 4448 } 4449 4450 private AtomicBoolean mVoicePlaybackActive = new AtomicBoolean(false); 4451 private AtomicBoolean mMediaPlaybackActive = new AtomicBoolean(false); 4452 4453 private final IPlaybackConfigDispatcher mPlaybackActivityMonitor = 4454 new IPlaybackConfigDispatcher.Stub() { 4455 @Override 4456 public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs, 4457 boolean flush) { 4458 sendMsg(mAudioHandler, MSG_PLAYBACK_CONFIG_CHANGE, SENDMSG_REPLACE, 4459 0 /*arg1 ignored*/, 0 /*arg2 ignored*/, 4460 configs /*obj*/, 0 /*delay*/); 4461 } 4462 }; 4463 onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs)4464 private void onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) { 4465 boolean voiceActive = false; 4466 boolean mediaActive = false; 4467 for (AudioPlaybackConfiguration config : configs) { 4468 final int usage = config.getAudioAttributes().getUsage(); 4469 if (!config.isActive()) { 4470 continue; 4471 } 4472 if (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION 4473 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) { 4474 voiceActive = true; 4475 } 4476 if (usage == AudioAttributes.USAGE_MEDIA || usage == AudioAttributes.USAGE_GAME 4477 || usage == AudioAttributes.USAGE_UNKNOWN) { 4478 mediaActive = true; 4479 } 4480 } 4481 if (mVoicePlaybackActive.getAndSet(voiceActive) != voiceActive) { 4482 updateHearingAidVolumeOnVoiceActivityUpdate(); 4483 } 4484 if (mMediaPlaybackActive.getAndSet(mediaActive) != mediaActive && mediaActive) { 4485 mSoundDoseHelper.scheduleMusicActiveCheck(); 4486 } 4487 4488 mLoudnessCodecHelper.updateCodecParameters(configs); 4489 4490 // Update playback active state for all apps in audio mode stack. 4491 // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE 4492 // and request an audio mode update immediately. Upon any other change, queue the message 4493 // and request an audio mode update after a grace period. 4494 updateAudioModeHandlers( 4495 configs /* playbackConfigs */, null /* recordConfigs */); 4496 mDeviceBroker.updateCommunicationRouteClientsActivity( 4497 configs /* playbackConfigs */, null /* recordConfigs */); 4498 } 4499 updateAudioModeHandlers(List<AudioPlaybackConfiguration> playbackConfigs, List<AudioRecordingConfiguration> recordConfigs)4500 void updateAudioModeHandlers(List<AudioPlaybackConfiguration> playbackConfigs, 4501 List<AudioRecordingConfiguration> recordConfigs) { 4502 synchronized (mDeviceBroker.mSetModeLock) { 4503 boolean updateAudioMode = false; 4504 int existingMsgPolicy = SENDMSG_QUEUE; 4505 int delay = CHECK_MODE_FOR_UID_PERIOD_MS; 4506 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 4507 boolean wasActive = h.isActive(); 4508 if (playbackConfigs != null) { 4509 h.setPlaybackActive(false); 4510 for (AudioPlaybackConfiguration config : playbackConfigs) { 4511 final int usage = config.getAudioAttributes().getUsage(); 4512 if (config.getClientUid() == h.getUid() 4513 && (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION 4514 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) 4515 && config.isActive()) { 4516 h.setPlaybackActive(true); 4517 break; 4518 } 4519 } 4520 } 4521 if (recordConfigs != null) { 4522 h.setRecordingActive(false); 4523 for (AudioRecordingConfiguration config : recordConfigs) { 4524 if (config.getClientUid() == h.getUid() && !config.isClientSilenced() 4525 && config.getAudioSource() == AudioSource.VOICE_COMMUNICATION) { 4526 h.setRecordingActive(true); 4527 break; 4528 } 4529 } 4530 } 4531 if (wasActive != h.isActive()) { 4532 updateAudioMode = true; 4533 if (h.isActive() && h == getAudioModeOwnerHandler()) { 4534 existingMsgPolicy = SENDMSG_REPLACE; 4535 delay = 0; 4536 } 4537 } 4538 } 4539 if (updateAudioMode) { 4540 sendMsg(mAudioHandler, 4541 MSG_UPDATE_AUDIO_MODE, 4542 existingMsgPolicy, 4543 AudioSystem.MODE_CURRENT, 4544 android.os.Process.myPid(), 4545 mContext.getPackageName(), 4546 delay); 4547 } 4548 } 4549 } 4550 4551 private final IRecordingConfigDispatcher mVoiceRecordingActivityMonitor = 4552 new IRecordingConfigDispatcher.Stub() { 4553 @Override 4554 public void dispatchRecordingConfigChange(List<AudioRecordingConfiguration> configs) { 4555 sendMsg(mAudioHandler, MSG_RECORDING_CONFIG_CHANGE, SENDMSG_REPLACE, 4556 0 /*arg1 ignored*/, 0 /*arg2 ignored*/, 4557 configs /*obj*/, 0 /*delay*/); 4558 } 4559 }; 4560 onRecordingConfigChange(List<AudioRecordingConfiguration> configs)4561 private void onRecordingConfigChange(List<AudioRecordingConfiguration> configs) { 4562 // Update recording active state for all apps in audio mode stack. 4563 // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE 4564 // and request an audio mode update immediately. Upon any other change, queue the message 4565 // and request an audio mode update after a grace period. 4566 updateAudioModeHandlers( 4567 null /* playbackConfigs */, configs /* recordConfigs */); 4568 mDeviceBroker.updateCommunicationRouteClientsActivity( 4569 null /* playbackConfigs */, configs /* recordConfigs */); 4570 } 4571 dumpFlags(PrintWriter pw)4572 private void dumpFlags(PrintWriter pw) { 4573 4574 pw.println("\nFun with Flags:"); 4575 pw.println("\tandroid.media.audio.autoPublicVolumeApiHardening:" 4576 + autoPublicVolumeApiHardening()); 4577 pw.println("\tandroid.media.audio.Flags.automaticBtDeviceType:" 4578 + automaticBtDeviceType()); 4579 pw.println("\tandroid.media.audio.featureSpatialAudioHeadtrackingLowLatency:" 4580 + featureSpatialAudioHeadtrackingLowLatency()); 4581 pw.println("\tandroid.media.audio.focusFreezeTestApi:" 4582 + focusFreezeTestApi()); 4583 pw.println("\tcom.android.media.audio.audioserverPermissions:" 4584 + audioserverPermissions()); 4585 pw.println("\tcom.android.media.audio.disablePrescaleAbsoluteVolume:" 4586 + disablePrescaleAbsoluteVolume()); 4587 pw.println("\tcom.android.media.audio.setStreamVolumeOrder:" 4588 + setStreamVolumeOrder()); 4589 pw.println("\tandroid.media.audio.roForegroundAudioControl:" 4590 + roForegroundAudioControl()); 4591 pw.println("\tandroid.media.audio.scoManagedByAudio:" 4592 + scoManagedByAudio()); 4593 pw.println("\tcom.android.media.audio.vgsVssSyncMuteOrder:" 4594 + vgsVssSyncMuteOrder()); 4595 pw.println("\tcom.android.media.audio.absVolumeIndexFix:" 4596 + absVolumeIndexFix()); 4597 } 4598 dumpAudioMode(PrintWriter pw)4599 private void dumpAudioMode(PrintWriter pw) { 4600 pw.println("\nAudio mode: "); 4601 pw.println("- Requested mode = " + AudioSystem.modeToString(getMode())); 4602 pw.println("- Actual mode = " + AudioSystem.modeToString(mMode.get())); 4603 pw.println("- Mode owner: "); 4604 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 4605 if (hdlr != null) { 4606 hdlr.dump(pw, -1); 4607 } else { 4608 pw.println(" None"); 4609 } 4610 pw.println("- Mode owner stack: "); 4611 if (mSetModeDeathHandlers.isEmpty()) { 4612 pw.println(" Empty"); 4613 } else { 4614 for (int i = 0; i < mSetModeDeathHandlers.size(); i++) { 4615 mSetModeDeathHandlers.get(i).dump(pw, i); 4616 } 4617 } 4618 } 4619 updateHearingAidVolumeOnVoiceActivityUpdate()4620 private void updateHearingAidVolumeOnVoiceActivityUpdate() { 4621 final int streamType = getBluetoothContextualVolumeStream(); 4622 final int index = getStreamVolume(streamType); 4623 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_HEARING_AID, 4624 mVoicePlaybackActive.get(), streamType, index)); 4625 mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType); 4626 4627 } 4628 4629 /** 4630 * Manage an audio mode change for audio devices that use an "absolute volume" model, 4631 * i.e. the framework sends the full scale signal, and the actual volume for the use case 4632 * is communicated separately. 4633 */ updateAbsVolumeMultiModeDevices(int oldMode, int newMode)4634 void updateAbsVolumeMultiModeDevices(int oldMode, int newMode) { 4635 if (oldMode == newMode) { 4636 return; 4637 } 4638 switch (newMode) { 4639 case AudioSystem.MODE_IN_COMMUNICATION: 4640 case AudioSystem.MODE_IN_CALL: 4641 case AudioSystem.MODE_NORMAL: 4642 case AudioSystem.MODE_CALL_SCREENING: 4643 case AudioSystem.MODE_CALL_REDIRECT: 4644 case AudioSystem.MODE_COMMUNICATION_REDIRECT: 4645 break; 4646 default: 4647 // no-op is enough for all other values 4648 return; 4649 } 4650 4651 int streamType = getBluetoothContextualVolumeStream(newMode); 4652 4653 final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType); 4654 final Set<Integer> absVolumeMultiModeCaseDevices = AudioSystem.intersectionAudioDeviceTypes( 4655 mAbsVolumeMultiModeCaseDevices, deviceTypes); 4656 if (absVolumeMultiModeCaseDevices.isEmpty()) { 4657 return; 4658 } 4659 4660 // handling of specific interfaces goes here: 4661 if (AudioSystem.isSingleAudioDeviceType( 4662 absVolumeMultiModeCaseDevices, AudioSystem.DEVICE_OUT_HEARING_AID)) { 4663 final int index = getStreamVolume(streamType); 4664 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID, 4665 newMode, streamType, index)); 4666 mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType); 4667 } 4668 } 4669 setLeAudioVolumeOnModeUpdate(int mode, int device, int streamType, int index, int maxIndex)4670 private void setLeAudioVolumeOnModeUpdate(int mode, int device, int streamType, int index, 4671 int maxIndex) { 4672 switch (mode) { 4673 case AudioSystem.MODE_IN_COMMUNICATION: 4674 case AudioSystem.MODE_IN_CALL: 4675 case AudioSystem.MODE_NORMAL: 4676 case AudioSystem.MODE_CALL_SCREENING: 4677 case AudioSystem.MODE_CALL_REDIRECT: 4678 case AudioSystem.MODE_COMMUNICATION_REDIRECT: 4679 case AudioSystem.MODE_RINGTONE: 4680 break; 4681 default: 4682 // no-op is enough for all other values 4683 return; 4684 } 4685 4686 // In some cases (like the outgoing or rejected call) the value of 'device' is not 4687 // DEVICE_OUT_BLE_* even when BLE is connected. Changing the volume level in such case 4688 // may cuase the other devices volume level leaking into the LeAudio device settings. 4689 if (!AudioSystem.isLeAudioDeviceType(device)) { 4690 Log.w(TAG, "setLeAudioVolumeOnModeUpdate ignoring invalid device=" 4691 + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex 4692 + " streamType=" + streamType); 4693 return; 4694 } 4695 4696 if (DEBUG_VOL) { 4697 Log.d(TAG, "setLeAudioVolumeOnModeUpdate postSetLeAudioVolumeIndex device=" 4698 + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex 4699 + " streamType=" + streamType); 4700 } 4701 mDeviceBroker.postSetLeAudioVolumeIndex(index, maxIndex, streamType); 4702 mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "setLeAudioVolumeOnModeUpdate"); 4703 } 4704 setStreamVolume(int streamType, int index, int flags, @Nullable AudioDeviceAttributes ada, String callingPackage, String caller, String attributionTag, int uid, boolean hasModifyAudioSettings, boolean canChangeMuteAndUpdateController)4705 private void setStreamVolume(int streamType, int index, int flags, 4706 @Nullable AudioDeviceAttributes ada, 4707 String callingPackage, String caller, String attributionTag, int uid, 4708 boolean hasModifyAudioSettings, 4709 boolean canChangeMuteAndUpdateController) { 4710 4711 if (DEBUG_VOL) { 4712 Log.d(TAG, "setStreamVolume(stream=" + streamType+", index=" + index 4713 + ", dev=" + ada 4714 + ", calling=" + callingPackage + ")"); 4715 } 4716 if (mUseFixedVolume) { 4717 return; 4718 } 4719 4720 ensureValidStreamType(streamType); 4721 int streamTypeAlias = mStreamVolumeAlias[streamType]; 4722 VolumeStreamState streamState = mStreamStates[streamTypeAlias]; 4723 4724 if ((streamType == AudioManager.STREAM_VOICE_CALL) 4725 && isInCommunication() && mDeviceBroker.isBluetoothScoActive()) { 4726 Log.i(TAG, "setStreamVolume for STREAM_VOICE_CALL, switching to STREAM_BLUETOOTH_SCO"); 4727 streamType = AudioManager.STREAM_BLUETOOTH_SCO; 4728 } 4729 4730 final int device = (ada == null) 4731 ? getDeviceForStream(streamType) 4732 : ada.getInternalType(); 4733 int oldIndex; 4734 4735 // skip a2dp absolute volume control request when the device 4736 // is neither an a2dp device nor BLE device 4737 if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 4738 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device)) 4739 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { 4740 return; 4741 } 4742 // If we are being called by the system (e.g. hardware keys) check for current user 4743 // so we handle user restrictions correctly. 4744 if (uid == android.os.Process.SYSTEM_UID) { 4745 uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); 4746 } 4747 if (!checkNoteAppOp( 4748 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) { 4749 return; 4750 } 4751 4752 if (isAndroidNPlus(callingPackage) 4753 && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags)) 4754 && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) { 4755 throw new SecurityException("Not allowed to change Do Not Disturb state"); 4756 } 4757 4758 if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) { 4759 return; 4760 } 4761 4762 mSoundDoseHelper.invalidatePendingVolumeCommand(); 4763 4764 oldIndex = streamState.getIndex(device); 4765 4766 index = rescaleIndex(index * 10, streamType, streamTypeAlias); 4767 4768 if (setStreamVolumeOrder()) { 4769 flags &= ~AudioManager.FLAG_FIXED_VOLUME; 4770 if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) { 4771 flags |= AudioManager.FLAG_FIXED_VOLUME; 4772 4773 // volume is either 0 or max allowed for fixed volume devices 4774 if (index != 0) { 4775 index = mSoundDoseHelper.getSafeMediaVolumeIndex(device); 4776 if (index < 0) { 4777 index = streamState.getMaxIndex(); 4778 } 4779 } 4780 } 4781 4782 if (!mSoundDoseHelper.willDisplayWarningAfterCheckVolume(streamType, index, device, 4783 flags)) { 4784 onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings, 4785 // ada is non-null when called from setDeviceVolume, 4786 // which shouldn't update the mute state 4787 canChangeMuteAndUpdateController /*canChangeMute*/); 4788 index = mStreamStates[streamType].getIndex(device); 4789 } 4790 } 4791 4792 int streamToDriveAbsVol = absVolumeIndexFix() ? getBluetoothContextualVolumeStream() : 4793 AudioSystem.STREAM_MUSIC; 4794 if (streamTypeAlias == streamToDriveAbsVol 4795 && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 4796 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 4797 if (DEBUG_VOL) { 4798 Log.d(TAG, "setStreamVolume postSetAvrcpAbsoluteVolumeIndex index=" + index 4799 + "stream=" + streamType); 4800 } 4801 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10); 4802 } else if (isAbsoluteVolumeDevice(device) 4803 && ((flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0)) { 4804 AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device); 4805 4806 dispatchAbsoluteVolumeChanged(streamType, info, index); 4807 } 4808 4809 if (AudioSystem.isLeAudioDeviceType(device) 4810 && streamType == getBluetoothContextualVolumeStream() 4811 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 4812 if (DEBUG_VOL) { 4813 Log.d(TAG, "setStreamVolume postSetLeAudioVolumeIndex index=" 4814 + index + " stream=" + streamType); 4815 } 4816 mDeviceBroker.postSetLeAudioVolumeIndex(index, mStreamStates[streamType].getMaxIndex(), 4817 streamType); 4818 } 4819 4820 if (device == AudioSystem.DEVICE_OUT_HEARING_AID 4821 && streamType == getBluetoothContextualVolumeStream()) { 4822 Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index 4823 + " stream=" + streamType); 4824 mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType); 4825 } 4826 4827 if (!setStreamVolumeOrder()) { 4828 flags &= ~AudioManager.FLAG_FIXED_VOLUME; 4829 if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) { 4830 flags |= AudioManager.FLAG_FIXED_VOLUME; 4831 4832 // volume is either 0 or max allowed for fixed volume devices 4833 if (index != 0) { 4834 index = mSoundDoseHelper.getSafeMediaVolumeIndex(device); 4835 if (index < 0) { 4836 index = streamState.getMaxIndex(); 4837 } 4838 } 4839 } 4840 4841 if (!mSoundDoseHelper.willDisplayWarningAfterCheckVolume(streamType, index, device, 4842 flags)) { 4843 onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings, 4844 // ada is non-null when called from setDeviceVolume, 4845 // which shouldn't update the mute state 4846 canChangeMuteAndUpdateController /*canChangeMute*/); 4847 index = mStreamStates[streamType].getIndex(device); 4848 } 4849 } 4850 4851 synchronized (mHdmiClientLock) { 4852 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 4853 && (oldIndex != index)) { 4854 maybeSendSystemAudioStatusCommand(false); 4855 } 4856 } 4857 if (canChangeMuteAndUpdateController) { 4858 // only non-null when coming here from setDeviceVolume 4859 // TODO change test to check early if device is current device or not 4860 sendVolumeUpdate(streamType, oldIndex, index, flags, device); 4861 } 4862 } 4863 dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index)4864 private void dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, 4865 int index) { 4866 VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType); 4867 if (volumeInfo != null) { 4868 try { 4869 deviceInfo.mCallback.dispatchDeviceVolumeChanged(deviceInfo.mDevice, 4870 new VolumeInfo.Builder(volumeInfo) 4871 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo)) 4872 .build()); 4873 } catch (RemoteException e) { 4874 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume change"); 4875 } 4876 } 4877 } 4878 dispatchAbsoluteVolumeAdjusted(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode)4879 private void dispatchAbsoluteVolumeAdjusted(int streamType, 4880 AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode) { 4881 VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType); 4882 if (volumeInfo != null) { 4883 try { 4884 deviceInfo.mCallback.dispatchDeviceVolumeAdjusted(deviceInfo.mDevice, 4885 new VolumeInfo.Builder(volumeInfo) 4886 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo)) 4887 .build(), 4888 direction, 4889 mode); 4890 } catch (RemoteException e) { 4891 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume adjustment"); 4892 } 4893 } 4894 } 4895 4896 // No ringer or zen muted stream volumes can be changed unless it'll exit dnd volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags)4897 private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) { 4898 switch (mNm.getZenMode()) { 4899 case Settings.Global.ZEN_MODE_OFF: 4900 return true; 4901 case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: 4902 case Settings.Global.ZEN_MODE_ALARMS: 4903 case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: 4904 return !isStreamMutedByRingerOrZenMode(streamTypeAlias) 4905 || isUiSoundsStreamType(streamTypeAlias) 4906 || (flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0; 4907 } 4908 4909 return true; 4910 } 4911 4912 /** @see AudioManager#forceVolumeControlStream(int) */ forceVolumeControlStream(int streamType, IBinder cb)4913 public void forceVolumeControlStream(int streamType, IBinder cb) { 4914 if (mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE) 4915 != PackageManager.PERMISSION_GRANTED) { 4916 return; 4917 } 4918 if (DEBUG_VOL) { Log.d(TAG, String.format("forceVolumeControlStream(%d)", streamType)); } 4919 synchronized(mForceControlStreamLock) { 4920 if (mVolumeControlStream != -1 && streamType != -1) { 4921 mUserSelectedVolumeControlStream = true; 4922 } 4923 mVolumeControlStream = streamType; 4924 if (mVolumeControlStream == -1) { 4925 if (mForceControlStreamClient != null) { 4926 mForceControlStreamClient.release(); 4927 mForceControlStreamClient = null; 4928 } 4929 mUserSelectedVolumeControlStream = false; 4930 } else { 4931 if (null == mForceControlStreamClient) { 4932 mForceControlStreamClient = new ForceControlStreamClient(cb); 4933 } else { 4934 if (mForceControlStreamClient.getBinder() == cb) { 4935 Log.d(TAG, "forceVolumeControlStream cb:" + cb + " is already linked."); 4936 } else { 4937 mForceControlStreamClient.release(); 4938 mForceControlStreamClient = new ForceControlStreamClient(cb); 4939 } 4940 } 4941 } 4942 } 4943 } 4944 4945 private class ForceControlStreamClient implements IBinder.DeathRecipient { 4946 private IBinder mCb; // To be notified of client's death 4947 ForceControlStreamClient(IBinder cb)4948 ForceControlStreamClient(IBinder cb) { 4949 if (cb != null) { 4950 try { 4951 cb.linkToDeath(this, 0); 4952 } catch (RemoteException e) { 4953 // Client has died! 4954 Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death"); 4955 cb = null; 4956 } 4957 } 4958 mCb = cb; 4959 } 4960 binderDied()4961 public void binderDied() { 4962 synchronized(mForceControlStreamLock) { 4963 Log.w(TAG, "SCO client died"); 4964 if (mForceControlStreamClient != this) { 4965 Log.w(TAG, "unregistered control stream client died"); 4966 } else { 4967 mForceControlStreamClient = null; 4968 mVolumeControlStream = -1; 4969 mUserSelectedVolumeControlStream = false; 4970 } 4971 } 4972 } 4973 release()4974 public void release() { 4975 if (mCb != null) { 4976 mCb.unlinkToDeath(this, 0); 4977 mCb = null; 4978 } 4979 } 4980 getBinder()4981 public IBinder getBinder() { 4982 return mCb; 4983 } 4984 } 4985 sendBroadcastToAll(Intent intent, Bundle options)4986 private void sendBroadcastToAll(Intent intent, Bundle options) { 4987 if (!mSystemServer.isPrivileged()) { 4988 return; 4989 } 4990 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 4991 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 4992 final long ident = Binder.clearCallingIdentity(); 4993 try { 4994 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 4995 null /* receiverPermission */, options); 4996 } finally { 4997 Binder.restoreCallingIdentity(ident); 4998 } 4999 } 5000 sendStickyBroadcastToAll(Intent intent)5001 private void sendStickyBroadcastToAll(Intent intent) { 5002 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 5003 final long ident = Binder.clearCallingIdentity(); 5004 try { 5005 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 5006 } finally { 5007 Binder.restoreCallingIdentity(ident); 5008 } 5009 } 5010 getCurrentUserId()5011 private int getCurrentUserId() { 5012 final long ident = Binder.clearCallingIdentity(); 5013 try { 5014 UserInfo currentUser = ActivityManager.getService().getCurrentUser(); 5015 return currentUser.id; 5016 } catch (RemoteException e) { 5017 // Activity manager not running, nothing we can do assume user 0. 5018 } finally { 5019 Binder.restoreCallingIdentity(ident); 5020 } 5021 return UserHandle.USER_SYSTEM; 5022 } 5023 5024 // UI update and Broadcast Intent sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)5025 protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device) 5026 { 5027 streamType = mStreamVolumeAlias[streamType]; 5028 5029 if (streamType == AudioSystem.STREAM_MUSIC && isFullVolumeDevice(device)) { 5030 flags &= ~AudioManager.FLAG_SHOW_UI; 5031 } 5032 mVolumeController.postVolumeChanged(streamType, flags); 5033 } 5034 5035 // Don't show volume UI when: 5036 // - Hdmi-CEC system audio mode is on and we are a TV panel updateFlagsForTvPlatform(int flags)5037 private int updateFlagsForTvPlatform(int flags) { 5038 synchronized (mHdmiClientLock) { 5039 if (mHdmiTvClient != null && mHdmiSystemAudioSupported 5040 && mHdmiCecVolumeControlEnabled) { 5041 flags &= ~AudioManager.FLAG_SHOW_UI; 5042 } 5043 } 5044 return flags; 5045 } 5046 // UI update and Broadcast Intent sendMasterMuteUpdate(boolean muted, int flags)5047 private void sendMasterMuteUpdate(boolean muted, int flags) { 5048 mVolumeController.postMasterMuteChanged(updateFlagsForTvPlatform(flags)); 5049 sendMsg(mAudioHandler, MSG_BROADCAST_MASTER_MUTE, 5050 SENDMSG_QUEUE, muted ? 1 : 0, 0, null, 0); 5051 } 5052 5053 5054 /** 5055 * Sets the stream state's index, and posts a message to set system volume. 5056 * This will not call out to the UI. Assumes a valid stream type. 5057 * 5058 * @param streamType Type of the stream 5059 * @param index Desired volume index of the stream 5060 * @param device the device whose volume must be changed 5061 * @param force If true, set the volume even if the desired volume is same 5062 * @param caller 5063 * @param hasModifyAudioSettings true if the caller is granted MODIFY_AUDIO_SETTINGS or 5064 * MODIFY_AUDIO_ROUTING permission 5065 * as the current volume. 5066 */ setStreamVolumeInt(int streamType, int index, int device, boolean force, String caller, boolean hasModifyAudioSettings)5067 private void setStreamVolumeInt(int streamType, 5068 int index, 5069 int device, 5070 boolean force, 5071 String caller, boolean hasModifyAudioSettings) { 5072 if (isFullVolumeDevice(device)) { 5073 return; 5074 } 5075 VolumeStreamState streamState = mStreamStates[streamType]; 5076 5077 if (streamState.setIndex(index, device, caller, hasModifyAudioSettings) || force) { 5078 // Post message to set system volume (it in turn will post a message 5079 // to persist). 5080 sendMsg(mAudioHandler, 5081 MSG_SET_DEVICE_VOLUME, 5082 SENDMSG_QUEUE, 5083 device, 5084 0, 5085 streamState, 5086 0); 5087 } 5088 } 5089 5090 /** get stream mute state. */ isStreamMute(int streamType)5091 public boolean isStreamMute(int streamType) { 5092 if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 5093 streamType = getActiveStreamType(streamType); 5094 } 5095 synchronized (VolumeStreamState.class) { 5096 ensureValidStreamType(streamType); 5097 return mStreamStates[streamType].mIsMuted; 5098 } 5099 } 5100 5101 private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient { 5102 private IBinder mICallback; // To be notified of client's death 5103 RmtSbmxFullVolDeathHandler(IBinder cb)5104 RmtSbmxFullVolDeathHandler(IBinder cb) { 5105 mICallback = cb; 5106 try { 5107 cb.linkToDeath(this, 0/*flags*/); 5108 } catch (RemoteException e) { 5109 Log.e(TAG, "can't link to death", e); 5110 } 5111 } 5112 isHandlerFor(IBinder cb)5113 boolean isHandlerFor(IBinder cb) { 5114 return mICallback.equals(cb); 5115 } 5116 forget()5117 void forget() { 5118 try { 5119 mICallback.unlinkToDeath(this, 0/*flags*/); 5120 } catch (NoSuchElementException e) { 5121 Log.e(TAG, "error unlinking to death", e); 5122 } 5123 } 5124 binderDied()5125 public void binderDied() { 5126 Log.w(TAG, "Recorder with remote submix at full volume died " + mICallback); 5127 forceRemoteSubmixFullVolume(false, mICallback); 5128 } 5129 } 5130 5131 /** 5132 * call must be synchronized on mRmtSbmxFullVolDeathHandlers 5133 * @return true if there is a registered death handler, false otherwise */ discardRmtSbmxFullVolDeathHandlerFor(IBinder cb)5134 private boolean discardRmtSbmxFullVolDeathHandlerFor(IBinder cb) { 5135 Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator(); 5136 while (it.hasNext()) { 5137 final RmtSbmxFullVolDeathHandler handler = it.next(); 5138 if (handler.isHandlerFor(cb)) { 5139 handler.forget(); 5140 mRmtSbmxFullVolDeathHandlers.remove(handler); 5141 return true; 5142 } 5143 } 5144 return false; 5145 } 5146 5147 /** call synchronized on mRmtSbmxFullVolDeathHandlers */ hasRmtSbmxFullVolDeathHandlerFor(IBinder cb)5148 private boolean hasRmtSbmxFullVolDeathHandlerFor(IBinder cb) { 5149 Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator(); 5150 while (it.hasNext()) { 5151 if (it.next().isHandlerFor(cb)) { 5152 return true; 5153 } 5154 } 5155 return false; 5156 } 5157 5158 private int mRmtSbmxFullVolRefCount = 0; 5159 private final ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers = 5160 new ArrayList<RmtSbmxFullVolDeathHandler>(); 5161 forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb)5162 public void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb) { 5163 if (cb == null) { 5164 return; 5165 } 5166 if ((PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 5167 CAPTURE_AUDIO_OUTPUT))) { 5168 Log.w(TAG, "Trying to call forceRemoteSubmixFullVolume() without CAPTURE_AUDIO_OUTPUT"); 5169 return; 5170 } 5171 synchronized(mRmtSbmxFullVolDeathHandlers) { 5172 boolean applyRequired = false; 5173 if (startForcing) { 5174 if (!hasRmtSbmxFullVolDeathHandlerFor(cb)) { 5175 mRmtSbmxFullVolDeathHandlers.add(new RmtSbmxFullVolDeathHandler(cb)); 5176 if (mRmtSbmxFullVolRefCount == 0) { 5177 mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 5178 mFixedVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 5179 applyRequired = true; 5180 } 5181 mRmtSbmxFullVolRefCount++; 5182 } 5183 } else { 5184 if (discardRmtSbmxFullVolDeathHandlerFor(cb) && (mRmtSbmxFullVolRefCount > 0)) { 5185 mRmtSbmxFullVolRefCount--; 5186 if (mRmtSbmxFullVolRefCount == 0) { 5187 mFullVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 5188 mFixedVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 5189 applyRequired = true; 5190 } 5191 } 5192 } 5193 if (applyRequired) { 5194 // Assumes only STREAM_MUSIC going through DEVICE_OUT_REMOTE_SUBMIX 5195 checkAllFixedVolumeDevices(AudioSystem.STREAM_MUSIC); 5196 mStreamStates[AudioSystem.STREAM_MUSIC].applyAllVolumes(); 5197 } 5198 } 5199 } 5200 setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, int userId, int pid, String attributionTag)5201 private void setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, 5202 int userId, int pid, String attributionTag) { 5203 // If we are being called by the system check for user we are going to change 5204 // so we handle user restrictions correctly. 5205 if (uid == android.os.Process.SYSTEM_UID) { 5206 uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 5207 } 5208 // If OP_AUDIO_MASTER_VOLUME is set, disallow unmuting. 5209 if (!mute && !checkNoteAppOp( 5210 AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage, attributionTag)) { 5211 return; 5212 } 5213 if (userId != UserHandle.getCallingUserId() && 5214 mContext.checkPermission(INTERACT_ACROSS_USERS_FULL, pid, uid) 5215 != PackageManager.PERMISSION_GRANTED) { 5216 return; 5217 } 5218 setMasterMuteInternalNoCallerCheck(mute, flags, userId, "setMasterMute"); 5219 } 5220 setMasterMuteInternalNoCallerCheck( boolean mute, int flags, int userId, String eventSource)5221 private void setMasterMuteInternalNoCallerCheck( 5222 boolean mute, int flags, int userId, String eventSource) { 5223 if (DEBUG_VOL) { 5224 Log.d(TAG, TextUtils.formatSimple("Master mute %s, flags 0x%x, userId=%d from %s", 5225 mute, flags, userId, eventSource)); 5226 } 5227 5228 if (!isPlatformAutomotive() && mUseFixedVolume) { 5229 // If using fixed volume, we don't mute. 5230 // TODO: remove the isPlatformAutomotive check here. 5231 // The isPlatformAutomotive check is added for safety but may not be necessary. 5232 mute = false; 5233 } 5234 // For automotive, 5235 // - the car service is always running as system user 5236 // - foreground users are non-system users 5237 // Car service is in charge of dispatching the key event include global mute to Android. 5238 // Therefore, the getCurrentUser() is always different to the foreground user. 5239 if ((isPlatformAutomotive() && userId == UserHandle.USER_SYSTEM) 5240 || (getCurrentUserId() == userId)) { 5241 if (mute != mMasterMute.getAndSet(mute)) { 5242 sVolumeLogger.enqueue(new VolumeEvent( 5243 VolumeEvent.VOL_MASTER_MUTE, mute)); 5244 mAudioSystem.setMasterMute(mute); 5245 sendMasterMuteUpdate(mute, flags); 5246 } 5247 } 5248 } 5249 5250 /** get global mute state. */ isMasterMute()5251 public boolean isMasterMute() { 5252 return mMasterMute.get(); 5253 } 5254 5255 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 5256 /** @see AudioManager#setMasterMute(boolean, int) */ setMasterMute(boolean mute, int flags, String callingPackage, int userId, String attributionTag)5257 public void setMasterMute(boolean mute, int flags, String callingPackage, int userId, 5258 String attributionTag) { 5259 5260 super.setMasterMute_enforcePermission(); 5261 5262 setMasterMuteInternal(mute, flags, callingPackage, 5263 Binder.getCallingUid(), userId, Binder.getCallingPid(), attributionTag); 5264 } 5265 5266 /** @see AudioManager#getStreamVolume(int) */ getStreamVolume(int streamType)5267 public int getStreamVolume(int streamType) { 5268 ensureValidStreamType(streamType); 5269 int device = getDeviceForStream(streamType); 5270 return getStreamVolume(streamType, device); 5271 } 5272 getStreamVolume(int streamType, int device)5273 private int getStreamVolume(int streamType, int device) { 5274 synchronized (VolumeStreamState.class) { 5275 int index = mStreamStates[streamType].getIndex(device); 5276 5277 // by convention getStreamVolume() returns 0 when a stream is muted. 5278 if (mStreamStates[streamType].mIsMuted) { 5279 index = 0; 5280 } 5281 if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) && 5282 isFixedVolumeDevice(device)) { 5283 index = mStreamStates[streamType].getMaxIndex(); 5284 } 5285 return (index + 5) / 10; 5286 } 5287 } 5288 5289 @Override 5290 @android.annotation.EnforcePermission(anyOf = { 5291 MODIFY_AUDIO_ROUTING, MODIFY_AUDIO_SETTINGS_PRIVILEGED }) 5292 /** 5293 * @see AudioDeviceVolumeManager#getDeviceVolume(VolumeInfo, AudioDeviceAttributes) 5294 */ getDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)5295 public @NonNull VolumeInfo getDeviceVolume(@NonNull VolumeInfo vi, 5296 @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage) { 5297 super.getDeviceVolume_enforcePermission(); 5298 Objects.requireNonNull(vi); 5299 Objects.requireNonNull(ada); 5300 Objects.requireNonNull(callingPackage); 5301 if (!vi.hasStreamType()) { 5302 Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception()); 5303 return getDefaultVolumeInfo(); 5304 } 5305 5306 int streamType = vi.getStreamType(); 5307 final VolumeInfo.Builder vib = new VolumeInfo.Builder(vi); 5308 vib.setMinVolumeIndex((mStreamStates[streamType].mIndexMin + 5) / 10); 5309 vib.setMaxVolumeIndex((mStreamStates[streamType].mIndexMax + 5) / 10); 5310 synchronized (VolumeStreamState.class) { 5311 final int index; 5312 if (isFixedVolumeDevice(ada.getInternalType())) { 5313 index = (mStreamStates[streamType].mIndexMax + 5) / 10; 5314 } else { 5315 index = (mStreamStates[streamType].getIndex(ada.getInternalType()) + 5) / 10; 5316 } 5317 vib.setVolumeIndex(index); 5318 // only set as a mute command if stream muted 5319 if (mStreamStates[streamType].mIsMuted) { 5320 vib.setMuted(true); 5321 } 5322 return vib.build(); 5323 } 5324 } 5325 5326 /** @see AudioManager#getStreamMaxVolume(int) */ getStreamMaxVolume(int streamType)5327 public int getStreamMaxVolume(int streamType) { 5328 ensureValidStreamType(streamType); 5329 return (mStreamStates[streamType].getMaxIndex() + 5) / 10; 5330 } 5331 5332 /** @see AudioManager#getStreamMinVolumeInt(int) 5333 * Part of service interface, check permissions here */ getStreamMinVolume(int streamType)5334 public int getStreamMinVolume(int streamType) { 5335 ensureValidStreamType(streamType); 5336 final boolean isPrivileged = 5337 Binder.getCallingUid() == Process.SYSTEM_UID 5338 || callingHasAudioSettingsPermission() 5339 || (mContext.checkCallingPermission(MODIFY_AUDIO_ROUTING) 5340 == PackageManager.PERMISSION_GRANTED); 5341 return (mStreamStates[streamType].getMinIndex(isPrivileged) + 5) / 10; 5342 } 5343 5344 @android.annotation.EnforcePermission(QUERY_AUDIO_STATE) 5345 /** Get last audible volume before stream was muted. */ getLastAudibleStreamVolume(int streamType)5346 public int getLastAudibleStreamVolume(int streamType) { 5347 super.getLastAudibleStreamVolume_enforcePermission(); 5348 5349 ensureValidStreamType(streamType); 5350 int device = getDeviceForStream(streamType); 5351 return (mStreamStates[streamType].getIndex(device) + 5) / 10; 5352 } 5353 5354 /** 5355 * Default VolumeInfo returned by {@link VolumeInfo#getDefaultVolumeInfo()} 5356 * Lazily initialized in {@link #getDefaultVolumeInfo()} 5357 */ 5358 static VolumeInfo sDefaultVolumeInfo; 5359 5360 /** @see VolumeInfo#getDefaultVolumeInfo() */ getDefaultVolumeInfo()5361 public VolumeInfo getDefaultVolumeInfo() { 5362 if (sDefaultVolumeInfo == null) { 5363 sDefaultVolumeInfo = new VolumeInfo.Builder(AudioSystem.STREAM_MUSIC) 5364 .setMinVolumeIndex(getStreamMinVolume(AudioSystem.STREAM_MUSIC)) 5365 .setMaxVolumeIndex(getStreamMaxVolume(AudioSystem.STREAM_MUSIC)) 5366 .build(); 5367 } 5368 return sDefaultVolumeInfo; 5369 } 5370 5371 /** 5372 * list of callback dispatchers for stream aliasing updates 5373 */ 5374 final RemoteCallbackList<IStreamAliasingDispatcher> mStreamAliasingDispatchers = 5375 new RemoteCallbackList<IStreamAliasingDispatcher>(); 5376 5377 /** 5378 * Register/unregister a callback for stream aliasing updates 5379 * @param isad the callback dispatcher 5380 * @param register whether this for a registration or unregistration 5381 * @see AudioManager#addOnStreamAliasingChangedListener(Executor, Runnable) 5382 * @see AudioManager#removeOnStreamAliasingChangedListener(Runnable) 5383 */ 5384 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) registerStreamAliasingDispatcher(IStreamAliasingDispatcher isad, boolean register)5385 public void registerStreamAliasingDispatcher(IStreamAliasingDispatcher isad, boolean register) { 5386 super.registerStreamAliasingDispatcher_enforcePermission(); 5387 Objects.requireNonNull(isad); 5388 5389 if (register) { 5390 mStreamAliasingDispatchers.register(isad); 5391 } else { 5392 mStreamAliasingDispatchers.unregister(isad); 5393 } 5394 } 5395 dispatchStreamAliasingUpdate()5396 protected void dispatchStreamAliasingUpdate() { 5397 final int nbDispatchers = mStreamAliasingDispatchers.beginBroadcast(); 5398 for (int i = 0; i < nbDispatchers; i++) { 5399 try { 5400 mStreamAliasingDispatchers.getBroadcastItem(i).dispatchStreamAliasingChanged(); 5401 } catch (RemoteException e) { 5402 Log.e(TAG, "Error on stream alias update dispatch", e); 5403 } 5404 } 5405 mStreamAliasingDispatchers.finishBroadcast(); 5406 } 5407 5408 /** 5409 * @see AudioManager#getIndependentStreamTypes() 5410 * @return the list of non-aliased stream types 5411 */ 5412 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) getIndependentStreamTypes()5413 public ArrayList<Integer> getIndependentStreamTypes() { 5414 super.getIndependentStreamTypes_enforcePermission(); 5415 5416 if (mUseVolumeGroupAliases) { 5417 return new ArrayList<>(Arrays.stream(AudioManager.getPublicStreamTypes()) 5418 .boxed().toList()); 5419 } 5420 ArrayList<Integer> res = new ArrayList(1); 5421 for (int stream : mStreamVolumeAlias) { 5422 if (!res.contains(stream)) { 5423 res.add(stream); 5424 } 5425 } 5426 return res; 5427 } 5428 5429 /** 5430 * @see AudioManager#getStreamTypeAlias(int) 5431 * @param sourceStreamType the stream type for which the alias is queried 5432 * @return the stream alias 5433 */ 5434 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) 5435 public @AudioManager.PublicStreamTypes getStreamTypeAlias(@udioManager.PublicStreamTypes int sourceStreamType)5436 int getStreamTypeAlias(@AudioManager.PublicStreamTypes int sourceStreamType) { 5437 super.getStreamTypeAlias_enforcePermission(); 5438 // verify parameters 5439 ensureValidStreamType(sourceStreamType); 5440 5441 return mStreamVolumeAlias[sourceStreamType]; 5442 } 5443 5444 /** 5445 * @see AudioManager#isVolumeControlUsingVolumeGroups() 5446 * @return true when volume control is performed through volume groups, false if it uses 5447 * stream types. 5448 */ 5449 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isVolumeControlUsingVolumeGroups()5450 public boolean isVolumeControlUsingVolumeGroups() { 5451 super.isVolumeControlUsingVolumeGroups_enforcePermission(); 5452 5453 return mUseVolumeGroupAliases; 5454 } 5455 5456 /** @see AudioManager#getUiSoundsStreamType() 5457 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for 5458 * UI Sounds identification. 5459 * Fallback on Voice configuration to ensure correct behavior of DnD feature. 5460 */ getUiSoundsStreamType()5461 public int getUiSoundsStreamType() { 5462 return mUseVolumeGroupAliases ? STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM] 5463 : mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM]; 5464 } 5465 5466 /** 5467 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for 5468 * UI Sounds identification. 5469 * Fallback on Voice configuration to ensure correct behavior of DnD feature. 5470 */ isUiSoundsStreamType(int aliasStreamType)5471 private boolean isUiSoundsStreamType(int aliasStreamType) { 5472 return mUseVolumeGroupAliases 5473 ? STREAM_VOLUME_ALIAS_VOICE[aliasStreamType] 5474 == STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM] 5475 : aliasStreamType == mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM]; 5476 } 5477 5478 /** @see AudioManager#setMicrophoneMute(boolean) */ 5479 @Override setMicrophoneMute(boolean on, String callingPackage, int userId, String attributionTag)5480 public void setMicrophoneMute(boolean on, String callingPackage, int userId, 5481 String attributionTag) { 5482 // If we are being called by the system check for user we are going to change 5483 // so we handle user restrictions correctly. 5484 int uid = Binder.getCallingUid(); 5485 if (uid == android.os.Process.SYSTEM_UID) { 5486 uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 5487 } 5488 MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 5489 .setUid(uid) 5490 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage) 5491 .set(MediaMetrics.Property.EVENT, "setMicrophoneMute") 5492 .set(MediaMetrics.Property.REQUEST, on 5493 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE); 5494 5495 // If OP_MUTE_MICROPHONE is set, disallow unmuting. 5496 if (!on && !checkNoteAppOp( 5497 AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage, attributionTag)) { 5498 mmi.set(MediaMetrics.Property.EARLY_RETURN, "disallow unmuting").record(); 5499 return; 5500 } 5501 if (!checkAudioSettingsPermission("setMicrophoneMute()")) { 5502 mmi.set(MediaMetrics.Property.EARLY_RETURN, "!checkAudioSettingsPermission").record(); 5503 return; 5504 } 5505 if (userId != UserHandle.getCallingUserId() && 5506 mContext.checkCallingOrSelfPermission(INTERACT_ACROSS_USERS_FULL) 5507 != PackageManager.PERMISSION_GRANTED) { 5508 mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission").record(); 5509 return; 5510 } 5511 mMicMuteFromApi = on; 5512 mmi.record(); // record now, the no caller check will set the mute state. 5513 setMicrophoneMuteNoCallerCheck(userId); 5514 } 5515 5516 /** @see AudioManager#setMicrophoneMuteFromSwitch(boolean) */ setMicrophoneMuteFromSwitch(boolean on)5517 public void setMicrophoneMuteFromSwitch(boolean on) { 5518 int callingUid = Binder.getCallingUid(); 5519 if (callingUid != android.os.Process.SYSTEM_UID) { 5520 Log.e(TAG, "setMicrophoneMuteFromSwitch() called from non system user!"); 5521 return; 5522 } 5523 mMicMuteFromSwitch = on; 5524 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 5525 .setUid(callingUid) 5526 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteFromSwitch") 5527 .set(MediaMetrics.Property.REQUEST, on 5528 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE) 5529 .record(); 5530 setMicrophoneMuteNoCallerCheck(UserHandle.getCallingUserId()); 5531 } 5532 setMicMuteFromSwitchInput()5533 private void setMicMuteFromSwitchInput() { 5534 InputManager im = mContext.getSystemService(InputManager.class); 5535 final int isMicMuted = im.isMicMuted(); 5536 if (isMicMuted != InputManager.SWITCH_STATE_UNKNOWN) { 5537 setMicrophoneMuteFromSwitch(im.isMicMuted() != InputManager.SWITCH_STATE_OFF); 5538 } 5539 } 5540 5541 /** 5542 * Returns the microphone mute state as seen from the native audio system 5543 * @return true if microphone is reported as muted by primary HAL 5544 */ isMicrophoneMuted()5545 public boolean isMicrophoneMuted() { 5546 return mMicMuteFromSystemCached 5547 && (!mMicMuteFromPrivacyToggle 5548 || mMicMuteFromApi || mMicMuteFromRestrictions || mMicMuteFromSwitch); 5549 } 5550 isMicrophoneSupposedToBeMuted()5551 private boolean isMicrophoneSupposedToBeMuted() { 5552 return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi 5553 || mMicMuteFromPrivacyToggle; 5554 } 5555 setMicrophoneMuteNoCallerCheck(int userId)5556 private void setMicrophoneMuteNoCallerCheck(int userId) { 5557 final boolean muted = isMicrophoneSupposedToBeMuted(); 5558 if (DEBUG_VOL) { 5559 Log.d(TAG, String.format("Mic mute %b, user=%d", muted, userId)); 5560 } 5561 // only mute for the current user or for the system user. 5562 if (getCurrentUserId() == userId || userId == UserHandle.USER_SYSTEM) { 5563 final boolean currentMute = mAudioSystem.isMicrophoneMuted(); 5564 int callingUid = Binder.getCallingUid(); 5565 final long identity = Binder.clearCallingIdentity(); 5566 try { 5567 final int ret = mAudioSystem.muteMicrophone(muted); 5568 5569 // update cache with the real state independently from what was set 5570 mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted(); 5571 if (ret != AudioSystem.AUDIO_STATUS_OK) { 5572 Log.e(TAG, "Error changing mic mute state to " + muted + " current:" 5573 + mMicMuteFromSystemCached); 5574 } 5575 5576 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 5577 .setUid(callingUid) 5578 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteNoCallerCheck") 5579 .set(MediaMetrics.Property.MUTE, mMicMuteFromSystemCached 5580 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 5581 .set(MediaMetrics.Property.REQUEST, muted 5582 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE) 5583 .set(MediaMetrics.Property.STATUS, ret) 5584 .record(); 5585 5586 // send the intent even if there was a failure to change the actual mute state: 5587 // the AudioManager.setMicrophoneMute API doesn't have a return value to 5588 // indicate if the call failed to successfully change the mute state, and receiving 5589 // the intent may be the only time an application can resynchronize its mic mute 5590 // state with the actual system mic mute state 5591 if (muted != currentMute) { 5592 sendMsg(mAudioHandler, MSG_BROADCAST_MICROPHONE_MUTE, 5593 SENDMSG_NOOP, 0, 0, null, 0); 5594 } 5595 } finally { 5596 Binder.restoreCallingIdentity(identity); 5597 } 5598 } 5599 } 5600 5601 @Override getRingerModeExternal()5602 public int getRingerModeExternal() { 5603 synchronized(mSettingsLock) { 5604 return mRingerModeExternal; 5605 } 5606 } 5607 5608 @Override getRingerModeInternal()5609 public int getRingerModeInternal() { 5610 synchronized(mSettingsLock) { 5611 return mRingerMode; 5612 } 5613 } 5614 ensureValidRingerMode(int ringerMode)5615 private void ensureValidRingerMode(int ringerMode) { 5616 if (!isValidRingerMode(ringerMode)) { 5617 throw new IllegalArgumentException("Bad ringer mode " + ringerMode); 5618 } 5619 } 5620 5621 /** @see AudioManager#isValidRingerMode(int) */ isValidRingerMode(int ringerMode)5622 public boolean isValidRingerMode(int ringerMode) { 5623 return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX; 5624 } 5625 setRingerModeExternal(int ringerMode, String caller)5626 public void setRingerModeExternal(int ringerMode, String caller) { 5627 if (mHardeningEnforcer.blockVolumeMethod( 5628 HardeningEnforcer.METHOD_AUDIO_MANAGER_SET_RINGER_MODE)) { 5629 return; 5630 } 5631 if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode) 5632 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)) { 5633 throw new SecurityException("Not allowed to change Do Not Disturb state"); 5634 } 5635 5636 setRingerMode(ringerMode, caller, true /*external*/); 5637 } 5638 setRingerModeInternal(int ringerMode, String caller)5639 public void setRingerModeInternal(int ringerMode, String caller) { 5640 enforceVolumeController("setRingerModeInternal"); 5641 setRingerMode(ringerMode, caller, false /*external*/); 5642 } 5643 silenceRingerModeInternal(String reason)5644 public void silenceRingerModeInternal(String reason) { 5645 VibrationEffect effect = null; 5646 int ringerMode = AudioManager.RINGER_MODE_SILENT; 5647 int toastText = 0; 5648 5649 int silenceRingerSetting = Settings.Secure.VOLUME_HUSH_OFF; 5650 if (mContext.getResources() 5651 .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) { 5652 silenceRingerSetting = mSettings.getSecureIntForUser(mContentResolver, 5653 Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF, 5654 UserHandle.USER_CURRENT); 5655 } 5656 5657 switch(silenceRingerSetting) { 5658 case VOLUME_HUSH_MUTE: 5659 effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK); 5660 ringerMode = AudioManager.RINGER_MODE_SILENT; 5661 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent; 5662 break; 5663 case VOLUME_HUSH_VIBRATE: 5664 effect = VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK); 5665 ringerMode = AudioManager.RINGER_MODE_VIBRATE; 5666 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate; 5667 break; 5668 } 5669 maybeVibrate(effect, reason); 5670 setRingerModeInternal(ringerMode, reason); 5671 Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT).show(); 5672 } 5673 maybeVibrate(VibrationEffect effect, String reason)5674 private boolean maybeVibrate(VibrationEffect effect, String reason) { 5675 if (!mHasVibrator) { 5676 return false; 5677 } 5678 if (effect == null) { 5679 return false; 5680 } 5681 mVibrator.vibrate(Binder.getCallingUid(), mContext.getOpPackageName(), effect, 5682 reason, TOUCH_VIBRATION_ATTRIBUTES); 5683 return true; 5684 } 5685 setRingerMode(int ringerMode, String caller, boolean external)5686 private void setRingerMode(int ringerMode, String caller, boolean external) { 5687 if (mUseFixedVolume || mIsSingleVolume || mUseVolumeGroupAliases) { 5688 return; 5689 } 5690 if (caller == null || caller.length() == 0) { 5691 throw new IllegalArgumentException("Bad caller: " + caller); 5692 } 5693 ensureValidRingerMode(ringerMode); 5694 if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { 5695 ringerMode = AudioManager.RINGER_MODE_SILENT; 5696 } 5697 final long identity = Binder.clearCallingIdentity(); 5698 try { 5699 synchronized (mSettingsLock) { 5700 final int ringerModeInternal = getRingerModeInternal(); 5701 final int ringerModeExternal = getRingerModeExternal(); 5702 if (external) { 5703 setRingerModeExt(ringerMode); 5704 if (mRingerModeDelegate != null) { 5705 ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal, 5706 ringerMode, caller, ringerModeInternal, mVolumePolicy); 5707 } 5708 if (ringerMode != ringerModeInternal) { 5709 setRingerModeInt(ringerMode, true /*persist*/); 5710 } 5711 } else /*internal*/ { 5712 if (ringerMode != ringerModeInternal) { 5713 setRingerModeInt(ringerMode, true /*persist*/); 5714 } 5715 if (mRingerModeDelegate != null) { 5716 ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal, 5717 ringerMode, caller, ringerModeExternal, mVolumePolicy); 5718 } 5719 setRingerModeExt(ringerMode); 5720 } 5721 } 5722 } finally { 5723 Binder.restoreCallingIdentity(identity); 5724 } 5725 } 5726 setRingerModeExt(int ringerMode)5727 private void setRingerModeExt(int ringerMode) { 5728 synchronized(mSettingsLock) { 5729 if (ringerMode == mRingerModeExternal) return; 5730 mRingerModeExternal = ringerMode; 5731 } 5732 // Send sticky broadcast 5733 broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode); 5734 } 5735 5736 @GuardedBy("mSettingsLock") muteRingerModeStreams()5737 private void muteRingerModeStreams() { 5738 // Mute stream if not previously muted by ringer mode and (ringer mode 5739 // is not RINGER_MODE_NORMAL OR stream is zen muted) and stream is affected by ringer mode. 5740 // Unmute stream if previously muted by ringer/zen mode and ringer mode 5741 // is RINGER_MODE_NORMAL or stream is not affected by ringer mode. 5742 int numStreamTypes = AudioSystem.getNumStreamTypes(); 5743 5744 if (mNm == null) { 5745 mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 5746 } 5747 5748 final int ringerMode = mRingerMode; // Read ringer mode as reading primitives is atomic 5749 final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE 5750 || ringerMode == AudioManager.RINGER_MODE_SILENT; 5751 final boolean shouldRingSco = ringerMode == AudioManager.RINGER_MODE_VIBRATE 5752 && mDeviceBroker.isBluetoothScoActive(); 5753 // Ask audio policy engine to force use Bluetooth SCO channel if needed 5754 final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid() 5755 + "/" + Binder.getCallingPid(); 5756 sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, AudioSystem.FOR_VIBRATE_RINGING, 5757 shouldRingSco ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE, eventSource, 0); 5758 5759 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 5760 final boolean isMuted = isStreamMutedByRingerOrZenMode(streamType); 5761 final boolean muteAllowedBySco = 5762 !(shouldRingSco && streamType == AudioSystem.STREAM_RING); 5763 final boolean shouldZenMute = isStreamAffectedByCurrentZen(streamType); 5764 final boolean shouldMute = shouldZenMute || (ringerModeMute 5765 && isStreamAffectedByRingerMode(streamType) && muteAllowedBySco); 5766 if (isMuted == shouldMute) continue; 5767 if (!shouldMute) { 5768 // unmute 5769 // ring and notifications volume should never be 0 when not silenced 5770 if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING 5771 || mStreamVolumeAlias[streamType] == AudioSystem.STREAM_NOTIFICATION) { 5772 synchronized (VolumeStreamState.class) { 5773 final VolumeStreamState vss = mStreamStates[streamType]; 5774 for (int i = 0; i < vss.mIndexMap.size(); i++) { 5775 int device = vss.mIndexMap.keyAt(i); 5776 int value = vss.mIndexMap.valueAt(i); 5777 if (value == 0) { 5778 vss.setIndex(10, device, TAG, true /*hasModifyAudioSettings*/); 5779 } 5780 } 5781 // Persist volume for stream ring when it is changed here 5782 final int device = getDeviceForStream(streamType); 5783 sendMsg(mAudioHandler, 5784 MSG_PERSIST_VOLUME, 5785 SENDMSG_QUEUE, 5786 device, 5787 0, 5788 mStreamStates[streamType], 5789 PERSIST_DELAY); 5790 } 5791 } 5792 sRingerAndZenModeMutedStreams &= ~(1 << streamType); 5793 sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent( 5794 sRingerAndZenModeMutedStreams, "muteRingerModeStreams")); 5795 mStreamStates[streamType].mute(false, "muteRingerModeStreams"); 5796 } else { 5797 // mute 5798 sRingerAndZenModeMutedStreams |= (1 << streamType); 5799 sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent( 5800 sRingerAndZenModeMutedStreams, "muteRingerModeStreams")); 5801 mStreamStates[streamType].mute(true, "muteRingerModeStreams"); 5802 } 5803 } 5804 } 5805 isAlarm(int streamType)5806 private boolean isAlarm(int streamType) { 5807 return streamType == AudioSystem.STREAM_ALARM; 5808 } 5809 isNotificationOrRinger(int streamType)5810 private boolean isNotificationOrRinger(int streamType) { 5811 return streamType == AudioSystem.STREAM_NOTIFICATION 5812 || streamType == AudioSystem.STREAM_RING; 5813 } 5814 isMedia(int streamType)5815 private boolean isMedia(int streamType) { 5816 return streamType == AudioSystem.STREAM_MUSIC; 5817 } 5818 5819 isSystem(int streamType)5820 private boolean isSystem(int streamType) { 5821 return streamType == AudioSystem.STREAM_SYSTEM; 5822 } 5823 setRingerModeInt(int ringerMode, boolean persist)5824 private void setRingerModeInt(int ringerMode, boolean persist) { 5825 final boolean change; 5826 synchronized(mSettingsLock) { 5827 change = mRingerMode != ringerMode; 5828 mRingerMode = ringerMode; 5829 muteRingerModeStreams(); 5830 } 5831 5832 // Post a persist ringer mode msg 5833 if (persist) { 5834 sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE, 5835 SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY); 5836 } 5837 if (change) { 5838 // Send sticky broadcast 5839 broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, ringerMode); 5840 } 5841 } 5842 postUpdateRingerModeServiceInt()5843 /*package*/ void postUpdateRingerModeServiceInt() { 5844 sendMsg(mAudioHandler, MSG_UPDATE_RINGER_MODE, SENDMSG_QUEUE, 0, 0, null, 0); 5845 } 5846 onUpdateRingerModeServiceInt()5847 private void onUpdateRingerModeServiceInt() { 5848 setRingerModeInt(getRingerModeInternal(), false); 5849 } 5850 5851 /** @see AudioManager#shouldVibrate(int) */ shouldVibrate(int vibrateType)5852 public boolean shouldVibrate(int vibrateType) { 5853 if (!mHasVibrator) return false; 5854 5855 switch (getVibrateSetting(vibrateType)) { 5856 5857 case AudioManager.VIBRATE_SETTING_ON: 5858 return getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT; 5859 5860 case AudioManager.VIBRATE_SETTING_ONLY_SILENT: 5861 return getRingerModeExternal() == AudioManager.RINGER_MODE_VIBRATE; 5862 5863 case AudioManager.VIBRATE_SETTING_OFF: 5864 // return false, even for incoming calls 5865 return false; 5866 5867 default: 5868 return false; 5869 } 5870 } 5871 5872 /** @see AudioManager#getVibrateSetting(int) */ getVibrateSetting(int vibrateType)5873 public int getVibrateSetting(int vibrateType) { 5874 if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF; 5875 return (mVibrateSetting >> (vibrateType * 2)) & 3; 5876 } 5877 5878 /** @see AudioManager#setVibrateSetting(int, int) */ setVibrateSetting(int vibrateType, int vibrateSetting)5879 public void setVibrateSetting(int vibrateType, int vibrateSetting) { 5880 5881 if (!mHasVibrator) return; 5882 5883 mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, vibrateType, 5884 vibrateSetting); 5885 5886 // Broadcast change 5887 broadcastVibrateSetting(vibrateType); 5888 5889 } 5890 5891 private class SetModeDeathHandler implements IBinder.DeathRecipient { 5892 private final IBinder mCb; // To be notified of client's death 5893 private final int mPid; 5894 private final int mUid; 5895 private final boolean mIsPrivileged; 5896 private final String mPackage; 5897 private int mMode; 5898 private long mUpdateTime; 5899 private boolean mPlaybackActive = false; 5900 private boolean mRecordingActive = false; 5901 SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, String caller, int mode)5902 SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, 5903 String caller, int mode) { 5904 mMode = mode; 5905 mCb = cb; 5906 mPid = pid; 5907 mUid = uid; 5908 mPackage = caller; 5909 mIsPrivileged = isPrivileged; 5910 mUpdateTime = java.lang.System.currentTimeMillis(); 5911 } 5912 binderDied()5913 public void binderDied() { 5914 synchronized (mDeviceBroker.mSetModeLock) { 5915 Log.w(TAG, "SetModeDeathHandler client died"); 5916 int index = mSetModeDeathHandlers.indexOf(this); 5917 if (index < 0) { 5918 Log.w(TAG, "unregistered SetModeDeathHandler client died"); 5919 } else { 5920 SetModeDeathHandler h = mSetModeDeathHandlers.get(index); 5921 mSetModeDeathHandlers.remove(index); 5922 sendMsg(mAudioHandler, 5923 MSG_UPDATE_AUDIO_MODE, 5924 SENDMSG_QUEUE, 5925 AudioSystem.MODE_CURRENT, 5926 android.os.Process.myPid(), 5927 mContext.getPackageName(), 5928 0); 5929 } 5930 } 5931 } 5932 getPid()5933 public int getPid() { 5934 return mPid; 5935 } 5936 setMode(int mode)5937 public void setMode(int mode) { 5938 mMode = mode; 5939 mUpdateTime = java.lang.System.currentTimeMillis(); 5940 } 5941 getMode()5942 public int getMode() { 5943 return mMode; 5944 } 5945 getBinder()5946 public IBinder getBinder() { 5947 return mCb; 5948 } 5949 getUid()5950 public int getUid() { 5951 return mUid; 5952 } 5953 getPackage()5954 public String getPackage() { 5955 return mPackage; 5956 } 5957 isPrivileged()5958 public boolean isPrivileged() { 5959 return mIsPrivileged; 5960 } 5961 getUpdateTime()5962 public long getUpdateTime() { 5963 return mUpdateTime; 5964 } 5965 setPlaybackActive(boolean active)5966 public void setPlaybackActive(boolean active) { 5967 mPlaybackActive = active; 5968 } 5969 setRecordingActive(boolean active)5970 public void setRecordingActive(boolean active) { 5971 mRecordingActive = active; 5972 } 5973 5974 /** 5975 * An app is considered active if: 5976 * - It is privileged (has MODIFY_PHONE_STATE permission) 5977 * or 5978 * - It requests mode MODE_IN_COMMUNICATION, and it is either playing 5979 * or recording for VOICE_COMMUNICATION. 5980 * or 5981 * - It requests a mode different from MODE_IN_COMMUNICATION or MODE_NORMAL 5982 * Note: only privileged apps can request MODE_IN_CALL, MODE_CALL_REDIRECT 5983 * or MODE_COMMUNICATION_REDIRECT. 5984 */ isActive()5985 public boolean isActive() { 5986 return mIsPrivileged 5987 || ((mMode == AudioSystem.MODE_IN_COMMUNICATION) 5988 && (mRecordingActive || mPlaybackActive)) 5989 || mMode == AudioSystem.MODE_RINGTONE 5990 || mMode == AudioSystem.MODE_CALL_SCREENING; 5991 } 5992 dump(PrintWriter pw, int index)5993 public void dump(PrintWriter pw, int index) { 5994 SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss:SSS"); 5995 5996 if (index >= 0) { 5997 pw.println(" Requester # " + (index + 1) + ":"); 5998 } 5999 pw.println(" - Mode: " + AudioSystem.modeToString(mMode)); 6000 pw.println(" - Binder: " + mCb); 6001 pw.println(" - Pid: " + mPid); 6002 pw.println(" - Uid: " + mUid); 6003 pw.println(" - Package: " + mPackage); 6004 pw.println(" - Privileged: " + mIsPrivileged); 6005 pw.println(" - Active: " + isActive()); 6006 pw.println(" Playback active: " + mPlaybackActive); 6007 pw.println(" Recording active: " + mRecordingActive); 6008 pw.println(" - update time: " + format.format(new Date(mUpdateTime))); 6009 } 6010 } 6011 6012 @GuardedBy("mDeviceBroker.mSetModeLock") getAudioModeOwnerHandler()6013 private SetModeDeathHandler getAudioModeOwnerHandler() { 6014 // The Audio mode owner is: 6015 // 1) the most recent privileged app in the stack 6016 // 2) the most recent active app in the tack 6017 SetModeDeathHandler modeOwner = null; 6018 SetModeDeathHandler privilegedModeOwner = null; 6019 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 6020 if (h.isActive()) { 6021 // privileged apps are always active 6022 if (h.isPrivileged()) { 6023 if (privilegedModeOwner == null 6024 || h.getUpdateTime() > privilegedModeOwner.getUpdateTime()) { 6025 privilegedModeOwner = h; 6026 } 6027 } else { 6028 if (modeOwner == null 6029 || h.getUpdateTime() > modeOwner.getUpdateTime()) { 6030 modeOwner = h; 6031 } 6032 } 6033 } 6034 } 6035 return privilegedModeOwner != null ? privilegedModeOwner : modeOwner; 6036 } 6037 6038 /** 6039 * Return information on the current audio mode owner 6040 * @return 0 if nobody owns the mode 6041 */ 6042 @GuardedBy("mDeviceBroker.mSetModeLock") getAudioModeOwner()6043 /*package*/ AudioDeviceBroker.AudioModeInfo getAudioModeOwner() { 6044 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 6045 if (hdlr != null) { 6046 return new AudioDeviceBroker.AudioModeInfo( 6047 hdlr.getMode(), hdlr.getPid(), hdlr.getUid()); 6048 } 6049 return new AudioDeviceBroker.AudioModeInfo(AudioSystem.MODE_NORMAL, 0 , 0); 6050 } 6051 6052 /** 6053 * Return the uid of the current audio mode owner 6054 * @return 0 if nobody owns the mode 6055 */ 6056 @GuardedBy("mDeviceBroker.mSetModeLock") getModeOwnerUid()6057 /*package*/ int getModeOwnerUid() { 6058 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 6059 if (hdlr != null) { 6060 return hdlr.getUid(); 6061 } 6062 return 0; 6063 } 6064 6065 /** @see AudioManager#setMode(int) */ setMode(int mode, IBinder cb, String callingPackage)6066 public void setMode(int mode, IBinder cb, String callingPackage) { 6067 int pid = Binder.getCallingPid(); 6068 int uid = Binder.getCallingUid(); 6069 if (DEBUG_MODE) { 6070 Log.v(TAG, "setMode(mode=" + mode + ", pid=" + pid 6071 + ", uid=" + uid + ", caller=" + callingPackage + ")"); 6072 } 6073 if (!checkAudioSettingsPermission("setMode()")) { 6074 return; 6075 } 6076 if (cb == null) { 6077 Log.e(TAG, "setMode() called with null binder"); 6078 return; 6079 } 6080 if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) { 6081 Log.w(TAG, "setMode() invalid mode: " + mode); 6082 return; 6083 } 6084 6085 if (mode == AudioSystem.MODE_CURRENT) { 6086 mode = getMode(); 6087 } 6088 6089 if (mode == AudioSystem.MODE_CALL_SCREENING && !mIsCallScreeningModeSupported) { 6090 Log.w(TAG, "setMode(MODE_CALL_SCREENING) not permitted " 6091 + "when call screening is not supported"); 6092 return; 6093 } 6094 6095 final boolean hasModifyPhoneStatePermission = mContext.checkCallingOrSelfPermission( 6096 MODIFY_PHONE_STATE) 6097 == PackageManager.PERMISSION_GRANTED; 6098 if ((mode == AudioSystem.MODE_IN_CALL 6099 || mode == AudioSystem.MODE_CALL_REDIRECT 6100 || mode == AudioSystem.MODE_COMMUNICATION_REDIRECT) 6101 && !hasModifyPhoneStatePermission) { 6102 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setMode(" 6103 + AudioSystem.modeToString(mode) + ") from pid=" + pid 6104 + ", uid=" + Binder.getCallingUid()); 6105 return; 6106 } 6107 6108 SetModeDeathHandler currentModeHandler = null; 6109 synchronized (mDeviceBroker.mSetModeLock) { 6110 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 6111 if (h.getPid() == pid) { 6112 currentModeHandler = h; 6113 break; 6114 } 6115 } 6116 6117 if (mode == AudioSystem.MODE_NORMAL) { 6118 if (currentModeHandler != null) { 6119 if (!currentModeHandler.isPrivileged() 6120 && currentModeHandler.getMode() == AudioSystem.MODE_IN_COMMUNICATION) { 6121 mAudioHandler.removeEqualMessages( 6122 MSG_CHECK_MODE_FOR_UID, currentModeHandler); 6123 } 6124 mSetModeDeathHandlers.remove(currentModeHandler); 6125 if (DEBUG_MODE) { 6126 Log.v(TAG, "setMode(" + mode + ") removing hldr for pid: " + pid); 6127 } 6128 try { 6129 currentModeHandler.getBinder().unlinkToDeath(currentModeHandler, 0); 6130 } catch (NoSuchElementException e) { 6131 Log.w(TAG, "setMode link does not exist ..."); 6132 } 6133 } 6134 } else { 6135 if (currentModeHandler != null) { 6136 currentModeHandler.setMode(mode); 6137 if (DEBUG_MODE) { 6138 Log.v(TAG, "setMode(" + mode + ") updating hldr for pid: " + pid); 6139 } 6140 } else { 6141 currentModeHandler = new SetModeDeathHandler(cb, pid, uid, 6142 hasModifyPhoneStatePermission, callingPackage, mode); 6143 // Register for client death notification 6144 try { 6145 cb.linkToDeath(currentModeHandler, 0); 6146 } catch (RemoteException e) { 6147 // Client has died! 6148 Log.w(TAG, "setMode() could not link to " + cb + " binder death"); 6149 return; 6150 } 6151 mSetModeDeathHandlers.add(currentModeHandler); 6152 if (DEBUG_MODE) { 6153 Log.v(TAG, "setMode(" + mode + ") adding handler for pid=" + pid); 6154 } 6155 } 6156 if (mode == AudioSystem.MODE_IN_COMMUNICATION) { 6157 // Force active state when entering/updating the stack to avoid glitches when 6158 // an app starts playing/recording after settng the audio mode, 6159 // and send a reminder to check activity after a grace period. 6160 if (!currentModeHandler.isPrivileged()) { 6161 currentModeHandler.setPlaybackActive(true); 6162 currentModeHandler.setRecordingActive(true); 6163 sendMsg(mAudioHandler, 6164 MSG_CHECK_MODE_FOR_UID, 6165 SENDMSG_QUEUE, 6166 0, 6167 0, 6168 currentModeHandler, 6169 CHECK_MODE_FOR_UID_PERIOD_MS); 6170 } 6171 } 6172 } 6173 6174 sendMsg(mAudioHandler, 6175 MSG_UPDATE_AUDIO_MODE, 6176 SENDMSG_REPLACE, 6177 mode, 6178 pid, 6179 callingPackage, 6180 0); 6181 } 6182 } 6183 6184 @GuardedBy("mDeviceBroker.mSetModeLock") onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, boolean force)6185 void onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, 6186 boolean force) { 6187 if (requestedMode == AudioSystem.MODE_CURRENT) { 6188 requestedMode = getMode(); 6189 } 6190 int mode = AudioSystem.MODE_NORMAL; 6191 int uid = 0; 6192 int pid = 0; 6193 SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler(); 6194 if (currentModeHandler != null) { 6195 mode = currentModeHandler.getMode(); 6196 uid = currentModeHandler.getUid(); 6197 pid = currentModeHandler.getPid(); 6198 } 6199 if (DEBUG_MODE) { 6200 Log.v(TAG, "onUpdateAudioMode() new mode: " + mode + ", current mode: " 6201 + mMode.get() + " requested mode: " + requestedMode); 6202 } 6203 if (mode != mMode.get() || force) { 6204 int status = AudioSystem.SUCCESS; 6205 final long identity = Binder.clearCallingIdentity(); 6206 try { 6207 status = mAudioSystem.setPhoneState(mode, uid); 6208 } finally { 6209 Binder.restoreCallingIdentity(identity); 6210 } 6211 if (status == AudioSystem.AUDIO_STATUS_OK) { 6212 if (DEBUG_MODE) { 6213 Log.v(TAG, "onUpdateAudioMode: mode successfully set to " + mode); 6214 } 6215 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_MODE, SENDMSG_REPLACE, mode, 0, 6216 /*obj*/ null, /*delay*/ 0); 6217 int previousMode = mMode.getAndSet(mode); 6218 // Note: newModeOwnerPid is always 0 when actualMode is MODE_NORMAL 6219 mModeLogger.enqueue(new PhoneStateEvent(requesterPackage, requesterPid, 6220 requestedMode, pid, mode)); 6221 6222 final int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE); 6223 final int device = getDeviceForStream(streamType); 6224 final int streamAlias = mStreamVolumeAlias[streamType]; 6225 6226 if (DEBUG_MODE) { 6227 Log.v(TAG, "onUpdateAudioMode: streamType=" + streamType 6228 + ", streamAlias=" + streamAlias); 6229 } 6230 6231 final int index = mStreamStates[streamAlias].getIndex(device); 6232 final int maxIndex = mStreamStates[streamAlias].getMaxIndex(); 6233 setStreamVolumeInt(streamAlias, index, device, true, 6234 requesterPackage, true /*hasModifyAudioSettings*/); 6235 6236 updateStreamVolumeAlias(true /*updateVolumes*/, requesterPackage); 6237 6238 // change of mode may require volume to be re-applied on some devices 6239 updateAbsVolumeMultiModeDevices(previousMode, mode); 6240 6241 setLeAudioVolumeOnModeUpdate(mode, device, streamAlias, index, maxIndex); 6242 6243 synchronized (mCachedAbsVolDrivingStreamsLock) { 6244 mCachedAbsVolDrivingStreams.replaceAll((absDev, stream) -> { 6245 int streamToDriveAbs = getBluetoothContextualVolumeStream(); 6246 if (stream != streamToDriveAbs) { 6247 mAudioSystem.setDeviceAbsoluteVolumeEnabled(absDev, /*address=*/ 6248 "", /*enabled*/true, streamToDriveAbs); 6249 } 6250 return streamToDriveAbs; 6251 }); 6252 } 6253 6254 // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO 6255 // connections not started by the application changing the mode when pid changes 6256 mDeviceBroker.postSetModeOwner(mode, pid, uid); 6257 } else { 6258 Log.w(TAG, "onUpdateAudioMode: failed to set audio mode to: " + mode); 6259 } 6260 } 6261 } 6262 6263 /** @see AudioManager#getMode() */ getMode()6264 public int getMode() { 6265 synchronized (mDeviceBroker.mSetModeLock) { 6266 SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler(); 6267 if (currentModeHandler != null) { 6268 return currentModeHandler.getMode(); 6269 } 6270 return AudioSystem.MODE_NORMAL; 6271 } 6272 } 6273 6274 /** cached value read from audiopolicy manager after initialization. */ 6275 private boolean mIsCallScreeningModeSupported = false; 6276 6277 /** @see AudioManager#isCallScreeningModeSupported() */ isCallScreeningModeSupported()6278 public boolean isCallScreeningModeSupported() { 6279 return mIsCallScreeningModeSupported; 6280 } 6281 dispatchMode(int mode)6282 protected void dispatchMode(int mode) { 6283 final int nbDispatchers = mModeDispatchers.beginBroadcast(); 6284 for (int i = 0; i < nbDispatchers; i++) { 6285 try { 6286 mModeDispatchers.getBroadcastItem(i).dispatchAudioModeChanged(mode); 6287 } catch (RemoteException e) { 6288 } 6289 } 6290 mModeDispatchers.finishBroadcast(); 6291 } 6292 6293 final RemoteCallbackList<IAudioModeDispatcher> mModeDispatchers = 6294 new RemoteCallbackList<IAudioModeDispatcher>(); 6295 6296 /** 6297 * @see {@link AudioManager#addOnModeChangedListener(Executor, AudioManager.OnModeChangedListener)} 6298 * @param dispatcher 6299 */ registerModeDispatcher( @onNull IAudioModeDispatcher dispatcher)6300 public void registerModeDispatcher( 6301 @NonNull IAudioModeDispatcher dispatcher) { 6302 mModeDispatchers.register(dispatcher); 6303 } 6304 6305 /** 6306 * @see {@link AudioManager#removeOnModeChangedListener(AudioManager.OnModeChangedListener)} 6307 * @param dispatcher 6308 */ unregisterModeDispatcher( @onNull IAudioModeDispatcher dispatcher)6309 public void unregisterModeDispatcher( 6310 @NonNull IAudioModeDispatcher dispatcher) { 6311 mModeDispatchers.unregister(dispatcher); 6312 } 6313 6314 @android.annotation.EnforcePermission(CALL_AUDIO_INTERCEPTION) 6315 /** @see AudioManager#isPstnCallAudioInterceptable() */ isPstnCallAudioInterceptable()6316 public boolean isPstnCallAudioInterceptable() { 6317 6318 super.isPstnCallAudioInterceptable_enforcePermission(); 6319 6320 boolean uplinkDeviceFound = false; 6321 boolean downlinkDeviceFound = false; 6322 AudioDeviceInfo[] devices = AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_ALL); 6323 for (AudioDeviceInfo device : devices) { 6324 if (device.getInternalType() == AudioSystem.DEVICE_OUT_TELEPHONY_TX) { 6325 uplinkDeviceFound = true; 6326 } else if (device.getInternalType() == AudioSystem.DEVICE_IN_TELEPHONY_RX) { 6327 downlinkDeviceFound = true; 6328 } 6329 if (uplinkDeviceFound && downlinkDeviceFound) { 6330 return true; 6331 } 6332 } 6333 return false; 6334 } 6335 6336 /** @see AudioManager#setRttEnabled() */ 6337 @Override setRttEnabled(boolean rttEnabled)6338 public void setRttEnabled(boolean rttEnabled) { 6339 if (mContext.checkCallingOrSelfPermission( 6340 MODIFY_PHONE_STATE) 6341 != PackageManager.PERMISSION_GRANTED) { 6342 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setRttEnabled from pid=" 6343 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 6344 return; 6345 } 6346 synchronized (mSettingsLock) { 6347 mRttEnabled = rttEnabled; 6348 final long identity = Binder.clearCallingIdentity(); 6349 try { 6350 AudioSystem.setRttEnabled(rttEnabled); 6351 } finally { 6352 Binder.restoreCallingIdentity(identity); 6353 } 6354 } 6355 } 6356 6357 /** @see AudioManager#adjustSuggestedStreamVolumeForUid(int, int, int, String, int, int, int) */ 6358 @Override adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6359 public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, 6360 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 6361 int targetSdkVersion) { 6362 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 6363 throw new SecurityException("Should only be called from system process"); 6364 } 6365 6366 // direction and stream type swap here because the public 6367 // adjustSuggested has a different order than the other methods. 6368 adjustSuggestedStreamVolume(direction, streamType, flags, packageName, packageName, 6369 uid, pid, hasAudioSettingsPermission(uid, pid), 6370 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 6371 } 6372 6373 /** @see AudioManager#adjustStreamVolumeForUid(int, int, int, String, int, int, int) */ 6374 @Override adjustStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6375 public void adjustStreamVolumeForUid(int streamType, int direction, int flags, 6376 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 6377 int targetSdkVersion) { 6378 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 6379 throw new SecurityException("Should only be called from system process"); 6380 } 6381 6382 if (direction != AudioManager.ADJUST_SAME) { 6383 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType, 6384 direction/*val1*/, flags/*val2*/, 6385 new StringBuilder(packageName).append(" uid:").append(uid) 6386 .toString())); 6387 } 6388 6389 adjustStreamVolume(streamType, direction, flags, packageName, packageName, uid, pid, 6390 null, hasAudioSettingsPermission(uid, pid), 6391 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 6392 } 6393 6394 /** 6395 * @see AudioManager#adjustVolume(int, int) 6396 * This method is redirected from AudioManager to AudioService for API hardening rules 6397 * enforcement then to MediaSession for implementation. 6398 */ 6399 @Override adjustVolume(int direction, int flags)6400 public void adjustVolume(int direction, int flags) { 6401 if (mHardeningEnforcer.blockVolumeMethod( 6402 HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_VOLUME)) { 6403 return; 6404 } 6405 getMediaSessionManager().dispatchAdjustVolume(AudioManager.USE_DEFAULT_STREAM_TYPE, 6406 direction, flags); 6407 } 6408 6409 /** 6410 * @see AudioManager#adjustSuggestedStreamVolume(int, int, int) 6411 * This method is redirected from AudioManager to AudioService for API hardening rules 6412 * enforcement then to MediaSession for implementation. 6413 */ 6414 @Override adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags)6415 public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) { 6416 if (mHardeningEnforcer.blockVolumeMethod( 6417 HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_SUGGESTED_STREAM_VOLUME)) { 6418 return; 6419 } 6420 getMediaSessionManager().dispatchAdjustVolume(suggestedStreamType, direction, flags); 6421 } 6422 6423 /** @see AudioManager#setStreamVolumeForUid(int, int, int, String, int, int, int) */ 6424 @Override setStreamVolumeForUid(int streamType, int index, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6425 public void setStreamVolumeForUid(int streamType, int index, int flags, 6426 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 6427 int targetSdkVersion) { 6428 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 6429 throw new SecurityException("Should only be called from system process"); 6430 } 6431 6432 setStreamVolume(streamType, index, flags, /*device*/ null, 6433 packageName, packageName, null, uid, 6434 hasAudioSettingsPermission(uid, pid), 6435 true /*canChangeMuteAndUpdateController*/); 6436 } 6437 6438 //========================================================================================== 6439 // Sound Effects 6440 //========================================================================================== 6441 private static final class LoadSoundEffectReply 6442 implements SoundEffectsHelper.OnEffectsLoadCompleteHandler { 6443 private static final int SOUND_EFFECTS_LOADING = 1; 6444 private static final int SOUND_EFFECTS_LOADED = 0; 6445 private static final int SOUND_EFFECTS_ERROR = -1; 6446 private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000; 6447 6448 private int mStatus = SOUND_EFFECTS_LOADING; 6449 6450 @Override run(boolean success)6451 public synchronized void run(boolean success) { 6452 mStatus = success ? SOUND_EFFECTS_LOADED : SOUND_EFFECTS_ERROR; 6453 notify(); 6454 } 6455 waitForLoaded(int attempts)6456 public synchronized boolean waitForLoaded(int attempts) { 6457 while ((mStatus == SOUND_EFFECTS_LOADING) && (attempts-- > 0)) { 6458 try { 6459 wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS); 6460 } catch (InterruptedException e) { 6461 Log.w(TAG, "Interrupted while waiting sound pool loaded."); 6462 } 6463 } 6464 return mStatus == SOUND_EFFECTS_LOADED; 6465 } 6466 } 6467 6468 /** @see AudioManager#playSoundEffect(int, int) */ playSoundEffect(int effectType, int userId)6469 public void playSoundEffect(int effectType, int userId) { 6470 if (querySoundEffectsEnabled(userId)) { 6471 playSoundEffectVolume(effectType, -1.0f); 6472 } 6473 } 6474 6475 /** 6476 * Settings has an in memory cache, so this is fast. 6477 */ querySoundEffectsEnabled(int user)6478 private boolean querySoundEffectsEnabled(int user) { 6479 return mSettings.getSystemIntForUser(getContentResolver(), 6480 Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0; 6481 } 6482 6483 /** @see AudioManager#playSoundEffect(int, float) */ playSoundEffectVolume(int effectType, float volume)6484 public void playSoundEffectVolume(int effectType, float volume) { 6485 // do not try to play the sound effect if the system stream is muted 6486 if (isStreamMute(STREAM_SYSTEM)) { 6487 return; 6488 } 6489 6490 if (effectType >= AudioManager.NUM_SOUND_EFFECTS || effectType < 0) { 6491 Log.w(TAG, "AudioService effectType value " + effectType + " out of range"); 6492 return; 6493 } 6494 6495 sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE, 6496 effectType, (int) (volume * 1000), null, 0); 6497 } 6498 6499 /** 6500 * Loads samples into the soundpool. 6501 * This method must be called at first when sound effects are enabled 6502 */ loadSoundEffects()6503 public boolean loadSoundEffects() { 6504 LoadSoundEffectReply reply = new LoadSoundEffectReply(); 6505 sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0); 6506 return reply.waitForLoaded(3 /*attempts*/); 6507 } 6508 6509 /** 6510 * Schedule loading samples into the soundpool. 6511 * This method can be overridden to schedule loading at a later time. 6512 */ scheduleLoadSoundEffects()6513 protected void scheduleLoadSoundEffects() { 6514 sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0); 6515 } 6516 6517 /** 6518 * Unloads samples from the sound pool. 6519 * This method can be called to free some memory when 6520 * sound effects are disabled. 6521 */ unloadSoundEffects()6522 public void unloadSoundEffects() { 6523 sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0); 6524 } 6525 6526 /** @see AudioManager#reloadAudioSettings() */ reloadAudioSettings()6527 public void reloadAudioSettings() { 6528 readAudioSettings(false /*userSwitch*/); 6529 } 6530 readAudioSettings(boolean userSwitch)6531 private void readAudioSettings(boolean userSwitch) { 6532 // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings 6533 readPersistedSettings(); 6534 readUserRestrictions(); 6535 6536 // restore volume settings 6537 int numStreamTypes = AudioSystem.getNumStreamTypes(); 6538 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 6539 VolumeStreamState streamState = mStreamStates[streamType]; 6540 6541 if (userSwitch && mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) { 6542 continue; 6543 } 6544 6545 streamState.readSettings(); 6546 synchronized (VolumeStreamState.class) { 6547 // unmute stream that was muted but is not affect by mute anymore 6548 if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) && 6549 !isStreamMutedByRingerOrZenMode(streamType)) || mUseFixedVolume)) { 6550 streamState.mIsMuted = false; 6551 } 6552 } 6553 } 6554 6555 readVolumeGroupsSettings(userSwitch); 6556 6557 // apply new ringer mode before checking volume for alias streams so that streams 6558 // muted by ringer mode have the correct volume 6559 setRingerModeInt(getRingerModeInternal(), false); 6560 6561 checkAllFixedVolumeDevices(); 6562 checkAllAliasStreamVolumes(); 6563 checkMuteAffectedStreams(); 6564 6565 mSoundDoseHelper.restoreMusicActiveMs(); 6566 mSoundDoseHelper.enforceSafeMediaVolumeIfActive(TAG); 6567 6568 if (DEBUG_VOL) { 6569 Log.d(TAG, "Restoring device volume behavior"); 6570 } 6571 restoreDeviceVolumeBehavior(); 6572 } 6573 6574 /** @see AudioManager#getAvailableCommunicationDevices(int) */ getAvailableCommunicationDeviceIds()6575 public int[] getAvailableCommunicationDeviceIds() { 6576 List<AudioDeviceInfo> commDevices = AudioDeviceBroker.getAvailableCommunicationDevices(); 6577 return commDevices.stream().mapToInt(AudioDeviceInfo::getId).toArray(); 6578 } 6579 6580 /** 6581 * @see AudioManager#setCommunicationDevice(int) 6582 * @see AudioManager#clearCommunicationDevice() 6583 */ setCommunicationDevice(IBinder cb, int portId)6584 public boolean setCommunicationDevice(IBinder cb, int portId) { 6585 final int uid = Binder.getCallingUid(); 6586 final int pid = Binder.getCallingPid(); 6587 6588 AudioDeviceInfo device = null; 6589 if (portId != 0) { 6590 device = AudioManager.getDeviceForPortId(portId, AudioManager.GET_DEVICES_OUTPUTS); 6591 if (device == null) { 6592 Log.w(TAG, "setCommunicationDevice: invalid portID " + portId); 6593 return false; 6594 } 6595 if (!AudioDeviceBroker.isValidCommunicationDevice(device)) { 6596 if (!device.isSink()) { 6597 throw new IllegalArgumentException("device must have sink role"); 6598 } else { 6599 throw new IllegalArgumentException("invalid device type: " + device.getType()); 6600 } 6601 } 6602 } 6603 final String eventSource = new StringBuilder() 6604 .append(device == null ? "clearCommunicationDevice(" : "setCommunicationDevice(") 6605 .append(") from u/pid:").append(uid).append("/") 6606 .append(pid).toString(); 6607 6608 int deviceType = AudioSystem.DEVICE_OUT_DEFAULT; 6609 String deviceAddress = null; 6610 if (device != null) { 6611 deviceType = device.getPort().type(); 6612 deviceAddress = device.getAddress(); 6613 } else { 6614 AudioDeviceInfo curDevice = mDeviceBroker.getCommunicationDevice(); 6615 if (curDevice != null) { 6616 deviceType = curDevice.getPort().type(); 6617 deviceAddress = curDevice.getAddress(); 6618 } 6619 } 6620 // do not log metrics if clearing communication device while no communication device 6621 // was selected 6622 if (deviceType != AudioSystem.DEVICE_OUT_DEFAULT) { 6623 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 6624 + MediaMetrics.SEPARATOR + "setCommunicationDevice") 6625 .set(MediaMetrics.Property.DEVICE, 6626 AudioSystem.getDeviceName(deviceType)) 6627 .set(MediaMetrics.Property.ADDRESS, deviceAddress) 6628 .set(MediaMetrics.Property.STATE, device != null 6629 ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED) 6630 .record(); 6631 } 6632 final boolean isPrivileged = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE) 6633 == PackageManager.PERMISSION_GRANTED; 6634 final long ident = Binder.clearCallingIdentity(); 6635 try { 6636 return mDeviceBroker.setCommunicationDevice(cb, uid, device, isPrivileged, eventSource); 6637 } finally { 6638 Binder.restoreCallingIdentity(ident); 6639 } 6640 } 6641 6642 /** @see AudioManager#getCommunicationDevice() */ getCommunicationDevice()6643 public int getCommunicationDevice() { 6644 int deviceId = 0; 6645 final long ident = Binder.clearCallingIdentity(); 6646 try { 6647 AudioDeviceInfo device = mDeviceBroker.getCommunicationDevice(); 6648 deviceId = device != null ? device.getId() : 0; 6649 } finally { 6650 Binder.restoreCallingIdentity(ident); 6651 } 6652 return deviceId; 6653 } 6654 6655 /** @see AudioManager#addOnCommunicationDeviceChangedListener( 6656 * Executor, AudioManager.OnCommunicationDeviceChangedListener) 6657 */ registerCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)6658 public void registerCommunicationDeviceDispatcher( 6659 @Nullable ICommunicationDeviceDispatcher dispatcher) { 6660 if (dispatcher == null) { 6661 return; 6662 } 6663 mDeviceBroker.registerCommunicationDeviceDispatcher(dispatcher); 6664 } 6665 6666 /** @see AudioManager#removeOnCommunicationDeviceChangedListener( 6667 * AudioManager.OnCommunicationDeviceChangedListener) 6668 */ unregisterCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)6669 public void unregisterCommunicationDeviceDispatcher( 6670 @Nullable ICommunicationDeviceDispatcher dispatcher) { 6671 if (dispatcher == null) { 6672 return; 6673 } 6674 mDeviceBroker.unregisterCommunicationDeviceDispatcher(dispatcher); 6675 } 6676 6677 /** @see AudioManager#setSpeakerphoneOn(boolean) */ setSpeakerphoneOn(IBinder cb, boolean on)6678 public void setSpeakerphoneOn(IBinder cb, boolean on) { 6679 if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) { 6680 return; 6681 } 6682 final boolean isPrivileged = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE) 6683 == PackageManager.PERMISSION_GRANTED; 6684 6685 // for logging only 6686 final int uid = Binder.getCallingUid(); 6687 final int pid = Binder.getCallingPid(); 6688 6689 final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on) 6690 .append(") from u/pid:").append(uid).append("/") 6691 .append(pid).toString(); 6692 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 6693 + MediaMetrics.SEPARATOR + "setSpeakerphoneOn") 6694 .setUid(uid) 6695 .setPid(pid) 6696 .set(MediaMetrics.Property.STATE, on 6697 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 6698 .record(); 6699 6700 final long ident = Binder.clearCallingIdentity(); 6701 try { 6702 mDeviceBroker.setSpeakerphoneOn(cb, uid, on, isPrivileged, eventSource); 6703 } finally { 6704 Binder.restoreCallingIdentity(ident); 6705 } 6706 } 6707 6708 /** @see AudioManager#isSpeakerphoneOn() */ isSpeakerphoneOn()6709 public boolean isSpeakerphoneOn() { 6710 return mDeviceBroker.isSpeakerphoneOn(); 6711 } 6712 6713 6714 /** BT SCO audio state seen by apps using the deprecated API setBluetoothScoOn(). 6715 * @see isBluetoothScoOn() */ 6716 private boolean mBtScoOnByApp; 6717 6718 /** @see AudioManager#setBluetoothScoOn(boolean) */ setBluetoothScoOn(boolean on)6719 public void setBluetoothScoOn(boolean on) { 6720 if (!checkAudioSettingsPermission("setBluetoothScoOn()")) { 6721 return; 6722 } 6723 6724 // Only enable calls from system components 6725 if (UserHandle.getCallingAppId() >= FIRST_APPLICATION_UID) { 6726 mBtScoOnByApp = on; 6727 return; 6728 } 6729 6730 // for logging only 6731 final int uid = Binder.getCallingUid(); 6732 final int pid = Binder.getCallingPid(); 6733 final String eventSource = new StringBuilder("setBluetoothScoOn(").append(on) 6734 .append(") from u/pid:").append(uid).append("/").append(pid).toString(); 6735 6736 //bt sco 6737 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 6738 + MediaMetrics.SEPARATOR + "setBluetoothScoOn") 6739 .setUid(uid) 6740 .setPid(pid) 6741 .set(MediaMetrics.Property.STATE, on 6742 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 6743 .record(); 6744 6745 mDeviceBroker.setBluetoothScoOn(on, eventSource); 6746 } 6747 6748 /** @see AudioManager#setA2dpSuspended(boolean) */ 6749 @android.annotation.EnforcePermission(BLUETOOTH_STACK) setA2dpSuspended(boolean enable)6750 public void setA2dpSuspended(boolean enable) { 6751 super.setA2dpSuspended_enforcePermission(); 6752 final String eventSource = new StringBuilder("setA2dpSuspended(").append(enable) 6753 .append(") from u/pid:").append(Binder.getCallingUid()).append("/") 6754 .append(Binder.getCallingPid()).toString(); 6755 mDeviceBroker.setA2dpSuspended(enable, false /*internal*/, eventSource); 6756 } 6757 6758 /** @see AudioManager#setA2dpSuspended(boolean) */ 6759 @android.annotation.EnforcePermission(BLUETOOTH_STACK) setLeAudioSuspended(boolean enable)6760 public void setLeAudioSuspended(boolean enable) { 6761 super.setLeAudioSuspended_enforcePermission(); 6762 final String eventSource = new StringBuilder("setLeAudioSuspended(").append(enable) 6763 .append(") from u/pid:").append(Binder.getCallingUid()).append("/") 6764 .append(Binder.getCallingPid()).toString(); 6765 mDeviceBroker.setLeAudioSuspended(enable, false /*internal*/, eventSource); 6766 } 6767 6768 /** @see AudioManager#isBluetoothScoOn() 6769 * Note that it doesn't report internal state, but state seen by apps (which may have 6770 * called setBluetoothScoOn() */ isBluetoothScoOn()6771 public boolean isBluetoothScoOn() { 6772 return mBtScoOnByApp || mDeviceBroker.isBluetoothScoOn(); 6773 } 6774 6775 // TODO investigate internal users due to deprecation of SDK API 6776 /** @see AudioManager#setBluetoothA2dpOn(boolean) */ setBluetoothA2dpOn(boolean on)6777 public void setBluetoothA2dpOn(boolean on) { 6778 if (!checkAudioSettingsPermission("setBluetoothA2dpOn()")) { 6779 return; 6780 } 6781 6782 // for logging only 6783 final int uid = Binder.getCallingUid(); 6784 final int pid = Binder.getCallingPid(); 6785 final String eventSource = new StringBuilder("setBluetoothA2dpOn(").append(on) 6786 .append(") from u/pid:").append(uid).append("/") 6787 .append(pid).toString(); 6788 6789 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 6790 + MediaMetrics.SEPARATOR + "setBluetoothA2dpOn") 6791 .setUid(uid) 6792 .setPid(pid) 6793 .set(MediaMetrics.Property.STATE, on 6794 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 6795 .record(); 6796 6797 mDeviceBroker.setBluetoothA2dpOn_Async(on, eventSource); 6798 } 6799 6800 /** @see AudioManager#isBluetoothA2dpOn() */ isBluetoothA2dpOn()6801 public boolean isBluetoothA2dpOn() { 6802 return mDeviceBroker.isBluetoothA2dpOn(); 6803 } 6804 6805 /** @see AudioManager#startBluetoothSco() */ startBluetoothSco(IBinder cb, int targetSdkVersion)6806 public void startBluetoothSco(IBinder cb, int targetSdkVersion) { 6807 if (!checkAudioSettingsPermission("startBluetoothSco()")) { 6808 return; 6809 } 6810 6811 final int uid = Binder.getCallingUid(); 6812 final int pid = Binder.getCallingPid(); 6813 final int scoAudioMode = 6814 (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ? 6815 BtHelper.SCO_MODE_VIRTUAL_CALL : BtHelper.SCO_MODE_UNDEFINED; 6816 final String eventSource = new StringBuilder("startBluetoothSco()") 6817 .append(") from u/pid:").append(uid).append("/") 6818 .append(pid).toString(); 6819 6820 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 6821 .setUid(uid) 6822 .setPid(pid) 6823 .set(MediaMetrics.Property.EVENT, "startBluetoothSco") 6824 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 6825 BtHelper.scoAudioModeToString(scoAudioMode)) 6826 .record(); 6827 startBluetoothScoInt(cb, uid, scoAudioMode, eventSource); 6828 6829 } 6830 6831 /** @see AudioManager#startBluetoothScoVirtualCall() */ startBluetoothScoVirtualCall(IBinder cb)6832 public void startBluetoothScoVirtualCall(IBinder cb) { 6833 if (!checkAudioSettingsPermission("startBluetoothScoVirtualCall()")) { 6834 return; 6835 } 6836 6837 final int uid = Binder.getCallingUid(); 6838 final int pid = Binder.getCallingPid(); 6839 final String eventSource = new StringBuilder("startBluetoothScoVirtualCall()") 6840 .append(") from u/pid:").append(uid).append("/") 6841 .append(pid).toString(); 6842 6843 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 6844 .setUid(uid) 6845 .setPid(pid) 6846 .set(MediaMetrics.Property.EVENT, "startBluetoothScoVirtualCall") 6847 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 6848 BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_VIRTUAL_CALL)) 6849 .record(); 6850 startBluetoothScoInt(cb, uid, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource); 6851 } 6852 startBluetoothScoInt(IBinder cb, int uid, int scoAudioMode, @NonNull String eventSource)6853 void startBluetoothScoInt(IBinder cb, int uid, int scoAudioMode, @NonNull String eventSource) { 6854 MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 6855 .set(MediaMetrics.Property.EVENT, "startBluetoothScoInt") 6856 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 6857 BtHelper.scoAudioModeToString(scoAudioMode)); 6858 6859 if (!checkAudioSettingsPermission("startBluetoothSco()") || 6860 !mSystemReady) { 6861 mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission or systemReady").record(); 6862 return; 6863 } 6864 final boolean isPrivileged = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE) 6865 == PackageManager.PERMISSION_GRANTED; 6866 final long ident = Binder.clearCallingIdentity(); 6867 try { 6868 mDeviceBroker.startBluetoothScoForClient( 6869 cb, uid, scoAudioMode, isPrivileged, eventSource); 6870 } finally { 6871 Binder.restoreCallingIdentity(ident); 6872 } 6873 mmi.record(); 6874 } 6875 6876 /** @see AudioManager#stopBluetoothSco() */ stopBluetoothSco(IBinder cb)6877 public void stopBluetoothSco(IBinder cb){ 6878 if (!checkAudioSettingsPermission("stopBluetoothSco()") || 6879 !mSystemReady) { 6880 return; 6881 } 6882 final int uid = Binder.getCallingUid(); 6883 final int pid = Binder.getCallingPid(); 6884 final String eventSource = new StringBuilder("stopBluetoothSco()") 6885 .append(") from u/pid:").append(uid).append("/") 6886 .append(pid).toString(); 6887 final boolean isPrivileged = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE) 6888 == PackageManager.PERMISSION_GRANTED; 6889 final long ident = Binder.clearCallingIdentity(); 6890 try { 6891 mDeviceBroker.stopBluetoothScoForClient(cb, uid, isPrivileged, eventSource); 6892 } finally { 6893 Binder.restoreCallingIdentity(ident); 6894 } 6895 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 6896 .setUid(uid) 6897 .setPid(pid) 6898 .set(MediaMetrics.Property.EVENT, "stopBluetoothSco") 6899 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 6900 BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_UNDEFINED)) 6901 .record(); 6902 } 6903 6904 getContentResolver()6905 /*package*/ ContentResolver getContentResolver() { 6906 return mContentResolver; 6907 } 6908 6909 @VisibleForTesting(visibility = PACKAGE) getSettings()6910 public SettingsAdapter getSettings() { 6911 return mSettings; 6912 } 6913 6914 /////////////////////////////////////////////////////////////////////////// 6915 // Internal methods 6916 /////////////////////////////////////////////////////////////////////////// 6917 6918 /** 6919 * Checks if the adjustment should change ringer mode instead of just 6920 * adjusting volume. If so, this will set the proper ringer mode and volume 6921 * indices on the stream states. 6922 */ checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, String caller, int flags)6923 private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, 6924 String caller, int flags) { 6925 int result = FLAG_ADJUST_VOLUME; 6926 if (isPlatformTelevision() || mIsSingleVolume) { 6927 return result; 6928 } 6929 6930 int ringerMode = getRingerModeInternal(); 6931 6932 switch (ringerMode) { 6933 case RINGER_MODE_NORMAL: 6934 if (direction == AudioManager.ADJUST_LOWER) { 6935 if (mHasVibrator) { 6936 // "step" is the delta in internal index units corresponding to a 6937 // change of 1 in UI index units. 6938 // Because of rounding when rescaling from one stream index range to its alias 6939 // index range, we cannot simply test oldIndex == step: 6940 // (step <= oldIndex < 2 * step) is equivalent to: (old UI index == 1) 6941 if (step <= oldIndex && oldIndex < 2 * step) { 6942 ringerMode = RINGER_MODE_VIBRATE; 6943 mLoweredFromNormalToVibrateTime = SystemClock.uptimeMillis(); 6944 } 6945 } else { 6946 if (oldIndex == step && mVolumePolicy.volumeDownToEnterSilent) { 6947 ringerMode = RINGER_MODE_SILENT; 6948 } 6949 } 6950 } 6951 break; 6952 case RINGER_MODE_VIBRATE: 6953 if (!mHasVibrator) { 6954 Log.e(TAG, "checkForRingerModeChange() current ringer mode is vibrate" + 6955 "but no vibrator is present"); 6956 break; 6957 } 6958 if (direction == AudioManager.ADJUST_LOWER) { 6959 if (mPrevVolDirection != AudioManager.ADJUST_LOWER) { 6960 if (mVolumePolicy.volumeDownToEnterSilent) { 6961 final long diff = SystemClock.uptimeMillis() 6962 - mLoweredFromNormalToVibrateTime; 6963 if (diff > mVolumePolicy.vibrateToSilentDebounce 6964 && mRingerModeDelegate.canVolumeDownEnterSilent()) { 6965 ringerMode = RINGER_MODE_SILENT; 6966 } 6967 } else { 6968 result |= AudioManager.FLAG_SHOW_VIBRATE_HINT; 6969 } 6970 } 6971 } else if (direction == AudioManager.ADJUST_RAISE 6972 || direction == AudioManager.ADJUST_TOGGLE_MUTE 6973 || direction == AudioManager.ADJUST_UNMUTE) { 6974 ringerMode = RINGER_MODE_NORMAL; 6975 } 6976 result &= ~FLAG_ADJUST_VOLUME; 6977 break; 6978 case RINGER_MODE_SILENT: 6979 if (direction == AudioManager.ADJUST_RAISE 6980 || direction == AudioManager.ADJUST_TOGGLE_MUTE 6981 || direction == AudioManager.ADJUST_UNMUTE) { 6982 if (!mVolumePolicy.volumeUpToExitSilent) { 6983 result |= AudioManager.FLAG_SHOW_SILENT_HINT; 6984 } else { 6985 if (mHasVibrator && direction == AudioManager.ADJUST_RAISE) { 6986 ringerMode = RINGER_MODE_VIBRATE; 6987 } else { 6988 // If we don't have a vibrator or they were toggling mute 6989 // go straight back to normal. 6990 ringerMode = RINGER_MODE_NORMAL; 6991 } 6992 } 6993 } 6994 result &= ~FLAG_ADJUST_VOLUME; 6995 break; 6996 default: 6997 Log.e(TAG, "checkForRingerModeChange() wrong ringer mode: "+ringerMode); 6998 break; 6999 } 7000 7001 if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode) 7002 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller) 7003 && (flags & AudioManager.FLAG_FROM_KEY) == 0) { 7004 throw new SecurityException("Not allowed to change Do Not Disturb state"); 7005 } 7006 7007 setRingerMode(ringerMode, TAG + ".checkForRingerModeChange", false /*external*/); 7008 7009 mPrevVolDirection = direction; 7010 7011 return result; 7012 } 7013 7014 @Override isStreamAffectedByRingerMode(int streamType)7015 public boolean isStreamAffectedByRingerMode(int streamType) { 7016 return (mRingerModeAffectedStreams & (1 << streamType)) != 0; 7017 } 7018 isStreamAffectedByCurrentZen(int streamType)7019 public boolean isStreamAffectedByCurrentZen(int streamType) { 7020 return (mZenModeAffectedStreams & (1 << streamType)) != 0; 7021 } 7022 isStreamMutedByRingerOrZenMode(int streamType)7023 private boolean isStreamMutedByRingerOrZenMode(int streamType) { 7024 return (sRingerAndZenModeMutedStreams & (1 << streamType)) != 0; 7025 } 7026 7027 /** 7028 * Volume streams can be muted based on the current DND state: 7029 * DND total silence: ringer, notification, system, media and alarms streams muted by DND 7030 * DND alarms only: ringer, notification, system streams muted by DND 7031 * DND priority only: alarms, media, system, ringer and notification streams can be muted by 7032 * DND. The current applied zenPolicy determines which streams will be muted by DND. 7033 * @return true if changed, else false 7034 */ updateZenModeAffectedStreams()7035 private boolean updateZenModeAffectedStreams() { 7036 if (!mSystemReady) { 7037 return false; 7038 } 7039 7040 // If DND is off, no streams are muted by DND 7041 int zenModeAffectedStreams = 0; 7042 final int zenMode = mNm.getZenMode(); 7043 7044 if (zenMode == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS) { 7045 zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM; 7046 zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION; 7047 zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING; 7048 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM; 7049 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC; 7050 } else if (zenMode == Settings.Global.ZEN_MODE_ALARMS) { 7051 zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM; 7052 zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION; 7053 zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING; 7054 } else if (zenMode == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { 7055 NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy(); 7056 if ((zenPolicy.priorityCategories 7057 & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0) { 7058 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM; 7059 } 7060 7061 if ((zenPolicy.priorityCategories 7062 & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0) { 7063 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC; 7064 } 7065 7066 // even if zen isn't muting the system stream, the ringer mode can still mute 7067 // the system stream 7068 if ((zenPolicy.priorityCategories 7069 & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) { 7070 zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM; 7071 } 7072 7073 if (ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(zenPolicy)) { 7074 zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION; 7075 zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING; 7076 } 7077 } 7078 7079 if (mZenModeAffectedStreams != zenModeAffectedStreams) { 7080 mZenModeAffectedStreams = zenModeAffectedStreams; 7081 return true; 7082 } 7083 7084 return false; 7085 } 7086 7087 @GuardedBy("mSettingsLock") updateRingerAndZenModeAffectedStreams()7088 private boolean updateRingerAndZenModeAffectedStreams() { 7089 boolean updatedZenModeAffectedStreams = updateZenModeAffectedStreams(); 7090 int ringerModeAffectedStreams = mSettings.getSystemIntForUser(mContentResolver, 7091 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 7092 ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)| 7093 (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)), 7094 UserHandle.USER_CURRENT); 7095 if (mIsSingleVolume) { 7096 ringerModeAffectedStreams = 0; 7097 } else if (mRingerModeDelegate != null) { 7098 ringerModeAffectedStreams = mRingerModeDelegate 7099 .getRingerModeAffectedStreams(ringerModeAffectedStreams); 7100 } 7101 if (mCameraSoundForced) { 7102 ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 7103 } else { 7104 ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 7105 } 7106 if (mStreamVolumeAlias[AudioSystem.STREAM_DTMF] == AudioSystem.STREAM_RING) { 7107 ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF); 7108 } else { 7109 ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF); 7110 } 7111 7112 if (ringerModeAffectsAlarm()) { 7113 if (mRingerModeAffectsAlarm) { 7114 boolean muteAlarmWithRinger = 7115 mSettings.getGlobalInt(mContentResolver, 7116 Settings.Global.MUTE_ALARM_STREAM_WITH_RINGER_MODE, 7117 /* def= */ 0) != 0; 7118 if (muteAlarmWithRinger) { 7119 ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_ALARM); 7120 } else { 7121 ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_ALARM); 7122 } 7123 } 7124 } 7125 if (ringerModeAffectedStreams != mRingerModeAffectedStreams) { 7126 mSettings.putSystemIntForUser(mContentResolver, 7127 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 7128 ringerModeAffectedStreams, 7129 UserHandle.USER_CURRENT); 7130 mRingerModeAffectedStreams = ringerModeAffectedStreams; 7131 return true; 7132 } 7133 return updatedZenModeAffectedStreams; 7134 } 7135 7136 @Override isStreamAffectedByMute(int streamType)7137 public boolean isStreamAffectedByMute(int streamType) { 7138 return (mMuteAffectedStreams & (1 << streamType)) != 0; 7139 } 7140 7141 @Override isStreamMutableByUi(int streamType)7142 public boolean isStreamMutableByUi(int streamType) { 7143 return (mUserMutableStreams & (1 << streamType)) != 0; 7144 } 7145 ensureValidDirection(int direction)7146 private void ensureValidDirection(int direction) { 7147 switch (direction) { 7148 case AudioManager.ADJUST_LOWER: 7149 case AudioManager.ADJUST_RAISE: 7150 case AudioManager.ADJUST_SAME: 7151 case AudioManager.ADJUST_MUTE: 7152 case AudioManager.ADJUST_UNMUTE: 7153 case AudioManager.ADJUST_TOGGLE_MUTE: 7154 break; 7155 default: 7156 throw new IllegalArgumentException("Bad direction " + direction); 7157 } 7158 } 7159 ensureValidStreamType(int streamType)7160 private void ensureValidStreamType(int streamType) { 7161 if (streamType < 0 || streamType >= mStreamStates.length) { 7162 throw new IllegalArgumentException("Bad stream type " + streamType); 7163 } 7164 } 7165 isMuteAdjust(int adjust)7166 private boolean isMuteAdjust(int adjust) { 7167 return adjust == AudioManager.ADJUST_MUTE || adjust == AudioManager.ADJUST_UNMUTE 7168 || adjust == AudioManager.ADJUST_TOGGLE_MUTE; 7169 } 7170 7171 /** only public for mocking/spying, do not call outside of AudioService */ 7172 @VisibleForTesting isInCommunication()7173 public boolean isInCommunication() { 7174 boolean IsInCall = false; 7175 7176 TelecomManager telecomManager = 7177 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 7178 7179 final long ident = Binder.clearCallingIdentity(); 7180 try { 7181 IsInCall = telecomManager.isInCall(); 7182 } finally { 7183 Binder.restoreCallingIdentity(ident); 7184 } 7185 7186 int mode = mMode.get(); 7187 return (IsInCall 7188 || mode == AudioManager.MODE_IN_COMMUNICATION 7189 || mode == AudioManager.MODE_IN_CALL); 7190 } 7191 7192 /** 7193 * For code clarity for getActiveStreamType(int) 7194 * @param delay_ms max time since last stream activity to consider 7195 * @return true if stream is active in streams handled by AudioFlinger now or 7196 * in the last "delay_ms" ms. 7197 */ wasStreamActiveRecently(int stream, int delay_ms)7198 private boolean wasStreamActiveRecently(int stream, int delay_ms) { 7199 return mAudioSystem.isStreamActive(stream, delay_ms) 7200 || mAudioSystem.isStreamActiveRemotely(stream, delay_ms); 7201 } 7202 getActiveStreamType(int suggestedStreamType)7203 private int getActiveStreamType(int suggestedStreamType) { 7204 if (mIsSingleVolume 7205 && suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 7206 return AudioSystem.STREAM_MUSIC; 7207 } 7208 7209 switch (mPlatformType) { 7210 case AudioSystem.PLATFORM_VOICE: 7211 if (isInCommunication() 7212 || mAudioSystem.isStreamActive(AudioManager.STREAM_VOICE_CALL, 0)) { 7213 if (mDeviceBroker.isBluetoothScoActive()) { 7214 // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO..."); 7215 return AudioSystem.STREAM_BLUETOOTH_SCO; 7216 } else { 7217 // Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL..."); 7218 return AudioSystem.STREAM_VOICE_CALL; 7219 } 7220 } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 7221 if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 7222 if (DEBUG_VOL) 7223 Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active"); 7224 return AudioSystem.STREAM_RING; 7225 } else if (wasStreamActiveRecently( 7226 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 7227 if (DEBUG_VOL) { 7228 Log.v( 7229 TAG, 7230 "getActiveStreamType: Forcing STREAM_NOTIFICATION stream" 7231 + " active"); 7232 } 7233 return AudioSystem.STREAM_NOTIFICATION; 7234 } else { 7235 if (DEBUG_VOL) { 7236 Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK(" 7237 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default"); 7238 } 7239 return DEFAULT_VOL_STREAM_NO_PLAYBACK; 7240 } 7241 } else if ( 7242 wasStreamActiveRecently(AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 7243 if (DEBUG_VOL) 7244 Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active"); 7245 return AudioSystem.STREAM_NOTIFICATION; 7246 } else if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 7247 if (DEBUG_VOL) 7248 Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active"); 7249 return AudioSystem.STREAM_RING; 7250 } 7251 default: 7252 if (isInCommunication()) { 7253 if (mDeviceBroker.isBluetoothScoActive()) { 7254 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO"); 7255 return AudioSystem.STREAM_BLUETOOTH_SCO; 7256 } else { 7257 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL"); 7258 return AudioSystem.STREAM_VOICE_CALL; 7259 } 7260 } else if (mAudioSystem.isStreamActive( 7261 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 7262 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION"); 7263 return AudioSystem.STREAM_NOTIFICATION; 7264 } else if (mAudioSystem.isStreamActive( 7265 AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 7266 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING"); 7267 return AudioSystem.STREAM_RING; 7268 } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 7269 if (mAudioSystem.isStreamActive( 7270 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 7271 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION"); 7272 return AudioSystem.STREAM_NOTIFICATION; 7273 } 7274 if (mAudioSystem.isStreamActive( 7275 AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 7276 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING"); 7277 return AudioSystem.STREAM_RING; 7278 } 7279 if (DEBUG_VOL) { 7280 Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK(" 7281 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default"); 7282 } 7283 return DEFAULT_VOL_STREAM_NO_PLAYBACK; 7284 } 7285 break; 7286 } 7287 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Returning suggested type " 7288 + suggestedStreamType); 7289 return suggestedStreamType; 7290 } 7291 broadcastRingerMode(String action, int ringerMode)7292 private void broadcastRingerMode(String action, int ringerMode) { 7293 if (!mSystemServer.isPrivileged()) { 7294 return; 7295 } 7296 // Send sticky broadcast 7297 Intent broadcast = new Intent(action); 7298 broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, ringerMode); 7299 broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 7300 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 7301 sendStickyBroadcastToAll(broadcast); 7302 } 7303 broadcastVibrateSetting(int vibrateType)7304 private void broadcastVibrateSetting(int vibrateType) { 7305 if (!mSystemServer.isPrivileged()) { 7306 return; 7307 } 7308 // Send broadcast 7309 if (mActivityManagerInternal.isSystemReady()) { 7310 Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION); 7311 broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType); 7312 broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType)); 7313 sendBroadcastToAll(broadcast, null /* options */); 7314 } 7315 } 7316 7317 // Message helper methods 7318 /** 7319 * Queue a message on the given handler's message queue, after acquiring the service wake lock. 7320 * Note that the wake lock needs to be released after the message has been handled. 7321 */ queueMsgUnderWakeLock(Handler handler, int msg, int arg1, int arg2, Object obj, int delay)7322 private void queueMsgUnderWakeLock(Handler handler, int msg, 7323 int arg1, int arg2, Object obj, int delay) { 7324 final long ident = Binder.clearCallingIdentity(); 7325 try { 7326 // Always acquire the wake lock as AudioService because it is released by the 7327 // message handler. 7328 mAudioEventWakeLock.acquire(); 7329 } finally { 7330 Binder.restoreCallingIdentity(ident); 7331 } 7332 sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay); 7333 } 7334 sendMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, int delay)7335 private static void sendMsg(Handler handler, int msg, 7336 int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) { 7337 if (existingMsgPolicy == SENDMSG_REPLACE) { 7338 handler.removeMessages(msg); 7339 } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) { 7340 return; 7341 } 7342 7343 final long time = SystemClock.uptimeMillis() + delay; 7344 handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time); 7345 } 7346 sendBundleMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, Bundle bundle, int delay)7347 private static void sendBundleMsg(Handler handler, int msg, 7348 int existingMsgPolicy, int arg1, int arg2, Object obj, Bundle bundle, int delay) { 7349 if (existingMsgPolicy == SENDMSG_REPLACE) { 7350 handler.removeMessages(msg); 7351 } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) { 7352 return; 7353 } 7354 7355 final long time = SystemClock.uptimeMillis() + delay; 7356 Message message = handler.obtainMessage(msg, arg1, arg2, obj); 7357 message.setData(bundle); 7358 handler.sendMessageAtTime(message, time); 7359 } 7360 checkAudioSettingsPermission(String method)7361 boolean checkAudioSettingsPermission(String method) { 7362 if (callingOrSelfHasAudioSettingsPermission()) { 7363 return true; 7364 } 7365 String msg = "Audio Settings Permission Denial: " + method + " from pid=" 7366 + Binder.getCallingPid() 7367 + ", uid=" + Binder.getCallingUid(); 7368 Log.w(TAG, msg); 7369 return false; 7370 } 7371 callingOrSelfHasAudioSettingsPermission()7372 private boolean callingOrSelfHasAudioSettingsPermission() { 7373 return mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_SETTINGS) 7374 == PackageManager.PERMISSION_GRANTED; 7375 } 7376 callingHasAudioSettingsPermission()7377 private boolean callingHasAudioSettingsPermission() { 7378 return mContext.checkCallingPermission(MODIFY_AUDIO_SETTINGS) 7379 == PackageManager.PERMISSION_GRANTED; 7380 } 7381 hasAudioSettingsPermission(int uid, int pid)7382 private boolean hasAudioSettingsPermission(int uid, int pid) { 7383 return mContext.checkPermission(MODIFY_AUDIO_SETTINGS, pid, uid) 7384 == PackageManager.PERMISSION_GRANTED; 7385 } 7386 7387 /** 7388 * Minimum attenuation that can be set for alarms over speaker by an application that 7389 * doesn't have the MODIFY_AUDIO_SETTINGS permission. 7390 */ 7391 protected static final float MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB = -36.0f; 7392 7393 /** 7394 * Configures the VolumeStreamState instances for minimum stream index that can be accessed 7395 * without MODIFY_AUDIO_SETTINGS permission. 7396 * Can only be done successfully once audio policy has finished reading its configuration files 7397 * for the volume curves. If not, getStreamVolumeDB will return NaN, and the min value will 7398 * remain at the stream min index value. 7399 */ initMinStreamVolumeWithoutModifyAudioSettings()7400 protected void initMinStreamVolumeWithoutModifyAudioSettings() { 7401 int idx; 7402 int deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER_SAFE; 7403 if (Float.isNaN(AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, 7404 MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM], deviceForAlarm))) { 7405 deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER; 7406 } 7407 for (idx = MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; 7408 idx >= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; idx--) { 7409 if (AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, idx, deviceForAlarm) 7410 < MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB) { 7411 break; 7412 } 7413 } 7414 final int safeIndex = idx <= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM] 7415 ? MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM] 7416 : Math.min(idx + 1, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]); 7417 // update the VolumeStreamState for STREAM_ALARM and its aliases 7418 for (int stream : mStreamVolumeAlias) { 7419 if (mStreamVolumeAlias[stream] == AudioSystem.STREAM_ALARM) { 7420 mStreamStates[stream].updateNoPermMinIndex(safeIndex); 7421 } 7422 } 7423 } 7424 7425 /** 7426 * Returns device associated with the stream volume. 7427 * 7428 * Only public for mocking/spying, do not call outside of AudioService. 7429 * Device volume aliasing means DEVICE_OUT_SPEAKER may be returned for 7430 * DEVICE_OUT_SPEAKER_SAFE. 7431 */ 7432 @VisibleForTesting getDeviceForStream(int stream)7433 public int getDeviceForStream(int stream) { 7434 return selectOneAudioDevice(getDeviceSetForStream(stream)); 7435 } 7436 7437 /* 7438 * Must match native apm_extract_one_audio_device() used in getDeviceForVolume() 7439 * or the wrong device volume may be adjusted. 7440 */ selectOneAudioDevice(Set<Integer> deviceSet)7441 private int selectOneAudioDevice(Set<Integer> deviceSet) { 7442 if (deviceSet.isEmpty()) { 7443 return AudioSystem.DEVICE_NONE; 7444 } else if (deviceSet.size() == 1) { 7445 return deviceSet.iterator().next(); 7446 } else { 7447 // Multiple device selection is either: 7448 // - dock + one other device: give priority to dock in this case. 7449 // - speaker + one other device: give priority to speaker in this case. 7450 // - one A2DP device + another device: happens with duplicated output. In this case 7451 // retain the device on the A2DP output as the other must not correspond to an active 7452 // selection if not the speaker. 7453 // - HDMI-CEC system audio mode only output: give priority to available item in order. 7454 7455 if (deviceSet.contains(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET)) { 7456 return AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET; 7457 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER)) { 7458 return AudioSystem.DEVICE_OUT_SPEAKER; 7459 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER_SAFE)) { 7460 // Note: DEVICE_OUT_SPEAKER_SAFE not present in getDeviceSetForStreamDirect 7461 return AudioSystem.DEVICE_OUT_SPEAKER_SAFE; 7462 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_ARC)) { 7463 return AudioSystem.DEVICE_OUT_HDMI_ARC; 7464 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_EARC)) { 7465 return AudioSystem.DEVICE_OUT_HDMI_EARC; 7466 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_AUX_LINE)) { 7467 return AudioSystem.DEVICE_OUT_AUX_LINE; 7468 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPDIF)) { 7469 return AudioSystem.DEVICE_OUT_SPDIF; 7470 } else { 7471 // At this point, deviceSet should contain exactly one A2DP device; 7472 // regardless, return the first A2DP device in numeric order. 7473 // If there is no A2DP device, this falls through to log an error. 7474 for (int deviceType : deviceSet) { 7475 if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType)) { 7476 return deviceType; 7477 } 7478 } 7479 } 7480 } 7481 Log.w(TAG, "selectOneAudioDevice returning DEVICE_NONE from invalid device combination " 7482 + AudioSystem.deviceSetToString(deviceSet)); 7483 return AudioSystem.DEVICE_NONE; 7484 } 7485 7486 /** 7487 * @see AudioManager#getDevicesForStream(int) 7488 * @deprecated on {@link android.os.Build.VERSION_CODES#T} as new devices 7489 * will have multi-bit device types since S. 7490 * Use {@link #getDevicesForAttributes()} instead. 7491 */ 7492 @Override 7493 @Deprecated getDeviceMaskForStream(int streamType)7494 public int getDeviceMaskForStream(int streamType) { 7495 ensureValidStreamType(streamType); 7496 // no permission required 7497 final long token = Binder.clearCallingIdentity(); 7498 try { 7499 return AudioSystem.getDeviceMaskFromSet( 7500 getDeviceSetForStreamDirect(streamType)); 7501 } finally { 7502 Binder.restoreCallingIdentity(token); 7503 } 7504 } 7505 7506 /** 7507 * Returns the devices associated with a stream type. 7508 * 7509 * SPEAKER_SAFE will alias to SPEAKER. 7510 */ 7511 @NonNull getDeviceSetForStreamDirect(int stream)7512 private Set<Integer> getDeviceSetForStreamDirect(int stream) { 7513 final AudioAttributes attr = 7514 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream); 7515 Set<Integer> deviceSet = 7516 AudioSystem.generateAudioDeviceTypesSet( 7517 getDevicesForAttributesInt(attr, true /* forVolume */)); 7518 return deviceSet; 7519 } 7520 7521 /** 7522 * Returns a reference to the list of devices for the stream, do not modify. 7523 * 7524 * The device returned may be aliased to the actual device whose volume curve 7525 * will be used. For example DEVICE_OUT_SPEAKER_SAFE aliases to DEVICE_OUT_SPEAKER. 7526 */ 7527 @NonNull getDeviceSetForStream(int stream)7528 public Set<Integer> getDeviceSetForStream(int stream) { 7529 ensureValidStreamType(stream); 7530 synchronized (VolumeStreamState.class) { 7531 return mStreamStates[stream].observeDevicesForStream_syncVSS(true); 7532 } 7533 } 7534 onObserveDevicesForAllStreams(int skipStream)7535 private void onObserveDevicesForAllStreams(int skipStream) { 7536 synchronized (mSettingsLock) { 7537 synchronized (VolumeStreamState.class) { 7538 for (int stream = 0; stream < mStreamStates.length; stream++) { 7539 if (stream != skipStream) { 7540 Set<Integer> deviceSet = 7541 mStreamStates[stream].observeDevicesForStream_syncVSS( 7542 false /*checkOthers*/); 7543 for (Integer device : deviceSet) { 7544 // Update volume states for devices routed for the stream 7545 updateVolumeStates(device, stream, 7546 "AudioService#onObserveDevicesForAllStreams"); 7547 } 7548 } 7549 } 7550 } 7551 } 7552 } 7553 7554 /** only public for mocking/spying, do not call outside of AudioService */ 7555 @VisibleForTesting postObserveDevicesForAllStreams()7556 public void postObserveDevicesForAllStreams() { 7557 postObserveDevicesForAllStreams(-1); 7558 } 7559 7560 /** only public for mocking/spying, do not call outside of AudioService */ 7561 @VisibleForTesting postObserveDevicesForAllStreams(int skipStream)7562 public void postObserveDevicesForAllStreams(int skipStream) { 7563 sendMsg(mAudioHandler, 7564 MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS, 7565 SENDMSG_QUEUE, skipStream /*arg1*/, 0 /*arg2*/, null /*obj*/, 7566 0 /*delay*/); 7567 } 7568 7569 /** 7570 * @see AudioDeviceVolumeManager#setDeviceAbsoluteMultiVolumeBehavior 7571 * 7572 * @param register Whether the listener is to be registered or unregistered. If false, the 7573 * device adopts variable volume behavior. 7574 */ 7575 @RequiresPermission(anyOf = { MODIFY_AUDIO_ROUTING, BLUETOOTH_PRIVILEGED }) registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register, IAudioDeviceVolumeDispatcher cb, String packageName, AudioDeviceAttributes device, List<VolumeInfo> volumes, boolean handlesVolumeAdjustment, @AudioManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior)7576 public void registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register, 7577 IAudioDeviceVolumeDispatcher cb, String packageName, 7578 AudioDeviceAttributes device, List<VolumeInfo> volumes, 7579 boolean handlesVolumeAdjustment, 7580 @AudioManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior) { 7581 // verify permissions 7582 if (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING) 7583 != PackageManager.PERMISSION_GRANTED 7584 && mContext.checkCallingOrSelfPermission(BLUETOOTH_PRIVILEGED) 7585 != PackageManager.PERMISSION_GRANTED) { 7586 throw new SecurityException( 7587 "Missing MODIFY_AUDIO_ROUTING or BLUETOOTH_PRIVILEGED permissions"); 7588 } 7589 // verify arguments 7590 Objects.requireNonNull(device); 7591 Objects.requireNonNull(volumes); 7592 7593 int deviceOut = device.getInternalType(); 7594 if (register) { 7595 AbsoluteVolumeDeviceInfo info = new AbsoluteVolumeDeviceInfo( 7596 device, volumes, cb, handlesVolumeAdjustment, deviceVolumeBehavior); 7597 AbsoluteVolumeDeviceInfo oldInfo = mAbsoluteVolumeDeviceInfoMap.get(deviceOut); 7598 boolean volumeBehaviorChanged = (oldInfo == null) 7599 || (oldInfo.mDeviceVolumeBehavior != deviceVolumeBehavior); 7600 if (volumeBehaviorChanged) { 7601 removeAudioSystemDeviceOutFromFullVolumeDevices(deviceOut); 7602 removeAudioSystemDeviceOutFromFixedVolumeDevices(deviceOut); 7603 addAudioSystemDeviceOutToAbsVolumeDevices(deviceOut, info); 7604 7605 dispatchDeviceVolumeBehavior(device, deviceVolumeBehavior); 7606 } 7607 // Update stream volumes to the given device, if specified in a VolumeInfo. 7608 // Mute state is not updated because it is stream-wide - the only way to mute a 7609 // stream's output to a particular device is to set the volume index to zero. 7610 for (VolumeInfo volumeInfo : volumes) { 7611 if (volumeInfo.getVolumeIndex() != VolumeInfo.INDEX_NOT_SET 7612 && volumeInfo.getMinVolumeIndex() != VolumeInfo.INDEX_NOT_SET 7613 && volumeInfo.getMaxVolumeIndex() != VolumeInfo.INDEX_NOT_SET) { 7614 if (volumeInfo.hasStreamType()) { 7615 setStreamVolumeInt(volumeInfo.getStreamType(), 7616 rescaleIndex(volumeInfo, volumeInfo.getStreamType()), 7617 deviceOut, false /*force*/, packageName, 7618 true /*hasModifyAudioSettings*/); 7619 } else { 7620 for (int streamType : volumeInfo.getVolumeGroup().getLegacyStreamTypes()) { 7621 setStreamVolumeInt(streamType, rescaleIndex(volumeInfo, streamType), 7622 deviceOut, false /*force*/, packageName, 7623 true /*hasModifyAudioSettings*/); 7624 } 7625 } 7626 } 7627 } 7628 } else { 7629 boolean wasAbsVol = removeAudioSystemDeviceOutFromAbsVolumeDevices(deviceOut) != null; 7630 if (wasAbsVol) { 7631 dispatchDeviceVolumeBehavior(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE); 7632 } 7633 } 7634 } 7635 7636 /** 7637 * @see AudioManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int) 7638 * @param device the audio device to be affected 7639 * @param deviceVolumeBehavior one of the device behaviors 7640 */ 7641 @android.annotation.EnforcePermission(anyOf = { 7642 MODIFY_AUDIO_ROUTING, MODIFY_AUDIO_SETTINGS_PRIVILEGED }) setDeviceVolumeBehavior(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName)7643 public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device, 7644 @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName) { 7645 // verify permissions 7646 super.setDeviceVolumeBehavior_enforcePermission(); 7647 // verify arguments 7648 Objects.requireNonNull(device); 7649 AudioManager.enforceValidVolumeBehavior(deviceVolumeBehavior); 7650 7651 device = retrieveBluetoothAddress(device); 7652 7653 sVolumeLogger.enqueue(new EventLogger.StringEvent("setDeviceVolumeBehavior: dev:" 7654 + AudioSystem.getOutputDeviceName(device.getInternalType()) + " addr:" 7655 + Utils.anonymizeBluetoothAddress(device.getAddress()) + " behavior:" 7656 + AudioDeviceVolumeManager.volumeBehaviorName(deviceVolumeBehavior) 7657 + " pack:" + pkgName).printLog(TAG)); 7658 if (pkgName == null) { 7659 pkgName = ""; 7660 } 7661 if (device.getType() == TYPE_BLUETOOTH_A2DP) { 7662 avrcpSupportsAbsoluteVolume(device.getAddress(), 7663 deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE); 7664 return; 7665 } 7666 7667 setDeviceVolumeBehaviorInternal(device, deviceVolumeBehavior, pkgName); 7668 persistDeviceVolumeBehavior(device.getInternalType(), deviceVolumeBehavior); 7669 } 7670 setDeviceVolumeBehaviorInternal(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller)7671 private void setDeviceVolumeBehaviorInternal(@NonNull AudioDeviceAttributes device, 7672 @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller) { 7673 int audioSystemDeviceOut = device.getInternalType(); 7674 boolean volumeBehaviorChanged = false; 7675 // update device masks based on volume behavior 7676 switch (deviceVolumeBehavior) { 7677 case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE: 7678 volumeBehaviorChanged |= 7679 removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut) 7680 | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut) 7681 | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut) 7682 != null); 7683 break; 7684 case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED: 7685 volumeBehaviorChanged |= 7686 removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut) 7687 | addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut) 7688 | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut) 7689 != null); 7690 break; 7691 case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL: 7692 volumeBehaviorChanged |= 7693 addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut) 7694 | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut) 7695 | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut) 7696 != null); 7697 break; 7698 case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE: 7699 case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY: 7700 case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE: 7701 throw new IllegalArgumentException("Absolute volume unsupported for now"); 7702 } 7703 7704 if (volumeBehaviorChanged) { 7705 sendMsg(mAudioHandler, MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR, SENDMSG_QUEUE, 7706 deviceVolumeBehavior, 0, device, /*delay*/ 0); 7707 } 7708 7709 // log event and caller 7710 sDeviceLogger.enqueue(new EventLogger.StringEvent( 7711 "Volume behavior " + deviceVolumeBehavior + " for dev=0x" 7712 + Integer.toHexString(audioSystemDeviceOut) + " from:" + caller)); 7713 // make sure we have a volume entry for this device, and that volume is updated according 7714 // to volume behavior 7715 postUpdateVolumeStatesForAudioDevice(audioSystemDeviceOut, 7716 "setDeviceVolumeBehavior:" + caller); 7717 } 7718 7719 /** 7720 * @see AudioManager#getDeviceVolumeBehavior(AudioDeviceAttributes) 7721 * @param device the audio output device type 7722 * @return the volume behavior for the device 7723 */ 7724 @android.annotation.EnforcePermission(anyOf = { 7725 MODIFY_AUDIO_ROUTING, QUERY_AUDIO_STATE, MODIFY_AUDIO_SETTINGS_PRIVILEGED 7726 }) 7727 public @AudioManager.DeviceVolumeBehavior getDeviceVolumeBehavior(@onNull AudioDeviceAttributes device)7728 int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) { 7729 // verify permissions 7730 super.getDeviceVolumeBehavior_enforcePermission(); 7731 // verify parameters 7732 Objects.requireNonNull(device); 7733 7734 device = retrieveBluetoothAddress(device); 7735 7736 return getDeviceVolumeBehaviorInt(device); 7737 } 7738 7739 private @AudioManager.DeviceVolumeBehavior getDeviceVolumeBehaviorInt(@onNull AudioDeviceAttributes device)7740 int getDeviceVolumeBehaviorInt(@NonNull AudioDeviceAttributes device) { 7741 // Get the internal type set by the AudioDeviceAttributes constructor which is always more 7742 // exact (avoids double conversions) than a conversion from SDK type via 7743 // AudioDeviceInfo.convertDeviceTypeToInternalDevice() 7744 final int audioSystemDeviceOut = device.getInternalType(); 7745 7746 // setDeviceVolumeBehavior has not been explicitly called for the device type. Deduce the 7747 // current volume behavior. 7748 if (mFullVolumeDevices.contains(audioSystemDeviceOut)) { 7749 return AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL; 7750 } 7751 if (mFixedVolumeDevices.contains(audioSystemDeviceOut)) { 7752 return AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED; 7753 } 7754 if (mAbsVolumeMultiModeCaseDevices.contains(audioSystemDeviceOut)) { 7755 return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE; 7756 } 7757 if (mAbsoluteVolumeDeviceInfoMap.containsKey(audioSystemDeviceOut)) { 7758 return mAbsoluteVolumeDeviceInfoMap.get(audioSystemDeviceOut).mDeviceVolumeBehavior; 7759 } 7760 7761 if (isA2dpAbsoluteVolumeDevice(audioSystemDeviceOut) 7762 || AudioSystem.isLeAudioDeviceType(audioSystemDeviceOut)) { 7763 return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE; 7764 } 7765 return AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE; 7766 } 7767 7768 /** 7769 * @see AudioManager#isVolumeFixed() 7770 * Note there are no permission checks on this operation, as this is part of API 21 7771 * @return true if the current device's volume behavior for media is 7772 * DEVICE_VOLUME_BEHAVIOR_FIXED 7773 */ isVolumeFixed()7774 public boolean isVolumeFixed() { 7775 if (mUseFixedVolume) { 7776 return true; 7777 } 7778 final AudioAttributes attributes = new AudioAttributes.Builder() 7779 .setUsage(AudioAttributes.USAGE_MEDIA) 7780 .build(); 7781 // calling getDevice*Int to bypass permission check 7782 final List<AudioDeviceAttributes> devices = 7783 getDevicesForAttributesInt(attributes, true /* forVolume */); 7784 for (AudioDeviceAttributes device : devices) { 7785 if (getDeviceVolumeBehaviorInt(device) == AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED) { 7786 return true; 7787 } 7788 } 7789 return false; 7790 } 7791 7792 /*package*/ static final int CONNECTION_STATE_DISCONNECTED = 0; 7793 /*package*/ static final int CONNECTION_STATE_CONNECTED = 1; 7794 /** 7795 * The states that can be used with AudioService.setWiredDeviceConnectionState() 7796 * Attention: those values differ from those in BluetoothProfile, follow annotations to 7797 * distinguish between @ConnectionState and @BtProfileConnectionState 7798 */ 7799 @IntDef({ 7800 CONNECTION_STATE_DISCONNECTED, 7801 CONNECTION_STATE_CONNECTED, 7802 }) 7803 @Retention(RetentionPolicy.SOURCE) 7804 public @interface ConnectionState {} 7805 7806 /** 7807 * Default SAD for a TV using ARC, used when the Amplifier didn't report any SADs. 7808 * Represents 2-channel LPCM including all defined sample rates and bit depths. 7809 * For the format definition, see Table 34 in the CEA standard CEA-861-D. 7810 */ 7811 private static final byte[] DEFAULT_ARC_AUDIO_DESCRIPTOR = new byte[]{0x09, 0x7f, 0x07}; 7812 7813 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 7814 /** 7815 * see AudioManager.setWiredDeviceConnectionState() 7816 */ setWiredDeviceConnectionState(@onNull AudioDeviceAttributes attributes, @ConnectionState int state, String caller)7817 public void setWiredDeviceConnectionState(@NonNull AudioDeviceAttributes attributes, 7818 @ConnectionState int state, String caller) { 7819 super.setWiredDeviceConnectionState_enforcePermission(); 7820 Objects.requireNonNull(attributes); 7821 7822 attributes = retrieveBluetoothAddress(attributes); 7823 7824 // When using ARC, a TV should use default 2 channel LPCM if the Amplifier didn't 7825 // report any SADs. See section 13.15.3 of the HDMI-CEC spec version 1.4b. 7826 if (attributes.getType() == AudioDeviceInfo.TYPE_HDMI_ARC 7827 && attributes.getRole() == AudioDeviceAttributes.ROLE_OUTPUT 7828 && attributes.getAudioDescriptors().isEmpty()) { 7829 attributes = new AudioDeviceAttributes( 7830 attributes.getRole(), 7831 attributes.getType(), 7832 attributes.getAddress(), 7833 attributes.getName(), 7834 attributes.getAudioProfiles(), 7835 new ArrayList<AudioDescriptor>(Collections.singletonList( 7836 new AudioDescriptor( 7837 AudioDescriptor.STANDARD_EDID, 7838 AudioProfile.AUDIO_ENCAPSULATION_TYPE_NONE, 7839 DEFAULT_ARC_AUDIO_DESCRIPTOR 7840 ) 7841 )) 7842 ); 7843 } 7844 7845 if (state != CONNECTION_STATE_CONNECTED 7846 && state != CONNECTION_STATE_DISCONNECTED) { 7847 throw new IllegalArgumentException("Invalid state " + state); 7848 } 7849 new MediaMetrics.Item(mMetricsId + "setWiredDeviceConnectionState") 7850 .set(MediaMetrics.Property.ADDRESS, attributes.getAddress()) 7851 .set(MediaMetrics.Property.CLIENT_NAME, caller) 7852 .set(MediaMetrics.Property.DEVICE, 7853 AudioSystem.getDeviceName(attributes.getInternalType())) 7854 .set(MediaMetrics.Property.NAME, attributes.getName()) 7855 .set(MediaMetrics.Property.STATE, 7856 state == CONNECTION_STATE_CONNECTED ? "connected" : "disconnected") 7857 .record(); 7858 mDeviceBroker.setWiredDeviceConnectionState(attributes, state, caller); 7859 // The Dynamic Soundbar mode feature introduces dynamic presence for an HDMI Audio System 7860 // Client. For example, the device can start with the Audio System Client unavailable. 7861 // When the feature is activated the client becomes available, therefore Audio Service 7862 // requests a new HDMI Audio System Client instance when the ARC status is changed. 7863 if (attributes.getInternalType() == AudioSystem.DEVICE_IN_HDMI_ARC) { 7864 updateHdmiAudioSystemClient(); 7865 } 7866 } 7867 7868 /** 7869 * Replace the current HDMI Audio System Client. 7870 * See {@link #setWiredDeviceConnectionState(AudioDeviceAttributes, int, String)}. 7871 */ updateHdmiAudioSystemClient()7872 private void updateHdmiAudioSystemClient() { 7873 Slog.d(TAG, "Hdmi Audio System Client is updated"); 7874 synchronized (mHdmiClientLock) { 7875 mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient(); 7876 } 7877 } 7878 7879 /** @see AudioManager#setTestDeviceConnectionState(AudioDeviceAttributes, boolean) */ setTestDeviceConnectionState(@onNull AudioDeviceAttributes device, boolean connected)7880 public void setTestDeviceConnectionState(@NonNull AudioDeviceAttributes device, 7881 boolean connected) { 7882 Objects.requireNonNull(device); 7883 enforceModifyAudioRoutingPermission(); 7884 7885 device = retrieveBluetoothAddress(device); 7886 7887 mDeviceBroker.setTestDeviceConnectionState(device, 7888 connected ? CONNECTION_STATE_CONNECTED : CONNECTION_STATE_DISCONNECTED); 7889 // simulate a routing update from native 7890 sendMsg(mAudioHandler, 7891 MSG_ROUTING_UPDATED, 7892 SENDMSG_REPLACE, 0, 0, null, 7893 /*delay*/ 0); 7894 } 7895 7896 /** 7897 * @hide 7898 * The states that can be used with AudioService.setBluetoothHearingAidDeviceConnectionState() 7899 * and AudioService.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent() 7900 */ 7901 @IntDef({ 7902 BluetoothProfile.STATE_DISCONNECTED, 7903 BluetoothProfile.STATE_CONNECTED, 7904 }) 7905 @Retention(RetentionPolicy.SOURCE) 7906 public @interface BtProfileConnectionState {} 7907 7908 /** 7909 * @hide 7910 * The profiles that can be used with AudioService.handleBluetoothActiveDeviceChanged() 7911 */ 7912 @IntDef({ 7913 BluetoothProfile.HEARING_AID, 7914 BluetoothProfile.A2DP, 7915 BluetoothProfile.A2DP_SINK, 7916 BluetoothProfile.LE_AUDIO, 7917 BluetoothProfile.LE_AUDIO_BROADCAST, 7918 }) 7919 @Retention(RetentionPolicy.SOURCE) 7920 public @interface BtProfile {} 7921 7922 7923 @android.annotation.EnforcePermission(BLUETOOTH_STACK) 7924 /** 7925 * See AudioManager.handleBluetoothActiveDeviceChanged(...) 7926 */ handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice, BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info)7927 public void handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice, 7928 BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info) { 7929 handleBluetoothActiveDeviceChanged_enforcePermission(); 7930 if (info == null) { 7931 throw new IllegalArgumentException("Illegal null BluetoothProfileConnectionInfo for" 7932 + " device " + previousDevice + " -> " + newDevice); 7933 } 7934 final int profile = info.getProfile(); 7935 if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK 7936 && profile != BluetoothProfile.LE_AUDIO 7937 && profile != BluetoothProfile.LE_AUDIO_BROADCAST 7938 && profile != BluetoothProfile.HEARING_AID 7939 && !(mDeviceBroker.isScoManagedByAudio() && profile == BluetoothProfile.HEADSET)) { 7940 throw new IllegalArgumentException("Illegal BluetoothProfile profile for device " 7941 + previousDevice + " -> " + newDevice + ". Got: " + profile); 7942 } 7943 7944 sDeviceLogger.enqueue(new EventLogger.StringEvent("BluetoothActiveDeviceChanged for " 7945 + BluetoothProfile.getProfileName(profile) + ", device update " + previousDevice 7946 + " -> " + newDevice).printLog(TAG)); 7947 AudioDeviceBroker.BtDeviceChangedData data = 7948 new AudioDeviceBroker.BtDeviceChangedData(newDevice, previousDevice, info, 7949 "AudioService"); 7950 sendMsg(mAudioHandler, MSG_BT_DEV_CHANGED, SENDMSG_QUEUE, 0, 0, 7951 /*obj*/ data, /*delay*/ 0); 7952 } 7953 7954 /** only public for mocking/spying, do not call outside of AudioService */ 7955 @VisibleForTesting setMusicMute(boolean mute)7956 public void setMusicMute(boolean mute) { 7957 mStreamStates[AudioSystem.STREAM_MUSIC].muteInternally(mute); 7958 } 7959 7960 private static final Set<Integer> DEVICE_MEDIA_UNMUTED_ON_PLUG_SET; 7961 static { 7962 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET = new HashSet<>(); 7963 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADSET); 7964 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE); 7965 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_LINE); 7966 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_HEARING_AID); 7967 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_A2DP_SET); 7968 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_BLE_SET); 7969 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_USB_SET); 7970 } 7971 7972 /** only public for mocking/spying, do not call outside of AudioService */ 7973 @VisibleForTesting postAccessoryPlugMediaUnmute(int newDevice)7974 public void postAccessoryPlugMediaUnmute(int newDevice) { 7975 sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE, 7976 newDevice, 0, null, 0); 7977 } 7978 onAccessoryPlugMediaUnmute(int newDevice)7979 private void onAccessoryPlugMediaUnmute(int newDevice) { 7980 if (DEBUG_VOL) { 7981 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute newDevice=%d [%s]", 7982 newDevice, AudioSystem.getOutputDeviceName(newDevice))); 7983 } 7984 7985 if (mNm.getZenMode() != Settings.Global.ZEN_MODE_NO_INTERRUPTIONS 7986 && !isStreamMutedByRingerOrZenMode(AudioSystem.STREAM_MUSIC) 7987 && DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.contains(newDevice) 7988 && mStreamStates[AudioSystem.STREAM_MUSIC].mIsMuted 7989 && mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(newDevice) != 0 7990 && getDeviceSetForStreamDirect(AudioSystem.STREAM_MUSIC).contains(newDevice)) { 7991 if (DEBUG_VOL) { 7992 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute unmuting device=%d [%s]", 7993 newDevice, AudioSystem.getOutputDeviceName(newDevice))); 7994 } 7995 // Locking mSettingsLock to avoid inversion when calling vss.mute -> vss.doMute -> 7996 // vss.updateVolumeGroupIndex 7997 synchronized (mSettingsLock) { 7998 mStreamStates[AudioSystem.STREAM_MUSIC].mute(false, "onAccessoryPlugMediaUnmute"); 7999 } 8000 } 8001 } 8002 8003 /** 8004 * See AudioManager.hasHapticChannels(Context, Uri). 8005 */ hasHapticChannels(Uri uri)8006 public boolean hasHapticChannels(Uri uri) { 8007 return AudioManager.hasHapticChannelsImpl(mContext, uri); 8008 } 8009 8010 /////////////////////////////////////////////////////////////////////////// 8011 // Inner classes 8012 /////////////////////////////////////////////////////////////////////////// 8013 /** 8014 * Key is the AudioManager VolumeGroupId 8015 * Value is the VolumeGroupState 8016 */ 8017 private static final SparseArray<VolumeGroupState> sVolumeGroupStates = new SparseArray<>(); 8018 initVolumeGroupStates()8019 private void initVolumeGroupStates() { 8020 for (final AudioVolumeGroup avg : getAudioVolumeGroups()) { 8021 try { 8022 // if no valid attributes, this volume group is not controllable, throw exception 8023 ensureValidAttributes(avg); 8024 sVolumeGroupStates.append(avg.getId(), new VolumeGroupState(avg)); 8025 } catch (IllegalArgumentException e) { 8026 // Volume Groups without attributes are not controllable through set/get volume 8027 // using attributes. Do not append them. 8028 if (DEBUG_VOL) { 8029 Log.d(TAG, "volume group " + avg.name() + " for internal policy needs"); 8030 } 8031 continue; 8032 } 8033 } 8034 8035 // need mSettingsLock for vgs.applyAllVolumes -> vss.setIndex which grabs this lock after 8036 // VSS.class. Locking order needs to be preserved 8037 synchronized (mSettingsLock) { 8038 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 8039 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 8040 vgs.applyAllVolumes(/* userSwitch= */ false); 8041 } 8042 } 8043 } 8044 ensureValidAttributes(AudioVolumeGroup avg)8045 private void ensureValidAttributes(AudioVolumeGroup avg) { 8046 boolean hasAtLeastOneValidAudioAttributes = avg.getAudioAttributes().stream() 8047 .anyMatch(aa -> !aa.equals(AudioProductStrategy.getDefaultAttributes())); 8048 if (!hasAtLeastOneValidAudioAttributes) { 8049 throw new IllegalArgumentException("Volume Group " + avg.name() 8050 + " has no valid audio attributes"); 8051 } 8052 } 8053 readVolumeGroupsSettings(boolean userSwitch)8054 private void readVolumeGroupsSettings(boolean userSwitch) { 8055 synchronized (mSettingsLock) { 8056 synchronized (VolumeStreamState.class) { 8057 if (DEBUG_VOL) { 8058 Log.d(TAG, "readVolumeGroupsSettings userSwitch=" + userSwitch); 8059 } 8060 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 8061 VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 8062 // as for STREAM_MUSIC, preserve volume from one user to the next. 8063 if (!(userSwitch && vgs.isMusic())) { 8064 vgs.clearIndexCache(); 8065 vgs.readSettings(); 8066 } 8067 vgs.applyAllVolumes(userSwitch); 8068 } 8069 } 8070 } 8071 } 8072 8073 // Called upon crash of AudioServer restoreVolumeGroups()8074 private void restoreVolumeGroups() { 8075 if (DEBUG_VOL) { 8076 Log.v(TAG, "restoreVolumeGroups"); 8077 } 8078 8079 // need mSettingsLock for vgs.applyAllVolumes -> vss.setIndex which grabs this lock after 8080 // VSS.class. Locking order needs to be preserved 8081 synchronized (mSettingsLock) { 8082 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 8083 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 8084 vgs.applyAllVolumes(false/*userSwitch*/); 8085 } 8086 } 8087 } 8088 dumpVolumeGroups(PrintWriter pw)8089 private void dumpVolumeGroups(PrintWriter pw) { 8090 pw.println("\nVolume Groups (device: index)"); 8091 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 8092 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 8093 vgs.dump(pw); 8094 pw.println(""); 8095 } 8096 } 8097 isCallStream(int stream)8098 private static boolean isCallStream(int stream) { 8099 return stream == AudioSystem.STREAM_VOICE_CALL 8100 || stream == AudioSystem.STREAM_BLUETOOTH_SCO; 8101 } 8102 getVolumeGroupForStreamType(int stream)8103 private static int getVolumeGroupForStreamType(int stream) { 8104 AudioAttributes attributes = 8105 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream); 8106 if (attributes.equals(new AudioAttributes.Builder().build())) { 8107 return AudioVolumeGroup.DEFAULT_VOLUME_GROUP; 8108 } 8109 return AudioProductStrategy.getVolumeGroupIdForAudioAttributes( 8110 attributes, /* fallbackOnDefault= */ false); 8111 } 8112 8113 // NOTE: Locking order for synchronized objects related to volume management: 8114 // 1 mSettingsLock 8115 // 2 VolumeStreamState.class 8116 private class VolumeGroupState { 8117 private final AudioVolumeGroup mAudioVolumeGroup; 8118 private final SparseIntArray mIndexMap = new SparseIntArray(8); 8119 private int mIndexMin; 8120 private int mIndexMax; 8121 private boolean mHasValidStreamType = false; 8122 private int mPublicStreamType = AudioSystem.STREAM_MUSIC; 8123 private AudioAttributes mAudioAttributes = AudioProductStrategy.getDefaultAttributes(); 8124 private boolean mIsMuted = false; 8125 private String mSettingName; 8126 8127 // No API in AudioSystem to get a device from strategy or from attributes. 8128 // Need a valid public stream type to use current API getDeviceForStream getDeviceForVolume()8129 private int getDeviceForVolume() { 8130 return getDeviceForStream(mPublicStreamType); 8131 } 8132 VolumeGroupState(AudioVolumeGroup avg)8133 private VolumeGroupState(AudioVolumeGroup avg) { 8134 mAudioVolumeGroup = avg; 8135 if (DEBUG_VOL) { 8136 Log.v(TAG, "VolumeGroupState for " + avg.toString()); 8137 } 8138 // mAudioAttributes is the default at this point 8139 for (AudioAttributes aa : avg.getAudioAttributes()) { 8140 if (!aa.equals(mAudioAttributes)) { 8141 mAudioAttributes = aa; 8142 break; 8143 } 8144 } 8145 int[] streamTypes = mAudioVolumeGroup.getLegacyStreamTypes(); 8146 String streamSettingName = ""; 8147 if (streamTypes.length != 0) { 8148 // Uses already initialized MIN / MAX if a stream type is attached to group 8149 for (int streamType : streamTypes) { 8150 if (streamType != AudioSystem.STREAM_DEFAULT 8151 && streamType < AudioSystem.getNumStreamTypes()) { 8152 mPublicStreamType = streamType; 8153 mHasValidStreamType = true; 8154 streamSettingName = System.VOLUME_SETTINGS_INT[mPublicStreamType]; 8155 break; 8156 } 8157 } 8158 mIndexMin = MIN_STREAM_VOLUME[mPublicStreamType]; 8159 mIndexMax = MAX_STREAM_VOLUME[mPublicStreamType]; 8160 } else if (!avg.getAudioAttributes().isEmpty()) { 8161 mIndexMin = AudioSystem.getMinVolumeIndexForAttributes(mAudioAttributes); 8162 mIndexMax = AudioSystem.getMaxVolumeIndexForAttributes(mAudioAttributes); 8163 } else { 8164 throw new IllegalArgumentException("volume group: " + mAudioVolumeGroup.name() 8165 + " has neither valid attributes nor valid stream types assigned"); 8166 } 8167 mSettingName = !streamSettingName.isEmpty() ? streamSettingName : ("volume_" + name()); 8168 // Load volume indexes from data base 8169 readSettings(); 8170 } 8171 getLegacyStreamTypes()8172 public @NonNull int[] getLegacyStreamTypes() { 8173 return mAudioVolumeGroup.getLegacyStreamTypes(); 8174 } 8175 name()8176 public String name() { 8177 return mAudioVolumeGroup.name(); 8178 } 8179 getId()8180 public int getId() { 8181 return mAudioVolumeGroup.getId(); 8182 } 8183 8184 /** 8185 * Volume group with non null minimum index are considered as non mutable, thus 8186 * bijectivity is broken with potential associated stream type. 8187 * VOICE_CALL stream has minVolumeIndex > 0 but can be muted directly by an 8188 * app that has MODIFY_PHONE_STATE permission. 8189 */ isVssMuteBijective(int stream)8190 private boolean isVssMuteBijective(int stream) { 8191 return isStreamAffectedByMute(stream) 8192 && (getMinIndex() == (mStreamStates[stream].mIndexMin + 5) / 10) 8193 && (getMinIndex() == 0 || isCallStream(stream)); 8194 } 8195 isMutable()8196 private boolean isMutable() { 8197 return mIndexMin == 0 || (mHasValidStreamType && isVssMuteBijective(mPublicStreamType)); 8198 } 8199 /** 8200 * Mute/unmute the volume group 8201 * @param muted the new mute state 8202 */ 8203 @GuardedBy("AudioService.VolumeStreamState.class") mute(boolean muted)8204 public boolean mute(boolean muted) { 8205 if (!isMutable()) { 8206 // Non mutable volume group 8207 if (DEBUG_VOL) { 8208 Log.d(TAG, "invalid mute on unmutable volume group " + name()); 8209 } 8210 return false; 8211 } 8212 boolean changed = (mIsMuted != muted); 8213 // As for VSS, mute shall apply minIndex to all devices found in IndexMap and default. 8214 if (changed) { 8215 mIsMuted = muted; 8216 applyAllVolumes(false /*userSwitch*/); 8217 } 8218 return changed; 8219 } 8220 isMuted()8221 public boolean isMuted() { 8222 return mIsMuted; 8223 } 8224 adjustVolume(int direction, int flags)8225 public void adjustVolume(int direction, int flags) { 8226 synchronized (mSettingsLock) { 8227 synchronized (AudioService.VolumeStreamState.class) { 8228 int device = getDeviceForVolume(); 8229 int previousIndex = getIndex(device); 8230 if (isMuteAdjust(direction) && !isMutable()) { 8231 // Non mutable volume group 8232 if (DEBUG_VOL) { 8233 Log.d(TAG, "invalid mute on unmutable volume group " + name()); 8234 } 8235 return; 8236 } 8237 switch (direction) { 8238 case AudioManager.ADJUST_TOGGLE_MUTE: { 8239 // Note: If muted by volume 0, unmute will restore volume 0. 8240 mute(!mIsMuted); 8241 break; 8242 } 8243 case AudioManager.ADJUST_UNMUTE: 8244 // Note: If muted by volume 0, unmute will restore volume 0. 8245 mute(false); 8246 break; 8247 case AudioManager.ADJUST_MUTE: 8248 // May be already muted by setvolume 0, prevent from setting same value 8249 if (previousIndex != 0) { 8250 // bypass persist 8251 mute(true); 8252 } 8253 mIsMuted = true; 8254 break; 8255 case AudioManager.ADJUST_RAISE: 8256 // As for stream, RAISE during mute will increment the index 8257 setVolumeIndex(Math.min(previousIndex + 1, mIndexMax), device, flags); 8258 break; 8259 case AudioManager.ADJUST_LOWER: 8260 // For stream, ADJUST_LOWER on a muted VSS is a no-op 8261 // If we decide to unmute on ADJUST_LOWER, cannot fallback on 8262 // adjustStreamVolume for group associated to legacy stream type 8263 if (isMuted() && previousIndex != 0) { 8264 mute(false); 8265 } else { 8266 int newIndex = Math.max(previousIndex - 1, mIndexMin); 8267 setVolumeIndex(newIndex, device, flags); 8268 } 8269 break; 8270 } 8271 } 8272 } 8273 } 8274 getVolumeIndex()8275 public int getVolumeIndex() { 8276 synchronized (AudioService.VolumeStreamState.class) { 8277 return getIndex(getDeviceForVolume()); 8278 } 8279 } 8280 setVolumeIndex(int index, int flags)8281 public void setVolumeIndex(int index, int flags) { 8282 synchronized (mSettingsLock) { 8283 synchronized (AudioService.VolumeStreamState.class) { 8284 if (mUseFixedVolume) { 8285 return; 8286 } 8287 setVolumeIndex(index, getDeviceForVolume(), flags); 8288 } 8289 } 8290 } 8291 8292 @GuardedBy("AudioService.VolumeStreamState.class") setVolumeIndex(int index, int device, int flags)8293 private void setVolumeIndex(int index, int device, int flags) { 8294 // Update cache & persist (muted by volume 0 shall be persisted) 8295 updateVolumeIndex(index, device); 8296 // setting non-zero volume for a muted stream unmutes the stream and vice versa, 8297 boolean changed = mute(index == 0); 8298 if (!changed) { 8299 // Set the volume index only if mute operation is a no-op 8300 index = getValidIndex(index); 8301 setVolumeIndexInt(index, device, flags); 8302 } 8303 } 8304 8305 @GuardedBy("AudioService.VolumeStreamState.class") updateVolumeIndex(int index, int device)8306 public void updateVolumeIndex(int index, int device) { 8307 // Filter persistency if already exist and the index has not changed 8308 if (mIndexMap.indexOfKey(device) < 0 || mIndexMap.get(device) != index) { 8309 // Update local cache 8310 mIndexMap.put(device, getValidIndex(index)); 8311 8312 // update data base - post a persist volume group msg 8313 sendMsg(mAudioHandler, 8314 MSG_PERSIST_VOLUME_GROUP, 8315 SENDMSG_QUEUE, 8316 device, 8317 0, 8318 this, 8319 PERSIST_DELAY); 8320 } 8321 } 8322 8323 @GuardedBy("AudioService.VolumeStreamState.class") setVolumeIndexInt(int index, int device, int flags)8324 private void setVolumeIndexInt(int index, int device, int flags) { 8325 // Reflect mute state of corresponding stream by forcing index to 0 if muted 8326 // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted. 8327 // This allows RX path muting by the audio HAL only when explicitly muted but not when 8328 // index is just set to 0 to repect BT requirements 8329 if (mHasValidStreamType && isVssMuteBijective(mPublicStreamType) 8330 && mStreamStates[mPublicStreamType].isFullyMuted()) { 8331 index = 0; 8332 } else if (mPublicStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0) { 8333 index = 1; 8334 } 8335 // Set the volume index 8336 mAudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, device); 8337 } 8338 8339 @GuardedBy("AudioService.VolumeStreamState.class") getIndex(int device)8340 private int getIndex(int device) { 8341 int index = mIndexMap.get(device, -1); 8342 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT 8343 return (index != -1) ? index : mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); 8344 } 8345 8346 @GuardedBy("AudioService.VolumeStreamState.class") hasIndexForDevice(int device)8347 private boolean hasIndexForDevice(int device) { 8348 return (mIndexMap.get(device, -1) != -1); 8349 } 8350 getMaxIndex()8351 public int getMaxIndex() { 8352 return mIndexMax; 8353 } 8354 getMinIndex()8355 public int getMinIndex() { 8356 return mIndexMin; 8357 } 8358 isValidStream(int stream)8359 private boolean isValidStream(int stream) { 8360 return (stream != AudioSystem.STREAM_DEFAULT) && (stream < mStreamStates.length); 8361 } 8362 isMusic()8363 public boolean isMusic() { 8364 return mHasValidStreamType && mPublicStreamType == AudioSystem.STREAM_MUSIC; 8365 } 8366 applyAllVolumes(boolean userSwitch)8367 public void applyAllVolumes(boolean userSwitch) { 8368 String caller = "from vgs"; 8369 synchronized (AudioService.VolumeStreamState.class) { 8370 // apply device specific volumes first 8371 for (int i = 0; i < mIndexMap.size(); i++) { 8372 int device = mIndexMap.keyAt(i); 8373 int index = mIndexMap.valueAt(i); 8374 boolean synced = false; 8375 if (device != AudioSystem.DEVICE_OUT_DEFAULT) { 8376 for (int stream : getLegacyStreamTypes()) { 8377 if (isValidStream(stream)) { 8378 boolean streamMuted = mStreamStates[stream].mIsMuted; 8379 int deviceForStream = getDeviceForStream(stream); 8380 int indexForStream = 8381 (mStreamStates[stream].getIndex(deviceForStream) + 5) / 10; 8382 if (device == deviceForStream) { 8383 if (indexForStream == index && (isMuted() == streamMuted) 8384 && isVssMuteBijective(stream)) { 8385 synced = true; 8386 continue; 8387 } 8388 if (vgsVssSyncMuteOrder()) { 8389 if ((isMuted() != streamMuted) && isVssMuteBijective( 8390 stream)) { 8391 mStreamStates[stream].mute(isMuted(), 8392 "VGS.applyAllVolumes#1"); 8393 } 8394 } 8395 if (indexForStream != index) { 8396 mStreamStates[stream].setIndex(index * 10, device, caller, 8397 true /*hasModifyAudioSettings*/); 8398 } 8399 if (!vgsVssSyncMuteOrder()) { 8400 if ((isMuted() != streamMuted) && isVssMuteBijective( 8401 stream)) { 8402 mStreamStates[stream].mute(isMuted(), 8403 "VGS.applyAllVolumes#1"); 8404 } 8405 } 8406 } 8407 } 8408 } 8409 if (!synced) { 8410 if (DEBUG_VOL) { 8411 Log.d(TAG, "applyAllVolumes: apply index " + index + ", group " 8412 + mAudioVolumeGroup.name() + " and device " 8413 + AudioSystem.getOutputDeviceName(device)); 8414 } 8415 setVolumeIndexInt(isMuted() ? 0 : index, device, 0 /*flags*/); 8416 } 8417 } 8418 } 8419 // apply default volume last: by convention , default device volume will be used 8420 // by audio policy manager if no explicit volume is present for a given device type 8421 int index = getIndex(AudioSystem.DEVICE_OUT_DEFAULT); 8422 boolean synced = false; 8423 int deviceForVolume = getDeviceForVolume(); 8424 boolean forceDeviceSync = userSwitch && (mIndexMap.indexOfKey(deviceForVolume) < 0); 8425 for (int stream : getLegacyStreamTypes()) { 8426 if (isValidStream(stream)) { 8427 boolean streamMuted = mStreamStates[stream].mIsMuted; 8428 int defaultStreamIndex = (mStreamStates[stream].getIndex( 8429 AudioSystem.DEVICE_OUT_DEFAULT) + 5) / 10; 8430 if (forceDeviceSync) { 8431 mStreamStates[stream].setIndex(index * 10, deviceForVolume, caller, 8432 true /*hasModifyAudioSettings*/); 8433 } 8434 if (defaultStreamIndex == index && (isMuted() == streamMuted) 8435 && isVssMuteBijective(stream)) { 8436 synced = true; 8437 continue; 8438 } 8439 if (defaultStreamIndex != index) { 8440 mStreamStates[stream].setIndex( 8441 index * 10, AudioSystem.DEVICE_OUT_DEFAULT, caller, 8442 true /*hasModifyAudioSettings*/); 8443 } 8444 if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) { 8445 mStreamStates[stream].mute(isMuted(), "VGS.applyAllVolumes#2"); 8446 } 8447 } 8448 } 8449 if (!synced) { 8450 if (DEBUG_VOL) { 8451 Log.d(TAG, "applyAllVolumes: apply default device index " + index 8452 + ", group " + mAudioVolumeGroup.name()); 8453 } 8454 setVolumeIndexInt( 8455 isMuted() ? 0 : index, AudioSystem.DEVICE_OUT_DEFAULT, 0 /*flags*/); 8456 } 8457 if (forceDeviceSync) { 8458 if (DEBUG_VOL) { 8459 Log.d(TAG, "applyAllVolumes: forceDeviceSync index " + index 8460 + ", device " + AudioSystem.getOutputDeviceName(deviceForVolume) 8461 + ", group " + mAudioVolumeGroup.name()); 8462 } 8463 setVolumeIndexInt(isMuted() ? 0 : index, deviceForVolume, 0); 8464 } 8465 } 8466 } 8467 clearIndexCache()8468 public void clearIndexCache() { 8469 mIndexMap.clear(); 8470 } 8471 persistVolumeGroup(int device)8472 private void persistVolumeGroup(int device) { 8473 // No need to persist the index if the volume group is backed up 8474 // by a public stream type as this is redundant 8475 if (mUseFixedVolume || mHasValidStreamType) { 8476 return; 8477 } 8478 if (DEBUG_VOL) { 8479 Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) + " for group " 8480 + mAudioVolumeGroup.name() 8481 + ", device " + AudioSystem.getOutputDeviceName(device) 8482 + " and User=" + getCurrentUserId() 8483 + " mSettingName: " + mSettingName); 8484 } 8485 8486 boolean success = mSettings.putSystemIntForUser(mContentResolver, 8487 getSettingNameForDevice(device), 8488 getIndex(device), 8489 isMusic() ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT); 8490 if (!success) { 8491 Log.e(TAG, "persistVolumeGroup failed for group " + mAudioVolumeGroup.name()); 8492 } 8493 } 8494 readSettings()8495 public void readSettings() { 8496 synchronized (AudioService.VolumeStreamState.class) { 8497 // force maximum volume on all streams if fixed volume property is set 8498 if (mUseFixedVolume) { 8499 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax); 8500 return; 8501 } 8502 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 8503 // retrieve current volume for device 8504 // if no volume stored for current volume group and device, use default volume 8505 // if default device, continue otherwise 8506 int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) 8507 ? AudioSystem.DEFAULT_STREAM_VOLUME[mPublicStreamType] : -1; 8508 int index; 8509 String name = getSettingNameForDevice(device); 8510 index = mSettings.getSystemIntForUser( 8511 mContentResolver, name, defaultIndex, 8512 isMusic() ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT); 8513 if (index == -1) { 8514 continue; 8515 } 8516 if (mPublicStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED 8517 && mCameraSoundForced) { 8518 index = mIndexMax; 8519 } 8520 if (DEBUG_VOL) { 8521 Log.v(TAG, "readSettings: found stored index " + getValidIndex(index) 8522 + " for group " + mAudioVolumeGroup.name() + ", device: " + name 8523 + ", User=" + getCurrentUserId()); 8524 } 8525 mIndexMap.put(device, getValidIndex(index)); 8526 } 8527 } 8528 } 8529 8530 @GuardedBy("AudioService.VolumeStreamState.class") getValidIndex(int index)8531 private int getValidIndex(int index) { 8532 if (index < mIndexMin) { 8533 return mIndexMin; 8534 } else if (mUseFixedVolume || index > mIndexMax) { 8535 return mIndexMax; 8536 } 8537 return index; 8538 } 8539 getSettingNameForDevice(int device)8540 public @NonNull String getSettingNameForDevice(int device) { 8541 String suffix = AudioSystem.getOutputDeviceName(device); 8542 if (suffix.isEmpty()) { 8543 return mSettingName; 8544 } 8545 return mSettingName + "_" + AudioSystem.getOutputDeviceName(device); 8546 } 8547 setSettingName(String settingName)8548 void setSettingName(String settingName) { 8549 mSettingName = settingName; 8550 } 8551 getSettingName()8552 String getSettingName() { 8553 return mSettingName; 8554 } 8555 dump(PrintWriter pw)8556 private void dump(PrintWriter pw) { 8557 pw.println("- VOLUME GROUP " + mAudioVolumeGroup.name() + ":"); 8558 pw.print(" Muted: "); 8559 pw.println(mIsMuted); 8560 pw.print(" Min: "); 8561 pw.println(mIndexMin); 8562 pw.print(" Max: "); 8563 pw.println(mIndexMax); 8564 pw.print(" Current: "); 8565 for (int i = 0; i < mIndexMap.size(); i++) { 8566 if (i > 0) { 8567 pw.print(", "); 8568 } 8569 int device = mIndexMap.keyAt(i); 8570 pw.print(Integer.toHexString(device)); 8571 String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 8572 : AudioSystem.getOutputDeviceName(device); 8573 if (!deviceName.isEmpty()) { 8574 pw.print(" ("); 8575 pw.print(deviceName); 8576 pw.print(")"); 8577 } 8578 pw.print(": "); 8579 pw.print(mIndexMap.valueAt(i)); 8580 } 8581 pw.println(); 8582 pw.print(" Devices: "); 8583 int n = 0; 8584 int devices = getDeviceForVolume(); 8585 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 8586 if ((devices & device) == device) { 8587 if (n++ > 0) { 8588 pw.print(", "); 8589 } 8590 pw.print(AudioSystem.getOutputDeviceName(device)); 8591 } 8592 } 8593 pw.println(); 8594 pw.print(" Streams: "); 8595 Arrays.stream(getLegacyStreamTypes()) 8596 .forEach(stream -> pw.print(AudioSystem.streamToString(stream) + " ")); 8597 } 8598 } 8599 8600 8601 // NOTE: Locking order for synchronized objects related to volume or ringer mode management: 8602 // 1 mScoclient OR mSafeMediaVolumeState 8603 // 2 mSetModeLock 8604 // 3 mSettingsLock 8605 // 4 VolumeStreamState.class 8606 /*package*/ class VolumeStreamState { 8607 private final int mStreamType; 8608 private VolumeGroupState mVolumeGroupState = null; 8609 private int mIndexMin; 8610 // min index when user doesn't have permission to change audio settings 8611 private int mIndexMinNoPerm; 8612 private int mIndexMax; 8613 8614 private boolean mIsMuted = false; 8615 private boolean mIsMutedInternally = false; 8616 private String mVolumeIndexSettingName; 8617 @NonNull private Set<Integer> mObservedDeviceSet = new TreeSet<>(); 8618 8619 private final SparseIntArray mIndexMap = new SparseIntArray(8) { 8620 @Override 8621 public void put(int key, int value) { 8622 super.put(key, value); 8623 record("put", key, value); 8624 } 8625 @Override 8626 public void setValueAt(int index, int value) { 8627 super.setValueAt(index, value); 8628 record("setValueAt", keyAt(index), value); 8629 } 8630 8631 // Record all changes in the VolumeStreamState 8632 private void record(String event, int key, int value) { 8633 final String device = key == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 8634 : AudioSystem.getOutputDeviceName(key); 8635 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME + MediaMetrics.SEPARATOR 8636 + AudioSystem.streamToString(mStreamType) 8637 + "." + device) 8638 .set(MediaMetrics.Property.EVENT, event) 8639 .set(MediaMetrics.Property.INDEX, value) 8640 .set(MediaMetrics.Property.MIN_INDEX, mIndexMin) 8641 .set(MediaMetrics.Property.MAX_INDEX, mIndexMax) 8642 .record(); 8643 } 8644 }; 8645 private final Intent mVolumeChanged; 8646 private final Bundle mVolumeChangedOptions; 8647 private final Intent mStreamDevicesChanged; 8648 private final Bundle mStreamDevicesChangedOptions; 8649 VolumeStreamState(String settingName, int streamType)8650 private VolumeStreamState(String settingName, int streamType) { 8651 mVolumeIndexSettingName = settingName; 8652 8653 mStreamType = streamType; 8654 mIndexMin = MIN_STREAM_VOLUME[streamType] * 10; 8655 mIndexMinNoPerm = mIndexMin; // may be overwritten later in updateNoPermMinIndex() 8656 mIndexMax = MAX_STREAM_VOLUME[streamType] * 10; 8657 final int status = AudioSystem.initStreamVolume( 8658 streamType, mIndexMin / 10, mIndexMax / 10); 8659 if (status != AudioSystem.AUDIO_STATUS_OK) { 8660 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 8661 "VSS() stream:" + streamType + " initStreamVolume=" + status) 8662 .printLog(ALOGE, TAG)); 8663 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 8664 "VSS()" /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 8665 } 8666 8667 readSettings(); 8668 mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION); 8669 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 8670 final BroadcastOptions volumeChangedOptions = BroadcastOptions.makeBasic(); 8671 // This allows us to discard older broadcasts still waiting to be delivered 8672 // which have the same namespace (VOLUME_CHANGED_ACTION) and key (mStreamType). 8673 volumeChangedOptions.setDeliveryGroupPolicy(DELIVERY_GROUP_POLICY_MOST_RECENT); 8674 volumeChangedOptions.setDeliveryGroupMatchingKey( 8675 AudioManager.VOLUME_CHANGED_ACTION, String.valueOf(mStreamType)); 8676 volumeChangedOptions.setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE); 8677 mVolumeChangedOptions = volumeChangedOptions.toBundle(); 8678 8679 mStreamDevicesChanged = new Intent(AudioManager.STREAM_DEVICES_CHANGED_ACTION); 8680 mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 8681 final BroadcastOptions streamDevicesChangedOptions = BroadcastOptions.makeBasic(); 8682 streamDevicesChangedOptions.setDeliveryGroupPolicy(DELIVERY_GROUP_POLICY_MOST_RECENT); 8683 streamDevicesChangedOptions.setDeliveryGroupMatchingKey( 8684 AudioManager.STREAM_DEVICES_CHANGED_ACTION, String.valueOf(mStreamType)); 8685 streamDevicesChangedOptions.setDeferralPolicy( 8686 BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE); 8687 mStreamDevicesChangedOptions = streamDevicesChangedOptions.toBundle(); 8688 } 8689 8690 /** 8691 * Associate a {@link volumeGroupState} on the {@link VolumeStreamState}. 8692 * <p> It helps to synchronize the index, mute attributes on the maching 8693 * {@link volumeGroupState} 8694 * @param volumeGroupState matching the {@link VolumeStreamState} 8695 */ setVolumeGroupState(VolumeGroupState volumeGroupState)8696 public void setVolumeGroupState(VolumeGroupState volumeGroupState) { 8697 mVolumeGroupState = volumeGroupState; 8698 if (mVolumeGroupState != null) { 8699 mVolumeGroupState.setSettingName(mVolumeIndexSettingName); 8700 } 8701 } 8702 /** 8703 * Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission 8704 * @param index minimum index expressed in "UI units", i.e. no 10x factor 8705 */ updateNoPermMinIndex(int index)8706 public void updateNoPermMinIndex(int index) { 8707 mIndexMinNoPerm = index * 10; 8708 if (mIndexMinNoPerm < mIndexMin) { 8709 Log.e(TAG, "Invalid mIndexMinNoPerm for stream " + mStreamType); 8710 mIndexMinNoPerm = mIndexMin; 8711 } 8712 } 8713 8714 /** 8715 * Returns a list of devices associated with the stream type. 8716 * 8717 * This is a reference to the local list, do not modify. 8718 */ 8719 @GuardedBy("VolumeStreamState.class") 8720 @NonNull observeDevicesForStream_syncVSS( boolean checkOthers)8721 public Set<Integer> observeDevicesForStream_syncVSS( 8722 boolean checkOthers) { 8723 if (!mSystemServer.isPrivileged()) { 8724 return new TreeSet<Integer>(); 8725 } 8726 final Set<Integer> deviceSet = 8727 getDeviceSetForStreamDirect(mStreamType); 8728 if (deviceSet.equals(mObservedDeviceSet)) { 8729 return mObservedDeviceSet; 8730 } 8731 8732 // Use legacy bit masks for message signalling. 8733 // TODO(b/185386781): message needs update since it uses devices bit-mask. 8734 final int devices = AudioSystem.getDeviceMaskFromSet(deviceSet); 8735 final int prevDevices = AudioSystem.getDeviceMaskFromSet(mObservedDeviceSet); 8736 8737 mObservedDeviceSet = deviceSet; 8738 if (checkOthers) { 8739 // one stream's devices have changed, check the others 8740 postObserveDevicesForAllStreams(mStreamType); 8741 } 8742 // log base stream changes to the event log 8743 if (mStreamVolumeAlias[mStreamType] == mStreamType) { 8744 EventLogTags.writeStreamDevicesChanged(mStreamType, prevDevices, devices); 8745 } 8746 // send STREAM_DEVICES_CHANGED_ACTION on the message handler so it is scheduled after 8747 // the postObserveDevicesForStreams is handled 8748 final SomeArgs args = SomeArgs.obtain(); 8749 args.arg1 = mStreamDevicesChanged; 8750 args.arg2 = mStreamDevicesChangedOptions; 8751 sendMsg(mAudioHandler, 8752 MSG_STREAM_DEVICES_CHANGED, 8753 SENDMSG_QUEUE, prevDevices /*arg1*/, devices /*arg2*/, 8754 // ok to send reference to this object, it is final 8755 args /*obj*/, 0 /*delay*/); 8756 return mObservedDeviceSet; 8757 } 8758 getSettingNameForDevice(int device)8759 public @Nullable String getSettingNameForDevice(int device) { 8760 if (!hasValidSettingsName()) { 8761 return null; 8762 } 8763 final String suffix = AudioSystem.getOutputDeviceName(device); 8764 if (suffix.isEmpty()) { 8765 return mVolumeIndexSettingName; 8766 } 8767 return mVolumeIndexSettingName + "_" + suffix; 8768 } 8769 hasValidSettingsName()8770 private boolean hasValidSettingsName() { 8771 return (mVolumeIndexSettingName != null && !mVolumeIndexSettingName.isEmpty()); 8772 } 8773 setSettingName(String settingName)8774 void setSettingName(String settingName) { 8775 mVolumeIndexSettingName = settingName; 8776 if (mVolumeGroupState != null) { 8777 mVolumeGroupState.setSettingName(mVolumeIndexSettingName); 8778 } 8779 } 8780 getSettingName()8781 String getSettingName() { 8782 return mVolumeIndexSettingName; 8783 } 8784 readSettings()8785 public void readSettings() { 8786 synchronized (mSettingsLock) { 8787 synchronized (VolumeStreamState.class) { 8788 // force maximum volume on all streams if fixed volume property is set 8789 if (mUseFixedVolume) { 8790 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax); 8791 return; 8792 } 8793 // do not read system stream volume from settings: this stream is always aliased 8794 // to another stream type and its volume is never persisted. Values in settings can 8795 // only be stale values 8796 if ((mStreamType == AudioSystem.STREAM_SYSTEM) || 8797 (mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)) { 8798 int index = 10 * AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType]; 8799 if (mCameraSoundForced) { 8800 index = mIndexMax; 8801 } 8802 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, index); 8803 return; 8804 } 8805 } 8806 } 8807 synchronized (VolumeStreamState.class) { 8808 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 8809 8810 // retrieve current volume for device 8811 // if no volume stored for current stream and device, use default volume if default 8812 // device, continue otherwise 8813 int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ? 8814 AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType] : -1; 8815 int index; 8816 if (!hasValidSettingsName()) { 8817 index = defaultIndex; 8818 } else { 8819 String name = getSettingNameForDevice(device); 8820 index = mSettings.getSystemIntForUser( 8821 mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT); 8822 } 8823 if (index == -1) { 8824 continue; 8825 } 8826 8827 mIndexMap.put(device, getValidIndex(10 * index, 8828 true /*hasModifyAudioSettings*/)); 8829 } 8830 } 8831 } 8832 getAbsoluteVolumeIndex(int index)8833 private int getAbsoluteVolumeIndex(int index) { 8834 if (absVolumeIndexFix()) { 8835 // The attenuation is applied in the APM. No need to manipulate the index here 8836 return index; 8837 } else { 8838 /* Special handling for Bluetooth Absolute Volume scenario 8839 * If we send full audio gain, some accessories are too loud even at its lowest 8840 * volume. We are not able to enumerate all such accessories, so here is the 8841 * workaround from phone side. 8842 * Pre-scale volume at lowest volume steps 1 2 and 3. 8843 * For volume step 0, set audio gain to 0 as some accessories won't mute on their 8844 * end. 8845 */ 8846 if (index == 0) { 8847 // 0% for volume 0 8848 index = 0; 8849 } else if (!disablePrescaleAbsoluteVolume() && index > 0 && index <= 3) { 8850 // Pre-scale for volume steps 1 2 and 3 8851 index = (int) (mIndexMax * mPrescaleAbsoluteVolume[index - 1]) / 10; 8852 } else { 8853 // otherwise, full gain 8854 index = (mIndexMax + 5) / 10; 8855 } 8856 return index; 8857 } 8858 } 8859 setStreamVolumeIndex(int index, int device)8860 private void setStreamVolumeIndex(int index, int device) { 8861 // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted. 8862 // This allows RX path muting by the audio HAL only when explicitly muted but not when 8863 // index is just set to 0 to repect BT requirements 8864 if (mStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0 8865 && !isFullyMuted()) { 8866 index = 1; 8867 } 8868 8869 if (DEBUG_VOL) { 8870 Log.d(TAG, "setStreamVolumeIndexAS(" + mStreamType + ", " + index + ", " + device 8871 + ")"); 8872 } 8873 mAudioSystem.setStreamVolumeIndexAS(mStreamType, index, device); 8874 } 8875 8876 // must be called while synchronized VolumeStreamState.class applyDeviceVolume_syncVSS(int device)8877 /*package*/ void applyDeviceVolume_syncVSS(int device) { 8878 int index; 8879 if (isFullyMuted()) { 8880 index = 0; 8881 } else if (isAbsoluteVolumeDevice(device) 8882 || isA2dpAbsoluteVolumeDevice(device) 8883 || AudioSystem.isLeAudioDeviceType(device)) { 8884 // do not change the volume logic for dynamic abs behavior devices like HDMI 8885 if (absVolumeIndexFix() && isAbsoluteVolumeDevice(device)) { 8886 index = getAbsoluteVolumeIndex((mIndexMax + 5) / 10); 8887 } else { 8888 index = getAbsoluteVolumeIndex((getIndex(device) + 5) / 10); 8889 } 8890 } else if (isFullVolumeDevice(device)) { 8891 index = (mIndexMax + 5)/10; 8892 } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 8893 if (absVolumeIndexFix()) { 8894 index = getAbsoluteVolumeIndex((getIndex(device) + 5) / 10); 8895 } else { 8896 index = (mIndexMax + 5) / 10; 8897 } 8898 } else { 8899 index = (getIndex(device) + 5)/10; 8900 } 8901 8902 setStreamVolumeIndex(index, device); 8903 } 8904 applyAllVolumes()8905 public void applyAllVolumes() { 8906 synchronized (VolumeStreamState.class) { 8907 // apply device specific volumes first 8908 int index; 8909 boolean isAbsoluteVolume = false; 8910 for (int i = 0; i < mIndexMap.size(); i++) { 8911 final int device = mIndexMap.keyAt(i); 8912 if (device != AudioSystem.DEVICE_OUT_DEFAULT) { 8913 if (isFullyMuted()) { 8914 index = 0; 8915 } else if (isAbsoluteVolumeDevice(device) 8916 || isA2dpAbsoluteVolumeDevice(device) 8917 || AudioSystem.isLeAudioDeviceType(device)) { 8918 isAbsoluteVolume = true; 8919 // do not change the volume logic for dynamic abs behavior devices 8920 // like HDMI 8921 if (absVolumeIndexFix() && isAbsoluteVolumeDevice(device)) { 8922 index = getAbsoluteVolumeIndex((mIndexMax + 5) / 10); 8923 } else { 8924 index = getAbsoluteVolumeIndex((getIndex(device) + 5) / 10); 8925 } 8926 } else if (isFullVolumeDevice(device)) { 8927 index = (mIndexMax + 5)/10; 8928 } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 8929 if (absVolumeIndexFix()) { 8930 isAbsoluteVolume = true; 8931 index = getAbsoluteVolumeIndex((getIndex(device) + 5) / 10); 8932 } else { 8933 index = (mIndexMax + 5) / 10; 8934 } 8935 } else { 8936 index = (mIndexMap.valueAt(i) + 5)/10; 8937 } 8938 8939 sendMsg(mAudioHandler, SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION, 8940 SENDMSG_REPLACE, device, isAbsoluteVolume ? 1 : 0, this, 8941 /*delay=*/0); 8942 8943 setStreamVolumeIndex(index, device); 8944 } 8945 } 8946 // apply default volume last: by convention , default device volume will be used 8947 // by audio policy manager if no explicit volume is present for a given device type 8948 if (isFullyMuted()) { 8949 index = 0; 8950 } else { 8951 index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10; 8952 } 8953 setStreamVolumeIndex(index, AudioSystem.DEVICE_OUT_DEFAULT); 8954 } 8955 } 8956 adjustIndex(int deltaIndex, int device, String caller, boolean hasModifyAudioSettings)8957 public boolean adjustIndex(int deltaIndex, int device, String caller, 8958 boolean hasModifyAudioSettings) { 8959 return setIndex(getIndex(device) + deltaIndex, device, caller, 8960 hasModifyAudioSettings); 8961 } 8962 setIndex(int index, int device, String caller, boolean hasModifyAudioSettings)8963 public boolean setIndex(int index, int device, String caller, 8964 boolean hasModifyAudioSettings) { 8965 boolean changed; 8966 int oldIndex; 8967 final boolean isCurrentDevice; 8968 final StringBuilder aliasStreamIndexes = new StringBuilder(); 8969 synchronized (mSettingsLock) { 8970 synchronized (VolumeStreamState.class) { 8971 oldIndex = getIndex(device); 8972 index = getValidIndex(index, hasModifyAudioSettings); 8973 // for STREAM_SYSTEM_ENFORCED, do not sync aliased streams on the enforced index 8974 int aliasIndex = index; 8975 if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) && mCameraSoundForced) { 8976 index = mIndexMax; 8977 } 8978 mIndexMap.put(device, index); 8979 8980 changed = oldIndex != index; 8981 // Apply change to all streams using this one as alias if: 8982 // - the index actually changed OR 8983 // - there is no volume index stored for this device on alias stream. 8984 // If changing volume of current device, also change volume of current 8985 // device on aliased stream 8986 isCurrentDevice = (device == getDeviceForStream(mStreamType)); 8987 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 8988 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 8989 final VolumeStreamState aliasStreamState = mStreamStates[streamType]; 8990 if (streamType != mStreamType && 8991 mStreamVolumeAlias[streamType] == mStreamType && 8992 (changed || !aliasStreamState.hasIndexForDevice(device))) { 8993 final int scaledIndex = 8994 rescaleIndex(aliasIndex, mStreamType, streamType); 8995 boolean changedAlias = aliasStreamState.setIndex(scaledIndex, device, 8996 caller, hasModifyAudioSettings); 8997 if (isCurrentDevice) { 8998 changedAlias |= aliasStreamState.setIndex(scaledIndex, 8999 getDeviceForStream(streamType), caller, 9000 hasModifyAudioSettings); 9001 } 9002 if (changedAlias) { 9003 aliasStreamIndexes.append(AudioSystem.streamToString(streamType)) 9004 .append(":").append((scaledIndex + 5) / 10).append(" "); 9005 } 9006 } 9007 } 9008 // Mirror changes in SPEAKER ringtone volume on SCO when 9009 if (changed && mStreamType == AudioSystem.STREAM_RING 9010 && device == AudioSystem.DEVICE_OUT_SPEAKER) { 9011 for (int i = 0; i < mIndexMap.size(); i++) { 9012 int otherDevice = mIndexMap.keyAt(i); 9013 if (AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(otherDevice)) { 9014 mIndexMap.put(otherDevice, index); 9015 } 9016 } 9017 } 9018 } 9019 } 9020 if (changed) { 9021 // If associated to volume group, update group cache 9022 updateVolumeGroupIndex(device, /* forceMuteState= */ false); 9023 9024 oldIndex = (oldIndex + 5) / 10; 9025 index = (index + 5) / 10; 9026 // log base stream changes to the event log 9027 if (mStreamVolumeAlias[mStreamType] == mStreamType) { 9028 if (caller == null) { 9029 Log.w(TAG, "No caller for volume_changed event", new Throwable()); 9030 } 9031 EventLogTags.writeVolumeChanged(mStreamType, oldIndex, index, mIndexMax / 10, 9032 caller); 9033 } 9034 // fire changed intents for all streams, but only when the device it changed on 9035 // is the current device 9036 if ((index != oldIndex) && isCurrentDevice) { 9037 // for single volume devices, only send the volume change broadcast 9038 // on the alias stream 9039 if (!mIsSingleVolume || (mStreamVolumeAlias[mStreamType] == mStreamType)) { 9040 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index); 9041 mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, 9042 oldIndex); 9043 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS, 9044 mStreamVolumeAlias[mStreamType]); 9045 if (mStreamType == mStreamVolumeAlias[mStreamType]) { 9046 String aliasStreamIndexesString = ""; 9047 if (!aliasStreamIndexes.isEmpty()) { 9048 aliasStreamIndexesString = 9049 " aliased streams: " + aliasStreamIndexes; 9050 } 9051 AudioService.sVolumeLogger.enqueue(new VolChangedBroadcastEvent( 9052 mStreamType, aliasStreamIndexesString, index, oldIndex)); 9053 } 9054 sendBroadcastToAll(mVolumeChanged, mVolumeChangedOptions); 9055 } 9056 } 9057 } 9058 return changed; 9059 } 9060 getIndex(int device)9061 public int getIndex(int device) { 9062 synchronized (VolumeStreamState.class) { 9063 int index = mIndexMap.get(device, -1); 9064 if (index == -1) { 9065 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT 9066 index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); 9067 } 9068 return index; 9069 } 9070 } 9071 getVolumeInfo(int device)9072 public @NonNull VolumeInfo getVolumeInfo(int device) { 9073 synchronized (VolumeStreamState.class) { 9074 int index = mIndexMap.get(device, -1); 9075 if (index == -1) { 9076 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT 9077 index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); 9078 } 9079 final VolumeInfo vi = new VolumeInfo.Builder(mStreamType) 9080 .setMinVolumeIndex(mIndexMin) 9081 .setMaxVolumeIndex(mIndexMax) 9082 .setVolumeIndex(index) 9083 .setMuted(isFullyMuted()) 9084 .build(); 9085 return vi; 9086 } 9087 } 9088 hasIndexForDevice(int device)9089 public boolean hasIndexForDevice(int device) { 9090 synchronized (VolumeStreamState.class) { 9091 return (mIndexMap.get(device, -1) != -1); 9092 } 9093 } 9094 getMaxIndex()9095 public int getMaxIndex() { 9096 return mIndexMax; 9097 } 9098 9099 /** 9100 * @return the lowest index regardless of permissions 9101 */ getMinIndex()9102 public int getMinIndex() { 9103 return mIndexMin; 9104 } 9105 9106 /** 9107 * @param isPrivileged true if the caller is privileged and not subject to minimum 9108 * volume index thresholds 9109 * @return the lowest index that this caller can set or adjust to 9110 */ getMinIndex(boolean isPrivileged)9111 public int getMinIndex(boolean isPrivileged) { 9112 return isPrivileged ? mIndexMin : mIndexMinNoPerm; 9113 } 9114 9115 /** 9116 * Copies all device/index pairs from the given VolumeStreamState after initializing 9117 * them with the volume for DEVICE_OUT_DEFAULT. No-op if the source VolumeStreamState 9118 * has the same stream type as this instance. 9119 * @param srcStream 9120 * @param caller 9121 */ 9122 // must be sync'd on mSettingsLock before VolumeStreamState.class 9123 @GuardedBy("VolumeStreamState.class") setAllIndexes(VolumeStreamState srcStream, String caller)9124 public void setAllIndexes(VolumeStreamState srcStream, String caller) { 9125 if (mStreamType == srcStream.mStreamType) { 9126 return; 9127 } 9128 int srcStreamType = srcStream.getStreamType(); 9129 // apply default device volume from source stream to all devices first in case 9130 // some devices are present in this stream state but not in source stream state 9131 int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT); 9132 index = rescaleIndex(index, srcStreamType, mStreamType); 9133 for (int i = 0; i < mIndexMap.size(); i++) { 9134 mIndexMap.put(mIndexMap.keyAt(i), index); 9135 } 9136 // Now apply actual volume for devices in source stream state 9137 SparseIntArray srcMap = srcStream.mIndexMap; 9138 for (int i = 0; i < srcMap.size(); i++) { 9139 int device = srcMap.keyAt(i); 9140 index = srcMap.valueAt(i); 9141 index = rescaleIndex(index, srcStreamType, mStreamType); 9142 9143 setIndex(index, device, caller, true /*hasModifyAudioSettings*/); 9144 } 9145 } 9146 9147 // must be sync'd on mSettingsLock before VolumeStreamState.class 9148 @GuardedBy("VolumeStreamState.class") setAllIndexesToMax()9149 public void setAllIndexesToMax() { 9150 for (int i = 0; i < mIndexMap.size(); i++) { 9151 mIndexMap.put(mIndexMap.keyAt(i), mIndexMax); 9152 } 9153 } 9154 9155 // If associated to volume group, update group cache updateVolumeGroupIndex(int device, boolean forceMuteState)9156 private void updateVolumeGroupIndex(int device, boolean forceMuteState) { 9157 // need mSettingsLock when called from setIndex for vgs.mute -> vgs.applyAllVolumes -> 9158 // vss.setIndex which grabs this lock after VSS.class. Locking order needs to be 9159 // preserved 9160 synchronized (mSettingsLock) { 9161 synchronized (VolumeStreamState.class) { 9162 if (mVolumeGroupState != null) { 9163 int groupIndex = (getIndex(device) + 5) / 10; 9164 if (DEBUG_VOL) { 9165 Log.d(TAG, "updateVolumeGroupIndex for stream " + mStreamType 9166 + ", muted=" + mIsMuted + ", device=" + device + ", index=" 9167 + getIndex(device) + ", group " + mVolumeGroupState.name() 9168 + " Muted=" + mVolumeGroupState.isMuted() + ", Index=" 9169 + groupIndex + ", forceMuteState=" + forceMuteState); 9170 } 9171 mVolumeGroupState.updateVolumeIndex(groupIndex, device); 9172 // Only propage mute of stream when applicable 9173 if (isMutable()) { 9174 // For call stream, align mute only when muted, not when index is set to 9175 // 0 9176 mVolumeGroupState.mute( 9177 forceMuteState ? mIsMuted : 9178 (groupIndex == 0 && !isCallStream(mStreamType)) 9179 || mIsMuted); 9180 } 9181 } 9182 } 9183 } 9184 } 9185 9186 /** 9187 * Mute/unmute the stream 9188 * @param state the new mute state 9189 * @return true if the mute state was changed 9190 */ mute(boolean state, String source)9191 public boolean mute(boolean state, String source) { 9192 boolean changed = false; 9193 synchronized (VolumeStreamState.class) { 9194 changed = mute(state, true, source); 9195 } 9196 if (changed) { 9197 broadcastMuteSetting(mStreamType, state); 9198 } 9199 return changed; 9200 } 9201 9202 /** 9203 * Mute/unmute the stream by AudioService 9204 * @param state the new mute state 9205 * @return true if the mute state was changed 9206 */ muteInternally(boolean state)9207 public boolean muteInternally(boolean state) { 9208 boolean changed = false; 9209 synchronized (VolumeStreamState.class) { 9210 if (state != mIsMutedInternally) { 9211 changed = true; 9212 mIsMutedInternally = state; 9213 // mute immediately to avoid delay and preemption when using a message. 9214 applyAllVolumes(); 9215 } 9216 } 9217 if (changed) { 9218 sVolumeLogger.enqueue(new VolumeEvent( 9219 VolumeEvent.VOL_MUTE_STREAM_INT, mStreamType, state)); 9220 } 9221 return changed; 9222 } 9223 9224 @GuardedBy("VolumeStreamState.class") isFullyMuted()9225 public boolean isFullyMuted() { 9226 return mIsMuted || mIsMutedInternally; 9227 } 9228 9229 isMutable()9230 private boolean isMutable() { 9231 return isStreamAffectedByMute(mStreamType) 9232 && (mIndexMin == 0 || isCallStream(mStreamType)); 9233 } 9234 9235 /** 9236 * Mute/unmute the stream 9237 * @param state the new mute state 9238 * @param apply true to propagate to HW, or false just to update the cache. May be needed 9239 * to mute a stream and its aliases as applyAllVolume will force settings to aliases. 9240 * It prevents unnecessary calls to {@see AudioSystem#setStreamVolume} 9241 * @return true if the mute state was changed 9242 */ mute(boolean state, boolean apply, String src)9243 public boolean mute(boolean state, boolean apply, String src) { 9244 synchronized (VolumeStreamState.class) { 9245 boolean changed = state != mIsMuted; 9246 if (changed) { 9247 sMuteLogger.enqueue( 9248 new AudioServiceEvents.StreamMuteEvent(mStreamType, state, src)); 9249 // check to see if unmuting should not have happened due to ringer muted streams 9250 if (!state && isStreamMutedByRingerOrZenMode(mStreamType)) { 9251 Log.e(TAG, "Unmuting stream " + mStreamType 9252 + " despite ringer-zen muted stream 0x" 9253 + Integer.toHexString(AudioService.sRingerAndZenModeMutedStreams), 9254 new Exception()); // this will put a stack trace in the logs 9255 sMuteLogger.enqueue(new AudioServiceEvents.StreamUnmuteErrorEvent( 9256 mStreamType, AudioService.sRingerAndZenModeMutedStreams)); 9257 } 9258 mIsMuted = state; 9259 if (apply) { 9260 doMute(); 9261 } 9262 } 9263 return changed; 9264 } 9265 } 9266 doMute()9267 public void doMute() { 9268 synchronized (VolumeStreamState.class) { 9269 // If associated to volume group, update group cache 9270 updateVolumeGroupIndex(getDeviceForStream(mStreamType), /* forceMuteState= */ true); 9271 9272 // Set the new mute volume. This propagates the values to 9273 // the audio system, otherwise the volume won't be changed 9274 // at the lower level. 9275 sendMsg(mAudioHandler, 9276 MSG_SET_ALL_VOLUMES, 9277 SENDMSG_QUEUE, 9278 0, 9279 0, 9280 this, 0); 9281 } 9282 } 9283 getStreamType()9284 public int getStreamType() { 9285 return mStreamType; 9286 } 9287 checkFixedVolumeDevices()9288 public void checkFixedVolumeDevices() { 9289 synchronized (VolumeStreamState.class) { 9290 // ignore settings for fixed volume devices: volume should always be at max or 0 9291 if (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_MUSIC) { 9292 for (int i = 0; i < mIndexMap.size(); i++) { 9293 int device = mIndexMap.keyAt(i); 9294 int index = mIndexMap.valueAt(i); 9295 if (isFullVolumeDevice(device) 9296 || (isFixedVolumeDevice(device) && index != 0)) { 9297 mIndexMap.put(device, mIndexMax); 9298 } 9299 applyDeviceVolume_syncVSS(device); 9300 } 9301 } 9302 } 9303 } 9304 getValidIndex(int index, boolean hasModifyAudioSettings)9305 private int getValidIndex(int index, boolean hasModifyAudioSettings) { 9306 final int indexMin = hasModifyAudioSettings ? mIndexMin : mIndexMinNoPerm; 9307 if (index < indexMin) { 9308 return indexMin; 9309 } else if (mUseFixedVolume || index > mIndexMax) { 9310 return mIndexMax; 9311 } 9312 9313 return index; 9314 } 9315 dump(PrintWriter pw)9316 private void dump(PrintWriter pw) { 9317 pw.print(" Muted: "); 9318 pw.println(mIsMuted); 9319 pw.print(" Muted Internally: "); 9320 pw.println(mIsMutedInternally); 9321 pw.print(" Min: "); 9322 pw.print((mIndexMin + 5) / 10); 9323 if (mIndexMin != mIndexMinNoPerm) { 9324 pw.print(" w/o perm:"); 9325 pw.println((mIndexMinNoPerm + 5) / 10); 9326 } else { 9327 pw.println(); 9328 } 9329 pw.print(" Max: "); 9330 pw.println((mIndexMax + 5) / 10); 9331 pw.print(" streamVolume:"); pw.println(getStreamVolume(mStreamType)); 9332 pw.print(" Current: "); 9333 for (int i = 0; i < mIndexMap.size(); i++) { 9334 if (i > 0) { 9335 pw.print(", "); 9336 } 9337 final int device = mIndexMap.keyAt(i); 9338 pw.print(Integer.toHexString(device)); 9339 final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 9340 : AudioSystem.getOutputDeviceName(device); 9341 if (!deviceName.isEmpty()) { 9342 pw.print(" ("); 9343 pw.print(deviceName); 9344 pw.print(")"); 9345 } 9346 pw.print(": "); 9347 final int index = (mIndexMap.valueAt(i) + 5) / 10; 9348 pw.print(index); 9349 } 9350 pw.println(); 9351 pw.print(" Devices: "); 9352 pw.print(AudioSystem.deviceSetToString(getDeviceSetForStream(mStreamType))); 9353 pw.println(); 9354 pw.print(" Volume Group: "); 9355 pw.println(mVolumeGroupState != null ? mVolumeGroupState.name() : "n/a"); 9356 } 9357 } 9358 9359 /** Thread that handles native AudioSystem control. */ 9360 private class AudioSystemThread extends Thread { AudioSystemThread()9361 AudioSystemThread() { 9362 super("AudioService"); 9363 } 9364 9365 @Override run()9366 public void run() { 9367 // Set this thread up so the handler will work on it 9368 Looper.prepare(); 9369 9370 synchronized(AudioService.this) { 9371 mAudioHandler = new AudioHandler(); 9372 9373 // Notify that the handler has been created 9374 AudioService.this.notify(); 9375 } 9376 9377 // Listen for volume change requests that are set by VolumePanel 9378 Looper.loop(); 9379 } 9380 } 9381 9382 private static final class DeviceVolumeUpdate { 9383 final int mStreamType; 9384 final int mDevice; 9385 final @NonNull String mCaller; 9386 private static final int NO_NEW_INDEX = -2049; 9387 private final int mVssVolIndex; 9388 9389 // Constructor with volume index, meant to cause this volume to be set and applied for the 9390 // given stream type on the given device DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller)9391 DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller) { 9392 mStreamType = streamType; 9393 mVssVolIndex = vssVolIndex; 9394 mDevice = device; 9395 mCaller = caller; 9396 } 9397 9398 // Constructor with no volume index, meant to cause re-apply of volume for the given 9399 // stream type on the given device DeviceVolumeUpdate(int streamType, int device, @NonNull String caller)9400 DeviceVolumeUpdate(int streamType, int device, @NonNull String caller) { 9401 mStreamType = streamType; 9402 mVssVolIndex = NO_NEW_INDEX; 9403 mDevice = device; 9404 mCaller = caller; 9405 } 9406 hasVolumeIndex()9407 boolean hasVolumeIndex() { 9408 return mVssVolIndex != NO_NEW_INDEX; 9409 } 9410 getVolumeIndex()9411 int getVolumeIndex() throws IllegalStateException { 9412 Preconditions.checkState(mVssVolIndex != NO_NEW_INDEX); 9413 return mVssVolIndex; 9414 } 9415 } 9416 9417 /** only public for mocking/spying, do not call outside of AudioService */ 9418 @VisibleForTesting postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, String caller)9419 public void postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, 9420 String caller) { 9421 sendMsg(mAudioHandler, 9422 MSG_SET_DEVICE_STREAM_VOLUME, 9423 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/, 9424 new DeviceVolumeUpdate(streamType, vssVolIndex, device, caller), 9425 0 /*delay*/); 9426 } 9427 postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller)9428 /*package*/ void postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller) { 9429 sendMsg(mAudioHandler, 9430 MSG_SET_DEVICE_STREAM_VOLUME, 9431 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/, 9432 new DeviceVolumeUpdate(streamType, device, caller), 9433 0 /*delay*/); 9434 } 9435 onSetVolumeIndexOnDevice(@onNull DeviceVolumeUpdate update)9436 private void onSetVolumeIndexOnDevice(@NonNull DeviceVolumeUpdate update) { 9437 final VolumeStreamState streamState = mStreamStates[update.mStreamType]; 9438 if (update.hasVolumeIndex()) { 9439 int index = update.getVolumeIndex(); 9440 if (mSoundDoseHelper.checkSafeMediaVolume(update.mStreamType, index, update.mDevice)) { 9441 index = mSoundDoseHelper.safeMediaVolumeIndex(update.mDevice); 9442 } 9443 streamState.setIndex(index, update.mDevice, update.mCaller, 9444 // trusted as index is always validated before message is posted 9445 true /*hasModifyAudioSettings*/); 9446 sVolumeLogger.enqueue(new EventLogger.StringEvent(update.mCaller + " dev:0x" 9447 + Integer.toHexString(update.mDevice) + " volIdx:" + index)); 9448 } else { 9449 sVolumeLogger.enqueue(new EventLogger.StringEvent(update.mCaller 9450 + " update vol on dev:0x" + Integer.toHexString(update.mDevice))); 9451 } 9452 setDeviceVolume(streamState, update.mDevice); 9453 } 9454 setDeviceVolume(VolumeStreamState streamState, int device)9455 /*package*/ void setDeviceVolume(VolumeStreamState streamState, int device) { 9456 9457 synchronized (VolumeStreamState.class) { 9458 sendMsg(mAudioHandler, SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION, SENDMSG_REPLACE, 9459 device, (isAbsoluteVolumeDevice(device) || isA2dpAbsoluteVolumeDevice(device) 9460 || AudioSystem.isLeAudioDeviceType(device) ? 1 : 0), 9461 streamState, /*delay=*/0); 9462 // Apply volume 9463 streamState.applyDeviceVolume_syncVSS(device); 9464 9465 // Apply change to all streams using this one as alias 9466 int numStreamTypes = AudioSystem.getNumStreamTypes(); 9467 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 9468 if (streamType != streamState.mStreamType && 9469 mStreamVolumeAlias[streamType] == streamState.mStreamType) { 9470 // Make sure volume is also maxed out on A2DP device for aliased stream 9471 // that may have a different device selected 9472 int streamDevice = getDeviceForStream(streamType); 9473 if ((device != streamDevice) 9474 && (isAbsoluteVolumeDevice(device) 9475 || isA2dpAbsoluteVolumeDevice(device) 9476 || AudioSystem.isLeAudioDeviceType(device))) { 9477 mStreamStates[streamType].applyDeviceVolume_syncVSS(device); 9478 } 9479 mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice); 9480 } 9481 } 9482 } 9483 // Post a persist volume msg 9484 sendMsg(mAudioHandler, 9485 MSG_PERSIST_VOLUME, 9486 SENDMSG_QUEUE, 9487 device, 9488 0, 9489 streamState, 9490 PERSIST_DELAY); 9491 9492 } 9493 9494 /** Handles internal volume messages in separate volume thread. */ 9495 /*package*/ class AudioHandler extends Handler { 9496 AudioHandler()9497 AudioHandler() { 9498 super(); 9499 } 9500 AudioHandler(Looper looper)9501 AudioHandler(Looper looper) { 9502 super(looper); 9503 } 9504 setAllVolumes(VolumeStreamState streamState)9505 private void setAllVolumes(VolumeStreamState streamState) { 9506 9507 // Apply volume 9508 streamState.applyAllVolumes(); 9509 9510 // Apply change to all streams using this one as alias 9511 int numStreamTypes = AudioSystem.getNumStreamTypes(); 9512 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 9513 if (streamType != streamState.mStreamType && 9514 mStreamVolumeAlias[streamType] == streamState.mStreamType) { 9515 mStreamStates[streamType].applyAllVolumes(); 9516 } 9517 } 9518 } 9519 persistVolume(VolumeStreamState streamState, int device)9520 private void persistVolume(VolumeStreamState streamState, int device) { 9521 if (mUseFixedVolume) { 9522 return; 9523 } 9524 if (mIsSingleVolume && (streamState.mStreamType != AudioSystem.STREAM_MUSIC)) { 9525 return; 9526 } 9527 9528 // Persisting STREAM_SYSTEM_ENFORCED index is not needed as its alias (STREAM_RING) 9529 // is persisted. This can also be problematic when the enforcement is active as it will 9530 // override current SYSTEM_RING persisted value given they share the same settings name 9531 // (due to aliasing). 9532 if (streamState.mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) { 9533 return; 9534 } 9535 if (streamState.hasValidSettingsName()) { 9536 mSettings.putSystemIntForUser(mContentResolver, 9537 streamState.getSettingNameForDevice(device), 9538 (streamState.getIndex(device) + 5) / 10, 9539 UserHandle.USER_CURRENT); 9540 } 9541 } 9542 persistRingerMode(int ringerMode)9543 private void persistRingerMode(int ringerMode) { 9544 if (mUseFixedVolume) { 9545 return; 9546 } 9547 mSettings.putGlobalInt(mContentResolver, Settings.Global.MODE_RINGER, ringerMode); 9548 } 9549 onNotifyVolumeEvent(@onNull IAudioPolicyCallback apc, @AudioManager.VolumeAdjustment int direction)9550 private void onNotifyVolumeEvent(@NonNull IAudioPolicyCallback apc, 9551 @AudioManager.VolumeAdjustment int direction) { 9552 try { 9553 apc.notifyVolumeAdjust(direction); 9554 } catch(Exception e) { 9555 // nothing we can do about this. Do not log error, too much potential for spam 9556 } 9557 } 9558 9559 @Override handleMessage(Message msg)9560 public void handleMessage(Message msg) { 9561 switch (msg.what) { 9562 9563 case MSG_SET_DEVICE_VOLUME: 9564 setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1); 9565 break; 9566 9567 case MSG_SET_ALL_VOLUMES: 9568 setAllVolumes((VolumeStreamState) msg.obj); 9569 break; 9570 9571 case MSG_PERSIST_VOLUME: 9572 persistVolume((VolumeStreamState) msg.obj, msg.arg1); 9573 break; 9574 9575 case MSG_PERSIST_VOLUME_GROUP: 9576 final VolumeGroupState vgs = (VolumeGroupState) msg.obj; 9577 vgs.persistVolumeGroup(msg.arg1); 9578 break; 9579 9580 case MSG_PERSIST_RINGER_MODE: 9581 // note that the value persisted is the current ringer mode, not the 9582 // value of ringer mode as of the time the request was made to persist 9583 persistRingerMode(getRingerModeInternal()); 9584 break; 9585 9586 case MSG_AUDIO_SERVER_DIED: 9587 onAudioServerDied(); 9588 break; 9589 9590 case MSG_DISPATCH_AUDIO_SERVER_STATE: 9591 onDispatchAudioServerStateChange(msg.arg1 == 1); 9592 break; 9593 9594 case MSG_UNLOAD_SOUND_EFFECTS: 9595 mSfxHelper.unloadSoundEffects(); 9596 break; 9597 9598 case MSG_LOAD_SOUND_EFFECTS: 9599 { 9600 LoadSoundEffectReply reply = (LoadSoundEffectReply) msg.obj; 9601 if (mSystemReady) { 9602 mSfxHelper.loadSoundEffects(reply); 9603 } else { 9604 Log.w(TAG, "[schedule]loadSoundEffects() called before boot complete"); 9605 if (reply != null) { 9606 reply.run(false); 9607 } 9608 } 9609 } 9610 break; 9611 9612 case MSG_PLAY_SOUND_EFFECT: 9613 mSfxHelper.playSoundEffect(msg.arg1, msg.arg2); 9614 break; 9615 9616 case MSG_SET_FORCE_USE: 9617 { 9618 final String eventSource = (String) msg.obj; 9619 final int useCase = msg.arg1; 9620 final int config = msg.arg2; 9621 if (useCase == AudioSystem.FOR_MEDIA) { 9622 Log.wtf(TAG, "Invalid force use FOR_MEDIA in AudioService from " 9623 + eventSource); 9624 break; 9625 } 9626 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE 9627 + MediaMetrics.SEPARATOR + AudioSystem.forceUseUsageToString(useCase)) 9628 .set(MediaMetrics.Property.EVENT, "setForceUse") 9629 .set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource) 9630 .set(MediaMetrics.Property.FORCE_USE_MODE, 9631 AudioSystem.forceUseConfigToString(config)) 9632 .record(); 9633 sForceUseLogger.enqueue( 9634 new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource)); 9635 mAudioSystem.setForceUse(useCase, config); 9636 } 9637 break; 9638 9639 case MSG_DISABLE_AUDIO_FOR_UID: 9640 mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */, 9641 msg.arg2 /* uid */); 9642 mAudioEventWakeLock.release(); 9643 break; 9644 9645 case MSG_INIT_STREAMS_VOLUMES: 9646 onInitStreamsAndVolumes(); 9647 mAudioEventWakeLock.release(); 9648 break; 9649 9650 case MSG_INIT_ADI_DEVICE_STATES: 9651 onInitAdiDeviceStates(); 9652 mAudioEventWakeLock.release(); 9653 break; 9654 9655 case MSG_INIT_SPATIALIZER: 9656 onInitSpatializer(); 9657 // the device inventory can only be synchronized after the 9658 // spatializer has been initialized 9659 mDeviceBroker.postSynchronizeAdiDevicesInInventory(null); 9660 mAudioEventWakeLock.release(); 9661 break; 9662 9663 case MSG_INIT_HEADTRACKING_SENSORS: 9664 mSpatializerHelper.onInitSensors(); 9665 break; 9666 9667 case MSG_RESET_SPATIALIZER: 9668 mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect); 9669 break; 9670 9671 case MSG_SYSTEM_READY: 9672 onSystemReady(); 9673 break; 9674 9675 case MSG_INDICATE_SYSTEM_READY: 9676 onIndicateSystemReady(); 9677 break; 9678 9679 case MSG_ACCESSORY_PLUG_MEDIA_UNMUTE: 9680 onAccessoryPlugMediaUnmute(msg.arg1); 9681 break; 9682 9683 case MSG_UNMUTE_STREAM_ON_SINGLE_VOL_DEVICE: 9684 onUnmuteStreamOnSingleVolDevice(msg.arg1, msg.arg2); 9685 break; 9686 9687 case MSG_DYN_POLICY_MIX_STATE_UPDATE: 9688 onDynPolicyMixStateUpdate((String) msg.obj, msg.arg1); 9689 break; 9690 9691 case MSG_NOTIFY_VOL_EVENT: 9692 onNotifyVolumeEvent((IAudioPolicyCallback) msg.obj, msg.arg1); 9693 break; 9694 9695 case MSG_ENABLE_SURROUND_FORMATS: 9696 onEnableSurroundFormats((ArrayList<Integer>) msg.obj); 9697 break; 9698 9699 case MSG_UPDATE_RINGER_MODE: 9700 onUpdateRingerModeServiceInt(); 9701 break; 9702 9703 case MSG_SET_DEVICE_STREAM_VOLUME: 9704 onSetVolumeIndexOnDevice((DeviceVolumeUpdate) msg.obj); 9705 break; 9706 9707 case MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS: 9708 onObserveDevicesForAllStreams(/*skipStream*/ msg.arg1); 9709 break; 9710 9711 case MSG_HDMI_VOLUME_CHECK: 9712 onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj); 9713 break; 9714 9715 case MSG_PLAYBACK_CONFIG_CHANGE: 9716 onPlaybackConfigChange((List<AudioPlaybackConfiguration>) msg.obj); 9717 break; 9718 case MSG_RECORDING_CONFIG_CHANGE: 9719 onRecordingConfigChange((List<AudioRecordingConfiguration>) msg.obj); 9720 break; 9721 9722 case MSG_BROADCAST_MICROPHONE_MUTE: 9723 mSystemServer.sendMicrophoneMuteChangedIntent(); 9724 break; 9725 9726 case MSG_BROADCAST_MASTER_MUTE: 9727 mSystemServer.broadcastMasterMuteStatus(msg.arg1 == 1); 9728 break; 9729 9730 case MSG_CHECK_MODE_FOR_UID: 9731 synchronized (mDeviceBroker.mSetModeLock) { 9732 if (msg.obj == null) { 9733 break; 9734 } 9735 // Update active playback/recording for apps requesting IN_COMMUNICATION 9736 // mode after a grace period following the mode change 9737 SetModeDeathHandler h = (SetModeDeathHandler) msg.obj; 9738 if (mSetModeDeathHandlers.indexOf(h) < 0) { 9739 break; 9740 } 9741 boolean wasActive = h.isActive(); 9742 h.setPlaybackActive(isPlaybackActiveForUid(h.getUid())); 9743 h.setRecordingActive(isRecordingActiveForUid(h.getUid())); 9744 if (wasActive != h.isActive()) { 9745 onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(), 9746 mContext.getPackageName(), false /*force*/); 9747 } 9748 } 9749 break; 9750 9751 case MSG_STREAM_DEVICES_CHANGED: 9752 final SomeArgs args = (SomeArgs) msg.obj; 9753 final Intent intent = (Intent) args.arg1; 9754 final Bundle options = (Bundle) args.arg2; 9755 args.recycle(); 9756 sendBroadcastToAll(intent 9757 .putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_DEVICES, msg.arg1) 9758 .putExtra(AudioManager.EXTRA_VOLUME_STREAM_DEVICES, msg.arg2), 9759 options); 9760 break; 9761 9762 case MSG_UPDATE_VOLUME_STATES_FOR_DEVICE: 9763 onUpdateVolumeStatesForAudioDevice(msg.arg1, (String) msg.obj); 9764 break; 9765 9766 case MSG_REINIT_VOLUMES: 9767 onReinitVolumes((String) msg.obj); 9768 break; 9769 9770 case MSG_UPDATE_A11Y_SERVICE_UIDS: 9771 onUpdateAccessibilityServiceUids(); 9772 break; 9773 9774 case MSG_UPDATE_AUDIO_MODE: 9775 synchronized (mDeviceBroker.mSetModeLock) { 9776 onUpdateAudioMode(msg.arg1, msg.arg2, (String) msg.obj, false /*force*/); 9777 } 9778 break; 9779 9780 case MSG_BT_DEV_CHANGED: 9781 mDeviceBroker.queueOnBluetoothActiveDeviceChanged( 9782 (AudioDeviceBroker.BtDeviceChangedData) msg.obj); 9783 break; 9784 9785 case MSG_DISPATCH_AUDIO_MODE: 9786 dispatchMode(msg.arg1); 9787 break; 9788 9789 case MSG_ROUTING_UPDATED: 9790 onRoutingUpdatedFromAudioThread(); 9791 break; 9792 9793 case MSG_ADD_ASSISTANT_SERVICE_UID: 9794 onAddAssistantServiceUids(new int[]{msg.arg1}); 9795 break; 9796 9797 case MSG_REMOVE_ASSISTANT_SERVICE_UID: 9798 onRemoveAssistantServiceUids(new int[]{msg.arg1}); 9799 break; 9800 case MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID: 9801 updateActiveAssistantServiceUids(); 9802 break; 9803 9804 case MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR: 9805 dispatchDeviceVolumeBehavior((AudioDeviceAttributes) msg.obj, msg.arg1); 9806 break; 9807 9808 case MSG_ROTATION_UPDATE: 9809 // rotation parameter format: "rotation=x" where x is one of 0, 90, 180, 270 9810 mAudioSystem.setParameters((String) msg.obj); 9811 break; 9812 9813 case MSG_FOLD_UPDATE: 9814 // fold parameter format: "device_folded=x" where x is one of on, off 9815 mAudioSystem.setParameters((String) msg.obj); 9816 break; 9817 9818 case MSG_NO_LOG_FOR_PLAYER_I: 9819 mPlaybackMonitor.ignorePlayerIId(msg.arg1); 9820 break; 9821 9822 case MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES: 9823 onDispatchPreferredMixerAttributesChanged(msg.getData(), msg.arg1); 9824 break; 9825 9826 case MSG_CONFIGURATION_CHANGED: 9827 onConfigurationChanged(); 9828 break; 9829 9830 case MusicFxHelper.MSG_EFFECT_CLIENT_GONE: 9831 mMusicFxHelper.handleMessage(msg); 9832 break; 9833 9834 case SoundDoseHelper.MSG_CONFIGURE_SAFE_MEDIA: 9835 case SoundDoseHelper.MSG_CONFIGURE_SAFE_MEDIA_FORCED: 9836 case SoundDoseHelper.MSG_PERSIST_SAFE_VOLUME_STATE: 9837 case SoundDoseHelper.MSG_PERSIST_MUSIC_ACTIVE_MS: 9838 case SoundDoseHelper.MSG_PERSIST_CSD_VALUES: 9839 case SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION: 9840 case SoundDoseHelper.MSG_LOWER_VOLUME_TO_RS1: 9841 mSoundDoseHelper.handleMessage(msg); 9842 break; 9843 9844 default: 9845 Log.e(TAG, "Unsupported msgId " + msg.what); 9846 } 9847 } 9848 } 9849 9850 private class SettingsObserver extends ContentObserver { 9851 SettingsObserver()9852 SettingsObserver() { 9853 super(new Handler()); 9854 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9855 Settings.Global.ZEN_MODE), false, this); 9856 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9857 Settings.Global.ZEN_MODE_CONFIG_ETAG), false, this); 9858 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9859 Settings.Global.MUTE_ALARM_STREAM_WITH_RINGER_MODE), false, this); 9860 mContentResolver.registerContentObserver(Settings.System.getUriFor( 9861 Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this); 9862 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9863 Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this); 9864 mContentResolver.registerContentObserver(Settings.System.getUriFor( 9865 Settings.System.MASTER_MONO), false, this, UserHandle.USER_ALL); 9866 mContentResolver.registerContentObserver(Settings.System.getUriFor( 9867 Settings.System.MASTER_BALANCE), false, this, UserHandle.USER_ALL); 9868 9869 mEncodedSurroundMode = mSettings.getGlobalInt( 9870 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT, 9871 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 9872 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9873 Settings.Global.ENCODED_SURROUND_OUTPUT), false, this); 9874 mEnabledSurroundFormats = mSettings.getGlobalString( 9875 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 9876 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9877 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS), false, this); 9878 9879 mContentResolver.registerContentObserver(Settings.Secure.getUriFor( 9880 Settings.Secure.VOICE_INTERACTION_SERVICE), false, this); 9881 } 9882 9883 @Override onChange(boolean selfChange)9884 public void onChange(boolean selfChange) { 9885 super.onChange(selfChange); 9886 // FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode. 9887 // However there appear to be some missing locks around sRingerAndZenModeMutedStreams 9888 // and mRingerModeAffectedStreams, so will leave this synchronized for now. 9889 // sRingerAndZenModeMutedStreams and mMuteAffectedStreams are safe (only accessed once). 9890 synchronized (mSettingsLock) { 9891 if (updateRingerAndZenModeAffectedStreams()) { 9892 /* 9893 * Ensure all stream types that should be affected by ringer mode 9894 * are in the proper state. 9895 */ 9896 setRingerModeInt(getRingerModeInternal(), false); 9897 } 9898 readDockAudioSettings(mContentResolver); 9899 updateMasterMono(mContentResolver); 9900 updateMasterBalance(mContentResolver); 9901 updateEncodedSurroundOutput(); 9902 sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged); 9903 updateAssistantUIdLocked(/* forceUpdate= */ false); 9904 } 9905 } 9906 updateEncodedSurroundOutput()9907 private void updateEncodedSurroundOutput() { 9908 int newSurroundMode = mSettings.getGlobalInt( 9909 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT, 9910 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 9911 // Did it change? 9912 if (mEncodedSurroundMode != newSurroundMode) { 9913 // Send to AudioPolicyManager 9914 sendEncodedSurroundMode(newSurroundMode, "SettingsObserver"); 9915 mDeviceBroker.toggleHdmiIfConnected_Async(); 9916 mEncodedSurroundMode = newSurroundMode; 9917 mSurroundModeChanged = true; 9918 } else { 9919 mSurroundModeChanged = false; 9920 } 9921 } 9922 } 9923 avrcpSupportsAbsoluteVolume(String address, boolean support)9924 private void avrcpSupportsAbsoluteVolume(String address, boolean support) { 9925 // address is not used for now, but may be used when multiple a2dp devices are supported 9926 sVolumeLogger.enqueue(new EventLogger.StringEvent("avrcpSupportsAbsoluteVolume addr=" 9927 + Utils.anonymizeBluetoothAddress(address) + " support=" + support).printLog(TAG)); 9928 mDeviceBroker.setAvrcpAbsoluteVolumeSupported(support); 9929 setAvrcpAbsoluteVolumeSupported(support); 9930 } 9931 setAvrcpAbsoluteVolumeSupported(boolean support)9932 /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean support) { 9933 mAvrcpAbsVolSupported = support; 9934 if (absVolumeIndexFix()) { 9935 int a2dpDev = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP; 9936 synchronized (mCachedAbsVolDrivingStreamsLock) { 9937 mCachedAbsVolDrivingStreams.compute(a2dpDev, (dev, stream) -> { 9938 if (stream != null && !mAvrcpAbsVolSupported) { 9939 mAudioSystem.setDeviceAbsoluteVolumeEnabled(a2dpDev, /*address=*/ 9940 "", /*enabled*/false, AudioSystem.DEVICE_NONE); 9941 return null; 9942 } 9943 // For A2DP and AVRCP we need to set the driving stream based on the 9944 // BT contextual stream. Hence, we need to make sure in adjustStreamVolume 9945 // and setStreamVolume that the driving abs volume stream is consistent. 9946 int streamToDriveAbs = getBluetoothContextualVolumeStream(); 9947 if (stream == null || stream != streamToDriveAbs) { 9948 mAudioSystem.setDeviceAbsoluteVolumeEnabled(a2dpDev, /*address=*/ 9949 "", /*enabled*/true, streamToDriveAbs); 9950 } 9951 return streamToDriveAbs; 9952 }); 9953 } 9954 } 9955 sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE, 9956 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, 9957 mStreamStates[AudioSystem.STREAM_MUSIC], 0); 9958 } 9959 9960 /** 9961 * @return true if there is currently a registered dynamic mixing policy that affects media 9962 * and is not a render + loopback policy 9963 */ 9964 // only public for mocking/spying 9965 @VisibleForTesting hasMediaDynamicPolicy()9966 public boolean hasMediaDynamicPolicy() { 9967 synchronized (mAudioPolicies) { 9968 if (mAudioPolicies.isEmpty()) { 9969 return false; 9970 } 9971 final Collection<AudioPolicyProxy> appColl = mAudioPolicies.values(); 9972 for (AudioPolicyProxy app : appColl) { 9973 if (app.hasMixAffectingUsage(AudioAttributes.USAGE_MEDIA, 9974 AudioMix.ROUTE_FLAG_LOOP_BACK_RENDER)) { 9975 return true; 9976 } 9977 } 9978 return false; 9979 } 9980 } 9981 9982 /** only public for mocking/spying, do not call outside of AudioService */ 9983 @VisibleForTesting checkMusicActive(int deviceType, String caller)9984 public void checkMusicActive(int deviceType, String caller) { 9985 if (mSoundDoseHelper.safeDevicesContains(deviceType)) { 9986 mSoundDoseHelper.scheduleMusicActiveCheck(); 9987 } 9988 } 9989 9990 /** 9991 * Receiver for misc intent broadcasts the Phone app cares about. 9992 */ 9993 private class AudioServiceBroadcastReceiver extends BroadcastReceiver { 9994 @Override onReceive(Context context, Intent intent)9995 public void onReceive(Context context, Intent intent) { 9996 final String action = intent.getAction(); 9997 int outDevice; 9998 int inDevice; 9999 int state; 10000 10001 if (action.equals(Intent.ACTION_DOCK_EVENT)) { 10002 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 10003 Intent.EXTRA_DOCK_STATE_UNDOCKED); 10004 int config; 10005 switch (dockState) { 10006 case Intent.EXTRA_DOCK_STATE_DESK: 10007 config = AudioSystem.FORCE_BT_DESK_DOCK; 10008 break; 10009 case Intent.EXTRA_DOCK_STATE_CAR: 10010 config = AudioSystem.FORCE_BT_CAR_DOCK; 10011 break; 10012 case Intent.EXTRA_DOCK_STATE_LE_DESK: 10013 config = AudioSystem.FORCE_ANALOG_DOCK; 10014 break; 10015 case Intent.EXTRA_DOCK_STATE_HE_DESK: 10016 config = AudioSystem.FORCE_DIGITAL_DOCK; 10017 break; 10018 case Intent.EXTRA_DOCK_STATE_UNDOCKED: 10019 default: 10020 config = AudioSystem.FORCE_NONE; 10021 } 10022 // Low end docks have a menu to enable or disable audio 10023 // (see mDockAudioMediaEnabled) 10024 if (!((dockState == Intent.EXTRA_DOCK_STATE_LE_DESK) 10025 || ((dockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) 10026 && (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK)))) { 10027 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, config, 10028 "ACTION_DOCK_EVENT intent"); 10029 } 10030 mDockState = dockState; 10031 } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED) 10032 || action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { 10033 mDeviceBroker.postReceiveBtEvent(intent); 10034 } else if (action.equals(Intent.ACTION_SCREEN_ON)) { 10035 if (mMonitorRotation) { 10036 RotationHelper.enable(); 10037 } 10038 AudioSystem.setParameters("screen_state=on"); 10039 } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { 10040 if (mMonitorRotation) { 10041 //reduce wakeups (save current) by only listening when display is on 10042 RotationHelper.disable(); 10043 } 10044 AudioSystem.setParameters("screen_state=off"); 10045 } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) { 10046 sendMsg(mAudioHandler, 10047 MSG_CONFIGURATION_CHANGED, 10048 SENDMSG_REPLACE, 10049 0, 10050 0, 10051 null, 0); 10052 } else if (action.equals(Intent.ACTION_USER_SWITCHED)) { 10053 // the current audio focus owner is likely no longer valid 10054 final boolean audioDiscarded = mMediaFocusControl.maybeDiscardAudioFocusOwner(); 10055 if (audioDiscarded && mUserSwitchedReceived) { 10056 // attempt to stop music playback for background user except on first user 10057 // switch (i.e. first boot) 10058 mDeviceBroker.postBroadcastBecomingNoisy(); 10059 } 10060 mUserSwitchedReceived = true; 10061 10062 if (mSupportsMicPrivacyToggle) { 10063 mMicMuteFromPrivacyToggle = mSensorPrivacyManagerInternal 10064 .isSensorPrivacyEnabled(getCurrentUserId(), 10065 SensorPrivacyManager.Sensors.MICROPHONE); 10066 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); 10067 } 10068 10069 // load volume settings for new user 10070 readAudioSettings(true /*userSwitch*/); 10071 // preserve STREAM_MUSIC volume from one user to the next. 10072 sendMsg(mAudioHandler, 10073 MSG_SET_ALL_VOLUMES, 10074 SENDMSG_QUEUE, 10075 0, 10076 0, 10077 mStreamStates[AudioSystem.STREAM_MUSIC], 0); 10078 } else if (action.equals(Intent.ACTION_USER_BACKGROUND)) { 10079 // Disable audio recording for the background user/profile 10080 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 10081 if (userId >= 0) { 10082 // TODO Kill recording streams instead of killing processes holding permission 10083 UserInfo userInfo = UserManagerService.getInstance().getUserInfo(userId); 10084 killBackgroundUserProcessesWithRecordAudioPermission(userInfo); 10085 } 10086 try { 10087 UserManagerService.getInstance().setUserRestriction( 10088 UserManager.DISALLOW_RECORD_AUDIO, true, userId); 10089 } catch (IllegalArgumentException e) { 10090 Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e); 10091 } 10092 } else if (action.equals(Intent.ACTION_USER_FOREGROUND)) { 10093 // Enable audio recording for foreground user/profile 10094 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 10095 try { 10096 UserManagerService.getInstance().setUserRestriction( 10097 UserManager.DISALLOW_RECORD_AUDIO, false, userId); 10098 } catch (IllegalArgumentException e) { 10099 Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e); 10100 } 10101 } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) || 10102 action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) { 10103 mMusicFxHelper.handleAudioEffectBroadcast(context, intent); 10104 } else if (action.equals(Intent.ACTION_PACKAGES_SUSPENDED)) { 10105 final int[] suspendedUids = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST); 10106 final String[] suspendedPackages = 10107 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 10108 if (suspendedPackages == null || suspendedUids == null 10109 || suspendedPackages.length != suspendedUids.length) { 10110 return; 10111 } 10112 for (int i = 0; i < suspendedUids.length; i++) { 10113 if (!TextUtils.isEmpty(suspendedPackages[i])) { 10114 mMediaFocusControl.noFocusForSuspendedApp( 10115 suspendedPackages[i], suspendedUids[i]); 10116 } 10117 } 10118 } else if (action.equals(ACTION_CHECK_MUSIC_ACTIVE)) { 10119 mSoundDoseHelper.onCheckMusicActive(ACTION_CHECK_MUSIC_ACTIVE, 10120 mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)); 10121 } 10122 } 10123 } // end class AudioServiceBroadcastReceiver 10124 10125 private class AudioServiceUserRestrictionsListener implements UserRestrictionsListener { 10126 10127 @Override onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions)10128 public void onUserRestrictionsChanged(int userId, Bundle newRestrictions, 10129 Bundle prevRestrictions) { 10130 // Update mic mute state. 10131 { 10132 final boolean wasRestricted = 10133 prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE); 10134 final boolean isRestricted = 10135 newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE); 10136 if (wasRestricted != isRestricted) { 10137 mMicMuteFromRestrictions = isRestricted; 10138 setMicrophoneMuteNoCallerCheck(userId); 10139 } 10140 } 10141 10142 // Update speaker mute state. 10143 { 10144 final boolean wasRestricted = 10145 prevRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME) 10146 || prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE); 10147 final boolean isRestricted = 10148 newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME) 10149 || newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE); 10150 if (wasRestricted != isRestricted) { 10151 setMasterMuteInternalNoCallerCheck( 10152 isRestricted, /* flags =*/ 0, userId, "onUserRestrictionsChanged"); 10153 } 10154 } 10155 } 10156 } // end class AudioServiceUserRestrictionsListener 10157 killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser)10158 private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) { 10159 PackageManager pm = mContext.getPackageManager(); 10160 // Find the home activity of the user. It should not be killed to avoid expensive restart, 10161 // when the user switches back. For managed profiles, we should kill all recording apps 10162 ComponentName homeActivityName = null; 10163 if (!oldUser.isManagedProfile()) { 10164 homeActivityName = LocalServices.getService( 10165 ActivityTaskManagerInternal.class).getHomeActivityForUser(oldUser.id); 10166 } 10167 final String[] permissions = { Manifest.permission.RECORD_AUDIO }; 10168 List<PackageInfo> packages; 10169 try { 10170 packages = AppGlobals.getPackageManager() 10171 .getPackagesHoldingPermissions(permissions, 0, oldUser.id).getList(); 10172 } catch (RemoteException e) { 10173 throw new AndroidRuntimeException(e); 10174 } 10175 for (int j = packages.size() - 1; j >= 0; j--) { 10176 PackageInfo pkg = packages.get(j); 10177 // Skip system processes 10178 if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) { 10179 continue; 10180 } 10181 // Skip packages that have permission to interact across users 10182 if (pm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS, pkg.packageName) 10183 == PackageManager.PERMISSION_GRANTED) { 10184 continue; 10185 } 10186 if (homeActivityName != null 10187 && pkg.packageName.equals(homeActivityName.getPackageName()) 10188 && pkg.applicationInfo.isSystemApp()) { 10189 continue; 10190 } 10191 try { 10192 final int uid = pkg.applicationInfo.uid; 10193 ActivityManager.getService().killUid(UserHandle.getAppId(uid), 10194 UserHandle.getUserId(uid), 10195 "killBackgroundUserProcessesWithAudioRecordPermission"); 10196 } catch (RemoteException e) { 10197 Log.w(TAG, "Error calling killUid", e); 10198 } 10199 } 10200 } 10201 10202 10203 //========================================================================================== 10204 // Audio Focus 10205 //========================================================================================== 10206 /** 10207 * Returns whether a focus request is eligible to force ducking. 10208 * Will return true if: 10209 * - the AudioAttributes have a usage of USAGE_ASSISTANCE_ACCESSIBILITY, 10210 * - the focus request is AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 10211 * - the associated Bundle has KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING set to true, 10212 * - the uid of the requester is a known accessibility service or root. 10213 * @param aa AudioAttributes of the focus request 10214 * @param uid uid of the focus requester 10215 * @return true if ducking is to be forced 10216 */ forceFocusDuckingForAccessibility(@ullable AudioAttributes aa, int request, int uid)10217 private boolean forceFocusDuckingForAccessibility(@Nullable AudioAttributes aa, 10218 int request, int uid) { 10219 if (aa == null || aa.getUsage() != AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY 10220 || request != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) { 10221 return false; 10222 } 10223 final Bundle extraInfo = aa.getBundle(); 10224 if (extraInfo == null || 10225 !extraInfo.getBoolean(AudioFocusRequest.KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING)) { 10226 return false; 10227 } 10228 if (uid == 0) { 10229 return true; 10230 } 10231 synchronized (mAccessibilityServiceUidsLock) { 10232 if (mAccessibilityServiceUids != null) { 10233 int callingUid = Binder.getCallingUid(); 10234 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 10235 if (mAccessibilityServiceUids[i] == callingUid) { 10236 return true; 10237 } 10238 } 10239 } 10240 } 10241 return false; 10242 } 10243 isSupportedSystemUsage(@udioAttributes.AttributeUsage int usage)10244 private boolean isSupportedSystemUsage(@AudioAttributes.AttributeUsage int usage) { 10245 synchronized (mSupportedSystemUsagesLock) { 10246 for (int i = 0; i < mSupportedSystemUsages.length; i++) { 10247 if (mSupportedSystemUsages[i] == usage) { 10248 return true; 10249 } 10250 } 10251 return false; 10252 } 10253 } 10254 validateAudioAttributesUsage(@onNull AudioAttributes audioAttributes)10255 private void validateAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) { 10256 @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage(); 10257 if (AudioAttributes.isSystemUsage(usage)) { 10258 if ((usage == AudioAttributes.USAGE_CALL_ASSISTANT 10259 && (audioAttributes.getAllFlags() & AudioAttributes.FLAG_CALL_REDIRECTION) != 0 10260 && callerHasPermission(CALL_AUDIO_INTERCEPTION)) 10261 || callerHasPermission(MODIFY_AUDIO_ROUTING)) { 10262 if (!isSupportedSystemUsage(usage)) { 10263 throw new IllegalArgumentException( 10264 "Unsupported usage " + AudioAttributes.usageToString(usage)); 10265 } 10266 } else { 10267 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission"); 10268 } 10269 } 10270 } 10271 isValidAudioAttributesUsage(@onNull AudioAttributes audioAttributes)10272 private boolean isValidAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) { 10273 @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage(); 10274 if (AudioAttributes.isSystemUsage(usage)) { 10275 return isSupportedSystemUsage(usage) 10276 && ((usage == AudioAttributes.USAGE_CALL_ASSISTANT 10277 && (audioAttributes.getAllFlags() 10278 & AudioAttributes.FLAG_CALL_REDIRECTION) != 0 10279 && callerHasPermission(CALL_AUDIO_INTERCEPTION)) 10280 || callerHasPermission(MODIFY_AUDIO_ROUTING)); 10281 } 10282 return true; 10283 } 10284 requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk)10285 public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, 10286 IAudioFocusDispatcher fd, String clientId, String callingPackageName, 10287 String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk) { 10288 if ((flags & AudioManager.AUDIOFOCUS_FLAG_TEST) != 0) { 10289 throw new IllegalArgumentException("Invalid test flag"); 10290 } 10291 final int uid = Binder.getCallingUid(); 10292 MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus") 10293 .setUid(uid) 10294 //.putInt("durationHint", durationHint) 10295 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) 10296 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 10297 .set(MediaMetrics.Property.EVENT, "requestAudioFocus") 10298 .set(MediaMetrics.Property.FLAGS, flags); 10299 10300 // permission checks 10301 if (aa != null && !isValidAudioAttributesUsage(aa)) { 10302 final String reason = "Request using unsupported usage"; 10303 Log.w(TAG, reason); 10304 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 10305 .record(); 10306 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 10307 } 10308 if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) { 10309 if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) { 10310 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 10311 MODIFY_PHONE_STATE)) { 10312 final String reason = "Invalid permission to (un)lock audio focus"; 10313 Log.e(TAG, reason, new Exception()); 10314 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 10315 .record(); 10316 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 10317 } 10318 } else { 10319 // only a registered audio policy can be used to lock focus 10320 synchronized (mAudioPolicies) { 10321 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 10322 final String reason = 10323 "Invalid unregistered AudioPolicy to (un)lock audio focus"; 10324 Log.e(TAG, reason); 10325 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 10326 .record(); 10327 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 10328 } 10329 } 10330 } 10331 } 10332 10333 if (callingPackageName == null || clientId == null || aa == null) { 10334 final String reason = "Invalid null parameter to request audio focus"; 10335 Log.e(TAG, reason); 10336 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 10337 .record(); 10338 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 10339 } 10340 10341 // does caller have system privileges to bypass HardeningEnforcer 10342 boolean permissionOverridesCheck = false; 10343 if ((mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) 10344 == PackageManager.PERMISSION_GRANTED) 10345 || (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING) 10346 == PackageManager.PERMISSION_GRANTED)) { 10347 permissionOverridesCheck = true; 10348 } else if (uid < UserHandle.AID_APP_START) { 10349 permissionOverridesCheck = true; 10350 } 10351 10352 final long token = Binder.clearCallingIdentity(); 10353 try { 10354 if (!permissionOverridesCheck && mHardeningEnforcer.blockFocusMethod(uid, 10355 HardeningEnforcer.METHOD_AUDIO_MANAGER_REQUEST_AUDIO_FOCUS, 10356 clientId, durationHint, callingPackageName, attributionTag, sdk)) { 10357 final String reason = "Audio focus request blocked by hardening"; 10358 Log.w(TAG, reason); 10359 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason).record(); 10360 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 10361 } 10362 } finally { 10363 Binder.restoreCallingIdentity(token); 10364 } 10365 10366 mmi.record(); 10367 return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd, 10368 clientId, callingPackageName, flags, sdk, 10369 forceFocusDuckingForAccessibility(aa, durationHint, uid), -1 /*testUid, ignored*/, 10370 permissionOverridesCheck); 10371 } 10372 10373 /** 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)10374 public int requestAudioFocusForTest(AudioAttributes aa, int durationHint, IBinder cb, 10375 IAudioFocusDispatcher fd, String clientId, String callingPackageName, 10376 int flags, int fakeUid, int sdk) { 10377 if (!enforceQueryAudioStateForTest("focus request")) { 10378 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 10379 } 10380 if (callingPackageName == null || clientId == null || aa == null) { 10381 final String reason = "Invalid null parameter to request audio focus"; 10382 Log.e(TAG, reason); 10383 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 10384 } 10385 return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd, 10386 clientId, callingPackageName, flags, 10387 sdk, false /*forceDuck*/, fakeUid, true /*permissionOverridesCheck*/); 10388 } 10389 abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)10390 public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, 10391 String callingPackageName) { 10392 MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus") 10393 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) 10394 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 10395 .set(MediaMetrics.Property.EVENT, "abandonAudioFocus"); 10396 10397 if (aa != null && !isValidAudioAttributesUsage(aa)) { 10398 Log.w(TAG, "Request using unsupported usage."); 10399 mmi.set(MediaMetrics.Property.EARLY_RETURN, "unsupported usage").record(); 10400 10401 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 10402 } 10403 mmi.record(); 10404 return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName); 10405 } 10406 10407 /** see {@link AudioManager#abandonAudioFocusForTest(AudioFocusRequest, String)} */ abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)10408 public int abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, 10409 AudioAttributes aa, String callingPackageName) { 10410 if (!enforceQueryAudioStateForTest("focus abandon")) { 10411 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 10412 } 10413 return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName); 10414 } 10415 10416 /** see {@link AudioManager#getFocusDuckedUidsForTest()} */ 10417 @Override 10418 @EnforcePermission("android.permission.QUERY_AUDIO_STATE") getFocusDuckedUidsForTest()10419 public @NonNull List<Integer> getFocusDuckedUidsForTest() { 10420 super.getFocusDuckedUidsForTest_enforcePermission(); 10421 return mPlaybackMonitor.getFocusDuckedUids(); 10422 } 10423 unregisterAudioFocusClient(String clientId)10424 public void unregisterAudioFocusClient(String clientId) { 10425 new MediaMetrics.Item(mMetricsId + "focus") 10426 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 10427 .set(MediaMetrics.Property.EVENT, "unregisterAudioFocusClient") 10428 .record(); 10429 mMediaFocusControl.unregisterAudioFocusClient(clientId); 10430 } 10431 getCurrentAudioFocus()10432 public int getCurrentAudioFocus() { 10433 return mMediaFocusControl.getCurrentAudioFocus(); 10434 } 10435 getFocusRampTimeMs(int focusGain, AudioAttributes attr)10436 public int getFocusRampTimeMs(int focusGain, AudioAttributes attr) { 10437 return mMediaFocusControl.getFocusRampTimeMs(focusGain, attr); 10438 } 10439 10440 /** 10441 * Test method to return the duration of the fade out applied on the players of a focus loser 10442 * @see AudioManager#getFocusFadeOutDurationForTest() 10443 * @return the fade out duration, in ms 10444 */ 10445 @EnforcePermission("android.permission.QUERY_AUDIO_STATE") getFocusFadeOutDurationForTest()10446 public long getFocusFadeOutDurationForTest() { 10447 super.getFocusFadeOutDurationForTest_enforcePermission(); 10448 return mMediaFocusControl.getFocusFadeOutDurationForTest(); 10449 } 10450 10451 /** 10452 * Test method to return the length of time after a fade out before the focus loser is unmuted 10453 * (and is faded back in). 10454 * @see AudioManager#getFocusUnmuteDelayAfterFadeOutForTest() 10455 * @return the time gap after a fade out completion on focus loss, and fade in start, in ms 10456 */ 10457 @Override 10458 @EnforcePermission("android.permission.QUERY_AUDIO_STATE") getFocusUnmuteDelayAfterFadeOutForTest()10459 public long getFocusUnmuteDelayAfterFadeOutForTest() { 10460 super.getFocusUnmuteDelayAfterFadeOutForTest_enforcePermission(); 10461 return mMediaFocusControl.getFocusUnmuteDelayAfterFadeOutForTest(); 10462 } 10463 10464 /** 10465 * Test method to start preventing applications from requesting audio focus during a test, 10466 * which could interfere with the testing of the functionality/behavior under test. 10467 * Calling this method needs to be paired with a call to {@link #exitAudioFocusFreezeForTest} 10468 * when the testing is done. If this is not the case (e.g. in case of a test crash), 10469 * a death observer mechanism will ensure the system is not left in a bad state, but this should 10470 * not be relied on when implementing tests. 10471 * @see AudioManager#enterAudioFocusFreezeForTest(List) 10472 * @param cb IBinder to track the death of the client of this method 10473 * @param exemptedUids a list of UIDs that are exempt from the freeze. This would for instance 10474 * be those of the test runner and other players used in the test 10475 * @return true if the focus freeze mode is successfully entered, false if there was an issue, 10476 * such as another freeze currently used. 10477 */ 10478 @Override 10479 @EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) enterAudioFocusFreezeForTest(IBinder cb, int[] exemptedUids)10480 public boolean enterAudioFocusFreezeForTest(IBinder cb, int[] exemptedUids) { 10481 super.enterAudioFocusFreezeForTest_enforcePermission(); 10482 Objects.requireNonNull(exemptedUids); 10483 Objects.requireNonNull(cb); 10484 return mMediaFocusControl.enterAudioFocusFreezeForTest(cb, exemptedUids); 10485 } 10486 10487 /** 10488 * Test method to end preventing applications from requesting audio focus during a test. 10489 * @see AudioManager#exitAudioFocusFreezeForTest() 10490 * @param cb IBinder identifying the client of this method 10491 * @return true if the focus freeze mode is successfully exited, false if there was an issue, 10492 * such as the freeze already having ended, or not started. 10493 */ 10494 @Override 10495 @EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) exitAudioFocusFreezeForTest(IBinder cb)10496 public boolean exitAudioFocusFreezeForTest(IBinder cb) { 10497 super.exitAudioFocusFreezeForTest_enforcePermission(); 10498 Objects.requireNonNull(cb); 10499 return mMediaFocusControl.exitAudioFocusFreezeForTest(cb); 10500 } 10501 10502 /** only public for mocking/spying, do not call outside of AudioService */ 10503 @VisibleForTesting hasAudioFocusUsers()10504 public boolean hasAudioFocusUsers() { 10505 return mMediaFocusControl.hasAudioFocusUsers(); 10506 } 10507 10508 /** see {@link AudioManager#getFadeOutDurationOnFocusLossMillis(AudioAttributes)} */ 10509 @Override getFadeOutDurationOnFocusLossMillis(AudioAttributes aa)10510 public long getFadeOutDurationOnFocusLossMillis(AudioAttributes aa) { 10511 if (!enforceQueryAudioStateForTest("fade out duration")) { 10512 return 0; 10513 } 10514 return mMediaFocusControl.getFadeOutDurationOnFocusLossMillis(aa); 10515 } 10516 enforceQueryAudioStateForTest(String mssg)10517 private boolean enforceQueryAudioStateForTest(String mssg) { 10518 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 10519 Manifest.permission.QUERY_AUDIO_STATE)) { 10520 final String reason = "Doesn't have QUERY_AUDIO_STATE permission for " 10521 + mssg + " test API"; 10522 Log.e(TAG, reason, new Exception()); 10523 return false; 10524 } 10525 return true; 10526 } 10527 10528 //========================================================================================== 10529 private final @NonNull SpatializerHelper mSpatializerHelper; 10530 /** 10531 * Initialized from property ro.audio.spatializer_enabled 10532 * Should only be 1 when the device ships with a Spatializer effect 10533 */ 10534 private final boolean mHasSpatializerEffect; 10535 /** 10536 * Default value for the spatial audio feature 10537 */ 10538 private static final boolean SPATIAL_AUDIO_ENABLED_DEFAULT = true; 10539 enforceModifyDefaultAudioEffectsPermission()10540 private void enforceModifyDefaultAudioEffectsPermission() { 10541 if (mContext.checkCallingOrSelfPermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10542 != PackageManager.PERMISSION_GRANTED) { 10543 throw new SecurityException("Missing MODIFY_DEFAULT_AUDIO_EFFECTS permission"); 10544 } 10545 } 10546 10547 /** 10548 * Returns the immersive audio level that the platform is capable of 10549 * @see Spatializer#getImmersiveAudioLevel() 10550 */ getSpatializerImmersiveAudioLevel()10551 public int getSpatializerImmersiveAudioLevel() { 10552 return mSpatializerHelper.getCapableImmersiveAudioLevel(); 10553 } 10554 10555 /** @see Spatializer#isEnabled() */ isSpatializerEnabled()10556 public boolean isSpatializerEnabled() { 10557 return mSpatializerHelper.isEnabled(); 10558 } 10559 10560 /** @see Spatializer#isAvailable() */ isSpatializerAvailable()10561 public boolean isSpatializerAvailable() { 10562 return mSpatializerHelper.isAvailable(); 10563 } 10564 10565 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10566 /** @see Spatializer#isAvailableForDevice(AudioDeviceAttributes) */ isSpatializerAvailableForDevice(@onNull AudioDeviceAttributes device)10567 public boolean isSpatializerAvailableForDevice(@NonNull AudioDeviceAttributes device) { 10568 super.isSpatializerAvailableForDevice_enforcePermission(); 10569 10570 return mSpatializerHelper.isAvailableForDevice(Objects.requireNonNull(device)); 10571 } 10572 10573 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10574 /** @see Spatializer#hasHeadTracker(AudioDeviceAttributes) */ hasHeadTracker(@onNull AudioDeviceAttributes device)10575 public boolean hasHeadTracker(@NonNull AudioDeviceAttributes device) { 10576 super.hasHeadTracker_enforcePermission(); 10577 10578 return mSpatializerHelper.hasHeadTracker(Objects.requireNonNull(device)); 10579 } 10580 10581 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10582 /** @see Spatializer#setHeadTrackerEnabled(boolean, AudioDeviceAttributes) */ setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device)10583 public void setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device) { 10584 super.setHeadTrackerEnabled_enforcePermission(); 10585 10586 mSpatializerHelper.setHeadTrackerEnabled(enabled, Objects.requireNonNull(device)); 10587 } 10588 10589 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10590 /** @see Spatializer#isHeadTrackerEnabled(AudioDeviceAttributes) */ isHeadTrackerEnabled(@onNull AudioDeviceAttributes device)10591 public boolean isHeadTrackerEnabled(@NonNull AudioDeviceAttributes device) { 10592 super.isHeadTrackerEnabled_enforcePermission(); 10593 10594 return mSpatializerHelper.isHeadTrackerEnabled(Objects.requireNonNull(device)); 10595 } 10596 10597 /** @see Spatializer#isHeadTrackerAvailable() */ isHeadTrackerAvailable()10598 public boolean isHeadTrackerAvailable() { 10599 return mSpatializerHelper.isHeadTrackerAvailable(); 10600 } 10601 10602 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10603 /** @see Spatializer#setSpatializerEnabled(boolean) */ setSpatializerEnabled(boolean enabled)10604 public void setSpatializerEnabled(boolean enabled) { 10605 super.setSpatializerEnabled_enforcePermission(); 10606 10607 mSpatializerHelper.setFeatureEnabled(enabled); 10608 } 10609 10610 /** @see Spatializer#canBeSpatialized() */ canBeSpatialized( @onNull AudioAttributes attributes, @NonNull AudioFormat format)10611 public boolean canBeSpatialized( 10612 @NonNull AudioAttributes attributes, @NonNull AudioFormat format) { 10613 Objects.requireNonNull(attributes); 10614 Objects.requireNonNull(format); 10615 return mSpatializerHelper.canBeSpatialized(attributes, format); 10616 } 10617 10618 /** @see Spatializer.SpatializerInfoDispatcherStub */ registerSpatializerCallback( @onNull ISpatializerCallback cb)10619 public void registerSpatializerCallback( 10620 @NonNull ISpatializerCallback cb) { 10621 Objects.requireNonNull(cb); 10622 mSpatializerHelper.registerStateCallback(cb); 10623 } 10624 10625 /** @see Spatializer.SpatializerInfoDispatcherStub */ unregisterSpatializerCallback( @onNull ISpatializerCallback cb)10626 public void unregisterSpatializerCallback( 10627 @NonNull ISpatializerCallback cb) { 10628 Objects.requireNonNull(cb); 10629 mSpatializerHelper.unregisterStateCallback(cb); 10630 } 10631 10632 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10633 /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */ registerSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)10634 public void registerSpatializerHeadTrackingCallback( 10635 @NonNull ISpatializerHeadTrackingModeCallback cb) { 10636 super.registerSpatializerHeadTrackingCallback_enforcePermission(); 10637 10638 Objects.requireNonNull(cb); 10639 mSpatializerHelper.registerHeadTrackingModeCallback(cb); 10640 } 10641 10642 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10643 /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */ unregisterSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)10644 public void unregisterSpatializerHeadTrackingCallback( 10645 @NonNull ISpatializerHeadTrackingModeCallback cb) { 10646 super.unregisterSpatializerHeadTrackingCallback_enforcePermission(); 10647 10648 Objects.requireNonNull(cb); 10649 mSpatializerHelper.unregisterHeadTrackingModeCallback(cb); 10650 } 10651 10652 /** @see Spatializer.SpatializerHeadTrackerAvailableDispatcherStub */ registerSpatializerHeadTrackerAvailableCallback( @onNull ISpatializerHeadTrackerAvailableCallback cb, boolean register)10653 public void registerSpatializerHeadTrackerAvailableCallback( 10654 @NonNull ISpatializerHeadTrackerAvailableCallback cb, boolean register) { 10655 Objects.requireNonNull(cb); 10656 mSpatializerHelper.registerHeadTrackerAvailableCallback(cb, register); 10657 } 10658 10659 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10660 /** @see Spatializer#setOnHeadToSoundstagePoseUpdatedListener */ registerHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)10661 public void registerHeadToSoundstagePoseCallback( 10662 @NonNull ISpatializerHeadToSoundStagePoseCallback cb) { 10663 super.registerHeadToSoundstagePoseCallback_enforcePermission(); 10664 10665 Objects.requireNonNull(cb); 10666 mSpatializerHelper.registerHeadToSoundstagePoseCallback(cb); 10667 } 10668 10669 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10670 /** @see Spatializer#clearOnHeadToSoundstagePoseUpdatedListener */ unregisterHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)10671 public void unregisterHeadToSoundstagePoseCallback( 10672 @NonNull ISpatializerHeadToSoundStagePoseCallback cb) { 10673 super.unregisterHeadToSoundstagePoseCallback_enforcePermission(); 10674 10675 Objects.requireNonNull(cb); 10676 mSpatializerHelper.unregisterHeadToSoundstagePoseCallback(cb); 10677 } 10678 10679 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10680 /** @see Spatializer#getSpatializerCompatibleAudioDevices() */ getSpatializerCompatibleAudioDevices()10681 public @NonNull List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices() { 10682 super.getSpatializerCompatibleAudioDevices_enforcePermission(); 10683 10684 return mSpatializerHelper.getCompatibleAudioDevices(); 10685 } 10686 10687 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10688 /** @see Spatializer#addSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */ addSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)10689 public void addSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { 10690 super.addSpatializerCompatibleAudioDevice_enforcePermission(); 10691 10692 Objects.requireNonNull(ada); 10693 mSpatializerHelper.addCompatibleAudioDevice(ada); 10694 } 10695 10696 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10697 /** @see Spatializer#removeSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */ removeSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)10698 public void removeSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { 10699 super.removeSpatializerCompatibleAudioDevice_enforcePermission(); 10700 10701 Objects.requireNonNull(ada); 10702 mSpatializerHelper.removeCompatibleAudioDevice(ada); 10703 } 10704 10705 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10706 /** @see Spatializer#getSupportedHeadTrackingModes() */ getSupportedHeadTrackingModes()10707 public int[] getSupportedHeadTrackingModes() { 10708 super.getSupportedHeadTrackingModes_enforcePermission(); 10709 10710 return mSpatializerHelper.getSupportedHeadTrackingModes(); 10711 } 10712 10713 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10714 /** @see Spatializer#getHeadTrackingMode() */ getActualHeadTrackingMode()10715 public int getActualHeadTrackingMode() { 10716 super.getActualHeadTrackingMode_enforcePermission(); 10717 10718 return mSpatializerHelper.getActualHeadTrackingMode(); 10719 } 10720 10721 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10722 /** @see Spatializer#getDesiredHeadTrackingMode() */ getDesiredHeadTrackingMode()10723 public int getDesiredHeadTrackingMode() { 10724 super.getDesiredHeadTrackingMode_enforcePermission(); 10725 10726 return mSpatializerHelper.getDesiredHeadTrackingMode(); 10727 } 10728 10729 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10730 /** @see Spatializer#setGlobalTransform */ setSpatializerGlobalTransform(@onNull float[] transform)10731 public void setSpatializerGlobalTransform(@NonNull float[] transform) { 10732 super.setSpatializerGlobalTransform_enforcePermission(); 10733 10734 Objects.requireNonNull(transform); 10735 mSpatializerHelper.setGlobalTransform(transform); 10736 } 10737 10738 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10739 /** @see Spatializer#recenterHeadTracker() */ recenterHeadTracker()10740 public void recenterHeadTracker() { 10741 super.recenterHeadTracker_enforcePermission(); 10742 10743 mSpatializerHelper.recenterHeadTracker(); 10744 } 10745 10746 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10747 /** @see Spatializer#setDesiredHeadTrackingMode */ setDesiredHeadTrackingMode(@patializer.HeadTrackingModeSet int mode)10748 public void setDesiredHeadTrackingMode(@Spatializer.HeadTrackingModeSet int mode) { 10749 super.setDesiredHeadTrackingMode_enforcePermission(); 10750 10751 switch(mode) { 10752 case Spatializer.HEAD_TRACKING_MODE_DISABLED: 10753 case Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD: 10754 case Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE: 10755 break; 10756 default: 10757 return; 10758 } 10759 mSpatializerHelper.setDesiredHeadTrackingMode(mode); 10760 } 10761 10762 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10763 /** @see Spatializer#setEffectParameter */ setSpatializerParameter(int key, @NonNull byte[] value)10764 public void setSpatializerParameter(int key, @NonNull byte[] value) { 10765 super.setSpatializerParameter_enforcePermission(); 10766 10767 Objects.requireNonNull(value); 10768 mSpatializerHelper.setEffectParameter(key, value); 10769 } 10770 10771 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10772 /** @see Spatializer#getEffectParameter */ getSpatializerParameter(int key, @NonNull byte[] value)10773 public void getSpatializerParameter(int key, @NonNull byte[] value) { 10774 super.getSpatializerParameter_enforcePermission(); 10775 10776 Objects.requireNonNull(value); 10777 mSpatializerHelper.getEffectParameter(key, value); 10778 } 10779 10780 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10781 /** @see Spatializer#getOutput */ getSpatializerOutput()10782 public int getSpatializerOutput() { 10783 super.getSpatializerOutput_enforcePermission(); 10784 10785 return mSpatializerHelper.getOutput(); 10786 } 10787 10788 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10789 /** @see Spatializer#setOnSpatializerOutputChangedListener */ registerSpatializerOutputCallback(ISpatializerOutputCallback cb)10790 public void registerSpatializerOutputCallback(ISpatializerOutputCallback cb) { 10791 super.registerSpatializerOutputCallback_enforcePermission(); 10792 10793 Objects.requireNonNull(cb); 10794 mSpatializerHelper.registerSpatializerOutputCallback(cb); 10795 } 10796 10797 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 10798 /** @see Spatializer#clearOnSpatializerOutputChangedListener */ unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb)10799 public void unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb) { 10800 super.unregisterSpatializerOutputCallback_enforcePermission(); 10801 10802 Objects.requireNonNull(cb); 10803 mSpatializerHelper.unregisterSpatializerOutputCallback(cb); 10804 } 10805 10806 /** 10807 * post a message to schedule init/release of head tracking sensors 10808 * whether to initialize or release sensors is based on the state of spatializer 10809 */ postInitSpatializerHeadTrackingSensors()10810 void postInitSpatializerHeadTrackingSensors() { 10811 sendMsg(mAudioHandler, 10812 MSG_INIT_HEADTRACKING_SENSORS, 10813 SENDMSG_REPLACE, 10814 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0); 10815 } 10816 10817 /** 10818 * post a message to schedule a reset of the spatializer state 10819 */ postResetSpatializer()10820 void postResetSpatializer() { 10821 sendMsg(mAudioHandler, 10822 MSG_RESET_SPATIALIZER, 10823 SENDMSG_REPLACE, 10824 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0); 10825 } 10826 onInitAdiDeviceStates()10827 void onInitAdiDeviceStates() { 10828 mDeviceBroker.onReadAudioDeviceSettings(); 10829 mSoundDoseHelper.initCachedAudioDeviceCategories( 10830 mDeviceBroker.getImmutableDeviceInventory()); 10831 } 10832 onInitSpatializer()10833 void onInitSpatializer() { 10834 mSpatializerHelper.init(/*effectExpected*/ mHasSpatializerEffect); 10835 mSpatializerHelper.setFeatureEnabled(mHasSpatializerEffect); 10836 } 10837 isSADevice(AdiDeviceState deviceState)10838 /*package*/ boolean isSADevice(AdiDeviceState deviceState) { 10839 return mSpatializerHelper.isSADevice(deviceState); 10840 } 10841 isBluetoothPrividged()10842 private boolean isBluetoothPrividged() { 10843 return PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 10844 Manifest.permission.BLUETOOTH_CONNECT) 10845 || Binder.getCallingUid() == Process.SYSTEM_UID; 10846 } 10847 retrieveBluetoothAddresses(List<AudioDeviceAttributes> devices)10848 List<AudioDeviceAttributes> retrieveBluetoothAddresses(List<AudioDeviceAttributes> devices) { 10849 if (isBluetoothPrividged()) { 10850 return devices; 10851 } 10852 10853 List<AudioDeviceAttributes> checkedDevices = new ArrayList<AudioDeviceAttributes>(); 10854 for (AudioDeviceAttributes ada : devices) { 10855 if (ada == null) { 10856 continue; 10857 } 10858 checkedDevices.add(retrieveBluetoothAddressUncheked(ada)); 10859 } 10860 return checkedDevices; 10861 } 10862 retrieveBluetoothAddress(@onNull AudioDeviceAttributes ada)10863 AudioDeviceAttributes retrieveBluetoothAddress(@NonNull AudioDeviceAttributes ada) { 10864 if (isBluetoothPrividged()) { 10865 return ada; 10866 } 10867 return retrieveBluetoothAddressUncheked(ada); 10868 } 10869 retrieveBluetoothAddressUncheked(@onNull AudioDeviceAttributes ada)10870 AudioDeviceAttributes retrieveBluetoothAddressUncheked(@NonNull AudioDeviceAttributes ada) { 10871 Objects.requireNonNull(ada); 10872 if (AudioSystem.isBluetoothDevice(ada.getInternalType())) { 10873 String anonymizedAddress = Utils.anonymizeBluetoothAddress(ada.getAddress()); 10874 for (AdiDeviceState ads : mDeviceBroker.getImmutableDeviceInventory()) { 10875 if (!(AudioSystem.isBluetoothDevice(ads.getInternalDeviceType()) 10876 && (ada.getInternalType() == ads.getInternalDeviceType()) 10877 && anonymizedAddress.equals(Utils.anonymizeBluetoothAddress( 10878 ads.getDeviceAddress())))) { 10879 continue; 10880 } 10881 ada.setAddress(ads.getDeviceAddress()); 10882 break; 10883 } 10884 } 10885 return ada; 10886 } 10887 anonymizeAudioDeviceAttributesList( List<AudioDeviceAttributes> devices)10888 private List<AudioDeviceAttributes> anonymizeAudioDeviceAttributesList( 10889 List<AudioDeviceAttributes> devices) { 10890 if (isBluetoothPrividged()) { 10891 return devices; 10892 } 10893 return anonymizeAudioDeviceAttributesListUnchecked(devices); 10894 } 10895 anonymizeAudioDeviceAttributesListUnchecked( List<AudioDeviceAttributes> devices)10896 /* package */ List<AudioDeviceAttributes> anonymizeAudioDeviceAttributesListUnchecked( 10897 List<AudioDeviceAttributes> devices) { 10898 List<AudioDeviceAttributes> anonymizedDevices = new ArrayList<AudioDeviceAttributes>(); 10899 for (AudioDeviceAttributes ada : devices) { 10900 anonymizedDevices.add(anonymizeAudioDeviceAttributesUnchecked(ada)); 10901 } 10902 return anonymizedDevices; 10903 } 10904 anonymizeAudioDeviceAttributesUnchecked( AudioDeviceAttributes ada)10905 private AudioDeviceAttributes anonymizeAudioDeviceAttributesUnchecked( 10906 AudioDeviceAttributes ada) { 10907 if (!AudioSystem.isBluetoothDevice(ada.getInternalType())) { 10908 return ada; 10909 } 10910 AudioDeviceAttributes res = new AudioDeviceAttributes(ada); 10911 res.setAddress(Utils.anonymizeBluetoothAddress(ada.getAddress())); 10912 return res; 10913 } 10914 anonymizeAudioDeviceAttributes(AudioDeviceAttributes ada)10915 private AudioDeviceAttributes anonymizeAudioDeviceAttributes(AudioDeviceAttributes ada) { 10916 if (isBluetoothPrividged()) { 10917 return ada; 10918 } 10919 10920 return anonymizeAudioDeviceAttributesUnchecked(ada); 10921 } 10922 10923 // ======================================================================================== 10924 // LoudnessCodecConfigurator 10925 10926 @Override registerLoudnessCodecUpdatesDispatcher(ILoudnessCodecUpdatesDispatcher dispatcher)10927 public void registerLoudnessCodecUpdatesDispatcher(ILoudnessCodecUpdatesDispatcher dispatcher) { 10928 mLoudnessCodecHelper.registerLoudnessCodecUpdatesDispatcher(dispatcher); 10929 } 10930 10931 @Override unregisterLoudnessCodecUpdatesDispatcher( ILoudnessCodecUpdatesDispatcher dispatcher)10932 public void unregisterLoudnessCodecUpdatesDispatcher( 10933 ILoudnessCodecUpdatesDispatcher dispatcher) { 10934 mLoudnessCodecHelper.unregisterLoudnessCodecUpdatesDispatcher(dispatcher); 10935 } 10936 10937 /** @see LoudnessCodecController#create(int) */ 10938 @Override startLoudnessCodecUpdates(int sessionId)10939 public void startLoudnessCodecUpdates(int sessionId) { 10940 mLoudnessCodecHelper.startLoudnessCodecUpdates(sessionId); 10941 } 10942 10943 /** @see LoudnessCodecController#release() */ 10944 @Override stopLoudnessCodecUpdates(int sessionId)10945 public void stopLoudnessCodecUpdates(int sessionId) { 10946 mLoudnessCodecHelper.stopLoudnessCodecUpdates(sessionId); 10947 } 10948 10949 /** @see LoudnessCodecController#addMediaCodec(MediaCodec) */ 10950 @Override addLoudnessCodecInfo(int sessionId, int mediaCodecHash, LoudnessCodecInfo codecInfo)10951 public void addLoudnessCodecInfo(int sessionId, int mediaCodecHash, 10952 LoudnessCodecInfo codecInfo) { 10953 mLoudnessCodecHelper.addLoudnessCodecInfo(sessionId, mediaCodecHash, codecInfo); 10954 } 10955 10956 /** @see LoudnessCodecController#removeMediaCodec(MediaCodec) */ 10957 @Override removeLoudnessCodecInfo(int sessionId, LoudnessCodecInfo codecInfo)10958 public void removeLoudnessCodecInfo(int sessionId, LoudnessCodecInfo codecInfo) { 10959 mLoudnessCodecHelper.removeLoudnessCodecInfo(sessionId, codecInfo); 10960 } 10961 10962 /** @see LoudnessCodecController#getLoudnessCodecParams(MediaCodec) */ 10963 @Override getLoudnessParams(LoudnessCodecInfo codecInfo)10964 public PersistableBundle getLoudnessParams(LoudnessCodecInfo codecInfo) { 10965 return mLoudnessCodecHelper.getLoudnessParams(codecInfo); 10966 } 10967 10968 //========================================================================================== 10969 10970 // camera sound is forced if any of the resources corresponding to one active SIM 10971 // demands it. readCameraSoundForced()10972 private boolean readCameraSoundForced() { 10973 if (SystemProperties.getBoolean("audio.camerasound.force", false) 10974 || mContext.getResources().getBoolean( 10975 com.android.internal.R.bool.config_camera_sound_forced)) { 10976 return true; 10977 } 10978 10979 SubscriptionManager subscriptionManager = mContext.getSystemService( 10980 SubscriptionManager.class); 10981 if (subscriptionManager == null) { 10982 Log.e(TAG, "readCameraSoundForced cannot create SubscriptionManager!"); 10983 return false; 10984 } 10985 int[] subscriptionIds = subscriptionManager.getActiveSubscriptionIdList(false); 10986 for (int subId : subscriptionIds) { 10987 if (SubscriptionManager.getResourcesForSubId(mContext, subId).getBoolean( 10988 com.android.internal.R.bool.config_camera_sound_forced)) { 10989 return true; 10990 } 10991 } 10992 return false; 10993 } 10994 10995 //========================================================================================== 10996 private final Object mMuteAwaitConnectionLock = new Object(); 10997 10998 /** 10999 * The device that is expected to be connected soon, and causes players to be muted until 11000 * its connection, or it times out. 11001 * Null when no active muting command, or it has timed out. 11002 */ 11003 @GuardedBy("mMuteAwaitConnectionLock") 11004 private AudioDeviceAttributes mMutingExpectedDevice; 11005 @GuardedBy("mMuteAwaitConnectionLock") 11006 private @Nullable int[] mMutedUsagesAwaitingConnection; 11007 11008 /** @see AudioManager#muteAwaitConnection */ 11009 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection muteAwaitConnection(@onNull int[] usages, @NonNull AudioDeviceAttributes device, long timeOutMs)11010 public void muteAwaitConnection(@NonNull int[] usages, 11011 @NonNull AudioDeviceAttributes device, long timeOutMs) { 11012 Objects.requireNonNull(usages); 11013 Objects.requireNonNull(device); 11014 enforceModifyAudioRoutingPermission(); 11015 11016 final AudioDeviceAttributes ada = retrieveBluetoothAddress(device); 11017 11018 if (timeOutMs <= 0 || usages.length == 0) { 11019 throw new IllegalArgumentException("Invalid timeOutMs/usagesToMute"); 11020 } 11021 Log.i(TAG, "muteAwaitConnection dev:" + device + " timeOutMs:" + timeOutMs 11022 + " usages:" + Arrays.toString(usages)); 11023 11024 if (mDeviceBroker.isDeviceConnected(ada)) { 11025 // not throwing an exception as there could be a race between a connection (server-side, 11026 // notification of connection in flight) and a mute operation (client-side) 11027 Log.i(TAG, "muteAwaitConnection ignored, device (" + device + ") already connected"); 11028 return; 11029 } 11030 synchronized (mMuteAwaitConnectionLock) { 11031 if (mMutingExpectedDevice != null) { 11032 Log.e(TAG, "muteAwaitConnection ignored, another in progress for device:" 11033 + mMutingExpectedDevice); 11034 throw new IllegalStateException("muteAwaitConnection already in progress"); 11035 } 11036 mMutingExpectedDevice = ada; 11037 mMutedUsagesAwaitingConnection = usages; 11038 mPlaybackMonitor.muteAwaitConnection(usages, ada, timeOutMs); 11039 } 11040 dispatchMuteAwaitConnection((cb, isPrivileged) -> { 11041 try { 11042 AudioDeviceAttributes dev = ada; 11043 if (!isPrivileged) { 11044 dev = anonymizeAudioDeviceAttributesUnchecked(ada); 11045 } 11046 cb.dispatchOnMutedUntilConnection(dev, usages); 11047 } catch (RemoteException e) { } 11048 }); 11049 } 11050 11051 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 11052 /** @see AudioManager#getMutingExpectedDevice */ getMutingExpectedDevice()11053 public @Nullable AudioDeviceAttributes getMutingExpectedDevice() { 11054 super.getMutingExpectedDevice_enforcePermission(); 11055 11056 synchronized (mMuteAwaitConnectionLock) { 11057 return anonymizeAudioDeviceAttributes(mMutingExpectedDevice); 11058 } 11059 } 11060 11061 /** @see AudioManager#cancelMuteAwaitConnection */ 11062 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection cancelMuteAwaitConnection(@onNull AudioDeviceAttributes device)11063 public void cancelMuteAwaitConnection(@NonNull AudioDeviceAttributes device) { 11064 Objects.requireNonNull(device); 11065 enforceModifyAudioRoutingPermission(); 11066 11067 final AudioDeviceAttributes ada = retrieveBluetoothAddress(device); 11068 11069 Log.i(TAG, "cancelMuteAwaitConnection for device:" + device); 11070 final int[] mutedUsages; 11071 synchronized (mMuteAwaitConnectionLock) { 11072 if (mMutingExpectedDevice == null) { 11073 // not throwing an exception as there could be a race between a timeout 11074 // (server-side) and a cancel operation (client-side) 11075 Log.i(TAG, "cancelMuteAwaitConnection ignored, no expected device"); 11076 return; 11077 } 11078 if (!ada.equalTypeAddress(mMutingExpectedDevice)) { 11079 Log.e(TAG, "cancelMuteAwaitConnection ignored, got " + device 11080 + "] but expected device is" + mMutingExpectedDevice); 11081 throw new IllegalStateException("cancelMuteAwaitConnection for wrong device"); 11082 } 11083 mutedUsages = mMutedUsagesAwaitingConnection; 11084 mMutingExpectedDevice = null; 11085 mMutedUsagesAwaitingConnection = null; 11086 mPlaybackMonitor.cancelMuteAwaitConnection("cancelMuteAwaitConnection dev:" + device); 11087 } 11088 dispatchMuteAwaitConnection((cb, isPrivileged) -> { 11089 try { 11090 AudioDeviceAttributes dev = ada; 11091 if (!isPrivileged) { 11092 dev = anonymizeAudioDeviceAttributesUnchecked(ada); 11093 } 11094 cb.dispatchOnUnmutedEvent( 11095 AudioManager.MuteAwaitConnectionCallback.EVENT_CANCEL, dev, mutedUsages); 11096 } catch (RemoteException e) { } }); 11097 } 11098 11099 final RemoteCallbackList<IMuteAwaitConnectionCallback> mMuteAwaitConnectionDispatchers = 11100 new RemoteCallbackList<IMuteAwaitConnectionCallback>(); 11101 11102 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 11103 /** @see AudioManager#registerMuteAwaitConnectionCallback */ registerMuteAwaitConnectionDispatcher(@onNull IMuteAwaitConnectionCallback cb, boolean register)11104 public void registerMuteAwaitConnectionDispatcher(@NonNull IMuteAwaitConnectionCallback cb, 11105 boolean register) { 11106 super.registerMuteAwaitConnectionDispatcher_enforcePermission(); 11107 11108 if (register) { 11109 mMuteAwaitConnectionDispatchers.register(cb, isBluetoothPrividged()); 11110 } else { 11111 mMuteAwaitConnectionDispatchers.unregister(cb); 11112 } 11113 } 11114 11115 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection checkMuteAwaitConnection()11116 void checkMuteAwaitConnection() { 11117 final AudioDeviceAttributes device; 11118 final int[] mutedUsages; 11119 synchronized (mMuteAwaitConnectionLock) { 11120 if (mMutingExpectedDevice == null) { 11121 return; 11122 } 11123 device = mMutingExpectedDevice; 11124 mutedUsages = mMutedUsagesAwaitingConnection; 11125 if (!mDeviceBroker.isDeviceConnected(device)) { 11126 return; 11127 } 11128 mMutingExpectedDevice = null; 11129 mMutedUsagesAwaitingConnection = null; 11130 mPlaybackMonitor.cancelMuteAwaitConnection( 11131 "checkMuteAwaitConnection device " + device + " connected, unmuting"); 11132 } 11133 dispatchMuteAwaitConnection((cb, isPrivileged) -> { 11134 try { 11135 AudioDeviceAttributes ada = device; 11136 if (!isPrivileged) { 11137 ada = anonymizeAudioDeviceAttributesUnchecked(device); 11138 } 11139 cb.dispatchOnUnmutedEvent(AudioManager.MuteAwaitConnectionCallback.EVENT_CONNECTION, 11140 ada, mutedUsages); 11141 } catch (RemoteException e) { } }); 11142 } 11143 11144 /** 11145 * Called by PlaybackActivityMonitor when the timeout hit for the mute on device connection 11146 */ 11147 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection onMuteAwaitConnectionTimeout(@onNull AudioDeviceAttributes timedOutDevice)11148 void onMuteAwaitConnectionTimeout(@NonNull AudioDeviceAttributes timedOutDevice) { 11149 final int[] mutedUsages; 11150 synchronized (mMuteAwaitConnectionLock) { 11151 if (!timedOutDevice.equals(mMutingExpectedDevice)) { 11152 return; 11153 } 11154 Log.i(TAG, "muteAwaitConnection timeout, clearing expected device " 11155 + mMutingExpectedDevice); 11156 mutedUsages = mMutedUsagesAwaitingConnection; 11157 mMutingExpectedDevice = null; 11158 mMutedUsagesAwaitingConnection = null; 11159 } 11160 dispatchMuteAwaitConnection((cb, isPrivileged) -> { 11161 try { 11162 cb.dispatchOnUnmutedEvent( 11163 AudioManager.MuteAwaitConnectionCallback.EVENT_TIMEOUT, 11164 timedOutDevice, mutedUsages); 11165 } catch (RemoteException e) { } }); 11166 } 11167 dispatchMuteAwaitConnection( java.util.function.BiConsumer<IMuteAwaitConnectionCallback, Boolean> callback)11168 private void dispatchMuteAwaitConnection( 11169 java.util.function.BiConsumer<IMuteAwaitConnectionCallback, Boolean> callback) { 11170 final int nbDispatchers = mMuteAwaitConnectionDispatchers.beginBroadcast(); 11171 // lazy initialization as errors unlikely 11172 ArrayList<IMuteAwaitConnectionCallback> errorList = null; 11173 for (int i = 0; i < nbDispatchers; i++) { 11174 try { 11175 callback.accept(mMuteAwaitConnectionDispatchers.getBroadcastItem(i), 11176 (Boolean) mMuteAwaitConnectionDispatchers.getBroadcastCookie(i)); 11177 } catch (Exception e) { 11178 if (errorList == null) { 11179 errorList = new ArrayList<>(1); 11180 } 11181 errorList.add(mMuteAwaitConnectionDispatchers.getBroadcastItem(i)); 11182 } 11183 } 11184 if (errorList != null) { 11185 for (IMuteAwaitConnectionCallback errorItem : errorList) { 11186 mMuteAwaitConnectionDispatchers.unregister(errorItem); 11187 } 11188 } 11189 mMuteAwaitConnectionDispatchers.finishBroadcast(); 11190 } 11191 11192 final RemoteCallbackList<IDeviceVolumeBehaviorDispatcher> mDeviceVolumeBehaviorDispatchers = 11193 new RemoteCallbackList<IDeviceVolumeBehaviorDispatcher>(); 11194 11195 /** 11196 * @see AudioDeviceVolumeManager#addOnDeviceVolumeBehaviorChangedListener and 11197 * AudioDeviceVolumeManager#removeOnDeviceVolumeBehaviorChangedListener 11198 */ registerDeviceVolumeBehaviorDispatcher(boolean register, @NonNull IDeviceVolumeBehaviorDispatcher dispatcher)11199 public void registerDeviceVolumeBehaviorDispatcher(boolean register, 11200 @NonNull IDeviceVolumeBehaviorDispatcher dispatcher) { 11201 enforceQueryStateOrModifyRoutingPermission(); 11202 Objects.requireNonNull(dispatcher); 11203 if (register) { 11204 mDeviceVolumeBehaviorDispatchers.register(dispatcher); 11205 } else { 11206 mDeviceVolumeBehaviorDispatchers.unregister(dispatcher); 11207 } 11208 } 11209 dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior)11210 private void dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior) { 11211 final int dispatchers = mDeviceVolumeBehaviorDispatchers.beginBroadcast(); 11212 for (int i = 0; i < dispatchers; i++) { 11213 try { 11214 mDeviceVolumeBehaviorDispatchers.getBroadcastItem(i) 11215 .dispatchDeviceVolumeBehaviorChanged(device, volumeBehavior); 11216 } catch (RemoteException e) { 11217 } 11218 } 11219 mDeviceVolumeBehaviorDispatchers.finishBroadcast(); 11220 } 11221 11222 //========================================================================================== 11223 // Device orientation 11224 //========================================================================================== 11225 /** 11226 * Handles device configuration changes that may map to a change in rotation. 11227 * Monitoring rotation is optional, and is defined by the definition and value 11228 * of the "ro.audio.monitorRotation" system property. 11229 */ onConfigurationChanged()11230 private void onConfigurationChanged() { 11231 try { 11232 // reading new configuration "safely" (i.e. under try catch) in case anything 11233 // goes wrong. 11234 Configuration config = mContext.getResources().getConfiguration(); 11235 mSoundDoseHelper.configureSafeMedia(/*forced*/false, TAG); 11236 11237 boolean cameraSoundForced = readCameraSoundForced(); 11238 synchronized (mSettingsLock) { 11239 final boolean cameraSoundForcedChanged = (cameraSoundForced != mCameraSoundForced); 11240 mCameraSoundForced = cameraSoundForced; 11241 if (cameraSoundForcedChanged) { 11242 if (!mIsSingleVolume) { 11243 synchronized (VolumeStreamState.class) { 11244 VolumeStreamState s = mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED]; 11245 if (cameraSoundForced) { 11246 s.setAllIndexesToMax(); 11247 mRingerModeAffectedStreams &= 11248 ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 11249 } else { 11250 s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM], TAG); 11251 mRingerModeAffectedStreams |= 11252 (1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 11253 } 11254 } 11255 // take new state into account for streams muted by ringer mode 11256 setRingerModeInt(getRingerModeInternal(), false); 11257 } 11258 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, 11259 cameraSoundForced ? 11260 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE, 11261 "onConfigurationChanged"); 11262 sendMsg(mAudioHandler, 11263 MSG_SET_ALL_VOLUMES, 11264 SENDMSG_QUEUE, 11265 0, 11266 0, 11267 mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED], 0); 11268 11269 } 11270 } 11271 mVolumeController.setLayoutDirection(config.getLayoutDirection()); 11272 } catch (Exception e) { 11273 Log.e(TAG, "Error handling configuration change: ", e); 11274 } 11275 } 11276 11277 @android.annotation.EnforcePermission(Manifest.permission.REMOTE_AUDIO_PLAYBACK) 11278 @Override setRingtonePlayer(IRingtonePlayer player)11279 public void setRingtonePlayer(IRingtonePlayer player) { 11280 setRingtonePlayer_enforcePermission(); 11281 mRingtonePlayer = player; 11282 } 11283 11284 @Override getRingtonePlayer()11285 public IRingtonePlayer getRingtonePlayer() { 11286 return mRingtonePlayer; 11287 } 11288 11289 @Override startWatchingRoutes(IAudioRoutesObserver observer)11290 public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) { 11291 return mDeviceBroker.startWatchingRoutes(observer); 11292 } 11293 11294 @Override disableSafeMediaVolume(String callingPackage)11295 public void disableSafeMediaVolume(String callingPackage) { 11296 enforceVolumeController("disable the safe media volume"); 11297 mSoundDoseHelper.disableSafeMediaVolume(callingPackage); 11298 } 11299 11300 @Override lowerVolumeToRs1(String callingPackage)11301 public void lowerVolumeToRs1(String callingPackage) { 11302 enforceVolumeController("lowerVolumeToRs1"); 11303 postLowerVolumeToRs1(); 11304 } 11305 postLowerVolumeToRs1()11306 /*package*/ void postLowerVolumeToRs1() { 11307 sendMsg(mAudioHandler, SoundDoseHelper.MSG_LOWER_VOLUME_TO_RS1, SENDMSG_QUEUE, 11308 // no params, no delay 11309 0, 0, null, 0); 11310 } 11311 11312 @Override 11313 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) getOutputRs2UpperBound()11314 public float getOutputRs2UpperBound() { 11315 super.getOutputRs2UpperBound_enforcePermission(); 11316 return mSoundDoseHelper.getOutputRs2UpperBound(); 11317 } 11318 11319 @Override 11320 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setOutputRs2UpperBound(float rs2Value)11321 public void setOutputRs2UpperBound(float rs2Value) { 11322 super.setOutputRs2UpperBound_enforcePermission(); 11323 mSoundDoseHelper.setOutputRs2UpperBound(rs2Value); 11324 } 11325 11326 @Override 11327 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) getCsd()11328 public float getCsd() { 11329 super.getCsd_enforcePermission(); 11330 return mSoundDoseHelper.getCsd(); 11331 } 11332 11333 @Override 11334 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setCsd(float csd)11335 public void setCsd(float csd) { 11336 super.setCsd_enforcePermission(); 11337 if (csd < 0.0f) { 11338 mSoundDoseHelper.resetCsdTimeouts(); 11339 } else { 11340 mSoundDoseHelper.setCsd(csd); 11341 } 11342 } 11343 11344 @Override 11345 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) forceUseFrameworkMel(boolean useFrameworkMel)11346 public void forceUseFrameworkMel(boolean useFrameworkMel) { 11347 super.forceUseFrameworkMel_enforcePermission(); 11348 mSoundDoseHelper.forceUseFrameworkMel(useFrameworkMel); 11349 } 11350 11351 @Override 11352 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices)11353 public void forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices) { 11354 super.forceComputeCsdOnAllDevices_enforcePermission(); 11355 mSoundDoseHelper.forceComputeCsdOnAllDevices(computeCsdOnAllDevices); 11356 } 11357 11358 @Override 11359 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isCsdEnabled()11360 public boolean isCsdEnabled() { 11361 super.isCsdEnabled_enforcePermission(); 11362 return mSoundDoseHelper.isCsdEnabled(); 11363 } 11364 11365 @Override 11366 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isCsdAsAFeatureAvailable()11367 public boolean isCsdAsAFeatureAvailable() { 11368 super.isCsdAsAFeatureAvailable_enforcePermission(); 11369 return mSoundDoseHelper.isCsdAsAFeatureAvailable(); 11370 } 11371 11372 @Override 11373 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isCsdAsAFeatureEnabled()11374 public boolean isCsdAsAFeatureEnabled() { 11375 super.isCsdAsAFeatureEnabled_enforcePermission(); 11376 return mSoundDoseHelper.isCsdAsAFeatureEnabled(); 11377 } 11378 11379 @Override 11380 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setCsdAsAFeatureEnabled(boolean csdToggleValue)11381 public void setCsdAsAFeatureEnabled(boolean csdToggleValue) { 11382 super.setCsdAsAFeatureEnabled_enforcePermission(); 11383 mSoundDoseHelper.setCsdAsAFeatureEnabled(csdToggleValue); 11384 } 11385 11386 @Override 11387 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setBluetoothAudioDeviceCategory_legacy(@onNull String address, boolean isBle, @AudioDeviceCategory int btAudioDeviceCategory)11388 public void setBluetoothAudioDeviceCategory_legacy(@NonNull String address, boolean isBle, 11389 @AudioDeviceCategory int btAudioDeviceCategory) { 11390 super.setBluetoothAudioDeviceCategory_legacy_enforcePermission(); 11391 if (automaticBtDeviceType()) { 11392 // do nothing 11393 return; 11394 } 11395 11396 final String addr = Objects.requireNonNull(address); 11397 11398 AdiDeviceState deviceState = mDeviceBroker.findBtDeviceStateForAddress(addr, 11399 (isBle ? AudioSystem.DEVICE_OUT_BLE_HEADSET 11400 : AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP)); 11401 11402 int internalType = !isBle ? DEVICE_OUT_BLUETOOTH_A2DP 11403 : ((btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES) 11404 ? DEVICE_OUT_BLE_HEADSET : DEVICE_OUT_BLE_SPEAKER); 11405 int deviceType = !isBle ? TYPE_BLUETOOTH_A2DP 11406 : ((btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES) ? TYPE_BLE_HEADSET 11407 : TYPE_BLE_SPEAKER); 11408 11409 if (deviceState == null) { 11410 deviceState = new AdiDeviceState(deviceType, internalType, addr); 11411 } 11412 11413 deviceState.setAudioDeviceCategory(btAudioDeviceCategory); 11414 11415 mDeviceBroker.addOrUpdateBtAudioDeviceCategoryInInventory( 11416 deviceState, true /*syncInventory*/); 11417 mDeviceBroker.postPersistAudioDeviceSettings(); 11418 11419 mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes(), 11420 false /* initState */); 11421 mSoundDoseHelper.setAudioDeviceCategory(addr, internalType, 11422 btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES); 11423 } 11424 11425 @Override 11426 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) 11427 @AudioDeviceCategory getBluetoothAudioDeviceCategory_legacy(@onNull String address, boolean isBle)11428 public int getBluetoothAudioDeviceCategory_legacy(@NonNull String address, boolean isBle) { 11429 super.getBluetoothAudioDeviceCategory_legacy_enforcePermission(); 11430 if (automaticBtDeviceType()) { 11431 return AUDIO_DEVICE_CATEGORY_UNKNOWN; 11432 } 11433 11434 final AdiDeviceState deviceState = mDeviceBroker.findBtDeviceStateForAddress( 11435 Objects.requireNonNull(address), (isBle ? AudioSystem.DEVICE_OUT_BLE_HEADSET 11436 : AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP)); 11437 if (deviceState == null) { 11438 return AUDIO_DEVICE_CATEGORY_UNKNOWN; 11439 } 11440 11441 return deviceState.getAudioDeviceCategory(); 11442 } 11443 11444 @Override 11445 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setBluetoothAudioDeviceCategory(@onNull String address, @AudioDeviceCategory int btAudioDeviceCategory)11446 public boolean setBluetoothAudioDeviceCategory(@NonNull String address, 11447 @AudioDeviceCategory int btAudioDeviceCategory) { 11448 super.setBluetoothAudioDeviceCategory_enforcePermission(); 11449 if (!automaticBtDeviceType()) { 11450 return false; 11451 } 11452 11453 final String addr = Objects.requireNonNull(address); 11454 if (isBluetoothAudioDeviceCategoryFixed(addr)) { 11455 Log.w(TAG, "Cannot set fixed audio device type for address " 11456 + Utils.anonymizeBluetoothAddress(address)); 11457 return false; 11458 } 11459 11460 mDeviceBroker.addAudioDeviceWithCategoryInInventoryIfNeeded(address, btAudioDeviceCategory); 11461 11462 return true; 11463 } 11464 11465 @Override 11466 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) 11467 @AudioDeviceCategory getBluetoothAudioDeviceCategory(@onNull String address)11468 public int getBluetoothAudioDeviceCategory(@NonNull String address) { 11469 super.getBluetoothAudioDeviceCategory_enforcePermission(); 11470 if (!automaticBtDeviceType()) { 11471 return AUDIO_DEVICE_CATEGORY_UNKNOWN; 11472 } 11473 11474 return mDeviceBroker.getAndUpdateBtAdiDeviceStateCategoryForAddress(address); 11475 } 11476 11477 @Override 11478 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isBluetoothAudioDeviceCategoryFixed(@onNull String address)11479 public boolean isBluetoothAudioDeviceCategoryFixed(@NonNull String address) { 11480 super.isBluetoothAudioDeviceCategoryFixed_enforcePermission(); 11481 if (!automaticBtDeviceType()) { 11482 return false; 11483 } 11484 11485 return mDeviceBroker.isBluetoothAudioDeviceCategoryFixed(address); 11486 } 11487 11488 /** Update the sound dose and spatializer state based on the new AdiDeviceState. */ 11489 @VisibleForTesting(visibility = PACKAGE) onUpdatedAdiDeviceState(AdiDeviceState deviceState, boolean initSA)11490 public void onUpdatedAdiDeviceState(AdiDeviceState deviceState, boolean initSA) { 11491 if (deviceState == null) { 11492 return; 11493 } 11494 mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes(), initSA); 11495 mSoundDoseHelper.setAudioDeviceCategory(deviceState.getDeviceAddress(), 11496 deviceState.getInternalDeviceType(), 11497 deviceState.getAudioDeviceCategory() == AUDIO_DEVICE_CATEGORY_HEADPHONES); 11498 } 11499 11500 //========================================================================================== 11501 // Hdmi CEC: 11502 // - System audio mode: 11503 // If Hdmi Cec's system audio mode is on, audio service should send the volume change 11504 // to HdmiControlService so that the audio receiver can handle it. 11505 // - CEC sink: 11506 // OUT_HDMI becomes a "full volume device", i.e. output is always at maximum level 11507 // and volume changes won't be taken into account on this device. Volume adjustments 11508 // are transformed into key events for the HDMI playback client. 11509 //========================================================================================== 11510 11511 @GuardedBy("mHdmiClientLock") updateHdmiCecSinkLocked(boolean hdmiCecSink)11512 private void updateHdmiCecSinkLocked(boolean hdmiCecSink) { 11513 if (!hasDeviceVolumeBehavior(AudioSystem.DEVICE_OUT_HDMI)) { 11514 if (hdmiCecSink) { 11515 if (DEBUG_VOL) { 11516 Log.d(TAG, "CEC sink: setting HDMI as full vol device"); 11517 } 11518 setDeviceVolumeBehaviorInternal( 11519 new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""), 11520 AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL, 11521 "AudioService.updateHdmiCecSinkLocked()"); 11522 } else { 11523 if (DEBUG_VOL) { 11524 Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device"); 11525 } 11526 // Android TV devices without CEC service apply software volume on 11527 // HDMI output 11528 setDeviceVolumeBehaviorInternal( 11529 new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""), 11530 AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE, 11531 "AudioService.updateHdmiCecSinkLocked()"); 11532 } 11533 postUpdateVolumeStatesForAudioDevice(AudioSystem.DEVICE_OUT_HDMI, 11534 "HdmiPlaybackClient.DisplayStatusCallback"); 11535 } 11536 } 11537 11538 private class MyHdmiControlStatusChangeListenerCallback 11539 implements HdmiControlManager.HdmiControlStatusChangeListener { onStatusChange(@dmiControlManager.HdmiCecControl int isCecEnabled, boolean isCecAvailable)11540 public void onStatusChange(@HdmiControlManager.HdmiCecControl int isCecEnabled, 11541 boolean isCecAvailable) { 11542 synchronized (mHdmiClientLock) { 11543 if (mHdmiManager == null) return; 11544 boolean cecEnabled = isCecEnabled == HdmiControlManager.HDMI_CEC_CONTROL_ENABLED; 11545 updateHdmiCecSinkLocked(cecEnabled ? isCecAvailable : false); 11546 } 11547 } 11548 }; 11549 11550 private class MyHdmiCecVolumeControlFeatureListener 11551 implements HdmiControlManager.HdmiCecVolumeControlFeatureListener { onHdmiCecVolumeControlFeature( @dmiControlManager.VolumeControl int hdmiCecVolumeControl)11552 public void onHdmiCecVolumeControlFeature( 11553 @HdmiControlManager.VolumeControl int hdmiCecVolumeControl) { 11554 synchronized (mHdmiClientLock) { 11555 if (mHdmiManager == null) return; 11556 mHdmiCecVolumeControlEnabled = 11557 hdmiCecVolumeControl == HdmiControlManager.VOLUME_CONTROL_ENABLED; 11558 } 11559 } 11560 }; 11561 11562 private final Object mHdmiClientLock = new Object(); 11563 11564 // If HDMI-CEC system audio is supported 11565 // Note that for CEC volume commands mHdmiCecVolumeControlEnabled will play a role on volume 11566 // commands 11567 private boolean mHdmiSystemAudioSupported = false; 11568 // Set only when device is tv. 11569 @GuardedBy("mHdmiClientLock") 11570 private HdmiTvClient mHdmiTvClient; 11571 // true if the device has system feature PackageManager.FEATURE_LEANBACK. 11572 // cached HdmiControlManager interface 11573 @GuardedBy("mHdmiClientLock") 11574 private HdmiControlManager mHdmiManager; 11575 // Set only when device is a set-top box. 11576 @GuardedBy("mHdmiClientLock") 11577 private HdmiPlaybackClient mHdmiPlaybackClient; 11578 // Set only when device is an audio system. 11579 @GuardedBy("mHdmiClientLock") 11580 private HdmiAudioSystemClient mHdmiAudioSystemClient; 11581 // True when volume control over HDMI CEC is used when CEC is enabled (meaningless otherwise) 11582 @GuardedBy("mHdmiClientLock") 11583 private boolean mHdmiCecVolumeControlEnabled; 11584 11585 private MyHdmiControlStatusChangeListenerCallback mHdmiControlStatusChangeListenerCallback = 11586 new MyHdmiControlStatusChangeListenerCallback(); 11587 11588 private MyHdmiCecVolumeControlFeatureListener mMyHdmiCecVolumeControlFeatureListener = 11589 new MyHdmiCecVolumeControlFeatureListener(); 11590 11591 @Override setHdmiSystemAudioSupported(boolean on)11592 public int setHdmiSystemAudioSupported(boolean on) { 11593 int device = AudioSystem.DEVICE_NONE; 11594 synchronized (mHdmiClientLock) { 11595 if (mHdmiManager != null) { 11596 if (mHdmiTvClient == null && mHdmiAudioSystemClient == null) { 11597 Log.w(TAG, "Only Hdmi-Cec enabled TV or audio system device supports" 11598 + "system audio mode."); 11599 return device; 11600 } 11601 if (mHdmiSystemAudioSupported != on) { 11602 mHdmiSystemAudioSupported = on; 11603 final int config = on ? AudioSystem.FORCE_HDMI_SYSTEM_AUDIO_ENFORCED : 11604 AudioSystem.FORCE_NONE; 11605 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_HDMI_SYSTEM_AUDIO, config, 11606 "setHdmiSystemAudioSupported"); 11607 } 11608 // TODO(b/185386781): Update AudioManager API to use device list. 11609 // So far, this value appears to be advisory for debug log. 11610 device = getDeviceMaskForStream(AudioSystem.STREAM_MUSIC); 11611 } 11612 } 11613 return device; 11614 } 11615 11616 @Override isHdmiSystemAudioSupported()11617 public boolean isHdmiSystemAudioSupported() { 11618 return mHdmiSystemAudioSupported; 11619 } 11620 11621 //========================================================================================== 11622 // Accessibility 11623 initA11yMonitoring()11624 private void initA11yMonitoring() { 11625 final AccessibilityManager accessibilityManager = 11626 (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); 11627 updateDefaultStreamOverrideDelay(accessibilityManager.isTouchExplorationEnabled()); 11628 updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive()); 11629 accessibilityManager.addTouchExplorationStateChangeListener(this, null); 11630 accessibilityManager.addAccessibilityServicesStateChangeListener(this); 11631 } 11632 11633 //--------------------------------------------------------------------------------- 11634 // A11y: taking touch exploration into account for selecting the default 11635 // stream override timeout when adjusting volume 11636 //--------------------------------------------------------------------------------- 11637 11638 // - STREAM_NOTIFICATION on tablets during this period after a notification stopped 11639 // - STREAM_RING on phones during this period after a notification stopped 11640 // - STREAM_MUSIC otherwise 11641 11642 private static final int DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS = 0; 11643 private static final int TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS = 1000; 11644 11645 private static int sStreamOverrideDelayMs; 11646 11647 @Override onTouchExplorationStateChanged(boolean enabled)11648 public void onTouchExplorationStateChanged(boolean enabled) { 11649 updateDefaultStreamOverrideDelay(enabled); 11650 } 11651 updateDefaultStreamOverrideDelay(boolean touchExploreEnabled)11652 private void updateDefaultStreamOverrideDelay(boolean touchExploreEnabled) { 11653 if (touchExploreEnabled) { 11654 sStreamOverrideDelayMs = TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS; 11655 } else { 11656 sStreamOverrideDelayMs = DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS; 11657 } 11658 if (DEBUG_VOL) Log.d(TAG, "Touch exploration enabled=" + touchExploreEnabled 11659 + " stream override delay is now " + sStreamOverrideDelayMs + " ms"); 11660 } 11661 11662 //--------------------------------------------------------------------------------- 11663 // A11y: taking a11y state into account for the handling of a11y prompts volume 11664 //--------------------------------------------------------------------------------- 11665 11666 private static boolean sIndependentA11yVolume = false; 11667 11668 // implementation of AccessibilityServicesStateChangeListener 11669 @Override onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager)11670 public void onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager) { 11671 updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive()); 11672 } 11673 updateA11yVolumeAlias(boolean a11VolEnabled)11674 private void updateA11yVolumeAlias(boolean a11VolEnabled) { 11675 if (DEBUG_VOL) Log.d(TAG, "Accessibility volume enabled = " + a11VolEnabled); 11676 if (mIsSingleVolume) { 11677 if (DEBUG_VOL) Log.d(TAG, "Accessibility volume is not set on single volume device"); 11678 return; 11679 } 11680 if (sIndependentA11yVolume != a11VolEnabled) { 11681 sIndependentA11yVolume = a11VolEnabled; 11682 // update the volume mapping scheme 11683 updateStreamVolumeAlias(true /*updateVolumes*/, TAG); 11684 // update the volume controller behavior 11685 mVolumeController.setA11yMode(sIndependentA11yVolume ? 11686 VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME : 11687 VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME); 11688 mVolumeController.postVolumeChanged(AudioManager.STREAM_ACCESSIBILITY, 0); 11689 } 11690 } 11691 11692 //========================================================================================== 11693 // Camera shutter sound policy. 11694 // config_camera_sound_forced configuration option in config.xml defines if the camera shutter 11695 // sound is forced (sound even if the device is in silent mode) or not. This option is false by 11696 // default and can be overridden by country specific overlay in values-mccXXX/config.xml. 11697 //========================================================================================== 11698 11699 // cached value of com.android.internal.R.bool.config_camera_sound_forced 11700 @GuardedBy("mSettingsLock") 11701 private boolean mCameraSoundForced; 11702 11703 // called by android.hardware.Camera to populate CameraInfo.canDisableShutterSound isCameraSoundForced()11704 public boolean isCameraSoundForced() { 11705 synchronized (mSettingsLock) { 11706 return mCameraSoundForced; 11707 } 11708 } 11709 11710 //========================================================================================== 11711 // AudioService logging and dumpsys 11712 //========================================================================================== 11713 static final int LOG_NB_EVENTS_LIFECYCLE = 20; 11714 static final int LOG_NB_EVENTS_PHONE_STATE = 20; 11715 static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 50; 11716 static final int LOG_NB_EVENTS_FORCE_USE = 20; 11717 static final int LOG_NB_EVENTS_VOLUME = 100; 11718 static final int LOG_NB_EVENTS_DYN_POLICY = 10; 11719 static final int LOG_NB_EVENTS_SPATIAL = 30; 11720 static final int LOG_NB_EVENTS_SOUND_DOSE = 30; 11721 11722 static final int LOG_NB_EVENTS_LOUDNESS_CODEC = 30; 11723 11724 static final EventLogger 11725 sLifecycleLogger = new EventLogger(LOG_NB_EVENTS_LIFECYCLE, 11726 "audio services lifecycle"); 11727 11728 static final EventLogger sMuteLogger = new EventLogger(30, 11729 "mute commands"); 11730 11731 final private EventLogger 11732 mModeLogger = new EventLogger(LOG_NB_EVENTS_PHONE_STATE, 11733 "phone state (logged after successful call to AudioSystem.setPhoneState(int, int))"); 11734 11735 // logs for wired + A2DP device connections: 11736 // - wired: logged before onSetWiredDeviceConnectionState() is executed 11737 // - A2DP: logged at reception of method call 11738 /*package*/ static final EventLogger 11739 sDeviceLogger = new EventLogger( 11740 LOG_NB_EVENTS_DEVICE_CONNECTION, "wired/A2DP/hearing aid device connection"); 11741 11742 static final EventLogger 11743 sForceUseLogger = new EventLogger( 11744 LOG_NB_EVENTS_FORCE_USE, 11745 "force use (logged before setForceUse() is executed)"); 11746 11747 static final EventLogger 11748 sVolumeLogger = new EventLogger(LOG_NB_EVENTS_VOLUME, 11749 "volume changes (logged when command received by AudioService)"); 11750 11751 static final EventLogger 11752 sSpatialLogger = new EventLogger(LOG_NB_EVENTS_SPATIAL, 11753 "spatial audio"); 11754 11755 final private EventLogger 11756 mDynPolicyLogger = new EventLogger(LOG_NB_EVENTS_DYN_POLICY, 11757 "dynamic policy events (logged when command received by AudioService)"); 11758 11759 private static final String[] RINGER_MODE_NAMES = new String[] { 11760 "SILENT", 11761 "VIBRATE", 11762 "NORMAL" 11763 }; 11764 dumpRingerMode(PrintWriter pw)11765 private void dumpRingerMode(PrintWriter pw) { 11766 pw.println("\nRinger mode: "); 11767 pw.println("- mode (internal) = " + RINGER_MODE_NAMES[mRingerMode]); 11768 pw.println("- mode (external) = " + RINGER_MODE_NAMES[mRingerModeExternal]); 11769 pw.println("- zen mode:" + Settings.Global.zenModeToString(mNm.getZenMode())); 11770 dumpRingerModeStreams(pw, "affected", mRingerModeAffectedStreams); 11771 dumpRingerModeStreams(pw, "muted", sRingerAndZenModeMutedStreams); 11772 pw.print("- delegate = "); pw.println(mRingerModeDelegate); 11773 } 11774 dumpRingerModeStreams(PrintWriter pw, String type, int streams)11775 private void dumpRingerModeStreams(PrintWriter pw, String type, int streams) { 11776 pw.print("- ringer mode "); pw.print(type); pw.print(" streams = 0x"); 11777 pw.print(Integer.toHexString(streams)); 11778 if (streams != 0) { 11779 pw.print(" ("); 11780 boolean first = true; 11781 for (int i = 0; i < AudioSystem.STREAM_NAMES.length; i++) { 11782 final int stream = (1 << i); 11783 if ((streams & stream) != 0) { 11784 if (!first) pw.print(','); 11785 pw.print(AudioSystem.STREAM_NAMES[i]); 11786 streams &= ~stream; 11787 first = false; 11788 } 11789 } 11790 if (streams != 0) { 11791 if (!first) pw.print(','); 11792 pw.print(streams); 11793 } 11794 pw.print(')'); 11795 } 11796 pw.println(); 11797 } 11798 getAbsoluteVolumeDevicesWithBehavior(int behavior)11799 private Set<Integer> getAbsoluteVolumeDevicesWithBehavior(int behavior) { 11800 return mAbsoluteVolumeDeviceInfoMap.entrySet().stream() 11801 .filter(entry -> entry.getValue().mDeviceVolumeBehavior == behavior) 11802 .map(Map.Entry::getKey) 11803 .collect(Collectors.toSet()); 11804 } 11805 dumpDeviceTypes(@onNull Set<Integer> deviceTypes)11806 private String dumpDeviceTypes(@NonNull Set<Integer> deviceTypes) { 11807 Iterator<Integer> it = deviceTypes.iterator(); 11808 if (!it.hasNext()) { 11809 return ""; 11810 } 11811 final StringBuilder sb = new StringBuilder(); 11812 sb.append("0x" + Integer.toHexString(it.next())); 11813 while (it.hasNext()) { 11814 sb.append("," + "0x" + Integer.toHexString(it.next())); 11815 } 11816 return sb.toString(); 11817 } 11818 11819 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)11820 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11821 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 11822 11823 sLifecycleLogger.dump(pw); 11824 if (mAudioHandler != null) { 11825 pw.println("\nMessage handler (watch for unhandled messages):"); 11826 mAudioHandler.dump(new PrintWriterPrinter(pw), " "); 11827 } else { 11828 pw.println("\nMessage handler is null"); 11829 } 11830 dumpFlags(pw); 11831 mHardeningEnforcer.dump(pw); 11832 mMediaFocusControl.dump(pw); 11833 dumpStreamStates(pw); 11834 dumpVolumeGroups(pw); 11835 dumpRingerMode(pw); 11836 dumpAudioMode(pw); 11837 pw.println("\nAudio routes:"); 11838 pw.print(" mMainType=0x"); pw.println(Integer.toHexString( 11839 mDeviceBroker.getCurAudioRoutes().mainType)); 11840 pw.print(" mBluetoothName="); pw.println(mDeviceBroker.getCurAudioRoutes().bluetoothName); 11841 11842 pw.println("\nOther state:"); 11843 pw.print(" mUseVolumeGroupAliases="); pw.println(mUseVolumeGroupAliases); 11844 pw.print(" mVolumeController="); pw.println(mVolumeController); 11845 mSoundDoseHelper.dump(pw); 11846 pw.print(" sIndependentA11yVolume="); pw.println(sIndependentA11yVolume); 11847 pw.print(" mCameraSoundForced="); pw.println(isCameraSoundForced()); 11848 pw.print(" mHasVibrator="); pw.println(mHasVibrator); 11849 pw.print(" mVolumePolicy="); pw.println(mVolumePolicy); 11850 pw.print(" mAvrcpAbsVolSupported="); pw.println(mAvrcpAbsVolSupported); 11851 pw.print(" mBtScoOnByApp="); pw.println(mBtScoOnByApp); 11852 pw.print(" mIsSingleVolume="); pw.println(mIsSingleVolume); 11853 pw.print(" mUseFixedVolume="); pw.println(mUseFixedVolume); 11854 pw.print(" mNotifAliasRing="); pw.println(mNotifAliasRing); 11855 pw.print(" mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices)); 11856 pw.print(" mFullVolumeDevices="); pw.println(dumpDeviceTypes(mFullVolumeDevices)); 11857 pw.print(" absolute volume devices="); pw.println(dumpDeviceTypes( 11858 getAbsoluteVolumeDevicesWithBehavior( 11859 AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE))); 11860 pw.print(" adjust-only absolute volume devices="); pw.println(dumpDeviceTypes( 11861 getAbsoluteVolumeDevicesWithBehavior( 11862 AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY))); 11863 pw.print(" pre-scale for bluetooth absolute volume "); 11864 if (disablePrescaleAbsoluteVolume()) { 11865 pw.println("= disabled"); 11866 } else { 11867 pw.println("=" + mPrescaleAbsoluteVolume[0] 11868 + ", " + mPrescaleAbsoluteVolume[1] 11869 + ", " + mPrescaleAbsoluteVolume[2]); 11870 } 11871 pw.print(" mExtVolumeController="); pw.println(mExtVolumeController); 11872 pw.print(" mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient); 11873 pw.print(" mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient); 11874 pw.print(" mHdmiTvClient="); pw.println(mHdmiTvClient); 11875 pw.print(" mHdmiSystemAudioSupported="); pw.println(mHdmiSystemAudioSupported); 11876 synchronized (mHdmiClientLock) { 11877 pw.print(" mHdmiCecVolumeControlEnabled="); pw.println(mHdmiCecVolumeControlEnabled); 11878 } 11879 pw.print(" mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported); 11880 pw.println(" mic mute FromSwitch=" + mMicMuteFromSwitch 11881 + " FromRestrictions=" + mMicMuteFromRestrictions 11882 + " FromApi=" + mMicMuteFromApi 11883 + " from system=" + mMicMuteFromSystemCached); 11884 pw.print(" mMasterMute="); pw.println(mMasterMute.get()); 11885 dumpAccessibilityServiceUids(pw); 11886 dumpAssistantServicesUids(pw); 11887 11888 pw.print(" supportsBluetoothVariableLatency="); 11889 pw.println(AudioSystem.supportsBluetoothVariableLatency()); 11890 pw.print(" isBluetoothVariableLatencyEnabled="); 11891 pw.println(AudioSystem.isBluetoothVariableLatencyEnabled()); 11892 11893 dumpAudioPolicies(pw); 11894 mDynPolicyLogger.dump(pw); 11895 mPlaybackMonitor.dump(pw); 11896 mRecordMonitor.dump(pw); 11897 11898 pw.println("\nAudioDeviceBroker:"); 11899 mDeviceBroker.dump(pw, " "); 11900 pw.println("\nSoundEffects:"); 11901 mSfxHelper.dump(pw, " "); 11902 11903 pw.println("\n"); 11904 pw.println("\nEvent logs:"); 11905 mModeLogger.dump(pw); 11906 pw.println("\n"); 11907 sDeviceLogger.dump(pw); 11908 pw.println("\n"); 11909 sForceUseLogger.dump(pw); 11910 pw.println("\n"); 11911 sVolumeLogger.dump(pw); 11912 pw.println("\n"); 11913 sMuteLogger.dump(pw); 11914 pw.println("\n"); 11915 dumpSupportedSystemUsage(pw); 11916 11917 pw.println("\n"); 11918 pw.println("\nSpatial audio:"); 11919 pw.println("mHasSpatializerEffect:" + mHasSpatializerEffect + " (effect present)"); 11920 pw.println("isSpatializerEnabled:" + isSpatializerEnabled() + " (routing dependent)"); 11921 mSpatializerHelper.dump(pw); 11922 sSpatialLogger.dump(pw); 11923 11924 pw.println("\n"); 11925 pw.println("\nLoudness alignment:"); 11926 mLoudnessCodecHelper.dump(pw); 11927 11928 mAudioSystem.dump(pw); 11929 } 11930 dumpSupportedSystemUsage(PrintWriter pw)11931 private void dumpSupportedSystemUsage(PrintWriter pw) { 11932 pw.println("Supported System Usages:"); 11933 synchronized (mSupportedSystemUsagesLock) { 11934 for (int i = 0; i < mSupportedSystemUsages.length; i++) { 11935 pw.printf("\t%s\n", AudioAttributes.usageToString(mSupportedSystemUsages[i])); 11936 } 11937 } 11938 } 11939 dumpAssistantServicesUids(PrintWriter pw)11940 private void dumpAssistantServicesUids(PrintWriter pw) { 11941 synchronized (mSettingsLock) { 11942 if (mAssistantUids.size() > 0) { 11943 pw.println(" Assistant service UIDs:"); 11944 for (int uid : mAssistantUids) { 11945 pw.println(" - " + uid); 11946 } 11947 } else { 11948 pw.println(" No Assistant service Uids."); 11949 } 11950 } 11951 } 11952 dumpAccessibilityServiceUids(PrintWriter pw)11953 private void dumpAccessibilityServiceUids(PrintWriter pw) { 11954 synchronized (mSupportedSystemUsagesLock) { 11955 if (mAccessibilityServiceUids != null && mAccessibilityServiceUids.length > 0) { 11956 pw.println(" Accessibility service Uids:"); 11957 for (int uid : mAccessibilityServiceUids) { 11958 pw.println(" - " + uid); 11959 } 11960 } else { 11961 pw.println(" No accessibility service Uids."); 11962 } 11963 } 11964 } 11965 11966 /** 11967 * Audio Analytics ids. 11968 */ 11969 private static final String mMetricsId = MediaMetrics.Name.AUDIO_SERVICE 11970 + MediaMetrics.SEPARATOR; 11971 initializeAudioServerPermissionProvider( Context context, AudioPolicyFacade audioPolicy, Executor audioserverExecutor)11972 private static AudioServerPermissionProvider initializeAudioServerPermissionProvider( 11973 Context context, AudioPolicyFacade audioPolicy, Executor audioserverExecutor) { 11974 Collection<PackageState> packageStates = null; 11975 try (PackageManagerLocal.UnfilteredSnapshot snapshot = 11976 LocalManagerRegistry.getManager(PackageManagerLocal.class) 11977 .withUnfilteredSnapshot()) { 11978 packageStates = snapshot.getPackageStates().values(); 11979 } 11980 var umi = LocalServices.getService(UserManagerInternal.class); 11981 var pmsi = LocalServices.getService(PermissionManagerServiceInternal.class); 11982 var provider = new AudioServerPermissionProvider(packageStates, 11983 (Integer uid, String perm) -> (pmsi.checkUidPermission(uid, perm, 11984 Context.DEVICE_ID_DEFAULT) == PackageManager.PERMISSION_GRANTED), 11985 () -> umi.getUserIds() 11986 ); 11987 audioPolicy.registerOnStartTask(() -> { 11988 provider.onServiceStart(audioPolicy.getPermissionController()); 11989 }); 11990 11991 // Set up event listeners 11992 // Must be kept in sync with PermissionManager 11993 Runnable cacheSysPropHandler = new Runnable() { 11994 private AtomicReference<SystemProperties.Handle> mHandle = new AtomicReference(); 11995 private AtomicLong mNonce = new AtomicLong(); 11996 @Override 11997 public void run() { 11998 if (mHandle.get() == null) { 11999 // Cache the handle 12000 mHandle.compareAndSet(null, SystemProperties.find( 12001 PermissionManager.CACHE_KEY_PACKAGE_INFO)); 12002 } 12003 long nonce; 12004 SystemProperties.Handle ref; 12005 if ((ref = mHandle.get()) != null && (nonce = ref.getLong(0)) != 0 && 12006 mNonce.getAndSet(nonce) != nonce) { 12007 audioserverExecutor.execute(() -> provider.onPermissionStateChanged()); 12008 } 12009 } 12010 }; 12011 12012 SystemProperties.addChangeCallback(cacheSysPropHandler); 12013 12014 IntentFilter packageUpdateFilter = new IntentFilter(); 12015 packageUpdateFilter.addAction(ACTION_PACKAGE_ADDED); 12016 packageUpdateFilter.addAction(ACTION_PACKAGE_REMOVED); 12017 packageUpdateFilter.addDataScheme("package"); 12018 12019 context.registerReceiverForAllUsers(new BroadcastReceiver() { 12020 @Override 12021 public void onReceive(Context context, Intent intent) { 12022 String action = intent.getAction(); 12023 String pkgName = intent.getData().getEncodedSchemeSpecificPart(); 12024 int uid = intent.getIntExtra(Intent.EXTRA_UID, Process.INVALID_UID); 12025 if (intent.getBooleanExtra(EXTRA_REPLACING, false) || 12026 intent.getBooleanExtra(EXTRA_ARCHIVAL, false)) return; 12027 if (action.equals(ACTION_PACKAGE_ADDED)) { 12028 audioserverExecutor.execute(() -> 12029 provider.onModifyPackageState(uid, pkgName, false /* isRemoved */)); 12030 } else if (action.equals(ACTION_PACKAGE_REMOVED)) { 12031 audioserverExecutor.execute(() -> 12032 provider.onModifyPackageState(uid, pkgName, true /* isRemoved */)); 12033 } 12034 } 12035 }, packageUpdateFilter, null, null); // main thread is fine, since dispatch on executor 12036 return provider; 12037 } 12038 12039 // Inform AudioFlinger of our device's low RAM attribute readAndSetLowRamDevice()12040 private static void readAndSetLowRamDevice() 12041 { 12042 boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic(); 12043 long totalMemory = 1024 * 1024 * 1024; // 1GB is the default if ActivityManager fails. 12044 12045 try { 12046 final ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo(); 12047 ActivityManager.getService().getMemoryInfo(info); 12048 totalMemory = info.totalMem; 12049 } catch (RemoteException e) { 12050 Log.w(TAG, "Cannot obtain MemoryInfo from ActivityManager, assume low memory device"); 12051 isLowRamDevice = true; 12052 } 12053 12054 final int status = AudioSystem.setLowRamDevice(isLowRamDevice, totalMemory); 12055 if (status != 0) { 12056 Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status); 12057 } 12058 } 12059 enforceVolumeController(String action)12060 private void enforceVolumeController(String action) { 12061 mContext.enforceCallingOrSelfPermission(Manifest.permission.STATUS_BAR_SERVICE, 12062 "Only SystemUI can " + action); 12063 } 12064 12065 @Override setVolumeController(final IVolumeController controller)12066 public void setVolumeController(final IVolumeController controller) { 12067 enforceVolumeController("set the volume controller"); 12068 12069 // return early if things are not actually changing 12070 if (mVolumeController.isSameBinder(controller)) { 12071 return; 12072 } 12073 12074 // dismiss the old volume controller 12075 mVolumeController.postDismiss(); 12076 if (controller != null) { 12077 // we are about to register a new controller, listen for its death 12078 try { 12079 controller.asBinder().linkToDeath(new DeathRecipient() { 12080 @Override 12081 public void binderDied() { 12082 if (mVolumeController.isSameBinder(controller)) { 12083 Log.w(TAG, "Current remote volume controller died, unregistering"); 12084 setVolumeController(null); 12085 } 12086 } 12087 }, 0); 12088 } catch (RemoteException e) { 12089 // noop 12090 } 12091 } 12092 mVolumeController.setController(controller); 12093 if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController); 12094 } 12095 12096 @Override 12097 @Nullable getVolumeController()12098 public IVolumeController getVolumeController() { 12099 enforceVolumeController("get the volume controller"); 12100 if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController); 12101 12102 return mVolumeController.getController(); 12103 } 12104 12105 @Override notifyVolumeControllerVisible(final IVolumeController controller, boolean visible)12106 public void notifyVolumeControllerVisible(final IVolumeController controller, boolean visible) { 12107 enforceVolumeController("notify about volume controller visibility"); 12108 12109 // return early if the controller is not current 12110 if (!mVolumeController.isSameBinder(controller)) { 12111 return; 12112 } 12113 12114 mVolumeController.setVisible(visible); 12115 if (DEBUG_VOL) Log.d(TAG, "Volume controller visible: " + visible); 12116 } 12117 12118 @Override setVolumePolicy(VolumePolicy policy)12119 public void setVolumePolicy(VolumePolicy policy) { 12120 enforceVolumeController("set volume policy"); 12121 if (policy != null && !policy.equals(mVolumePolicy)) { 12122 mVolumePolicy = policy; 12123 if (DEBUG_VOL) Log.d(TAG, "Volume policy changed: " + mVolumePolicy); 12124 } 12125 } 12126 12127 /** Interface used for enforcing the safe hearing standard. */ 12128 public interface ISafeHearingVolumeController { 12129 /** Displays an instructional safeguard as required by the safe hearing standard. */ postDisplaySafeVolumeWarning(int flags)12130 void postDisplaySafeVolumeWarning(int flags); 12131 12132 /** Displays a warning about transient exposure to high level playback */ postDisplayCsdWarning(@udioManager.CsdWarning int csdEvent, int displayDurationMs)12133 void postDisplayCsdWarning(@AudioManager.CsdWarning int csdEvent, int displayDurationMs); 12134 } 12135 12136 /** Wrapper which encapsulates the {@link IVolumeController} functionality. */ 12137 public class VolumeController implements ISafeHearingVolumeController { 12138 private static final String TAG = "VolumeController"; 12139 12140 private IVolumeController mController; 12141 private boolean mVisible; 12142 private long mNextLongPress; 12143 private int mLongPressTimeout; 12144 setController(IVolumeController controller)12145 public void setController(IVolumeController controller) { 12146 mController = controller; 12147 mVisible = false; 12148 } 12149 getController()12150 public IVolumeController getController() { 12151 return mController; 12152 } 12153 loadSettings(ContentResolver cr)12154 public void loadSettings(ContentResolver cr) { 12155 mLongPressTimeout = mSettings.getSecureIntForUser(cr, 12156 Settings.Secure.LONG_PRESS_TIMEOUT, 500, UserHandle.USER_CURRENT); 12157 } 12158 suppressAdjustment(int resolvedStream, int flags, boolean isMute)12159 public boolean suppressAdjustment(int resolvedStream, int flags, boolean isMute) { 12160 if (isMute) { 12161 return false; 12162 } 12163 boolean suppress = false; 12164 // Intended behavior: 12165 // 1/ if the stream is not the default UI stream, do not suppress (as it is not involved 12166 // in bringing up the UI) 12167 // 2/ if the resolved and default stream is MUSIC, and media is playing, do not suppress 12168 // 3/ otherwise suppress the first adjustments that occur during the "long press 12169 // timeout" interval. Note this is true regardless of whether this is a "real long 12170 // press" (where the user keeps pressing on the volume button), or repeated single 12171 // presses (here we don't know if we are in a real long press, or repeated fast 12172 // button presses). 12173 // Once the long press timeout occurs (mNextLongPress reset to 0), do not suppress. 12174 // Example: for a default and resolved stream of MUSIC, this allows modifying rapidly 12175 // the volume when media is playing (whether by long press or repeated individual 12176 // presses), or to bring up the volume UI when media is not playing, in order to make 12177 // another change (e.g. switch ringer modes) without changing media volume. 12178 if (resolvedStream == DEFAULT_VOL_STREAM_NO_PLAYBACK && mController != null) { 12179 // never suppress media vol adjustement during media playback 12180 if (resolvedStream == AudioSystem.STREAM_MUSIC 12181 && mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, mLongPressTimeout)) 12182 { 12183 // media is playing, adjust the volume right away 12184 return false; 12185 } 12186 12187 final long now = SystemClock.uptimeMillis(); 12188 if ((flags & AudioManager.FLAG_SHOW_UI) != 0 && !mVisible) { 12189 // UI is not visible yet, adjustment is ignored 12190 if (mNextLongPress < now) { 12191 mNextLongPress = now + mLongPressTimeout; 12192 } 12193 suppress = true; 12194 } else if (mNextLongPress > 0) { // in a long-press 12195 if (now > mNextLongPress) { 12196 // long press triggered, no more suppression 12197 mNextLongPress = 0; 12198 } else { 12199 // keep suppressing until the long press triggers 12200 suppress = true; 12201 } 12202 } 12203 } 12204 return suppress; 12205 } 12206 setVisible(boolean visible)12207 public void setVisible(boolean visible) { 12208 mVisible = visible; 12209 } 12210 isSameBinder(IVolumeController controller)12211 public boolean isSameBinder(IVolumeController controller) { 12212 return Objects.equals(asBinder(), binder(controller)); 12213 } 12214 asBinder()12215 public IBinder asBinder() { 12216 return binder(mController); 12217 } 12218 binder(IVolumeController controller)12219 private IBinder binder(IVolumeController controller) { 12220 return controller == null ? null : controller.asBinder(); 12221 } 12222 12223 @Override toString()12224 public String toString() { 12225 return "VolumeController(" + asBinder() + ",mVisible=" + mVisible + ")"; 12226 } 12227 12228 @Override postDisplaySafeVolumeWarning(int flags)12229 public void postDisplaySafeVolumeWarning(int flags) { 12230 if (mController == null) 12231 return; 12232 flags = flags | AudioManager.FLAG_SHOW_UI; 12233 try { 12234 mController.displaySafeVolumeWarning(flags); 12235 } catch (RemoteException e) { 12236 Log.w(TAG, "Error calling displaySafeVolumeWarning", e); 12237 } 12238 } 12239 12240 @Override postDisplayCsdWarning( @udioManager.CsdWarning int csdWarning, int displayDurationMs)12241 public void postDisplayCsdWarning( 12242 @AudioManager.CsdWarning int csdWarning, int displayDurationMs) { 12243 if (mController == null) { 12244 Log.e(TAG, "Unable to display CSD warning, no controller"); 12245 return; 12246 } 12247 try { 12248 mController.displayCsdWarning(csdWarning, displayDurationMs); 12249 } catch (RemoteException e) { 12250 Log.w(TAG, "Error calling displayCsdWarning for warning " + csdWarning, e); 12251 } 12252 } 12253 postVolumeChanged(int streamType, int flags)12254 public void postVolumeChanged(int streamType, int flags) { 12255 if (mController == null) 12256 return; 12257 try { 12258 mController.volumeChanged(streamType, flags); 12259 } catch (RemoteException e) { 12260 Log.w(TAG, "Error calling volumeChanged", e); 12261 } 12262 } 12263 postMasterMuteChanged(int flags)12264 public void postMasterMuteChanged(int flags) { 12265 if (mController == null) 12266 return; 12267 try { 12268 mController.masterMuteChanged(flags); 12269 } catch (RemoteException e) { 12270 Log.w(TAG, "Error calling masterMuteChanged", e); 12271 } 12272 } 12273 setLayoutDirection(int layoutDirection)12274 public void setLayoutDirection(int layoutDirection) { 12275 if (mController == null) 12276 return; 12277 try { 12278 mController.setLayoutDirection(layoutDirection); 12279 } catch (RemoteException e) { 12280 Log.w(TAG, "Error calling setLayoutDirection", e); 12281 } 12282 } 12283 postDismiss()12284 public void postDismiss() { 12285 if (mController == null) 12286 return; 12287 try { 12288 mController.dismiss(); 12289 } catch (RemoteException e) { 12290 Log.w(TAG, "Error calling dismiss", e); 12291 } 12292 } 12293 setA11yMode(int a11yMode)12294 public void setA11yMode(int a11yMode) { 12295 if (mController == null) 12296 return; 12297 try { 12298 mController.setA11yMode(a11yMode); 12299 } catch (RemoteException e) { 12300 Log.w(TAG, "Error calling setA11Mode", e); 12301 } 12302 } 12303 } 12304 12305 /** 12306 * Interface for system components to get some extra functionality through 12307 * LocalServices. 12308 */ 12309 final class AudioServiceInternal extends AudioManagerInternal { 12310 @Override setRingerModeDelegate(RingerModeDelegate delegate)12311 public void setRingerModeDelegate(RingerModeDelegate delegate) { 12312 mRingerModeDelegate = delegate; 12313 if (mRingerModeDelegate != null) { 12314 synchronized (mSettingsLock) { 12315 updateRingerAndZenModeAffectedStreams(); 12316 } 12317 setRingerModeInternal(getRingerModeInternal(), TAG + ".setRingerModeDelegate"); 12318 } 12319 } 12320 12321 @Override getRingerModeInternal()12322 public int getRingerModeInternal() { 12323 return AudioService.this.getRingerModeInternal(); 12324 } 12325 12326 @Override setRingerModeInternal(int ringerMode, String caller)12327 public void setRingerModeInternal(int ringerMode, String caller) { 12328 AudioService.this.setRingerModeInternal(ringerMode, caller); 12329 } 12330 12331 @Override silenceRingerModeInternal(String caller)12332 public void silenceRingerModeInternal(String caller) { 12333 AudioService.this.silenceRingerModeInternal(caller); 12334 } 12335 12336 @Override updateRingerModeAffectedStreamsInternal()12337 public void updateRingerModeAffectedStreamsInternal() { 12338 synchronized (mSettingsLock) { 12339 if (updateRingerAndZenModeAffectedStreams()) { 12340 setRingerModeInt(getRingerModeInternal(), false); 12341 } 12342 } 12343 } 12344 12345 @Override addAssistantServiceUid(int uid)12346 public void addAssistantServiceUid(int uid) { 12347 sendMsg(mAudioHandler, MSG_ADD_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE, 12348 uid, 0, null, 0); 12349 } 12350 12351 @Override removeAssistantServiceUid(int uid)12352 public void removeAssistantServiceUid(int uid) { 12353 sendMsg(mAudioHandler, MSG_REMOVE_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE, 12354 uid, 0, null, 0); 12355 } 12356 12357 @Override setActiveAssistantServicesUids(IntArray activeUids)12358 public void setActiveAssistantServicesUids(IntArray activeUids) { 12359 synchronized (mSettingsLock) { 12360 if (activeUids.size() == 0) { 12361 mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS; 12362 } else { 12363 boolean changed = (mActiveAssistantServiceUids == null) 12364 || (mActiveAssistantServiceUids.length != activeUids.size()); 12365 if (!changed) { 12366 for (int i = 0; i < mActiveAssistantServiceUids.length; i++) { 12367 if (activeUids.get(i) != mActiveAssistantServiceUids[i]) { 12368 changed = true; 12369 break; 12370 } 12371 } 12372 } 12373 if (changed) { 12374 mActiveAssistantServiceUids = activeUids.toArray(); 12375 } 12376 } 12377 } 12378 sendMsg(mAudioHandler, MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID, SENDMSG_REPLACE, 12379 0, 0, null, 0); 12380 } 12381 12382 @Override setAccessibilityServiceUids(IntArray uids)12383 public void setAccessibilityServiceUids(IntArray uids) { 12384 // TODO(b/233287010): Fix voice interaction and a11y concurrency in audio policy service 12385 if (isPlatformAutomotive()) { 12386 return; 12387 } 12388 12389 synchronized (mAccessibilityServiceUidsLock) { 12390 if (uids.size() == 0) { 12391 mAccessibilityServiceUids = null; 12392 } else { 12393 boolean changed = (mAccessibilityServiceUids == null) 12394 || (mAccessibilityServiceUids.length != uids.size()); 12395 if (!changed) { 12396 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 12397 if (uids.get(i) != mAccessibilityServiceUids[i]) { 12398 changed = true; 12399 break; 12400 } 12401 } 12402 } 12403 if (changed) { 12404 mAccessibilityServiceUids = uids.toArray(); 12405 } 12406 } 12407 sendMsg(mAudioHandler, MSG_UPDATE_A11Y_SERVICE_UIDS, SENDMSG_REPLACE, 12408 0, 0, null, 0); 12409 } 12410 } 12411 12412 /** 12413 * {@inheritDoc} 12414 */ 12415 @Override setInputMethodServiceUid(int uid)12416 public void setInputMethodServiceUid(int uid) { 12417 synchronized (mInputMethodServiceUidLock) { 12418 if (mInputMethodServiceUid != uid) { 12419 mAudioSystem.setCurrentImeUid(uid); 12420 mInputMethodServiceUid = uid; 12421 } 12422 } 12423 } 12424 } 12425 onUpdateAccessibilityServiceUids()12426 private void onUpdateAccessibilityServiceUids() { 12427 int[] accessibilityServiceUids; 12428 synchronized (mAccessibilityServiceUidsLock) { 12429 accessibilityServiceUids = mAccessibilityServiceUids; 12430 } 12431 AudioSystem.setA11yServicesUids(accessibilityServiceUids); 12432 } 12433 12434 //========================================================================================== 12435 // Audio policy management 12436 //========================================================================================== registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection, AttributionSource attributionSource)12437 public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, 12438 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, 12439 boolean isVolumeController, IMediaProjection projection, 12440 AttributionSource attributionSource) { 12441 Objects.requireNonNull(attributionSource); 12442 AudioSystem.setDynamicPolicyCallback(mDynPolicyCallback); 12443 12444 if (!isPolicyRegisterAllowed(policyConfig, 12445 isFocusPolicy || isTestFocusPolicy || hasFocusListener, 12446 isVolumeController, 12447 projection)) { 12448 Slog.w(TAG, "Permission denied to register audio policy for pid " 12449 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid() 12450 + ", need system permission or a MediaProjection that can project audio"); 12451 return null; 12452 } 12453 12454 String regId = null; 12455 synchronized (mAudioPolicies) { 12456 if (mAudioPolicies.containsKey(pcb.asBinder())) { 12457 Slog.e(TAG, "Cannot re-register policy"); 12458 return null; 12459 } 12460 try { 12461 AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, pcb, hasFocusListener, 12462 isFocusPolicy, isTestFocusPolicy, isVolumeController, projection, 12463 attributionSource); 12464 pcb.asBinder().linkToDeath(app, 0/*flags*/); 12465 12466 // logging after registration so we have the registration id 12467 mDynPolicyLogger.enqueue((new EventLogger.StringEvent("registerAudioPolicy for " 12468 + pcb.asBinder() + " u/pid:" + Binder.getCallingUid() + "/" 12469 + Binder.getCallingPid() + " with config:" + app.toCompactLogString())) 12470 .printLog(TAG)); 12471 12472 regId = app.getRegistrationId(); 12473 mAudioPolicies.put(pcb.asBinder(), app); 12474 } catch (RemoteException e) { 12475 // audio policy owner has already died! 12476 Slog.w(TAG, "Audio policy registration failed, could not link to " + pcb + 12477 " binder death", e); 12478 return null; 12479 } catch (IllegalStateException e) { 12480 Slog.w(TAG, "Audio policy registration failed for binder " + pcb, e); 12481 return null; 12482 } 12483 } 12484 return regId; 12485 } 12486 12487 /** 12488 * Called by an AudioPolicyProxy when the client dies. 12489 * Checks if an active playback for media use case is currently routed to one of the 12490 * remote submix devices owned by this dynamic policy and broadcasts a becoming noisy 12491 * intend in this case. 12492 * @param addresses list of remote submix device addresses to check. 12493 */ onPolicyClientDeath(List<String> addresses)12494 private void onPolicyClientDeath(List<String> addresses) { 12495 for (String address : addresses) { 12496 if (mPlaybackMonitor.hasActiveMediaPlaybackOnSubmixWithAddress(address)) { 12497 mDeviceBroker.postBroadcastBecomingNoisy(); 12498 return; 12499 } 12500 } 12501 } 12502 /** 12503 * Apps with MODIFY_AUDIO_ROUTING can register any policy. 12504 * Apps with an audio capable MediaProjection are allowed to register a RENDER|LOOPBACK policy 12505 * as those policy do not modify the audio routing. 12506 */ isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, boolean hasFocusAccess, boolean isVolumeController, IMediaProjection projection)12507 private boolean isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, 12508 boolean hasFocusAccess, 12509 boolean isVolumeController, 12510 IMediaProjection projection) { 12511 12512 boolean requireValidProjection = false; 12513 boolean requireCaptureAudioOrMediaOutputPerm = false; 12514 boolean requireModifyRouting = false; 12515 boolean requireCallAudioInterception = false; 12516 ArrayList<AudioMix> voiceCommunicationCaptureMixes = null; 12517 12518 12519 if (hasFocusAccess || isVolumeController) { 12520 requireModifyRouting |= true; 12521 } else if (policyConfig.getMixes().isEmpty()) { 12522 // An empty policy could be used to lock the focus or add mixes later 12523 requireModifyRouting |= true; 12524 } 12525 for (AudioMix mix : policyConfig.getMixes()) { 12526 // If mix is requesting privileged capture 12527 if (mix.getRule().allowPrivilegedMediaPlaybackCapture()) { 12528 // then its format must be low quality enough 12529 String privilegedMediaCaptureError = 12530 mix.canBeUsedForPrivilegedMediaCapture(mix.getFormat()); 12531 if (privilegedMediaCaptureError != null) { 12532 Log.e(TAG, privilegedMediaCaptureError); 12533 return false; 12534 } 12535 // and it must have CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT permission 12536 requireCaptureAudioOrMediaOutputPerm |= true; 12537 12538 } 12539 // If mix is trying to explicitly capture USAGE_VOICE_COMMUNICATION 12540 if (mix.containsMatchAttributeRuleForUsage( 12541 AudioAttributes.USAGE_VOICE_COMMUNICATION) 12542 && (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER)) { 12543 // It must have CAPTURE_USAGE_VOICE_COMMUNICATION_OUTPUT permission 12544 // Note that for UID, USERID or EXCLDUE rules, the capture will be silenced 12545 // in AudioPolicyMix 12546 if (voiceCommunicationCaptureMixes == null) { 12547 voiceCommunicationCaptureMixes = new ArrayList<AudioMix>(); 12548 } 12549 voiceCommunicationCaptureMixes.add(mix); 12550 } 12551 12552 // If mix is RENDER|LOOPBACK, then an audio MediaProjection is enough 12553 // otherwise MODIFY_AUDIO_ROUTING permission is required 12554 if (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER && projection != null) { 12555 requireValidProjection |= true; 12556 } else if (mix.isForCallRedirection()) { 12557 requireCallAudioInterception |= true; 12558 } else if (mix.containsMatchAttributeRuleForUsage( 12559 AudioAttributes.USAGE_VOICE_COMMUNICATION)) { 12560 requireModifyRouting |= true; 12561 } 12562 } 12563 12564 if (requireCaptureAudioOrMediaOutputPerm 12565 && !callerHasPermission(CAPTURE_MEDIA_OUTPUT) 12566 && !callerHasPermission(CAPTURE_AUDIO_OUTPUT)) { 12567 Log.e(TAG, "Privileged audio capture requires CAPTURE_MEDIA_OUTPUT or " 12568 + "CAPTURE_AUDIO_OUTPUT system permission"); 12569 return false; 12570 } 12571 12572 if (voiceCommunicationCaptureMixes != null && voiceCommunicationCaptureMixes.size() > 0) { 12573 if (!callerHasPermission( 12574 Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT)) { 12575 Log.e(TAG, "Audio capture for voice communication requires " 12576 + "CAPTURE_VOICE_COMMUNICATION_OUTPUT system permission"); 12577 return false; 12578 } 12579 12580 // If permission check succeeded, we set the flag in each of the mixing rules 12581 for (AudioMix mix : voiceCommunicationCaptureMixes) { 12582 mix.getRule().setVoiceCommunicationCaptureAllowed(true); 12583 } 12584 } 12585 12586 if (requireValidProjection && !canProjectAudio(projection)) { 12587 return false; 12588 } 12589 12590 if (requireModifyRouting 12591 && !callerHasPermission(MODIFY_AUDIO_ROUTING)) { 12592 Log.e(TAG, "Can not capture audio without MODIFY_AUDIO_ROUTING"); 12593 return false; 12594 } 12595 12596 if (requireCallAudioInterception && !callerHasPermission(CALL_AUDIO_INTERCEPTION)) { 12597 Log.e(TAG, "Can not capture audio without CALL_AUDIO_INTERCEPTION"); 12598 return false; 12599 } 12600 12601 return true; 12602 } 12603 callerHasPermission(String permission)12604 private boolean callerHasPermission(String permission) { 12605 return mContext.checkCallingOrSelfPermission(permission) 12606 == PackageManager.PERMISSION_GRANTED; 12607 } 12608 12609 /** @return true if projection is a valid MediaProjection that can project audio. */ canProjectAudio(IMediaProjection projection)12610 private boolean canProjectAudio(IMediaProjection projection) { 12611 if (projection == null) { 12612 Log.e(TAG, "MediaProjection is null"); 12613 return false; 12614 } 12615 12616 IMediaProjectionManager projectionService = getProjectionService(); 12617 if (projectionService == null) { 12618 Log.e(TAG, "Can't get service IMediaProjectionManager"); 12619 return false; 12620 } 12621 12622 final long token = Binder.clearCallingIdentity(); 12623 try { 12624 if (!projectionService.isCurrentProjection(projection)) { 12625 Log.w(TAG, "App passed invalid MediaProjection token"); 12626 return false; 12627 } 12628 } catch (RemoteException e) { 12629 Log.e(TAG, "Can't call .isCurrentProjection() on IMediaProjectionManager" 12630 + projectionService.asBinder(), e); 12631 return false; 12632 } finally { 12633 Binder.restoreCallingIdentity(token); 12634 } 12635 12636 try { 12637 if (!projection.canProjectAudio()) { 12638 Log.w(TAG, "App passed MediaProjection that can not project audio"); 12639 return false; 12640 } 12641 } catch (RemoteException e) { 12642 Log.e(TAG, "Can't call .canProjectAudio() on valid IMediaProjection" 12643 + projection.asBinder(), e); 12644 return false; 12645 } 12646 12647 return true; 12648 } 12649 getProjectionService()12650 private IMediaProjectionManager getProjectionService() { 12651 if (mProjectionService == null) { 12652 IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE); 12653 mProjectionService = IMediaProjectionManager.Stub.asInterface(b); 12654 } 12655 return mProjectionService; 12656 } 12657 12658 /** 12659 * See {@link AudioManager#unregisterAudioPolicyAsync(AudioPolicy)} 12660 * Declared oneway 12661 * @param pcb nullable because on service interface 12662 */ unregisterAudioPolicyAsync(@ullable IAudioPolicyCallback pcb)12663 public void unregisterAudioPolicyAsync(@Nullable IAudioPolicyCallback pcb) { 12664 if (pcb == null) { 12665 return; 12666 } 12667 unregisterAudioPolicyInt(pcb, "unregisterAudioPolicyAsync"); 12668 } 12669 12670 /** 12671 * See {@link AudioManager#unregisterAudioPolicy(AudioPolicy)} 12672 * @param pcb nullable because on service interface 12673 */ unregisterAudioPolicy(@ullable IAudioPolicyCallback pcb)12674 public void unregisterAudioPolicy(@Nullable IAudioPolicyCallback pcb) { 12675 if (pcb == null) { 12676 return; 12677 } 12678 unregisterAudioPolicyInt(pcb, "unregisterAudioPolicy"); 12679 } 12680 12681 unregisterAudioPolicyInt(@onNull IAudioPolicyCallback pcb, String operationName)12682 private void unregisterAudioPolicyInt(@NonNull IAudioPolicyCallback pcb, String operationName) { 12683 mDynPolicyLogger.enqueue((new EventLogger.StringEvent(operationName + " for " 12684 + pcb.asBinder()).printLog(TAG))); 12685 synchronized (mAudioPolicies) { 12686 AudioPolicyProxy app = mAudioPolicies.remove(pcb.asBinder()); 12687 if (app == null) { 12688 Slog.w(TAG, "Trying to unregister unknown audio policy for pid " 12689 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()); 12690 return; 12691 } else { 12692 pcb.asBinder().unlinkToDeath(app, 0/*flags*/); 12693 } 12694 app.release(); 12695 } 12696 // TODO implement clearing mix attribute matching info in native audio policy 12697 } 12698 12699 /** 12700 * Checks whether caller has MODIFY_AUDIO_ROUTING permission, and the policy is registered. 12701 * @param errorMsg log warning if permission check failed. 12702 * @return null if the operation on the audio mixes should be cancelled. 12703 */ 12704 @GuardedBy("mAudioPolicies") checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg)12705 private AudioPolicyProxy checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg) { 12706 // permission check 12707 final boolean hasPermissionForPolicy = 12708 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 12709 MODIFY_AUDIO_ROUTING)); 12710 if (!hasPermissionForPolicy) { 12711 Slog.w(TAG, errorMsg + " for pid " + 12712 + Binder.getCallingPid() + " / uid " 12713 + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING"); 12714 return null; 12715 } 12716 // policy registered? 12717 final AudioPolicyProxy app = mAudioPolicies.get(pcb.asBinder()); 12718 if (app == null) { 12719 Slog.w(TAG, errorMsg + " for pid " + 12720 + Binder.getCallingPid() + " / uid " 12721 + Binder.getCallingUid() + ", unregistered policy"); 12722 return null; 12723 } 12724 return app; 12725 } 12726 12727 /** 12728 * Retrieves all audioMixes registered with the AudioPolicyManager 12729 * @return list of registered audio mixes 12730 */ getRegisteredPolicyMixes()12731 public List<AudioMix> getRegisteredPolicyMixes() { 12732 if (!android.media.audiopolicy.Flags.audioMixTestApi()) { 12733 return Collections.emptyList(); 12734 } 12735 12736 synchronized (mAudioPolicies) { 12737 return mAudioSystem.getRegisteredPolicyMixes(); 12738 } 12739 } 12740 addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)12741 public int addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) { 12742 if (DEBUG_AP) { Log.d(TAG, "addMixForPolicy for " + pcb.asBinder() 12743 + " with config:" + policyConfig); } 12744 synchronized (mAudioPolicies) { 12745 final AudioPolicyProxy app = 12746 checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy"); 12747 if (app == null){ 12748 return AudioManager.ERROR; 12749 } 12750 return app.addMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS 12751 ? AudioManager.SUCCESS : AudioManager.ERROR; 12752 } 12753 } 12754 removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)12755 public int removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) { 12756 if (DEBUG_AP) { Log.d(TAG, "removeMixForPolicy for " + pcb.asBinder() 12757 + " with config:" + policyConfig); } 12758 synchronized (mAudioPolicies) { 12759 final AudioPolicyProxy app = 12760 checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy"); 12761 if (app == null) { 12762 return AudioManager.ERROR; 12763 } 12764 if (android.media.audiopolicy.Flags.audioMixOwnership()) { 12765 for (AudioMix mix : policyConfig.getMixes()) { 12766 if (!app.getMixes().contains(mix)) { 12767 Slog.e(TAG, 12768 "removeMixForPolicy attempted to unregister AudioMix(es) not " 12769 + "belonging to the AudioPolicy"); 12770 return AudioManager.ERROR; 12771 } 12772 } 12773 } 12774 return app.removeMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS 12775 ? AudioManager.SUCCESS : AudioManager.ERROR; 12776 } 12777 } 12778 12779 /** 12780 * Update {@link AudioMixingRule}-s for already registered {@link AudioMix}-es. 12781 * 12782 * @param mixesToUpdate - array of already registered {@link AudioMix}-es to update. 12783 * @param updatedMixingRules - array of {@link AudioMixingRule}-s corresponding to 12784 * {@code mixesToUpdate} mixes. The array must be same size as 12785 * {@code mixesToUpdate} and i-th {@link AudioMixingRule} must 12786 * correspond to i-th {@link AudioMix} from mixesToUpdate array. 12787 * @param pcb - {@link IAudioPolicyCallback} corresponding to the registered 12788 * {@link AudioPolicy} all {@link AudioMix}-es for {@code mixesToUpdate} 12789 * are part of. 12790 * @return {@link AudioManager#SUCCESS} iff the mixing rules were updated successfully, 12791 * {@link AudioManager#ERROR} otherwise. 12792 */ 12793 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) updateMixingRulesForPolicy( @onNull AudioMix[] mixesToUpdate, @NonNull AudioMixingRule[] updatedMixingRules, @NonNull IAudioPolicyCallback pcb)12794 public int updateMixingRulesForPolicy( 12795 @NonNull AudioMix[] mixesToUpdate, 12796 @NonNull AudioMixingRule[] updatedMixingRules, 12797 @NonNull IAudioPolicyCallback pcb) { 12798 super.updateMixingRulesForPolicy_enforcePermission(); 12799 Objects.requireNonNull(mixesToUpdate); 12800 Objects.requireNonNull(updatedMixingRules); 12801 Objects.requireNonNull(pcb); 12802 if (mixesToUpdate.length != updatedMixingRules.length) { 12803 Log.e(TAG, "Provided list of audio mixes to update and corresponding mixing rules " 12804 + "have mismatching length (mixesToUpdate.length = " + mixesToUpdate.length 12805 + ", updatedMixingRules.length = " + updatedMixingRules.length + ")."); 12806 return AudioManager.ERROR; 12807 } 12808 if (DEBUG_AP) { 12809 Log.d(TAG, "updateMixingRules for " + pcb.asBinder() + "with mix rules: "); 12810 } 12811 synchronized (mAudioPolicies) { 12812 final AudioPolicyProxy app = 12813 checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy"); 12814 if (app == null) { 12815 return AudioManager.ERROR; 12816 } 12817 return app.updateMixingRules(mixesToUpdate, updatedMixingRules) == AudioSystem.SUCCESS 12818 ? AudioManager.SUCCESS : AudioManager.ERROR; 12819 } 12820 } 12821 12822 /** see AudioPolicy.setUidDeviceAffinity() */ setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)12823 public int setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, 12824 @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) { 12825 if (DEBUG_AP) { 12826 Log.d(TAG, "setUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid); 12827 } 12828 synchronized (mAudioPolicies) { 12829 final AudioPolicyProxy app = 12830 checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy"); 12831 if (app == null) { 12832 return AudioManager.ERROR; 12833 } 12834 if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) { 12835 return AudioManager.ERROR; 12836 } 12837 return app.setUidDeviceAffinities(uid, deviceTypes, deviceAddresses); 12838 } 12839 } 12840 12841 /** see AudioPolicy.setUserIdDeviceAffinity() */ setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)12842 public int setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, 12843 @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) { 12844 if (DEBUG_AP) { 12845 Log.d(TAG, "setUserIdDeviceAffinity for " + pcb.asBinder() + " user:" + userId); 12846 } 12847 12848 synchronized (mAudioPolicies) { 12849 final AudioPolicyProxy app = 12850 checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy"); 12851 if (app == null) { 12852 return AudioManager.ERROR; 12853 } 12854 if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) { 12855 return AudioManager.ERROR; 12856 } 12857 return app.setUserIdDeviceAffinities(userId, deviceTypes, deviceAddresses); 12858 } 12859 } 12860 12861 /** see AudioPolicy.removeUidDeviceAffinity() */ removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid)12862 public int removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid) { 12863 if (DEBUG_AP) { 12864 Log.d(TAG, "removeUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid); 12865 } 12866 synchronized (mAudioPolicies) { 12867 final AudioPolicyProxy app = 12868 checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy"); 12869 if (app == null) { 12870 return AudioManager.ERROR; 12871 } 12872 return app.removeUidDeviceAffinities(uid); 12873 } 12874 } 12875 12876 /** see AudioPolicy.removeUserIdDeviceAffinity() */ removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId)12877 public int removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId) { 12878 if (DEBUG_AP) { 12879 Log.d(TAG, "removeUserIdDeviceAffinity for " + pcb.asBinder() 12880 + " userId:" + userId); 12881 } 12882 synchronized (mAudioPolicies) { 12883 final AudioPolicyProxy app = 12884 checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy"); 12885 if (app == null) { 12886 return AudioManager.ERROR; 12887 } 12888 return app.removeUserIdDeviceAffinities(userId); 12889 } 12890 } 12891 setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb)12892 public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) { 12893 if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior 12894 + " policy " + pcb.asBinder()); 12895 synchronized (mAudioPolicies) { 12896 final AudioPolicyProxy app = 12897 checkUpdateForPolicy(pcb, "Cannot change audio policy focus properties"); 12898 if (app == null){ 12899 return AudioManager.ERROR; 12900 } 12901 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 12902 Slog.e(TAG, "Cannot change audio policy focus properties, unregistered policy"); 12903 return AudioManager.ERROR; 12904 } 12905 if (duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 12906 // is there already one policy managing ducking? 12907 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 12908 if (policy.mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 12909 Slog.e(TAG, "Cannot change audio policy ducking behavior, already handled"); 12910 return AudioManager.ERROR; 12911 } 12912 } 12913 } 12914 app.mFocusDuckBehavior = duckingBehavior; 12915 mMediaFocusControl.setDuckingInExtPolicyAvailable( 12916 duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY); 12917 } 12918 return AudioManager.SUCCESS; 12919 } 12920 12921 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 12922 /** @see AudioPolicy#getFocusStack() */ getFocusStack()12923 public List<AudioFocusInfo> getFocusStack() { 12924 super.getFocusStack_enforcePermission(); 12925 12926 return mMediaFocusControl.getFocusStack(); 12927 } 12928 12929 /** @see AudioPolicy#sendFocusLoss */ sendFocusLoss(@onNull AudioFocusInfo focusLoser, @NonNull IAudioPolicyCallback apcb)12930 public boolean sendFocusLoss(@NonNull AudioFocusInfo focusLoser, 12931 @NonNull IAudioPolicyCallback apcb) { 12932 Objects.requireNonNull(focusLoser); 12933 Objects.requireNonNull(apcb); 12934 enforceModifyAudioRoutingPermission(); 12935 if (!mAudioPolicies.containsKey(apcb.asBinder())) { 12936 throw new IllegalStateException("Only registered AudioPolicy can change focus"); 12937 } 12938 if (!mAudioPolicies.get(apcb.asBinder()).mHasFocusListener) { 12939 throw new IllegalStateException("AudioPolicy must have focus listener to change focus"); 12940 } 12941 return mMediaFocusControl.sendFocusLoss(focusLoser); 12942 } 12943 12944 /** 12945 * see {@link AudioPolicy#setFadeManagerConfigurationForFocusLoss(FadeManagerConfiguration)} 12946 */ 12947 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setFadeManagerConfigurationForFocusLoss( @onNull FadeManagerConfiguration fmcForFocusLoss)12948 public int setFadeManagerConfigurationForFocusLoss( 12949 @NonNull FadeManagerConfiguration fmcForFocusLoss) { 12950 super.setFadeManagerConfigurationForFocusLoss_enforcePermission(); 12951 ensureFadeManagerConfigIsEnabled(); 12952 Objects.requireNonNull(fmcForFocusLoss, 12953 "Fade manager config for focus loss cannot be null"); 12954 validateFadeManagerConfiguration(fmcForFocusLoss); 12955 12956 return mPlaybackMonitor.setFadeManagerConfiguration(AudioManager.AUDIOFOCUS_LOSS, 12957 fmcForFocusLoss); 12958 } 12959 12960 /** 12961 * see {@link AudioPolicy#clearFadeManagerConfigurationForFocusLoss()} 12962 */ 12963 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) clearFadeManagerConfigurationForFocusLoss()12964 public int clearFadeManagerConfigurationForFocusLoss() { 12965 super.clearFadeManagerConfigurationForFocusLoss_enforcePermission(); 12966 ensureFadeManagerConfigIsEnabled(); 12967 12968 return mPlaybackMonitor.clearFadeManagerConfiguration(AudioManager.AUDIOFOCUS_LOSS); 12969 } 12970 12971 /** 12972 * see {@link AudioPolicy#getFadeManagerConfigurationForFocusLoss()} 12973 */ 12974 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) getFadeManagerConfigurationForFocusLoss()12975 public FadeManagerConfiguration getFadeManagerConfigurationForFocusLoss() { 12976 super.getFadeManagerConfigurationForFocusLoss_enforcePermission(); 12977 ensureFadeManagerConfigIsEnabled(); 12978 12979 return mPlaybackMonitor.getFadeManagerConfiguration(AudioManager.AUDIOFOCUS_LOSS); 12980 } 12981 12982 /** 12983 * @see AudioManager#getHalVersion 12984 */ getHalVersion()12985 public @Nullable AudioHalVersionInfo getHalVersion() { 12986 for (AudioHalVersionInfo version : AudioHalVersionInfo.VERSIONS) { 12987 try { 12988 String versionStr = version.getMajorVersion() + "." + version.getMinorVersion(); 12989 final String aidlStr = "android.hardware.audio.core.IModule/default"; 12990 final String hidlStr = String.format("android.hardware.audio@%s::IDevicesFactory", 12991 versionStr); 12992 if (null != ServiceManager.checkService(aidlStr)) { 12993 return version; 12994 } else { 12995 HwBinder.getService(hidlStr, "default"); 12996 return version; 12997 } 12998 } catch (NoSuchElementException e) { 12999 // Ignore, the specified HAL interface is not found. 13000 } catch (RemoteException re) { 13001 Log.e(TAG, "Remote exception when getting hardware audio service:", re); 13002 } 13003 } 13004 return null; 13005 } 13006 13007 /** see AudioManager.hasRegisteredDynamicPolicy */ hasRegisteredDynamicPolicy()13008 public boolean hasRegisteredDynamicPolicy() { 13009 synchronized (mAudioPolicies) { 13010 return !mAudioPolicies.isEmpty(); 13011 } 13012 } 13013 13014 /** 13015 * @see AudioManager#setPreferredMixerAttributes( 13016 * AudioAttributes, AudioDeviceInfo, AudioMixerAttributes) 13017 */ setPreferredMixerAttributes(AudioAttributes attributes, int portId, AudioMixerAttributes mixerAttributes)13018 public int setPreferredMixerAttributes(AudioAttributes attributes, 13019 int portId, AudioMixerAttributes mixerAttributes) { 13020 Objects.requireNonNull(attributes); 13021 Objects.requireNonNull(mixerAttributes); 13022 if (!checkAudioSettingsPermission("setPreferredMixerAttributes()")) { 13023 return AudioSystem.PERMISSION_DENIED; 13024 } 13025 final int uid = Binder.getCallingUid(); 13026 final int pid = Binder.getCallingPid(); 13027 int status = AudioSystem.SUCCESS; 13028 final long token = Binder.clearCallingIdentity(); 13029 try { 13030 final String logString = TextUtils.formatSimple( 13031 "setPreferredMixerAttributes u/pid:%d/%d attr:%s mixerAttributes:%s portId:%d", 13032 uid, pid, attributes.toString(), mixerAttributes.toString(), portId); 13033 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 13034 13035 status = mAudioSystem.setPreferredMixerAttributes( 13036 attributes, portId, uid, mixerAttributes); 13037 if (status == AudioSystem.SUCCESS) { 13038 dispatchPreferredMixerAttributesChanged(attributes, portId, mixerAttributes); 13039 } else { 13040 Log.e(TAG, TextUtils.formatSimple("Error %d in %s)", status, logString)); 13041 } 13042 } finally { 13043 Binder.restoreCallingIdentity(token); 13044 } 13045 return status; 13046 } 13047 13048 /** 13049 * @see AudioManager#clearPreferredMixerAttributes(AudioAttributes, AudioDeviceInfo) 13050 */ clearPreferredMixerAttributes(AudioAttributes attributes, int portId)13051 public int clearPreferredMixerAttributes(AudioAttributes attributes, int portId) { 13052 Objects.requireNonNull(attributes); 13053 if (!checkAudioSettingsPermission("clearPreferredMixerAttributes()")) { 13054 return AudioSystem.PERMISSION_DENIED; 13055 } 13056 final int uid = Binder.getCallingUid(); 13057 final int pid = Binder.getCallingPid(); 13058 int status = AudioSystem.SUCCESS; 13059 final long token = Binder.clearCallingIdentity(); 13060 try { 13061 final String logString = TextUtils.formatSimple( 13062 "clearPreferredMixerAttributes u/pid:%d/%d attr:%s", 13063 uid, pid, attributes.toString()); 13064 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 13065 13066 status = mAudioSystem.clearPreferredMixerAttributes(attributes, portId, uid); 13067 if (status == AudioSystem.SUCCESS) { 13068 dispatchPreferredMixerAttributesChanged(attributes, portId, null /*mixerAttr*/); 13069 } else { 13070 Log.e(TAG, TextUtils.formatSimple("Error %d in %s)", status, logString)); 13071 } 13072 } finally { 13073 Binder.restoreCallingIdentity(token); 13074 } 13075 return status; 13076 } 13077 dispatchPreferredMixerAttributesChanged( AudioAttributes attr, int deviceId, AudioMixerAttributes mixerAttr)13078 void dispatchPreferredMixerAttributesChanged( 13079 AudioAttributes attr, int deviceId, AudioMixerAttributes mixerAttr) { 13080 Bundle bundle = new Bundle(); 13081 bundle.putParcelable(KEY_AUDIO_ATTRIBUTES, attr); 13082 bundle.putParcelable(KEY_AUDIO_MIXER_ATTRIBUTES, mixerAttr); 13083 sendBundleMsg(mAudioHandler, MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES, SENDMSG_QUEUE, 13084 deviceId, 0, null, bundle, 0); 13085 } 13086 13087 final RemoteCallbackList<IPreferredMixerAttributesDispatcher> mPrefMixerAttrDispatcher = 13088 new RemoteCallbackList<IPreferredMixerAttributesDispatcher>(); 13089 private static final String KEY_AUDIO_ATTRIBUTES = "audio_attributes"; 13090 private static final String KEY_AUDIO_MIXER_ATTRIBUTES = "audio_mixer_attributes"; 13091 13092 /** @see AudioManager#addOnPreferredMixerAttributesChangedListener( 13093 * Executor, AudioManager.OnPreferredMixerAttributesChangedListener) 13094 */ registerPreferredMixerAttributesDispatcher( @ullable IPreferredMixerAttributesDispatcher dispatcher)13095 public void registerPreferredMixerAttributesDispatcher( 13096 @Nullable IPreferredMixerAttributesDispatcher dispatcher) { 13097 if (dispatcher == null) { 13098 return; 13099 } 13100 mPrefMixerAttrDispatcher.register(dispatcher); 13101 } 13102 13103 /** @see AudioManager#removeOnPreferredMixerAttributesChangedListener( 13104 * AudioManager.OnPreferredMixerAttributesChangedListener) 13105 */ unregisterPreferredMixerAttributesDispatcher( @ullable IPreferredMixerAttributesDispatcher dispatcher)13106 public void unregisterPreferredMixerAttributesDispatcher( 13107 @Nullable IPreferredMixerAttributesDispatcher dispatcher) { 13108 if (dispatcher == null) { 13109 return; 13110 } 13111 mPrefMixerAttrDispatcher.unregister(dispatcher); 13112 } 13113 onDispatchPreferredMixerAttributesChanged(Bundle data, int deviceId)13114 protected void onDispatchPreferredMixerAttributesChanged(Bundle data, int deviceId) { 13115 final int nbDispathers = mPrefMixerAttrDispatcher.beginBroadcast(); 13116 final AudioAttributes attr = data.getParcelable( 13117 KEY_AUDIO_ATTRIBUTES, AudioAttributes.class); 13118 final AudioMixerAttributes mixerAttr = data.getParcelable( 13119 KEY_AUDIO_MIXER_ATTRIBUTES, AudioMixerAttributes.class); 13120 for (int i = 0; i < nbDispathers; i++) { 13121 try { 13122 mPrefMixerAttrDispatcher.getBroadcastItem(i) 13123 .dispatchPrefMixerAttributesChanged(attr, deviceId, mixerAttr); 13124 } catch (RemoteException e) { 13125 Log.e(TAG, "Can't call dispatchPrefMixerAttributesChanged() " 13126 + "IPreferredMixerAttributesDispatcher " 13127 + mPrefMixerAttrDispatcher.getBroadcastItem(i).asBinder(), e); 13128 } 13129 } 13130 mPrefMixerAttrDispatcher.finishBroadcast(); 13131 } 13132 13133 13134 /** @see AudioManager#supportsBluetoothVariableLatency() */ 13135 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) supportsBluetoothVariableLatency()13136 public boolean supportsBluetoothVariableLatency() { 13137 super.supportsBluetoothVariableLatency_enforcePermission(); 13138 try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { 13139 return AudioSystem.supportsBluetoothVariableLatency(); 13140 } 13141 } 13142 13143 /** @see AudioManager#setBluetoothVariableLatencyEnabled(boolean) */ 13144 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) setBluetoothVariableLatencyEnabled(boolean enabled)13145 public void setBluetoothVariableLatencyEnabled(boolean enabled) { 13146 super.setBluetoothVariableLatencyEnabled_enforcePermission(); 13147 try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { 13148 AudioSystem.setBluetoothVariableLatencyEnabled(enabled); 13149 } 13150 } 13151 13152 /** @see AudioManager#isBluetoothVariableLatencyEnabled(boolean) */ 13153 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) isBluetoothVariableLatencyEnabled()13154 public boolean isBluetoothVariableLatencyEnabled() { 13155 super.isBluetoothVariableLatencyEnabled_enforcePermission(); 13156 try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { 13157 return AudioSystem.isBluetoothVariableLatencyEnabled(); 13158 } 13159 } 13160 13161 private final Object mExtVolumeControllerLock = new Object(); 13162 private IAudioPolicyCallback mExtVolumeController; setExtVolumeController(IAudioPolicyCallback apc)13163 private void setExtVolumeController(IAudioPolicyCallback apc) { 13164 if (!mContext.getResources().getBoolean( 13165 com.android.internal.R.bool.config_handleVolumeKeysInWindowManager)) { 13166 Log.e(TAG, "Cannot set external volume controller: device not set for volume keys" + 13167 " handled in PhoneWindowManager"); 13168 return; 13169 } 13170 synchronized (mExtVolumeControllerLock) { 13171 if (mExtVolumeController != null && !mExtVolumeController.asBinder().pingBinder()) { 13172 Log.e(TAG, "Cannot set external volume controller: existing controller"); 13173 } 13174 mExtVolumeController = apc; 13175 } 13176 } 13177 dumpAudioPolicies(PrintWriter pw)13178 private void dumpAudioPolicies(PrintWriter pw) { 13179 pw.println("\nAudio policies:"); 13180 synchronized (mAudioPolicies) { 13181 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 13182 pw.println(policy.toLogFriendlyString()); 13183 } 13184 } 13185 } 13186 ensureFadeManagerConfigIsEnabled()13187 private void ensureFadeManagerConfigIsEnabled() { 13188 Preconditions.checkState(enableFadeManagerConfiguration(), 13189 "Fade manager configuration not supported"); 13190 } 13191 validateFadeManagerConfiguration(FadeManagerConfiguration fmc)13192 private void validateFadeManagerConfiguration(FadeManagerConfiguration fmc) { 13193 // validate permission of audio attributes 13194 List<AudioAttributes> attrs = fmc.getAudioAttributesWithVolumeShaperConfigs(); 13195 for (int index = 0; index < attrs.size(); index++) { 13196 validateAudioAttributesUsage(attrs.get(index)); 13197 } 13198 } 13199 13200 //====================== 13201 // Audio policy callbacks from AudioSystem for dynamic policies 13202 //====================== 13203 private final AudioSystem.DynamicPolicyCallback mDynPolicyCallback = 13204 new AudioSystem.DynamicPolicyCallback() { 13205 public void onDynamicPolicyMixStateUpdate(String regId, int state) { 13206 if (!TextUtils.isEmpty(regId)) { 13207 sendMsg(mAudioHandler, MSG_DYN_POLICY_MIX_STATE_UPDATE, SENDMSG_QUEUE, 13208 state /*arg1*/, 0 /*arg2 ignored*/, regId /*obj*/, 0 /*delay*/); 13209 } 13210 } 13211 }; 13212 onDynPolicyMixStateUpdate(String regId, int state)13213 private void onDynPolicyMixStateUpdate(String regId, int state) { 13214 if (DEBUG_AP) Log.d(TAG, "onDynamicPolicyMixStateUpdate("+ regId + ", " + state +")"); 13215 synchronized (mAudioPolicies) { 13216 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 13217 for (AudioMix mix : policy.getMixes()) { 13218 if (mix.getRegistration().equals(regId)) { 13219 try { 13220 policy.mPolicyCallback.notifyMixStateUpdate(regId, state); 13221 } catch (RemoteException e) { 13222 Log.e(TAG, "Can't call notifyMixStateUpdate() on IAudioPolicyCallback " 13223 + policy.mPolicyCallback.asBinder(), e); 13224 } 13225 return; 13226 } 13227 } 13228 } 13229 } 13230 } 13231 13232 //====================== 13233 // Audio policy callbacks from AudioSystem for recording configuration updates 13234 //====================== 13235 private final RecordingActivityMonitor mRecordMonitor; 13236 registerRecordingCallback(IRecordingConfigDispatcher rcdb)13237 public void registerRecordingCallback(IRecordingConfigDispatcher rcdb) { 13238 final boolean isPrivileged = 13239 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 13240 MODIFY_AUDIO_ROUTING)); 13241 mRecordMonitor.registerRecordingCallback(rcdb, isPrivileged); 13242 } 13243 unregisterRecordingCallback(IRecordingConfigDispatcher rcdb)13244 public void unregisterRecordingCallback(IRecordingConfigDispatcher rcdb) { 13245 mRecordMonitor.unregisterRecordingCallback(rcdb); 13246 } 13247 getActiveRecordingConfigurations()13248 public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() { 13249 final boolean isPrivileged = Binder.getCallingUid() == Process.SYSTEM_UID 13250 || (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 13251 MODIFY_AUDIO_ROUTING)); 13252 return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged); 13253 } 13254 13255 //====================== 13256 // Audio recording state notification from clients 13257 //====================== 13258 /** 13259 * Track a recorder provided by the client 13260 */ trackRecorder(IBinder recorder)13261 public int trackRecorder(IBinder recorder) { 13262 return mRecordMonitor.trackRecorder(recorder); 13263 } 13264 13265 /** 13266 * Receive an event from the client about a tracked recorder 13267 */ recorderEvent(int riid, int event)13268 public void recorderEvent(int riid, int event) { 13269 mRecordMonitor.recorderEvent(riid, event); 13270 } 13271 13272 /** 13273 * Stop tracking the recorder 13274 */ releaseRecorder(int riid)13275 public void releaseRecorder(int riid) { 13276 mRecordMonitor.releaseRecorder(riid); 13277 } 13278 13279 //====================== 13280 // Audio playback notification 13281 //====================== 13282 private final PlaybackActivityMonitor mPlaybackMonitor; 13283 registerPlaybackCallback(IPlaybackConfigDispatcher pcdb)13284 public void registerPlaybackCallback(IPlaybackConfigDispatcher pcdb) { 13285 final boolean isPrivileged = 13286 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 13287 MODIFY_AUDIO_ROUTING)); 13288 mPlaybackMonitor.registerPlaybackCallback(pcdb, isPrivileged); 13289 } 13290 unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb)13291 public void unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb) { 13292 mPlaybackMonitor.unregisterPlaybackCallback(pcdb); 13293 } 13294 getActivePlaybackConfigurations()13295 public List<AudioPlaybackConfiguration> getActivePlaybackConfigurations() { 13296 final boolean isPrivileged = 13297 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 13298 MODIFY_AUDIO_ROUTING)); 13299 return mPlaybackMonitor.getActivePlaybackConfigurations(isPrivileged); 13300 } 13301 trackPlayer(PlayerBase.PlayerIdCard pic)13302 public int trackPlayer(PlayerBase.PlayerIdCard pic) { 13303 if (pic != null && pic.mAttributes != null) { 13304 validateAudioAttributesUsage(pic.mAttributes); 13305 } 13306 return mPlaybackMonitor.trackPlayer(pic); 13307 } 13308 playerAttributes(int piid, AudioAttributes attr)13309 public void playerAttributes(int piid, AudioAttributes attr) { 13310 if (attr != null) { 13311 validateAudioAttributesUsage(attr); 13312 } 13313 mPlaybackMonitor.playerAttributes(piid, attr, Binder.getCallingUid()); 13314 } 13315 13316 /** 13317 * Update player session ID 13318 * @param piid Player id to update 13319 * @param sessionId The new audio session ID 13320 */ playerSessionId(int piid, int sessionId)13321 public void playerSessionId(int piid, int sessionId) { 13322 if (sessionId <= AudioSystem.AUDIO_SESSION_ALLOCATE) { 13323 throw new IllegalArgumentException("invalid session Id " + sessionId); 13324 } 13325 mPlaybackMonitor.playerSessionId(piid, sessionId, Binder.getCallingUid()); 13326 } 13327 13328 /** 13329 * Update player event 13330 * @param piid Player id to update 13331 * @param event The new player event 13332 * @param eventValue The value associated with this event 13333 */ playerEvent(int piid, int event, int eventValue)13334 public void playerEvent(int piid, int event, int eventValue) { 13335 mPlaybackMonitor.playerEvent(piid, event, eventValue, Binder.getCallingUid()); 13336 } 13337 13338 /** 13339 * Update event for port id 13340 * @param portId Port id to update 13341 * @param event The new event for the given port 13342 * @param extras Bundle of extra values to describe the event 13343 */ portEvent(int portId, int event, @Nullable PersistableBundle extras)13344 public void portEvent(int portId, int event, @Nullable PersistableBundle extras) { 13345 mPlaybackMonitor.portEvent(portId, event, extras, Binder.getCallingUid()); 13346 } 13347 playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio)13348 public void playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio) { 13349 mPlaybackMonitor.playerHasOpPlayAudio(piid, hasOpPlayAudio, Binder.getCallingUid()); 13350 } 13351 releasePlayer(int piid)13352 public void releasePlayer(int piid) { 13353 mPlaybackMonitor.releasePlayer(piid, Binder.getCallingUid()); 13354 } 13355 13356 /** 13357 * Specifies whether the audio played by this app may or may not be captured by other apps or 13358 * the system. 13359 * 13360 * @param capturePolicy one of 13361 * {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}, 13362 * {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM}, 13363 * {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}. 13364 * @return AudioSystem.AUDIO_STATUS_OK if set allowed capture policy succeed. 13365 * @throws IllegalArgumentException if the argument is not a valid value. 13366 */ setAllowedCapturePolicy(int capturePolicy)13367 public int setAllowedCapturePolicy(int capturePolicy) { 13368 int callingUid = Binder.getCallingUid(); 13369 int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0); 13370 final long identity = Binder.clearCallingIdentity(); 13371 try { 13372 synchronized (mPlaybackMonitor) { 13373 int result = mAudioSystem.setAllowedCapturePolicy(callingUid, flags); 13374 if (result == AudioSystem.AUDIO_STATUS_OK) { 13375 mPlaybackMonitor.setAllowedCapturePolicy(callingUid, capturePolicy); 13376 } 13377 return result; 13378 } 13379 } finally { 13380 Binder.restoreCallingIdentity(identity); 13381 } 13382 } 13383 13384 /** 13385 * Return the capture policy. 13386 * @return the cached capture policy for the calling uid. 13387 */ getAllowedCapturePolicy()13388 public int getAllowedCapturePolicy() { 13389 int callingUid = Binder.getCallingUid(); 13390 final long identity = Binder.clearCallingIdentity(); 13391 try { 13392 return mPlaybackMonitor.getAllowedCapturePolicy(callingUid); 13393 } finally { 13394 Binder.restoreCallingIdentity(identity); 13395 } 13396 } 13397 13398 /* package */ isPlaybackActiveForUid(int uid)13399 boolean isPlaybackActiveForUid(int uid) { 13400 return mPlaybackMonitor.isPlaybackActiveForUid(uid); 13401 } 13402 13403 /* package */ isRecordingActiveForUid(int uid)13404 boolean isRecordingActiveForUid(int uid) { 13405 return mRecordMonitor.isRecordingActiveForUid(uid); 13406 } 13407 13408 //====================== 13409 // Audio device management 13410 //====================== 13411 private final AudioDeviceBroker mDeviceBroker; 13412 13413 //====================== 13414 // Audio policy proxy 13415 //====================== 13416 private static final class AudioDeviceArray { 13417 final @NonNull int[] mDeviceTypes; 13418 final @NonNull String[] mDeviceAddresses; AudioDeviceArray(@onNull int[] types, @NonNull String[] addresses)13419 AudioDeviceArray(@NonNull int[] types, @NonNull String[] addresses) { 13420 mDeviceTypes = types; 13421 mDeviceAddresses = addresses; 13422 } 13423 } 13424 13425 /** 13426 * This internal class inherits from AudioPolicyConfig, each instance contains all the 13427 * mixes of an AudioPolicy and their configurations. 13428 */ 13429 public class AudioPolicyProxy extends AudioPolicyConfig implements IBinder.DeathRecipient { 13430 private static final String TAG = "AudioPolicyProxy"; 13431 final IAudioPolicyCallback mPolicyCallback; 13432 final AttributionSource mAttributionSource; 13433 final boolean mHasFocusListener; 13434 final boolean mIsVolumeController; 13435 final HashMap<Integer, AudioDeviceArray> mUidDeviceAffinities = 13436 new HashMap<Integer, AudioDeviceArray>(); 13437 13438 final HashMap<Integer, AudioDeviceArray> mUserIdDeviceAffinities = 13439 new HashMap<>(); 13440 13441 final IMediaProjection mProjection; 13442 private final class UnregisterOnStopCallback extends IMediaProjectionCallback.Stub { onStop()13443 public void onStop() { 13444 unregisterAudioPolicyAsync(mPolicyCallback); 13445 } 13446 13447 @Override onCapturedContentResize(int width, int height)13448 public void onCapturedContentResize(int width, int height) { 13449 // Ignore resize of the captured content. 13450 } 13451 13452 @Override onCapturedContentVisibilityChanged(boolean isVisible)13453 public void onCapturedContentVisibilityChanged(boolean isVisible) { 13454 // Ignore visibility changes of the captured content. 13455 } 13456 }; 13457 UnregisterOnStopCallback mProjectionCallback; 13458 13459 /** 13460 * Audio focus ducking behavior for an audio policy. 13461 * This variable reflects the value that was successfully set in 13462 * {@link AudioService#setFocusPropertiesForPolicy(int, IAudioPolicyCallback)}. This 13463 * implies that a value of FOCUS_POLICY_DUCKING_IN_POLICY means the corresponding policy 13464 * is handling ducking for audio focus. 13465 */ 13466 int mFocusDuckBehavior = AudioPolicy.FOCUS_POLICY_DUCKING_DEFAULT; 13467 boolean mIsFocusPolicy = false; 13468 boolean mIsTestFocusPolicy = false; 13469 AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection, AttributionSource attributionSource)13470 AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, 13471 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, 13472 boolean isVolumeController, IMediaProjection projection, 13473 AttributionSource attributionSource) { 13474 super(config); 13475 setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++)); 13476 mPolicyCallback = token; 13477 mAttributionSource = attributionSource; 13478 mHasFocusListener = hasFocusListener; 13479 mIsVolumeController = isVolumeController; 13480 mProjection = projection; 13481 if (mHasFocusListener) { 13482 mMediaFocusControl.addFocusFollower(mPolicyCallback); 13483 // can only ever be true if there is a focus listener 13484 if (isFocusPolicy) { 13485 mIsFocusPolicy = true; 13486 mIsTestFocusPolicy = isTestFocusPolicy; 13487 mMediaFocusControl.setFocusPolicy(mPolicyCallback, mIsTestFocusPolicy); 13488 } 13489 } 13490 if (mIsVolumeController) { 13491 setExtVolumeController(mPolicyCallback); 13492 } 13493 if (mProjection != null) { 13494 mProjectionCallback = new UnregisterOnStopCallback(); 13495 try { 13496 mProjection.registerCallback(mProjectionCallback); 13497 } catch (RemoteException e) { 13498 release(); 13499 throw new IllegalStateException("MediaProjection callback registration failed, " 13500 + "could not link to " + projection + " binder death", e); 13501 } 13502 } 13503 13504 int status = connectMixes(); 13505 if (status != AudioSystem.SUCCESS) { 13506 release(); 13507 throw new IllegalStateException("Could not connect mix, error: " + status); 13508 } 13509 } 13510 binderDied()13511 public void binderDied() { 13512 mDynPolicyLogger.enqueue((new EventLogger.StringEvent("AudioPolicy " 13513 + mPolicyCallback.asBinder() + " died").printLog(TAG))); 13514 13515 List<String> addresses = new ArrayList<>(); 13516 for (AudioMix mix : mMixes) { 13517 addresses.add(mix.getRegistration()); 13518 } 13519 onPolicyClientDeath(addresses); 13520 13521 release(); 13522 } 13523 getRegistrationId()13524 String getRegistrationId() { 13525 return getRegistration(); 13526 } 13527 release()13528 void release() { 13529 if (mIsFocusPolicy) { 13530 mMediaFocusControl.unsetFocusPolicy(mPolicyCallback, mIsTestFocusPolicy); 13531 } 13532 if (mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 13533 mMediaFocusControl.setDuckingInExtPolicyAvailable(false); 13534 } 13535 if (mHasFocusListener) { 13536 mMediaFocusControl.removeFocusFollower(mPolicyCallback); 13537 } 13538 if (mProjectionCallback != null) { 13539 try { 13540 mProjection.unregisterCallback(mProjectionCallback); 13541 } catch (RemoteException e) { 13542 Log.e(TAG, "Fail to unregister Audiopolicy callback from MediaProjection"); 13543 } 13544 } 13545 if (mIsVolumeController) { 13546 synchronized (mExtVolumeControllerLock) { 13547 mExtVolumeController = null; 13548 } 13549 } 13550 final long identity = Binder.clearCallingIdentity(); 13551 try { 13552 if (android.media.audiopolicy.Flags.audioMixOwnership()) { 13553 synchronized (mMixes) { 13554 removeMixes(new ArrayList(mMixes)); 13555 } 13556 } else { 13557 mAudioSystem.registerPolicyMixes(mMixes, false); 13558 } 13559 } finally { 13560 Binder.restoreCallingIdentity(identity); 13561 } 13562 synchronized (mAudioPolicies) { 13563 mAudioPolicies.remove(mPolicyCallback.asBinder()); 13564 } 13565 try { 13566 mPolicyCallback.notifyUnregistration(); 13567 } catch (RemoteException e) { } 13568 } 13569 hasMixAffectingUsage(int usage, int excludedFlags)13570 boolean hasMixAffectingUsage(int usage, int excludedFlags) { 13571 for (AudioMix mix : mMixes) { 13572 if (mix.isAffectingUsage(usage) 13573 && ((mix.getRouteFlags() & excludedFlags) != excludedFlags)) { 13574 return true; 13575 } 13576 } 13577 return false; 13578 } 13579 13580 // Verify all the devices in the array are served by mixes defined in this policy hasMixRoutedToDevices(@onNull int[] deviceTypes, @NonNull String[] deviceAddresses)13581 boolean hasMixRoutedToDevices(@NonNull int[] deviceTypes, 13582 @NonNull String[] deviceAddresses) { 13583 for (int i = 0; i < deviceTypes.length; i++) { 13584 boolean hasDevice = false; 13585 for (AudioMix mix : mMixes) { 13586 // this will check both that the mix has ROUTE_FLAG_RENDER and the device 13587 // is reached by this mix 13588 if (mix.isRoutedToDevice(deviceTypes[i], deviceAddresses[i])) { 13589 hasDevice = true; 13590 break; 13591 } 13592 } 13593 if (!hasDevice) { 13594 return false; 13595 } 13596 } 13597 return true; 13598 } 13599 addMixes(@onNull ArrayList<AudioMix> mixes)13600 int addMixes(@NonNull ArrayList<AudioMix> mixes) { 13601 synchronized (mMixes) { 13602 if (android.media.audiopolicy.Flags.audioMixOwnership()) { 13603 for (AudioMix mix : mixes) { 13604 setMixRegistration(mix); 13605 mix.setVirtualDeviceId(mAttributionSource.getDeviceId()); 13606 } 13607 13608 int result = mAudioSystem.registerPolicyMixes(mixes, true); 13609 if (result == AudioSystem.SUCCESS) { 13610 this.add(mixes); 13611 } 13612 return result; 13613 } 13614 this.add(mixes); 13615 return mAudioSystem.registerPolicyMixes(mixes, true); 13616 } 13617 } 13618 removeMixes(@onNull ArrayList<AudioMix> mixes)13619 int removeMixes(@NonNull ArrayList<AudioMix> mixes) { 13620 synchronized (mMixes) { 13621 this.remove(mixes); 13622 return mAudioSystem.registerPolicyMixes(mixes, false); 13623 } 13624 } 13625 connectMixes()13626 @AudioSystem.AudioSystemError int connectMixes() { 13627 final long identity = Binder.clearCallingIdentity(); 13628 try { 13629 for (AudioMix mix : mMixes) { 13630 mix.setVirtualDeviceId(mAttributionSource.getDeviceId()); 13631 } 13632 return mAudioSystem.registerPolicyMixes(mMixes, true); 13633 } finally { 13634 Binder.restoreCallingIdentity(identity); 13635 } 13636 13637 } 13638 updateMixingRules( @onNull AudioMix[] mixesToUpdate, @NonNull AudioMixingRule[] updatedMixingRules)13639 @AudioSystem.AudioSystemError int updateMixingRules( 13640 @NonNull AudioMix[] mixesToUpdate, 13641 @NonNull AudioMixingRule[] updatedMixingRules) { 13642 Objects.requireNonNull(mixesToUpdate); 13643 Objects.requireNonNull(updatedMixingRules); 13644 13645 for (AudioMix mix : mixesToUpdate) { 13646 mix.setVirtualDeviceId(mAttributionSource.getDeviceId()); 13647 } 13648 if (mixesToUpdate.length != updatedMixingRules.length) { 13649 Log.e(TAG, "Provided list of audio mixes to update and corresponding mixing rules " 13650 + "have mismatching length (mixesToUpdate.length = " + mixesToUpdate.length 13651 + ", updatedMixingRules.length = " + updatedMixingRules.length + ")."); 13652 return AudioSystem.BAD_VALUE; 13653 } 13654 13655 synchronized (mMixes) { 13656 try (SafeCloseable unused = ClearCallingIdentityContext.create()) { 13657 int ret = mAudioSystem.updateMixingRules(mixesToUpdate, updatedMixingRules); 13658 if (ret == AudioSystem.SUCCESS) { 13659 for (int i = 0; i < mixesToUpdate.length; i++) { 13660 AudioMix audioMixToUpdate = mixesToUpdate[i]; 13661 AudioMixingRule audioMixingRule = updatedMixingRules[i]; 13662 mMixes.stream().filter(audioMixToUpdate::equals).findAny().ifPresent( 13663 mix -> mix.setAudioMixingRule(audioMixingRule)); 13664 } 13665 } 13666 return ret; 13667 } 13668 } 13669 } 13670 setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses)13671 int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) { 13672 final Integer Uid = new Integer(uid); 13673 if (mUidDeviceAffinities.remove(Uid) != null) { 13674 if (removeUidDeviceAffinitiesFromSystem(uid) != AudioSystem.SUCCESS) { 13675 Log.e(TAG, "AudioSystem. removeUidDeviceAffinities(" + uid + ") failed, " 13676 + " cannot call AudioSystem.setUidDeviceAffinities"); 13677 return AudioManager.ERROR; 13678 } 13679 } 13680 AudioDeviceArray deviceArray = new AudioDeviceArray(types, addresses); 13681 if (setUidDeviceAffinitiesOnSystem(uid, deviceArray) == AudioSystem.SUCCESS) { 13682 mUidDeviceAffinities.put(Uid, deviceArray); 13683 return AudioManager.SUCCESS; 13684 } 13685 Log.e(TAG, "AudioSystem. setUidDeviceAffinities(" + uid + ") failed"); 13686 return AudioManager.ERROR; 13687 } 13688 removeUidDeviceAffinities(int uid)13689 int removeUidDeviceAffinities(int uid) { 13690 if (mUidDeviceAffinities.remove(new Integer(uid)) != null) { 13691 if (removeUidDeviceAffinitiesFromSystem(uid) == AudioSystem.SUCCESS) { 13692 return AudioManager.SUCCESS; 13693 } 13694 } 13695 Log.e(TAG, "AudioSystem. removeUidDeviceAffinities failed"); 13696 return AudioManager.ERROR; 13697 } 13698 removeUidDeviceAffinitiesFromSystem(int uid)13699 @AudioSystem.AudioSystemError private int removeUidDeviceAffinitiesFromSystem(int uid) { 13700 final long identity = Binder.clearCallingIdentity(); 13701 try { 13702 return mAudioSystem.removeUidDeviceAffinities(uid); 13703 } finally { 13704 Binder.restoreCallingIdentity(identity); 13705 } 13706 } 13707 setUidDeviceAffinitiesOnSystem(int uid, AudioDeviceArray deviceArray)13708 @AudioSystem.AudioSystemError private int setUidDeviceAffinitiesOnSystem(int uid, 13709 AudioDeviceArray deviceArray) { 13710 final long identity = Binder.clearCallingIdentity(); 13711 try { 13712 return mAudioSystem.setUidDeviceAffinities(uid, deviceArray.mDeviceTypes, 13713 deviceArray.mDeviceAddresses); 13714 } finally { 13715 Binder.restoreCallingIdentity(identity); 13716 } 13717 } 13718 setUserIdDeviceAffinities(int userId, @NonNull int[] types, @NonNull String[] addresses)13719 int setUserIdDeviceAffinities(int userId, 13720 @NonNull int[] types, @NonNull String[] addresses) { 13721 final Integer UserId = new Integer(userId); 13722 if (mUserIdDeviceAffinities.remove(UserId) != null) { 13723 if (removeUserIdDeviceAffinitiesFromSystem(userId) != AudioSystem.SUCCESS) { 13724 Log.e(TAG, "AudioSystem. removeUserIdDeviceAffinities(" 13725 + UserId + ") failed, " 13726 + " cannot call AudioSystem.setUserIdDeviceAffinities"); 13727 return AudioManager.ERROR; 13728 } 13729 } 13730 AudioDeviceArray audioDeviceArray = new AudioDeviceArray(types, addresses); 13731 if (setUserIdDeviceAffinitiesOnSystem(userId, audioDeviceArray) 13732 == AudioSystem.SUCCESS) { 13733 mUserIdDeviceAffinities.put(UserId, audioDeviceArray); 13734 return AudioManager.SUCCESS; 13735 } 13736 Log.e(TAG, "AudioSystem.setUserIdDeviceAffinities(" + userId + ") failed"); 13737 return AudioManager.ERROR; 13738 } 13739 removeUserIdDeviceAffinities(int userId)13740 int removeUserIdDeviceAffinities(int userId) { 13741 if (mUserIdDeviceAffinities.remove(new Integer(userId)) != null) { 13742 if (removeUserIdDeviceAffinitiesFromSystem(userId) == AudioSystem.SUCCESS) { 13743 return AudioManager.SUCCESS; 13744 } 13745 } 13746 Log.e(TAG, "AudioSystem.removeUserIdDeviceAffinities failed"); 13747 return AudioManager.ERROR; 13748 } 13749 removeUserIdDeviceAffinitiesFromSystem( @serIdInt int userId)13750 @AudioSystem.AudioSystemError private int removeUserIdDeviceAffinitiesFromSystem( 13751 @UserIdInt int userId) { 13752 final long identity = Binder.clearCallingIdentity(); 13753 try { 13754 return mAudioSystem.removeUserIdDeviceAffinities(userId); 13755 } finally { 13756 Binder.restoreCallingIdentity(identity); 13757 } 13758 } 13759 setUserIdDeviceAffinitiesOnSystem( @serIdInt int userId, AudioDeviceArray deviceArray)13760 @AudioSystem.AudioSystemError private int setUserIdDeviceAffinitiesOnSystem( 13761 @UserIdInt int userId, AudioDeviceArray deviceArray) { 13762 final long identity = Binder.clearCallingIdentity(); 13763 try { 13764 return mAudioSystem.setUserIdDeviceAffinities(userId, deviceArray.mDeviceTypes, 13765 deviceArray.mDeviceAddresses); 13766 } finally { 13767 Binder.restoreCallingIdentity(identity); 13768 } 13769 } 13770 setupDeviceAffinities()13771 @AudioSystem.AudioSystemError int setupDeviceAffinities() { 13772 for (Map.Entry<Integer, AudioDeviceArray> uidEntry : mUidDeviceAffinities.entrySet()) { 13773 int uidStatus = removeUidDeviceAffinitiesFromSystem(uidEntry.getKey()); 13774 if (uidStatus != AudioSystem.SUCCESS) { 13775 Log.e(TAG, 13776 "setupDeviceAffinities failed to remove device affinity for uid " 13777 + uidEntry.getKey()); 13778 return uidStatus; 13779 } 13780 uidStatus = setUidDeviceAffinitiesOnSystem(uidEntry.getKey(), uidEntry.getValue()); 13781 if (uidStatus != AudioSystem.SUCCESS) { 13782 Log.e(TAG, 13783 "setupDeviceAffinities failed to set device affinity for uid " 13784 + uidEntry.getKey()); 13785 return uidStatus; 13786 } 13787 } 13788 13789 for (Map.Entry<Integer, AudioDeviceArray> userIdEntry : 13790 mUserIdDeviceAffinities.entrySet()) { 13791 int userIdStatus = removeUserIdDeviceAffinitiesFromSystem(userIdEntry.getKey()); 13792 if (userIdStatus != AudioSystem.SUCCESS) { 13793 Log.e(TAG, 13794 "setupDeviceAffinities failed to remove device affinity for userId " 13795 + userIdEntry.getKey()); 13796 return userIdStatus; 13797 } 13798 userIdStatus = setUserIdDeviceAffinitiesOnSystem(userIdEntry.getKey(), 13799 userIdEntry.getValue()); 13800 if (userIdStatus != AudioSystem.SUCCESS) { 13801 Log.e(TAG, 13802 "setupDeviceAffinities failed to set device affinity for userId " 13803 + userIdEntry.getKey()); 13804 return userIdStatus; 13805 } 13806 } 13807 return AudioSystem.SUCCESS; 13808 } 13809 13810 /** @return human readable debug informations summarizing the state of the object. */ toLogFriendlyString()13811 public String toLogFriendlyString() { 13812 String textDump = super.toLogFriendlyString(); 13813 textDump += " Uid Device Affinities:\n"; 13814 String spacer = " "; 13815 textDump += logFriendlyAttributeDeviceArrayMap("Uid", 13816 mUidDeviceAffinities, spacer); 13817 textDump += " UserId Device Affinities:\n"; 13818 textDump += logFriendlyAttributeDeviceArrayMap("UserId", 13819 mUserIdDeviceAffinities, spacer); 13820 textDump += " Proxy:\n"; 13821 textDump += " is focus policy= " + mIsFocusPolicy + "\n"; 13822 if (mIsFocusPolicy) { 13823 textDump += " focus duck behaviour= " + mFocusDuckBehavior + "\n"; 13824 textDump += " is test focus policy= " + mIsTestFocusPolicy + "\n"; 13825 textDump += " has focus listener= " + mHasFocusListener + "\n"; 13826 } 13827 textDump += " media projection= " + mProjection + "\n"; 13828 return textDump; 13829 } 13830 logFriendlyAttributeDeviceArrayMap(String attribute, Map<Integer, AudioDeviceArray> map, String spacer)13831 private String logFriendlyAttributeDeviceArrayMap(String attribute, 13832 Map<Integer, AudioDeviceArray> map, String spacer) { 13833 final StringBuilder stringBuilder = new StringBuilder(); 13834 for (Map.Entry<Integer, AudioDeviceArray> mapEntry : map.entrySet()) { 13835 stringBuilder.append(spacer).append(attribute).append(": ") 13836 .append(mapEntry.getKey()).append("\n"); 13837 AudioDeviceArray deviceArray = mapEntry.getValue(); 13838 String deviceSpacer = spacer + " "; 13839 for (int i = 0; i < deviceArray.mDeviceTypes.length; i++) { 13840 stringBuilder.append(deviceSpacer).append("Type: 0x") 13841 .append(Integer.toHexString(deviceArray.mDeviceTypes[i])) 13842 .append(" Address: ").append(deviceArray.mDeviceAddresses[i]) 13843 .append("\n"); 13844 } 13845 } 13846 return stringBuilder.toString(); 13847 } 13848 }; 13849 13850 //====================== 13851 // Audio policy: focus 13852 //====================== 13853 /** */ dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb)13854 public int dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb) { 13855 if (afi == null) { 13856 throw new IllegalArgumentException("Illegal null AudioFocusInfo"); 13857 } 13858 if (pcb == null) { 13859 throw new IllegalArgumentException("Illegal null AudioPolicy callback"); 13860 } 13861 synchronized (mAudioPolicies) { 13862 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 13863 throw new IllegalStateException("Unregistered AudioPolicy for focus dispatch"); 13864 } 13865 return mMediaFocusControl.dispatchFocusChange(afi, focusChange); 13866 } 13867 } 13868 setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, IAudioPolicyCallback pcb)13869 public void setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, 13870 IAudioPolicyCallback pcb) { 13871 if (afi == null) { 13872 throw new IllegalArgumentException("Illegal null AudioFocusInfo"); 13873 } 13874 if (pcb == null) { 13875 throw new IllegalArgumentException("Illegal null AudioPolicy callback"); 13876 } 13877 synchronized (mAudioPolicies) { 13878 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 13879 throw new IllegalStateException("Unregistered AudioPolicy for external focus"); 13880 } 13881 mMediaFocusControl.setFocusRequestResultFromExtPolicy(afi, requestResult); 13882 } 13883 } 13884 13885 /** 13886 * see {@link AudioManager#dispatchAudioFocusChangeWithFade(AudioFocusInfo, int, AudioPolicy, 13887 * List, FadeManagerConfiguration)} 13888 */ 13889 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) dispatchFocusChangeWithFade(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb, List<AudioFocusInfo> otherActiveAfis, FadeManagerConfiguration transientFadeMgrConfig)13890 public int dispatchFocusChangeWithFade(AudioFocusInfo afi, int focusChange, 13891 IAudioPolicyCallback pcb, List<AudioFocusInfo> otherActiveAfis, 13892 FadeManagerConfiguration transientFadeMgrConfig) { 13893 super.dispatchFocusChangeWithFade_enforcePermission(); 13894 ensureFadeManagerConfigIsEnabled(); 13895 Objects.requireNonNull(afi, "AudioFocusInfo cannot be null"); 13896 Objects.requireNonNull(pcb, "AudioPolicy callback cannot be null"); 13897 Objects.requireNonNull(otherActiveAfis, 13898 "Other active AudioFocusInfo list cannot be null"); 13899 if (transientFadeMgrConfig != null) { 13900 validateFadeManagerConfiguration(transientFadeMgrConfig); 13901 } 13902 13903 synchronized (mAudioPolicies) { 13904 Preconditions.checkState(mAudioPolicies.containsKey(pcb.asBinder()), 13905 "Unregistered AudioPolicy for focus dispatch with fade"); 13906 13907 // set the transient fade manager config to be used for handling this focus change 13908 if (transientFadeMgrConfig != null) { 13909 mPlaybackMonitor.setTransientFadeManagerConfiguration(focusChange, 13910 transientFadeMgrConfig); 13911 } 13912 int status = mMediaFocusControl.dispatchFocusChangeWithFade(afi, focusChange, 13913 otherActiveAfis); 13914 13915 if (transientFadeMgrConfig != null) { 13916 mPlaybackMonitor.clearTransientFadeManagerConfiguration(focusChange); 13917 } 13918 return status; 13919 } 13920 } 13921 13922 13923 /** 13924 * @see AudioManager#shouldNotificationSoundPlay(AudioAttributes) 13925 */ 13926 @android.annotation.EnforcePermission(QUERY_AUDIO_STATE) shouldNotificationSoundPlay(@onNull final AudioAttributes aa)13927 public boolean shouldNotificationSoundPlay(@NonNull final AudioAttributes aa) { 13928 super.shouldNotificationSoundPlay_enforcePermission(); 13929 Objects.requireNonNull(aa); 13930 13931 // don't play notifications if the stream volume associated with the 13932 // AudioAttributes of the notification record is 0 (non-zero volume implies 13933 // not silenced by SILENT or VIBRATE ringer mode) 13934 final int stream = AudioAttributes.toLegacyStreamType(aa); 13935 final boolean mutingFromVolume = getStreamVolume(stream) == 0; 13936 if (mutingFromVolume) { 13937 Slog.i(TAG, "shouldNotificationSoundPlay false: muted stream:" + stream 13938 + " attr:" + aa); 13939 return false; 13940 } 13941 13942 // don't play notifications if there is a user of GAIN_TRANSIENT_EXCLUSIVE audio focus 13943 // and the focus owner is recording 13944 final int uid = mMediaFocusControl.getExclusiveFocusOwnerUid(); 13945 if (uid == -1) { // return value is -1 if focus isn't GAIN_TRANSIENT_EXCLUSIVE 13946 return true; 13947 } 13948 // is the owner of GAIN_TRANSIENT_EXCLUSIVE focus also recording? 13949 final boolean mutingFromFocusAndRecording = mRecordMonitor.isRecordingActiveForUid(uid); 13950 if (mutingFromFocusAndRecording) { 13951 Slog.i(TAG, "shouldNotificationSoundPlay false: exclusive focus owner recording " 13952 + " uid:" + uid + " attr:" + aa); 13953 return false; 13954 } 13955 return true; 13956 } 13957 13958 //====================== 13959 // Audioserver state dispatch 13960 //====================== 13961 private class AsdProxy implements IBinder.DeathRecipient { 13962 private final IAudioServerStateDispatcher mAsd; 13963 AsdProxy(IAudioServerStateDispatcher asd)13964 AsdProxy(IAudioServerStateDispatcher asd) { 13965 mAsd = asd; 13966 } 13967 binderDied()13968 public void binderDied() { 13969 synchronized (mAudioServerStateListeners) { 13970 mAudioServerStateListeners.remove(mAsd.asBinder()); 13971 } 13972 } 13973 callback()13974 IAudioServerStateDispatcher callback() { 13975 return mAsd; 13976 } 13977 } 13978 13979 private final HashMap<IBinder, AsdProxy> mAudioServerStateListeners = 13980 new HashMap<IBinder, AsdProxy>(); 13981 checkMonitorAudioServerStatePermission()13982 private void checkMonitorAudioServerStatePermission() { 13983 if (!(mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE) 13984 == PackageManager.PERMISSION_GRANTED 13985 || mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING) 13986 == PackageManager.PERMISSION_GRANTED)) { 13987 throw new SecurityException("Not allowed to monitor audioserver state"); 13988 } 13989 } 13990 registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd)13991 public void registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd) { 13992 checkMonitorAudioServerStatePermission(); 13993 synchronized (mAudioServerStateListeners) { 13994 if (mAudioServerStateListeners.containsKey(asd.asBinder())) { 13995 Slog.w(TAG, "Cannot re-register audio server state dispatcher"); 13996 return; 13997 } 13998 AsdProxy asdp = new AsdProxy(asd); 13999 try { 14000 asd.asBinder().linkToDeath(asdp, 0/*flags*/); 14001 } catch (RemoteException e) { 14002 14003 } 14004 mAudioServerStateListeners.put(asd.asBinder(), asdp); 14005 } 14006 } 14007 unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd)14008 public void unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd) { 14009 checkMonitorAudioServerStatePermission(); 14010 synchronized (mAudioServerStateListeners) { 14011 AsdProxy asdp = mAudioServerStateListeners.remove(asd.asBinder()); 14012 if (asdp == null) { 14013 Slog.w(TAG, "Trying to unregister unknown audioserver state dispatcher for pid " 14014 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()); 14015 return; 14016 } else { 14017 asd.asBinder().unlinkToDeath(asdp, 0/*flags*/); 14018 } 14019 } 14020 } 14021 isAudioServerRunning()14022 public boolean isAudioServerRunning() { 14023 checkMonitorAudioServerStatePermission(); 14024 return (AudioSystem.checkAudioFlinger() == AudioSystem.AUDIO_STATUS_OK); 14025 } 14026 14027 //====================== 14028 // Audio HAL process dump 14029 //====================== 14030 14031 private static final String AUDIO_HAL_SERVICE_PREFIX = "android.hardware.audio"; 14032 getAudioAidlHalPids(HashSet<Integer> pids)14033 private void getAudioAidlHalPids(HashSet<Integer> pids) { 14034 try { 14035 ServiceDebugInfo[] infos = ServiceManager.getServiceDebugInfo(); 14036 if (infos == null) return; 14037 for (ServiceDebugInfo info : infos) { 14038 if (info.debugPid > 0 && info.name.startsWith(AUDIO_HAL_SERVICE_PREFIX)) { 14039 pids.add(info.debugPid); 14040 } 14041 } 14042 } catch (RuntimeException e) { 14043 // ignored, pid hashset does not change 14044 } 14045 } 14046 getAudioHalHidlPids(HashSet<Integer> pids)14047 private void getAudioHalHidlPids(HashSet<Integer> pids) { 14048 try { 14049 IServiceManager serviceManager = IServiceManager.getService(); 14050 ArrayList<IServiceManager.InstanceDebugInfo> dump = 14051 serviceManager.debugDump(); 14052 for (IServiceManager.InstanceDebugInfo info : dump) { 14053 if (info.pid != IServiceManager.PidConstant.NO_PID 14054 && info.interfaceName != null 14055 && info.interfaceName.startsWith(AUDIO_HAL_SERVICE_PREFIX)) { 14056 pids.add(info.pid); 14057 } 14058 } 14059 } catch (RemoteException | RuntimeException e) { 14060 // ignored, pid hashset does not change 14061 } 14062 } 14063 getAudioHalPids()14064 private Set<Integer> getAudioHalPids() { 14065 HashSet<Integer> pids = new HashSet<>(); 14066 getAudioAidlHalPids(pids); 14067 getAudioHalHidlPids(pids); 14068 return pids; 14069 } 14070 updateAudioHalPids()14071 private void updateAudioHalPids() { 14072 Set<Integer> pidsSet = getAudioHalPids(); 14073 if (pidsSet.isEmpty()) { 14074 Slog.w(TAG, "Could not retrieve audio HAL service pids"); 14075 return; 14076 } 14077 int[] pidsArray = pidsSet.stream().mapToInt(Integer::intValue).toArray(); 14078 AudioSystem.setAudioHalPids(pidsArray); 14079 } 14080 14081 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 14082 //====================== 14083 // Multi Audio Focus 14084 //====================== setMultiAudioFocusEnabled(boolean enabled)14085 public void setMultiAudioFocusEnabled(boolean enabled) { 14086 super.setMultiAudioFocusEnabled_enforcePermission(); 14087 14088 if (mMediaFocusControl != null) { 14089 boolean mafEnabled = mMediaFocusControl.getMultiAudioFocusEnabled(); 14090 if (mafEnabled != enabled) { 14091 mMediaFocusControl.updateMultiAudioFocus(enabled); 14092 if (!enabled) { 14093 mDeviceBroker.postBroadcastBecomingNoisy(); 14094 } 14095 } 14096 } 14097 } 14098 14099 /** 14100 * @hide 14101 * Sets an additional audio output device delay in milliseconds. 14102 * 14103 * The additional output delay is a request to the output device to 14104 * delay audio presentation (generally with respect to video presentation for better 14105 * synchronization). 14106 * It may not be supported by all output devices, 14107 * and typically increases the audio latency by the amount of additional 14108 * audio delay requested. 14109 * 14110 * If additional audio delay is supported by an audio output device, 14111 * it is expected to be supported for all output streams (and configurations) 14112 * opened on that device. 14113 * 14114 * @param deviceType 14115 * @param address 14116 * @param delayMillis delay in milliseconds desired. This should be in range of {@code 0} 14117 * to the value returned by {@link #getMaxAdditionalOutputDeviceDelay()}. 14118 * @return true if successful, false if the device does not support output device delay 14119 * or the delay is not in range of {@link #getMaxAdditionalOutputDeviceDelay()}. 14120 */ 14121 @Override 14122 //@RequiresPermission(MODIFY_AUDIO_ROUTING) setAdditionalOutputDeviceDelay( @onNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis)14123 public boolean setAdditionalOutputDeviceDelay( 14124 @NonNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis) { 14125 Objects.requireNonNull(device, "device must not be null"); 14126 enforceModifyAudioRoutingPermission(); 14127 14128 device = retrieveBluetoothAddress(device); 14129 14130 final String getterKey = "additional_output_device_delay=" 14131 + device.getInternalType() + "," + device.getAddress(); // "getter" key as an id. 14132 final String setterKey = getterKey + "," + delayMillis; // append the delay for setter 14133 return mRestorableParameters.setParameters(getterKey, setterKey) 14134 == AudioSystem.AUDIO_STATUS_OK; 14135 } 14136 14137 /** 14138 * @hide 14139 * Returns the current additional audio output device delay in milliseconds. 14140 * 14141 * @param deviceType 14142 * @param address 14143 * @return the additional output device delay. This is a non-negative number. 14144 * {@code 0} is returned if unsupported. 14145 */ 14146 @Override 14147 @IntRange(from = 0) getAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)14148 public long getAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) { 14149 Objects.requireNonNull(device, "device must not be null"); 14150 14151 device = retrieveBluetoothAddress(device); 14152 14153 final String key = "additional_output_device_delay"; 14154 final String reply = AudioSystem.getParameters( 14155 key + "=" + device.getInternalType() + "," + device.getAddress()); 14156 long delayMillis; 14157 try { 14158 delayMillis = Long.parseLong(reply.substring(key.length() + 1)); 14159 } catch (NullPointerException e) { 14160 delayMillis = 0; 14161 } 14162 return delayMillis; 14163 } 14164 14165 /** 14166 * @hide 14167 * Returns the maximum additional audio output device delay in milliseconds. 14168 * 14169 * @param deviceType 14170 * @param address 14171 * @return the maximum output device delay in milliseconds that can be set. 14172 * This is a non-negative number 14173 * representing the additional audio delay supported for the device. 14174 * {@code 0} is returned if unsupported. 14175 */ 14176 @Override 14177 @IntRange(from = 0) getMaxAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)14178 public long getMaxAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) { 14179 Objects.requireNonNull(device, "device must not be null"); 14180 14181 device = retrieveBluetoothAddress(device); 14182 14183 final String key = "max_additional_output_device_delay"; 14184 final String reply = AudioSystem.getParameters( 14185 key + "=" + device.getInternalType() + "," + device.getAddress()); 14186 long delayMillis; 14187 try { 14188 delayMillis = Long.parseLong(reply.substring(key.length() + 1)); 14189 } catch (NullPointerException e) { 14190 delayMillis = 0; 14191 } 14192 return delayMillis; 14193 } 14194 14195 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 14196 /** @see AudioManager#addAssistantServicesUids(int []) */ 14197 @Override addAssistantServicesUids(int [] assistantUids)14198 public void addAssistantServicesUids(int [] assistantUids) { 14199 super.addAssistantServicesUids_enforcePermission(); 14200 14201 Objects.requireNonNull(assistantUids); 14202 14203 synchronized (mSettingsLock) { 14204 addAssistantServiceUidsLocked(assistantUids); 14205 } 14206 } 14207 14208 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 14209 /** @see AudioManager#removeAssistantServicesUids(int []) */ 14210 @Override removeAssistantServicesUids(int [] assistantUids)14211 public void removeAssistantServicesUids(int [] assistantUids) { 14212 super.removeAssistantServicesUids_enforcePermission(); 14213 14214 Objects.requireNonNull(assistantUids); 14215 synchronized (mSettingsLock) { 14216 removeAssistantServiceUidsLocked(assistantUids); 14217 } 14218 } 14219 14220 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 14221 /** @see AudioManager#getAssistantServicesUids() */ 14222 @Override getAssistantServicesUids()14223 public int[] getAssistantServicesUids() { 14224 super.getAssistantServicesUids_enforcePermission(); 14225 14226 int [] assistantUids; 14227 synchronized (mSettingsLock) { 14228 assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray(); 14229 } 14230 return assistantUids; 14231 } 14232 14233 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 14234 /** @see AudioManager#setActiveAssistantServiceUids(int []) */ 14235 @Override setActiveAssistantServiceUids(int [] activeAssistantUids)14236 public void setActiveAssistantServiceUids(int [] activeAssistantUids) { 14237 super.setActiveAssistantServiceUids_enforcePermission(); 14238 14239 Objects.requireNonNull(activeAssistantUids); 14240 synchronized (mSettingsLock) { 14241 mActiveAssistantServiceUids = activeAssistantUids; 14242 } 14243 updateActiveAssistantServiceUids(); 14244 } 14245 14246 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 14247 /** @see AudioManager#getActiveAssistantServiceUids() */ 14248 @Override getActiveAssistantServiceUids()14249 public int[] getActiveAssistantServiceUids() { 14250 super.getActiveAssistantServiceUids_enforcePermission(); 14251 14252 int [] activeAssistantUids; 14253 synchronized (mSettingsLock) { 14254 activeAssistantUids = mActiveAssistantServiceUids.clone(); 14255 } 14256 return activeAssistantUids; 14257 } 14258 getDeviceIdentityAddresses(AudioDeviceAttributes device)14259 List<String> getDeviceIdentityAddresses(AudioDeviceAttributes device) { 14260 return mDeviceBroker.getDeviceIdentityAddresses(device); 14261 } 14262 14263 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) getMusicFxHelper()14264 MusicFxHelper getMusicFxHelper() { 14265 return mMusicFxHelper; 14266 } 14267 14268 //====================== 14269 // misc 14270 //====================== 14271 private final HashMap<IBinder, AudioPolicyProxy> mAudioPolicies = 14272 new HashMap<IBinder, AudioPolicyProxy>(); 14273 @GuardedBy("mAudioPolicies") 14274 private int mAudioPolicyCounter = 0; 14275 14276 //====================== 14277 // Helper functions for full and fixed volume device 14278 //====================== isFixedVolumeDevice(int deviceType)14279 private boolean isFixedVolumeDevice(int deviceType) { 14280 if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX 14281 && mRecordMonitor.isLegacyRemoteSubmixActive()) { 14282 return false; 14283 } 14284 return mFixedVolumeDevices.contains(deviceType); 14285 } 14286 isFullVolumeDevice(int deviceType)14287 private boolean isFullVolumeDevice(int deviceType) { 14288 if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX 14289 && mRecordMonitor.isLegacyRemoteSubmixActive()) { 14290 return false; 14291 } 14292 return mFullVolumeDevices.contains(deviceType); 14293 } 14294 14295 /** 14296 * Returns whether the input device uses absolute volume behavior, including its variants. 14297 * For included volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}. 14298 * 14299 * This is distinct from Bluetooth A2DP absolute volume behavior 14300 * ({@link #isA2dpAbsoluteVolumeDevice}). 14301 */ isAbsoluteVolumeDevice(int deviceType)14302 private boolean isAbsoluteVolumeDevice(int deviceType) { 14303 return mAbsoluteVolumeDeviceInfoMap.containsKey(deviceType); 14304 } 14305 14306 /** 14307 * Returns whether the input device is a Bluetooth A2dp device that uses absolute volume 14308 * behavior. This is distinct from the general implementation of absolute volume behavior 14309 * ({@link #isAbsoluteVolumeDevice}). 14310 */ isA2dpAbsoluteVolumeDevice(int deviceType)14311 private boolean isA2dpAbsoluteVolumeDevice(int deviceType) { 14312 return mAvrcpAbsVolSupported && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType); 14313 } 14314 14315 //==================== 14316 // Helper functions for {set,get}DeviceVolumeBehavior 14317 //==================== getSettingsNameForDeviceVolumeBehavior(int deviceType)14318 private static String getSettingsNameForDeviceVolumeBehavior(int deviceType) { 14319 return "AudioService_DeviceVolumeBehavior_" + AudioSystem.getOutputDeviceName(deviceType); 14320 } 14321 persistDeviceVolumeBehavior(int deviceType, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior)14322 private void persistDeviceVolumeBehavior(int deviceType, 14323 @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) { 14324 if (DEBUG_VOL) { 14325 Log.d(TAG, "Persisting Volume Behavior for DeviceType: " + deviceType); 14326 } 14327 final long callingIdentity = Binder.clearCallingIdentity(); 14328 try { 14329 mSettings.putSystemIntForUser(mContentResolver, 14330 getSettingsNameForDeviceVolumeBehavior(deviceType), 14331 deviceVolumeBehavior, 14332 UserHandle.USER_CURRENT); 14333 } finally { 14334 Binder.restoreCallingIdentity(callingIdentity); 14335 } 14336 } 14337 14338 @AudioManager.DeviceVolumeBehaviorState retrieveStoredDeviceVolumeBehavior(int deviceType)14339 private int retrieveStoredDeviceVolumeBehavior(int deviceType) { 14340 return mSettings.getSystemIntForUser(mContentResolver, 14341 getSettingsNameForDeviceVolumeBehavior(deviceType), 14342 AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET, 14343 UserHandle.USER_CURRENT); 14344 } 14345 restoreDeviceVolumeBehavior()14346 private void restoreDeviceVolumeBehavior() { 14347 for (int deviceType : AudioSystem.DEVICE_OUT_ALL_SET) { 14348 if (DEBUG_VOL) { 14349 Log.d(TAG, "Retrieving Volume Behavior for DeviceType: " + deviceType); 14350 } 14351 int deviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(deviceType); 14352 if (deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) { 14353 if (DEBUG_VOL) { 14354 Log.d(TAG, "Skipping Setting Volume Behavior for DeviceType: " + deviceType); 14355 } 14356 continue; 14357 } 14358 14359 setDeviceVolumeBehaviorInternal(new AudioDeviceAttributes(deviceType, ""), 14360 deviceVolumeBehavior, "AudioService.restoreDeviceVolumeBehavior()"); 14361 } 14362 } 14363 14364 /** 14365 * @param audioSystemDeviceOut one of AudioSystem.DEVICE_OUT_* 14366 * @return whether {@code audioSystemDeviceOut} has previously been set to a specific volume 14367 * behavior 14368 */ hasDeviceVolumeBehavior( int audioSystemDeviceOut)14369 private boolean hasDeviceVolumeBehavior( 14370 int audioSystemDeviceOut) { 14371 return retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut) 14372 != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET; 14373 } 14374 addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut)14375 private boolean addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut) { 14376 if (DEBUG_VOL) { 14377 Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 14378 + " to mFixedVolumeDevices"); 14379 } 14380 return mFixedVolumeDevices.add(audioSystemDeviceOut); 14381 } 14382 removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut)14383 private boolean removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut) { 14384 if (DEBUG_VOL) { 14385 Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 14386 + " from mFixedVolumeDevices"); 14387 } 14388 return mFixedVolumeDevices.remove(audioSystemDeviceOut); 14389 } 14390 addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut)14391 private boolean addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut) { 14392 if (DEBUG_VOL) { 14393 Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 14394 + " to mFullVolumeDevices"); 14395 } 14396 return mFullVolumeDevices.add(audioSystemDeviceOut); 14397 } 14398 removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut)14399 private boolean removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut) { 14400 if (DEBUG_VOL) { 14401 Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 14402 + " from mFullVolumeDevices"); 14403 } 14404 return mFullVolumeDevices.remove(audioSystemDeviceOut); 14405 } 14406 addAudioSystemDeviceOutToAbsVolumeDevices(int audioSystemDeviceOut, AbsoluteVolumeDeviceInfo info)14407 private void addAudioSystemDeviceOutToAbsVolumeDevices(int audioSystemDeviceOut, 14408 AbsoluteVolumeDeviceInfo info) { 14409 if (DEBUG_VOL) { 14410 Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 14411 + " to mAbsoluteVolumeDeviceInfoMap with behavior " 14412 + AudioDeviceVolumeManager.volumeBehaviorName(info.mDeviceVolumeBehavior) 14413 ); 14414 } 14415 mAbsoluteVolumeDeviceInfoMap.put(audioSystemDeviceOut, info); 14416 } 14417 removeAudioSystemDeviceOutFromAbsVolumeDevices( int audioSystemDeviceOut)14418 private AbsoluteVolumeDeviceInfo removeAudioSystemDeviceOutFromAbsVolumeDevices( 14419 int audioSystemDeviceOut) { 14420 if (DEBUG_VOL) { 14421 Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 14422 + " from mAbsoluteVolumeDeviceInfoMap"); 14423 } 14424 return mAbsoluteVolumeDeviceInfoMap.remove(audioSystemDeviceOut); 14425 } 14426 14427 //==================== 14428 // Helper functions for app ops 14429 //==================== 14430 /** 14431 * Validates, and notes an app op for a given uid and package name. 14432 * Validation comes from exception catching: a security exception indicates the package 14433 * doesn't exist, an IAE indicates the uid and package don't match. The code only checks 14434 * if exception was thrown for robustness to code changes in op validation 14435 * @param op the app op to check 14436 * @param uid the uid of the caller 14437 * @param packageName the package to check 14438 * @return true if the origin of the call is valid (no uid / package mismatch) and the caller 14439 * is allowed to perform the operation 14440 */ checkNoteAppOp(int op, int uid, String packageName, String attributionTag)14441 private boolean checkNoteAppOp(int op, int uid, String packageName, String attributionTag) { 14442 try { 14443 if (mAppOps.noteOp(op, uid, packageName, attributionTag, null) 14444 != AppOpsManager.MODE_ALLOWED) { 14445 return false; 14446 } 14447 } catch (Exception e) { 14448 Log.e(TAG, "Error noting op:" + op + " on uid:" + uid + " for package:" 14449 + packageName, e); 14450 return false; 14451 } 14452 return true; 14453 } 14454 } 14455