1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.audio; 18 19 import static android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED; 20 import static android.Manifest.permission.REMOTE_AUDIO_PLAYBACK; 21 import static android.app.BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT; 22 import static android.media.AudioDeviceInfo.TYPE_BLE_HEADSET; 23 import static android.media.AudioDeviceInfo.TYPE_BLE_SPEAKER; 24 import static android.media.AudioDeviceInfo.TYPE_BLUETOOTH_A2DP; 25 import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES; 26 import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_UNKNOWN; 27 import static android.media.AudioManager.DEVICE_OUT_BLE_HEADSET; 28 import static android.media.AudioManager.DEVICE_OUT_BLE_SPEAKER; 29 import static android.media.AudioManager.DEVICE_OUT_BLUETOOTH_A2DP; 30 import static android.media.AudioManager.RINGER_MODE_NORMAL; 31 import static android.media.AudioManager.RINGER_MODE_SILENT; 32 import static android.media.AudioManager.RINGER_MODE_VIBRATE; 33 import static android.media.AudioManager.STREAM_MUSIC; 34 import static android.media.AudioManager.STREAM_SYSTEM; 35 import static android.os.Process.FIRST_APPLICATION_UID; 36 import static android.os.Process.INVALID_UID; 37 import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE; 38 import static android.provider.Settings.Secure.VOLUME_HUSH_OFF; 39 import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE; 40 41 import static com.android.server.audio.SoundDoseHelper.ACTION_CHECK_MUSIC_ACTIVE; 42 import static com.android.server.utils.EventLogger.Event.ALOGE; 43 import static com.android.server.utils.EventLogger.Event.ALOGI; 44 import static com.android.server.utils.EventLogger.Event.ALOGW; 45 46 import android.Manifest; 47 import android.annotation.IntDef; 48 import android.annotation.IntRange; 49 import android.annotation.NonNull; 50 import android.annotation.Nullable; 51 import android.annotation.RequiresPermission; 52 import android.annotation.SuppressLint; 53 import android.annotation.UserIdInt; 54 import android.app.ActivityManager; 55 import android.app.ActivityManagerInternal; 56 import android.app.AppGlobals; 57 import android.app.AppOpsManager; 58 import android.app.BroadcastOptions; 59 import android.app.IUidObserver; 60 import android.app.NotificationManager; 61 import android.app.UidObserver; 62 import android.app.role.OnRoleHoldersChangedListener; 63 import android.app.role.RoleManager; 64 import android.bluetooth.BluetoothDevice; 65 import android.bluetooth.BluetoothHeadset; 66 import android.bluetooth.BluetoothProfile; 67 import android.content.BroadcastReceiver; 68 import android.content.ComponentName; 69 import android.content.ContentResolver; 70 import android.content.Context; 71 import android.content.Intent; 72 import android.content.IntentFilter; 73 import android.content.pm.ApplicationInfo; 74 import android.content.pm.PackageInfo; 75 import android.content.pm.PackageManager; 76 import android.content.pm.ResolveInfo; 77 import android.content.pm.UserInfo; 78 import android.content.res.Configuration; 79 import android.content.res.Resources; 80 import android.database.ContentObserver; 81 import android.hardware.SensorPrivacyManager; 82 import android.hardware.SensorPrivacyManagerInternal; 83 import android.hardware.hdmi.HdmiAudioSystemClient; 84 import android.hardware.hdmi.HdmiClient; 85 import android.hardware.hdmi.HdmiControlManager; 86 import android.hardware.hdmi.HdmiPlaybackClient; 87 import android.hardware.hdmi.HdmiTvClient; 88 import android.hardware.input.InputManager; 89 import android.hardware.usb.UsbManager; 90 import android.hidl.manager.V1_0.IServiceManager; 91 import android.media.AudioAttributes; 92 import android.media.AudioAttributes.AttributeSystemUsage; 93 import android.media.AudioDeviceAttributes; 94 import android.media.AudioDeviceInfo; 95 import android.media.AudioDeviceVolumeManager; 96 import android.media.AudioFocusInfo; 97 import android.media.AudioFocusRequest; 98 import android.media.AudioFormat; 99 import android.media.AudioHalVersionInfo; 100 import android.media.AudioManager; 101 import android.media.AudioManager.AudioDeviceCategory; 102 import android.media.AudioManagerInternal; 103 import android.media.AudioMixerAttributes; 104 import android.media.AudioPlaybackConfiguration; 105 import android.media.AudioRecordingConfiguration; 106 import android.media.AudioRoutesInfo; 107 import android.media.AudioSystem; 108 import android.media.BluetoothProfileConnectionInfo; 109 import android.media.IAudioDeviceVolumeDispatcher; 110 import android.media.IAudioFocusDispatcher; 111 import android.media.IAudioModeDispatcher; 112 import android.media.IAudioRoutesObserver; 113 import android.media.IAudioServerStateDispatcher; 114 import android.media.IAudioService; 115 import android.media.ICapturePresetDevicesRoleDispatcher; 116 import android.media.ICommunicationDeviceDispatcher; 117 import android.media.IDeviceVolumeBehaviorDispatcher; 118 import android.media.IDevicesForAttributesCallback; 119 import android.media.IMuteAwaitConnectionCallback; 120 import android.media.IPlaybackConfigDispatcher; 121 import android.media.IPreferredMixerAttributesDispatcher; 122 import android.media.IRecordingConfigDispatcher; 123 import android.media.IRingtonePlayer; 124 import android.media.ISpatializerCallback; 125 import android.media.ISpatializerHeadToSoundStagePoseCallback; 126 import android.media.ISpatializerHeadTrackerAvailableCallback; 127 import android.media.ISpatializerHeadTrackingModeCallback; 128 import android.media.ISpatializerOutputCallback; 129 import android.media.IStrategyNonDefaultDevicesDispatcher; 130 import android.media.IStrategyPreferredDevicesDispatcher; 131 import android.media.IStreamAliasingDispatcher; 132 import android.media.IVolumeController; 133 import android.media.MediaMetrics; 134 import android.media.MediaRecorder.AudioSource; 135 import android.media.PlayerBase; 136 import android.media.Spatializer; 137 import android.media.VolumeInfo; 138 import android.media.VolumePolicy; 139 import android.media.audiofx.AudioEffect; 140 import android.media.audiopolicy.AudioMix; 141 import android.media.audiopolicy.AudioPolicy; 142 import android.media.audiopolicy.AudioPolicyConfig; 143 import android.media.audiopolicy.AudioProductStrategy; 144 import android.media.audiopolicy.AudioVolumeGroup; 145 import android.media.audiopolicy.IAudioPolicyCallback; 146 import android.media.permission.ClearCallingIdentityContext; 147 import android.media.permission.SafeCloseable; 148 import android.media.projection.IMediaProjection; 149 import android.media.projection.IMediaProjectionCallback; 150 import android.media.projection.IMediaProjectionManager; 151 import android.net.Uri; 152 import android.os.Binder; 153 import android.os.Build; 154 import android.os.Bundle; 155 import android.os.Handler; 156 import android.os.HwBinder; 157 import android.os.IBinder; 158 import android.os.Looper; 159 import android.os.Message; 160 import android.os.PermissionEnforcer; 161 import android.os.PersistableBundle; 162 import android.os.PowerManager; 163 import android.os.Process; 164 import android.os.RemoteCallbackList; 165 import android.os.RemoteException; 166 import android.os.ResultReceiver; 167 import android.os.ServiceDebugInfo; 168 import android.os.ServiceManager; 169 import android.os.ShellCallback; 170 import android.os.SystemClock; 171 import android.os.SystemProperties; 172 import android.os.UserHandle; 173 import android.os.UserManager; 174 import android.os.VibrationAttributes; 175 import android.os.VibrationEffect; 176 import android.os.Vibrator; 177 import android.os.VibratorManager; 178 import android.provider.Settings; 179 import android.provider.Settings.System; 180 import android.service.notification.ZenModeConfig; 181 import android.telecom.TelecomManager; 182 import android.telephony.SubscriptionManager; 183 import android.text.TextUtils; 184 import android.util.AndroidRuntimeException; 185 import android.util.ArrayMap; 186 import android.util.ArraySet; 187 import android.util.IntArray; 188 import android.util.Log; 189 import android.util.PrintWriterPrinter; 190 import android.util.Slog; 191 import android.util.SparseArray; 192 import android.util.SparseIntArray; 193 import android.view.KeyEvent; 194 import android.view.accessibility.AccessibilityManager; 195 import android.widget.Toast; 196 197 import com.android.internal.annotations.GuardedBy; 198 import com.android.internal.annotations.VisibleForTesting; 199 import com.android.internal.os.SomeArgs; 200 import com.android.internal.util.DumpUtils; 201 import com.android.internal.util.Preconditions; 202 import com.android.server.EventLogTags; 203 import com.android.server.LocalServices; 204 import com.android.server.SystemService; 205 import com.android.server.audio.AudioServiceEvents.DeviceVolumeEvent; 206 import com.android.server.audio.AudioServiceEvents.PhoneStateEvent; 207 import com.android.server.audio.AudioServiceEvents.VolChangedBroadcastEvent; 208 import com.android.server.audio.AudioServiceEvents.VolumeEvent; 209 import com.android.server.pm.UserManagerInternal; 210 import com.android.server.pm.UserManagerInternal.UserRestrictionsListener; 211 import com.android.server.pm.UserManagerService; 212 import com.android.server.utils.EventLogger; 213 import com.android.server.wm.ActivityTaskManagerInternal; 214 215 import java.io.FileDescriptor; 216 import java.io.PrintWriter; 217 import java.lang.annotation.Retention; 218 import java.lang.annotation.RetentionPolicy; 219 import java.text.SimpleDateFormat; 220 import java.util.ArrayList; 221 import java.util.Arrays; 222 import java.util.Collection; 223 import java.util.Date; 224 import java.util.HashMap; 225 import java.util.HashSet; 226 import java.util.Iterator; 227 import java.util.LinkedHashMap; 228 import java.util.List; 229 import java.util.Map; 230 import java.util.NoSuchElementException; 231 import java.util.Objects; 232 import java.util.Set; 233 import java.util.TreeSet; 234 import java.util.UUID; 235 import java.util.concurrent.Executor; 236 import java.util.concurrent.atomic.AtomicBoolean; 237 import java.util.concurrent.atomic.AtomicInteger; 238 import java.util.function.BooleanSupplier; 239 import java.util.stream.Collectors; 240 241 /** 242 * The implementation of the audio service for volume, audio focus, device management... 243 * <p> 244 * This implementation focuses on delivering a responsive UI. Most methods are 245 * asynchronous to external calls. For example, the task of setting a volume 246 * will update our internal state, but in a separate thread will set the system 247 * volume and later persist to the database. Similarly, setting the ringer mode 248 * will update the state and broadcast a change and in a separate thread later 249 * persist the ringer mode. 250 * 251 * @hide 252 */ 253 public class AudioService extends IAudioService.Stub 254 implements AccessibilityManager.TouchExplorationStateChangeListener, 255 AccessibilityManager.AccessibilityServicesStateChangeListener, 256 AudioSystemAdapter.OnRoutingUpdatedListener, 257 AudioSystemAdapter.OnVolRangeInitRequestListener { 258 259 private static final String TAG = "AS.AudioService"; 260 261 private final AudioSystemAdapter mAudioSystem; 262 private final SystemServerAdapter mSystemServer; 263 private final SettingsAdapter mSettings; 264 private final AudioPolicyFacade mAudioPolicy; 265 266 /** Debug audio mode */ 267 protected static final boolean DEBUG_MODE = false; 268 269 /** Debug audio policy feature */ 270 protected static final boolean DEBUG_AP = false; 271 272 /** Debug volumes */ 273 protected static final boolean DEBUG_VOL = false; 274 275 /** debug calls to devices APIs */ 276 protected static final boolean DEBUG_DEVICES = false; 277 278 /** Debug communication route */ 279 protected static final boolean DEBUG_COMM_RTE = false; 280 281 /** Debug log sound fx (touchsounds...) in dumpsys */ 282 protected static final boolean DEBUG_LOG_SOUND_FX = false; 283 284 /** How long to delay before persisting a change in volume/ringer mode. */ 285 private static final int PERSIST_DELAY = 500; 286 287 /** How long to delay after a volume down event before unmuting a stream */ 288 private static final int UNMUTE_STREAM_DELAY = 350; 289 290 /** 291 * Delay before disconnecting a device that would cause BECOMING_NOISY intent to be sent, 292 * to give a chance to applications to pause. 293 */ 294 @VisibleForTesting 295 public static final int BECOMING_NOISY_DELAY_MS = 1000; 296 297 /** 298 * Only used in the result from {@link #checkForRingerModeChange(int, int, int)} 299 */ 300 private static final int FLAG_ADJUST_VOLUME = 1; 301 302 final Context mContext; 303 private final ContentResolver mContentResolver; 304 private final AppOpsManager mAppOps; 305 306 // the platform type affects volume and silent mode behavior 307 private final int mPlatformType; 308 309 // indicates whether the system maps all streams to a single stream. 310 private final boolean mIsSingleVolume; 311 312 /** 313 * indicates whether STREAM_NOTIFICATION is aliased to STREAM_RING 314 * not final due to test method, see {@link #setNotifAliasRingForTest(boolean)}. 315 */ 316 private boolean mNotifAliasRing = false; 317 318 /** 319 * Test method to temporarily override whether STREAM_NOTIFICATION is aliased to STREAM_RING, 320 * volumes will be updated in case of a change. 321 * @param alias if true, STREAM_NOTIFICATION is aliased to STREAM_RING 322 */ 323 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setNotifAliasRingForTest(boolean alias)324 public void setNotifAliasRingForTest(boolean alias) { 325 super.setNotifAliasRingForTest_enforcePermission(); 326 boolean update = (mNotifAliasRing != alias); 327 mNotifAliasRing = alias; 328 if (update) { 329 updateStreamVolumeAlias(true, "AudioServiceTest"); 330 } 331 } 332 isPlatformVoice()333 /*package*/ boolean isPlatformVoice() { 334 return mPlatformType == AudioSystem.PLATFORM_VOICE; 335 } 336 isPlatformTelevision()337 /*package*/ boolean isPlatformTelevision() { 338 return mPlatformType == AudioSystem.PLATFORM_TELEVISION; 339 } 340 isPlatformAutomotive()341 /*package*/ boolean isPlatformAutomotive() { 342 return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); 343 } 344 345 /** The controller for the volume UI. */ 346 private final VolumeController mVolumeController = new VolumeController(); 347 348 // sendMsg() flags 349 /** If the msg is already queued, replace it with this one. */ 350 private static final int SENDMSG_REPLACE = 0; 351 /** If the msg is already queued, ignore this one and leave the old. */ 352 private static final int SENDMSG_NOOP = 1; 353 /** If the msg is already queued, queue this one and leave the old. */ 354 private static final int SENDMSG_QUEUE = 2; 355 356 // AudioHandler messages 357 /*package*/ static final int MSG_SET_DEVICE_VOLUME = 0; 358 private static final int MSG_PERSIST_VOLUME = 1; 359 private static final int MSG_PERSIST_VOLUME_GROUP = 2; 360 private static final int MSG_PERSIST_RINGER_MODE = 3; 361 private static final int MSG_AUDIO_SERVER_DIED = 4; 362 private static final int MSG_PLAY_SOUND_EFFECT = 5; 363 private static final int MSG_LOAD_SOUND_EFFECTS = 7; 364 private static final int MSG_SET_FORCE_USE = 8; 365 private static final int MSG_SET_ALL_VOLUMES = 10; 366 private static final int MSG_UNLOAD_SOUND_EFFECTS = 15; 367 private static final int MSG_SYSTEM_READY = 16; 368 private static final int MSG_UNMUTE_STREAM = 18; 369 private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 19; 370 private static final int MSG_INDICATE_SYSTEM_READY = 20; 371 private static final int MSG_ACCESSORY_PLUG_MEDIA_UNMUTE = 21; 372 private static final int MSG_NOTIFY_VOL_EVENT = 22; 373 private static final int MSG_DISPATCH_AUDIO_SERVER_STATE = 23; 374 private static final int MSG_ENABLE_SURROUND_FORMATS = 24; 375 private static final int MSG_UPDATE_RINGER_MODE = 25; 376 private static final int MSG_SET_DEVICE_STREAM_VOLUME = 26; 377 private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27; 378 private static final int MSG_HDMI_VOLUME_CHECK = 28; 379 private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29; 380 private static final int MSG_BROADCAST_MICROPHONE_MUTE = 30; 381 private static final int MSG_CHECK_MODE_FOR_UID = 31; 382 private static final int MSG_STREAM_DEVICES_CHANGED = 32; 383 private static final int MSG_UPDATE_VOLUME_STATES_FOR_DEVICE = 33; 384 private static final int MSG_REINIT_VOLUMES = 34; 385 private static final int MSG_UPDATE_A11Y_SERVICE_UIDS = 35; 386 private static final int MSG_UPDATE_AUDIO_MODE = 36; 387 private static final int MSG_RECORDING_CONFIG_CHANGE = 37; 388 private static final int MSG_BT_DEV_CHANGED = 38; 389 390 private static final int MSG_DISPATCH_AUDIO_MODE = 40; 391 private static final int MSG_ROUTING_UPDATED = 41; 392 private static final int MSG_INIT_HEADTRACKING_SENSORS = 42; 393 private static final int MSG_ADD_ASSISTANT_SERVICE_UID = 44; 394 private static final int MSG_REMOVE_ASSISTANT_SERVICE_UID = 45; 395 private static final int MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID = 46; 396 private static final int MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR = 47; 397 private static final int MSG_ROTATION_UPDATE = 48; 398 private static final int MSG_FOLD_UPDATE = 49; 399 private static final int MSG_RESET_SPATIALIZER = 50; 400 private static final int MSG_NO_LOG_FOR_PLAYER_I = 51; 401 private static final int MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES = 52; 402 private static final int MSG_LOWER_VOLUME_TO_RS1 = 53; 403 private static final int MSG_CONFIGURATION_CHANGED = 54; 404 405 /** Messages handled by the {@link SoundDoseHelper}. */ 406 /*package*/ static final int SAFE_MEDIA_VOLUME_MSG_START = 1000; 407 408 // start of messages handled under wakelock 409 // these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(), 410 // and not with sendMsg(..., ..., SENDMSG_QUEUE, ...) 411 private static final int MSG_DISABLE_AUDIO_FOR_UID = 100; 412 private static final int MSG_INIT_STREAMS_VOLUMES = 101; 413 private static final int MSG_INIT_SPATIALIZER = 102; 414 private static final int MSG_INIT_ADI_DEVICE_STATES = 103; 415 416 // end of messages handled under wakelock 417 418 // retry delay in case of failure to indicate system ready to AudioFlinger 419 private static final int INDICATE_SYSTEM_READY_RETRY_DELAY_MS = 1000; 420 421 // List of empty UIDs used to reset the active assistant list 422 private static final int[] NO_ACTIVE_ASSISTANT_SERVICE_UIDS = new int[0]; 423 424 // check playback or record activity every 6 seconds for UIDs owning mode IN_COMMUNICATION 425 private static final int CHECK_MODE_FOR_UID_PERIOD_MS = 6000; 426 427 /** @see AudioSystemThread */ 428 private AudioSystemThread mAudioSystemThread; 429 /** @see AudioHandler */ 430 private AudioHandler mAudioHandler; 431 /** @see VolumeStreamState */ 432 private VolumeStreamState[] mStreamStates; 433 getVssVolumeForDevice(int stream, int device)434 /*package*/ int getVssVolumeForDevice(int stream, int device) { 435 return mStreamStates[stream].getIndex(device); 436 } 437 getVssVolumeForStream(int stream)438 /*package*/ VolumeStreamState getVssVolumeForStream(int stream) { 439 return mStreamStates[stream]; 440 } 441 getMaxVssVolumeForStream(int stream)442 /*package*/ int getMaxVssVolumeForStream(int stream) { 443 return mStreamStates[stream].getMaxIndex(); 444 } 445 446 private SettingsObserver mSettingsObserver; 447 448 private AtomicInteger mMode = new AtomicInteger(AudioSystem.MODE_NORMAL); 449 450 // protects mRingerMode 451 private final Object mSettingsLock = new Object(); 452 453 /** Maximum volume index values for audio streams */ 454 protected static int[] MAX_STREAM_VOLUME = new int[] { 455 5, // STREAM_VOICE_CALL 456 7, // STREAM_SYSTEM 457 7, // STREAM_RING // configured by config_audio_ring_vol_steps 458 15, // STREAM_MUSIC 459 7, // STREAM_ALARM 460 7, // STREAM_NOTIFICATION // configured by config_audio_notif_vol_steps 461 15, // STREAM_BLUETOOTH_SCO 462 7, // STREAM_SYSTEM_ENFORCED 463 15, // STREAM_DTMF 464 15, // STREAM_TTS 465 15, // STREAM_ACCESSIBILITY 466 15 // STREAM_ASSISTANT 467 }; 468 469 /** Minimum volume index values for audio streams */ 470 protected static int[] MIN_STREAM_VOLUME = new int[] { 471 1, // STREAM_VOICE_CALL 472 0, // STREAM_SYSTEM 473 0, // STREAM_RING 474 0, // STREAM_MUSIC 475 1, // STREAM_ALARM 476 0, // STREAM_NOTIFICATION 477 0, // STREAM_BLUETOOTH_SCO 478 0, // STREAM_SYSTEM_ENFORCED 479 0, // STREAM_DTMF 480 0, // STREAM_TTS 481 1, // STREAM_ACCESSIBILITY 482 0 // STREAM_ASSISTANT 483 }; 484 485 /* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings 486 * of another stream: This avoids multiplying the volume settings for hidden 487 * stream types that follow other stream behavior for volume settings 488 * NOTE: do not create loops in aliases! 489 * Some streams alias to different streams according to device category (phone or tablet) or 490 * use case (in call vs off call...). See updateStreamVolumeAlias() for more details. 491 * mStreamVolumeAlias contains STREAM_VOLUME_ALIAS_VOICE aliases for a voice capable device 492 * (phone), STREAM_VOLUME_ALIAS_TELEVISION for a television or set-top box and 493 * STREAM_VOLUME_ALIAS_DEFAULT for other devices (e.g. tablets).*/ 494 private final int[] STREAM_VOLUME_ALIAS_VOICE = new int[] { 495 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 496 AudioSystem.STREAM_RING, // STREAM_SYSTEM 497 AudioSystem.STREAM_RING, // STREAM_RING 498 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 499 AudioSystem.STREAM_ALARM, // STREAM_ALARM 500 AudioSystem.STREAM_RING, // STREAM_NOTIFICATION 501 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 502 AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED 503 AudioSystem.STREAM_RING, // STREAM_DTMF 504 AudioSystem.STREAM_MUSIC, // STREAM_TTS 505 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 506 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 507 }; 508 private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] { 509 AudioSystem.STREAM_MUSIC, // STREAM_VOICE_CALL 510 AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM 511 AudioSystem.STREAM_MUSIC, // STREAM_RING 512 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 513 AudioSystem.STREAM_MUSIC, // STREAM_ALARM 514 AudioSystem.STREAM_MUSIC, // STREAM_NOTIFICATION 515 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 516 AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM_ENFORCED 517 AudioSystem.STREAM_MUSIC, // STREAM_DTMF 518 AudioSystem.STREAM_MUSIC, // STREAM_TTS 519 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 520 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 521 }; 522 /** 523 * Using Volume groups configuration allows to control volume per attributes 524 * and group definition may differ from stream aliases. 525 * So, do not alias any stream on one another when using volume groups. 526 * TODO(b/181140246): volume group definition hosting alias definition. 527 */ 528 private final int[] STREAM_VOLUME_ALIAS_NONE = new int[] { 529 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 530 AudioSystem.STREAM_SYSTEM, // STREAM_SYSTEM 531 AudioSystem.STREAM_RING, // STREAM_RING 532 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 533 AudioSystem.STREAM_ALARM, // STREAM_ALARM 534 AudioSystem.STREAM_NOTIFICATION, // STREAM_NOTIFICATION 535 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 536 AudioSystem.STREAM_SYSTEM_ENFORCED, // STREAM_SYSTEM_ENFORCED 537 AudioSystem.STREAM_DTMF, // STREAM_DTMF 538 AudioSystem.STREAM_TTS, // STREAM_TTS 539 AudioSystem.STREAM_ACCESSIBILITY, // STREAM_ACCESSIBILITY 540 AudioSystem.STREAM_ASSISTANT // STREAM_ASSISTANT 541 }; 542 private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] { 543 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 544 AudioSystem.STREAM_RING, // STREAM_SYSTEM 545 AudioSystem.STREAM_RING, // STREAM_RING 546 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 547 AudioSystem.STREAM_ALARM, // STREAM_ALARM 548 AudioSystem.STREAM_RING, // STREAM_NOTIFICATION 549 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 550 AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED 551 AudioSystem.STREAM_RING, // STREAM_DTMF 552 AudioSystem.STREAM_MUSIC, // STREAM_TTS 553 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 554 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 555 }; 556 protected static int[] mStreamVolumeAlias; 557 private static final int UNSET_INDEX = -1; 558 559 /** 560 * Map AudioSystem.STREAM_* constants to app ops. This should be used 561 * after mapping through mStreamVolumeAlias. 562 */ 563 private static final int[] STREAM_VOLUME_OPS = new int[] { 564 AppOpsManager.OP_AUDIO_VOICE_VOLUME, // STREAM_VOICE_CALL 565 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_SYSTEM 566 AppOpsManager.OP_AUDIO_RING_VOLUME, // STREAM_RING 567 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_MUSIC 568 AppOpsManager.OP_AUDIO_ALARM_VOLUME, // STREAM_ALARM 569 AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME, // STREAM_NOTIFICATION 570 AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME, // STREAM_BLUETOOTH_SCO 571 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_SYSTEM_ENFORCED 572 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_DTMF 573 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_TTS 574 AppOpsManager.OP_AUDIO_ACCESSIBILITY_VOLUME, // STREAM_ACCESSIBILITY 575 AppOpsManager.OP_AUDIO_MEDIA_VOLUME // STREAM_ASSISTANT 576 }; 577 578 private final boolean mUseFixedVolume; 579 private final boolean mUseVolumeGroupAliases; 580 581 // If absolute volume is supported in AVRCP device 582 private volatile boolean mAvrcpAbsVolSupported = false; 583 584 /** 585 * Default stream type used for volume control in the absence of playback 586 * e.g. user on homescreen, no app playing anything, presses hardware volume buttons, this 587 * stream type is controlled. 588 */ 589 protected static final int DEFAULT_VOL_STREAM_NO_PLAYBACK = AudioSystem.STREAM_MUSIC; 590 591 private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() { 592 public void onError(int error) { 593 switch (error) { 594 case AudioSystem.AUDIO_STATUS_SERVER_DIED: 595 // check for null in case error callback is called during instance creation 596 if (mRecordMonitor != null) { 597 mRecordMonitor.onAudioServerDied(); 598 } 599 // Notify the playback monitor that the audio server has died 600 if (mPlaybackMonitor != null) { 601 mPlaybackMonitor.onAudioServerDied(); 602 } 603 sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, 604 SENDMSG_NOOP, 0, 0, null, 0); 605 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE, 606 SENDMSG_QUEUE, 0, 0, null, 0); 607 break; 608 default: 609 break; 610 } 611 } 612 }; 613 614 /** 615 * Current ringer mode from one of {@link AudioManager#RINGER_MODE_NORMAL}, 616 * {@link AudioManager#RINGER_MODE_SILENT}, or 617 * {@link AudioManager#RINGER_MODE_VIBRATE}. 618 */ 619 @GuardedBy("mSettingsLock") 620 private int mRingerMode; // internal ringer mode, affects muting of underlying streams 621 @GuardedBy("mSettingsLock") 622 private int mRingerModeExternal = -1; // reported ringer mode to outside clients (AudioManager) 623 624 /** @see System#MODE_RINGER_STREAMS_AFFECTED */ 625 private int mRingerModeAffectedStreams = 0; 626 627 private int mZenModeAffectedStreams = 0; 628 629 // Streams currently muted by ringer mode and dnd 630 protected static volatile int sRingerAndZenModeMutedStreams; 631 632 /** Streams that can be muted. Do not resolve to aliases when checking. 633 * @see System#MUTE_STREAMS_AFFECTED */ 634 private int mMuteAffectedStreams; 635 636 @NonNull 637 private SoundEffectsHelper mSfxHelper; 638 639 /** 640 * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated. 641 * mVibrateSetting is just maintained during deprecation period but vibration policy is 642 * now only controlled by mHasVibrator and mRingerMode 643 */ 644 private int mVibrateSetting; 645 646 // Is there a vibrator 647 private final boolean mHasVibrator; 648 // Used to play vibrations 649 private Vibrator mVibrator; 650 private static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES = 651 VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH); 652 653 // Broadcast receiver for device connections intent broadcasts 654 private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver(); 655 656 private IMediaProjectionManager mProjectionService; // to validate projection token 657 658 /** Interface for UserManagerService. */ 659 private final UserManagerInternal mUserManagerInternal; 660 private final ActivityManagerInternal mActivityManagerInternal; 661 private final SensorPrivacyManagerInternal mSensorPrivacyManagerInternal; 662 663 private final UserRestrictionsListener mUserRestrictionsListener = 664 new AudioServiceUserRestrictionsListener(); 665 666 // List of binder death handlers for setMode() client processes. 667 // The last process to have called setMode() is at the top of the list. 668 // package-private so it can be accessed in AudioDeviceBroker.getSetModeDeathHandlers 669 //TODO candidate to be moved to separate class that handles synchronization 670 @GuardedBy("mDeviceBroker.mSetModeLock") 671 /*package*/ final ArrayList<SetModeDeathHandler> mSetModeDeathHandlers = 672 new ArrayList<SetModeDeathHandler>(); 673 674 // true if boot sequence has been completed 675 private boolean mSystemReady; 676 // true if Intent.ACTION_USER_SWITCHED has ever been received 677 private boolean mUserSwitchedReceived; 678 // previous volume adjustment direction received by checkForRingerModeChange() 679 private int mPrevVolDirection = AudioManager.ADJUST_SAME; 680 // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume 681 // is controlled by Vol keys. 682 private int mVolumeControlStream = -1; 683 // interpretation of whether the volume stream has been selected by the user by clicking on a 684 // volume slider to change which volume is controlled by the volume keys. Is false 685 // when mVolumeControlStream is -1. 686 private boolean mUserSelectedVolumeControlStream = false; 687 private final Object mForceControlStreamLock = new Object(); 688 // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system 689 // server process so in theory it is not necessary to monitor the client death. 690 // However it is good to be ready for future evolutions. 691 private ForceControlStreamClient mForceControlStreamClient = null; 692 // Used to play ringtones outside system_server 693 private volatile IRingtonePlayer mRingtonePlayer; 694 695 // Devices for which the volume is fixed (volume is either max or muted) 696 Set<Integer> mFixedVolumeDevices = new HashSet<>(Arrays.asList( 697 AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, 698 AudioSystem.DEVICE_OUT_AUX_LINE)); 699 // Devices for which the volume is always max, no volume panel 700 Set<Integer> mFullVolumeDevices = new HashSet<>(Arrays.asList( 701 AudioSystem.DEVICE_OUT_HDMI_ARC, 702 AudioSystem.DEVICE_OUT_HDMI_EARC 703 )); 704 705 // Devices where the framework sends a full scale audio signal, and controls the volume of 706 // the external audio system separately. 707 // For possible volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}. 708 Map<Integer, AbsoluteVolumeDeviceInfo> mAbsoluteVolumeDeviceInfoMap = new ArrayMap<>(); 709 710 /** 711 * Stores information about a device using absolute volume behavior. 712 */ 713 private static final class AbsoluteVolumeDeviceInfo { 714 private final AudioDeviceAttributes mDevice; 715 private final List<VolumeInfo> mVolumeInfos; 716 private final IAudioDeviceVolumeDispatcher mCallback; 717 private final boolean mHandlesVolumeAdjustment; 718 private @AudioManager.AbsoluteDeviceVolumeBehavior int mDeviceVolumeBehavior; 719 AbsoluteVolumeDeviceInfo( AudioDeviceAttributes device, List<VolumeInfo> volumeInfos, IAudioDeviceVolumeDispatcher callback, boolean handlesVolumeAdjustment, @AudioManager.AbsoluteDeviceVolumeBehavior int behavior)720 private AbsoluteVolumeDeviceInfo( 721 AudioDeviceAttributes device, 722 List<VolumeInfo> volumeInfos, 723 IAudioDeviceVolumeDispatcher callback, 724 boolean handlesVolumeAdjustment, 725 @AudioManager.AbsoluteDeviceVolumeBehavior int behavior) { 726 this.mDevice = device; 727 this.mVolumeInfos = volumeInfos; 728 this.mCallback = callback; 729 this.mHandlesVolumeAdjustment = handlesVolumeAdjustment; 730 this.mDeviceVolumeBehavior = behavior; 731 } 732 733 /** 734 * Given a stream type, returns a matching VolumeInfo. 735 */ 736 @Nullable getMatchingVolumeInfoForStream(int streamType)737 private VolumeInfo getMatchingVolumeInfoForStream(int streamType) { 738 for (VolumeInfo volumeInfo : mVolumeInfos) { 739 boolean streamTypeMatches = volumeInfo.hasStreamType() 740 && volumeInfo.getStreamType() == streamType; 741 boolean volumeGroupMatches = volumeInfo.hasVolumeGroup() 742 && Arrays.stream(volumeInfo.getVolumeGroup().getLegacyStreamTypes()) 743 .anyMatch(s -> s == streamType); 744 if (streamTypeMatches || volumeGroupMatches) { 745 return volumeInfo; 746 } 747 } 748 return null; 749 } 750 } 751 752 // Devices for the which use the "absolute volume" concept (framework sends audio signal 753 // full scale, and volume control separately) and can be used for multiple use cases reflected 754 // by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL). 755 Set<Integer> mAbsVolumeMultiModeCaseDevices = new HashSet<>( 756 Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID)); 757 758 private final boolean mMonitorRotation; 759 760 private boolean mDockAudioMediaEnabled = true; 761 762 /** 763 * RestorableParameters is a thread-safe class used to store a 764 * first-in first-out history of parameters for replay / restoration. 765 * 766 * The idealized implementation of restoration would have a list of setting methods and 767 * values to be called for restoration. Explicitly managing such setters and 768 * values would be tedious - a simpler method is to store the values and the 769 * method implicitly by lambda capture (the values must be immutable or synchronization 770 * needs to be taken). 771 * 772 * We provide queueRestoreWithRemovalIfTrue() to allow 773 * the caller to provide a BooleanSupplier lambda, which conveniently packages 774 * the setter and its parameters needed for restoration. If during restoration, 775 * the BooleanSupplier returns true, e.g. on error, it is removed from the mMap 776 * so as not to be called on a subsequent restore. 777 * 778 * We provide a setParameters() method as an example helper method. 779 */ 780 private static class RestorableParameters { 781 /** 782 * Sets a parameter and queues for restoration if successful. 783 * 784 * @param id a string handle associated with this parameter. 785 * @param parameter the actual parameter string. 786 * @return the result of AudioSystem.setParameters 787 */ setParameters(@onNull String id, @NonNull String parameter)788 public int setParameters(@NonNull String id, @NonNull String parameter) { 789 Objects.requireNonNull(id, "id must not be null"); 790 Objects.requireNonNull(parameter, "parameter must not be null"); 791 synchronized (mMap) { 792 final int status = AudioSystem.setParameters(parameter); 793 if (status == AudioSystem.AUDIO_STATUS_OK) { // Java uses recursive mutexes. 794 queueRestoreWithRemovalIfTrue(id, () -> { // remove me if set fails. 795 return AudioSystem.setParameters(parameter) != AudioSystem.AUDIO_STATUS_OK; 796 }); 797 } 798 // Implementation detail: We do not mMap.remove(id); on failure. 799 return status; 800 } 801 } 802 803 /** 804 * Queues a restore method which is executed on restoreAll(). 805 * 806 * If the supplier null, the id is removed from the restore map. 807 * 808 * Note: When the BooleanSupplier restore method is executed 809 * during restoreAll, if it returns true, it is removed from the 810 * restore map. 811 * 812 * @param id a unique tag associated with the restore method. 813 * @param supplier is a BooleanSupplier lambda. 814 */ queueRestoreWithRemovalIfTrue( @onNull String id, @Nullable BooleanSupplier supplier)815 public void queueRestoreWithRemovalIfTrue( 816 @NonNull String id, @Nullable BooleanSupplier supplier) { 817 Objects.requireNonNull(id, "id must not be null"); 818 synchronized (mMap) { 819 if (supplier != null) { 820 mMap.put(id, supplier); 821 } else { 822 mMap.remove(id); 823 } 824 } 825 } 826 827 /** 828 * Restore all parameters 829 * 830 * During restoration after audioserver death, any BooleanSupplier that returns 831 * true, for example on parameter restoration error, will be removed from mMap 832 * so as not to be executed on a subsequent restoreAll(). 833 */ restoreAll()834 public void restoreAll() { 835 synchronized (mMap) { 836 // Note: removing from values() also removes from the backing map. 837 // TODO: Consider catching exceptions? 838 mMap.values().removeIf(v -> { 839 return v.getAsBoolean(); // this iterates the setters(). 840 }); 841 } 842 } 843 844 /** 845 * mMap is a LinkedHashMap<Key, Value> of parameters restored by restore(). 846 * The Key is a unique id tag for identification. 847 * The Value is a lambda expression which returns true if the entry is to 848 * be removed. 849 * 850 * 1) For memory limitation purposes, mMap keeps the latest MAX_ENTRIES 851 * accessed in the map. 852 * 2) Parameters are restored in order of queuing, first in first out, 853 * from earliest to latest. 854 */ 855 @GuardedBy("mMap") 856 private Map</* @NonNull */ String, /* @NonNull */ BooleanSupplier> mMap = 857 new LinkedHashMap<>() { 858 // TODO: do we need this memory limitation? 859 private static final int MAX_ENTRIES = 1000; // limit our memory for now. 860 @Override 861 protected boolean removeEldestEntry(Map.Entry eldest) { 862 if (size() <= MAX_ENTRIES) return false; 863 Log.w(TAG, "Parameter map exceeds " 864 + MAX_ENTRIES + " removing " + eldest.getKey()); // don't silently remove. 865 return true; 866 } 867 }; 868 } 869 870 // We currently have one instance for mRestorableParameters used for 871 // setAdditionalOutputDeviceDelay(). Other methods requiring restoration could share this 872 // or use their own instance. 873 private RestorableParameters mRestorableParameters = new RestorableParameters(); 874 875 private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; 876 877 private PowerManager.WakeLock mAudioEventWakeLock; 878 879 private final MediaFocusControl mMediaFocusControl; 880 881 // Pre-scale for Bluetooth Absolute Volume 882 private float[] mPrescaleAbsoluteVolume = new float[] { 883 0.6f, // Pre-scale for index 1 884 0.8f, // Pre-scale for index 2 885 0.9f, // Pre-scale for index 3 886 }; 887 888 private NotificationManager mNm; 889 private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate; 890 private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT; 891 private long mLoweredFromNormalToVibrateTime; 892 893 // Array of Uids of valid assistant services to check if caller is one of them 894 @GuardedBy("mSettingsLock") 895 private final ArraySet<Integer> mAssistantUids = new ArraySet<>(); 896 @GuardedBy("mSettingsLock") 897 private int mPrimaryAssistantUid = INVALID_UID; 898 899 // Array of Uids of valid active assistant service to check if caller is one of them 900 @GuardedBy("mSettingsLock") 901 private int[] mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS; 902 903 // Array of Uids of valid accessibility services to check if caller is one of them 904 private final Object mAccessibilityServiceUidsLock = new Object(); 905 @GuardedBy("mAccessibilityServiceUidsLock") 906 private int[] mAccessibilityServiceUids; 907 908 // Uid of the active input method service to check if caller is the one or not. 909 private int mInputMethodServiceUid = android.os.Process.INVALID_UID; 910 private final Object mInputMethodServiceUidLock = new Object(); 911 912 private int mEncodedSurroundMode; 913 private String mEnabledSurroundFormats; 914 private boolean mSurroundModeChanged; 915 916 private boolean mSupportsMicPrivacyToggle; 917 918 private boolean mMicMuteFromSwitch; 919 private boolean mMicMuteFromApi; 920 private boolean mMicMuteFromRestrictions; 921 private boolean mMicMuteFromPrivacyToggle; 922 // caches the value returned by AudioSystem.isMicrophoneMuted() 923 private boolean mMicMuteFromSystemCached; 924 925 private boolean mNavigationRepeatSoundEffectsEnabled; 926 private boolean mHomeSoundEffectEnabled; 927 928 private final SoundDoseHelper mSoundDoseHelper; 929 930 private final Object mSupportedSystemUsagesLock = new Object(); 931 @GuardedBy("mSupportedSystemUsagesLock") 932 private @AttributeSystemUsage int[] mSupportedSystemUsages = 933 new int[]{AudioAttributes.USAGE_CALL_ASSISTANT}; 934 935 // Defines the format for the connection "address" for ALSA devices makeAlsaAddressString(int card, int device)936 public static String makeAlsaAddressString(int card, int device) { 937 return "card=" + card + ";device=" + device; 938 } 939 940 public static final class Lifecycle extends SystemService { 941 private AudioService mService; 942 Lifecycle(Context context)943 public Lifecycle(Context context) { 944 super(context); 945 mService = new AudioService(context, 946 AudioSystemAdapter.getDefaultAdapter(), 947 SystemServerAdapter.getDefaultAdapter(context), 948 SettingsAdapter.getDefaultAdapter(), 949 new DefaultAudioPolicyFacade(), 950 null); 951 952 } 953 954 @Override onStart()955 public void onStart() { 956 publishBinderService(Context.AUDIO_SERVICE, mService); 957 } 958 959 @Override onBootPhase(int phase)960 public void onBootPhase(int phase) { 961 if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { 962 mService.systemReady(); 963 } 964 } 965 } 966 967 final private IUidObserver mUidObserver = new UidObserver() { 968 @Override public void onUidGone(int uid, boolean disabled) { 969 // Once the uid is no longer running, no need to keep trying to disable its audio. 970 disableAudioForUid(false, uid); 971 } 972 973 @Override public void onUidCachedChanged(int uid, boolean cached) { 974 disableAudioForUid(cached, uid); 975 } 976 977 private void disableAudioForUid(boolean disable, int uid) { 978 queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID, 979 disable ? 1 : 0 /* arg1 */, uid /* arg2 */, 980 null /* obj */, 0 /* delay */); 981 } 982 }; 983 984 @GuardedBy("mSettingsLock") 985 private boolean mRttEnabled = false; 986 987 /////////////////////////////////////////////////////////////////////////// 988 // Construction 989 /////////////////////////////////////////////////////////////////////////// 990 991 992 /** 993 * @param context 994 * @param audioSystem Adapter for {@link AudioSystem} 995 * @param systemServer Adapter for privilieged functionality for system server components 996 * @param settings Adapter for {@link Settings} 997 * @param looper Looper to use for the service's message handler. If this is null, an 998 * {@link AudioSystemThread} is created as the messaging thread instead. 999 */ AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer, SettingsAdapter settings, AudioPolicyFacade audioPolicy, @Nullable Looper looper)1000 public AudioService(Context context, AudioSystemAdapter audioSystem, 1001 SystemServerAdapter systemServer, SettingsAdapter settings, 1002 AudioPolicyFacade audioPolicy, @Nullable Looper looper) { 1003 this (context, audioSystem, systemServer, settings, audioPolicy, looper, 1004 context.getSystemService(AppOpsManager.class), 1005 PermissionEnforcer.fromContext(context)); 1006 } 1007 1008 /** 1009 * @param context 1010 * @param audioSystem Adapter for {@link AudioSystem} 1011 * @param systemServer Adapter for privilieged functionality for system server components 1012 * @param settings Adapter for {@link Settings} 1013 * @param looper Looper to use for the service's message handler. If this is null, an 1014 * {@link AudioSystemThread} is created as the messaging thread instead. 1015 */ 1016 @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer, SettingsAdapter settings, AudioPolicyFacade audioPolicy, @Nullable Looper looper, AppOpsManager appOps, @NonNull PermissionEnforcer enforcer)1017 public AudioService(Context context, AudioSystemAdapter audioSystem, 1018 SystemServerAdapter systemServer, SettingsAdapter settings, 1019 AudioPolicyFacade audioPolicy, @Nullable Looper looper, AppOpsManager appOps, 1020 @NonNull PermissionEnforcer enforcer) { 1021 super(enforcer); 1022 sLifecycleLogger.enqueue(new EventLogger.StringEvent("AudioService()")); 1023 mContext = context; 1024 mContentResolver = context.getContentResolver(); 1025 mAppOps = appOps; 1026 1027 mAudioSystem = audioSystem; 1028 mSystemServer = systemServer; 1029 mSettings = settings; 1030 mAudioPolicy = audioPolicy; 1031 mPlatformType = AudioSystem.getPlatformType(context); 1032 1033 mDeviceBroker = new AudioDeviceBroker(mContext, this, mAudioSystem); 1034 1035 mIsSingleVolume = AudioSystem.isSingleVolume(context); 1036 1037 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 1038 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); 1039 mSensorPrivacyManagerInternal = 1040 LocalServices.getService(SensorPrivacyManagerInternal.class); 1041 1042 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 1043 mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent"); 1044 1045 mSfxHelper = new SoundEffectsHelper(mContext, playerBase -> ignorePlayerLogs(playerBase)); 1046 1047 boolean binauralEnabledDefault = SystemProperties.getBoolean( 1048 "ro.audio.spatializer_binaural_enabled_default", true); 1049 boolean transauralEnabledDefault = SystemProperties.getBoolean( 1050 "ro.audio.spatializer_transaural_enabled_default", true); 1051 boolean headTrackingEnabledDefault = mContext.getResources().getBoolean( 1052 com.android.internal.R.bool.config_spatial_audio_head_tracking_enabled_default); 1053 1054 mSpatializerHelper = new SpatializerHelper(this, mAudioSystem, mDeviceBroker, 1055 binauralEnabledDefault, transauralEnabledDefault, headTrackingEnabledDefault); 1056 1057 mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); 1058 mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator(); 1059 1060 mSupportsMicPrivacyToggle = context.getSystemService(SensorPrivacyManager.class) 1061 .supportsSensorToggle(SensorPrivacyManager.Sensors.MICROPHONE); 1062 1063 mUseVolumeGroupAliases = mContext.getResources().getBoolean( 1064 com.android.internal.R.bool.config_handleVolumeAliasesUsingVolumeGroups); 1065 1066 // Initialize volume 1067 // Priority 1 - Android Property 1068 // Priority 2 - Audio Policy Service 1069 // Priority 3 - Default Value 1070 if (AudioProductStrategy.getAudioProductStrategies().size() > 0) { 1071 int numStreamTypes = AudioSystem.getNumStreamTypes(); 1072 1073 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 1074 AudioAttributes attr = 1075 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType( 1076 streamType); 1077 int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr); 1078 if (maxVolume != -1) { 1079 MAX_STREAM_VOLUME[streamType] = maxVolume; 1080 } 1081 int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr); 1082 if (minVolume != -1) { 1083 MIN_STREAM_VOLUME[streamType] = minVolume; 1084 } 1085 } 1086 if (mUseVolumeGroupAliases) { 1087 // Set all default to uninitialized. 1088 for (int stream = 0; stream < AudioSystem.DEFAULT_STREAM_VOLUME.length; stream++) { 1089 AudioSystem.DEFAULT_STREAM_VOLUME[stream] = UNSET_INDEX; 1090 } 1091 } 1092 } 1093 1094 int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1); 1095 if (maxCallVolume != -1) { 1096 MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume; 1097 } 1098 1099 int defaultCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_default", -1); 1100 if (defaultCallVolume != -1 && 1101 defaultCallVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] && 1102 defaultCallVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) { 1103 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume; 1104 } else { 1105 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = 1106 (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4; 1107 } 1108 1109 int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1); 1110 if (maxMusicVolume != -1) { 1111 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume; 1112 } 1113 1114 int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1); 1115 if (defaultMusicVolume != -1 && 1116 defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] && 1117 defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) { 1118 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume; 1119 } else { 1120 if (isPlatformTelevision()) { 1121 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = 1122 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4; 1123 } else { 1124 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = 1125 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3; 1126 } 1127 } 1128 1129 int maxAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_steps", -1); 1130 if (maxAlarmVolume != -1) { 1131 MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = maxAlarmVolume; 1132 } 1133 1134 int defaultAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_default", -1); 1135 if (defaultAlarmVolume != -1 && 1136 defaultAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) { 1137 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = defaultAlarmVolume; 1138 } else { 1139 // Default is 6 out of 7 (default maximum), so scale accordingly. 1140 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = 1141 6 * MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] / 7; 1142 } 1143 1144 int maxSystemVolume = SystemProperties.getInt("ro.config.system_vol_steps", -1); 1145 if (maxSystemVolume != -1) { 1146 MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = maxSystemVolume; 1147 } 1148 1149 int defaultSystemVolume = SystemProperties.getInt("ro.config.system_vol_default", -1); 1150 if (defaultSystemVolume != -1 && 1151 defaultSystemVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]) { 1152 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = defaultSystemVolume; 1153 } else { 1154 // Default is to use maximum. 1155 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = 1156 MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]; 1157 } 1158 1159 int minAssistantVolume = SystemProperties.getInt("ro.config.assistant_vol_min", -1); 1160 if (minAssistantVolume != -1) { 1161 MIN_STREAM_VOLUME[AudioSystem.STREAM_ASSISTANT] = minAssistantVolume; 1162 } 1163 1164 // Read following properties to configure max volume (number of steps) and default volume 1165 // for STREAM_NOTIFICATION and STREAM_RING: 1166 // config_audio_notif_vol_default 1167 // config_audio_notif_vol_steps 1168 // config_audio_ring_vol_default 1169 // config_audio_ring_vol_steps 1170 int[] streams = { AudioSystem.STREAM_NOTIFICATION, AudioSystem.STREAM_RING }; 1171 int[] stepsResId = { com.android.internal.R.integer.config_audio_notif_vol_steps, 1172 com.android.internal.R.integer.config_audio_ring_vol_steps }; 1173 int[] defaultResId = { com.android.internal.R.integer.config_audio_notif_vol_default, 1174 com.android.internal.R.integer.config_audio_ring_vol_default }; 1175 for (int s = 0; s < streams.length; s++) { 1176 try { 1177 final int maxVol = mContext.getResources().getInteger(stepsResId[s]); 1178 if (maxVol <= 0) { 1179 throw new IllegalArgumentException("Invalid negative max volume for stream " 1180 + streams[s]); 1181 } 1182 Log.i(TAG, "Stream " + streams[s] + ": using max vol of " + maxVol); 1183 MAX_STREAM_VOLUME[streams[s]] = maxVol; 1184 } catch (Resources.NotFoundException e) { 1185 Log.e(TAG, "Error querying max vol for stream type " + streams[s], e); 1186 } 1187 try { 1188 final int defaultVol = mContext.getResources().getInteger(defaultResId[s]); 1189 if (defaultVol > MAX_STREAM_VOLUME[streams[s]]) { 1190 throw new IllegalArgumentException("Invalid default volume (" + defaultVol 1191 + ") for stream " + streams[s] + ", greater than max volume of " 1192 + MAX_STREAM_VOLUME[streams[s]]); 1193 } 1194 if (defaultVol < MIN_STREAM_VOLUME[streams[s]]) { 1195 throw new IllegalArgumentException("Invalid default volume (" + defaultVol 1196 + ") for stream " + streams[s] + ", lower than min volume of " 1197 + MIN_STREAM_VOLUME[streams[s]]); 1198 } 1199 Log.i(TAG, "Stream " + streams[s] + ": using default vol of " + defaultVol); 1200 AudioSystem.DEFAULT_STREAM_VOLUME[streams[s]] = defaultVol; 1201 } catch (Resources.NotFoundException e) { 1202 Log.e(TAG, "Error querying default vol for stream type " + streams[s], e); 1203 } 1204 } 1205 1206 if (looper == null) { 1207 createAudioSystemThread(); 1208 } else { 1209 mAudioHandler = new AudioHandler(looper); 1210 } 1211 1212 mSoundDoseHelper = new SoundDoseHelper(this, mContext, mAudioHandler, mSettings, 1213 mVolumeController); 1214 1215 AudioSystem.setErrorCallback(mAudioSystemCallback); 1216 1217 updateAudioHalPids(); 1218 1219 mUseFixedVolume = mContext.getResources().getBoolean( 1220 com.android.internal.R.bool.config_useFixedVolume); 1221 1222 mRecordMonitor = new RecordingActivityMonitor(mContext); 1223 mRecordMonitor.registerRecordingCallback(mVoiceRecordingActivityMonitor, true); 1224 1225 // must be called before readPersistedSettings() which needs a valid mStreamVolumeAlias[] 1226 // array initialized by updateStreamVolumeAlias() 1227 updateStreamVolumeAlias(false /*updateVolumes*/, TAG); 1228 readPersistedSettings(); 1229 readUserRestrictions(); 1230 1231 mPlaybackMonitor = 1232 new PlaybackActivityMonitor(context, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM], 1233 device -> onMuteAwaitConnectionTimeout(device)); 1234 mPlaybackMonitor.registerPlaybackCallback(mPlaybackActivityMonitor, true); 1235 1236 mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor); 1237 1238 readAndSetLowRamDevice(); 1239 1240 mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported(); 1241 1242 if (mSystemServer.isPrivileged()) { 1243 LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal()); 1244 1245 mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener); 1246 1247 mRecordMonitor.initMonitor(); 1248 } 1249 1250 mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false); 1251 1252 mHasSpatializerEffect = SystemProperties.getBoolean("ro.audio.spatializer_enabled", false); 1253 1254 // monitor routing updates coming from native 1255 mAudioSystem.setRoutingListener(this); 1256 // monitor requests for volume range initialization coming from native (typically when 1257 // errors are found by AudioPolicyManager 1258 mAudioSystem.setVolRangeInitReqListener(this); 1259 1260 // done with service initialization, continue additional work in our Handler thread 1261 queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES, 1262 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */); 1263 queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_ADI_DEVICE_STATES, 1264 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */); 1265 queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_SPATIALIZER, 1266 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */); 1267 } 1268 initVolumeStreamStates()1269 private void initVolumeStreamStates() { 1270 int numStreamTypes = AudioSystem.getNumStreamTypes(); 1271 synchronized (VolumeStreamState.class) { 1272 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 1273 VolumeStreamState streamState = mStreamStates[streamType]; 1274 int groupId = getVolumeGroupForStreamType(streamType); 1275 if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP 1276 && sVolumeGroupStates.indexOfKey(groupId) >= 0) { 1277 streamState.setVolumeGroupState(sVolumeGroupStates.get(groupId)); 1278 } 1279 } 1280 } 1281 } 1282 1283 /** 1284 * Called by handling of MSG_INIT_STREAMS_VOLUMES 1285 */ onInitStreamsAndVolumes()1286 private void onInitStreamsAndVolumes() { 1287 synchronized (mSettingsLock) { 1288 mCameraSoundForced = readCameraSoundForced(); 1289 sendMsg(mAudioHandler, 1290 MSG_SET_FORCE_USE, 1291 SENDMSG_QUEUE, 1292 AudioSystem.FOR_SYSTEM, 1293 mCameraSoundForced 1294 ? AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE, 1295 new String("AudioService ctor"), 1296 0); 1297 } 1298 1299 createStreamStates(); 1300 1301 // must be called after createStreamStates() as it uses MUSIC volume as default if no 1302 // persistent data 1303 initVolumeGroupStates(); 1304 1305 mSoundDoseHelper.initSafeMediaVolumeIndex(); 1306 // Link VGS on VSS 1307 initVolumeStreamStates(); 1308 1309 // Call setRingerModeInt() to apply correct mute 1310 // state on streams affected by ringer mode. 1311 sRingerAndZenModeMutedStreams = 0; 1312 sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent( 1313 sRingerAndZenModeMutedStreams, "onInitStreamsAndVolumes")); 1314 setRingerModeInt(getRingerModeInternal(), false); 1315 1316 final float[] preScale = new float[3]; 1317 preScale[0] = mContext.getResources().getFraction( 1318 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1, 1319 1, 1); 1320 preScale[1] = mContext.getResources().getFraction( 1321 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index2, 1322 1, 1); 1323 preScale[2] = mContext.getResources().getFraction( 1324 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index3, 1325 1, 1); 1326 for (int i = 0; i < preScale.length; i++) { 1327 if (0.0f <= preScale[i] && preScale[i] <= 1.0f) { 1328 mPrescaleAbsoluteVolume[i] = preScale[i]; 1329 } 1330 } 1331 1332 initExternalEventReceivers(); 1333 1334 // check on volume initialization 1335 checkVolumeRangeInitialization("AudioService()"); 1336 1337 } 1338 1339 private SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionChangedListener = 1340 new SubscriptionManager.OnSubscriptionsChangedListener() { 1341 @Override 1342 public void onSubscriptionsChanged() { 1343 Log.i(TAG, "onSubscriptionsChanged()"); 1344 sendMsg(mAudioHandler, MSG_CONFIGURATION_CHANGED, SENDMSG_REPLACE, 1345 0, 0, null, 0); 1346 } 1347 }; 1348 1349 /** 1350 * Initialize intent receives and settings observers for this service. 1351 * Must be called after createStreamStates() as the handling of some events 1352 * may affect or need volumes, e.g. BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED 1353 * (for intent receiver), or Settings.Global.ZEN_MODE (for settings observer) 1354 */ initExternalEventReceivers()1355 private void initExternalEventReceivers() { 1356 mSettingsObserver = new SettingsObserver(); 1357 1358 // Register for device connection intent broadcasts. 1359 IntentFilter intentFilter = 1360 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); 1361 intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED); 1362 intentFilter.addAction(Intent.ACTION_DOCK_EVENT); 1363 intentFilter.addAction(Intent.ACTION_SCREEN_ON); 1364 intentFilter.addAction(Intent.ACTION_SCREEN_OFF); 1365 intentFilter.addAction(Intent.ACTION_USER_SWITCHED); 1366 intentFilter.addAction(Intent.ACTION_USER_BACKGROUND); 1367 intentFilter.addAction(Intent.ACTION_USER_FOREGROUND); 1368 intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); 1369 intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED); 1370 1371 intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); 1372 if (mMonitorRotation) { 1373 RotationHelper.init(mContext, mAudioHandler, 1374 rotation -> onRotationUpdate(rotation), 1375 foldState -> onFoldStateUpdate(foldState)); 1376 } 1377 1378 intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION); 1379 intentFilter.addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION); 1380 intentFilter.addAction(ACTION_CHECK_MUSIC_ACTIVE); 1381 intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); 1382 1383 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null, 1384 Context.RECEIVER_EXPORTED); 1385 1386 SubscriptionManager subscriptionManager = mContext.getSystemService( 1387 SubscriptionManager.class); 1388 if (subscriptionManager == null) { 1389 Log.e(TAG, "initExternalEventReceivers cannot create SubscriptionManager!"); 1390 } else { 1391 subscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionChangedListener); 1392 } 1393 } 1394 systemReady()1395 public void systemReady() { 1396 sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE, 1397 0, 0, null, 0); 1398 if (false) { 1399 // This is turned off for now, because it is racy and thus causes apps to break. 1400 // Currently banning a uid means that if an app tries to start playing an audio 1401 // stream, that will be preventing, and unbanning it will not allow that stream 1402 // to resume. However these changes in uid state are racy with what the app is doing, 1403 // so that after taking a process out of the cached state we can't guarantee that 1404 // we will unban the uid before the app actually tries to start playing audio. 1405 // (To do that, the activity manager would need to wait until it knows for sure 1406 // that the ban has been removed, before telling the app to do whatever it is 1407 // supposed to do that caused it to go out of the cached state.) 1408 try { 1409 ActivityManager.getService().registerUidObserver(mUidObserver, 1410 ActivityManager.UID_OBSERVER_CACHED | ActivityManager.UID_OBSERVER_GONE, 1411 ActivityManager.PROCESS_STATE_UNKNOWN, null); 1412 } catch (RemoteException e) { 1413 // ignored; both services live in system_server 1414 } 1415 } 1416 } 1417 updateVibratorInfos()1418 private void updateVibratorInfos() { 1419 VibratorManager vibratorManager = mContext.getSystemService(VibratorManager.class); 1420 if (vibratorManager == null) { 1421 Slog.e(TAG, "Vibrator manager is not found"); 1422 return; 1423 } 1424 int[] vibratorIds = vibratorManager.getVibratorIds(); 1425 if (vibratorIds.length == 0) { 1426 Slog.d(TAG, "No vibrator found"); 1427 return; 1428 } 1429 List<Vibrator> vibrators = new ArrayList<>(vibratorIds.length); 1430 for (int id : vibratorIds) { 1431 Vibrator vibrator = vibratorManager.getVibrator(id); 1432 if (vibrator != null) { 1433 vibrators.add(vibrator); 1434 } else { 1435 Slog.w(TAG, "Vibrator(" + id + ") is not found"); 1436 } 1437 } 1438 if (vibrators.isEmpty()) { 1439 Slog.w(TAG, "Cannot find any available vibrator"); 1440 return; 1441 } 1442 AudioSystem.setVibratorInfos(vibrators); 1443 } 1444 onSystemReady()1445 public void onSystemReady() { 1446 mSystemReady = true; 1447 scheduleLoadSoundEffects(); 1448 1449 mDeviceBroker.onSystemReady(); 1450 1451 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) { 1452 synchronized (mHdmiClientLock) { 1453 mHdmiManager = mContext.getSystemService(HdmiControlManager.class); 1454 if (mHdmiManager != null) { 1455 mHdmiManager.addHdmiControlStatusChangeListener( 1456 mHdmiControlStatusChangeListenerCallback); 1457 mHdmiManager.addHdmiCecVolumeControlFeatureListener(mContext.getMainExecutor(), 1458 mMyHdmiCecVolumeControlFeatureListener); 1459 } 1460 mHdmiTvClient = mHdmiManager.getTvClient(); 1461 if (mHdmiTvClient != null) { 1462 mFixedVolumeDevices.removeAll( 1463 AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET); 1464 } 1465 mHdmiPlaybackClient = mHdmiManager.getPlaybackClient(); 1466 mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient(); 1467 } 1468 } 1469 1470 if (mSupportsMicPrivacyToggle) { 1471 mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers( 1472 SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> { 1473 if (userId == getCurrentUserId()) { 1474 mMicMuteFromPrivacyToggle = enabled; 1475 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); 1476 } 1477 }); 1478 } 1479 1480 mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 1481 1482 mSoundDoseHelper.configureSafeMedia(/*forced=*/true, TAG); 1483 1484 initA11yMonitoring(); 1485 1486 mRoleObserver = new RoleObserver(); 1487 mRoleObserver.register(); 1488 1489 onIndicateSystemReady(); 1490 1491 mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted(); 1492 setMicMuteFromSwitchInput(); 1493 1494 initMinStreamVolumeWithoutModifyAudioSettings(); 1495 1496 updateVibratorInfos(); 1497 1498 synchronized (mSupportedSystemUsagesLock) { 1499 AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages); 1500 } 1501 } 1502 1503 //----------------------------------------------------------------- 1504 // routing monitoring from AudioSystemAdapter 1505 @Override onRoutingUpdatedFromNative()1506 public void onRoutingUpdatedFromNative() { 1507 sendMsg(mAudioHandler, 1508 MSG_ROUTING_UPDATED, 1509 SENDMSG_REPLACE, 0, 0, null, 1510 /*delay*/ 0); 1511 } 1512 1513 /** 1514 * called when handling MSG_ROUTING_UPDATED 1515 */ onRoutingUpdatedFromAudioThread()1516 void onRoutingUpdatedFromAudioThread() { 1517 if (mHasSpatializerEffect) { 1518 mSpatializerHelper.onRoutingUpdated(); 1519 } 1520 checkMuteAwaitConnection(); 1521 } 1522 1523 //----------------------------------------------------------------- 1524 // rotation/fold updates coming from RotationHelper onRotationUpdate(Integer rotation)1525 void onRotationUpdate(Integer rotation) { 1526 mSpatializerHelper.setDisplayOrientation((float) (rotation * Math.PI / 180.)); 1527 // use REPLACE as only the last rotation matters 1528 final String rotationParameter = "rotation=" + rotation; 1529 sendMsg(mAudioHandler, MSG_ROTATION_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0, 1530 /*obj*/ rotationParameter, /*delay*/ 0); 1531 } 1532 onFoldStateUpdate(Boolean foldState)1533 void onFoldStateUpdate(Boolean foldState) { 1534 mSpatializerHelper.setFoldState(foldState); 1535 // use REPLACE as only the last fold state matters 1536 final String foldStateParameter = "device_folded=" + (foldState ? "on" : "off"); 1537 sendMsg(mAudioHandler, MSG_FOLD_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0, 1538 /*obj*/ foldStateParameter, /*delay*/ 0); 1539 } 1540 1541 //----------------------------------------------------------------- 1542 // Communicate to PlayackActivityMonitor whether to log or not 1543 // the sound FX activity (useful for removing touch sounds in the activity logs) ignorePlayerLogs(@onNull PlayerBase playerToIgnore)1544 void ignorePlayerLogs(@NonNull PlayerBase playerToIgnore) { 1545 if (DEBUG_LOG_SOUND_FX) { 1546 return; 1547 } 1548 sendMsg(mAudioHandler, MSG_NO_LOG_FOR_PLAYER_I, SENDMSG_REPLACE, 1549 /*arg1, piid of the player*/ playerToIgnore.getPlayerIId(), 1550 /*arg2 ignored*/ 0, /*obj ignored*/ null, /*delay*/ 0); 1551 } 1552 1553 //----------------------------------------------------------------- 1554 // monitoring requests for volume range initialization 1555 @Override // AudioSystemAdapter.OnVolRangeInitRequestListener onVolumeRangeInitRequestFromNative()1556 public void onVolumeRangeInitRequestFromNative() { 1557 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_REPLACE, 0, 0, 1558 "onVolumeRangeInitRequestFromNative" /*obj: caller, for dumpsys*/, /*delay*/ 0); 1559 } 1560 1561 //----------------------------------------------------------------- 1562 RoleObserver mRoleObserver; 1563 1564 class RoleObserver implements OnRoleHoldersChangedListener { 1565 private RoleManager mRm; 1566 private final Executor mExecutor; 1567 RoleObserver()1568 RoleObserver() { 1569 mExecutor = mContext.getMainExecutor(); 1570 } 1571 register()1572 public void register() { 1573 mRm = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE); 1574 if (mRm != null) { 1575 mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL); 1576 synchronized (mSettingsLock) { 1577 updateAssistantUIdLocked(/* forceUpdate= */ true); 1578 } 1579 } 1580 } 1581 1582 @Override onRoleHoldersChanged(@onNull String roleName, @NonNull UserHandle user)1583 public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) { 1584 if (RoleManager.ROLE_ASSISTANT.equals(roleName)) { 1585 synchronized (mSettingsLock) { 1586 updateAssistantUIdLocked(/* forceUpdate= */ false); 1587 } 1588 } 1589 } 1590 getAssistantRoleHolder()1591 public String getAssistantRoleHolder() { 1592 String assitantPackage = ""; 1593 if (mRm != null) { 1594 List<String> assistants = mRm.getRoleHolders(RoleManager.ROLE_ASSISTANT); 1595 assitantPackage = assistants.size() == 0 ? "" : assistants.get(0); 1596 } 1597 return assitantPackage; 1598 } 1599 } 1600 onIndicateSystemReady()1601 void onIndicateSystemReady() { 1602 if (AudioSystem.systemReady() == AudioSystem.SUCCESS) { 1603 return; 1604 } 1605 sendMsg(mAudioHandler, 1606 MSG_INDICATE_SYSTEM_READY, 1607 SENDMSG_REPLACE, 1608 0, 1609 0, 1610 null, 1611 INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 1612 } 1613 onAudioServerDied()1614 public void onAudioServerDied() { 1615 if (!mSystemReady || 1616 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) { 1617 Log.e(TAG, "Audioserver died."); 1618 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 1619 "onAudioServerDied() audioserver died")); 1620 sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0, 1621 null, 500); 1622 return; 1623 } 1624 Log.i(TAG, "Audioserver started."); 1625 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 1626 "onAudioServerDied() audioserver started")); 1627 1628 updateAudioHalPids(); 1629 1630 // indicate to audio HAL that we start the reconfiguration phase after a media 1631 // server crash 1632 // Note that we only execute this when the media server 1633 // process restarts after a crash, not the first time it is started. 1634 AudioSystem.setParameters("restarting=true"); 1635 1636 readAndSetLowRamDevice(); 1637 1638 mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported(); 1639 1640 // Restore device connection states, BT state 1641 mDeviceBroker.onAudioServerDied(); 1642 1643 // Restore call state 1644 synchronized (mDeviceBroker.mSetModeLock) { 1645 onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(), 1646 mContext.getPackageName(), true /*force*/); 1647 } 1648 final int forSys; 1649 synchronized (mSettingsLock) { 1650 forSys = mCameraSoundForced ? 1651 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE; 1652 } 1653 1654 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, forSys, "onAudioServerDied"); 1655 1656 // Restore stream volumes 1657 onReinitVolumes("after audioserver restart"); 1658 1659 // Restore audio volume groups 1660 restoreVolumeGroups(); 1661 1662 // Restore mono mode 1663 updateMasterMono(mContentResolver); 1664 1665 // Restore audio balance 1666 updateMasterBalance(mContentResolver); 1667 1668 // Restore ringer mode 1669 setRingerModeInt(getRingerModeInternal(), false); 1670 1671 // Reset device rotation (if monitored for this device) 1672 if (mMonitorRotation) { 1673 RotationHelper.updateOrientation(); 1674 } 1675 1676 // Restore setParameters and other queued setters. 1677 mRestorableParameters.restoreAll(); 1678 1679 synchronized (mSettingsLock) { 1680 final int forDock = mDockAudioMediaEnabled ? 1681 AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE; 1682 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, forDock, "onAudioServerDied"); 1683 sendEncodedSurroundMode(mContentResolver, "onAudioServerDied"); 1684 sendEnabledSurroundFormats(mContentResolver, true); 1685 AudioSystem.setRttEnabled(mRttEnabled); 1686 resetAssistantServicesUidsLocked(); 1687 } 1688 1689 synchronized (mAccessibilityServiceUidsLock) { 1690 AudioSystem.setA11yServicesUids(mAccessibilityServiceUids); 1691 } 1692 synchronized (mInputMethodServiceUidLock) { 1693 mAudioSystem.setCurrentImeUid(mInputMethodServiceUid); 1694 } 1695 synchronized (mHdmiClientLock) { 1696 if (mHdmiManager != null && mHdmiTvClient != null) { 1697 setHdmiSystemAudioSupported(mHdmiSystemAudioSupported); 1698 } 1699 } 1700 1701 synchronized (mSupportedSystemUsagesLock) { 1702 AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages); 1703 } 1704 1705 synchronized (mAudioPolicies) { 1706 ArrayList<AudioPolicyProxy> invalidProxies = new ArrayList<>(); 1707 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 1708 final int status = policy.connectMixes(); 1709 if (status != AudioSystem.SUCCESS) { 1710 // note that PERMISSION_DENIED may also indicate trouble getting to APService 1711 Log.e(TAG, "onAudioServerDied: error " 1712 + AudioSystem.audioSystemErrorToString(status) 1713 + " when connecting mixes for policy " + policy.toLogFriendlyString()); 1714 invalidProxies.add(policy); 1715 } else { 1716 final int deviceAffinitiesStatus = policy.setupDeviceAffinities(); 1717 if (deviceAffinitiesStatus != AudioSystem.SUCCESS) { 1718 Log.e(TAG, "onAudioServerDied: error " 1719 + AudioSystem.audioSystemErrorToString(deviceAffinitiesStatus) 1720 + " when connecting device affinities for policy " 1721 + policy.toLogFriendlyString()); 1722 invalidProxies.add(policy); 1723 } 1724 } 1725 } 1726 invalidProxies.forEach((policy) -> policy.release()); 1727 1728 } 1729 1730 // Restore capture policies 1731 synchronized (mPlaybackMonitor) { 1732 HashMap<Integer, Integer> allowedCapturePolicies = 1733 mPlaybackMonitor.getAllAllowedCapturePolicies(); 1734 for (HashMap.Entry<Integer, Integer> entry : allowedCapturePolicies.entrySet()) { 1735 int result = mAudioSystem.setAllowedCapturePolicy( 1736 entry.getKey(), 1737 AudioAttributes.capturePolicyToFlags(entry.getValue(), 0x0)); 1738 if (result != AudioSystem.AUDIO_STATUS_OK) { 1739 Log.e(TAG, "Failed to restore capture policy, uid: " 1740 + entry.getKey() + ", capture policy: " + entry.getValue() 1741 + ", result: " + result); 1742 // When restoring capture policy failed, set the capture policy as 1743 // ALLOW_CAPTURE_BY_ALL, which will result in removing the cached 1744 // capture policy in PlaybackActivityMonitor. 1745 mPlaybackMonitor.setAllowedCapturePolicy( 1746 entry.getKey(), AudioAttributes.ALLOW_CAPTURE_BY_ALL); 1747 } 1748 } 1749 } 1750 1751 mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect); 1752 mSoundDoseHelper.reset(); 1753 1754 // Restore rotation information. 1755 if (mMonitorRotation) { 1756 RotationHelper.forceUpdate(); 1757 } 1758 1759 onIndicateSystemReady(); 1760 // indicate the end of reconfiguration phase to audio HAL 1761 AudioSystem.setParameters("restarting=false"); 1762 1763 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE, 1764 SENDMSG_QUEUE, 1, 0, null, 0); 1765 1766 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); // will also update the mic mute cache 1767 setMicMuteFromSwitchInput(); 1768 1769 // Restore vibrator info 1770 updateVibratorInfos(); 1771 } 1772 onRemoveAssistantServiceUids(int[] uids)1773 private void onRemoveAssistantServiceUids(int[] uids) { 1774 synchronized (mSettingsLock) { 1775 removeAssistantServiceUidsLocked(uids); 1776 } 1777 } 1778 1779 @GuardedBy("mSettingsLock") removeAssistantServiceUidsLocked(int[] uids)1780 private void removeAssistantServiceUidsLocked(int[] uids) { 1781 boolean changed = false; 1782 for (int index = 0; index < uids.length; index++) { 1783 if (!mAssistantUids.remove(uids[index])) { 1784 Slog.e(TAG, TextUtils.formatSimple( 1785 "Cannot remove assistant service, uid(%d) not present", uids[index])); 1786 continue; 1787 } 1788 changed = true; 1789 } 1790 if (changed) { 1791 updateAssistantServicesUidsLocked(); 1792 } 1793 } 1794 onAddAssistantServiceUids(int[] uids)1795 private void onAddAssistantServiceUids(int[] uids) { 1796 synchronized (mSettingsLock) { 1797 addAssistantServiceUidsLocked(uids); 1798 } 1799 } 1800 1801 @GuardedBy("mSettingsLock") addAssistantServiceUidsLocked(int[] uids)1802 private void addAssistantServiceUidsLocked(int[] uids) { 1803 boolean changed = false; 1804 for (int index = 0; index < uids.length; index++) { 1805 if (uids[index] == INVALID_UID) { 1806 continue; 1807 } 1808 if (!mAssistantUids.add(uids[index])) { 1809 Slog.e(TAG, TextUtils.formatSimple( 1810 "Cannot add assistant service, uid(%d) already present", 1811 uids[index])); 1812 continue; 1813 } 1814 changed = true; 1815 } 1816 if (changed) { 1817 updateAssistantServicesUidsLocked(); 1818 } 1819 } 1820 1821 @GuardedBy("mSettingsLock") resetAssistantServicesUidsLocked()1822 private void resetAssistantServicesUidsLocked() { 1823 mAssistantUids.clear(); 1824 updateAssistantUIdLocked(/* forceUpdate= */ true); 1825 } 1826 1827 @GuardedBy("mSettingsLock") updateAssistantServicesUidsLocked()1828 private void updateAssistantServicesUidsLocked() { 1829 int[] assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray(); 1830 AudioSystem.setAssistantServicesUids(assistantUids); 1831 } 1832 updateActiveAssistantServiceUids()1833 private void updateActiveAssistantServiceUids() { 1834 int [] activeAssistantServiceUids; 1835 synchronized (mSettingsLock) { 1836 activeAssistantServiceUids = mActiveAssistantServiceUids; 1837 } 1838 AudioSystem.setActiveAssistantServicesUids(activeAssistantServiceUids); 1839 } 1840 onReinitVolumes(@onNull String caller)1841 private void onReinitVolumes(@NonNull String caller) { 1842 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 1843 // keep track of any error during stream volume initialization 1844 int status = AudioSystem.AUDIO_STATUS_OK; 1845 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 1846 VolumeStreamState streamState = mStreamStates[streamType]; 1847 final int res = AudioSystem.initStreamVolume( 1848 streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10); 1849 if (res != AudioSystem.AUDIO_STATUS_OK) { 1850 status = res; 1851 Log.e(TAG, "Failed to initStreamVolume (" + res + ") for stream " + streamType); 1852 // stream volume initialization failed, no need to try the others, it will be 1853 // attempted again when MSG_REINIT_VOLUMES is handled 1854 break; 1855 } 1856 streamState.applyAllVolumes(); 1857 } 1858 1859 // did it work? check based on status 1860 if (status != AudioSystem.AUDIO_STATUS_OK) { 1861 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 1862 caller + ": initStreamVolume failed with " + status + " will retry") 1863 .printLog(ALOGE, TAG)); 1864 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 1865 caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 1866 return; 1867 } 1868 1869 // did it work? check based on min/max values of some basic streams 1870 if (!checkVolumeRangeInitialization(caller)) { 1871 return; 1872 } 1873 1874 // success 1875 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 1876 caller + ": initStreamVolume succeeded").printLog(ALOGI, TAG)); 1877 } 1878 1879 /** 1880 * Check volume ranges were properly initialized 1881 * @return true if volume ranges were successfully initialized 1882 */ checkVolumeRangeInitialization(String caller)1883 private boolean checkVolumeRangeInitialization(String caller) { 1884 boolean success = true; 1885 final int[] basicStreams = { AudioSystem.STREAM_ALARM, AudioSystem.STREAM_RING, 1886 AudioSystem.STREAM_MUSIC, AudioSystem.STREAM_VOICE_CALL, 1887 AudioSystem.STREAM_ACCESSIBILITY }; 1888 for (int streamType : basicStreams) { 1889 final AudioAttributes aa = new AudioAttributes.Builder() 1890 .setInternalLegacyStreamType(streamType).build(); 1891 if (AudioSystem.getMaxVolumeIndexForAttributes(aa) < 0 1892 || AudioSystem.getMinVolumeIndexForAttributes(aa) < 0) { 1893 success = false; 1894 break; 1895 } 1896 } 1897 if (!success) { 1898 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 1899 caller + ": initStreamVolume succeeded but invalid mix/max levels, will retry") 1900 .printLog(ALOGW, TAG)); 1901 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 1902 caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 1903 } 1904 return success; 1905 } 1906 onDispatchAudioServerStateChange(boolean state)1907 private void onDispatchAudioServerStateChange(boolean state) { 1908 synchronized (mAudioServerStateListeners) { 1909 for (AsdProxy asdp : mAudioServerStateListeners.values()) { 1910 try { 1911 asdp.callback().dispatchAudioServerStateChange(state); 1912 } catch (RemoteException e) { 1913 Log.w(TAG, "Could not call dispatchAudioServerStateChange()", e); 1914 } 1915 } 1916 } 1917 } 1918 createAudioSystemThread()1919 private void createAudioSystemThread() { 1920 mAudioSystemThread = new AudioSystemThread(); 1921 mAudioSystemThread.start(); 1922 waitForAudioHandlerCreation(); 1923 } 1924 1925 /** Waits for the volume handler to be created by the other thread. */ waitForAudioHandlerCreation()1926 private void waitForAudioHandlerCreation() { 1927 synchronized(this) { 1928 while (mAudioHandler == null) { 1929 try { 1930 // Wait for mAudioHandler to be set by the other thread 1931 wait(); 1932 } catch (InterruptedException e) { 1933 Log.e(TAG, "Interrupted while waiting on volume handler."); 1934 } 1935 } 1936 } 1937 } 1938 1939 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 1940 /** 1941 * @see AudioManager#setSupportedSystemUsages(int[]) 1942 */ setSupportedSystemUsages(@onNull @ttributeSystemUsage int[] systemUsages)1943 public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) { 1944 super.setSupportedSystemUsages_enforcePermission(); 1945 1946 verifySystemUsages(systemUsages); 1947 1948 synchronized (mSupportedSystemUsagesLock) { 1949 AudioSystem.setSupportedSystemUsages(systemUsages); 1950 mSupportedSystemUsages = systemUsages; 1951 } 1952 } 1953 1954 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 1955 /** 1956 * @see AudioManager#getSupportedSystemUsages() 1957 */ getSupportedSystemUsages()1958 public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() { 1959 super.getSupportedSystemUsages_enforcePermission(); 1960 1961 synchronized (mSupportedSystemUsagesLock) { 1962 return Arrays.copyOf(mSupportedSystemUsages, mSupportedSystemUsages.length); 1963 } 1964 } 1965 verifySystemUsages(@onNull int[] systemUsages)1966 private void verifySystemUsages(@NonNull int[] systemUsages) { 1967 for (int i = 0; i < systemUsages.length; i++) { 1968 if (!AudioAttributes.isSystemUsage(systemUsages[i])) { 1969 throw new IllegalArgumentException("Non-system usage provided: " + systemUsages[i]); 1970 } 1971 } 1972 } 1973 1974 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 1975 /** 1976 * @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the 1977 * platform configuration file. 1978 */ 1979 @NonNull getAudioProductStrategies()1980 public List<AudioProductStrategy> getAudioProductStrategies() { 1981 // verify permissions 1982 super.getAudioProductStrategies_enforcePermission(); 1983 1984 return AudioProductStrategy.getAudioProductStrategies(); 1985 } 1986 1987 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 1988 /** 1989 * @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the 1990 * platform configuration file. 1991 */ 1992 @NonNull getAudioVolumeGroups()1993 public List<AudioVolumeGroup> getAudioVolumeGroups() { 1994 // verify permissions 1995 super.getAudioVolumeGroups_enforcePermission(); 1996 1997 return AudioVolumeGroup.getAudioVolumeGroups(); 1998 } 1999 checkAllAliasStreamVolumes()2000 private void checkAllAliasStreamVolumes() { 2001 synchronized (mSettingsLock) { 2002 synchronized (VolumeStreamState.class) { 2003 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2004 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 2005 mStreamStates[streamType] 2006 .setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]], TAG); 2007 // apply stream volume 2008 if (!mStreamStates[streamType].mIsMuted) { 2009 mStreamStates[streamType].applyAllVolumes(); 2010 } 2011 } 2012 } 2013 } 2014 } 2015 2016 2017 /** 2018 * Called from AudioDeviceBroker when DEVICE_OUT_HDMI is connected or disconnected. 2019 */ postCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2020 /*package*/ void postCheckVolumeCecOnHdmiConnection( 2021 @AudioService.ConnectionState int state, String caller) { 2022 sendMsg(mAudioHandler, MSG_HDMI_VOLUME_CHECK, SENDMSG_REPLACE, 2023 state /*arg1*/, 0 /*arg2 ignored*/, caller /*obj*/, 0 /*delay*/); 2024 } 2025 onCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2026 private void onCheckVolumeCecOnHdmiConnection( 2027 @AudioService.ConnectionState int state, String caller) { 2028 if (state == AudioService.CONNECTION_STATE_CONNECTED) { 2029 // DEVICE_OUT_HDMI is now connected 2030 if (mSoundDoseHelper.safeDevicesContains(AudioSystem.DEVICE_OUT_HDMI)) { 2031 mSoundDoseHelper.scheduleMusicActiveCheck(); 2032 } 2033 2034 if (isPlatformTelevision()) { 2035 synchronized (mHdmiClientLock) { 2036 if (mHdmiManager != null && mHdmiPlaybackClient != null) { 2037 updateHdmiCecSinkLocked( 2038 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)); 2039 } 2040 } 2041 } 2042 sendEnabledSurroundFormats(mContentResolver, true); 2043 } else { 2044 // DEVICE_OUT_HDMI disconnected 2045 if (isPlatformTelevision()) { 2046 synchronized (mHdmiClientLock) { 2047 if (mHdmiManager != null) { 2048 updateHdmiCecSinkLocked( 2049 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)); 2050 } 2051 } 2052 } 2053 } 2054 } 2055 2056 /** 2057 * Asynchronously update volume states for the given device. 2058 * 2059 * @param device a single audio device, ensure that this is not a devices bitmask 2060 * @param caller caller of this method 2061 */ postUpdateVolumeStatesForAudioDevice(int device, String caller)2062 private void postUpdateVolumeStatesForAudioDevice(int device, String caller) { 2063 sendMsg(mAudioHandler, 2064 MSG_UPDATE_VOLUME_STATES_FOR_DEVICE, 2065 SENDMSG_QUEUE, device /*arg1*/, 0 /*arg2*/, caller /*obj*/, 2066 0 /*delay*/); 2067 } 2068 2069 /** 2070 * Update volume states for the given device. 2071 * 2072 * This will initialize the volume index if no volume index is available. 2073 * If the device is the currently routed device, fixed/full volume policies will be applied. 2074 * 2075 * @param device a single audio device, ensure that this is not a devices bitmask 2076 * @param caller caller of this method 2077 */ onUpdateVolumeStatesForAudioDevice(int device, String caller)2078 private void onUpdateVolumeStatesForAudioDevice(int device, String caller) { 2079 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 2080 synchronized (mSettingsLock) { 2081 synchronized (VolumeStreamState.class) { 2082 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 2083 updateVolumeStates(device, streamType, caller); 2084 } 2085 } 2086 } 2087 } 2088 2089 /** 2090 * Update volume states for the given device and given stream. 2091 * 2092 * This will initialize the volume index if no volume index is available. 2093 * If the device is the currently routed device, fixed/full volume policies will be applied. 2094 * 2095 * @param device a single audio device, ensure that this is not a devices bitmask 2096 * @param streamType streamType to be updated 2097 * @param caller caller of this method 2098 */ updateVolumeStates(int device, int streamType, String caller)2099 private void updateVolumeStates(int device, int streamType, String caller) { 2100 // Handle device volume aliasing of SPEAKER_SAFE. 2101 if (device == AudioSystem.DEVICE_OUT_SPEAKER_SAFE) { 2102 device = AudioSystem.DEVICE_OUT_SPEAKER; 2103 } 2104 if (!mStreamStates[streamType].hasIndexForDevice(device)) { 2105 // set the default value, if device is affected by a full/fix/abs volume rule, it 2106 // will taken into account in checkFixedVolumeDevices() 2107 mStreamStates[streamType].setIndex( 2108 mStreamStates[mStreamVolumeAlias[streamType]] 2109 .getIndex(AudioSystem.DEVICE_OUT_DEFAULT), 2110 device, caller, true /*hasModifyAudioSettings*/); 2111 } 2112 2113 // Check if device to be updated is routed for the given audio stream 2114 // This may include devices such as SPEAKER_SAFE. 2115 List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributesInt( 2116 new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build(), 2117 true /* forVolume */); 2118 for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) { 2119 if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType( 2120 device)) { 2121 mStreamStates[streamType].checkFixedVolumeDevices(); 2122 2123 // Unmute streams if required and device is full volume 2124 if (isStreamMute(streamType) && mFullVolumeDevices.contains(device)) { 2125 mStreamStates[streamType].mute(false, "updateVolumeStates(" + caller); 2126 } 2127 } 2128 } 2129 } 2130 checkAllFixedVolumeDevices()2131 private void checkAllFixedVolumeDevices() 2132 { 2133 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2134 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 2135 mStreamStates[streamType].checkFixedVolumeDevices(); 2136 } 2137 } 2138 checkAllFixedVolumeDevices(int streamType)2139 private void checkAllFixedVolumeDevices(int streamType) { 2140 mStreamStates[streamType].checkFixedVolumeDevices(); 2141 } 2142 checkMuteAffectedStreams()2143 private void checkMuteAffectedStreams() { 2144 // any stream with a min level > 0 is not muteable by definition 2145 // STREAM_VOICE_CALL and STREAM_BLUETOOTH_SCO can be muted by applications 2146 // that has the the MODIFY_PHONE_STATE permission. 2147 for (int i = 0; i < mStreamStates.length; i++) { 2148 final VolumeStreamState vss = mStreamStates[i]; 2149 if (vss.mIndexMin > 0 && 2150 (vss.mStreamType != AudioSystem.STREAM_VOICE_CALL && 2151 vss.mStreamType != AudioSystem.STREAM_BLUETOOTH_SCO)) { 2152 mMuteAffectedStreams &= ~(1 << vss.mStreamType); 2153 } 2154 } 2155 } 2156 createStreamStates()2157 private void createStreamStates() { 2158 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2159 VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes]; 2160 2161 for (int i = 0; i < numStreamTypes; i++) { 2162 streams[i] = 2163 new VolumeStreamState(System.VOLUME_SETTINGS_INT[mStreamVolumeAlias[i]], i); 2164 } 2165 2166 checkAllFixedVolumeDevices(); 2167 checkAllAliasStreamVolumes(); 2168 checkMuteAffectedStreams(); 2169 updateDefaultVolumes(); 2170 } 2171 2172 /** 2173 * Update default indexes from aliased streams. Must be called after mStreamStates is created 2174 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for default 2175 * index. Need to make default index configurable and independent of streams. 2176 * Fallback on music stream for default initialization to take benefit of property based default 2177 * initialization. 2178 * For other volume groups not linked to any streams, default music stream index is considered. 2179 */ updateDefaultVolumes()2180 private void updateDefaultVolumes() { 2181 for (int stream = 0; stream < mStreamStates.length; stream++) { 2182 int streamVolumeAlias = mStreamVolumeAlias[stream]; 2183 if (mUseVolumeGroupAliases) { 2184 if (AudioSystem.DEFAULT_STREAM_VOLUME[stream] != UNSET_INDEX) { 2185 // Already initialized through default property based mecanism. 2186 continue; 2187 } 2188 streamVolumeAlias = AudioSystem.STREAM_MUSIC; 2189 int defaultAliasVolume = getUiDefaultRescaledIndex(streamVolumeAlias, stream); 2190 if ((defaultAliasVolume >= MIN_STREAM_VOLUME[stream]) 2191 && (defaultAliasVolume <= MAX_STREAM_VOLUME[stream])) { 2192 AudioSystem.DEFAULT_STREAM_VOLUME[stream] = defaultAliasVolume; 2193 continue; 2194 } 2195 } 2196 if (stream != streamVolumeAlias) { 2197 AudioSystem.DEFAULT_STREAM_VOLUME[stream] = 2198 getUiDefaultRescaledIndex(streamVolumeAlias, stream); 2199 } 2200 } 2201 } 2202 getUiDefaultRescaledIndex(int srcStream, int dstStream)2203 private int getUiDefaultRescaledIndex(int srcStream, int dstStream) { 2204 return (rescaleIndex(AudioSystem.DEFAULT_STREAM_VOLUME[srcStream] * 10, 2205 srcStream, dstStream) + 5) / 10; 2206 } 2207 dumpStreamStates(PrintWriter pw)2208 private void dumpStreamStates(PrintWriter pw) { 2209 pw.println("\nStream volumes (device: index)"); 2210 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2211 for (int i = 0; i < numStreamTypes; i++) { 2212 StringBuilder alias = new StringBuilder(); 2213 if (mStreamVolumeAlias[i] != i) { 2214 alias.append(" (aliased to: ") 2215 .append(AudioSystem.STREAM_NAMES[mStreamVolumeAlias[i]]) 2216 .append(")"); 2217 } 2218 pw.println("- " + AudioSystem.STREAM_NAMES[i] + alias + ":"); 2219 mStreamStates[i].dump(pw); 2220 pw.println(""); 2221 } 2222 pw.print("\n- mute affected streams = 0x"); 2223 pw.println(Integer.toHexString(mMuteAffectedStreams)); 2224 } 2225 updateStreamVolumeAlias(boolean updateVolumes, String caller)2226 private void updateStreamVolumeAlias(boolean updateVolumes, String caller) { 2227 int dtmfStreamAlias; 2228 final int a11yStreamAlias = sIndependentA11yVolume ? 2229 AudioSystem.STREAM_ACCESSIBILITY : AudioSystem.STREAM_MUSIC; 2230 final int assistantStreamAlias = mContext.getResources().getBoolean( 2231 com.android.internal.R.bool.config_useAssistantVolume) ? 2232 AudioSystem.STREAM_ASSISTANT : AudioSystem.STREAM_MUSIC; 2233 2234 if (mIsSingleVolume) { 2235 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION.clone(); 2236 dtmfStreamAlias = AudioSystem.STREAM_MUSIC; 2237 } else if (mUseVolumeGroupAliases) { 2238 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_NONE.clone(); 2239 dtmfStreamAlias = AudioSystem.STREAM_DTMF; 2240 } else { 2241 switch (mPlatformType) { 2242 case AudioSystem.PLATFORM_VOICE: 2243 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_VOICE.clone(); 2244 dtmfStreamAlias = AudioSystem.STREAM_RING; 2245 break; 2246 default: 2247 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_DEFAULT.clone(); 2248 dtmfStreamAlias = AudioSystem.STREAM_MUSIC; 2249 } 2250 if (!mNotifAliasRing) { 2251 mStreamVolumeAlias[AudioSystem.STREAM_NOTIFICATION] = 2252 AudioSystem.STREAM_NOTIFICATION; 2253 } 2254 } 2255 2256 if (mIsSingleVolume) { 2257 mRingerModeAffectedStreams = 0; 2258 } else { 2259 if (isInCommunication()) { 2260 dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL; 2261 mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF); 2262 } else { 2263 mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF); 2264 } 2265 } 2266 2267 mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias; 2268 mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias; 2269 mStreamVolumeAlias[AudioSystem.STREAM_ASSISTANT] = assistantStreamAlias; 2270 2271 if (updateVolumes && mStreamStates != null) { 2272 updateDefaultVolumes(); 2273 2274 synchronized (mSettingsLock) { 2275 synchronized (VolumeStreamState.class) { 2276 mStreamStates[AudioSystem.STREAM_DTMF] 2277 .setAllIndexes(mStreamStates[dtmfStreamAlias], caller); 2278 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setSettingName( 2279 System.VOLUME_SETTINGS_INT[a11yStreamAlias]); 2280 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setAllIndexes( 2281 mStreamStates[a11yStreamAlias], caller); 2282 } 2283 } 2284 if (sIndependentA11yVolume) { 2285 // restore the a11y values from the settings 2286 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].readSettings(); 2287 } 2288 2289 // apply stream mute states according to new value of mRingerModeAffectedStreams 2290 setRingerModeInt(getRingerModeInternal(), false); 2291 sendMsg(mAudioHandler, 2292 MSG_SET_ALL_VOLUMES, 2293 SENDMSG_QUEUE, 2294 0, 2295 0, 2296 mStreamStates[AudioSystem.STREAM_DTMF], 0); 2297 sendMsg(mAudioHandler, 2298 MSG_SET_ALL_VOLUMES, 2299 SENDMSG_QUEUE, 2300 0, 2301 0, 2302 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY], 0); 2303 } 2304 dispatchStreamAliasingUpdate(); 2305 } 2306 readDockAudioSettings(ContentResolver cr)2307 private void readDockAudioSettings(ContentResolver cr) 2308 { 2309 mDockAudioMediaEnabled = mSettings.getGlobalInt( 2310 cr, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED, 0) == 1; 2311 2312 sendMsg(mAudioHandler, 2313 MSG_SET_FORCE_USE, 2314 SENDMSG_QUEUE, 2315 AudioSystem.FOR_DOCK, 2316 mDockAudioMediaEnabled ? 2317 AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE, 2318 new String("readDockAudioSettings"), 2319 0); 2320 2321 } 2322 2323 updateMasterMono(ContentResolver cr)2324 private void updateMasterMono(ContentResolver cr) 2325 { 2326 final boolean masterMono = mSettings.getSystemIntForUser( 2327 cr, System.MASTER_MONO, 0 /* default */, UserHandle.USER_CURRENT) == 1; 2328 if (DEBUG_VOL) { 2329 Log.d(TAG, String.format("Master mono %b", masterMono)); 2330 } 2331 AudioSystem.setMasterMono(masterMono); 2332 } 2333 updateMasterBalance(ContentResolver cr)2334 private void updateMasterBalance(ContentResolver cr) { 2335 final float masterBalance = System.getFloatForUser( 2336 cr, System.MASTER_BALANCE, 0.f /* default */, UserHandle.USER_CURRENT); 2337 if (DEBUG_VOL) { 2338 Log.d(TAG, String.format("Master balance %f", masterBalance)); 2339 } 2340 if (AudioSystem.setMasterBalance(masterBalance) != 0) { 2341 Log.e(TAG, String.format("setMasterBalance failed for %f", masterBalance)); 2342 } 2343 } 2344 sendEncodedSurroundMode(ContentResolver cr, String eventSource)2345 private void sendEncodedSurroundMode(ContentResolver cr, String eventSource) 2346 { 2347 final int encodedSurroundMode = mSettings.getGlobalInt( 2348 cr, Settings.Global.ENCODED_SURROUND_OUTPUT, 2349 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 2350 sendEncodedSurroundMode(encodedSurroundMode, eventSource); 2351 } 2352 sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)2353 private void sendEncodedSurroundMode(int encodedSurroundMode, String eventSource) 2354 { 2355 // initialize to guaranteed bad value 2356 int forceSetting = AudioSystem.NUM_FORCE_CONFIG; 2357 switch (encodedSurroundMode) { 2358 case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO: 2359 forceSetting = AudioSystem.FORCE_NONE; 2360 break; 2361 case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER: 2362 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_NEVER; 2363 break; 2364 case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS: 2365 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_ALWAYS; 2366 break; 2367 case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL: 2368 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_MANUAL; 2369 break; 2370 default: 2371 Log.e(TAG, "updateSurroundSoundSettings: illegal value " 2372 + encodedSurroundMode); 2373 break; 2374 } 2375 if (forceSetting != AudioSystem.NUM_FORCE_CONFIG) { 2376 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_ENCODED_SURROUND, forceSetting, 2377 eventSource); 2378 } 2379 } 2380 2381 @Override // Binder call onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)2382 public void onShellCommand(FileDescriptor in, FileDescriptor out, 2383 FileDescriptor err, String[] args, ShellCallback callback, 2384 ResultReceiver resultReceiver) { 2385 if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_AUDIO_POLICY) 2386 != PackageManager.PERMISSION_GRANTED) { 2387 throw new SecurityException("Missing MANAGE_AUDIO_POLICY permission"); 2388 } 2389 new AudioManagerShellCommand(AudioService.this).exec(this, in, out, err, 2390 args, callback, resultReceiver); 2391 } 2392 2393 /** @see AudioManager#getSurroundFormats() */ 2394 @Override getSurroundFormats()2395 public Map<Integer, Boolean> getSurroundFormats() { 2396 Map<Integer, Boolean> surroundFormats = new HashMap<>(); 2397 int status = AudioSystem.getSurroundFormats(surroundFormats); 2398 if (status != AudioManager.SUCCESS) { 2399 // fail and bail! 2400 Log.e(TAG, "getSurroundFormats failed:" + status); 2401 return new HashMap<>(); // Always return a map. 2402 } 2403 return surroundFormats; 2404 } 2405 2406 /** @see AudioManager#getReportedSurroundFormats() */ 2407 @Override getReportedSurroundFormats()2408 public List<Integer> getReportedSurroundFormats() { 2409 ArrayList<Integer> reportedSurroundFormats = new ArrayList<>(); 2410 int status = AudioSystem.getReportedSurroundFormats(reportedSurroundFormats); 2411 if (status != AudioManager.SUCCESS) { 2412 // fail and bail! 2413 Log.e(TAG, "getReportedSurroundFormats failed:" + status); 2414 return new ArrayList<>(); // Always return a list. 2415 } 2416 return reportedSurroundFormats; 2417 } 2418 2419 /** @see AudioManager#isSurroundFormatEnabled(int) */ 2420 @Override isSurroundFormatEnabled(int audioFormat)2421 public boolean isSurroundFormatEnabled(int audioFormat) { 2422 if (!isSurroundFormat(audioFormat)) { 2423 Log.w(TAG, "audioFormat to enable is not a surround format."); 2424 return false; 2425 } 2426 2427 final long token = Binder.clearCallingIdentity(); 2428 try { 2429 synchronized (mSettingsLock) { 2430 HashSet<Integer> enabledFormats = getEnabledFormats(); 2431 return enabledFormats.contains(audioFormat); 2432 } 2433 } finally { 2434 Binder.restoreCallingIdentity(token); 2435 } 2436 } 2437 2438 /** @see AudioManager#setSurroundFormatEnabled(int, boolean) */ 2439 @Override setSurroundFormatEnabled(int audioFormat, boolean enabled)2440 public boolean setSurroundFormatEnabled(int audioFormat, boolean enabled) { 2441 if (!isSurroundFormat(audioFormat)) { 2442 Log.w(TAG, "audioFormat to enable is not a surround format."); 2443 return false; 2444 } 2445 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS) 2446 != PackageManager.PERMISSION_GRANTED) { 2447 throw new SecurityException("Missing WRITE_SETTINGS permission"); 2448 } 2449 2450 HashSet<Integer> enabledFormats = getEnabledFormats(); 2451 if (enabled) { 2452 enabledFormats.add(audioFormat); 2453 } else { 2454 enabledFormats.remove(audioFormat); 2455 } 2456 final long token = Binder.clearCallingIdentity(); 2457 try { 2458 synchronized (mSettingsLock) { 2459 mSettings.putGlobalString(mContentResolver, 2460 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS, 2461 TextUtils.join(",", enabledFormats)); 2462 } 2463 } finally { 2464 Binder.restoreCallingIdentity(token); 2465 } 2466 return true; 2467 } 2468 2469 /** @see AudioManager#setEncodedSurroundMode(int) */ 2470 @Override setEncodedSurroundMode(@udioManager.EncodedSurroundOutputMode int mode)2471 public boolean setEncodedSurroundMode(@AudioManager.EncodedSurroundOutputMode int mode) { 2472 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS) 2473 != PackageManager.PERMISSION_GRANTED) { 2474 throw new SecurityException("Missing WRITE_SETTINGS permission"); 2475 } 2476 2477 final long token = Binder.clearCallingIdentity(); 2478 try { 2479 synchronized (mSettingsLock) { 2480 mSettings.putGlobalInt(mContentResolver, 2481 Settings.Global.ENCODED_SURROUND_OUTPUT, 2482 toEncodedSurroundSetting(mode)); 2483 } 2484 } finally { 2485 Binder.restoreCallingIdentity(token); 2486 } 2487 return true; 2488 } 2489 2490 /** @see AudioManager#getEncodedSurroundMode() */ 2491 @Override getEncodedSurroundMode(int targetSdkVersion)2492 public int getEncodedSurroundMode(int targetSdkVersion) { 2493 final long token = Binder.clearCallingIdentity(); 2494 try { 2495 synchronized (mSettingsLock) { 2496 int encodedSurroundSetting = mSettings.getGlobalInt(mContentResolver, 2497 Settings.Global.ENCODED_SURROUND_OUTPUT, 2498 AudioManager.ENCODED_SURROUND_OUTPUT_AUTO); 2499 return toEncodedSurroundOutputMode(encodedSurroundSetting, targetSdkVersion); 2500 } 2501 } finally { 2502 Binder.restoreCallingIdentity(token); 2503 } 2504 } 2505 2506 /** @return the formats that are enabled in global settings */ getEnabledFormats()2507 private HashSet<Integer> getEnabledFormats() { 2508 HashSet<Integer> formats = new HashSet<>(); 2509 String enabledFormats = mSettings.getGlobalString(mContentResolver, 2510 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 2511 if (enabledFormats != null) { 2512 try { 2513 Arrays.stream(TextUtils.split(enabledFormats, ",")) 2514 .mapToInt(Integer::parseInt) 2515 .forEach(formats::add); 2516 } catch (NumberFormatException e) { 2517 Log.w(TAG, "ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS misformatted.", e); 2518 } 2519 } 2520 return formats; 2521 } 2522 2523 @SuppressWarnings("AndroidFrameworkCompatChange") 2524 @AudioManager.EncodedSurroundOutputMode toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion)2525 private int toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion) { 2526 if (targetSdkVersion <= Build.VERSION_CODES.S 2527 && encodedSurroundSetting > Settings.Global.ENCODED_SURROUND_SC_MAX) { 2528 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN; 2529 } 2530 switch (encodedSurroundSetting) { 2531 case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO: 2532 return AudioManager.ENCODED_SURROUND_OUTPUT_AUTO; 2533 case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER: 2534 return AudioManager.ENCODED_SURROUND_OUTPUT_NEVER; 2535 case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS: 2536 return AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS; 2537 case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL: 2538 return AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL; 2539 default: 2540 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN; 2541 } 2542 } 2543 toEncodedSurroundSetting( @udioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode)2544 private int toEncodedSurroundSetting( 2545 @AudioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode) { 2546 switch (encodedSurroundOutputMode) { 2547 case AudioManager.ENCODED_SURROUND_OUTPUT_NEVER: 2548 return Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER; 2549 case AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS: 2550 return Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS; 2551 case AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL: 2552 return Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL; 2553 default: 2554 return Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO; 2555 } 2556 } 2557 isSurroundFormat(int audioFormat)2558 private boolean isSurroundFormat(int audioFormat) { 2559 for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) { 2560 if (sf == audioFormat) { 2561 return true; 2562 } 2563 } 2564 return false; 2565 } 2566 sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate)2567 private void sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate) { 2568 if (mEncodedSurroundMode != Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL) { 2569 // Manually enable surround formats only when the setting is in manual mode. 2570 return; 2571 } 2572 String enabledSurroundFormats = mSettings.getGlobalString( 2573 cr, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 2574 if (enabledSurroundFormats == null) { 2575 // Never allow enabledSurroundFormats as a null, which could happen when 2576 // ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS is not appear in settings DB. 2577 enabledSurroundFormats = ""; 2578 } 2579 if (!forceUpdate && TextUtils.equals(enabledSurroundFormats, mEnabledSurroundFormats)) { 2580 // Update enabled surround formats to AudioPolicyManager only when forceUpdate 2581 // is true or enabled surround formats changed. 2582 return; 2583 } 2584 2585 mEnabledSurroundFormats = enabledSurroundFormats; 2586 String[] surroundFormats = TextUtils.split(enabledSurroundFormats, ","); 2587 ArrayList<Integer> formats = new ArrayList<>(); 2588 for (String format : surroundFormats) { 2589 try { 2590 int audioFormat = Integer.valueOf(format); 2591 if (isSurroundFormat(audioFormat) && !formats.contains(audioFormat)) { 2592 formats.add(audioFormat); 2593 } 2594 } catch (Exception e) { 2595 Log.e(TAG, "Invalid enabled surround format:" + format); 2596 } 2597 } 2598 // Set filtered surround formats to settings DB in case 2599 // there are invalid surround formats in original settings. 2600 mSettings.putGlobalString(mContext.getContentResolver(), 2601 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS, 2602 TextUtils.join(",", formats)); 2603 sendMsg(mAudioHandler, MSG_ENABLE_SURROUND_FORMATS, SENDMSG_QUEUE, 0, 0, formats, 0); 2604 } 2605 onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats)2606 private void onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats) { 2607 // Set surround format enabled accordingly. 2608 for (int surroundFormat : AudioFormat.SURROUND_SOUND_ENCODING) { 2609 boolean enabled = enabledSurroundFormats.contains(surroundFormat); 2610 int ret = AudioSystem.setSurroundFormatEnabled(surroundFormat, enabled); 2611 Log.i(TAG, "enable surround format:" + surroundFormat + " " + enabled + " " + ret); 2612 } 2613 } 2614 2615 @GuardedBy("mSettingsLock") updateAssistantUIdLocked(boolean forceUpdate)2616 private void updateAssistantUIdLocked(boolean forceUpdate) { 2617 int assistantUid = INVALID_UID; 2618 // Consider assistants in the following order of priority: 2619 // 1) apk in assistant role 2620 // 2) voice interaction service 2621 // 3) assistant service 2622 2623 String packageName = ""; 2624 if (mRoleObserver != null) { 2625 packageName = mRoleObserver.getAssistantRoleHolder(); 2626 } 2627 if (TextUtils.isEmpty(packageName)) { 2628 String assistantName = mSettings.getSecureStringForUser( 2629 mContentResolver, 2630 Settings.Secure.VOICE_INTERACTION_SERVICE, UserHandle.USER_CURRENT); 2631 if (TextUtils.isEmpty(assistantName)) { 2632 assistantName = mSettings.getSecureStringForUser( 2633 mContentResolver, 2634 Settings.Secure.ASSISTANT, UserHandle.USER_CURRENT); 2635 } 2636 if (!TextUtils.isEmpty(assistantName)) { 2637 ComponentName componentName = ComponentName.unflattenFromString(assistantName); 2638 if (componentName == null) { 2639 Slog.w(TAG, "Invalid service name for " 2640 + Settings.Secure.VOICE_INTERACTION_SERVICE + ": " + assistantName); 2641 return; 2642 } 2643 packageName = componentName.getPackageName(); 2644 } 2645 } 2646 if (!TextUtils.isEmpty(packageName)) { 2647 PackageManager pm = mContext.getPackageManager(); 2648 2649 if (pm.checkPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD, packageName) 2650 == PackageManager.PERMISSION_GRANTED) { 2651 try { 2652 assistantUid = pm.getPackageUidAsUser(packageName, getCurrentUserId()); 2653 } catch (PackageManager.NameNotFoundException e) { 2654 Log.e(TAG, 2655 "updateAssistantUId() could not find UID for package: " + packageName); 2656 } 2657 } 2658 } 2659 if ((mPrimaryAssistantUid != assistantUid) || forceUpdate) { 2660 mAssistantUids.remove(mPrimaryAssistantUid); 2661 mPrimaryAssistantUid = assistantUid; 2662 addAssistantServiceUidsLocked(new int[]{mPrimaryAssistantUid}); 2663 } 2664 } 2665 readPersistedSettings()2666 private void readPersistedSettings() { 2667 if (!mSystemServer.isPrivileged()) { 2668 return; 2669 } 2670 final ContentResolver cr = mContentResolver; 2671 2672 int ringerModeFromSettings = 2673 mSettings.getGlobalInt( 2674 cr, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL); 2675 int ringerMode = ringerModeFromSettings; 2676 // validity check in case the settings are restored from a device with incompatible 2677 // ringer modes 2678 if (!isValidRingerMode(ringerMode)) { 2679 ringerMode = AudioManager.RINGER_MODE_NORMAL; 2680 } 2681 if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { 2682 ringerMode = AudioManager.RINGER_MODE_SILENT; 2683 } 2684 if (ringerMode != ringerModeFromSettings) { 2685 mSettings.putGlobalInt(cr, Settings.Global.MODE_RINGER, ringerMode); 2686 } 2687 if (mUseFixedVolume || mIsSingleVolume) { 2688 ringerMode = AudioManager.RINGER_MODE_NORMAL; 2689 } 2690 synchronized(mSettingsLock) { 2691 mRingerMode = ringerMode; 2692 if (mRingerModeExternal == -1) { 2693 mRingerModeExternal = mRingerMode; 2694 } 2695 2696 // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting 2697 // are still needed while setVibrateSetting() and getVibrateSetting() are being 2698 // deprecated. 2699 mVibrateSetting = AudioSystem.getValueForVibrateSetting(0, 2700 AudioManager.VIBRATE_TYPE_NOTIFICATION, 2701 mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT 2702 : AudioManager.VIBRATE_SETTING_OFF); 2703 mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, 2704 AudioManager.VIBRATE_TYPE_RINGER, 2705 mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT 2706 : AudioManager.VIBRATE_SETTING_OFF); 2707 2708 updateRingerAndZenModeAffectedStreams(); 2709 readDockAudioSettings(cr); 2710 sendEncodedSurroundMode(cr, "readPersistedSettings"); 2711 sendEnabledSurroundFormats(cr, true); 2712 updateAssistantUIdLocked(/* forceUpdate= */ true); 2713 resetActiveAssistantUidsLocked(); 2714 AudioSystem.setRttEnabled(mRttEnabled); 2715 } 2716 2717 mMuteAffectedStreams = mSettings.getSystemIntForUser(cr, 2718 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED, 2719 UserHandle.USER_CURRENT); 2720 2721 updateMasterMono(cr); 2722 2723 updateMasterBalance(cr); 2724 2725 // Each stream will read its own persisted settings 2726 2727 // Broadcast the sticky intents 2728 broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal); 2729 broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode); 2730 2731 // Broadcast vibrate settings 2732 broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER); 2733 broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION); 2734 2735 // Load settings for the volume controller 2736 mVolumeController.loadSettings(cr); 2737 } 2738 2739 @GuardedBy("mSettingsLock") resetActiveAssistantUidsLocked()2740 private void resetActiveAssistantUidsLocked() { 2741 mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS; 2742 updateActiveAssistantServiceUids(); 2743 } 2744 readUserRestrictions()2745 private void readUserRestrictions() { 2746 if (!mSystemServer.isPrivileged()) { 2747 return; 2748 } 2749 final int currentUser = getCurrentUserId(); 2750 2751 // Check the current user restriction. 2752 boolean masterMute = 2753 mUserManagerInternal.getUserRestriction(currentUser, 2754 UserManager.DISALLOW_UNMUTE_DEVICE) 2755 || mUserManagerInternal.getUserRestriction(currentUser, 2756 UserManager.DISALLOW_ADJUST_VOLUME); 2757 if (mUseFixedVolume) { 2758 masterMute = false; 2759 AudioSystem.setMasterVolume(1.0f); 2760 } 2761 if (DEBUG_VOL) { 2762 Log.d(TAG, String.format("Master mute %s, user=%d", masterMute, currentUser)); 2763 } 2764 AudioSystem.setMasterMute(masterMute); 2765 broadcastMasterMuteStatus(masterMute); 2766 2767 mMicMuteFromRestrictions = mUserManagerInternal.getUserRestriction( 2768 currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE); 2769 if (DEBUG_VOL) { 2770 Log.d(TAG, String.format("Mic mute %b, user=%d", mMicMuteFromRestrictions, 2771 currentUser)); 2772 } 2773 setMicrophoneMuteNoCallerCheck(currentUser); 2774 } 2775 getIndexRange(int streamType)2776 private int getIndexRange(int streamType) { 2777 return (mStreamStates[streamType].getMaxIndex() - mStreamStates[streamType].getMinIndex()); 2778 } 2779 rescaleIndex(VolumeInfo volumeInfo, int dstStream)2780 private int rescaleIndex(VolumeInfo volumeInfo, int dstStream) { 2781 if (volumeInfo.getVolumeIndex() == VolumeInfo.INDEX_NOT_SET 2782 || volumeInfo.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET 2783 || volumeInfo.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) { 2784 Log.e(TAG, "rescaleIndex: volumeInfo has invalid index or range"); 2785 return mStreamStates[dstStream].getMinIndex(); 2786 } 2787 return rescaleIndex(volumeInfo.getVolumeIndex(), 2788 volumeInfo.getMinVolumeIndex(), volumeInfo.getMaxVolumeIndex(), 2789 mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex()); 2790 } 2791 rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo)2792 private int rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo) { 2793 int dstMin = dstVolumeInfo.getMinVolumeIndex(); 2794 int dstMax = dstVolumeInfo.getMaxVolumeIndex(); 2795 // Don't rescale index if the VolumeInfo is missing a min or max index 2796 if (dstMin == VolumeInfo.INDEX_NOT_SET || dstMax == VolumeInfo.INDEX_NOT_SET) { 2797 return index; 2798 } 2799 return rescaleIndex(index, 2800 mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(), 2801 dstMin, dstMax); 2802 } 2803 rescaleIndex(int index, int srcStream, int dstStream)2804 private int rescaleIndex(int index, int srcStream, int dstStream) { 2805 return rescaleIndex(index, 2806 mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(), 2807 mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex()); 2808 } 2809 rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax)2810 private int rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax) { 2811 int srcRange = srcMax - srcMin; 2812 int dstRange = dstMax - dstMin; 2813 if (srcRange == 0) { 2814 Log.e(TAG, "rescaleIndex : index range should not be zero"); 2815 return dstMin; 2816 } 2817 return dstMin + ((index - srcMin) * dstRange + srcRange / 2) / srcRange; 2818 } 2819 rescaleStep(int step, int srcStream, int dstStream)2820 private int rescaleStep(int step, int srcStream, int dstStream) { 2821 int srcRange = getIndexRange(srcStream); 2822 int dstRange = getIndexRange(dstStream); 2823 if (srcRange == 0) { 2824 Log.e(TAG, "rescaleStep : index range should not be zero"); 2825 return 0; 2826 } 2827 2828 return ((step * dstRange + srcRange / 2) / srcRange); 2829 } 2830 2831 /////////////////////////////////////////////////////////////////////////// 2832 // IPC methods 2833 /////////////////////////////////////////////////////////////////////////// 2834 /** 2835 * @see AudioManager#setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes) 2836 * @see AudioManager#setPreferredDevicesForStrategy(AudioProductStrategy, 2837 * List<AudioDeviceAttributes>) 2838 */ 2839 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices)2840 public int setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices) { 2841 super.setPreferredDevicesForStrategy_enforcePermission(); 2842 if (devices == null) { 2843 return AudioSystem.ERROR; 2844 } 2845 final String logString = String.format( 2846 "setPreferredDeviceForStrategy u/pid:%d/%d strat:%d dev:%s", 2847 Binder.getCallingUid(), Binder.getCallingPid(), strategy, 2848 devices.stream().map(e -> e.toString()).collect(Collectors.joining(","))); 2849 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 2850 if (devices.stream().anyMatch(device -> 2851 device.getRole() == AudioDeviceAttributes.ROLE_INPUT)) { 2852 Log.e(TAG, "Unsupported input routing in " + logString); 2853 return AudioSystem.ERROR; 2854 } 2855 2856 final int status = mDeviceBroker.setPreferredDevicesForStrategySync(strategy, devices); 2857 if (status != AudioSystem.SUCCESS) { 2858 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 2859 } 2860 2861 return status; 2862 } 2863 2864 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 2865 /** @see AudioManager#removePreferredDeviceForStrategy(AudioProductStrategy) */ removePreferredDevicesForStrategy(int strategy)2866 public int removePreferredDevicesForStrategy(int strategy) { 2867 super.removePreferredDevicesForStrategy_enforcePermission(); 2868 2869 final String logString = 2870 String.format("removePreferredDeviceForStrategy strat:%d", strategy); 2871 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 2872 2873 final int status = mDeviceBroker.removePreferredDevicesForStrategySync(strategy); 2874 if (status != AudioSystem.SUCCESS) { 2875 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 2876 } 2877 return status; 2878 } 2879 2880 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 2881 /** 2882 * @see AudioManager#getPreferredDeviceForStrategy(AudioProductStrategy) 2883 * @see AudioManager#getPreferredDevicesForStrategy(AudioProductStrategy) 2884 */ getPreferredDevicesForStrategy(int strategy)2885 public List<AudioDeviceAttributes> getPreferredDevicesForStrategy(int strategy) { 2886 super.getPreferredDevicesForStrategy_enforcePermission(); 2887 2888 List<AudioDeviceAttributes> devices = new ArrayList<>(); 2889 int status = AudioSystem.SUCCESS; 2890 final long identity = Binder.clearCallingIdentity(); 2891 try { 2892 status = AudioSystem.getDevicesForRoleAndStrategy( 2893 strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices); 2894 } finally { 2895 Binder.restoreCallingIdentity(identity); 2896 } 2897 if (status != AudioSystem.SUCCESS) { 2898 Log.e(TAG, String.format("Error %d in getPreferredDeviceForStrategy(%d)", 2899 status, strategy)); 2900 return new ArrayList<AudioDeviceAttributes>(); 2901 } else { 2902 return devices; 2903 } 2904 } 2905 2906 /** 2907 * @see AudioManager#setDeviceAsNonDefaultForStrategy(AudioProductStrategy, 2908 * AudioDeviceAttributes) 2909 * @see AudioManager#setDeviceAsNonDefaultForStrategy(AudioProductStrategy, 2910 * List<AudioDeviceAttributes>) 2911 */ 2912 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) setDeviceAsNonDefaultForStrategy(int strategy, @NonNull AudioDeviceAttributes device)2913 public int setDeviceAsNonDefaultForStrategy(int strategy, 2914 @NonNull AudioDeviceAttributes device) { 2915 super.setDeviceAsNonDefaultForStrategy_enforcePermission(); 2916 Objects.requireNonNull(device); 2917 final String logString = String.format( 2918 "setDeviceAsNonDefaultForStrategy u/pid:%d/%d strat:%d dev:%s", 2919 Binder.getCallingUid(), Binder.getCallingPid(), strategy, device.toString()); 2920 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 2921 if (device.getRole() == AudioDeviceAttributes.ROLE_INPUT) { 2922 Log.e(TAG, "Unsupported input routing in " + logString); 2923 return AudioSystem.ERROR; 2924 } 2925 2926 final int status = mDeviceBroker.setDeviceAsNonDefaultForStrategySync(strategy, device); 2927 if (status != AudioSystem.SUCCESS) { 2928 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 2929 } 2930 2931 return status; 2932 } 2933 2934 /** 2935 * @see AudioManager#removeDeviceAsNonDefaultForStrategy(AudioProductStrategy, 2936 * AudioDeviceAttributes) 2937 */ 2938 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) removeDeviceAsNonDefaultForStrategy(int strategy, AudioDeviceAttributes device)2939 public int removeDeviceAsNonDefaultForStrategy(int strategy, 2940 AudioDeviceAttributes device) { 2941 super.removeDeviceAsNonDefaultForStrategy_enforcePermission(); 2942 Objects.requireNonNull(device); 2943 final String logString = String.format( 2944 "removeDeviceAsNonDefaultForStrategy strat:%d dev:%s", strategy, device.toString()); 2945 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 2946 if (device.getRole() == AudioDeviceAttributes.ROLE_INPUT) { 2947 Log.e(TAG, "Unsupported input routing in " + logString); 2948 return AudioSystem.ERROR; 2949 } 2950 2951 final int status = mDeviceBroker.removeDeviceAsNonDefaultForStrategySync(strategy, device); 2952 if (status != AudioSystem.SUCCESS) { 2953 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 2954 } 2955 return status; 2956 } 2957 2958 /** 2959 * @see AudioManager#getNonDefaultDevicesForStrategy(AudioProductStrategy) 2960 */ 2961 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) getNonDefaultDevicesForStrategy(int strategy)2962 public List<AudioDeviceAttributes> getNonDefaultDevicesForStrategy(int strategy) { 2963 super.getNonDefaultDevicesForStrategy_enforcePermission(); 2964 List<AudioDeviceAttributes> devices = new ArrayList<>(); 2965 int status = AudioSystem.ERROR; 2966 2967 try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { 2968 status = AudioSystem.getDevicesForRoleAndStrategy( 2969 strategy, AudioSystem.DEVICE_ROLE_DISABLED, devices); 2970 } 2971 2972 if (status != AudioSystem.SUCCESS) { 2973 Log.e(TAG, String.format("Error %d in getNonDefaultDeviceForStrategy(%d)", 2974 status, strategy)); 2975 return new ArrayList<AudioDeviceAttributes>(); 2976 } else { 2977 return devices; 2978 } 2979 } 2980 2981 /** @see AudioManager#addOnPreferredDevicesForStrategyChangedListener( 2982 * Executor, AudioManager.OnPreferredDevicesForStrategyChangedListener) 2983 */ registerStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)2984 public void registerStrategyPreferredDevicesDispatcher( 2985 @Nullable IStrategyPreferredDevicesDispatcher dispatcher) { 2986 if (dispatcher == null) { 2987 return; 2988 } 2989 enforceModifyAudioRoutingPermission(); 2990 mDeviceBroker.registerStrategyPreferredDevicesDispatcher(dispatcher); 2991 } 2992 2993 /** @see AudioManager#removeOnPreferredDevicesForStrategyChangedListener( 2994 * AudioManager.OnPreferredDevicesForStrategyChangedListener) 2995 */ unregisterStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)2996 public void unregisterStrategyPreferredDevicesDispatcher( 2997 @Nullable IStrategyPreferredDevicesDispatcher dispatcher) { 2998 if (dispatcher == null) { 2999 return; 3000 } 3001 enforceModifyAudioRoutingPermission(); 3002 mDeviceBroker.unregisterStrategyPreferredDevicesDispatcher(dispatcher); 3003 } 3004 3005 /** @see AudioManager#addOnNonDefaultDevicesForStrategyChangedListener( 3006 * Executor, AudioManager.OnNonDefaultDevicesForStrategyChangedListener) 3007 */ registerStrategyNonDefaultDevicesDispatcher( @ullable IStrategyNonDefaultDevicesDispatcher dispatcher)3008 public void registerStrategyNonDefaultDevicesDispatcher( 3009 @Nullable IStrategyNonDefaultDevicesDispatcher dispatcher) { 3010 if (dispatcher == null) { 3011 return; 3012 } 3013 enforceModifyAudioRoutingPermission(); 3014 mDeviceBroker.registerStrategyNonDefaultDevicesDispatcher(dispatcher); 3015 } 3016 3017 /** @see AudioManager#removeOnNonDefaultDevicesForStrategyChangedListener( 3018 * AudioManager.OnNonDefaultDevicesForStrategyChangedListener) 3019 */ unregisterStrategyNonDefaultDevicesDispatcher( @ullable IStrategyNonDefaultDevicesDispatcher dispatcher)3020 public void unregisterStrategyNonDefaultDevicesDispatcher( 3021 @Nullable IStrategyNonDefaultDevicesDispatcher dispatcher) { 3022 if (dispatcher == null) { 3023 return; 3024 } 3025 enforceModifyAudioRoutingPermission(); 3026 mDeviceBroker.unregisterStrategyNonDefaultDevicesDispatcher(dispatcher); 3027 } 3028 3029 /** 3030 * @see AudioManager#setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes) 3031 */ setPreferredDevicesForCapturePreset( int capturePreset, List<AudioDeviceAttributes> devices)3032 public int setPreferredDevicesForCapturePreset( 3033 int capturePreset, List<AudioDeviceAttributes> devices) { 3034 if (devices == null) { 3035 return AudioSystem.ERROR; 3036 } 3037 enforceModifyAudioRoutingPermission(); 3038 final String logString = String.format( 3039 "setPreferredDevicesForCapturePreset u/pid:%d/%d source:%d dev:%s", 3040 Binder.getCallingUid(), Binder.getCallingPid(), capturePreset, 3041 devices.stream().map(e -> e.toString()).collect(Collectors.joining(","))); 3042 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 3043 if (devices.stream().anyMatch(device -> 3044 device.getRole() == AudioDeviceAttributes.ROLE_OUTPUT)) { 3045 Log.e(TAG, "Unsupported output routing in " + logString); 3046 return AudioSystem.ERROR; 3047 } 3048 3049 final int status = mDeviceBroker.setPreferredDevicesForCapturePresetSync( 3050 capturePreset, devices); 3051 if (status != AudioSystem.SUCCESS) { 3052 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 3053 } 3054 3055 return status; 3056 } 3057 3058 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 3059 /** @see AudioManager#clearPreferredDevicesForCapturePreset(int) */ clearPreferredDevicesForCapturePreset(int capturePreset)3060 public int clearPreferredDevicesForCapturePreset(int capturePreset) { 3061 super.clearPreferredDevicesForCapturePreset_enforcePermission(); 3062 3063 final String logString = String.format( 3064 "removePreferredDeviceForCapturePreset source:%d", capturePreset); 3065 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 3066 3067 final int status = mDeviceBroker.clearPreferredDevicesForCapturePresetSync(capturePreset); 3068 if (status != AudioSystem.SUCCESS) { 3069 Log.e(TAG, String.format("Error %d in %s", status, logString)); 3070 } 3071 return status; 3072 } 3073 3074 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 3075 /** 3076 * @see AudioManager#getPreferredDevicesForCapturePreset(int) 3077 */ getPreferredDevicesForCapturePreset(int capturePreset)3078 public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) { 3079 super.getPreferredDevicesForCapturePreset_enforcePermission(); 3080 3081 List<AudioDeviceAttributes> devices = new ArrayList<>(); 3082 int status = AudioSystem.SUCCESS; 3083 final long identity = Binder.clearCallingIdentity(); 3084 try { 3085 status = AudioSystem.getDevicesForRoleAndCapturePreset( 3086 capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices); 3087 } finally { 3088 Binder.restoreCallingIdentity(identity); 3089 } 3090 if (status != AudioSystem.SUCCESS) { 3091 Log.e(TAG, String.format("Error %d in getPreferredDeviceForCapturePreset(%d)", 3092 status, capturePreset)); 3093 return new ArrayList<AudioDeviceAttributes>(); 3094 } else { 3095 return devices; 3096 } 3097 } 3098 3099 /** 3100 * @see AudioManager#addOnPreferredDevicesForCapturePresetChangedListener( 3101 * Executor, OnPreferredDevicesForCapturePresetChangedListener) 3102 */ registerCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)3103 public void registerCapturePresetDevicesRoleDispatcher( 3104 @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) { 3105 if (dispatcher == null) { 3106 return; 3107 } 3108 enforceModifyAudioRoutingPermission(); 3109 mDeviceBroker.registerCapturePresetDevicesRoleDispatcher(dispatcher); 3110 } 3111 3112 /** 3113 * @see AudioManager#removeOnPreferredDevicesForCapturePresetChangedListener( 3114 * AudioManager.OnPreferredDevicesForCapturePresetChangedListener) 3115 */ unregisterCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)3116 public void unregisterCapturePresetDevicesRoleDispatcher( 3117 @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) { 3118 if (dispatcher == null) { 3119 return; 3120 } 3121 enforceModifyAudioRoutingPermission(); 3122 mDeviceBroker.unregisterCapturePresetDevicesRoleDispatcher(dispatcher); 3123 } 3124 3125 /** @see AudioManager#getDevicesForAttributes(AudioAttributes) */ getDevicesForAttributes( @onNull AudioAttributes attributes)3126 public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes( 3127 @NonNull AudioAttributes attributes) { 3128 enforceQueryStateOrModifyRoutingPermission(); 3129 return getDevicesForAttributesInt(attributes, false /* forVolume */); 3130 } 3131 3132 /** @see AudioManager#getAudioDevicesForAttributes(AudioAttributes) 3133 * This method is similar with AudioService#getDevicesForAttributes, 3134 * only it doesn't enforce permissions because it is used by an unprivileged public API 3135 * instead of the system API. 3136 */ getDevicesForAttributesUnprotected( @onNull AudioAttributes attributes)3137 public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesUnprotected( 3138 @NonNull AudioAttributes attributes) { 3139 return getDevicesForAttributesInt(attributes, false /* forVolume */); 3140 } 3141 3142 /** 3143 * @see AudioManager#isMusicActive() 3144 * @param remotely true if query is for remote playback (cast), false for local playback. 3145 */ isMusicActive(boolean remotely)3146 public boolean isMusicActive(boolean remotely) { 3147 // no permission required 3148 final long token = Binder.clearCallingIdentity(); 3149 try { 3150 if (remotely) { 3151 return AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, 0); 3152 } else { 3153 return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0); 3154 } 3155 } finally { 3156 Binder.restoreCallingIdentity(token); 3157 } 3158 } 3159 getDevicesForAttributesInt( @onNull AudioAttributes attributes, boolean forVolume)3160 protected @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesInt( 3161 @NonNull AudioAttributes attributes, boolean forVolume) { 3162 Objects.requireNonNull(attributes); 3163 return mAudioSystem.getDevicesForAttributes(attributes, forVolume); 3164 } 3165 3166 /** 3167 * @see AudioManager#addOnDevicesForAttributesChangedListener( 3168 * AudioAttributes, Executor, OnDevicesForAttributesChangedListener) 3169 */ addOnDevicesForAttributesChangedListener(AudioAttributes attributes, IDevicesForAttributesCallback callback)3170 public void addOnDevicesForAttributesChangedListener(AudioAttributes attributes, 3171 IDevicesForAttributesCallback callback) { 3172 mAudioSystem.addOnDevicesForAttributesChangedListener( 3173 attributes, false /* forVolume */, callback); 3174 } 3175 3176 /** 3177 * @see AudioManager#removeOnDevicesForAttributesChangedListener( 3178 * OnDevicesForAttributesChangedListener) 3179 */ removeOnDevicesForAttributesChangedListener( IDevicesForAttributesCallback callback)3180 public void removeOnDevicesForAttributesChangedListener( 3181 IDevicesForAttributesCallback callback) { 3182 mAudioSystem.removeOnDevicesForAttributesChangedListener(callback); 3183 } 3184 3185 // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP, 3186 // KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE handleVolumeKey(@onNull KeyEvent event, boolean isOnTv, @NonNull String callingPackage, @NonNull String caller)3187 public void handleVolumeKey(@NonNull KeyEvent event, boolean isOnTv, 3188 @NonNull String callingPackage, @NonNull String caller) { 3189 int keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_NORMAL; 3190 if (isOnTv) { 3191 if (event.getAction() == KeyEvent.ACTION_DOWN) { 3192 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_START; 3193 } else { // may catch more than ACTION_UP, but will end vol adjustement 3194 // the vol key is either released (ACTION_UP), or multiple keys are pressed 3195 // (ACTION_MULTIPLE) and we don't know what to do for volume control on CEC, end 3196 // the repeated volume adjustement 3197 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_END; 3198 } 3199 } else if (event.getAction() != KeyEvent.ACTION_DOWN) { 3200 return; 3201 } 3202 3203 int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND 3204 | AudioManager.FLAG_FROM_KEY; 3205 3206 switch (event.getKeyCode()) { 3207 case KeyEvent.KEYCODE_VOLUME_UP: 3208 adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE, 3209 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 3210 Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode); 3211 break; 3212 case KeyEvent.KEYCODE_VOLUME_DOWN: 3213 adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER, 3214 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 3215 Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode); 3216 break; 3217 case KeyEvent.KEYCODE_VOLUME_MUTE: 3218 if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 3219 adjustSuggestedStreamVolume(AudioManager.ADJUST_TOGGLE_MUTE, 3220 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 3221 Binder.getCallingUid(), Binder.getCallingPid(), 3222 true, AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 3223 } 3224 break; 3225 default: 3226 Log.e(TAG, "Invalid key code " + event.getKeyCode() + " sent by " + callingPackage); 3227 return; // not needed but added if code gets added below this switch statement 3228 } 3229 } 3230 setNavigationRepeatSoundEffectsEnabled(boolean enabled)3231 public void setNavigationRepeatSoundEffectsEnabled(boolean enabled) { 3232 mNavigationRepeatSoundEffectsEnabled = enabled; 3233 } 3234 3235 /** 3236 * @return true if the fast scroll sound effects are enabled 3237 */ areNavigationRepeatSoundEffectsEnabled()3238 public boolean areNavigationRepeatSoundEffectsEnabled() { 3239 return mNavigationRepeatSoundEffectsEnabled; 3240 } 3241 setHomeSoundEffectEnabled(boolean enabled)3242 public void setHomeSoundEffectEnabled(boolean enabled) { 3243 mHomeSoundEffectEnabled = enabled; 3244 } 3245 3246 /** 3247 * @return true if the home sound effect is enabled 3248 */ isHomeSoundEffectEnabled()3249 public boolean isHomeSoundEffectEnabled() { 3250 return mHomeSoundEffectEnabled; 3251 } 3252 3253 /** 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)3254 private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, 3255 String callingPackage, String caller, int uid, int pid, boolean hasModifyAudioSettings, 3256 int keyEventMode) { 3257 if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType 3258 + ", flags=" + flags + ", caller=" + caller 3259 + ", volControlStream=" + mVolumeControlStream 3260 + ", userSelect=" + mUserSelectedVolumeControlStream); 3261 if (direction != AudioManager.ADJUST_SAME) { 3262 sVolumeLogger.enqueue( 3263 new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType, 3264 direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage) 3265 .append("/").append(caller).append(" uid:").append(uid).toString())); 3266 } 3267 3268 boolean hasExternalVolumeController = notifyExternalVolumeController(direction); 3269 3270 new MediaMetrics.Item(mMetricsId + "adjustSuggestedStreamVolume") 3271 .setUid(Binder.getCallingUid()) 3272 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage) 3273 .set(MediaMetrics.Property.CLIENT_NAME, caller) 3274 .set(MediaMetrics.Property.DIRECTION, direction > 0 3275 ? MediaMetrics.Value.UP : MediaMetrics.Value.DOWN) 3276 .set(MediaMetrics.Property.EXTERNAL, hasExternalVolumeController 3277 ? MediaMetrics.Value.YES : MediaMetrics.Value.NO) 3278 .set(MediaMetrics.Property.FLAGS, flags) 3279 .record(); 3280 3281 if (hasExternalVolumeController) { 3282 return; 3283 } 3284 3285 final int streamType; 3286 synchronized (mForceControlStreamLock) { 3287 // Request lock in case mVolumeControlStream is changed by other thread. 3288 if (mUserSelectedVolumeControlStream) { // implies mVolumeControlStream != -1 3289 streamType = mVolumeControlStream; 3290 } else { 3291 // TODO discard activity on a muted stream? 3292 final int maybeActiveStreamType = getActiveStreamType(suggestedStreamType); 3293 final boolean activeForReal; 3294 if (maybeActiveStreamType == AudioSystem.STREAM_RING 3295 || maybeActiveStreamType == AudioSystem.STREAM_NOTIFICATION) { 3296 activeForReal = wasStreamActiveRecently(maybeActiveStreamType, 0); 3297 } else { 3298 activeForReal = mAudioSystem.isStreamActive(maybeActiveStreamType, 0); 3299 } 3300 if (activeForReal || mVolumeControlStream == -1) { 3301 streamType = maybeActiveStreamType; 3302 } else { 3303 streamType = mVolumeControlStream; 3304 } 3305 } 3306 } 3307 3308 final boolean isMute = isMuteAdjust(direction); 3309 3310 ensureValidStreamType(streamType); 3311 final int resolvedStream = mStreamVolumeAlias[streamType]; 3312 3313 // Play sounds on STREAM_RING only. 3314 if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 && 3315 resolvedStream != AudioSystem.STREAM_RING) { 3316 flags &= ~AudioManager.FLAG_PLAY_SOUND; 3317 } 3318 3319 // For notifications/ring, show the ui before making any adjustments 3320 // Don't suppress mute/unmute requests 3321 // Don't suppress adjustments for single volume device 3322 if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute) 3323 && !mIsSingleVolume) { 3324 direction = 0; 3325 flags &= ~AudioManager.FLAG_PLAY_SOUND; 3326 flags &= ~AudioManager.FLAG_VIBRATE; 3327 if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment"); 3328 } 3329 3330 adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid, pid, 3331 null, hasModifyAudioSettings, keyEventMode); 3332 } 3333 notifyExternalVolumeController(int direction)3334 private boolean notifyExternalVolumeController(int direction) { 3335 final IAudioPolicyCallback externalVolumeController; 3336 synchronized (mExtVolumeControllerLock) { 3337 externalVolumeController = mExtVolumeController; 3338 } 3339 if (externalVolumeController == null) { 3340 return false; 3341 } 3342 3343 sendMsg(mAudioHandler, MSG_NOTIFY_VOL_EVENT, SENDMSG_QUEUE, 3344 direction, 0 /*ignored*/, 3345 externalVolumeController, 0 /*delay*/); 3346 return true; 3347 } 3348 3349 /** Retain API for unsupported app usage */ adjustStreamVolume(int streamType, int direction, int flags, String callingPackage)3350 public void adjustStreamVolume(int streamType, int direction, int flags, 3351 String callingPackage) { 3352 adjustStreamVolumeWithAttribution(streamType, direction, flags, callingPackage, null); 3353 } 3354 3355 /** @see AudioManager#adjustStreamVolume(int, int, int) 3356 * Part of service interface, check permissions here */ adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, String callingPackage, String attributionTag)3357 public void adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, 3358 String callingPackage, String attributionTag) { 3359 if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { 3360 Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without" 3361 + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage); 3362 return; 3363 } 3364 3365 final VolumeEvent evt = new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType, 3366 direction/*val1*/, flags/*val2*/, callingPackage); 3367 sVolumeLogger.enqueue(evt); 3368 // also logging mute/unmute calls to the dedicated logger 3369 if (isMuteAdjust(direction)) { 3370 sMuteLogger.enqueue(evt); 3371 } 3372 adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage, 3373 Binder.getCallingUid(), Binder.getCallingPid(), attributionTag, 3374 callingHasAudioSettingsPermission(), AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 3375 } 3376 adjustStreamVolume(int streamType, int direction, int flags, String callingPackage, String caller, int uid, int pid, String attributionTag, boolean hasModifyAudioSettings, int keyEventMode)3377 protected void adjustStreamVolume(int streamType, int direction, int flags, 3378 String callingPackage, String caller, int uid, int pid, String attributionTag, 3379 boolean hasModifyAudioSettings, int keyEventMode) { 3380 if (mUseFixedVolume) { 3381 return; 3382 } 3383 if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction 3384 + ", flags=" + flags + ", caller=" + caller); 3385 3386 ensureValidDirection(direction); 3387 ensureValidStreamType(streamType); 3388 3389 boolean isMuteAdjust = isMuteAdjust(direction); 3390 3391 if (isMuteAdjust && !isStreamAffectedByMute(streamType)) { 3392 return; 3393 } 3394 3395 // If adjust is mute and the stream is STREAM_VOICE_CALL or STREAM_BLUETOOTH_SCO, make sure 3396 // that the calling app have the MODIFY_PHONE_STATE permission. 3397 if (isMuteAdjust && 3398 (streamType == AudioSystem.STREAM_VOICE_CALL || 3399 streamType == AudioSystem.STREAM_BLUETOOTH_SCO) && 3400 mContext.checkPermission(android.Manifest.permission.MODIFY_PHONE_STATE, pid, uid) 3401 != PackageManager.PERMISSION_GRANTED) { 3402 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: adjustStreamVolume from pid=" 3403 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 3404 return; 3405 } 3406 3407 // If the stream is STREAM_ASSISTANT, 3408 // make sure that the calling app have the MODIFY_AUDIO_ROUTING permission. 3409 if (streamType == AudioSystem.STREAM_ASSISTANT && 3410 mContext.checkPermission( 3411 android.Manifest.permission.MODIFY_AUDIO_ROUTING, pid, uid) 3412 != PackageManager.PERMISSION_GRANTED) { 3413 Log.w(TAG, "MODIFY_AUDIO_ROUTING Permission Denial: adjustStreamVolume from pid=" 3414 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 3415 return; 3416 } 3417 3418 // use stream type alias here so that streams with same alias have the same behavior, 3419 // including with regard to silent mode control (e.g the use of STREAM_RING below and in 3420 // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION) 3421 int streamTypeAlias = mStreamVolumeAlias[streamType]; 3422 3423 VolumeStreamState streamState = mStreamStates[streamTypeAlias]; 3424 3425 final int device = getDeviceForStream(streamTypeAlias); 3426 3427 int aliasIndex = streamState.getIndex(device); 3428 boolean adjustVolume = true; 3429 int step; 3430 3431 // skip a2dp absolute volume control request when the device 3432 // is neither an a2dp device nor BLE device 3433 if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 3434 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device)) 3435 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { 3436 return; 3437 } 3438 3439 // If we are being called by the system (e.g. hardware keys) check for current user 3440 // so we handle user restrictions correctly. 3441 if (uid == android.os.Process.SYSTEM_UID) { 3442 uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); 3443 } 3444 // validate calling package and app op 3445 if (!checkNoteAppOp( 3446 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) { 3447 return; 3448 } 3449 3450 mSoundDoseHelper.invalidatPendingVolumeCommand(); 3451 3452 flags &= ~AudioManager.FLAG_FIXED_VOLUME; 3453 if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) { 3454 flags |= AudioManager.FLAG_FIXED_VOLUME; 3455 3456 // Always toggle between max safe volume and 0 for fixed volume devices where safe 3457 // volume is enforced, and max and 0 for the others. 3458 // This is simulated by stepping by the full allowed volume range 3459 step = mSoundDoseHelper.getSafeMediaVolumeIndex(device); 3460 if (step < 0) { 3461 step = streamState.getMaxIndex(); 3462 } 3463 if (aliasIndex != 0) { 3464 aliasIndex = step; 3465 } 3466 } else { 3467 // convert one UI step (+/-1) into a number of internal units on the stream alias 3468 step = rescaleStep(10, streamType, streamTypeAlias); 3469 } 3470 3471 // If either the client forces allowing ringer modes for this adjustment, 3472 // or stream is used for UI sonification 3473 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 3474 (isUiSoundsStreamType(streamTypeAlias))) { 3475 int ringerMode = getRingerModeInternal(); 3476 // do not vibrate if already in vibrate mode 3477 if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { 3478 flags &= ~AudioManager.FLAG_VIBRATE; 3479 } 3480 // Check if the ringer mode handles this adjustment. If it does we don't 3481 // need to adjust the volume further. 3482 final int result = checkForRingerModeChange(aliasIndex, direction, step, 3483 streamState.mIsMuted, callingPackage, flags); 3484 adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0; 3485 // If suppressing a volume adjustment in silent mode, display the UI hint 3486 if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) { 3487 flags |= AudioManager.FLAG_SHOW_SILENT_HINT; 3488 } 3489 // If suppressing a volume down adjustment in vibrate mode, display the UI hint 3490 if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) { 3491 flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT; 3492 } 3493 } else if (isStreamMutedByRingerOrZenMode(streamTypeAlias) && streamState.mIsMuted) { 3494 // if the stream is currently muted streams by ringer/zen mode 3495 // then it cannot be unmuted (without FLAG_ALLOW_RINGER_MODES) with an unmute or raise 3496 if (direction == AudioManager.ADJUST_TOGGLE_MUTE 3497 || direction == AudioManager.ADJUST_UNMUTE 3498 || direction == AudioManager.ADJUST_RAISE) { 3499 adjustVolume = false; 3500 } 3501 } 3502 3503 // If the ringer mode or zen is muting the stream, do not change stream unless 3504 // it'll cause us to exit dnd 3505 if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) { 3506 adjustVolume = false; 3507 } 3508 int oldIndex = mStreamStates[streamType].getIndex(device); 3509 3510 // Check if the volume adjustment should be handled by an absolute volume controller instead 3511 if (isAbsoluteVolumeDevice(device) 3512 && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) { 3513 AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device); 3514 if (info.mHandlesVolumeAdjustment) { 3515 dispatchAbsoluteVolumeAdjusted(streamType, info, oldIndex, direction, 3516 keyEventMode); 3517 return; 3518 } 3519 } 3520 3521 if (adjustVolume && (direction != AudioManager.ADJUST_SAME) 3522 && (keyEventMode != AudioDeviceVolumeManager.ADJUST_MODE_END)) { 3523 mAudioHandler.removeMessages(MSG_UNMUTE_STREAM); 3524 3525 if (isMuteAdjust && !mFullVolumeDevices.contains(device)) { 3526 boolean state; 3527 if (direction == AudioManager.ADJUST_TOGGLE_MUTE) { 3528 state = !streamState.mIsMuted; 3529 } else { 3530 state = direction == AudioManager.ADJUST_MUTE; 3531 } 3532 muteAliasStreams(streamTypeAlias, state); 3533 } else if ((direction == AudioManager.ADJUST_RAISE) 3534 && mSoundDoseHelper.raiseVolumeDisplaySafeMediaVolume(streamTypeAlias, 3535 aliasIndex + step, device, flags)) { 3536 Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex); 3537 } else if (!isFullVolumeDevice(device) 3538 && (streamState.adjustIndex(direction * step, device, caller, 3539 hasModifyAudioSettings) 3540 || streamState.mIsMuted)) { 3541 // Post message to set system volume (it in turn will post a 3542 // message to persist). 3543 if (streamState.mIsMuted) { 3544 // Unmute the stream if it was previously muted 3545 if (direction == AudioManager.ADJUST_RAISE) { 3546 // unmute immediately for volume up 3547 muteAliasStreams(streamTypeAlias, false); 3548 } else if (direction == AudioManager.ADJUST_LOWER) { 3549 if (mIsSingleVolume) { 3550 sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE, 3551 streamTypeAlias, flags, null, UNMUTE_STREAM_DELAY); 3552 } 3553 } 3554 } 3555 sendMsg(mAudioHandler, 3556 MSG_SET_DEVICE_VOLUME, 3557 SENDMSG_QUEUE, 3558 device, 3559 0, 3560 streamState, 3561 0); 3562 } 3563 3564 int newIndex = mStreamStates[streamType].getIndex(device); 3565 3566 // Check if volume update should be send to AVRCP 3567 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 3568 && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 3569 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 3570 if (DEBUG_VOL) { 3571 Log.d(TAG, "adjustSreamVolume: postSetAvrcpAbsoluteVolumeIndex index=" 3572 + newIndex + "stream=" + streamType); 3573 } 3574 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10); 3575 } else if (isAbsoluteVolumeDevice(device) 3576 && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) { 3577 AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device); 3578 dispatchAbsoluteVolumeChanged(streamType, info, newIndex); 3579 } 3580 3581 if (AudioSystem.isLeAudioDeviceType(device) 3582 && streamType == getBluetoothContextualVolumeStream() 3583 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 3584 if (DEBUG_VOL) { 3585 Log.d(TAG, "adjustSreamVolume postSetLeAudioVolumeIndex index=" 3586 + newIndex + " stream=" + streamType); 3587 } 3588 mDeviceBroker.postSetLeAudioVolumeIndex(newIndex, 3589 mStreamStates[streamType].getMaxIndex(), streamType); 3590 } 3591 3592 // Check if volume update should be send to Hearing Aid 3593 if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 3594 // only modify the hearing aid attenuation when the stream to modify matches 3595 // the one expected by the hearing aid 3596 if (streamType == getBluetoothContextualVolumeStream()) { 3597 if (DEBUG_VOL) { 3598 Log.d(TAG, "adjustSreamVolume postSetHearingAidVolumeIndex index=" 3599 + newIndex + " stream=" + streamType); 3600 } 3601 mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType); 3602 } 3603 } 3604 } 3605 3606 final int newIndex = mStreamStates[streamType].getIndex(device); 3607 3608 if (adjustVolume) { 3609 synchronized (mHdmiClientLock) { 3610 if (mHdmiManager != null) { 3611 // At most one of mHdmiPlaybackClient and mHdmiTvClient should be non-null 3612 HdmiClient fullVolumeHdmiClient = mHdmiPlaybackClient; 3613 if (mHdmiTvClient != null) { 3614 fullVolumeHdmiClient = mHdmiTvClient; 3615 } 3616 3617 if (fullVolumeHdmiClient != null 3618 && mHdmiCecVolumeControlEnabled 3619 && streamTypeAlias == AudioSystem.STREAM_MUSIC 3620 // vol change on a full volume device 3621 && isFullVolumeDevice(device)) { 3622 int keyCode = KeyEvent.KEYCODE_UNKNOWN; 3623 switch (direction) { 3624 case AudioManager.ADJUST_RAISE: 3625 keyCode = KeyEvent.KEYCODE_VOLUME_UP; 3626 break; 3627 case AudioManager.ADJUST_LOWER: 3628 keyCode = KeyEvent.KEYCODE_VOLUME_DOWN; 3629 break; 3630 case AudioManager.ADJUST_TOGGLE_MUTE: 3631 case AudioManager.ADJUST_MUTE: 3632 case AudioManager.ADJUST_UNMUTE: 3633 // Many CEC devices only support toggle mute. Therefore, we send the 3634 // same keycode for all three mute options. 3635 keyCode = KeyEvent.KEYCODE_VOLUME_MUTE; 3636 break; 3637 default: 3638 break; 3639 } 3640 if (keyCode != KeyEvent.KEYCODE_UNKNOWN) { 3641 final long ident = Binder.clearCallingIdentity(); 3642 try { 3643 switch (keyEventMode) { 3644 case AudioDeviceVolumeManager.ADJUST_MODE_NORMAL: 3645 fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, true); 3646 fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, false); 3647 break; 3648 case AudioDeviceVolumeManager.ADJUST_MODE_START: 3649 fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, true); 3650 break; 3651 case AudioDeviceVolumeManager.ADJUST_MODE_END: 3652 fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, false); 3653 break; 3654 default: 3655 Log.e(TAG, "Invalid keyEventMode " + keyEventMode); 3656 } 3657 } finally { 3658 Binder.restoreCallingIdentity(ident); 3659 } 3660 } 3661 } 3662 3663 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 3664 && (oldIndex != newIndex || isMuteAdjust)) { 3665 maybeSendSystemAudioStatusCommand(isMuteAdjust); 3666 } 3667 } 3668 } 3669 } 3670 sendVolumeUpdate(streamType, oldIndex, newIndex, flags, device); 3671 } 3672 3673 /** 3674 * Loops on aliasted stream, update the mute cache attribute of each 3675 * {@see AudioService#VolumeStreamState}, and then apply the change. 3676 * It prevents to unnecessary {@see AudioSystem#setStreamVolume} done for each stream 3677 * and aliases before mute change changed and after. 3678 */ muteAliasStreams(int streamAlias, boolean state)3679 private void muteAliasStreams(int streamAlias, boolean state) { 3680 // Locking mSettingsLock to avoid inversion when calling doMute -> updateVolumeGroupIndex 3681 synchronized (mSettingsLock) { 3682 synchronized (VolumeStreamState.class) { 3683 List<Integer> streamsToMute = new ArrayList<>(); 3684 for (int stream = 0; stream < mStreamStates.length; stream++) { 3685 VolumeStreamState vss = mStreamStates[stream]; 3686 if (streamAlias == mStreamVolumeAlias[stream] && vss.isMutable()) { 3687 if (!(mCameraSoundForced 3688 && (vss.getStreamType() 3689 == AudioSystem.STREAM_SYSTEM_ENFORCED))) { 3690 boolean changed = vss.mute(state, /* apply= */ false, 3691 "muteAliasStreams"); 3692 if (changed) { 3693 streamsToMute.add(stream); 3694 } 3695 } 3696 } 3697 } 3698 streamsToMute.forEach(streamToMute -> { 3699 mStreamStates[streamToMute].doMute(); 3700 broadcastMuteSetting(streamToMute, state); 3701 }); 3702 } 3703 } 3704 } 3705 broadcastMuteSetting(int streamType, boolean isMuted)3706 private void broadcastMuteSetting(int streamType, boolean isMuted) { 3707 // Stream mute changed, fire the intent. 3708 Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION); 3709 intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType); 3710 intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, isMuted); 3711 sendBroadcastToAll(intent, null /* options */); 3712 } 3713 3714 // Called after a delay when volume down is pressed while muted onUnmuteStream(int stream, int flags)3715 private void onUnmuteStream(int stream, int flags) { 3716 boolean wasMuted; 3717 // Locking mSettingsLock to avoid inversion when calling vss.mute -> vss.doMute -> 3718 // vss.updateVolumeGroupIndex 3719 synchronized (mSettingsLock) { 3720 synchronized (VolumeStreamState.class) { 3721 final VolumeStreamState streamState = mStreamStates[stream]; 3722 // if unmuting causes a change, it was muted 3723 wasMuted = streamState.mute(false, "onUnmuteStream"); 3724 3725 final int device = getDeviceForStream(stream); 3726 final int index = streamState.getIndex(device); 3727 sendVolumeUpdate(stream, index, index, flags, device); 3728 } 3729 if (stream == AudioSystem.STREAM_MUSIC && wasMuted) { 3730 synchronized (mHdmiClientLock) { 3731 maybeSendSystemAudioStatusCommand(true); 3732 } 3733 } 3734 } 3735 } 3736 3737 @GuardedBy("mHdmiClientLock") maybeSendSystemAudioStatusCommand(boolean isMuteAdjust)3738 private void maybeSendSystemAudioStatusCommand(boolean isMuteAdjust) { 3739 if (mHdmiAudioSystemClient == null 3740 || !mHdmiSystemAudioSupported 3741 || !mHdmiCecVolumeControlEnabled) { 3742 return; 3743 } 3744 3745 final long identity = Binder.clearCallingIdentity(); 3746 try { 3747 mHdmiAudioSystemClient.sendReportAudioStatusCecCommand( 3748 isMuteAdjust, getStreamVolume(AudioSystem.STREAM_MUSIC), 3749 getStreamMaxVolume(AudioSystem.STREAM_MUSIC), 3750 isStreamMute(AudioSystem.STREAM_MUSIC)); 3751 } finally { 3752 Binder.restoreCallingIdentity(identity); 3753 } 3754 } 3755 getNewRingerMode(int stream, int index, int flags)3756 private int getNewRingerMode(int stream, int index, int flags) { 3757 // setRingerMode does nothing if the device is single volume,so the value would be unchanged 3758 if (mIsSingleVolume) { 3759 return getRingerModeExternal(); 3760 } 3761 3762 // setting volume on ui sounds stream type also controls silent mode 3763 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 3764 (stream == getUiSoundsStreamType())) { 3765 int newRingerMode; 3766 if (index == 0) { 3767 newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE 3768 : mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT 3769 : AudioManager.RINGER_MODE_NORMAL; 3770 } else { 3771 newRingerMode = AudioManager.RINGER_MODE_NORMAL; 3772 } 3773 return newRingerMode; 3774 } 3775 return getRingerModeExternal(); 3776 } 3777 isAndroidNPlus(String caller)3778 private boolean isAndroidNPlus(String caller) { 3779 try { 3780 final ApplicationInfo applicationInfo = 3781 mContext.getPackageManager().getApplicationInfoAsUser( 3782 caller, 0, UserHandle.getUserId(Binder.getCallingUid())); 3783 if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) { 3784 return true; 3785 } 3786 return false; 3787 } catch (PackageManager.NameNotFoundException e) { 3788 return true; 3789 } 3790 } 3791 wouldToggleZenMode(int newMode)3792 private boolean wouldToggleZenMode(int newMode) { 3793 if (getRingerModeExternal() == AudioManager.RINGER_MODE_SILENT 3794 && newMode != AudioManager.RINGER_MODE_SILENT) { 3795 return true; 3796 } else if (getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT 3797 && newMode == AudioManager.RINGER_MODE_SILENT) { 3798 return true; 3799 } 3800 return false; 3801 } 3802 3803 /** 3804 * Update stream volume, ringer mode and mute status after a volume index change 3805 * @param streamType 3806 * @param index 3807 * @param flags 3808 * @param device the device for which the volume is changed 3809 * @param caller 3810 * @param hasModifyAudioSettings 3811 * @param canChangeMute true if the origin of this event is one where the mute state should be 3812 * updated following the change in volume index 3813 */ onSetStreamVolume(int streamType, int index, int flags, int device, String caller, boolean hasModifyAudioSettings, boolean canChangeMute)3814 /*package*/ void onSetStreamVolume(int streamType, int index, int flags, int device, 3815 String caller, boolean hasModifyAudioSettings, boolean canChangeMute) { 3816 final int stream = mStreamVolumeAlias[streamType]; 3817 // setting volume on ui sounds stream type also controls silent mode 3818 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 3819 (stream == getUiSoundsStreamType())) { 3820 setRingerMode(getNewRingerMode(stream, index, flags), 3821 TAG + ".onSetStreamVolume", false /*external*/); 3822 } 3823 setStreamVolumeInt(stream, index, device, false, caller, hasModifyAudioSettings); 3824 // setting non-zero volume for a muted stream unmutes the stream and vice versa 3825 // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements 3826 if ((streamType != AudioSystem.STREAM_BLUETOOTH_SCO) && canChangeMute) { 3827 // As adjustStreamVolume with muteAdjust flags mute/unmutes stream and aliased streams. 3828 muteAliasStreams(stream, index == 0); 3829 } 3830 } 3831 enforceModifyAudioRoutingPermission()3832 private void enforceModifyAudioRoutingPermission() { 3833 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 3834 != PackageManager.PERMISSION_GRANTED) { 3835 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission"); 3836 } 3837 } 3838 enforceAccessUltrasoundPermission()3839 private void enforceAccessUltrasoundPermission() { 3840 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.ACCESS_ULTRASOUND) 3841 != PackageManager.PERMISSION_GRANTED) { 3842 throw new SecurityException("Missing ACCESS_ULTRASOUND permission"); 3843 } 3844 } 3845 enforceQueryStatePermission()3846 private void enforceQueryStatePermission() { 3847 if (mContext.checkCallingOrSelfPermission(Manifest.permission.QUERY_AUDIO_STATE) 3848 != PackageManager.PERMISSION_GRANTED) { 3849 throw new SecurityException("Missing QUERY_AUDIO_STATE permissions"); 3850 } 3851 } 3852 enforceQueryStateOrModifyRoutingPermission()3853 private void enforceQueryStateOrModifyRoutingPermission() { 3854 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 3855 != PackageManager.PERMISSION_GRANTED 3856 && mContext.checkCallingOrSelfPermission(Manifest.permission.QUERY_AUDIO_STATE) 3857 != PackageManager.PERMISSION_GRANTED) { 3858 throw new SecurityException( 3859 "Missing MODIFY_AUDIO_ROUTING or QUERY_AUDIO_STATE permissions"); 3860 } 3861 } 3862 enforceCallAudioInterceptionPermission()3863 private void enforceCallAudioInterceptionPermission() { 3864 if (mContext.checkCallingOrSelfPermission( 3865 android.Manifest.permission.CALL_AUDIO_INTERCEPTION) 3866 != PackageManager.PERMISSION_GRANTED) { 3867 throw new SecurityException("Missing CALL_AUDIO_INTERCEPTION permission"); 3868 } 3869 } 3870 3871 3872 @Override 3873 @android.annotation.EnforcePermission(anyOf = { 3874 MODIFY_AUDIO_SETTINGS_PRIVILEGED, 3875 android.Manifest.permission.MODIFY_AUDIO_ROUTING 3876 }) 3877 /** @see AudioManager#setVolumeGroupVolumeIndex(int, int, int) */ setVolumeGroupVolumeIndex(int groupId, int index, int flags, String callingPackage, String attributionTag)3878 public void setVolumeGroupVolumeIndex(int groupId, int index, int flags, 3879 String callingPackage, String attributionTag) { 3880 super.setVolumeGroupVolumeIndex_enforcePermission(); 3881 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 3882 Log.e(TAG, ": no volume group found for id " + groupId); 3883 return; 3884 } 3885 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 3886 3887 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, vgs.name(), 3888 index, flags, callingPackage + ", user " + getCurrentUserId())); 3889 3890 vgs.setVolumeIndex(index, flags); 3891 3892 // For legacy reason, propagate to all streams associated to this volume group 3893 for (int groupedStream : vgs.getLegacyStreamTypes()) { 3894 try { 3895 ensureValidStreamType(groupedStream); 3896 } catch (IllegalArgumentException e) { 3897 Log.d(TAG, "volume group " + groupId + " has internal streams (" + groupedStream 3898 + "), do not change associated stream volume"); 3899 continue; 3900 } 3901 setStreamVolume(groupedStream, index, flags, /*device*/ null, 3902 callingPackage, callingPackage, 3903 attributionTag, Binder.getCallingUid(), true /*hasModifyAudioSettings*/); 3904 } 3905 } 3906 3907 @Nullable getAudioVolumeGroupById(int volumeGroupId)3908 private AudioVolumeGroup getAudioVolumeGroupById(int volumeGroupId) { 3909 for (AudioVolumeGroup avg : AudioVolumeGroup.getAudioVolumeGroups()) { 3910 if (avg.getId() == volumeGroupId) { 3911 return avg; 3912 } 3913 } 3914 3915 Log.e(TAG, ": invalid volume group id: " + volumeGroupId + " requested"); 3916 return null; 3917 } 3918 3919 @Override 3920 @android.annotation.EnforcePermission(anyOf = { 3921 MODIFY_AUDIO_SETTINGS_PRIVILEGED, 3922 android.Manifest.permission.MODIFY_AUDIO_ROUTING 3923 }) 3924 /** @see AudioManager#getVolumeGroupVolumeIndex(int) */ getVolumeGroupVolumeIndex(int groupId)3925 public int getVolumeGroupVolumeIndex(int groupId) { 3926 super.getVolumeGroupVolumeIndex_enforcePermission(); 3927 synchronized (VolumeStreamState.class) { 3928 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 3929 throw new IllegalArgumentException("No volume group for id " + groupId); 3930 } 3931 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 3932 // Return 0 when muted, not min index since for e.g. Voice Call, it has a non zero 3933 // min but it mutable on permission condition. 3934 return vgs.isMuted() ? 0 : vgs.getVolumeIndex(); 3935 } 3936 } 3937 3938 /** @see AudioManager#getVolumeGroupMaxVolumeIndex(int) */ 3939 @android.annotation.EnforcePermission(anyOf = { 3940 MODIFY_AUDIO_SETTINGS_PRIVILEGED, 3941 android.Manifest.permission.MODIFY_AUDIO_ROUTING 3942 }) getVolumeGroupMaxVolumeIndex(int groupId)3943 public int getVolumeGroupMaxVolumeIndex(int groupId) { 3944 super.getVolumeGroupMaxVolumeIndex_enforcePermission(); 3945 synchronized (VolumeStreamState.class) { 3946 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 3947 throw new IllegalArgumentException("No volume group for id " + groupId); 3948 } 3949 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 3950 return vgs.getMaxIndex(); 3951 } 3952 } 3953 3954 /** @see AudioManager#getVolumeGroupMinVolumeIndex(int) */ 3955 @android.annotation.EnforcePermission(anyOf = { 3956 MODIFY_AUDIO_SETTINGS_PRIVILEGED, 3957 android.Manifest.permission.MODIFY_AUDIO_ROUTING 3958 }) getVolumeGroupMinVolumeIndex(int groupId)3959 public int getVolumeGroupMinVolumeIndex(int groupId) { 3960 super.getVolumeGroupMinVolumeIndex_enforcePermission(); 3961 synchronized (VolumeStreamState.class) { 3962 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 3963 throw new IllegalArgumentException("No volume group for id " + groupId); 3964 } 3965 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 3966 return vgs.getMinIndex(); 3967 } 3968 } 3969 3970 @Override 3971 @android.annotation.EnforcePermission(anyOf = { 3972 android.Manifest.permission.MODIFY_AUDIO_ROUTING, 3973 android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED 3974 }) 3975 /** @see AudioDeviceVolumeManager#setDeviceVolume(VolumeInfo, AudioDeviceAttributes) 3976 * Part of service interface, check permissions and parameters here 3977 * Note calling package is for logging purposes only, not to be trusted 3978 */ setDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)3979 public void setDeviceVolume(@NonNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, 3980 @NonNull String callingPackage) { 3981 super.setDeviceVolume_enforcePermission(); 3982 Objects.requireNonNull(vi); 3983 Objects.requireNonNull(ada); 3984 Objects.requireNonNull(callingPackage); 3985 3986 if (!vi.hasStreamType()) { 3987 Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception()); 3988 return; 3989 } 3990 3991 int index = vi.getVolumeIndex(); 3992 if (index == VolumeInfo.INDEX_NOT_SET && !vi.hasMuteCommand()) { 3993 throw new IllegalArgumentException( 3994 "changing device volume requires a volume index or mute command"); 3995 } 3996 3997 // force a cache clear to force reevaluating stream type to audio device selection 3998 // that can interfere with the sending of the VOLUME_CHANGED_ACTION intent 3999 mAudioSystem.clearRoutingCache(); 4000 4001 // log the current device that will be used when evaluating the sending of the 4002 // VOLUME_CHANGED_ACTION intent to see if the current device is the one being modified 4003 final int currDev = getDeviceForStream(vi.getStreamType()); 4004 4005 final boolean skipping = (currDev == ada.getInternalType()); 4006 4007 AudioService.sVolumeLogger.enqueue(new DeviceVolumeEvent(vi.getStreamType(), index, ada, 4008 currDev, callingPackage, skipping)); 4009 4010 if (skipping) { 4011 // setDeviceVolume was called on a device currently being used 4012 return; 4013 } 4014 4015 // TODO handle unmuting of current audio device 4016 // if a stream is not muted but the VolumeInfo is for muting, set the volume index 4017 // for the device to min volume 4018 if (vi.hasMuteCommand() && vi.isMuted() && !isStreamMute(vi.getStreamType())) { 4019 setStreamVolumeWithAttributionInt(vi.getStreamType(), 4020 mStreamStates[vi.getStreamType()].getMinIndex(), 4021 /*flags*/ 0, 4022 ada, callingPackage, null); 4023 return; 4024 } 4025 4026 AudioService.sVolumeLogger.enqueueAndLog("setDeviceVolume" + " from:" + callingPackage 4027 + " " + vi + " " + ada, EventLogger.Event.ALOGI, TAG); 4028 4029 if (vi.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET 4030 || vi.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) { 4031 // assume index meant to be in stream type range, validate 4032 if ((index * 10) < mStreamStates[vi.getStreamType()].getMinIndex() 4033 || (index * 10) > mStreamStates[vi.getStreamType()].getMaxIndex()) { 4034 throw new IllegalArgumentException("invalid volume index " + index 4035 + " not between min/max for stream " + vi.getStreamType()); 4036 } 4037 } else { 4038 // check if index needs to be rescaled 4039 final int min = (mStreamStates[vi.getStreamType()].getMinIndex() + 5) / 10; 4040 final int max = (mStreamStates[vi.getStreamType()].getMaxIndex() + 5) / 10; 4041 if (vi.getMinVolumeIndex() != min || vi.getMaxVolumeIndex() != max) { 4042 index = rescaleIndex(index, 4043 /*srcMin*/ vi.getMinVolumeIndex(), /*srcMax*/ vi.getMaxVolumeIndex(), 4044 /*dstMin*/ min, /*dstMax*/ max); 4045 } 4046 } 4047 setStreamVolumeWithAttributionInt(vi.getStreamType(), index, /*flags*/ 0, 4048 ada, callingPackage, null); 4049 } 4050 4051 /** Retain API for unsupported app usage */ setStreamVolume(int streamType, int index, int flags, String callingPackage)4052 public void setStreamVolume(int streamType, int index, int flags, String callingPackage) { 4053 setStreamVolumeWithAttribution(streamType, index, flags, 4054 callingPackage, /*attributionTag*/ null); 4055 } 4056 4057 /** @see AudioManager#adjustVolumeGroupVolume(int, int, int) */ adjustVolumeGroupVolume(int groupId, int direction, int flags, String callingPackage)4058 public void adjustVolumeGroupVolume(int groupId, int direction, int flags, 4059 String callingPackage) { 4060 ensureValidDirection(direction); 4061 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4062 Log.e(TAG, ": no volume group found for id " + groupId); 4063 return; 4064 } 4065 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4066 // For compatibility reason, use stream API if group linked to a valid stream 4067 boolean fallbackOnStream = false; 4068 for (int stream : vgs.getLegacyStreamTypes()) { 4069 try { 4070 ensureValidStreamType(stream); 4071 } catch (IllegalArgumentException e) { 4072 Log.d(TAG, "volume group " + groupId + " has internal streams (" + stream 4073 + "), do not change associated stream volume"); 4074 continue; 4075 } 4076 // Note: Group and Stream does not share same convention, 0 is mute for stream, 4077 // min index is acting as mute for Groups 4078 if (vgs.isVssMuteBijective(stream)) { 4079 adjustStreamVolume(stream, direction, flags, callingPackage); 4080 if (isMuteAdjust(direction)) { 4081 // will be propagated to all aliased streams 4082 return; 4083 } 4084 fallbackOnStream = true; 4085 } 4086 } 4087 if (fallbackOnStream) { 4088 // Handled by at least one stream, will be propagated to group, bailing out. 4089 return; 4090 } 4091 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_GROUP_VOL, vgs.name(), 4092 direction, flags, callingPackage)); 4093 vgs.adjustVolume(direction, flags); 4094 } 4095 4096 /** @see AudioManager#getLastAudibleVolumeForVolumeGroup(int) */ 4097 @android.annotation.EnforcePermission(android.Manifest.permission.QUERY_AUDIO_STATE) getLastAudibleVolumeForVolumeGroup(int groupId)4098 public int getLastAudibleVolumeForVolumeGroup(int groupId) { 4099 super.getLastAudibleVolumeForVolumeGroup_enforcePermission(); 4100 synchronized (VolumeStreamState.class) { 4101 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4102 Log.e(TAG, ": no volume group found for id " + groupId); 4103 return 0; 4104 } 4105 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4106 return vgs.getVolumeIndex(); 4107 } 4108 } 4109 4110 /** @see AudioManager#isVolumeGroupMuted(int) */ isVolumeGroupMuted(int groupId)4111 public boolean isVolumeGroupMuted(int groupId) { 4112 synchronized (VolumeStreamState.class) { 4113 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4114 Log.e(TAG, ": no volume group found for id " + groupId); 4115 return false; 4116 } 4117 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4118 return vgs.isMuted(); 4119 } 4120 } 4121 4122 /** @see AudioManager#setStreamVolume(int, int, int) 4123 * Part of service interface, check permissions here */ setStreamVolumeWithAttribution(int streamType, int index, int flags, String callingPackage, String attributionTag)4124 public void setStreamVolumeWithAttribution(int streamType, int index, int flags, 4125 String callingPackage, String attributionTag) { 4126 setStreamVolumeWithAttributionInt(streamType, index, flags, /*device*/ null, 4127 callingPackage, attributionTag); 4128 } 4129 4130 /** 4131 * Internal method for a stream type volume change. Can be used to change the volume on a 4132 * given device only 4133 * @param streamType the stream type whose volume is to be changed 4134 * @param index the volume index 4135 * @param flags options for volume handling 4136 * @param device null when controlling volume for the current routing, otherwise the device 4137 * for which volume is being changed 4138 * @param callingPackage client side-provided package name of caller, not to be trusted 4139 * @param attributionTag client side-provided attribution name, not to be trusted 4140 */ setStreamVolumeWithAttributionInt(int streamType, int index, int flags, @Nullable AudioDeviceAttributes device, String callingPackage, String attributionTag)4141 protected void setStreamVolumeWithAttributionInt(int streamType, int index, int flags, 4142 @Nullable AudioDeviceAttributes device, 4143 String callingPackage, String attributionTag) { 4144 if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { 4145 Log.w(TAG, "Trying to call setStreamVolume() for a11y without" 4146 + " CHANGE_ACCESSIBILITY_VOLUME callingPackage=" + callingPackage); 4147 return; 4148 } 4149 if ((streamType == AudioManager.STREAM_VOICE_CALL) && (index == 0) 4150 && (mContext.checkCallingOrSelfPermission( 4151 android.Manifest.permission.MODIFY_PHONE_STATE) 4152 != PackageManager.PERMISSION_GRANTED)) { 4153 Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL and index 0 without" 4154 + " MODIFY_PHONE_STATE callingPackage=" + callingPackage); 4155 return; 4156 } 4157 if ((streamType == AudioManager.STREAM_ASSISTANT) 4158 && (mContext.checkCallingOrSelfPermission( 4159 android.Manifest.permission.MODIFY_AUDIO_ROUTING) 4160 != PackageManager.PERMISSION_GRANTED)) { 4161 Log.w(TAG, "Trying to call setStreamVolume() for STREAM_ASSISTANT without" 4162 + " MODIFY_AUDIO_ROUTING callingPackage=" + callingPackage); 4163 return; 4164 } 4165 4166 if (device == null) { 4167 // call was already logged in setDeviceVolume() 4168 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType, 4169 index/*val1*/, flags/*val2*/, callingPackage)); 4170 } 4171 setStreamVolume(streamType, index, flags, device, 4172 callingPackage, callingPackage, attributionTag, 4173 Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission()); 4174 } 4175 4176 @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_ULTRASOUND) 4177 /** @see AudioManager#isUltrasoundSupported() */ isUltrasoundSupported()4178 public boolean isUltrasoundSupported() { 4179 super.isUltrasoundSupported_enforcePermission(); 4180 4181 return AudioSystem.isUltrasoundSupported(); 4182 } 4183 4184 /** @see AudioManager#isHotwordStreamSupported() */ 4185 @android.annotation.EnforcePermission(android.Manifest.permission.CAPTURE_AUDIO_HOTWORD) isHotwordStreamSupported(boolean lookbackAudio)4186 public boolean isHotwordStreamSupported(boolean lookbackAudio) { 4187 super.isHotwordStreamSupported_enforcePermission(); 4188 try { 4189 return mAudioPolicy.isHotwordStreamSupported(lookbackAudio); 4190 } catch (IllegalStateException e) { 4191 // Suppress connection failure to APM, since the method is purely informative 4192 Log.e(TAG, "Suppressing exception calling into AudioPolicy", e); 4193 return false; 4194 } 4195 } 4196 4197 canChangeAccessibilityVolume()4198 private boolean canChangeAccessibilityVolume() { 4199 synchronized (mAccessibilityServiceUidsLock) { 4200 if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 4201 android.Manifest.permission.CHANGE_ACCESSIBILITY_VOLUME)) { 4202 return true; 4203 } 4204 if (mAccessibilityServiceUids != null) { 4205 int callingUid = Binder.getCallingUid(); 4206 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 4207 if (mAccessibilityServiceUids[i] == callingUid) { 4208 return true; 4209 } 4210 } 4211 } 4212 return false; 4213 } 4214 } 4215 getBluetoothContextualVolumeStream()4216 /*package*/ int getBluetoothContextualVolumeStream() { 4217 return getBluetoothContextualVolumeStream(mMode.get()); 4218 } 4219 getBluetoothContextualVolumeStream(int mode)4220 private int getBluetoothContextualVolumeStream(int mode) { 4221 switch (mode) { 4222 case AudioSystem.MODE_IN_COMMUNICATION: 4223 case AudioSystem.MODE_IN_CALL: 4224 return AudioSystem.STREAM_VOICE_CALL; 4225 case AudioSystem.MODE_NORMAL: 4226 default: 4227 // other conditions will influence the stream type choice, read on... 4228 break; 4229 } 4230 if (mVoicePlaybackActive.get()) { 4231 return AudioSystem.STREAM_VOICE_CALL; 4232 } 4233 return AudioSystem.STREAM_MUSIC; 4234 } 4235 4236 private AtomicBoolean mVoicePlaybackActive = new AtomicBoolean(false); 4237 private AtomicBoolean mMediaPlaybackActive = new AtomicBoolean(false); 4238 4239 private final IPlaybackConfigDispatcher mPlaybackActivityMonitor = 4240 new IPlaybackConfigDispatcher.Stub() { 4241 @Override 4242 public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs, 4243 boolean flush) { 4244 sendMsg(mAudioHandler, MSG_PLAYBACK_CONFIG_CHANGE, SENDMSG_REPLACE, 4245 0 /*arg1 ignored*/, 0 /*arg2 ignored*/, 4246 configs /*obj*/, 0 /*delay*/); 4247 } 4248 }; 4249 onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs)4250 private void onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) { 4251 boolean voiceActive = false; 4252 boolean mediaActive = false; 4253 for (AudioPlaybackConfiguration config : configs) { 4254 final int usage = config.getAudioAttributes().getUsage(); 4255 if (!config.isActive()) { 4256 continue; 4257 } 4258 if (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION 4259 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) { 4260 voiceActive = true; 4261 } 4262 if (usage == AudioAttributes.USAGE_MEDIA || usage == AudioAttributes.USAGE_GAME) { 4263 mediaActive = true; 4264 } 4265 } 4266 if (mVoicePlaybackActive.getAndSet(voiceActive) != voiceActive) { 4267 updateHearingAidVolumeOnVoiceActivityUpdate(); 4268 } 4269 if (mMediaPlaybackActive.getAndSet(mediaActive) != mediaActive && mediaActive) { 4270 mSoundDoseHelper.scheduleMusicActiveCheck(); 4271 } 4272 // Update playback active state for all apps in audio mode stack. 4273 // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE 4274 // and request an audio mode update immediately. Upon any other change, queue the message 4275 // and request an audio mode update after a grace period. 4276 updateAudioModeHandlers( 4277 configs /* playbackConfigs */, null /* recordConfigs */); 4278 mDeviceBroker.updateCommunicationRouteClientsActivity( 4279 configs /* playbackConfigs */, null /* recordConfigs */); 4280 } 4281 updateAudioModeHandlers(List<AudioPlaybackConfiguration> playbackConfigs, List<AudioRecordingConfiguration> recordConfigs)4282 void updateAudioModeHandlers(List<AudioPlaybackConfiguration> playbackConfigs, 4283 List<AudioRecordingConfiguration> recordConfigs) { 4284 synchronized (mDeviceBroker.mSetModeLock) { 4285 boolean updateAudioMode = false; 4286 int existingMsgPolicy = SENDMSG_QUEUE; 4287 int delay = CHECK_MODE_FOR_UID_PERIOD_MS; 4288 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 4289 boolean wasActive = h.isActive(); 4290 if (playbackConfigs != null) { 4291 h.setPlaybackActive(false); 4292 for (AudioPlaybackConfiguration config : playbackConfigs) { 4293 final int usage = config.getAudioAttributes().getUsage(); 4294 if (config.getClientUid() == h.getUid() 4295 && (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION 4296 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) 4297 && config.isActive()) { 4298 h.setPlaybackActive(true); 4299 break; 4300 } 4301 } 4302 } 4303 if (recordConfigs != null) { 4304 h.setRecordingActive(false); 4305 for (AudioRecordingConfiguration config : recordConfigs) { 4306 if (config.getClientUid() == h.getUid() && !config.isClientSilenced() 4307 && config.getAudioSource() == AudioSource.VOICE_COMMUNICATION) { 4308 h.setRecordingActive(true); 4309 break; 4310 } 4311 } 4312 } 4313 if (wasActive != h.isActive()) { 4314 updateAudioMode = true; 4315 if (h.isActive() && h == getAudioModeOwnerHandler()) { 4316 existingMsgPolicy = SENDMSG_REPLACE; 4317 delay = 0; 4318 } 4319 } 4320 } 4321 if (updateAudioMode) { 4322 sendMsg(mAudioHandler, 4323 MSG_UPDATE_AUDIO_MODE, 4324 existingMsgPolicy, 4325 AudioSystem.MODE_CURRENT, 4326 android.os.Process.myPid(), 4327 mContext.getPackageName(), 4328 delay); 4329 } 4330 } 4331 } 4332 4333 private final IRecordingConfigDispatcher mVoiceRecordingActivityMonitor = 4334 new IRecordingConfigDispatcher.Stub() { 4335 @Override 4336 public void dispatchRecordingConfigChange(List<AudioRecordingConfiguration> configs) { 4337 sendMsg(mAudioHandler, MSG_RECORDING_CONFIG_CHANGE, SENDMSG_REPLACE, 4338 0 /*arg1 ignored*/, 0 /*arg2 ignored*/, 4339 configs /*obj*/, 0 /*delay*/); 4340 } 4341 }; 4342 onRecordingConfigChange(List<AudioRecordingConfiguration> configs)4343 private void onRecordingConfigChange(List<AudioRecordingConfiguration> configs) { 4344 // Update recording active state for all apps in audio mode stack. 4345 // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE 4346 // and request an audio mode update immediately. Upon any other change, queue the message 4347 // and request an audio mode update after a grace period. 4348 updateAudioModeHandlers( 4349 null /* playbackConfigs */, configs /* recordConfigs */); 4350 mDeviceBroker.updateCommunicationRouteClientsActivity( 4351 null /* playbackConfigs */, configs /* recordConfigs */); 4352 } 4353 dumpAudioMode(PrintWriter pw)4354 private void dumpAudioMode(PrintWriter pw) { 4355 pw.println("\nAudio mode: "); 4356 pw.println("- Requested mode = " + AudioSystem.modeToString(getMode())); 4357 pw.println("- Actual mode = " + AudioSystem.modeToString(mMode.get())); 4358 pw.println("- Mode owner: "); 4359 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 4360 if (hdlr != null) { 4361 hdlr.dump(pw, -1); 4362 } else { 4363 pw.println(" None"); 4364 } 4365 pw.println("- Mode owner stack: "); 4366 if (mSetModeDeathHandlers.isEmpty()) { 4367 pw.println(" Empty"); 4368 } else { 4369 for (int i = 0; i < mSetModeDeathHandlers.size(); i++) { 4370 mSetModeDeathHandlers.get(i).dump(pw, i); 4371 } 4372 } 4373 } 4374 updateHearingAidVolumeOnVoiceActivityUpdate()4375 private void updateHearingAidVolumeOnVoiceActivityUpdate() { 4376 final int streamType = getBluetoothContextualVolumeStream(); 4377 final int index = getStreamVolume(streamType); 4378 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_HEARING_AID, 4379 mVoicePlaybackActive.get(), streamType, index)); 4380 mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType); 4381 4382 } 4383 4384 /** 4385 * Manage an audio mode change for audio devices that use an "absolute volume" model, 4386 * i.e. the framework sends the full scale signal, and the actual volume for the use case 4387 * is communicated separately. 4388 */ updateAbsVolumeMultiModeDevices(int oldMode, int newMode)4389 void updateAbsVolumeMultiModeDevices(int oldMode, int newMode) { 4390 if (oldMode == newMode) { 4391 return; 4392 } 4393 switch (newMode) { 4394 case AudioSystem.MODE_IN_COMMUNICATION: 4395 case AudioSystem.MODE_IN_CALL: 4396 case AudioSystem.MODE_NORMAL: 4397 case AudioSystem.MODE_CALL_SCREENING: 4398 case AudioSystem.MODE_CALL_REDIRECT: 4399 case AudioSystem.MODE_COMMUNICATION_REDIRECT: 4400 break; 4401 default: 4402 // no-op is enough for all other values 4403 return; 4404 } 4405 4406 int streamType = getBluetoothContextualVolumeStream(newMode); 4407 4408 final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType); 4409 final Set<Integer> absVolumeMultiModeCaseDevices = AudioSystem.intersectionAudioDeviceTypes( 4410 mAbsVolumeMultiModeCaseDevices, deviceTypes); 4411 if (absVolumeMultiModeCaseDevices.isEmpty()) { 4412 return; 4413 } 4414 4415 // handling of specific interfaces goes here: 4416 if (AudioSystem.isSingleAudioDeviceType( 4417 absVolumeMultiModeCaseDevices, AudioSystem.DEVICE_OUT_HEARING_AID)) { 4418 final int index = getStreamVolume(streamType); 4419 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID, 4420 newMode, streamType, index)); 4421 mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType); 4422 } 4423 } 4424 setLeAudioVolumeOnModeUpdate(int mode, int device, int streamType, int index, int maxIndex)4425 private void setLeAudioVolumeOnModeUpdate(int mode, int device, int streamType, int index, 4426 int maxIndex) { 4427 switch (mode) { 4428 case AudioSystem.MODE_IN_COMMUNICATION: 4429 case AudioSystem.MODE_IN_CALL: 4430 case AudioSystem.MODE_NORMAL: 4431 case AudioSystem.MODE_CALL_SCREENING: 4432 case AudioSystem.MODE_CALL_REDIRECT: 4433 case AudioSystem.MODE_COMMUNICATION_REDIRECT: 4434 break; 4435 default: 4436 // no-op is enough for all other values 4437 return; 4438 } 4439 4440 // In some cases (like the outgoing or rejected call) the value of 'device' is not 4441 // DEVICE_OUT_BLE_* even when BLE is connected. Changing the volume level in such case 4442 // may cuase the other devices volume level leaking into the LeAudio device settings. 4443 if (!AudioSystem.isLeAudioDeviceType(device)) { 4444 Log.w(TAG, "setLeAudioVolumeOnModeUpdate ignoring invalid device=" 4445 + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex 4446 + " streamType=" + streamType); 4447 return; 4448 } 4449 4450 if (DEBUG_VOL) { 4451 Log.d(TAG, "setLeAudioVolumeOnModeUpdate postSetLeAudioVolumeIndex device=" 4452 + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex 4453 + " streamType=" + streamType); 4454 } 4455 mDeviceBroker.postSetLeAudioVolumeIndex(index, maxIndex, streamType); 4456 mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "setLeAudioVolumeOnModeUpdate"); 4457 } 4458 setStreamVolume(int streamType, int index, int flags, @Nullable AudioDeviceAttributes ada, String callingPackage, String caller, String attributionTag, int uid, boolean hasModifyAudioSettings)4459 private void setStreamVolume(int streamType, int index, int flags, 4460 @Nullable AudioDeviceAttributes ada, 4461 String callingPackage, String caller, String attributionTag, int uid, 4462 boolean hasModifyAudioSettings) { 4463 if (DEBUG_VOL) { 4464 Log.d(TAG, "setStreamVolume(stream=" + streamType+", index=" + index 4465 + ", dev=" + ada 4466 + ", calling=" + callingPackage + ")"); 4467 } 4468 if (mUseFixedVolume) { 4469 return; 4470 } 4471 4472 ensureValidStreamType(streamType); 4473 int streamTypeAlias = mStreamVolumeAlias[streamType]; 4474 VolumeStreamState streamState = mStreamStates[streamTypeAlias]; 4475 4476 final int device = (ada == null) 4477 ? getDeviceForStream(streamType) 4478 : ada.getInternalType(); 4479 int oldIndex; 4480 4481 // skip a2dp absolute volume control request when the device 4482 // is neither an a2dp device nor BLE device 4483 if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 4484 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device)) 4485 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { 4486 return; 4487 } 4488 // If we are being called by the system (e.g. hardware keys) check for current user 4489 // so we handle user restrictions correctly. 4490 if (uid == android.os.Process.SYSTEM_UID) { 4491 uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); 4492 } 4493 if (!checkNoteAppOp( 4494 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) { 4495 return; 4496 } 4497 4498 if (isAndroidNPlus(callingPackage) 4499 && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags)) 4500 && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) { 4501 throw new SecurityException("Not allowed to change Do Not Disturb state"); 4502 } 4503 4504 if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) { 4505 return; 4506 } 4507 4508 mSoundDoseHelper.invalidatPendingVolumeCommand(); 4509 4510 oldIndex = streamState.getIndex(device); 4511 4512 index = rescaleIndex(index * 10, streamType, streamTypeAlias); 4513 4514 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 4515 && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 4516 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 4517 if (DEBUG_VOL) { 4518 Log.d(TAG, "setStreamVolume postSetAvrcpAbsoluteVolumeIndex index=" + index 4519 + "stream=" + streamType); 4520 } 4521 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10); 4522 } else if (isAbsoluteVolumeDevice(device) 4523 && ((flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0)) { 4524 AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device); 4525 4526 dispatchAbsoluteVolumeChanged(streamType, info, index); 4527 } 4528 4529 if (AudioSystem.isLeAudioDeviceType(device) 4530 && streamType == getBluetoothContextualVolumeStream() 4531 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 4532 if (DEBUG_VOL) { 4533 Log.d(TAG, "adjustSreamVolume postSetLeAudioVolumeIndex index=" 4534 + index + " stream=" + streamType); 4535 } 4536 mDeviceBroker.postSetLeAudioVolumeIndex(index, mStreamStates[streamType].getMaxIndex(), 4537 streamType); 4538 } 4539 4540 if (device == AudioSystem.DEVICE_OUT_HEARING_AID 4541 && streamType == getBluetoothContextualVolumeStream()) { 4542 Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index 4543 + " stream=" + streamType); 4544 mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType); 4545 } 4546 4547 flags &= ~AudioManager.FLAG_FIXED_VOLUME; 4548 if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) { 4549 flags |= AudioManager.FLAG_FIXED_VOLUME; 4550 4551 // volume is either 0 or max allowed for fixed volume devices 4552 if (index != 0) { 4553 index = mSoundDoseHelper.getSafeMediaVolumeIndex(device); 4554 if (index < 0) { 4555 index = streamState.getMaxIndex(); 4556 } 4557 } 4558 } 4559 4560 if (!mSoundDoseHelper.willDisplayWarningAfterCheckVolume(streamType, index, device, 4561 flags)) { 4562 onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings, 4563 // ada is non-null when called from setDeviceVolume, 4564 // which shouldn't update the mute state 4565 ada == null /*canChangeMute*/); 4566 index = mStreamStates[streamType].getIndex(device); 4567 } 4568 4569 synchronized (mHdmiClientLock) { 4570 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 4571 && (oldIndex != index)) { 4572 maybeSendSystemAudioStatusCommand(false); 4573 } 4574 } 4575 if (ada == null) { 4576 // only non-null when coming here from setDeviceVolume 4577 // TODO change test to check early if device is current device or not 4578 sendVolumeUpdate(streamType, oldIndex, index, flags, device); 4579 } 4580 } 4581 dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index)4582 private void dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, 4583 int index) { 4584 VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType); 4585 if (volumeInfo != null) { 4586 try { 4587 deviceInfo.mCallback.dispatchDeviceVolumeChanged(deviceInfo.mDevice, 4588 new VolumeInfo.Builder(volumeInfo) 4589 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo)) 4590 .build()); 4591 } catch (RemoteException e) { 4592 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume change"); 4593 } 4594 } 4595 } 4596 dispatchAbsoluteVolumeAdjusted(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode)4597 private void dispatchAbsoluteVolumeAdjusted(int streamType, 4598 AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode) { 4599 VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType); 4600 if (volumeInfo != null) { 4601 try { 4602 deviceInfo.mCallback.dispatchDeviceVolumeAdjusted(deviceInfo.mDevice, 4603 new VolumeInfo.Builder(volumeInfo) 4604 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo)) 4605 .build(), 4606 direction, 4607 mode); 4608 } catch (RemoteException e) { 4609 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume adjustment"); 4610 } 4611 } 4612 } 4613 4614 // No ringer or zen muted stream volumes can be changed unless it'll exit dnd volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags)4615 private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) { 4616 switch (mNm.getZenMode()) { 4617 case Settings.Global.ZEN_MODE_OFF: 4618 return true; 4619 case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: 4620 case Settings.Global.ZEN_MODE_ALARMS: 4621 case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: 4622 return !isStreamMutedByRingerOrZenMode(streamTypeAlias) 4623 || isUiSoundsStreamType(streamTypeAlias) 4624 || (flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0; 4625 } 4626 4627 return true; 4628 } 4629 4630 /** @see AudioManager#forceVolumeControlStream(int) */ forceVolumeControlStream(int streamType, IBinder cb)4631 public void forceVolumeControlStream(int streamType, IBinder cb) { 4632 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) 4633 != PackageManager.PERMISSION_GRANTED) { 4634 return; 4635 } 4636 if (DEBUG_VOL) { Log.d(TAG, String.format("forceVolumeControlStream(%d)", streamType)); } 4637 synchronized(mForceControlStreamLock) { 4638 if (mVolumeControlStream != -1 && streamType != -1) { 4639 mUserSelectedVolumeControlStream = true; 4640 } 4641 mVolumeControlStream = streamType; 4642 if (mVolumeControlStream == -1) { 4643 if (mForceControlStreamClient != null) { 4644 mForceControlStreamClient.release(); 4645 mForceControlStreamClient = null; 4646 } 4647 mUserSelectedVolumeControlStream = false; 4648 } else { 4649 if (null == mForceControlStreamClient) { 4650 mForceControlStreamClient = new ForceControlStreamClient(cb); 4651 } else { 4652 if (mForceControlStreamClient.getBinder() == cb) { 4653 Log.d(TAG, "forceVolumeControlStream cb:" + cb + " is already linked."); 4654 } else { 4655 mForceControlStreamClient.release(); 4656 mForceControlStreamClient = new ForceControlStreamClient(cb); 4657 } 4658 } 4659 } 4660 } 4661 } 4662 4663 private class ForceControlStreamClient implements IBinder.DeathRecipient { 4664 private IBinder mCb; // To be notified of client's death 4665 ForceControlStreamClient(IBinder cb)4666 ForceControlStreamClient(IBinder cb) { 4667 if (cb != null) { 4668 try { 4669 cb.linkToDeath(this, 0); 4670 } catch (RemoteException e) { 4671 // Client has died! 4672 Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death"); 4673 cb = null; 4674 } 4675 } 4676 mCb = cb; 4677 } 4678 binderDied()4679 public void binderDied() { 4680 synchronized(mForceControlStreamLock) { 4681 Log.w(TAG, "SCO client died"); 4682 if (mForceControlStreamClient != this) { 4683 Log.w(TAG, "unregistered control stream client died"); 4684 } else { 4685 mForceControlStreamClient = null; 4686 mVolumeControlStream = -1; 4687 mUserSelectedVolumeControlStream = false; 4688 } 4689 } 4690 } 4691 release()4692 public void release() { 4693 if (mCb != null) { 4694 mCb.unlinkToDeath(this, 0); 4695 mCb = null; 4696 } 4697 } 4698 getBinder()4699 public IBinder getBinder() { 4700 return mCb; 4701 } 4702 } 4703 sendBroadcastToAll(Intent intent, Bundle options)4704 private void sendBroadcastToAll(Intent intent, Bundle options) { 4705 if (!mSystemServer.isPrivileged()) { 4706 return; 4707 } 4708 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 4709 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 4710 final long ident = Binder.clearCallingIdentity(); 4711 try { 4712 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 4713 null /* receiverPermission */, options); 4714 } finally { 4715 Binder.restoreCallingIdentity(ident); 4716 } 4717 } 4718 sendStickyBroadcastToAll(Intent intent)4719 private void sendStickyBroadcastToAll(Intent intent) { 4720 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 4721 final long ident = Binder.clearCallingIdentity(); 4722 try { 4723 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 4724 } finally { 4725 Binder.restoreCallingIdentity(ident); 4726 } 4727 } 4728 getCurrentUserId()4729 private int getCurrentUserId() { 4730 final long ident = Binder.clearCallingIdentity(); 4731 try { 4732 UserInfo currentUser = ActivityManager.getService().getCurrentUser(); 4733 return currentUser.id; 4734 } catch (RemoteException e) { 4735 // Activity manager not running, nothing we can do assume user 0. 4736 } finally { 4737 Binder.restoreCallingIdentity(ident); 4738 } 4739 return UserHandle.USER_SYSTEM; 4740 } 4741 4742 // UI update and Broadcast Intent sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)4743 protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device) 4744 { 4745 streamType = mStreamVolumeAlias[streamType]; 4746 4747 if (streamType == AudioSystem.STREAM_MUSIC && isFullVolumeDevice(device)) { 4748 flags &= ~AudioManager.FLAG_SHOW_UI; 4749 } 4750 mVolumeController.postVolumeChanged(streamType, flags); 4751 } 4752 4753 // Don't show volume UI when: 4754 // - Hdmi-CEC system audio mode is on and we are a TV panel updateFlagsForTvPlatform(int flags)4755 private int updateFlagsForTvPlatform(int flags) { 4756 synchronized (mHdmiClientLock) { 4757 if (mHdmiTvClient != null && mHdmiSystemAudioSupported 4758 && mHdmiCecVolumeControlEnabled) { 4759 flags &= ~AudioManager.FLAG_SHOW_UI; 4760 } 4761 } 4762 return flags; 4763 } 4764 // UI update and Broadcast Intent sendMasterMuteUpdate(boolean muted, int flags)4765 private void sendMasterMuteUpdate(boolean muted, int flags) { 4766 mVolumeController.postMasterMuteChanged(updateFlagsForTvPlatform(flags)); 4767 broadcastMasterMuteStatus(muted); 4768 } 4769 broadcastMasterMuteStatus(boolean muted)4770 private void broadcastMasterMuteStatus(boolean muted) { 4771 Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION); 4772 intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, muted); 4773 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 4774 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 4775 sendStickyBroadcastToAll(intent); 4776 } 4777 4778 /** 4779 * Sets the stream state's index, and posts a message to set system volume. 4780 * This will not call out to the UI. Assumes a valid stream type. 4781 * 4782 * @param streamType Type of the stream 4783 * @param index Desired volume index of the stream 4784 * @param device the device whose volume must be changed 4785 * @param force If true, set the volume even if the desired volume is same 4786 * @param caller 4787 * @param hasModifyAudioSettings true if the caller is granted MODIFY_AUDIO_SETTINGS or 4788 * MODIFY_AUDIO_ROUTING permission 4789 * as the current volume. 4790 */ setStreamVolumeInt(int streamType, int index, int device, boolean force, String caller, boolean hasModifyAudioSettings)4791 private void setStreamVolumeInt(int streamType, 4792 int index, 4793 int device, 4794 boolean force, 4795 String caller, boolean hasModifyAudioSettings) { 4796 if (isFullVolumeDevice(device)) { 4797 return; 4798 } 4799 VolumeStreamState streamState = mStreamStates[streamType]; 4800 4801 if (streamState.setIndex(index, device, caller, hasModifyAudioSettings) || force) { 4802 // Post message to set system volume (it in turn will post a message 4803 // to persist). 4804 sendMsg(mAudioHandler, 4805 MSG_SET_DEVICE_VOLUME, 4806 SENDMSG_QUEUE, 4807 device, 4808 0, 4809 streamState, 4810 0); 4811 } 4812 } 4813 4814 /** get stream mute state. */ isStreamMute(int streamType)4815 public boolean isStreamMute(int streamType) { 4816 if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 4817 streamType = getActiveStreamType(streamType); 4818 } 4819 synchronized (VolumeStreamState.class) { 4820 ensureValidStreamType(streamType); 4821 return mStreamStates[streamType].mIsMuted; 4822 } 4823 } 4824 4825 private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient { 4826 private IBinder mICallback; // To be notified of client's death 4827 RmtSbmxFullVolDeathHandler(IBinder cb)4828 RmtSbmxFullVolDeathHandler(IBinder cb) { 4829 mICallback = cb; 4830 try { 4831 cb.linkToDeath(this, 0/*flags*/); 4832 } catch (RemoteException e) { 4833 Log.e(TAG, "can't link to death", e); 4834 } 4835 } 4836 isHandlerFor(IBinder cb)4837 boolean isHandlerFor(IBinder cb) { 4838 return mICallback.equals(cb); 4839 } 4840 forget()4841 void forget() { 4842 try { 4843 mICallback.unlinkToDeath(this, 0/*flags*/); 4844 } catch (NoSuchElementException e) { 4845 Log.e(TAG, "error unlinking to death", e); 4846 } 4847 } 4848 binderDied()4849 public void binderDied() { 4850 Log.w(TAG, "Recorder with remote submix at full volume died " + mICallback); 4851 forceRemoteSubmixFullVolume(false, mICallback); 4852 } 4853 } 4854 4855 /** 4856 * call must be synchronized on mRmtSbmxFullVolDeathHandlers 4857 * @return true if there is a registered death handler, false otherwise */ discardRmtSbmxFullVolDeathHandlerFor(IBinder cb)4858 private boolean discardRmtSbmxFullVolDeathHandlerFor(IBinder cb) { 4859 Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator(); 4860 while (it.hasNext()) { 4861 final RmtSbmxFullVolDeathHandler handler = it.next(); 4862 if (handler.isHandlerFor(cb)) { 4863 handler.forget(); 4864 mRmtSbmxFullVolDeathHandlers.remove(handler); 4865 return true; 4866 } 4867 } 4868 return false; 4869 } 4870 4871 /** call synchronized on mRmtSbmxFullVolDeathHandlers */ hasRmtSbmxFullVolDeathHandlerFor(IBinder cb)4872 private boolean hasRmtSbmxFullVolDeathHandlerFor(IBinder cb) { 4873 Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator(); 4874 while (it.hasNext()) { 4875 if (it.next().isHandlerFor(cb)) { 4876 return true; 4877 } 4878 } 4879 return false; 4880 } 4881 4882 private int mRmtSbmxFullVolRefCount = 0; 4883 private final ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers = 4884 new ArrayList<RmtSbmxFullVolDeathHandler>(); 4885 forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb)4886 public void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb) { 4887 if (cb == null) { 4888 return; 4889 } 4890 if ((PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 4891 android.Manifest.permission.CAPTURE_AUDIO_OUTPUT))) { 4892 Log.w(TAG, "Trying to call forceRemoteSubmixFullVolume() without CAPTURE_AUDIO_OUTPUT"); 4893 return; 4894 } 4895 synchronized(mRmtSbmxFullVolDeathHandlers) { 4896 boolean applyRequired = false; 4897 if (startForcing) { 4898 if (!hasRmtSbmxFullVolDeathHandlerFor(cb)) { 4899 mRmtSbmxFullVolDeathHandlers.add(new RmtSbmxFullVolDeathHandler(cb)); 4900 if (mRmtSbmxFullVolRefCount == 0) { 4901 mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 4902 mFixedVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 4903 applyRequired = true; 4904 } 4905 mRmtSbmxFullVolRefCount++; 4906 } 4907 } else { 4908 if (discardRmtSbmxFullVolDeathHandlerFor(cb) && (mRmtSbmxFullVolRefCount > 0)) { 4909 mRmtSbmxFullVolRefCount--; 4910 if (mRmtSbmxFullVolRefCount == 0) { 4911 mFullVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 4912 mFixedVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 4913 applyRequired = true; 4914 } 4915 } 4916 } 4917 if (applyRequired) { 4918 // Assumes only STREAM_MUSIC going through DEVICE_OUT_REMOTE_SUBMIX 4919 checkAllFixedVolumeDevices(AudioSystem.STREAM_MUSIC); 4920 mStreamStates[AudioSystem.STREAM_MUSIC].applyAllVolumes(); 4921 } 4922 } 4923 } 4924 setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, int userId, int pid, String attributionTag)4925 private void setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, 4926 int userId, int pid, String attributionTag) { 4927 // If we are being called by the system check for user we are going to change 4928 // so we handle user restrictions correctly. 4929 if (uid == android.os.Process.SYSTEM_UID) { 4930 uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 4931 } 4932 // If OP_AUDIO_MASTER_VOLUME is set, disallow unmuting. 4933 if (!mute && !checkNoteAppOp( 4934 AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage, attributionTag)) { 4935 return; 4936 } 4937 if (userId != UserHandle.getCallingUserId() && 4938 mContext.checkPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4939 pid, uid) 4940 != PackageManager.PERMISSION_GRANTED) { 4941 return; 4942 } 4943 setMasterMuteInternalNoCallerCheck(mute, flags, userId); 4944 } 4945 setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId)4946 private void setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId) { 4947 if (DEBUG_VOL) { 4948 Log.d(TAG, String.format("Master mute %s, %d, user=%d", mute, flags, userId)); 4949 } 4950 if (!isPlatformAutomotive() && mUseFixedVolume) { 4951 // If using fixed volume, we don't mute. 4952 // TODO: remove the isPlatformAutomotive check here. 4953 // The isPlatformAutomotive check is added for safety but may not be necessary. 4954 return; 4955 } 4956 // For automotive, 4957 // - the car service is always running as system user 4958 // - foreground users are non-system users 4959 // Car service is in charge of dispatching the key event include global mute to Android. 4960 // Therefore, the getCurrentUser() is always different to the foreground user. 4961 if ((isPlatformAutomotive() && userId == UserHandle.USER_SYSTEM) 4962 || (getCurrentUserId() == userId)) { 4963 if (mute != AudioSystem.getMasterMute()) { 4964 AudioSystem.setMasterMute(mute); 4965 sendMasterMuteUpdate(mute, flags); 4966 } 4967 } 4968 } 4969 4970 /** get global mute state. */ isMasterMute()4971 public boolean isMasterMute() { 4972 return AudioSystem.getMasterMute(); 4973 } 4974 4975 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 4976 /** @see AudioManager#setMasterMute(boolean, int) */ setMasterMute(boolean mute, int flags, String callingPackage, int userId, String attributionTag)4977 public void setMasterMute(boolean mute, int flags, String callingPackage, int userId, 4978 String attributionTag) { 4979 super.setMasterMute_enforcePermission(); 4980 4981 setMasterMuteInternal(mute, flags, callingPackage, 4982 Binder.getCallingUid(), userId, Binder.getCallingPid(), attributionTag); 4983 } 4984 4985 /** @see AudioManager#getStreamVolume(int) */ getStreamVolume(int streamType)4986 public int getStreamVolume(int streamType) { 4987 ensureValidStreamType(streamType); 4988 int device = getDeviceForStream(streamType); 4989 synchronized (VolumeStreamState.class) { 4990 int index = mStreamStates[streamType].getIndex(device); 4991 4992 // by convention getStreamVolume() returns 0 when a stream is muted. 4993 if (mStreamStates[streamType].mIsMuted) { 4994 index = 0; 4995 } 4996 if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) && 4997 isFixedVolumeDevice(device)) { 4998 index = mStreamStates[streamType].getMaxIndex(); 4999 } 5000 return (index + 5) / 10; 5001 } 5002 } 5003 5004 @Override 5005 @android.annotation.EnforcePermission(anyOf = { 5006 android.Manifest.permission.MODIFY_AUDIO_ROUTING, 5007 android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED 5008 }) 5009 /** 5010 * @see AudioDeviceVolumeManager#getDeviceVolume(VolumeInfo, AudioDeviceAttributes) 5011 */ getDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)5012 public @NonNull VolumeInfo getDeviceVolume(@NonNull VolumeInfo vi, 5013 @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage) { 5014 super.getDeviceVolume_enforcePermission(); 5015 Objects.requireNonNull(vi); 5016 Objects.requireNonNull(ada); 5017 Objects.requireNonNull(callingPackage); 5018 if (!vi.hasStreamType()) { 5019 Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception()); 5020 return getDefaultVolumeInfo(); 5021 } 5022 5023 int streamType = vi.getStreamType(); 5024 final VolumeInfo.Builder vib = new VolumeInfo.Builder(vi); 5025 vib.setMinVolumeIndex((mStreamStates[streamType].mIndexMin + 5) / 10); 5026 vib.setMaxVolumeIndex((mStreamStates[streamType].mIndexMax + 5) / 10); 5027 synchronized (VolumeStreamState.class) { 5028 final int index; 5029 if (isFixedVolumeDevice(ada.getInternalType())) { 5030 index = (mStreamStates[streamType].mIndexMax + 5) / 10; 5031 } else { 5032 index = (mStreamStates[streamType].getIndex(ada.getInternalType()) + 5) / 10; 5033 } 5034 vib.setVolumeIndex(index); 5035 // only set as a mute command if stream muted 5036 if (mStreamStates[streamType].mIsMuted) { 5037 vib.setMuted(true); 5038 } 5039 return vib.build(); 5040 } 5041 } 5042 5043 /** @see AudioManager#getStreamMaxVolume(int) */ getStreamMaxVolume(int streamType)5044 public int getStreamMaxVolume(int streamType) { 5045 ensureValidStreamType(streamType); 5046 return (mStreamStates[streamType].getMaxIndex() + 5) / 10; 5047 } 5048 5049 /** @see AudioManager#getStreamMinVolumeInt(int) 5050 * Part of service interface, check permissions here */ getStreamMinVolume(int streamType)5051 public int getStreamMinVolume(int streamType) { 5052 ensureValidStreamType(streamType); 5053 final boolean isPrivileged = 5054 Binder.getCallingUid() == Process.SYSTEM_UID 5055 || callingHasAudioSettingsPermission() 5056 || (mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_ROUTING) 5057 == PackageManager.PERMISSION_GRANTED); 5058 return (mStreamStates[streamType].getMinIndex(isPrivileged) + 5) / 10; 5059 } 5060 5061 @android.annotation.EnforcePermission(android.Manifest.permission.QUERY_AUDIO_STATE) 5062 /** Get last audible volume before stream was muted. */ getLastAudibleStreamVolume(int streamType)5063 public int getLastAudibleStreamVolume(int streamType) { 5064 super.getLastAudibleStreamVolume_enforcePermission(); 5065 5066 ensureValidStreamType(streamType); 5067 int device = getDeviceForStream(streamType); 5068 return (mStreamStates[streamType].getIndex(device) + 5) / 10; 5069 } 5070 5071 /** 5072 * Default VolumeInfo returned by {@link VolumeInfo#getDefaultVolumeInfo()} 5073 * Lazily initialized in {@link #getDefaultVolumeInfo()} 5074 */ 5075 static VolumeInfo sDefaultVolumeInfo; 5076 5077 /** @see VolumeInfo#getDefaultVolumeInfo() */ getDefaultVolumeInfo()5078 public VolumeInfo getDefaultVolumeInfo() { 5079 if (sDefaultVolumeInfo == null) { 5080 sDefaultVolumeInfo = new VolumeInfo.Builder(AudioSystem.STREAM_MUSIC) 5081 .setMinVolumeIndex(getStreamMinVolume(AudioSystem.STREAM_MUSIC)) 5082 .setMaxVolumeIndex(getStreamMaxVolume(AudioSystem.STREAM_MUSIC)) 5083 .build(); 5084 } 5085 return sDefaultVolumeInfo; 5086 } 5087 5088 /** 5089 * list of callback dispatchers for stream aliasing updates 5090 */ 5091 final RemoteCallbackList<IStreamAliasingDispatcher> mStreamAliasingDispatchers = 5092 new RemoteCallbackList<IStreamAliasingDispatcher>(); 5093 5094 /** 5095 * Register/unregister a callback for stream aliasing updates 5096 * @param isad the callback dispatcher 5097 * @param register whether this for a registration or unregistration 5098 * @see AudioManager#addOnStreamAliasingChangedListener(Executor, Runnable) 5099 * @see AudioManager#removeOnStreamAliasingChangedListener(Runnable) 5100 */ 5101 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) registerStreamAliasingDispatcher(IStreamAliasingDispatcher isad, boolean register)5102 public void registerStreamAliasingDispatcher(IStreamAliasingDispatcher isad, boolean register) { 5103 super.registerStreamAliasingDispatcher_enforcePermission(); 5104 Objects.requireNonNull(isad); 5105 5106 if (register) { 5107 mStreamAliasingDispatchers.register(isad); 5108 } else { 5109 mStreamAliasingDispatchers.unregister(isad); 5110 } 5111 } 5112 dispatchStreamAliasingUpdate()5113 protected void dispatchStreamAliasingUpdate() { 5114 final int nbDispatchers = mStreamAliasingDispatchers.beginBroadcast(); 5115 for (int i = 0; i < nbDispatchers; i++) { 5116 try { 5117 mStreamAliasingDispatchers.getBroadcastItem(i).dispatchStreamAliasingChanged(); 5118 } catch (RemoteException e) { 5119 Log.e(TAG, "Error on stream alias update dispatch", e); 5120 } 5121 } 5122 mStreamAliasingDispatchers.finishBroadcast(); 5123 } 5124 5125 /** 5126 * @see AudioManager#getIndependentStreamTypes() 5127 * @return the list of non-aliased stream types 5128 */ 5129 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) getIndependentStreamTypes()5130 public ArrayList<Integer> getIndependentStreamTypes() { 5131 super.getIndependentStreamTypes_enforcePermission(); 5132 5133 if (mUseVolumeGroupAliases) { 5134 return new ArrayList<>(Arrays.stream(AudioManager.getPublicStreamTypes()) 5135 .boxed().toList()); 5136 } 5137 ArrayList<Integer> res = new ArrayList(1); 5138 for (int stream : mStreamVolumeAlias) { 5139 if (!res.contains(stream)) { 5140 res.add(stream); 5141 } 5142 } 5143 return res; 5144 } 5145 5146 /** 5147 * @see AudioManager#getStreamTypeAlias(int) 5148 * @param sourceStreamType the stream type for which the alias is queried 5149 * @return the stream alias 5150 */ 5151 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) 5152 public @AudioManager.PublicStreamTypes getStreamTypeAlias(@udioManager.PublicStreamTypes int sourceStreamType)5153 int getStreamTypeAlias(@AudioManager.PublicStreamTypes int sourceStreamType) { 5154 super.getStreamTypeAlias_enforcePermission(); 5155 // verify parameters 5156 ensureValidStreamType(sourceStreamType); 5157 5158 return mStreamVolumeAlias[sourceStreamType]; 5159 } 5160 5161 /** 5162 * @see AudioManager#isVolumeControlUsingVolumeGroups() 5163 * @return true when volume control is performed through volume groups, false if it uses 5164 * stream types. 5165 */ 5166 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isVolumeControlUsingVolumeGroups()5167 public boolean isVolumeControlUsingVolumeGroups() { 5168 super.isVolumeControlUsingVolumeGroups_enforcePermission(); 5169 5170 return mUseVolumeGroupAliases; 5171 } 5172 5173 /** @see AudioManager#getUiSoundsStreamType() 5174 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for 5175 * UI Sounds identification. 5176 * Fallback on Voice configuration to ensure correct behavior of DnD feature. 5177 */ getUiSoundsStreamType()5178 public int getUiSoundsStreamType() { 5179 return mUseVolumeGroupAliases ? STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM] 5180 : mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM]; 5181 } 5182 5183 /** 5184 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for 5185 * UI Sounds identification. 5186 * Fallback on Voice configuration to ensure correct behavior of DnD feature. 5187 */ isUiSoundsStreamType(int aliasStreamType)5188 private boolean isUiSoundsStreamType(int aliasStreamType) { 5189 return mUseVolumeGroupAliases 5190 ? STREAM_VOLUME_ALIAS_VOICE[aliasStreamType] 5191 == STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM] 5192 : aliasStreamType == mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM]; 5193 } 5194 5195 /** @see AudioManager#setMicrophoneMute(boolean) */ 5196 @Override setMicrophoneMute(boolean on, String callingPackage, int userId, String attributionTag)5197 public void setMicrophoneMute(boolean on, String callingPackage, int userId, 5198 String attributionTag) { 5199 // If we are being called by the system check for user we are going to change 5200 // so we handle user restrictions correctly. 5201 int uid = Binder.getCallingUid(); 5202 if (uid == android.os.Process.SYSTEM_UID) { 5203 uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 5204 } 5205 MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 5206 .setUid(uid) 5207 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage) 5208 .set(MediaMetrics.Property.EVENT, "setMicrophoneMute") 5209 .set(MediaMetrics.Property.REQUEST, on 5210 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE); 5211 5212 // If OP_MUTE_MICROPHONE is set, disallow unmuting. 5213 if (!on && !checkNoteAppOp( 5214 AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage, attributionTag)) { 5215 mmi.set(MediaMetrics.Property.EARLY_RETURN, "disallow unmuting").record(); 5216 return; 5217 } 5218 if (!checkAudioSettingsPermission("setMicrophoneMute()")) { 5219 mmi.set(MediaMetrics.Property.EARLY_RETURN, "!checkAudioSettingsPermission").record(); 5220 return; 5221 } 5222 if (userId != UserHandle.getCallingUserId() && 5223 mContext.checkCallingOrSelfPermission( 5224 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 5225 != PackageManager.PERMISSION_GRANTED) { 5226 mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission").record(); 5227 return; 5228 } 5229 mMicMuteFromApi = on; 5230 mmi.record(); // record now, the no caller check will set the mute state. 5231 setMicrophoneMuteNoCallerCheck(userId); 5232 } 5233 5234 /** @see AudioManager#setMicrophoneMuteFromSwitch(boolean) */ setMicrophoneMuteFromSwitch(boolean on)5235 public void setMicrophoneMuteFromSwitch(boolean on) { 5236 int userId = Binder.getCallingUid(); 5237 if (userId != android.os.Process.SYSTEM_UID) { 5238 Log.e(TAG, "setMicrophoneMuteFromSwitch() called from non system user!"); 5239 return; 5240 } 5241 mMicMuteFromSwitch = on; 5242 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 5243 .setUid(userId) 5244 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteFromSwitch") 5245 .set(MediaMetrics.Property.REQUEST, on 5246 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE) 5247 .record(); 5248 setMicrophoneMuteNoCallerCheck(userId); 5249 } 5250 setMicMuteFromSwitchInput()5251 private void setMicMuteFromSwitchInput() { 5252 InputManager im = mContext.getSystemService(InputManager.class); 5253 final int isMicMuted = im.isMicMuted(); 5254 if (isMicMuted != InputManager.SWITCH_STATE_UNKNOWN) { 5255 setMicrophoneMuteFromSwitch(im.isMicMuted() != InputManager.SWITCH_STATE_OFF); 5256 } 5257 } 5258 5259 /** 5260 * Returns the microphone mute state as seen from the native audio system 5261 * @return true if microphone is reported as muted by primary HAL 5262 */ isMicrophoneMuted()5263 public boolean isMicrophoneMuted() { 5264 return mMicMuteFromSystemCached 5265 && (!mMicMuteFromPrivacyToggle 5266 || mMicMuteFromApi || mMicMuteFromRestrictions || mMicMuteFromSwitch); 5267 } 5268 isMicrophoneSupposedToBeMuted()5269 private boolean isMicrophoneSupposedToBeMuted() { 5270 return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi 5271 || mMicMuteFromPrivacyToggle; 5272 } 5273 setMicrophoneMuteNoCallerCheck(int userId)5274 private void setMicrophoneMuteNoCallerCheck(int userId) { 5275 final boolean muted = isMicrophoneSupposedToBeMuted(); 5276 if (DEBUG_VOL) { 5277 Log.d(TAG, String.format("Mic mute %b, user=%d", muted, userId)); 5278 } 5279 // only mute for the current user 5280 if (getCurrentUserId() == userId || userId == android.os.Process.SYSTEM_UID) { 5281 final boolean currentMute = mAudioSystem.isMicrophoneMuted(); 5282 final long identity = Binder.clearCallingIdentity(); 5283 try { 5284 final int ret = mAudioSystem.muteMicrophone(muted); 5285 5286 // update cache with the real state independently from what was set 5287 mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted(); 5288 if (ret != AudioSystem.AUDIO_STATUS_OK) { 5289 Log.e(TAG, "Error changing mic mute state to " + muted + " current:" 5290 + mMicMuteFromSystemCached); 5291 } 5292 5293 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 5294 .setUid(userId) 5295 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteNoCallerCheck") 5296 .set(MediaMetrics.Property.MUTE, mMicMuteFromSystemCached 5297 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 5298 .set(MediaMetrics.Property.REQUEST, muted 5299 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE) 5300 .set(MediaMetrics.Property.STATUS, ret) 5301 .record(); 5302 5303 // send the intent even if there was a failure to change the actual mute state: 5304 // the AudioManager.setMicrophoneMute API doesn't have a return value to 5305 // indicate if the call failed to successfully change the mute state, and receiving 5306 // the intent may be the only time an application can resynchronize its mic mute 5307 // state with the actual system mic mute state 5308 if (muted != currentMute) { 5309 sendMsg(mAudioHandler, MSG_BROADCAST_MICROPHONE_MUTE, 5310 SENDMSG_NOOP, 0, 0, null, 0); 5311 } 5312 } finally { 5313 Binder.restoreCallingIdentity(identity); 5314 } 5315 } 5316 } 5317 5318 @Override getRingerModeExternal()5319 public int getRingerModeExternal() { 5320 synchronized(mSettingsLock) { 5321 return mRingerModeExternal; 5322 } 5323 } 5324 5325 @Override getRingerModeInternal()5326 public int getRingerModeInternal() { 5327 synchronized(mSettingsLock) { 5328 return mRingerMode; 5329 } 5330 } 5331 ensureValidRingerMode(int ringerMode)5332 private void ensureValidRingerMode(int ringerMode) { 5333 if (!isValidRingerMode(ringerMode)) { 5334 throw new IllegalArgumentException("Bad ringer mode " + ringerMode); 5335 } 5336 } 5337 5338 /** @see AudioManager#isValidRingerMode(int) */ isValidRingerMode(int ringerMode)5339 public boolean isValidRingerMode(int ringerMode) { 5340 return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX; 5341 } 5342 setRingerModeExternal(int ringerMode, String caller)5343 public void setRingerModeExternal(int ringerMode, String caller) { 5344 if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode) 5345 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)) { 5346 throw new SecurityException("Not allowed to change Do Not Disturb state"); 5347 } 5348 5349 setRingerMode(ringerMode, caller, true /*external*/); 5350 } 5351 setRingerModeInternal(int ringerMode, String caller)5352 public void setRingerModeInternal(int ringerMode, String caller) { 5353 enforceVolumeController("setRingerModeInternal"); 5354 setRingerMode(ringerMode, caller, false /*external*/); 5355 } 5356 silenceRingerModeInternal(String reason)5357 public void silenceRingerModeInternal(String reason) { 5358 VibrationEffect effect = null; 5359 int ringerMode = AudioManager.RINGER_MODE_SILENT; 5360 int toastText = 0; 5361 5362 int silenceRingerSetting = Settings.Secure.VOLUME_HUSH_OFF; 5363 if (mContext.getResources() 5364 .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) { 5365 silenceRingerSetting = mSettings.getSecureIntForUser(mContentResolver, 5366 Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF, 5367 UserHandle.USER_CURRENT); 5368 } 5369 5370 switch(silenceRingerSetting) { 5371 case VOLUME_HUSH_MUTE: 5372 effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK); 5373 ringerMode = AudioManager.RINGER_MODE_SILENT; 5374 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent; 5375 break; 5376 case VOLUME_HUSH_VIBRATE: 5377 effect = VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK); 5378 ringerMode = AudioManager.RINGER_MODE_VIBRATE; 5379 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate; 5380 break; 5381 } 5382 maybeVibrate(effect, reason); 5383 setRingerModeInternal(ringerMode, reason); 5384 Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT).show(); 5385 } 5386 maybeVibrate(VibrationEffect effect, String reason)5387 private boolean maybeVibrate(VibrationEffect effect, String reason) { 5388 if (!mHasVibrator) { 5389 return false; 5390 } 5391 if (effect == null) { 5392 return false; 5393 } 5394 mVibrator.vibrate(Binder.getCallingUid(), mContext.getOpPackageName(), effect, 5395 reason, TOUCH_VIBRATION_ATTRIBUTES); 5396 return true; 5397 } 5398 setRingerMode(int ringerMode, String caller, boolean external)5399 private void setRingerMode(int ringerMode, String caller, boolean external) { 5400 if (mUseFixedVolume || mIsSingleVolume || mUseVolumeGroupAliases) { 5401 return; 5402 } 5403 if (caller == null || caller.length() == 0) { 5404 throw new IllegalArgumentException("Bad caller: " + caller); 5405 } 5406 ensureValidRingerMode(ringerMode); 5407 if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { 5408 ringerMode = AudioManager.RINGER_MODE_SILENT; 5409 } 5410 final long identity = Binder.clearCallingIdentity(); 5411 try { 5412 synchronized (mSettingsLock) { 5413 final int ringerModeInternal = getRingerModeInternal(); 5414 final int ringerModeExternal = getRingerModeExternal(); 5415 if (external) { 5416 setRingerModeExt(ringerMode); 5417 if (mRingerModeDelegate != null) { 5418 ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal, 5419 ringerMode, caller, ringerModeInternal, mVolumePolicy); 5420 } 5421 if (ringerMode != ringerModeInternal) { 5422 setRingerModeInt(ringerMode, true /*persist*/); 5423 } 5424 } else /*internal*/ { 5425 if (ringerMode != ringerModeInternal) { 5426 setRingerModeInt(ringerMode, true /*persist*/); 5427 } 5428 if (mRingerModeDelegate != null) { 5429 ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal, 5430 ringerMode, caller, ringerModeExternal, mVolumePolicy); 5431 } 5432 setRingerModeExt(ringerMode); 5433 } 5434 } 5435 } finally { 5436 Binder.restoreCallingIdentity(identity); 5437 } 5438 } 5439 setRingerModeExt(int ringerMode)5440 private void setRingerModeExt(int ringerMode) { 5441 synchronized(mSettingsLock) { 5442 if (ringerMode == mRingerModeExternal) return; 5443 mRingerModeExternal = ringerMode; 5444 } 5445 // Send sticky broadcast 5446 broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode); 5447 } 5448 5449 @GuardedBy("mSettingsLock") muteRingerModeStreams()5450 private void muteRingerModeStreams() { 5451 // Mute stream if not previously muted by ringer mode and (ringer mode 5452 // is not RINGER_MODE_NORMAL OR stream is zen muted) and stream is affected by ringer mode. 5453 // Unmute stream if previously muted by ringer/zen mode and ringer mode 5454 // is RINGER_MODE_NORMAL or stream is not affected by ringer mode. 5455 int numStreamTypes = AudioSystem.getNumStreamTypes(); 5456 5457 if (mNm == null) { 5458 mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 5459 } 5460 5461 final int ringerMode = mRingerMode; // Read ringer mode as reading primitives is atomic 5462 final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE 5463 || ringerMode == AudioManager.RINGER_MODE_SILENT; 5464 final boolean shouldRingSco = ringerMode == AudioManager.RINGER_MODE_VIBRATE 5465 && mDeviceBroker.isBluetoothScoActive(); 5466 // Ask audio policy engine to force use Bluetooth SCO channel if needed 5467 final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid() 5468 + "/" + Binder.getCallingPid(); 5469 sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, AudioSystem.FOR_VIBRATE_RINGING, 5470 shouldRingSco ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE, eventSource, 0); 5471 5472 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 5473 final boolean isMuted = isStreamMutedByRingerOrZenMode(streamType); 5474 final boolean muteAllowedBySco = 5475 !(shouldRingSco && streamType == AudioSystem.STREAM_RING); 5476 final boolean shouldZenMute = shouldZenMuteStream(streamType); 5477 final boolean shouldMute = shouldZenMute || (ringerModeMute 5478 && isStreamAffectedByRingerMode(streamType) && muteAllowedBySco); 5479 if (isMuted == shouldMute) continue; 5480 if (!shouldMute) { 5481 // unmute 5482 // ring and notifications volume should never be 0 when not silenced 5483 if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING 5484 || mStreamVolumeAlias[streamType] == AudioSystem.STREAM_NOTIFICATION) { 5485 synchronized (VolumeStreamState.class) { 5486 final VolumeStreamState vss = mStreamStates[streamType]; 5487 for (int i = 0; i < vss.mIndexMap.size(); i++) { 5488 int device = vss.mIndexMap.keyAt(i); 5489 int value = vss.mIndexMap.valueAt(i); 5490 if (value == 0) { 5491 vss.setIndex(10, device, TAG, true /*hasModifyAudioSettings*/); 5492 } 5493 } 5494 // Persist volume for stream ring when it is changed here 5495 final int device = getDeviceForStream(streamType); 5496 sendMsg(mAudioHandler, 5497 MSG_PERSIST_VOLUME, 5498 SENDMSG_QUEUE, 5499 device, 5500 0, 5501 mStreamStates[streamType], 5502 PERSIST_DELAY); 5503 } 5504 } 5505 sRingerAndZenModeMutedStreams &= ~(1 << streamType); 5506 sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent( 5507 sRingerAndZenModeMutedStreams, "muteRingerModeStreams")); 5508 mStreamStates[streamType].mute(false, "muteRingerModeStreams"); 5509 } else { 5510 // mute 5511 sRingerAndZenModeMutedStreams |= (1 << streamType); 5512 sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent( 5513 sRingerAndZenModeMutedStreams, "muteRingerModeStreams")); 5514 mStreamStates[streamType].mute(true, "muteRingerModeStreams"); 5515 } 5516 } 5517 } 5518 isAlarm(int streamType)5519 private boolean isAlarm(int streamType) { 5520 return streamType == AudioSystem.STREAM_ALARM; 5521 } 5522 isNotificationOrRinger(int streamType)5523 private boolean isNotificationOrRinger(int streamType) { 5524 return streamType == AudioSystem.STREAM_NOTIFICATION 5525 || streamType == AudioSystem.STREAM_RING; 5526 } 5527 isMedia(int streamType)5528 private boolean isMedia(int streamType) { 5529 return streamType == AudioSystem.STREAM_MUSIC; 5530 } 5531 5532 isSystem(int streamType)5533 private boolean isSystem(int streamType) { 5534 return streamType == AudioSystem.STREAM_SYSTEM; 5535 } 5536 setRingerModeInt(int ringerMode, boolean persist)5537 private void setRingerModeInt(int ringerMode, boolean persist) { 5538 final boolean change; 5539 synchronized(mSettingsLock) { 5540 change = mRingerMode != ringerMode; 5541 mRingerMode = ringerMode; 5542 muteRingerModeStreams(); 5543 } 5544 5545 // Post a persist ringer mode msg 5546 if (persist) { 5547 sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE, 5548 SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY); 5549 } 5550 if (change) { 5551 // Send sticky broadcast 5552 broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, ringerMode); 5553 } 5554 } 5555 postUpdateRingerModeServiceInt()5556 /*package*/ void postUpdateRingerModeServiceInt() { 5557 sendMsg(mAudioHandler, MSG_UPDATE_RINGER_MODE, SENDMSG_QUEUE, 0, 0, null, 0); 5558 } 5559 onUpdateRingerModeServiceInt()5560 private void onUpdateRingerModeServiceInt() { 5561 setRingerModeInt(getRingerModeInternal(), false); 5562 } 5563 5564 /** @see AudioManager#shouldVibrate(int) */ shouldVibrate(int vibrateType)5565 public boolean shouldVibrate(int vibrateType) { 5566 if (!mHasVibrator) return false; 5567 5568 switch (getVibrateSetting(vibrateType)) { 5569 5570 case AudioManager.VIBRATE_SETTING_ON: 5571 return getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT; 5572 5573 case AudioManager.VIBRATE_SETTING_ONLY_SILENT: 5574 return getRingerModeExternal() == AudioManager.RINGER_MODE_VIBRATE; 5575 5576 case AudioManager.VIBRATE_SETTING_OFF: 5577 // return false, even for incoming calls 5578 return false; 5579 5580 default: 5581 return false; 5582 } 5583 } 5584 5585 /** @see AudioManager#getVibrateSetting(int) */ getVibrateSetting(int vibrateType)5586 public int getVibrateSetting(int vibrateType) { 5587 if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF; 5588 return (mVibrateSetting >> (vibrateType * 2)) & 3; 5589 } 5590 5591 /** @see AudioManager#setVibrateSetting(int, int) */ setVibrateSetting(int vibrateType, int vibrateSetting)5592 public void setVibrateSetting(int vibrateType, int vibrateSetting) { 5593 5594 if (!mHasVibrator) return; 5595 5596 mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, vibrateType, 5597 vibrateSetting); 5598 5599 // Broadcast change 5600 broadcastVibrateSetting(vibrateType); 5601 5602 } 5603 5604 private class SetModeDeathHandler implements IBinder.DeathRecipient { 5605 private final IBinder mCb; // To be notified of client's death 5606 private final int mPid; 5607 private final int mUid; 5608 private final boolean mIsPrivileged; 5609 private final String mPackage; 5610 private int mMode; 5611 private long mUpdateTime; 5612 private boolean mPlaybackActive = false; 5613 private boolean mRecordingActive = false; 5614 SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, String caller, int mode)5615 SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, 5616 String caller, int mode) { 5617 mMode = mode; 5618 mCb = cb; 5619 mPid = pid; 5620 mUid = uid; 5621 mPackage = caller; 5622 mIsPrivileged = isPrivileged; 5623 mUpdateTime = java.lang.System.currentTimeMillis(); 5624 } 5625 binderDied()5626 public void binderDied() { 5627 synchronized (mDeviceBroker.mSetModeLock) { 5628 Log.w(TAG, "SetModeDeathHandler client died"); 5629 int index = mSetModeDeathHandlers.indexOf(this); 5630 if (index < 0) { 5631 Log.w(TAG, "unregistered SetModeDeathHandler client died"); 5632 } else { 5633 SetModeDeathHandler h = mSetModeDeathHandlers.get(index); 5634 mSetModeDeathHandlers.remove(index); 5635 sendMsg(mAudioHandler, 5636 MSG_UPDATE_AUDIO_MODE, 5637 SENDMSG_QUEUE, 5638 AudioSystem.MODE_CURRENT, 5639 android.os.Process.myPid(), 5640 mContext.getPackageName(), 5641 0); 5642 } 5643 } 5644 } 5645 getPid()5646 public int getPid() { 5647 return mPid; 5648 } 5649 setMode(int mode)5650 public void setMode(int mode) { 5651 mMode = mode; 5652 mUpdateTime = java.lang.System.currentTimeMillis(); 5653 } 5654 getMode()5655 public int getMode() { 5656 return mMode; 5657 } 5658 getBinder()5659 public IBinder getBinder() { 5660 return mCb; 5661 } 5662 getUid()5663 public int getUid() { 5664 return mUid; 5665 } 5666 getPackage()5667 public String getPackage() { 5668 return mPackage; 5669 } 5670 isPrivileged()5671 public boolean isPrivileged() { 5672 return mIsPrivileged; 5673 } 5674 getUpdateTime()5675 public long getUpdateTime() { 5676 return mUpdateTime; 5677 } 5678 setPlaybackActive(boolean active)5679 public void setPlaybackActive(boolean active) { 5680 mPlaybackActive = active; 5681 } 5682 setRecordingActive(boolean active)5683 public void setRecordingActive(boolean active) { 5684 mRecordingActive = active; 5685 } 5686 5687 /** 5688 * An app is considered active if: 5689 * - It is privileged (has MODIFY_PHONE_STATE permission) 5690 * or 5691 * - It requests mode MODE_IN_COMMUNICATION, and it is either playing 5692 * or recording for VOICE_COMMUNICATION. 5693 * or 5694 * - It requests a mode different from MODE_IN_COMMUNICATION or MODE_NORMAL 5695 * Note: only privileged apps can request MODE_IN_CALL, MODE_CALL_REDIRECT 5696 * or MODE_COMMUNICATION_REDIRECT. 5697 */ isActive()5698 public boolean isActive() { 5699 return mIsPrivileged 5700 || ((mMode == AudioSystem.MODE_IN_COMMUNICATION) 5701 && (mRecordingActive || mPlaybackActive)) 5702 || mMode == AudioSystem.MODE_RINGTONE 5703 || mMode == AudioSystem.MODE_CALL_SCREENING; 5704 } 5705 dump(PrintWriter pw, int index)5706 public void dump(PrintWriter pw, int index) { 5707 SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss:SSS"); 5708 5709 if (index >= 0) { 5710 pw.println(" Requester # " + (index + 1) + ":"); 5711 } 5712 pw.println(" - Mode: " + AudioSystem.modeToString(mMode)); 5713 pw.println(" - Binder: " + mCb); 5714 pw.println(" - Pid: " + mPid); 5715 pw.println(" - Uid: " + mUid); 5716 pw.println(" - Package: " + mPackage); 5717 pw.println(" - Privileged: " + mIsPrivileged); 5718 pw.println(" - Active: " + isActive()); 5719 pw.println(" Playback active: " + mPlaybackActive); 5720 pw.println(" Recording active: " + mRecordingActive); 5721 pw.println(" - update time: " + format.format(new Date(mUpdateTime))); 5722 } 5723 } 5724 5725 @GuardedBy("mDeviceBroker.mSetModeLock") getAudioModeOwnerHandler()5726 private SetModeDeathHandler getAudioModeOwnerHandler() { 5727 // The Audio mode owner is: 5728 // 1) the most recent privileged app in the stack 5729 // 2) the most recent active app in the tack 5730 SetModeDeathHandler modeOwner = null; 5731 SetModeDeathHandler privilegedModeOwner = null; 5732 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 5733 if (h.isActive()) { 5734 // privileged apps are always active 5735 if (h.isPrivileged()) { 5736 if (privilegedModeOwner == null 5737 || h.getUpdateTime() > privilegedModeOwner.getUpdateTime()) { 5738 privilegedModeOwner = h; 5739 } 5740 } else { 5741 if (modeOwner == null 5742 || h.getUpdateTime() > modeOwner.getUpdateTime()) { 5743 modeOwner = h; 5744 } 5745 } 5746 } 5747 } 5748 return privilegedModeOwner != null ? privilegedModeOwner : modeOwner; 5749 } 5750 5751 /** 5752 * Return information on the current audio mode owner 5753 * @return 0 if nobody owns the mode 5754 */ 5755 @GuardedBy("mDeviceBroker.mSetModeLock") getAudioModeOwner()5756 /*package*/ AudioDeviceBroker.AudioModeInfo getAudioModeOwner() { 5757 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 5758 if (hdlr != null) { 5759 return new AudioDeviceBroker.AudioModeInfo( 5760 hdlr.getMode(), hdlr.getPid(), hdlr.getUid()); 5761 } 5762 return new AudioDeviceBroker.AudioModeInfo(AudioSystem.MODE_NORMAL, 0 , 0); 5763 } 5764 5765 /** 5766 * Return the uid of the current audio mode owner 5767 * @return 0 if nobody owns the mode 5768 */ 5769 @GuardedBy("mDeviceBroker.mSetModeLock") getModeOwnerUid()5770 /*package*/ int getModeOwnerUid() { 5771 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 5772 if (hdlr != null) { 5773 return hdlr.getUid(); 5774 } 5775 return 0; 5776 } 5777 5778 /** @see AudioManager#setMode(int) */ setMode(int mode, IBinder cb, String callingPackage)5779 public void setMode(int mode, IBinder cb, String callingPackage) { 5780 int pid = Binder.getCallingPid(); 5781 int uid = Binder.getCallingUid(); 5782 if (DEBUG_MODE) { 5783 Log.v(TAG, "setMode(mode=" + mode + ", pid=" + pid 5784 + ", uid=" + uid + ", caller=" + callingPackage + ")"); 5785 } 5786 if (!checkAudioSettingsPermission("setMode()")) { 5787 return; 5788 } 5789 if (cb == null) { 5790 Log.e(TAG, "setMode() called with null binder"); 5791 return; 5792 } 5793 if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) { 5794 Log.w(TAG, "setMode() invalid mode: " + mode); 5795 return; 5796 } 5797 5798 if (mode == AudioSystem.MODE_CURRENT) { 5799 mode = getMode(); 5800 } 5801 5802 if (mode == AudioSystem.MODE_CALL_SCREENING && !mIsCallScreeningModeSupported) { 5803 Log.w(TAG, "setMode(MODE_CALL_SCREENING) not permitted " 5804 + "when call screening is not supported"); 5805 return; 5806 } 5807 5808 final boolean hasModifyPhoneStatePermission = mContext.checkCallingOrSelfPermission( 5809 android.Manifest.permission.MODIFY_PHONE_STATE) 5810 == PackageManager.PERMISSION_GRANTED; 5811 if ((mode == AudioSystem.MODE_IN_CALL 5812 || mode == AudioSystem.MODE_CALL_REDIRECT 5813 || mode == AudioSystem.MODE_COMMUNICATION_REDIRECT) 5814 && !hasModifyPhoneStatePermission) { 5815 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setMode(" 5816 + AudioSystem.modeToString(mode) + ") from pid=" + pid 5817 + ", uid=" + Binder.getCallingUid()); 5818 return; 5819 } 5820 5821 SetModeDeathHandler currentModeHandler = null; 5822 synchronized (mDeviceBroker.mSetModeLock) { 5823 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 5824 if (h.getPid() == pid) { 5825 currentModeHandler = h; 5826 break; 5827 } 5828 } 5829 5830 if (mode == AudioSystem.MODE_NORMAL) { 5831 if (currentModeHandler != null) { 5832 if (!currentModeHandler.isPrivileged() 5833 && currentModeHandler.getMode() == AudioSystem.MODE_IN_COMMUNICATION) { 5834 mAudioHandler.removeEqualMessages( 5835 MSG_CHECK_MODE_FOR_UID, currentModeHandler); 5836 } 5837 mSetModeDeathHandlers.remove(currentModeHandler); 5838 if (DEBUG_MODE) { 5839 Log.v(TAG, "setMode(" + mode + ") removing hldr for pid: " + pid); 5840 } 5841 try { 5842 currentModeHandler.getBinder().unlinkToDeath(currentModeHandler, 0); 5843 } catch (NoSuchElementException e) { 5844 Log.w(TAG, "setMode link does not exist ..."); 5845 } 5846 } 5847 } else { 5848 if (currentModeHandler != null) { 5849 currentModeHandler.setMode(mode); 5850 if (DEBUG_MODE) { 5851 Log.v(TAG, "setMode(" + mode + ") updating hldr for pid: " + pid); 5852 } 5853 } else { 5854 currentModeHandler = new SetModeDeathHandler(cb, pid, uid, 5855 hasModifyPhoneStatePermission, callingPackage, mode); 5856 // Register for client death notification 5857 try { 5858 cb.linkToDeath(currentModeHandler, 0); 5859 } catch (RemoteException e) { 5860 // Client has died! 5861 Log.w(TAG, "setMode() could not link to " + cb + " binder death"); 5862 return; 5863 } 5864 mSetModeDeathHandlers.add(currentModeHandler); 5865 if (DEBUG_MODE) { 5866 Log.v(TAG, "setMode(" + mode + ") adding handler for pid=" + pid); 5867 } 5868 } 5869 if (mode == AudioSystem.MODE_IN_COMMUNICATION) { 5870 // Force active state when entering/updating the stack to avoid glitches when 5871 // an app starts playing/recording after settng the audio mode, 5872 // and send a reminder to check activity after a grace period. 5873 if (!currentModeHandler.isPrivileged()) { 5874 currentModeHandler.setPlaybackActive(true); 5875 currentModeHandler.setRecordingActive(true); 5876 sendMsg(mAudioHandler, 5877 MSG_CHECK_MODE_FOR_UID, 5878 SENDMSG_QUEUE, 5879 0, 5880 0, 5881 currentModeHandler, 5882 CHECK_MODE_FOR_UID_PERIOD_MS); 5883 } 5884 } 5885 } 5886 5887 sendMsg(mAudioHandler, 5888 MSG_UPDATE_AUDIO_MODE, 5889 SENDMSG_REPLACE, 5890 mode, 5891 pid, 5892 callingPackage, 5893 0); 5894 } 5895 } 5896 5897 @GuardedBy("mDeviceBroker.mSetModeLock") onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, boolean force)5898 void onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, 5899 boolean force) { 5900 if (requestedMode == AudioSystem.MODE_CURRENT) { 5901 requestedMode = getMode(); 5902 } 5903 int mode = AudioSystem.MODE_NORMAL; 5904 int uid = 0; 5905 int pid = 0; 5906 SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler(); 5907 if (currentModeHandler != null) { 5908 mode = currentModeHandler.getMode(); 5909 uid = currentModeHandler.getUid(); 5910 pid = currentModeHandler.getPid(); 5911 } 5912 if (DEBUG_MODE) { 5913 Log.v(TAG, "onUpdateAudioMode() new mode: " + mode + ", current mode: " 5914 + mMode.get() + " requested mode: " + requestedMode); 5915 } 5916 if (mode != mMode.get() || force) { 5917 int status = AudioSystem.SUCCESS; 5918 final long identity = Binder.clearCallingIdentity(); 5919 try { 5920 status = mAudioSystem.setPhoneState(mode, uid); 5921 } finally { 5922 Binder.restoreCallingIdentity(identity); 5923 } 5924 if (status == AudioSystem.AUDIO_STATUS_OK) { 5925 if (DEBUG_MODE) { 5926 Log.v(TAG, "onUpdateAudioMode: mode successfully set to " + mode); 5927 } 5928 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_MODE, SENDMSG_REPLACE, mode, 0, 5929 /*obj*/ null, /*delay*/ 0); 5930 int previousMode = mMode.getAndSet(mode); 5931 // Note: newModeOwnerPid is always 0 when actualMode is MODE_NORMAL 5932 mModeLogger.enqueue(new PhoneStateEvent(requesterPackage, requesterPid, 5933 requestedMode, pid, mode)); 5934 5935 final int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE); 5936 final int device = getDeviceForStream(streamType); 5937 final int streamAlias = mStreamVolumeAlias[streamType]; 5938 5939 if (DEBUG_MODE) { 5940 Log.v(TAG, "onUpdateAudioMode: streamType=" + streamType 5941 + ", streamAlias=" + streamAlias); 5942 } 5943 5944 final int index = mStreamStates[streamAlias].getIndex(device); 5945 final int maxIndex = mStreamStates[streamAlias].getMaxIndex(); 5946 setStreamVolumeInt(streamAlias, index, device, true, 5947 requesterPackage, true /*hasModifyAudioSettings*/); 5948 5949 updateStreamVolumeAlias(true /*updateVolumes*/, requesterPackage); 5950 5951 // change of mode may require volume to be re-applied on some devices 5952 updateAbsVolumeMultiModeDevices(previousMode, mode); 5953 5954 setLeAudioVolumeOnModeUpdate(mode, device, streamAlias, index, maxIndex); 5955 5956 // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO 5957 // connections not started by the application changing the mode when pid changes 5958 mDeviceBroker.postSetModeOwner(mode, pid, uid); 5959 } else { 5960 Log.w(TAG, "onUpdateAudioMode: failed to set audio mode to: " + mode); 5961 } 5962 } 5963 } 5964 5965 /** @see AudioManager#getMode() */ getMode()5966 public int getMode() { 5967 synchronized (mDeviceBroker.mSetModeLock) { 5968 SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler(); 5969 if (currentModeHandler != null) { 5970 return currentModeHandler.getMode(); 5971 } 5972 return AudioSystem.MODE_NORMAL; 5973 } 5974 } 5975 5976 /** cached value read from audiopolicy manager after initialization. */ 5977 private boolean mIsCallScreeningModeSupported = false; 5978 5979 /** @see AudioManager#isCallScreeningModeSupported() */ isCallScreeningModeSupported()5980 public boolean isCallScreeningModeSupported() { 5981 return mIsCallScreeningModeSupported; 5982 } 5983 dispatchMode(int mode)5984 protected void dispatchMode(int mode) { 5985 final int nbDispatchers = mModeDispatchers.beginBroadcast(); 5986 for (int i = 0; i < nbDispatchers; i++) { 5987 try { 5988 mModeDispatchers.getBroadcastItem(i).dispatchAudioModeChanged(mode); 5989 } catch (RemoteException e) { 5990 } 5991 } 5992 mModeDispatchers.finishBroadcast(); 5993 } 5994 5995 final RemoteCallbackList<IAudioModeDispatcher> mModeDispatchers = 5996 new RemoteCallbackList<IAudioModeDispatcher>(); 5997 5998 /** 5999 * @see {@link AudioManager#addOnModeChangedListener(Executor, AudioManager.OnModeChangedListener)} 6000 * @param dispatcher 6001 */ registerModeDispatcher( @onNull IAudioModeDispatcher dispatcher)6002 public void registerModeDispatcher( 6003 @NonNull IAudioModeDispatcher dispatcher) { 6004 mModeDispatchers.register(dispatcher); 6005 } 6006 6007 /** 6008 * @see {@link AudioManager#removeOnModeChangedListener(AudioManager.OnModeChangedListener)} 6009 * @param dispatcher 6010 */ unregisterModeDispatcher( @onNull IAudioModeDispatcher dispatcher)6011 public void unregisterModeDispatcher( 6012 @NonNull IAudioModeDispatcher dispatcher) { 6013 mModeDispatchers.unregister(dispatcher); 6014 } 6015 6016 @android.annotation.EnforcePermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION) 6017 /** @see AudioManager#isPstnCallAudioInterceptable() */ isPstnCallAudioInterceptable()6018 public boolean isPstnCallAudioInterceptable() { 6019 6020 super.isPstnCallAudioInterceptable_enforcePermission(); 6021 6022 boolean uplinkDeviceFound = false; 6023 boolean downlinkDeviceFound = false; 6024 AudioDeviceInfo[] devices = AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_ALL); 6025 for (AudioDeviceInfo device : devices) { 6026 if (device.getInternalType() == AudioSystem.DEVICE_OUT_TELEPHONY_TX) { 6027 uplinkDeviceFound = true; 6028 } else if (device.getInternalType() == AudioSystem.DEVICE_IN_TELEPHONY_RX) { 6029 downlinkDeviceFound = true; 6030 } 6031 if (uplinkDeviceFound && downlinkDeviceFound) { 6032 return true; 6033 } 6034 } 6035 return false; 6036 } 6037 6038 /** @see AudioManager#setRttEnabled() */ 6039 @Override setRttEnabled(boolean rttEnabled)6040 public void setRttEnabled(boolean rttEnabled) { 6041 if (mContext.checkCallingOrSelfPermission( 6042 android.Manifest.permission.MODIFY_PHONE_STATE) 6043 != PackageManager.PERMISSION_GRANTED) { 6044 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setRttEnabled from pid=" 6045 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 6046 return; 6047 } 6048 synchronized (mSettingsLock) { 6049 mRttEnabled = rttEnabled; 6050 final long identity = Binder.clearCallingIdentity(); 6051 try { 6052 AudioSystem.setRttEnabled(rttEnabled); 6053 } finally { 6054 Binder.restoreCallingIdentity(identity); 6055 } 6056 } 6057 } 6058 6059 /** @see AudioManager#adjustSuggestedStreamVolumeForUid(int, int, int, String, int, int, int) */ 6060 @Override adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6061 public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, 6062 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 6063 int targetSdkVersion) { 6064 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 6065 throw new SecurityException("Should only be called from system process"); 6066 } 6067 6068 // direction and stream type swap here because the public 6069 // adjustSuggested has a different order than the other methods. 6070 adjustSuggestedStreamVolume(direction, streamType, flags, packageName, packageName, 6071 uid, pid, hasAudioSettingsPermission(uid, pid), 6072 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 6073 } 6074 6075 /** @see AudioManager#adjustStreamVolumeForUid(int, int, int, String, int, int, int) */ 6076 @Override adjustStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6077 public void adjustStreamVolumeForUid(int streamType, int direction, int flags, 6078 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 6079 int targetSdkVersion) { 6080 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 6081 throw new SecurityException("Should only be called from system process"); 6082 } 6083 6084 if (direction != AudioManager.ADJUST_SAME) { 6085 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType, 6086 direction/*val1*/, flags/*val2*/, 6087 new StringBuilder(packageName).append(" uid:").append(uid) 6088 .toString())); 6089 } 6090 6091 adjustStreamVolume(streamType, direction, flags, packageName, packageName, uid, pid, 6092 null, hasAudioSettingsPermission(uid, pid), 6093 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 6094 } 6095 6096 /** @see AudioManager#setStreamVolumeForUid(int, int, int, String, int, int, int) */ 6097 @Override setStreamVolumeForUid(int streamType, int index, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6098 public void setStreamVolumeForUid(int streamType, int index, int flags, 6099 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 6100 int targetSdkVersion) { 6101 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 6102 throw new SecurityException("Should only be called from system process"); 6103 } 6104 6105 setStreamVolume(streamType, index, flags, /*device*/ null, 6106 packageName, packageName, null, uid, 6107 hasAudioSettingsPermission(uid, pid)); 6108 } 6109 6110 //========================================================================================== 6111 // Sound Effects 6112 //========================================================================================== 6113 private static final class LoadSoundEffectReply 6114 implements SoundEffectsHelper.OnEffectsLoadCompleteHandler { 6115 private static final int SOUND_EFFECTS_LOADING = 1; 6116 private static final int SOUND_EFFECTS_LOADED = 0; 6117 private static final int SOUND_EFFECTS_ERROR = -1; 6118 private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000; 6119 6120 private int mStatus = SOUND_EFFECTS_LOADING; 6121 6122 @Override run(boolean success)6123 public synchronized void run(boolean success) { 6124 mStatus = success ? SOUND_EFFECTS_LOADED : SOUND_EFFECTS_ERROR; 6125 notify(); 6126 } 6127 waitForLoaded(int attempts)6128 public synchronized boolean waitForLoaded(int attempts) { 6129 while ((mStatus == SOUND_EFFECTS_LOADING) && (attempts-- > 0)) { 6130 try { 6131 wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS); 6132 } catch (InterruptedException e) { 6133 Log.w(TAG, "Interrupted while waiting sound pool loaded."); 6134 } 6135 } 6136 return mStatus == SOUND_EFFECTS_LOADED; 6137 } 6138 } 6139 6140 /** @see AudioManager#playSoundEffect(int, int) */ playSoundEffect(int effectType, int userId)6141 public void playSoundEffect(int effectType, int userId) { 6142 if (querySoundEffectsEnabled(userId)) { 6143 playSoundEffectVolume(effectType, -1.0f); 6144 } 6145 } 6146 6147 /** 6148 * Settings has an in memory cache, so this is fast. 6149 */ querySoundEffectsEnabled(int user)6150 private boolean querySoundEffectsEnabled(int user) { 6151 return mSettings.getSystemIntForUser(getContentResolver(), 6152 Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0; 6153 } 6154 6155 /** @see AudioManager#playSoundEffect(int, float) */ playSoundEffectVolume(int effectType, float volume)6156 public void playSoundEffectVolume(int effectType, float volume) { 6157 // do not try to play the sound effect if the system stream is muted 6158 if (isStreamMute(STREAM_SYSTEM)) { 6159 return; 6160 } 6161 6162 if (effectType >= AudioManager.NUM_SOUND_EFFECTS || effectType < 0) { 6163 Log.w(TAG, "AudioService effectType value " + effectType + " out of range"); 6164 return; 6165 } 6166 6167 sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE, 6168 effectType, (int) (volume * 1000), null, 0); 6169 } 6170 6171 /** 6172 * Loads samples into the soundpool. 6173 * This method must be called at first when sound effects are enabled 6174 */ loadSoundEffects()6175 public boolean loadSoundEffects() { 6176 LoadSoundEffectReply reply = new LoadSoundEffectReply(); 6177 sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0); 6178 return reply.waitForLoaded(3 /*attempts*/); 6179 } 6180 6181 /** 6182 * Schedule loading samples into the soundpool. 6183 * This method can be overridden to schedule loading at a later time. 6184 */ scheduleLoadSoundEffects()6185 protected void scheduleLoadSoundEffects() { 6186 sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0); 6187 } 6188 6189 /** 6190 * Unloads samples from the sound pool. 6191 * This method can be called to free some memory when 6192 * sound effects are disabled. 6193 */ unloadSoundEffects()6194 public void unloadSoundEffects() { 6195 sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0); 6196 } 6197 6198 /** @see AudioManager#reloadAudioSettings() */ reloadAudioSettings()6199 public void reloadAudioSettings() { 6200 readAudioSettings(false /*userSwitch*/); 6201 } 6202 readAudioSettings(boolean userSwitch)6203 private void readAudioSettings(boolean userSwitch) { 6204 // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings 6205 readPersistedSettings(); 6206 readUserRestrictions(); 6207 6208 // restore volume settings 6209 int numStreamTypes = AudioSystem.getNumStreamTypes(); 6210 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 6211 VolumeStreamState streamState = mStreamStates[streamType]; 6212 6213 if (userSwitch && mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) { 6214 continue; 6215 } 6216 6217 streamState.readSettings(); 6218 synchronized (VolumeStreamState.class) { 6219 // unmute stream that was muted but is not affect by mute anymore 6220 if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) && 6221 !isStreamMutedByRingerOrZenMode(streamType)) || mUseFixedVolume)) { 6222 streamState.mIsMuted = false; 6223 } 6224 } 6225 } 6226 6227 readVolumeGroupsSettings(userSwitch); 6228 6229 // apply new ringer mode before checking volume for alias streams so that streams 6230 // muted by ringer mode have the correct volume 6231 setRingerModeInt(getRingerModeInternal(), false); 6232 6233 checkAllFixedVolumeDevices(); 6234 checkAllAliasStreamVolumes(); 6235 checkMuteAffectedStreams(); 6236 6237 mSoundDoseHelper.restoreMusicActiveMs(); 6238 mSoundDoseHelper.enforceSafeMediaVolumeIfActive(TAG); 6239 6240 if (DEBUG_VOL) { 6241 Log.d(TAG, "Restoring device volume behavior"); 6242 } 6243 restoreDeviceVolumeBehavior(); 6244 } 6245 6246 /** @see AudioManager#getAvailableCommunicationDevices(int) */ getAvailableCommunicationDeviceIds()6247 public int[] getAvailableCommunicationDeviceIds() { 6248 List<AudioDeviceInfo> commDevices = AudioDeviceBroker.getAvailableCommunicationDevices(); 6249 return commDevices.stream().mapToInt(AudioDeviceInfo::getId).toArray(); 6250 } 6251 6252 /** 6253 * @see AudioManager#setCommunicationDevice(int) 6254 * @see AudioManager#clearCommunicationDevice() 6255 */ setCommunicationDevice(IBinder cb, int portId)6256 public boolean setCommunicationDevice(IBinder cb, int portId) { 6257 final int uid = Binder.getCallingUid(); 6258 final int pid = Binder.getCallingPid(); 6259 6260 AudioDeviceInfo device = null; 6261 if (portId != 0) { 6262 device = AudioManager.getDeviceForPortId(portId, AudioManager.GET_DEVICES_OUTPUTS); 6263 if (device == null) { 6264 Log.w(TAG, "setCommunicationDevice: invalid portID " + portId); 6265 return false; 6266 } 6267 if (!AudioDeviceBroker.isValidCommunicationDevice(device)) { 6268 if (!device.isSink()) { 6269 throw new IllegalArgumentException("device must have sink role"); 6270 } else { 6271 throw new IllegalArgumentException("invalid device type: " + device.getType()); 6272 } 6273 } 6274 } 6275 final String eventSource = new StringBuilder() 6276 .append(device == null ? "clearCommunicationDevice(" : "setCommunicationDevice(") 6277 .append(") from u/pid:").append(uid).append("/") 6278 .append(pid).toString(); 6279 6280 int deviceType = AudioSystem.DEVICE_OUT_DEFAULT; 6281 String deviceAddress = null; 6282 if (device != null) { 6283 deviceType = device.getPort().type(); 6284 deviceAddress = device.getAddress(); 6285 } else { 6286 AudioDeviceInfo curDevice = mDeviceBroker.getCommunicationDevice(); 6287 if (curDevice != null) { 6288 deviceType = curDevice.getPort().type(); 6289 deviceAddress = curDevice.getAddress(); 6290 } 6291 } 6292 // do not log metrics if clearing communication device while no communication device 6293 // was selected 6294 if (deviceType != AudioSystem.DEVICE_OUT_DEFAULT) { 6295 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 6296 + MediaMetrics.SEPARATOR + "setCommunicationDevice") 6297 .set(MediaMetrics.Property.DEVICE, 6298 AudioSystem.getDeviceName(deviceType)) 6299 .set(MediaMetrics.Property.ADDRESS, deviceAddress) 6300 .set(MediaMetrics.Property.STATE, device != null 6301 ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED) 6302 .record(); 6303 } 6304 final boolean isPrivileged = mContext.checkCallingOrSelfPermission( 6305 android.Manifest.permission.MODIFY_PHONE_STATE) 6306 == PackageManager.PERMISSION_GRANTED; 6307 final long ident = Binder.clearCallingIdentity(); 6308 try { 6309 return mDeviceBroker.setCommunicationDevice(cb, uid, device, isPrivileged, eventSource); 6310 } finally { 6311 Binder.restoreCallingIdentity(ident); 6312 } 6313 } 6314 6315 /** @see AudioManager#getCommunicationDevice() */ getCommunicationDevice()6316 public int getCommunicationDevice() { 6317 int deviceId = 0; 6318 final long ident = Binder.clearCallingIdentity(); 6319 try { 6320 AudioDeviceInfo device = mDeviceBroker.getCommunicationDevice(); 6321 deviceId = device != null ? device.getId() : 0; 6322 } finally { 6323 Binder.restoreCallingIdentity(ident); 6324 } 6325 return deviceId; 6326 } 6327 6328 /** @see AudioManager#addOnCommunicationDeviceChangedListener( 6329 * Executor, AudioManager.OnCommunicationDeviceChangedListener) 6330 */ registerCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)6331 public void registerCommunicationDeviceDispatcher( 6332 @Nullable ICommunicationDeviceDispatcher dispatcher) { 6333 if (dispatcher == null) { 6334 return; 6335 } 6336 mDeviceBroker.registerCommunicationDeviceDispatcher(dispatcher); 6337 } 6338 6339 /** @see AudioManager#removeOnCommunicationDeviceChangedListener( 6340 * AudioManager.OnCommunicationDeviceChangedListener) 6341 */ unregisterCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)6342 public void unregisterCommunicationDeviceDispatcher( 6343 @Nullable ICommunicationDeviceDispatcher dispatcher) { 6344 if (dispatcher == null) { 6345 return; 6346 } 6347 mDeviceBroker.unregisterCommunicationDeviceDispatcher(dispatcher); 6348 } 6349 6350 /** @see AudioManager#setSpeakerphoneOn(boolean) */ setSpeakerphoneOn(IBinder cb, boolean on)6351 public void setSpeakerphoneOn(IBinder cb, boolean on) { 6352 if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) { 6353 return; 6354 } 6355 final boolean isPrivileged = mContext.checkCallingOrSelfPermission( 6356 android.Manifest.permission.MODIFY_PHONE_STATE) 6357 == PackageManager.PERMISSION_GRANTED; 6358 6359 // for logging only 6360 final int uid = Binder.getCallingUid(); 6361 final int pid = Binder.getCallingPid(); 6362 6363 final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on) 6364 .append(") from u/pid:").append(uid).append("/") 6365 .append(pid).toString(); 6366 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 6367 + MediaMetrics.SEPARATOR + "setSpeakerphoneOn") 6368 .setUid(uid) 6369 .setPid(pid) 6370 .set(MediaMetrics.Property.STATE, on 6371 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 6372 .record(); 6373 6374 final long ident = Binder.clearCallingIdentity(); 6375 try { 6376 mDeviceBroker.setSpeakerphoneOn(cb, uid, on, isPrivileged, eventSource); 6377 } finally { 6378 Binder.restoreCallingIdentity(ident); 6379 } 6380 } 6381 6382 /** @see AudioManager#isSpeakerphoneOn() */ isSpeakerphoneOn()6383 public boolean isSpeakerphoneOn() { 6384 return mDeviceBroker.isSpeakerphoneOn(); 6385 } 6386 6387 6388 /** BT SCO audio state seen by apps using the deprecated API setBluetoothScoOn(). 6389 * @see isBluetoothScoOn() */ 6390 private boolean mBtScoOnByApp; 6391 6392 /** @see AudioManager#setBluetoothScoOn(boolean) */ setBluetoothScoOn(boolean on)6393 public void setBluetoothScoOn(boolean on) { 6394 if (!checkAudioSettingsPermission("setBluetoothScoOn()")) { 6395 return; 6396 } 6397 6398 // Only enable calls from system components 6399 if (UserHandle.getCallingAppId() >= FIRST_APPLICATION_UID) { 6400 mBtScoOnByApp = on; 6401 return; 6402 } 6403 6404 // for logging only 6405 final int uid = Binder.getCallingUid(); 6406 final int pid = Binder.getCallingPid(); 6407 final String eventSource = new StringBuilder("setBluetoothScoOn(").append(on) 6408 .append(") from u/pid:").append(uid).append("/").append(pid).toString(); 6409 6410 //bt sco 6411 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 6412 + MediaMetrics.SEPARATOR + "setBluetoothScoOn") 6413 .setUid(uid) 6414 .setPid(pid) 6415 .set(MediaMetrics.Property.STATE, on 6416 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 6417 .record(); 6418 6419 mDeviceBroker.setBluetoothScoOn(on, eventSource); 6420 } 6421 6422 /** @see AudioManager#setA2dpSuspended(boolean) */ 6423 @android.annotation.EnforcePermission(android.Manifest.permission.BLUETOOTH_STACK) setA2dpSuspended(boolean enable)6424 public void setA2dpSuspended(boolean enable) { 6425 super.setA2dpSuspended_enforcePermission(); 6426 final String eventSource = new StringBuilder("setA2dpSuspended(").append(enable) 6427 .append(") from u/pid:").append(Binder.getCallingUid()).append("/") 6428 .append(Binder.getCallingPid()).toString(); 6429 mDeviceBroker.setA2dpSuspended(enable, false /*internal*/, eventSource); 6430 } 6431 6432 /** @see AudioManager#setA2dpSuspended(boolean) */ 6433 @android.annotation.EnforcePermission(android.Manifest.permission.BLUETOOTH_STACK) setLeAudioSuspended(boolean enable)6434 public void setLeAudioSuspended(boolean enable) { 6435 super.setLeAudioSuspended_enforcePermission(); 6436 final String eventSource = new StringBuilder("setLeAudioSuspended(").append(enable) 6437 .append(") from u/pid:").append(Binder.getCallingUid()).append("/") 6438 .append(Binder.getCallingPid()).toString(); 6439 mDeviceBroker.setLeAudioSuspended(enable, false /*internal*/, eventSource); 6440 } 6441 6442 /** @see AudioManager#isBluetoothScoOn() 6443 * Note that it doesn't report internal state, but state seen by apps (which may have 6444 * called setBluetoothScoOn() */ isBluetoothScoOn()6445 public boolean isBluetoothScoOn() { 6446 return mBtScoOnByApp || mDeviceBroker.isBluetoothScoOn(); 6447 } 6448 6449 // TODO investigate internal users due to deprecation of SDK API 6450 /** @see AudioManager#setBluetoothA2dpOn(boolean) */ setBluetoothA2dpOn(boolean on)6451 public void setBluetoothA2dpOn(boolean on) { 6452 if (!checkAudioSettingsPermission("setBluetoothA2dpOn()")) { 6453 return; 6454 } 6455 6456 // for logging only 6457 final int uid = Binder.getCallingUid(); 6458 final int pid = Binder.getCallingPid(); 6459 final String eventSource = new StringBuilder("setBluetoothA2dpOn(").append(on) 6460 .append(") from u/pid:").append(uid).append("/") 6461 .append(pid).toString(); 6462 6463 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 6464 + MediaMetrics.SEPARATOR + "setBluetoothA2dpOn") 6465 .setUid(uid) 6466 .setPid(pid) 6467 .set(MediaMetrics.Property.STATE, on 6468 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 6469 .record(); 6470 6471 mDeviceBroker.setBluetoothA2dpOn_Async(on, eventSource); 6472 } 6473 6474 /** @see AudioManager#isBluetoothA2dpOn() */ isBluetoothA2dpOn()6475 public boolean isBluetoothA2dpOn() { 6476 return mDeviceBroker.isBluetoothA2dpOn(); 6477 } 6478 6479 /** @see AudioManager#startBluetoothSco() */ startBluetoothSco(IBinder cb, int targetSdkVersion)6480 public void startBluetoothSco(IBinder cb, int targetSdkVersion) { 6481 if (!checkAudioSettingsPermission("startBluetoothSco()")) { 6482 return; 6483 } 6484 6485 final int uid = Binder.getCallingUid(); 6486 final int pid = Binder.getCallingPid(); 6487 final int scoAudioMode = 6488 (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ? 6489 BtHelper.SCO_MODE_VIRTUAL_CALL : BtHelper.SCO_MODE_UNDEFINED; 6490 final String eventSource = new StringBuilder("startBluetoothSco()") 6491 .append(") from u/pid:").append(uid).append("/") 6492 .append(pid).toString(); 6493 6494 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 6495 .setUid(uid) 6496 .setPid(pid) 6497 .set(MediaMetrics.Property.EVENT, "startBluetoothSco") 6498 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 6499 BtHelper.scoAudioModeToString(scoAudioMode)) 6500 .record(); 6501 startBluetoothScoInt(cb, uid, scoAudioMode, eventSource); 6502 6503 } 6504 6505 /** @see AudioManager#startBluetoothScoVirtualCall() */ startBluetoothScoVirtualCall(IBinder cb)6506 public void startBluetoothScoVirtualCall(IBinder cb) { 6507 if (!checkAudioSettingsPermission("startBluetoothScoVirtualCall()")) { 6508 return; 6509 } 6510 6511 final int uid = Binder.getCallingUid(); 6512 final int pid = Binder.getCallingPid(); 6513 final String eventSource = new StringBuilder("startBluetoothScoVirtualCall()") 6514 .append(") from u/pid:").append(uid).append("/") 6515 .append(pid).toString(); 6516 6517 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 6518 .setUid(uid) 6519 .setPid(pid) 6520 .set(MediaMetrics.Property.EVENT, "startBluetoothScoVirtualCall") 6521 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 6522 BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_VIRTUAL_CALL)) 6523 .record(); 6524 startBluetoothScoInt(cb, uid, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource); 6525 } 6526 startBluetoothScoInt(IBinder cb, int uid, int scoAudioMode, @NonNull String eventSource)6527 void startBluetoothScoInt(IBinder cb, int uid, int scoAudioMode, @NonNull String eventSource) { 6528 MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 6529 .set(MediaMetrics.Property.EVENT, "startBluetoothScoInt") 6530 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 6531 BtHelper.scoAudioModeToString(scoAudioMode)); 6532 6533 if (!checkAudioSettingsPermission("startBluetoothSco()") || 6534 !mSystemReady) { 6535 mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission or systemReady").record(); 6536 return; 6537 } 6538 final boolean isPrivileged = mContext.checkCallingOrSelfPermission( 6539 android.Manifest.permission.MODIFY_PHONE_STATE) 6540 == PackageManager.PERMISSION_GRANTED; 6541 final long ident = Binder.clearCallingIdentity(); 6542 try { 6543 mDeviceBroker.startBluetoothScoForClient( 6544 cb, uid, scoAudioMode, isPrivileged, eventSource); 6545 } finally { 6546 Binder.restoreCallingIdentity(ident); 6547 } 6548 mmi.record(); 6549 } 6550 6551 /** @see AudioManager#stopBluetoothSco() */ stopBluetoothSco(IBinder cb)6552 public void stopBluetoothSco(IBinder cb){ 6553 if (!checkAudioSettingsPermission("stopBluetoothSco()") || 6554 !mSystemReady) { 6555 return; 6556 } 6557 final int uid = Binder.getCallingUid(); 6558 final int pid = Binder.getCallingPid(); 6559 final String eventSource = new StringBuilder("stopBluetoothSco()") 6560 .append(") from u/pid:").append(uid).append("/") 6561 .append(pid).toString(); 6562 final boolean isPrivileged = mContext.checkCallingOrSelfPermission( 6563 android.Manifest.permission.MODIFY_PHONE_STATE) 6564 == PackageManager.PERMISSION_GRANTED; 6565 final long ident = Binder.clearCallingIdentity(); 6566 try { 6567 mDeviceBroker.stopBluetoothScoForClient(cb, uid, isPrivileged, eventSource); 6568 } finally { 6569 Binder.restoreCallingIdentity(ident); 6570 } 6571 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 6572 .setUid(uid) 6573 .setPid(pid) 6574 .set(MediaMetrics.Property.EVENT, "stopBluetoothSco") 6575 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 6576 BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_UNDEFINED)) 6577 .record(); 6578 } 6579 6580 getContentResolver()6581 /*package*/ ContentResolver getContentResolver() { 6582 return mContentResolver; 6583 } 6584 getSettings()6585 /*package*/ SettingsAdapter getSettings() { 6586 return mSettings; 6587 } 6588 6589 /////////////////////////////////////////////////////////////////////////// 6590 // Internal methods 6591 /////////////////////////////////////////////////////////////////////////// 6592 6593 /** 6594 * Checks if the adjustment should change ringer mode instead of just 6595 * adjusting volume. If so, this will set the proper ringer mode and volume 6596 * indices on the stream states. 6597 */ checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, String caller, int flags)6598 private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, 6599 String caller, int flags) { 6600 int result = FLAG_ADJUST_VOLUME; 6601 if (isPlatformTelevision() || mIsSingleVolume) { 6602 return result; 6603 } 6604 6605 int ringerMode = getRingerModeInternal(); 6606 6607 switch (ringerMode) { 6608 case RINGER_MODE_NORMAL: 6609 if (direction == AudioManager.ADJUST_LOWER) { 6610 if (mHasVibrator) { 6611 // "step" is the delta in internal index units corresponding to a 6612 // change of 1 in UI index units. 6613 // Because of rounding when rescaling from one stream index range to its alias 6614 // index range, we cannot simply test oldIndex == step: 6615 // (step <= oldIndex < 2 * step) is equivalent to: (old UI index == 1) 6616 if (step <= oldIndex && oldIndex < 2 * step) { 6617 ringerMode = RINGER_MODE_VIBRATE; 6618 mLoweredFromNormalToVibrateTime = SystemClock.uptimeMillis(); 6619 } 6620 } else { 6621 if (oldIndex == step && mVolumePolicy.volumeDownToEnterSilent) { 6622 ringerMode = RINGER_MODE_SILENT; 6623 } 6624 } 6625 } else if (mIsSingleVolume && (direction == AudioManager.ADJUST_TOGGLE_MUTE 6626 || direction == AudioManager.ADJUST_MUTE)) { 6627 if (mHasVibrator) { 6628 ringerMode = RINGER_MODE_VIBRATE; 6629 } else { 6630 ringerMode = RINGER_MODE_SILENT; 6631 } 6632 // Setting the ringer mode will toggle mute 6633 result &= ~FLAG_ADJUST_VOLUME; 6634 } 6635 break; 6636 case RINGER_MODE_VIBRATE: 6637 if (!mHasVibrator) { 6638 Log.e(TAG, "checkForRingerModeChange() current ringer mode is vibrate" + 6639 "but no vibrator is present"); 6640 break; 6641 } 6642 if ((direction == AudioManager.ADJUST_LOWER)) { 6643 // This is the case we were muted with the volume turned up 6644 if (mIsSingleVolume && oldIndex >= 2 * step && isMuted) { 6645 ringerMode = RINGER_MODE_NORMAL; 6646 } else if (mPrevVolDirection != AudioManager.ADJUST_LOWER) { 6647 if (mVolumePolicy.volumeDownToEnterSilent) { 6648 final long diff = SystemClock.uptimeMillis() 6649 - mLoweredFromNormalToVibrateTime; 6650 if (diff > mVolumePolicy.vibrateToSilentDebounce 6651 && mRingerModeDelegate.canVolumeDownEnterSilent()) { 6652 ringerMode = RINGER_MODE_SILENT; 6653 } 6654 } else { 6655 result |= AudioManager.FLAG_SHOW_VIBRATE_HINT; 6656 } 6657 } 6658 } else if (direction == AudioManager.ADJUST_RAISE 6659 || direction == AudioManager.ADJUST_TOGGLE_MUTE 6660 || direction == AudioManager.ADJUST_UNMUTE) { 6661 ringerMode = RINGER_MODE_NORMAL; 6662 } 6663 result &= ~FLAG_ADJUST_VOLUME; 6664 break; 6665 case RINGER_MODE_SILENT: 6666 if (mIsSingleVolume && direction == AudioManager.ADJUST_LOWER && oldIndex >= 2 * step && isMuted) { 6667 // This is the case we were muted with the volume turned up 6668 ringerMode = RINGER_MODE_NORMAL; 6669 } else if (direction == AudioManager.ADJUST_RAISE 6670 || direction == AudioManager.ADJUST_TOGGLE_MUTE 6671 || direction == AudioManager.ADJUST_UNMUTE) { 6672 if (!mVolumePolicy.volumeUpToExitSilent) { 6673 result |= AudioManager.FLAG_SHOW_SILENT_HINT; 6674 } else { 6675 if (mHasVibrator && direction == AudioManager.ADJUST_RAISE) { 6676 ringerMode = RINGER_MODE_VIBRATE; 6677 } else { 6678 // If we don't have a vibrator or they were toggling mute 6679 // go straight back to normal. 6680 ringerMode = RINGER_MODE_NORMAL; 6681 } 6682 } 6683 } 6684 result &= ~FLAG_ADJUST_VOLUME; 6685 break; 6686 default: 6687 Log.e(TAG, "checkForRingerModeChange() wrong ringer mode: "+ringerMode); 6688 break; 6689 } 6690 6691 if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode) 6692 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller) 6693 && (flags & AudioManager.FLAG_FROM_KEY) == 0) { 6694 throw new SecurityException("Not allowed to change Do Not Disturb state"); 6695 } 6696 6697 setRingerMode(ringerMode, TAG + ".checkForRingerModeChange", false /*external*/); 6698 6699 mPrevVolDirection = direction; 6700 6701 return result; 6702 } 6703 6704 @Override isStreamAffectedByRingerMode(int streamType)6705 public boolean isStreamAffectedByRingerMode(int streamType) { 6706 return (mRingerModeAffectedStreams & (1 << streamType)) != 0; 6707 } 6708 shouldZenMuteStream(int streamType)6709 private boolean shouldZenMuteStream(int streamType) { 6710 if (mNm.getZenMode() != Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { 6711 return false; 6712 } 6713 6714 NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy(); 6715 final boolean muteAlarms = (zenPolicy.priorityCategories 6716 & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0; 6717 final boolean muteMedia = (zenPolicy.priorityCategories 6718 & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0; 6719 final boolean muteSystem = (zenPolicy.priorityCategories 6720 & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0; 6721 final boolean muteNotificationAndRing = ZenModeConfig 6722 .areAllPriorityOnlyRingerSoundsMuted(zenPolicy); 6723 return muteAlarms && isAlarm(streamType) 6724 || muteMedia && isMedia(streamType) 6725 || muteSystem && isSystem(streamType) 6726 || muteNotificationAndRing && isNotificationOrRinger(streamType); 6727 } 6728 isStreamMutedByRingerOrZenMode(int streamType)6729 private boolean isStreamMutedByRingerOrZenMode(int streamType) { 6730 return (sRingerAndZenModeMutedStreams & (1 << streamType)) != 0; 6731 } 6732 6733 /** 6734 * Notifications, ringer and system sounds are controlled by the ringer: 6735 * {@link ZenModeHelper.RingerModeDelegate#getRingerModeAffectedStreams(int)} but can 6736 * also be muted by DND based on the DND mode: 6737 * DND total silence: media and alarms streams can be muted by DND 6738 * DND alarms only: no streams additionally controlled by DND 6739 * DND priority only: alarms, media, system, ringer and notification streams can be muted by 6740 * DND. The current applied zenPolicy determines which streams will be muted by DND. 6741 * @return true if changed, else false 6742 */ updateZenModeAffectedStreams()6743 private boolean updateZenModeAffectedStreams() { 6744 if (!mSystemReady) { 6745 return false; 6746 } 6747 6748 int zenModeAffectedStreams = 0; 6749 final int zenMode = mNm.getZenMode(); 6750 6751 if (zenMode == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS) { 6752 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM; 6753 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC; 6754 } else if (zenMode == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { 6755 NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy(); 6756 if ((zenPolicy.priorityCategories 6757 & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0) { 6758 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM; 6759 } 6760 6761 if ((zenPolicy.priorityCategories 6762 & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0) { 6763 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC; 6764 } 6765 6766 // even if zen isn't muting the system stream, the ringer mode can still mute 6767 // the system stream 6768 if ((zenPolicy.priorityCategories 6769 & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) { 6770 zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM; 6771 } 6772 6773 if (ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(zenPolicy)) { 6774 zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION; 6775 zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING; 6776 } 6777 } 6778 6779 if (mZenModeAffectedStreams != zenModeAffectedStreams) { 6780 mZenModeAffectedStreams = zenModeAffectedStreams; 6781 return true; 6782 } 6783 6784 return false; 6785 } 6786 6787 @GuardedBy("mSettingsLock") updateRingerAndZenModeAffectedStreams()6788 private boolean updateRingerAndZenModeAffectedStreams() { 6789 boolean updatedZenModeAffectedStreams = updateZenModeAffectedStreams(); 6790 int ringerModeAffectedStreams = mSettings.getSystemIntForUser(mContentResolver, 6791 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 6792 ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)| 6793 (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)), 6794 UserHandle.USER_CURRENT); 6795 6796 if (mIsSingleVolume) { 6797 ringerModeAffectedStreams = 0; 6798 } else if (mRingerModeDelegate != null) { 6799 ringerModeAffectedStreams = mRingerModeDelegate 6800 .getRingerModeAffectedStreams(ringerModeAffectedStreams); 6801 } 6802 if (mCameraSoundForced) { 6803 ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 6804 } else { 6805 ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 6806 } 6807 if (mStreamVolumeAlias[AudioSystem.STREAM_DTMF] == AudioSystem.STREAM_RING) { 6808 ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF); 6809 } else { 6810 ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF); 6811 } 6812 6813 if (ringerModeAffectedStreams != mRingerModeAffectedStreams) { 6814 mSettings.putSystemIntForUser(mContentResolver, 6815 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 6816 ringerModeAffectedStreams, 6817 UserHandle.USER_CURRENT); 6818 mRingerModeAffectedStreams = ringerModeAffectedStreams; 6819 return true; 6820 } 6821 return updatedZenModeAffectedStreams; 6822 } 6823 6824 @Override isStreamAffectedByMute(int streamType)6825 public boolean isStreamAffectedByMute(int streamType) { 6826 return (mMuteAffectedStreams & (1 << streamType)) != 0; 6827 } 6828 ensureValidDirection(int direction)6829 private void ensureValidDirection(int direction) { 6830 switch (direction) { 6831 case AudioManager.ADJUST_LOWER: 6832 case AudioManager.ADJUST_RAISE: 6833 case AudioManager.ADJUST_SAME: 6834 case AudioManager.ADJUST_MUTE: 6835 case AudioManager.ADJUST_UNMUTE: 6836 case AudioManager.ADJUST_TOGGLE_MUTE: 6837 break; 6838 default: 6839 throw new IllegalArgumentException("Bad direction " + direction); 6840 } 6841 } 6842 ensureValidStreamType(int streamType)6843 private void ensureValidStreamType(int streamType) { 6844 if (streamType < 0 || streamType >= mStreamStates.length) { 6845 throw new IllegalArgumentException("Bad stream type " + streamType); 6846 } 6847 } 6848 isMuteAdjust(int adjust)6849 private boolean isMuteAdjust(int adjust) { 6850 return adjust == AudioManager.ADJUST_MUTE || adjust == AudioManager.ADJUST_UNMUTE 6851 || adjust == AudioManager.ADJUST_TOGGLE_MUTE; 6852 } 6853 6854 /** only public for mocking/spying, do not call outside of AudioService */ 6855 @VisibleForTesting isInCommunication()6856 public boolean isInCommunication() { 6857 boolean IsInCall = false; 6858 6859 TelecomManager telecomManager = 6860 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 6861 6862 final long ident = Binder.clearCallingIdentity(); 6863 try { 6864 IsInCall = telecomManager.isInCall(); 6865 } finally { 6866 Binder.restoreCallingIdentity(ident); 6867 } 6868 6869 int mode = mMode.get(); 6870 return (IsInCall 6871 || mode == AudioManager.MODE_IN_COMMUNICATION 6872 || mode == AudioManager.MODE_IN_CALL); 6873 } 6874 6875 /** 6876 * For code clarity for getActiveStreamType(int) 6877 * @param delay_ms max time since last stream activity to consider 6878 * @return true if stream is active in streams handled by AudioFlinger now or 6879 * in the last "delay_ms" ms. 6880 */ wasStreamActiveRecently(int stream, int delay_ms)6881 private boolean wasStreamActiveRecently(int stream, int delay_ms) { 6882 return mAudioSystem.isStreamActive(stream, delay_ms) 6883 || mAudioSystem.isStreamActiveRemotely(stream, delay_ms); 6884 } 6885 getActiveStreamType(int suggestedStreamType)6886 private int getActiveStreamType(int suggestedStreamType) { 6887 if (mIsSingleVolume 6888 && suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 6889 return AudioSystem.STREAM_MUSIC; 6890 } 6891 6892 switch (mPlatformType) { 6893 case AudioSystem.PLATFORM_VOICE: 6894 if (isInCommunication()) { 6895 if (mDeviceBroker.isBluetoothScoActive()) { 6896 // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO..."); 6897 return AudioSystem.STREAM_BLUETOOTH_SCO; 6898 } else { 6899 // Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL..."); 6900 return AudioSystem.STREAM_VOICE_CALL; 6901 } 6902 } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 6903 if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 6904 if (DEBUG_VOL) 6905 Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active"); 6906 return AudioSystem.STREAM_RING; 6907 } else if (wasStreamActiveRecently( 6908 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 6909 if (DEBUG_VOL) { 6910 Log.v( 6911 TAG, 6912 "getActiveStreamType: Forcing STREAM_NOTIFICATION stream" 6913 + " active"); 6914 } 6915 return AudioSystem.STREAM_NOTIFICATION; 6916 } else { 6917 if (DEBUG_VOL) { 6918 Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK(" 6919 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default"); 6920 } 6921 return DEFAULT_VOL_STREAM_NO_PLAYBACK; 6922 } 6923 } else if ( 6924 wasStreamActiveRecently(AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 6925 if (DEBUG_VOL) 6926 Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active"); 6927 return AudioSystem.STREAM_NOTIFICATION; 6928 } else if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 6929 if (DEBUG_VOL) 6930 Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active"); 6931 return AudioSystem.STREAM_RING; 6932 } 6933 default: 6934 if (isInCommunication()) { 6935 if (mDeviceBroker.isBluetoothScoActive()) { 6936 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO"); 6937 return AudioSystem.STREAM_BLUETOOTH_SCO; 6938 } else { 6939 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL"); 6940 return AudioSystem.STREAM_VOICE_CALL; 6941 } 6942 } else if (mAudioSystem.isStreamActive( 6943 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 6944 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION"); 6945 return AudioSystem.STREAM_NOTIFICATION; 6946 } else if (mAudioSystem.isStreamActive( 6947 AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 6948 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING"); 6949 return AudioSystem.STREAM_RING; 6950 } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 6951 if (mAudioSystem.isStreamActive( 6952 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 6953 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION"); 6954 return AudioSystem.STREAM_NOTIFICATION; 6955 } 6956 if (mAudioSystem.isStreamActive( 6957 AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 6958 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING"); 6959 return AudioSystem.STREAM_RING; 6960 } 6961 if (DEBUG_VOL) { 6962 Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK(" 6963 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default"); 6964 } 6965 return DEFAULT_VOL_STREAM_NO_PLAYBACK; 6966 } 6967 break; 6968 } 6969 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Returning suggested type " 6970 + suggestedStreamType); 6971 return suggestedStreamType; 6972 } 6973 broadcastRingerMode(String action, int ringerMode)6974 private void broadcastRingerMode(String action, int ringerMode) { 6975 if (!mSystemServer.isPrivileged()) { 6976 return; 6977 } 6978 // Send sticky broadcast 6979 Intent broadcast = new Intent(action); 6980 broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, ringerMode); 6981 broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 6982 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 6983 sendStickyBroadcastToAll(broadcast); 6984 } 6985 broadcastVibrateSetting(int vibrateType)6986 private void broadcastVibrateSetting(int vibrateType) { 6987 if (!mSystemServer.isPrivileged()) { 6988 return; 6989 } 6990 // Send broadcast 6991 if (mActivityManagerInternal.isSystemReady()) { 6992 Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION); 6993 broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType); 6994 broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType)); 6995 sendBroadcastToAll(broadcast, null /* options */); 6996 } 6997 } 6998 6999 // Message helper methods 7000 /** 7001 * Queue a message on the given handler's message queue, after acquiring the service wake lock. 7002 * Note that the wake lock needs to be released after the message has been handled. 7003 */ queueMsgUnderWakeLock(Handler handler, int msg, int arg1, int arg2, Object obj, int delay)7004 private void queueMsgUnderWakeLock(Handler handler, int msg, 7005 int arg1, int arg2, Object obj, int delay) { 7006 final long ident = Binder.clearCallingIdentity(); 7007 try { 7008 // Always acquire the wake lock as AudioService because it is released by the 7009 // message handler. 7010 mAudioEventWakeLock.acquire(); 7011 } finally { 7012 Binder.restoreCallingIdentity(ident); 7013 } 7014 sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay); 7015 } 7016 sendMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, int delay)7017 private static void sendMsg(Handler handler, int msg, 7018 int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) { 7019 if (existingMsgPolicy == SENDMSG_REPLACE) { 7020 handler.removeMessages(msg); 7021 } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) { 7022 return; 7023 } 7024 7025 final long time = SystemClock.uptimeMillis() + delay; 7026 handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time); 7027 } 7028 sendBundleMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, Bundle bundle, int delay)7029 private static void sendBundleMsg(Handler handler, int msg, 7030 int existingMsgPolicy, int arg1, int arg2, Object obj, Bundle bundle, int delay) { 7031 if (existingMsgPolicy == SENDMSG_REPLACE) { 7032 handler.removeMessages(msg); 7033 } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) { 7034 return; 7035 } 7036 7037 final long time = SystemClock.uptimeMillis() + delay; 7038 Message message = handler.obtainMessage(msg, arg1, arg2, obj); 7039 message.setData(bundle); 7040 handler.sendMessageAtTime(message, time); 7041 } 7042 checkAudioSettingsPermission(String method)7043 boolean checkAudioSettingsPermission(String method) { 7044 if (callingOrSelfHasAudioSettingsPermission()) { 7045 return true; 7046 } 7047 String msg = "Audio Settings Permission Denial: " + method + " from pid=" 7048 + Binder.getCallingPid() 7049 + ", uid=" + Binder.getCallingUid(); 7050 Log.w(TAG, msg); 7051 return false; 7052 } 7053 callingOrSelfHasAudioSettingsPermission()7054 private boolean callingOrSelfHasAudioSettingsPermission() { 7055 return mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS) 7056 == PackageManager.PERMISSION_GRANTED; 7057 } 7058 callingHasAudioSettingsPermission()7059 private boolean callingHasAudioSettingsPermission() { 7060 return mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS) 7061 == PackageManager.PERMISSION_GRANTED; 7062 } 7063 hasAudioSettingsPermission(int uid, int pid)7064 private boolean hasAudioSettingsPermission(int uid, int pid) { 7065 return mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid) 7066 == PackageManager.PERMISSION_GRANTED; 7067 } 7068 7069 /** 7070 * Minimum attenuation that can be set for alarms over speaker by an application that 7071 * doesn't have the MODIFY_AUDIO_SETTINGS permission. 7072 */ 7073 protected static final float MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB = -36.0f; 7074 7075 /** 7076 * Configures the VolumeStreamState instances for minimum stream index that can be accessed 7077 * without MODIFY_AUDIO_SETTINGS permission. 7078 * Can only be done successfully once audio policy has finished reading its configuration files 7079 * for the volume curves. If not, getStreamVolumeDB will return NaN, and the min value will 7080 * remain at the stream min index value. 7081 */ initMinStreamVolumeWithoutModifyAudioSettings()7082 protected void initMinStreamVolumeWithoutModifyAudioSettings() { 7083 int idx; 7084 int deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER_SAFE; 7085 if (Float.isNaN(AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, 7086 MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM], deviceForAlarm))) { 7087 deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER; 7088 } 7089 for (idx = MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; 7090 idx >= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; idx--) { 7091 if (AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, idx, deviceForAlarm) 7092 < MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB) { 7093 break; 7094 } 7095 } 7096 final int safeIndex = idx <= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM] 7097 ? MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM] 7098 : Math.min(idx + 1, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]); 7099 // update the VolumeStreamState for STREAM_ALARM and its aliases 7100 for (int stream : mStreamVolumeAlias) { 7101 if (mStreamVolumeAlias[stream] == AudioSystem.STREAM_ALARM) { 7102 mStreamStates[stream].updateNoPermMinIndex(safeIndex); 7103 } 7104 } 7105 } 7106 7107 /** 7108 * Returns device associated with the stream volume. 7109 * 7110 * Only public for mocking/spying, do not call outside of AudioService. 7111 * Device volume aliasing means DEVICE_OUT_SPEAKER may be returned for 7112 * DEVICE_OUT_SPEAKER_SAFE. 7113 */ 7114 @VisibleForTesting getDeviceForStream(int stream)7115 public int getDeviceForStream(int stream) { 7116 return selectOneAudioDevice(getDeviceSetForStream(stream)); 7117 } 7118 7119 /* 7120 * Must match native apm_extract_one_audio_device() used in getDeviceForVolume() 7121 * or the wrong device volume may be adjusted. 7122 */ selectOneAudioDevice(Set<Integer> deviceSet)7123 private int selectOneAudioDevice(Set<Integer> deviceSet) { 7124 if (deviceSet.isEmpty()) { 7125 return AudioSystem.DEVICE_NONE; 7126 } else if (deviceSet.size() == 1) { 7127 return deviceSet.iterator().next(); 7128 } else { 7129 // Multiple device selection is either: 7130 // - dock + one other device: give priority to dock in this case. 7131 // - speaker + one other device: give priority to speaker in this case. 7132 // - one A2DP device + another device: happens with duplicated output. In this case 7133 // retain the device on the A2DP output as the other must not correspond to an active 7134 // selection if not the speaker. 7135 // - HDMI-CEC system audio mode only output: give priority to available item in order. 7136 7137 if (deviceSet.contains(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET)) { 7138 return AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET; 7139 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER)) { 7140 return AudioSystem.DEVICE_OUT_SPEAKER; 7141 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER_SAFE)) { 7142 // Note: DEVICE_OUT_SPEAKER_SAFE not present in getDeviceSetForStreamDirect 7143 return AudioSystem.DEVICE_OUT_SPEAKER_SAFE; 7144 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_ARC)) { 7145 return AudioSystem.DEVICE_OUT_HDMI_ARC; 7146 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_EARC)) { 7147 return AudioSystem.DEVICE_OUT_HDMI_EARC; 7148 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_AUX_LINE)) { 7149 return AudioSystem.DEVICE_OUT_AUX_LINE; 7150 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPDIF)) { 7151 return AudioSystem.DEVICE_OUT_SPDIF; 7152 } else { 7153 // At this point, deviceSet should contain exactly one A2DP device; 7154 // regardless, return the first A2DP device in numeric order. 7155 // If there is no A2DP device, this falls through to log an error. 7156 for (int deviceType : deviceSet) { 7157 if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType)) { 7158 return deviceType; 7159 } 7160 } 7161 } 7162 } 7163 Log.w(TAG, "selectOneAudioDevice returning DEVICE_NONE from invalid device combination " 7164 + AudioSystem.deviceSetToString(deviceSet)); 7165 return AudioSystem.DEVICE_NONE; 7166 } 7167 7168 /** 7169 * @see AudioManager#getDevicesForStream(int) 7170 * @deprecated on {@link android.os.Build.VERSION_CODES#T} as new devices 7171 * will have multi-bit device types since S. 7172 * Use {@link #getDevicesForAttributes()} instead. 7173 */ 7174 @Override 7175 @Deprecated getDeviceMaskForStream(int streamType)7176 public int getDeviceMaskForStream(int streamType) { 7177 ensureValidStreamType(streamType); 7178 // no permission required 7179 final long token = Binder.clearCallingIdentity(); 7180 try { 7181 return AudioSystem.getDeviceMaskFromSet( 7182 getDeviceSetForStreamDirect(streamType)); 7183 } finally { 7184 Binder.restoreCallingIdentity(token); 7185 } 7186 } 7187 7188 /** 7189 * Returns the devices associated with a stream type. 7190 * 7191 * SPEAKER_SAFE will alias to SPEAKER. 7192 */ 7193 @NonNull getDeviceSetForStreamDirect(int stream)7194 private Set<Integer> getDeviceSetForStreamDirect(int stream) { 7195 final AudioAttributes attr = 7196 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream); 7197 Set<Integer> deviceSet = 7198 AudioSystem.generateAudioDeviceTypesSet( 7199 getDevicesForAttributesInt(attr, true /* forVolume */)); 7200 return deviceSet; 7201 } 7202 7203 /** 7204 * Returns a reference to the list of devices for the stream, do not modify. 7205 * 7206 * The device returned may be aliased to the actual device whose volume curve 7207 * will be used. For example DEVICE_OUT_SPEAKER_SAFE aliases to DEVICE_OUT_SPEAKER. 7208 */ 7209 @NonNull getDeviceSetForStream(int stream)7210 public Set<Integer> getDeviceSetForStream(int stream) { 7211 ensureValidStreamType(stream); 7212 synchronized (VolumeStreamState.class) { 7213 return mStreamStates[stream].observeDevicesForStream_syncVSS(true); 7214 } 7215 } 7216 onObserveDevicesForAllStreams(int skipStream)7217 private void onObserveDevicesForAllStreams(int skipStream) { 7218 synchronized (mSettingsLock) { 7219 synchronized (VolumeStreamState.class) { 7220 for (int stream = 0; stream < mStreamStates.length; stream++) { 7221 if (stream != skipStream) { 7222 Set<Integer> deviceSet = 7223 mStreamStates[stream].observeDevicesForStream_syncVSS( 7224 false /*checkOthers*/); 7225 for (Integer device : deviceSet) { 7226 // Update volume states for devices routed for the stream 7227 updateVolumeStates(device, stream, 7228 "AudioService#onObserveDevicesForAllStreams"); 7229 } 7230 } 7231 } 7232 } 7233 } 7234 } 7235 7236 /** only public for mocking/spying, do not call outside of AudioService */ 7237 @VisibleForTesting postObserveDevicesForAllStreams()7238 public void postObserveDevicesForAllStreams() { 7239 postObserveDevicesForAllStreams(-1); 7240 } 7241 7242 /** only public for mocking/spying, do not call outside of AudioService */ 7243 @VisibleForTesting postObserveDevicesForAllStreams(int skipStream)7244 public void postObserveDevicesForAllStreams(int skipStream) { 7245 sendMsg(mAudioHandler, 7246 MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS, 7247 SENDMSG_QUEUE, skipStream /*arg1*/, 0 /*arg2*/, null /*obj*/, 7248 0 /*delay*/); 7249 } 7250 7251 /** 7252 * @see AudioDeviceVolumeManager#setDeviceAbsoluteMultiVolumeBehavior 7253 * 7254 * @param register Whether the listener is to be registered or unregistered. If false, the 7255 * device adopts variable volume behavior. 7256 */ 7257 @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING, 7258 android.Manifest.permission.BLUETOOTH_PRIVILEGED }) registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register, IAudioDeviceVolumeDispatcher cb, String packageName, AudioDeviceAttributes device, List<VolumeInfo> volumes, boolean handlesVolumeAdjustment, @AudioManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior)7259 public void registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register, 7260 IAudioDeviceVolumeDispatcher cb, String packageName, 7261 AudioDeviceAttributes device, List<VolumeInfo> volumes, 7262 boolean handlesVolumeAdjustment, 7263 @AudioManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior) { 7264 // verify permissions 7265 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 7266 != PackageManager.PERMISSION_GRANTED 7267 && mContext.checkCallingOrSelfPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) 7268 != PackageManager.PERMISSION_GRANTED) { 7269 throw new SecurityException( 7270 "Missing MODIFY_AUDIO_ROUTING or BLUETOOTH_PRIVILEGED permissions"); 7271 } 7272 // verify arguments 7273 Objects.requireNonNull(device); 7274 Objects.requireNonNull(volumes); 7275 7276 int deviceOut = device.getInternalType(); 7277 if (register) { 7278 AbsoluteVolumeDeviceInfo info = new AbsoluteVolumeDeviceInfo( 7279 device, volumes, cb, handlesVolumeAdjustment, deviceVolumeBehavior); 7280 AbsoluteVolumeDeviceInfo oldInfo = mAbsoluteVolumeDeviceInfoMap.get(deviceOut); 7281 boolean volumeBehaviorChanged = (oldInfo == null) 7282 || (oldInfo.mDeviceVolumeBehavior != deviceVolumeBehavior); 7283 if (volumeBehaviorChanged) { 7284 removeAudioSystemDeviceOutFromFullVolumeDevices(deviceOut); 7285 removeAudioSystemDeviceOutFromFixedVolumeDevices(deviceOut); 7286 addAudioSystemDeviceOutToAbsVolumeDevices(deviceOut, info); 7287 7288 dispatchDeviceVolumeBehavior(device, deviceVolumeBehavior); 7289 } 7290 // Update stream volumes to the given device, if specified in a VolumeInfo. 7291 // Mute state is not updated because it is stream-wide - the only way to mute a 7292 // stream's output to a particular device is to set the volume index to zero. 7293 for (VolumeInfo volumeInfo : volumes) { 7294 if (volumeInfo.getVolumeIndex() != VolumeInfo.INDEX_NOT_SET 7295 && volumeInfo.getMinVolumeIndex() != VolumeInfo.INDEX_NOT_SET 7296 && volumeInfo.getMaxVolumeIndex() != VolumeInfo.INDEX_NOT_SET) { 7297 if (volumeInfo.hasStreamType()) { 7298 setStreamVolumeInt(volumeInfo.getStreamType(), 7299 rescaleIndex(volumeInfo, volumeInfo.getStreamType()), 7300 deviceOut, false /*force*/, packageName, 7301 true /*hasModifyAudioSettings*/); 7302 } else { 7303 for (int streamType : volumeInfo.getVolumeGroup().getLegacyStreamTypes()) { 7304 setStreamVolumeInt(streamType, rescaleIndex(volumeInfo, streamType), 7305 deviceOut, false /*force*/, packageName, 7306 true /*hasModifyAudioSettings*/); 7307 } 7308 } 7309 } 7310 } 7311 } else { 7312 boolean wasAbsVol = removeAudioSystemDeviceOutFromAbsVolumeDevices(deviceOut) != null; 7313 if (wasAbsVol) { 7314 dispatchDeviceVolumeBehavior(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE); 7315 } 7316 } 7317 } 7318 7319 /** 7320 * @see AudioManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int) 7321 * @param device the audio device to be affected 7322 * @param deviceVolumeBehavior one of the device behaviors 7323 */ 7324 @android.annotation.EnforcePermission(anyOf = { 7325 android.Manifest.permission.MODIFY_AUDIO_ROUTING, 7326 android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED 7327 }) setDeviceVolumeBehavior(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName)7328 public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device, 7329 @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName) { 7330 // verify permissions 7331 super.setDeviceVolumeBehavior_enforcePermission(); 7332 // verify arguments 7333 Objects.requireNonNull(device); 7334 AudioManager.enforceValidVolumeBehavior(deviceVolumeBehavior); 7335 7336 sVolumeLogger.enqueue(new EventLogger.StringEvent("setDeviceVolumeBehavior: dev:" 7337 + AudioSystem.getOutputDeviceName(device.getInternalType()) + " addr:" 7338 + device.getAddress() + " behavior:" 7339 + AudioDeviceVolumeManager.volumeBehaviorName(deviceVolumeBehavior) 7340 + " pack:" + pkgName).printLog(TAG)); 7341 if (pkgName == null) { 7342 pkgName = ""; 7343 } 7344 if (device.getType() == TYPE_BLUETOOTH_A2DP) { 7345 avrcpSupportsAbsoluteVolume(device.getAddress(), 7346 deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE); 7347 return; 7348 } 7349 7350 setDeviceVolumeBehaviorInternal(device, deviceVolumeBehavior, pkgName); 7351 persistDeviceVolumeBehavior(device.getInternalType(), deviceVolumeBehavior); 7352 } 7353 setDeviceVolumeBehaviorInternal(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller)7354 private void setDeviceVolumeBehaviorInternal(@NonNull AudioDeviceAttributes device, 7355 @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller) { 7356 int audioSystemDeviceOut = device.getInternalType(); 7357 boolean volumeBehaviorChanged = false; 7358 // update device masks based on volume behavior 7359 switch (deviceVolumeBehavior) { 7360 case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE: 7361 volumeBehaviorChanged |= 7362 removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut) 7363 | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut) 7364 | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut) 7365 != null); 7366 break; 7367 case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED: 7368 volumeBehaviorChanged |= 7369 removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut) 7370 | addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut) 7371 | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut) 7372 != null); 7373 break; 7374 case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL: 7375 volumeBehaviorChanged |= 7376 addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut) 7377 | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut) 7378 | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut) 7379 != null); 7380 break; 7381 case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE: 7382 case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY: 7383 case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE: 7384 throw new IllegalArgumentException("Absolute volume unsupported for now"); 7385 } 7386 7387 if (volumeBehaviorChanged) { 7388 sendMsg(mAudioHandler, MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR, SENDMSG_QUEUE, 7389 deviceVolumeBehavior, 0, device, /*delay*/ 0); 7390 } 7391 7392 // log event and caller 7393 sDeviceLogger.enqueue(new EventLogger.StringEvent( 7394 "Volume behavior " + deviceVolumeBehavior + " for dev=0x" 7395 + Integer.toHexString(audioSystemDeviceOut) + " from:" + caller)); 7396 // make sure we have a volume entry for this device, and that volume is updated according 7397 // to volume behavior 7398 postUpdateVolumeStatesForAudioDevice(audioSystemDeviceOut, 7399 "setDeviceVolumeBehavior:" + caller); 7400 } 7401 7402 /** 7403 * @see AudioManager#getDeviceVolumeBehavior(AudioDeviceAttributes) 7404 * @param device the audio output device type 7405 * @return the volume behavior for the device 7406 */ 7407 @android.annotation.EnforcePermission(anyOf = { 7408 android.Manifest.permission.MODIFY_AUDIO_ROUTING, 7409 android.Manifest.permission.QUERY_AUDIO_STATE, 7410 android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED 7411 }) 7412 public @AudioManager.DeviceVolumeBehavior getDeviceVolumeBehavior(@onNull AudioDeviceAttributes device)7413 int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) { 7414 // verify permissions 7415 super.getDeviceVolumeBehavior_enforcePermission(); 7416 // verify parameters 7417 Objects.requireNonNull(device); 7418 7419 return getDeviceVolumeBehaviorInt(device); 7420 } 7421 7422 private @AudioManager.DeviceVolumeBehavior getDeviceVolumeBehaviorInt(@onNull AudioDeviceAttributes device)7423 int getDeviceVolumeBehaviorInt(@NonNull AudioDeviceAttributes device) { 7424 // Get the internal type set by the AudioDeviceAttributes constructor which is always more 7425 // exact (avoids double conversions) than a conversion from SDK type via 7426 // AudioDeviceInfo.convertDeviceTypeToInternalDevice() 7427 final int audioSystemDeviceOut = device.getInternalType(); 7428 7429 // setDeviceVolumeBehavior has not been explicitly called for the device type. Deduce the 7430 // current volume behavior. 7431 if (mFullVolumeDevices.contains(audioSystemDeviceOut)) { 7432 return AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL; 7433 } 7434 if (mFixedVolumeDevices.contains(audioSystemDeviceOut)) { 7435 return AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED; 7436 } 7437 if (mAbsVolumeMultiModeCaseDevices.contains(audioSystemDeviceOut)) { 7438 return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE; 7439 } 7440 if (mAbsoluteVolumeDeviceInfoMap.containsKey(audioSystemDeviceOut)) { 7441 return mAbsoluteVolumeDeviceInfoMap.get(audioSystemDeviceOut).mDeviceVolumeBehavior; 7442 } 7443 7444 if (isA2dpAbsoluteVolumeDevice(audioSystemDeviceOut) 7445 || AudioSystem.isLeAudioDeviceType(audioSystemDeviceOut)) { 7446 return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE; 7447 } 7448 return AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE; 7449 } 7450 7451 /** 7452 * @see AudioManager#isVolumeFixed() 7453 * Note there are no permission checks on this operation, as this is part of API 21 7454 * @return true if the current device's volume behavior for media is 7455 * DEVICE_VOLUME_BEHAVIOR_FIXED 7456 */ isVolumeFixed()7457 public boolean isVolumeFixed() { 7458 if (mUseFixedVolume) { 7459 return true; 7460 } 7461 final AudioAttributes attributes = new AudioAttributes.Builder() 7462 .setUsage(AudioAttributes.USAGE_MEDIA) 7463 .build(); 7464 // calling getDevice*Int to bypass permission check 7465 final List<AudioDeviceAttributes> devices = 7466 getDevicesForAttributesInt(attributes, true /* forVolume */); 7467 for (AudioDeviceAttributes device : devices) { 7468 if (getDeviceVolumeBehaviorInt(device) == AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED) { 7469 return true; 7470 } 7471 } 7472 return false; 7473 } 7474 7475 /*package*/ static final int CONNECTION_STATE_DISCONNECTED = 0; 7476 /*package*/ static final int CONNECTION_STATE_CONNECTED = 1; 7477 /** 7478 * The states that can be used with AudioService.setWiredDeviceConnectionState() 7479 * Attention: those values differ from those in BluetoothProfile, follow annotations to 7480 * distinguish between @ConnectionState and @BtProfileConnectionState 7481 */ 7482 @IntDef({ 7483 CONNECTION_STATE_DISCONNECTED, 7484 CONNECTION_STATE_CONNECTED, 7485 }) 7486 @Retention(RetentionPolicy.SOURCE) 7487 public @interface ConnectionState {} 7488 7489 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 7490 /** 7491 * see AudioManager.setWiredDeviceConnectionState() 7492 */ setWiredDeviceConnectionState(AudioDeviceAttributes attributes, @ConnectionState int state, String caller)7493 public void setWiredDeviceConnectionState(AudioDeviceAttributes attributes, 7494 @ConnectionState int state, String caller) { 7495 super.setWiredDeviceConnectionState_enforcePermission(); 7496 7497 if (state != CONNECTION_STATE_CONNECTED 7498 && state != CONNECTION_STATE_DISCONNECTED) { 7499 throw new IllegalArgumentException("Invalid state " + state); 7500 } 7501 new MediaMetrics.Item(mMetricsId + "setWiredDeviceConnectionState") 7502 .set(MediaMetrics.Property.ADDRESS, attributes.getAddress()) 7503 .set(MediaMetrics.Property.CLIENT_NAME, caller) 7504 .set(MediaMetrics.Property.DEVICE, 7505 AudioSystem.getDeviceName(attributes.getInternalType())) 7506 .set(MediaMetrics.Property.NAME, attributes.getName()) 7507 .set(MediaMetrics.Property.STATE, 7508 state == CONNECTION_STATE_CONNECTED ? "connected" : "disconnected") 7509 .record(); 7510 mDeviceBroker.setWiredDeviceConnectionState(attributes, state, caller); 7511 // The Dynamic Soundbar mode feature introduces dynamic presence for an HDMI Audio System 7512 // Client. For example, the device can start with the Audio System Client unavailable. 7513 // When the feature is activated the client becomes available, therefore Audio Service 7514 // requests a new HDMI Audio System Client instance when the ARC status is changed. 7515 if (attributes.getInternalType() == AudioSystem.DEVICE_IN_HDMI_ARC) { 7516 updateHdmiAudioSystemClient(); 7517 } 7518 } 7519 7520 /** 7521 * Replace the current HDMI Audio System Client. 7522 * See {@link #setWiredDeviceConnectionState(AudioDeviceAttributes, int, String)}. 7523 */ updateHdmiAudioSystemClient()7524 private void updateHdmiAudioSystemClient() { 7525 Slog.d(TAG, "Hdmi Audio System Client is updated"); 7526 synchronized (mHdmiClientLock) { 7527 mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient(); 7528 } 7529 } 7530 7531 /** @see AudioManager#setTestDeviceConnectionState(AudioDeviceAttributes, boolean) */ setTestDeviceConnectionState(@onNull AudioDeviceAttributes device, boolean connected)7532 public void setTestDeviceConnectionState(@NonNull AudioDeviceAttributes device, 7533 boolean connected) { 7534 Objects.requireNonNull(device); 7535 enforceModifyAudioRoutingPermission(); 7536 mDeviceBroker.setTestDeviceConnectionState(device, 7537 connected ? CONNECTION_STATE_CONNECTED : CONNECTION_STATE_DISCONNECTED); 7538 // simulate a routing update from native 7539 sendMsg(mAudioHandler, 7540 MSG_ROUTING_UPDATED, 7541 SENDMSG_REPLACE, 0, 0, null, 7542 /*delay*/ 0); 7543 } 7544 7545 /** 7546 * @hide 7547 * The states that can be used with AudioService.setBluetoothHearingAidDeviceConnectionState() 7548 * and AudioService.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent() 7549 */ 7550 @IntDef({ 7551 BluetoothProfile.STATE_DISCONNECTED, 7552 BluetoothProfile.STATE_CONNECTED, 7553 }) 7554 @Retention(RetentionPolicy.SOURCE) 7555 public @interface BtProfileConnectionState {} 7556 7557 /** 7558 * @hide 7559 * The profiles that can be used with AudioService.handleBluetoothActiveDeviceChanged() 7560 */ 7561 @IntDef({ 7562 BluetoothProfile.HEARING_AID, 7563 BluetoothProfile.A2DP, 7564 BluetoothProfile.A2DP_SINK, 7565 BluetoothProfile.LE_AUDIO, 7566 BluetoothProfile.LE_AUDIO_BROADCAST, 7567 }) 7568 @Retention(RetentionPolicy.SOURCE) 7569 public @interface BtProfile {} 7570 7571 7572 /** 7573 * See AudioManager.handleBluetoothActiveDeviceChanged(...) 7574 */ handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice, BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info)7575 public void handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice, 7576 BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info) { 7577 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.BLUETOOTH_STACK) 7578 != PackageManager.PERMISSION_GRANTED) { 7579 throw new SecurityException("Bluetooth is the only caller allowed"); 7580 } 7581 if (info == null) { 7582 throw new IllegalArgumentException("Illegal null BluetoothProfileConnectionInfo for" 7583 + " device " + previousDevice + " -> " + newDevice); 7584 } 7585 final int profile = info.getProfile(); 7586 if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK 7587 && profile != BluetoothProfile.LE_AUDIO 7588 && profile != BluetoothProfile.LE_AUDIO_BROADCAST 7589 && profile != BluetoothProfile.HEARING_AID) { 7590 throw new IllegalArgumentException("Illegal BluetoothProfile profile for device " 7591 + previousDevice + " -> " + newDevice + ". Got: " + profile); 7592 } 7593 7594 sDeviceLogger.enqueue(new EventLogger.StringEvent("BlutoothActiveDeviceChanged for " 7595 + BluetoothProfile.getProfileName(profile) + ", device update " + previousDevice 7596 + " -> " + newDevice)); 7597 AudioDeviceBroker.BtDeviceChangedData data = 7598 new AudioDeviceBroker.BtDeviceChangedData(newDevice, previousDevice, info, 7599 "AudioService"); 7600 sendMsg(mAudioHandler, MSG_BT_DEV_CHANGED, SENDMSG_QUEUE, 0, 0, 7601 /*obj*/ data, /*delay*/ 0); 7602 } 7603 7604 /** only public for mocking/spying, do not call outside of AudioService */ 7605 @VisibleForTesting setMusicMute(boolean mute)7606 public void setMusicMute(boolean mute) { 7607 mStreamStates[AudioSystem.STREAM_MUSIC].muteInternally(mute); 7608 } 7609 7610 private static final Set<Integer> DEVICE_MEDIA_UNMUTED_ON_PLUG_SET; 7611 static { 7612 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET = new HashSet<>(); 7613 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADSET); 7614 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE); 7615 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_LINE); 7616 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_A2DP_SET); 7617 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_BLE_SET); 7618 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_USB_SET); 7619 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_HDMI); 7620 } 7621 7622 /** only public for mocking/spying, do not call outside of AudioService */ 7623 @VisibleForTesting postAccessoryPlugMediaUnmute(int newDevice)7624 public void postAccessoryPlugMediaUnmute(int newDevice) { 7625 sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE, 7626 newDevice, 0, null, 0); 7627 } 7628 onAccessoryPlugMediaUnmute(int newDevice)7629 private void onAccessoryPlugMediaUnmute(int newDevice) { 7630 if (DEBUG_VOL) { 7631 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute newDevice=%d [%s]", 7632 newDevice, AudioSystem.getOutputDeviceName(newDevice))); 7633 } 7634 7635 if (mNm.getZenMode() != Settings.Global.ZEN_MODE_NO_INTERRUPTIONS 7636 && !isStreamMutedByRingerOrZenMode(AudioSystem.STREAM_MUSIC) 7637 && DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.contains(newDevice) 7638 && mStreamStates[AudioSystem.STREAM_MUSIC].mIsMuted 7639 && mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(newDevice) != 0 7640 && getDeviceSetForStreamDirect(AudioSystem.STREAM_MUSIC).contains(newDevice)) { 7641 if (DEBUG_VOL) { 7642 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute unmuting device=%d [%s]", 7643 newDevice, AudioSystem.getOutputDeviceName(newDevice))); 7644 } 7645 // Locking mSettingsLock to avoid inversion when calling vss.mute -> vss.doMute -> 7646 // vss.updateVolumeGroupIndex 7647 synchronized (mSettingsLock) { 7648 mStreamStates[AudioSystem.STREAM_MUSIC].mute(false, "onAccessoryPlugMediaUnmute"); 7649 } 7650 } 7651 } 7652 7653 /** 7654 * See AudioManager.hasHapticChannels(Context, Uri). 7655 */ hasHapticChannels(Uri uri)7656 public boolean hasHapticChannels(Uri uri) { 7657 return AudioManager.hasHapticChannelsImpl(mContext, uri); 7658 } 7659 7660 /////////////////////////////////////////////////////////////////////////// 7661 // Inner classes 7662 /////////////////////////////////////////////////////////////////////////// 7663 /** 7664 * Key is the AudioManager VolumeGroupId 7665 * Value is the VolumeGroupState 7666 */ 7667 private static final SparseArray<VolumeGroupState> sVolumeGroupStates = new SparseArray<>(); 7668 initVolumeGroupStates()7669 private void initVolumeGroupStates() { 7670 for (final AudioVolumeGroup avg : getAudioVolumeGroups()) { 7671 try { 7672 // if no valid attributes, this volume group is not controllable, throw exception 7673 ensureValidAttributes(avg); 7674 sVolumeGroupStates.append(avg.getId(), new VolumeGroupState(avg)); 7675 } catch (IllegalArgumentException e) { 7676 // Volume Groups without attributes are not controllable through set/get volume 7677 // using attributes. Do not append them. 7678 if (DEBUG_VOL) { 7679 Log.d(TAG, "volume group " + avg.name() + " for internal policy needs"); 7680 } 7681 continue; 7682 } 7683 } 7684 7685 // need mSettingsLock for vgs.applyAllVolumes -> vss.setIndex which grabs this lock after 7686 // VSS.class. Locking order needs to be preserved 7687 synchronized (mSettingsLock) { 7688 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 7689 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 7690 vgs.applyAllVolumes(/* userSwitch= */ false); 7691 } 7692 } 7693 } 7694 ensureValidAttributes(AudioVolumeGroup avg)7695 private void ensureValidAttributes(AudioVolumeGroup avg) { 7696 boolean hasAtLeastOneValidAudioAttributes = avg.getAudioAttributes().stream() 7697 .anyMatch(aa -> !aa.equals(AudioProductStrategy.getDefaultAttributes())); 7698 if (!hasAtLeastOneValidAudioAttributes) { 7699 throw new IllegalArgumentException("Volume Group " + avg.name() 7700 + " has no valid audio attributes"); 7701 } 7702 } 7703 readVolumeGroupsSettings(boolean userSwitch)7704 private void readVolumeGroupsSettings(boolean userSwitch) { 7705 synchronized (mSettingsLock) { 7706 synchronized (VolumeStreamState.class) { 7707 if (DEBUG_VOL) { 7708 Log.d(TAG, "readVolumeGroupsSettings userSwitch=" + userSwitch); 7709 } 7710 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 7711 VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 7712 // as for STREAM_MUSIC, preserve volume from one user to the next. 7713 if (!(userSwitch && vgs.isMusic())) { 7714 vgs.clearIndexCache(); 7715 vgs.readSettings(); 7716 } 7717 vgs.applyAllVolumes(userSwitch); 7718 } 7719 } 7720 } 7721 } 7722 7723 // Called upon crash of AudioServer restoreVolumeGroups()7724 private void restoreVolumeGroups() { 7725 if (DEBUG_VOL) { 7726 Log.v(TAG, "restoreVolumeGroups"); 7727 } 7728 7729 // need mSettingsLock for vgs.applyAllVolumes -> vss.setIndex which grabs this lock after 7730 // VSS.class. Locking order needs to be preserved 7731 synchronized (mSettingsLock) { 7732 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 7733 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 7734 vgs.applyAllVolumes(false/*userSwitch*/); 7735 } 7736 } 7737 } 7738 dumpVolumeGroups(PrintWriter pw)7739 private void dumpVolumeGroups(PrintWriter pw) { 7740 pw.println("\nVolume Groups (device: index)"); 7741 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 7742 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 7743 vgs.dump(pw); 7744 pw.println(""); 7745 } 7746 } 7747 isCallStream(int stream)7748 private static boolean isCallStream(int stream) { 7749 return stream == AudioSystem.STREAM_VOICE_CALL 7750 || stream == AudioSystem.STREAM_BLUETOOTH_SCO; 7751 } 7752 getVolumeGroupForStreamType(int stream)7753 private static int getVolumeGroupForStreamType(int stream) { 7754 AudioAttributes attributes = 7755 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream); 7756 if (attributes.equals(new AudioAttributes.Builder().build())) { 7757 return AudioVolumeGroup.DEFAULT_VOLUME_GROUP; 7758 } 7759 return AudioProductStrategy.getVolumeGroupIdForAudioAttributes( 7760 attributes, /* fallbackOnDefault= */ false); 7761 } 7762 7763 // NOTE: Locking order for synchronized objects related to volume management: 7764 // 1 mSettingsLock 7765 // 2 VolumeStreamState.class 7766 private class VolumeGroupState { 7767 private final AudioVolumeGroup mAudioVolumeGroup; 7768 private final SparseIntArray mIndexMap = new SparseIntArray(8); 7769 private int mIndexMin; 7770 private int mIndexMax; 7771 private boolean mHasValidStreamType = false; 7772 private int mPublicStreamType = AudioSystem.STREAM_MUSIC; 7773 private AudioAttributes mAudioAttributes = AudioProductStrategy.getDefaultAttributes(); 7774 private boolean mIsMuted = false; 7775 private String mSettingName; 7776 7777 // No API in AudioSystem to get a device from strategy or from attributes. 7778 // Need a valid public stream type to use current API getDeviceForStream getDeviceForVolume()7779 private int getDeviceForVolume() { 7780 return getDeviceForStream(mPublicStreamType); 7781 } 7782 VolumeGroupState(AudioVolumeGroup avg)7783 private VolumeGroupState(AudioVolumeGroup avg) { 7784 mAudioVolumeGroup = avg; 7785 if (DEBUG_VOL) { 7786 Log.v(TAG, "VolumeGroupState for " + avg.toString()); 7787 } 7788 // mAudioAttributes is the default at this point 7789 for (AudioAttributes aa : avg.getAudioAttributes()) { 7790 if (!aa.equals(mAudioAttributes)) { 7791 mAudioAttributes = aa; 7792 break; 7793 } 7794 } 7795 int[] streamTypes = mAudioVolumeGroup.getLegacyStreamTypes(); 7796 String streamSettingName = ""; 7797 if (streamTypes.length != 0) { 7798 // Uses already initialized MIN / MAX if a stream type is attached to group 7799 for (int streamType : streamTypes) { 7800 if (streamType != AudioSystem.STREAM_DEFAULT 7801 && streamType < AudioSystem.getNumStreamTypes()) { 7802 mPublicStreamType = streamType; 7803 mHasValidStreamType = true; 7804 streamSettingName = System.VOLUME_SETTINGS_INT[mPublicStreamType]; 7805 break; 7806 } 7807 } 7808 mIndexMin = MIN_STREAM_VOLUME[mPublicStreamType]; 7809 mIndexMax = MAX_STREAM_VOLUME[mPublicStreamType]; 7810 } else if (!avg.getAudioAttributes().isEmpty()) { 7811 mIndexMin = AudioSystem.getMinVolumeIndexForAttributes(mAudioAttributes); 7812 mIndexMax = AudioSystem.getMaxVolumeIndexForAttributes(mAudioAttributes); 7813 } else { 7814 throw new IllegalArgumentException("volume group: " + mAudioVolumeGroup.name() 7815 + " has neither valid attributes nor valid stream types assigned"); 7816 } 7817 mSettingName = !streamSettingName.isEmpty() ? streamSettingName : ("volume_" + name()); 7818 // Load volume indexes from data base 7819 readSettings(); 7820 } 7821 getLegacyStreamTypes()7822 public @NonNull int[] getLegacyStreamTypes() { 7823 return mAudioVolumeGroup.getLegacyStreamTypes(); 7824 } 7825 name()7826 public String name() { 7827 return mAudioVolumeGroup.name(); 7828 } 7829 7830 /** 7831 * Volume group with non null minimum index are considered as non mutable, thus 7832 * bijectivity is broken with potential associated stream type. 7833 * VOICE_CALL stream has minVolumeIndex > 0 but can be muted directly by an 7834 * app that has MODIFY_PHONE_STATE permission. 7835 */ isVssMuteBijective(int stream)7836 private boolean isVssMuteBijective(int stream) { 7837 return isStreamAffectedByMute(stream) 7838 && (getMinIndex() == (mStreamStates[stream].mIndexMin + 5) / 10) 7839 && (getMinIndex() == 0 || isCallStream(stream)); 7840 } 7841 isMutable()7842 private boolean isMutable() { 7843 return mIndexMin == 0 || (mHasValidStreamType && isVssMuteBijective(mPublicStreamType)); 7844 } 7845 /** 7846 * Mute/unmute the volume group 7847 * @param muted the new mute state 7848 */ 7849 @GuardedBy("AudioService.VolumeStreamState.class") mute(boolean muted)7850 public boolean mute(boolean muted) { 7851 if (!isMutable()) { 7852 // Non mutable volume group 7853 if (DEBUG_VOL) { 7854 Log.d(TAG, "invalid mute on unmutable volume group " + name()); 7855 } 7856 return false; 7857 } 7858 boolean changed = (mIsMuted != muted); 7859 // As for VSS, mute shall apply minIndex to all devices found in IndexMap and default. 7860 if (changed) { 7861 mIsMuted = muted; 7862 applyAllVolumes(false /*userSwitch*/); 7863 } 7864 return changed; 7865 } 7866 isMuted()7867 public boolean isMuted() { 7868 return mIsMuted; 7869 } 7870 adjustVolume(int direction, int flags)7871 public void adjustVolume(int direction, int flags) { 7872 synchronized (mSettingsLock) { 7873 synchronized (AudioService.VolumeStreamState.class) { 7874 int device = getDeviceForVolume(); 7875 int previousIndex = getIndex(device); 7876 if (isMuteAdjust(direction) && !isMutable()) { 7877 // Non mutable volume group 7878 if (DEBUG_VOL) { 7879 Log.d(TAG, "invalid mute on unmutable volume group " + name()); 7880 } 7881 return; 7882 } 7883 switch (direction) { 7884 case AudioManager.ADJUST_TOGGLE_MUTE: { 7885 // Note: If muted by volume 0, unmute will restore volume 0. 7886 mute(!mIsMuted); 7887 break; 7888 } 7889 case AudioManager.ADJUST_UNMUTE: 7890 // Note: If muted by volume 0, unmute will restore volume 0. 7891 mute(false); 7892 break; 7893 case AudioManager.ADJUST_MUTE: 7894 // May be already muted by setvolume 0, prevent from setting same value 7895 if (previousIndex != 0) { 7896 // bypass persist 7897 mute(true); 7898 } 7899 mIsMuted = true; 7900 break; 7901 case AudioManager.ADJUST_RAISE: 7902 // As for stream, RAISE during mute will increment the index 7903 setVolumeIndex(Math.min(previousIndex + 1, mIndexMax), device, flags); 7904 break; 7905 case AudioManager.ADJUST_LOWER: 7906 // For stream, ADJUST_LOWER on a muted VSS is a no-op 7907 // If we decide to unmute on ADJUST_LOWER, cannot fallback on 7908 // adjustStreamVolume for group associated to legacy stream type 7909 if (isMuted() && previousIndex != 0) { 7910 mute(false); 7911 } else { 7912 int newIndex = Math.max(previousIndex - 1, mIndexMin); 7913 setVolumeIndex(newIndex, device, flags); 7914 } 7915 break; 7916 } 7917 } 7918 } 7919 } 7920 getVolumeIndex()7921 public int getVolumeIndex() { 7922 synchronized (AudioService.VolumeStreamState.class) { 7923 return getIndex(getDeviceForVolume()); 7924 } 7925 } 7926 setVolumeIndex(int index, int flags)7927 public void setVolumeIndex(int index, int flags) { 7928 synchronized (mSettingsLock) { 7929 synchronized (AudioService.VolumeStreamState.class) { 7930 if (mUseFixedVolume) { 7931 return; 7932 } 7933 setVolumeIndex(index, getDeviceForVolume(), flags); 7934 } 7935 } 7936 } 7937 7938 @GuardedBy("AudioService.VolumeStreamState.class") setVolumeIndex(int index, int device, int flags)7939 private void setVolumeIndex(int index, int device, int flags) { 7940 // Update cache & persist (muted by volume 0 shall be persisted) 7941 updateVolumeIndex(index, device); 7942 // setting non-zero volume for a muted stream unmutes the stream and vice versa, 7943 boolean changed = mute(index == 0); 7944 if (!changed) { 7945 // Set the volume index only if mute operation is a no-op 7946 index = getValidIndex(index); 7947 setVolumeIndexInt(index, device, flags); 7948 } 7949 } 7950 7951 @GuardedBy("AudioService.VolumeStreamState.class") updateVolumeIndex(int index, int device)7952 public void updateVolumeIndex(int index, int device) { 7953 // Filter persistency if already exist and the index has not changed 7954 if (mIndexMap.indexOfKey(device) < 0 || mIndexMap.get(device) != index) { 7955 // Update local cache 7956 mIndexMap.put(device, getValidIndex(index)); 7957 7958 // update data base - post a persist volume group msg 7959 sendMsg(mAudioHandler, 7960 MSG_PERSIST_VOLUME_GROUP, 7961 SENDMSG_QUEUE, 7962 device, 7963 0, 7964 this, 7965 PERSIST_DELAY); 7966 } 7967 } 7968 7969 @GuardedBy("AudioService.VolumeStreamState.class") setVolumeIndexInt(int index, int device, int flags)7970 private void setVolumeIndexInt(int index, int device, int flags) { 7971 // Reflect mute state of corresponding stream by forcing index to 0 if muted 7972 // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted. 7973 // This allows RX path muting by the audio HAL only when explicitly muted but not when 7974 // index is just set to 0 to repect BT requirements 7975 if (mHasValidStreamType && isVssMuteBijective(mPublicStreamType) 7976 && mStreamStates[mPublicStreamType].isFullyMuted()) { 7977 index = 0; 7978 } else if (mPublicStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0) { 7979 index = 1; 7980 } 7981 // Set the volume index 7982 AudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, device); 7983 } 7984 7985 @GuardedBy("AudioService.VolumeStreamState.class") getIndex(int device)7986 private int getIndex(int device) { 7987 int index = mIndexMap.get(device, -1); 7988 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT 7989 return (index != -1) ? index : mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); 7990 } 7991 7992 @GuardedBy("AudioService.VolumeStreamState.class") hasIndexForDevice(int device)7993 private boolean hasIndexForDevice(int device) { 7994 return (mIndexMap.get(device, -1) != -1); 7995 } 7996 getMaxIndex()7997 public int getMaxIndex() { 7998 return mIndexMax; 7999 } 8000 getMinIndex()8001 public int getMinIndex() { 8002 return mIndexMin; 8003 } 8004 isValidStream(int stream)8005 private boolean isValidStream(int stream) { 8006 return (stream != AudioSystem.STREAM_DEFAULT) && (stream < mStreamStates.length); 8007 } 8008 isMusic()8009 public boolean isMusic() { 8010 return mHasValidStreamType && mPublicStreamType == AudioSystem.STREAM_MUSIC; 8011 } 8012 applyAllVolumes(boolean userSwitch)8013 public void applyAllVolumes(boolean userSwitch) { 8014 String caller = "from vgs"; 8015 synchronized (AudioService.VolumeStreamState.class) { 8016 // apply device specific volumes first 8017 for (int i = 0; i < mIndexMap.size(); i++) { 8018 int device = mIndexMap.keyAt(i); 8019 int index = mIndexMap.valueAt(i); 8020 boolean synced = false; 8021 if (device != AudioSystem.DEVICE_OUT_DEFAULT) { 8022 for (int stream : getLegacyStreamTypes()) { 8023 if (isValidStream(stream)) { 8024 boolean streamMuted = mStreamStates[stream].mIsMuted; 8025 int deviceForStream = getDeviceForStream(stream); 8026 int indexForStream = 8027 (mStreamStates[stream].getIndex(deviceForStream) + 5) / 10; 8028 if (device == deviceForStream) { 8029 if (indexForStream == index && (isMuted() == streamMuted) 8030 && isVssMuteBijective(stream)) { 8031 synced = true; 8032 continue; 8033 } 8034 if (indexForStream != index) { 8035 mStreamStates[stream].setIndex(index * 10, device, caller, 8036 true /*hasModifyAudioSettings*/); 8037 } 8038 if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) { 8039 mStreamStates[stream].mute(isMuted(), 8040 "VGS.applyAllVolumes#1"); 8041 } 8042 } 8043 } 8044 } 8045 if (!synced) { 8046 if (DEBUG_VOL) { 8047 Log.d(TAG, "applyAllVolumes: apply index " + index + ", group " 8048 + mAudioVolumeGroup.name() + " and device " 8049 + AudioSystem.getOutputDeviceName(device)); 8050 } 8051 setVolumeIndexInt(isMuted() ? 0 : index, device, 0 /*flags*/); 8052 } 8053 } 8054 } 8055 // apply default volume last: by convention , default device volume will be used 8056 // by audio policy manager if no explicit volume is present for a given device type 8057 int index = getIndex(AudioSystem.DEVICE_OUT_DEFAULT); 8058 boolean synced = false; 8059 int deviceForVolume = getDeviceForVolume(); 8060 boolean forceDeviceSync = userSwitch && (mIndexMap.indexOfKey(deviceForVolume) < 0); 8061 for (int stream : getLegacyStreamTypes()) { 8062 if (isValidStream(stream)) { 8063 boolean streamMuted = mStreamStates[stream].mIsMuted; 8064 int defaultStreamIndex = (mStreamStates[stream].getIndex( 8065 AudioSystem.DEVICE_OUT_DEFAULT) + 5) / 10; 8066 if (forceDeviceSync) { 8067 mStreamStates[stream].setIndex(index * 10, deviceForVolume, caller, 8068 true /*hasModifyAudioSettings*/); 8069 } 8070 if (defaultStreamIndex == index && (isMuted() == streamMuted) 8071 && isVssMuteBijective(stream)) { 8072 synced = true; 8073 continue; 8074 } 8075 if (defaultStreamIndex != index) { 8076 mStreamStates[stream].setIndex( 8077 index * 10, AudioSystem.DEVICE_OUT_DEFAULT, caller, 8078 true /*hasModifyAudioSettings*/); 8079 } 8080 if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) { 8081 mStreamStates[stream].mute(isMuted(), "VGS.applyAllVolumes#2"); 8082 } 8083 } 8084 } 8085 if (!synced) { 8086 if (DEBUG_VOL) { 8087 Log.d(TAG, "applyAllVolumes: apply default device index " + index 8088 + ", group " + mAudioVolumeGroup.name()); 8089 } 8090 setVolumeIndexInt( 8091 isMuted() ? 0 : index, AudioSystem.DEVICE_OUT_DEFAULT, 0 /*flags*/); 8092 } 8093 if (forceDeviceSync) { 8094 if (DEBUG_VOL) { 8095 Log.d(TAG, "applyAllVolumes: forceDeviceSync index " + index 8096 + ", device " + AudioSystem.getOutputDeviceName(deviceForVolume) 8097 + ", group " + mAudioVolumeGroup.name()); 8098 } 8099 setVolumeIndexInt(isMuted() ? 0 : index, deviceForVolume, 0); 8100 } 8101 } 8102 } 8103 clearIndexCache()8104 public void clearIndexCache() { 8105 mIndexMap.clear(); 8106 } 8107 persistVolumeGroup(int device)8108 private void persistVolumeGroup(int device) { 8109 // No need to persist the index if the volume group is backed up 8110 // by a public stream type as this is redundant 8111 if (mUseFixedVolume || mHasValidStreamType) { 8112 return; 8113 } 8114 if (DEBUG_VOL) { 8115 Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) + " for group " 8116 + mAudioVolumeGroup.name() 8117 + ", device " + AudioSystem.getOutputDeviceName(device) 8118 + " and User=" + getCurrentUserId() 8119 + " mSettingName: " + mSettingName); 8120 } 8121 8122 boolean success = mSettings.putSystemIntForUser(mContentResolver, 8123 getSettingNameForDevice(device), 8124 getIndex(device), 8125 isMusic() ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT); 8126 if (!success) { 8127 Log.e(TAG, "persistVolumeGroup failed for group " + mAudioVolumeGroup.name()); 8128 } 8129 } 8130 readSettings()8131 public void readSettings() { 8132 synchronized (AudioService.VolumeStreamState.class) { 8133 // force maximum volume on all streams if fixed volume property is set 8134 if (mUseFixedVolume) { 8135 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax); 8136 return; 8137 } 8138 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 8139 // retrieve current volume for device 8140 // if no volume stored for current volume group and device, use default volume 8141 // if default device, continue otherwise 8142 int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) 8143 ? AudioSystem.DEFAULT_STREAM_VOLUME[mPublicStreamType] : -1; 8144 int index; 8145 String name = getSettingNameForDevice(device); 8146 index = mSettings.getSystemIntForUser( 8147 mContentResolver, name, defaultIndex, 8148 isMusic() ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT); 8149 if (index == -1) { 8150 continue; 8151 } 8152 if (mPublicStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED 8153 && mCameraSoundForced) { 8154 index = mIndexMax; 8155 } 8156 if (DEBUG_VOL) { 8157 Log.v(TAG, "readSettings: found stored index " + getValidIndex(index) 8158 + " for group " + mAudioVolumeGroup.name() + ", device: " + name 8159 + ", User=" + getCurrentUserId()); 8160 } 8161 mIndexMap.put(device, getValidIndex(index)); 8162 } 8163 } 8164 } 8165 8166 @GuardedBy("AudioService.VolumeStreamState.class") getValidIndex(int index)8167 private int getValidIndex(int index) { 8168 if (index < mIndexMin) { 8169 return mIndexMin; 8170 } else if (mUseFixedVolume || index > mIndexMax) { 8171 return mIndexMax; 8172 } 8173 return index; 8174 } 8175 getSettingNameForDevice(int device)8176 public @NonNull String getSettingNameForDevice(int device) { 8177 String suffix = AudioSystem.getOutputDeviceName(device); 8178 if (suffix.isEmpty()) { 8179 return mSettingName; 8180 } 8181 return mSettingName + "_" + AudioSystem.getOutputDeviceName(device); 8182 } 8183 setSettingName(String settingName)8184 void setSettingName(String settingName) { 8185 mSettingName = settingName; 8186 } 8187 getSettingName()8188 String getSettingName() { 8189 return mSettingName; 8190 } 8191 dump(PrintWriter pw)8192 private void dump(PrintWriter pw) { 8193 pw.println("- VOLUME GROUP " + mAudioVolumeGroup.name() + ":"); 8194 pw.print(" Muted: "); 8195 pw.println(mIsMuted); 8196 pw.print(" Min: "); 8197 pw.println(mIndexMin); 8198 pw.print(" Max: "); 8199 pw.println(mIndexMax); 8200 pw.print(" Current: "); 8201 for (int i = 0; i < mIndexMap.size(); i++) { 8202 if (i > 0) { 8203 pw.print(", "); 8204 } 8205 int device = mIndexMap.keyAt(i); 8206 pw.print(Integer.toHexString(device)); 8207 String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 8208 : AudioSystem.getOutputDeviceName(device); 8209 if (!deviceName.isEmpty()) { 8210 pw.print(" ("); 8211 pw.print(deviceName); 8212 pw.print(")"); 8213 } 8214 pw.print(": "); 8215 pw.print(mIndexMap.valueAt(i)); 8216 } 8217 pw.println(); 8218 pw.print(" Devices: "); 8219 int n = 0; 8220 int devices = getDeviceForVolume(); 8221 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 8222 if ((devices & device) == device) { 8223 if (n++ > 0) { 8224 pw.print(", "); 8225 } 8226 pw.print(AudioSystem.getOutputDeviceName(device)); 8227 } 8228 } 8229 pw.println(); 8230 pw.print(" Streams: "); 8231 Arrays.stream(getLegacyStreamTypes()) 8232 .forEach(stream -> pw.print(AudioSystem.streamToString(stream) + " ")); 8233 } 8234 } 8235 8236 8237 // NOTE: Locking order for synchronized objects related to volume or ringer mode management: 8238 // 1 mScoclient OR mSafeMediaVolumeState 8239 // 2 mSetModeLock 8240 // 3 mSettingsLock 8241 // 4 VolumeStreamState.class 8242 /*package*/ class VolumeStreamState { 8243 private final int mStreamType; 8244 private VolumeGroupState mVolumeGroupState = null; 8245 private int mIndexMin; 8246 // min index when user doesn't have permission to change audio settings 8247 private int mIndexMinNoPerm; 8248 private int mIndexMax; 8249 8250 private boolean mIsMuted = false; 8251 private boolean mIsMutedInternally = false; 8252 private String mVolumeIndexSettingName; 8253 @NonNull private Set<Integer> mObservedDeviceSet = new TreeSet<>(); 8254 8255 private final SparseIntArray mIndexMap = new SparseIntArray(8) { 8256 @Override 8257 public void put(int key, int value) { 8258 super.put(key, value); 8259 record("put", key, value); 8260 } 8261 @Override 8262 public void setValueAt(int index, int value) { 8263 super.setValueAt(index, value); 8264 record("setValueAt", keyAt(index), value); 8265 } 8266 8267 // Record all changes in the VolumeStreamState 8268 private void record(String event, int key, int value) { 8269 final String device = key == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 8270 : AudioSystem.getOutputDeviceName(key); 8271 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME + MediaMetrics.SEPARATOR 8272 + AudioSystem.streamToString(mStreamType) 8273 + "." + device) 8274 .set(MediaMetrics.Property.EVENT, event) 8275 .set(MediaMetrics.Property.INDEX, value) 8276 .set(MediaMetrics.Property.MIN_INDEX, mIndexMin) 8277 .set(MediaMetrics.Property.MAX_INDEX, mIndexMax) 8278 .record(); 8279 } 8280 }; 8281 private final Intent mVolumeChanged; 8282 private final Bundle mVolumeChangedOptions; 8283 private final Intent mStreamDevicesChanged; 8284 private final Bundle mStreamDevicesChangedOptions; 8285 VolumeStreamState(String settingName, int streamType)8286 private VolumeStreamState(String settingName, int streamType) { 8287 mVolumeIndexSettingName = settingName; 8288 8289 mStreamType = streamType; 8290 mIndexMin = MIN_STREAM_VOLUME[streamType] * 10; 8291 mIndexMinNoPerm = mIndexMin; // may be overwritten later in updateNoPermMinIndex() 8292 mIndexMax = MAX_STREAM_VOLUME[streamType] * 10; 8293 final int status = AudioSystem.initStreamVolume( 8294 streamType, mIndexMin / 10, mIndexMax / 10); 8295 if (status != AudioSystem.AUDIO_STATUS_OK) { 8296 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 8297 "VSS() stream:" + streamType + " initStreamVolume=" + status) 8298 .printLog(ALOGE, TAG)); 8299 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 8300 "VSS()" /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 8301 } 8302 8303 readSettings(); 8304 mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION); 8305 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 8306 final BroadcastOptions volumeChangedOptions = BroadcastOptions.makeBasic(); 8307 // This allows us to discard older broadcasts still waiting to be delivered 8308 // which have the same namespace (VOLUME_CHANGED_ACTION) and key (mStreamType). 8309 volumeChangedOptions.setDeliveryGroupPolicy(DELIVERY_GROUP_POLICY_MOST_RECENT); 8310 volumeChangedOptions.setDeliveryGroupMatchingKey( 8311 AudioManager.VOLUME_CHANGED_ACTION, String.valueOf(mStreamType)); 8312 volumeChangedOptions.setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE); 8313 mVolumeChangedOptions = volumeChangedOptions.toBundle(); 8314 8315 mStreamDevicesChanged = new Intent(AudioManager.STREAM_DEVICES_CHANGED_ACTION); 8316 mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 8317 final BroadcastOptions streamDevicesChangedOptions = BroadcastOptions.makeBasic(); 8318 streamDevicesChangedOptions.setDeliveryGroupPolicy(DELIVERY_GROUP_POLICY_MOST_RECENT); 8319 streamDevicesChangedOptions.setDeliveryGroupMatchingKey( 8320 AudioManager.STREAM_DEVICES_CHANGED_ACTION, String.valueOf(mStreamType)); 8321 streamDevicesChangedOptions.setDeferralPolicy( 8322 BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE); 8323 mStreamDevicesChangedOptions = streamDevicesChangedOptions.toBundle(); 8324 } 8325 8326 /** 8327 * Associate a {@link volumeGroupState} on the {@link VolumeStreamState}. 8328 * <p> It helps to synchronize the index, mute attributes on the maching 8329 * {@link volumeGroupState} 8330 * @param volumeGroupState matching the {@link VolumeStreamState} 8331 */ setVolumeGroupState(VolumeGroupState volumeGroupState)8332 public void setVolumeGroupState(VolumeGroupState volumeGroupState) { 8333 mVolumeGroupState = volumeGroupState; 8334 if (mVolumeGroupState != null) { 8335 mVolumeGroupState.setSettingName(mVolumeIndexSettingName); 8336 } 8337 } 8338 /** 8339 * Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission 8340 * @param index minimum index expressed in "UI units", i.e. no 10x factor 8341 */ updateNoPermMinIndex(int index)8342 public void updateNoPermMinIndex(int index) { 8343 mIndexMinNoPerm = index * 10; 8344 if (mIndexMinNoPerm < mIndexMin) { 8345 Log.e(TAG, "Invalid mIndexMinNoPerm for stream " + mStreamType); 8346 mIndexMinNoPerm = mIndexMin; 8347 } 8348 } 8349 8350 /** 8351 * Returns a list of devices associated with the stream type. 8352 * 8353 * This is a reference to the local list, do not modify. 8354 */ 8355 @GuardedBy("VolumeStreamState.class") 8356 @NonNull observeDevicesForStream_syncVSS( boolean checkOthers)8357 public Set<Integer> observeDevicesForStream_syncVSS( 8358 boolean checkOthers) { 8359 if (!mSystemServer.isPrivileged()) { 8360 return new TreeSet<Integer>(); 8361 } 8362 final Set<Integer> deviceSet = 8363 getDeviceSetForStreamDirect(mStreamType); 8364 if (deviceSet.equals(mObservedDeviceSet)) { 8365 return mObservedDeviceSet; 8366 } 8367 8368 // Use legacy bit masks for message signalling. 8369 // TODO(b/185386781): message needs update since it uses devices bit-mask. 8370 final int devices = AudioSystem.getDeviceMaskFromSet(deviceSet); 8371 final int prevDevices = AudioSystem.getDeviceMaskFromSet(mObservedDeviceSet); 8372 8373 mObservedDeviceSet = deviceSet; 8374 if (checkOthers) { 8375 // one stream's devices have changed, check the others 8376 postObserveDevicesForAllStreams(mStreamType); 8377 } 8378 // log base stream changes to the event log 8379 if (mStreamVolumeAlias[mStreamType] == mStreamType) { 8380 EventLogTags.writeStreamDevicesChanged(mStreamType, prevDevices, devices); 8381 } 8382 // send STREAM_DEVICES_CHANGED_ACTION on the message handler so it is scheduled after 8383 // the postObserveDevicesForStreams is handled 8384 final SomeArgs args = SomeArgs.obtain(); 8385 args.arg1 = mStreamDevicesChanged; 8386 args.arg2 = mStreamDevicesChangedOptions; 8387 sendMsg(mAudioHandler, 8388 MSG_STREAM_DEVICES_CHANGED, 8389 SENDMSG_QUEUE, prevDevices /*arg1*/, devices /*arg2*/, 8390 // ok to send reference to this object, it is final 8391 args /*obj*/, 0 /*delay*/); 8392 return mObservedDeviceSet; 8393 } 8394 getSettingNameForDevice(int device)8395 public @Nullable String getSettingNameForDevice(int device) { 8396 if (!hasValidSettingsName()) { 8397 return null; 8398 } 8399 final String suffix = AudioSystem.getOutputDeviceName(device); 8400 if (suffix.isEmpty()) { 8401 return mVolumeIndexSettingName; 8402 } 8403 return mVolumeIndexSettingName + "_" + suffix; 8404 } 8405 hasValidSettingsName()8406 private boolean hasValidSettingsName() { 8407 return (mVolumeIndexSettingName != null && !mVolumeIndexSettingName.isEmpty()); 8408 } 8409 setSettingName(String settingName)8410 void setSettingName(String settingName) { 8411 mVolumeIndexSettingName = settingName; 8412 if (mVolumeGroupState != null) { 8413 mVolumeGroupState.setSettingName(mVolumeIndexSettingName); 8414 } 8415 } 8416 getSettingName()8417 String getSettingName() { 8418 return mVolumeIndexSettingName; 8419 } 8420 readSettings()8421 public void readSettings() { 8422 synchronized (mSettingsLock) { 8423 synchronized (VolumeStreamState.class) { 8424 // force maximum volume on all streams if fixed volume property is set 8425 if (mUseFixedVolume) { 8426 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax); 8427 return; 8428 } 8429 // do not read system stream volume from settings: this stream is always aliased 8430 // to another stream type and its volume is never persisted. Values in settings can 8431 // only be stale values 8432 if ((mStreamType == AudioSystem.STREAM_SYSTEM) || 8433 (mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)) { 8434 int index = 10 * AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType]; 8435 if (mCameraSoundForced) { 8436 index = mIndexMax; 8437 } 8438 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, index); 8439 return; 8440 } 8441 } 8442 } 8443 synchronized (VolumeStreamState.class) { 8444 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 8445 8446 // retrieve current volume for device 8447 // if no volume stored for current stream and device, use default volume if default 8448 // device, continue otherwise 8449 int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ? 8450 AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType] : -1; 8451 int index; 8452 if (!hasValidSettingsName()) { 8453 index = defaultIndex; 8454 } else { 8455 String name = getSettingNameForDevice(device); 8456 index = mSettings.getSystemIntForUser( 8457 mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT); 8458 } 8459 if (index == -1) { 8460 continue; 8461 } 8462 8463 mIndexMap.put(device, getValidIndex(10 * index, 8464 true /*hasModifyAudioSettings*/)); 8465 } 8466 } 8467 } 8468 getAbsoluteVolumeIndex(int index)8469 private int getAbsoluteVolumeIndex(int index) { 8470 /* Special handling for Bluetooth Absolute Volume scenario 8471 * If we send full audio gain, some accessories are too loud even at its lowest 8472 * volume. We are not able to enumerate all such accessories, so here is the 8473 * workaround from phone side. 8474 * Pre-scale volume at lowest volume steps 1 2 and 3. 8475 * For volume step 0, set audio gain to 0 as some accessories won't mute on their end. 8476 */ 8477 if (index == 0) { 8478 // 0% for volume 0 8479 index = 0; 8480 } else if (index > 0 && index <= 3) { 8481 // Pre-scale for volume steps 1 2 and 3 8482 index = (int) (mIndexMax * mPrescaleAbsoluteVolume[index - 1]) / 10; 8483 } else { 8484 // otherwise, full gain 8485 index = (mIndexMax + 5) / 10; 8486 } 8487 return index; 8488 } 8489 setStreamVolumeIndex(int index, int device)8490 private void setStreamVolumeIndex(int index, int device) { 8491 // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted. 8492 // This allows RX path muting by the audio HAL only when explicitly muted but not when 8493 // index is just set to 0 to repect BT requirements 8494 if (mStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0 8495 && !isFullyMuted()) { 8496 index = 1; 8497 } 8498 mAudioSystem.setStreamVolumeIndexAS(mStreamType, index, device); 8499 } 8500 8501 // must be called while synchronized VolumeStreamState.class applyDeviceVolume_syncVSS(int device)8502 /*package*/ void applyDeviceVolume_syncVSS(int device) { 8503 int index; 8504 if (isFullyMuted()) { 8505 index = 0; 8506 } else if (isAbsoluteVolumeDevice(device) 8507 || isA2dpAbsoluteVolumeDevice(device) 8508 || AudioSystem.isLeAudioDeviceType(device)) { 8509 index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10); 8510 } else if (isFullVolumeDevice(device)) { 8511 index = (mIndexMax + 5)/10; 8512 } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 8513 index = (mIndexMax + 5)/10; 8514 } else { 8515 index = (getIndex(device) + 5)/10; 8516 } 8517 setStreamVolumeIndex(index, device); 8518 } 8519 applyAllVolumes()8520 public void applyAllVolumes() { 8521 synchronized (VolumeStreamState.class) { 8522 // apply device specific volumes first 8523 int index; 8524 boolean isAbsoluteVolume = false; 8525 for (int i = 0; i < mIndexMap.size(); i++) { 8526 final int device = mIndexMap.keyAt(i); 8527 if (device != AudioSystem.DEVICE_OUT_DEFAULT) { 8528 if (isFullyMuted()) { 8529 index = 0; 8530 } else if (isAbsoluteVolumeDevice(device) 8531 || isA2dpAbsoluteVolumeDevice(device) 8532 || AudioSystem.isLeAudioDeviceType(device)) { 8533 isAbsoluteVolume = true; 8534 index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10); 8535 } else if (isFullVolumeDevice(device)) { 8536 index = (mIndexMax + 5)/10; 8537 } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 8538 index = (mIndexMax + 5)/10; 8539 } else { 8540 index = (mIndexMap.valueAt(i) + 5)/10; 8541 } 8542 8543 sendMsg(mAudioHandler, SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION, 8544 SENDMSG_REPLACE, device, isAbsoluteVolume ? 1 : 0, this, 8545 /*delay=*/0); 8546 8547 setStreamVolumeIndex(index, device); 8548 } 8549 } 8550 // apply default volume last: by convention , default device volume will be used 8551 // by audio policy manager if no explicit volume is present for a given device type 8552 if (isFullyMuted()) { 8553 index = 0; 8554 } else { 8555 index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10; 8556 } 8557 setStreamVolumeIndex(index, AudioSystem.DEVICE_OUT_DEFAULT); 8558 } 8559 } 8560 adjustIndex(int deltaIndex, int device, String caller, boolean hasModifyAudioSettings)8561 public boolean adjustIndex(int deltaIndex, int device, String caller, 8562 boolean hasModifyAudioSettings) { 8563 return setIndex(getIndex(device) + deltaIndex, device, caller, 8564 hasModifyAudioSettings); 8565 } 8566 setIndex(int index, int device, String caller, boolean hasModifyAudioSettings)8567 public boolean setIndex(int index, int device, String caller, 8568 boolean hasModifyAudioSettings) { 8569 boolean changed; 8570 int oldIndex; 8571 final boolean isCurrentDevice; 8572 synchronized (mSettingsLock) { 8573 synchronized (VolumeStreamState.class) { 8574 oldIndex = getIndex(device); 8575 index = getValidIndex(index, hasModifyAudioSettings); 8576 if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) && mCameraSoundForced) { 8577 index = mIndexMax; 8578 } 8579 mIndexMap.put(device, index); 8580 8581 changed = oldIndex != index; 8582 // Apply change to all streams using this one as alias if: 8583 // - the index actually changed OR 8584 // - there is no volume index stored for this device on alias stream. 8585 // If changing volume of current device, also change volume of current 8586 // device on aliased stream 8587 isCurrentDevice = (device == getDeviceForStream(mStreamType)); 8588 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 8589 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 8590 final VolumeStreamState aliasStreamState = mStreamStates[streamType]; 8591 if (streamType != mStreamType && 8592 mStreamVolumeAlias[streamType] == mStreamType && 8593 (changed || !aliasStreamState.hasIndexForDevice(device))) { 8594 final int scaledIndex = rescaleIndex(index, mStreamType, streamType); 8595 aliasStreamState.setIndex(scaledIndex, device, caller, 8596 hasModifyAudioSettings); 8597 if (isCurrentDevice) { 8598 aliasStreamState.setIndex(scaledIndex, 8599 getDeviceForStream(streamType), caller, 8600 hasModifyAudioSettings); 8601 } 8602 } 8603 } 8604 // Mirror changes in SPEAKER ringtone volume on SCO when 8605 if (changed && mStreamType == AudioSystem.STREAM_RING 8606 && device == AudioSystem.DEVICE_OUT_SPEAKER) { 8607 for (int i = 0; i < mIndexMap.size(); i++) { 8608 int otherDevice = mIndexMap.keyAt(i); 8609 if (AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(otherDevice)) { 8610 mIndexMap.put(otherDevice, index); 8611 } 8612 } 8613 } 8614 } 8615 } 8616 if (changed) { 8617 // If associated to volume group, update group cache 8618 updateVolumeGroupIndex(device, /* forceMuteState= */ false); 8619 8620 oldIndex = (oldIndex + 5) / 10; 8621 index = (index + 5) / 10; 8622 // log base stream changes to the event log 8623 if (mStreamVolumeAlias[mStreamType] == mStreamType) { 8624 if (caller == null) { 8625 Log.w(TAG, "No caller for volume_changed event", new Throwable()); 8626 } 8627 EventLogTags.writeVolumeChanged(mStreamType, oldIndex, index, mIndexMax / 10, 8628 caller); 8629 } 8630 // fire changed intents for all streams, but only when the device it changed on 8631 // is the current device 8632 if ((index != oldIndex) && isCurrentDevice) { 8633 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index); 8634 mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex); 8635 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS, 8636 mStreamVolumeAlias[mStreamType]); 8637 AudioService.sVolumeLogger.enqueue(new VolChangedBroadcastEvent( 8638 mStreamType, mStreamVolumeAlias[mStreamType], index)); 8639 sendBroadcastToAll(mVolumeChanged, mVolumeChangedOptions); 8640 } 8641 } 8642 return changed; 8643 } 8644 getIndex(int device)8645 public int getIndex(int device) { 8646 synchronized (VolumeStreamState.class) { 8647 int index = mIndexMap.get(device, -1); 8648 if (index == -1) { 8649 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT 8650 index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); 8651 } 8652 return index; 8653 } 8654 } 8655 getVolumeInfo(int device)8656 public @NonNull VolumeInfo getVolumeInfo(int device) { 8657 synchronized (VolumeStreamState.class) { 8658 int index = mIndexMap.get(device, -1); 8659 if (index == -1) { 8660 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT 8661 index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); 8662 } 8663 final VolumeInfo vi = new VolumeInfo.Builder(mStreamType) 8664 .setMinVolumeIndex(mIndexMin) 8665 .setMaxVolumeIndex(mIndexMax) 8666 .setVolumeIndex(index) 8667 .setMuted(isFullyMuted()) 8668 .build(); 8669 return vi; 8670 } 8671 } 8672 hasIndexForDevice(int device)8673 public boolean hasIndexForDevice(int device) { 8674 synchronized (VolumeStreamState.class) { 8675 return (mIndexMap.get(device, -1) != -1); 8676 } 8677 } 8678 getMaxIndex()8679 public int getMaxIndex() { 8680 return mIndexMax; 8681 } 8682 8683 /** 8684 * @return the lowest index regardless of permissions 8685 */ getMinIndex()8686 public int getMinIndex() { 8687 return mIndexMin; 8688 } 8689 8690 /** 8691 * @param isPrivileged true if the caller is privileged and not subject to minimum 8692 * volume index thresholds 8693 * @return the lowest index that this caller can set or adjust to 8694 */ getMinIndex(boolean isPrivileged)8695 public int getMinIndex(boolean isPrivileged) { 8696 return isPrivileged ? mIndexMin : mIndexMinNoPerm; 8697 } 8698 8699 /** 8700 * Copies all device/index pairs from the given VolumeStreamState after initializing 8701 * them with the volume for DEVICE_OUT_DEFAULT. No-op if the source VolumeStreamState 8702 * has the same stream type as this instance. 8703 * @param srcStream 8704 * @param caller 8705 */ 8706 // must be sync'd on mSettingsLock before VolumeStreamState.class 8707 @GuardedBy("VolumeStreamState.class") setAllIndexes(VolumeStreamState srcStream, String caller)8708 public void setAllIndexes(VolumeStreamState srcStream, String caller) { 8709 if (mStreamType == srcStream.mStreamType) { 8710 return; 8711 } 8712 int srcStreamType = srcStream.getStreamType(); 8713 // apply default device volume from source stream to all devices first in case 8714 // some devices are present in this stream state but not in source stream state 8715 int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT); 8716 index = rescaleIndex(index, srcStreamType, mStreamType); 8717 for (int i = 0; i < mIndexMap.size(); i++) { 8718 mIndexMap.put(mIndexMap.keyAt(i), index); 8719 } 8720 // Now apply actual volume for devices in source stream state 8721 SparseIntArray srcMap = srcStream.mIndexMap; 8722 for (int i = 0; i < srcMap.size(); i++) { 8723 int device = srcMap.keyAt(i); 8724 index = srcMap.valueAt(i); 8725 index = rescaleIndex(index, srcStreamType, mStreamType); 8726 8727 setIndex(index, device, caller, true /*hasModifyAudioSettings*/); 8728 } 8729 } 8730 8731 // must be sync'd on mSettingsLock before VolumeStreamState.class 8732 @GuardedBy("VolumeStreamState.class") setAllIndexesToMax()8733 public void setAllIndexesToMax() { 8734 for (int i = 0; i < mIndexMap.size(); i++) { 8735 mIndexMap.put(mIndexMap.keyAt(i), mIndexMax); 8736 } 8737 } 8738 8739 // If associated to volume group, update group cache updateVolumeGroupIndex(int device, boolean forceMuteState)8740 private void updateVolumeGroupIndex(int device, boolean forceMuteState) { 8741 // need mSettingsLock when called from setIndex for vgs.mute -> vgs.applyAllVolumes -> 8742 // vss.setIndex which grabs this lock after VSS.class. Locking order needs to be 8743 // preserved 8744 synchronized (mSettingsLock) { 8745 synchronized (VolumeStreamState.class) { 8746 if (mVolumeGroupState != null) { 8747 int groupIndex = (getIndex(device) + 5) / 10; 8748 if (DEBUG_VOL) { 8749 Log.d(TAG, "updateVolumeGroupIndex for stream " + mStreamType 8750 + ", muted=" + mIsMuted + ", device=" + device + ", index=" 8751 + getIndex(device) + ", group " + mVolumeGroupState.name() 8752 + " Muted=" + mVolumeGroupState.isMuted() + ", Index=" 8753 + groupIndex + ", forceMuteState=" + forceMuteState); 8754 } 8755 mVolumeGroupState.updateVolumeIndex(groupIndex, device); 8756 // Only propage mute of stream when applicable 8757 if (isMutable()) { 8758 // For call stream, align mute only when muted, not when index is set to 8759 // 0 8760 mVolumeGroupState.mute( 8761 forceMuteState ? mIsMuted : 8762 (groupIndex == 0 && !isCallStream(mStreamType)) 8763 || mIsMuted); 8764 } 8765 } 8766 } 8767 } 8768 } 8769 8770 /** 8771 * Mute/unmute the stream 8772 * @param state the new mute state 8773 * @return true if the mute state was changed 8774 */ mute(boolean state, String source)8775 public boolean mute(boolean state, String source) { 8776 boolean changed = false; 8777 synchronized (VolumeStreamState.class) { 8778 changed = mute(state, true, source); 8779 } 8780 if (changed) { 8781 broadcastMuteSetting(mStreamType, state); 8782 } 8783 return changed; 8784 } 8785 8786 /** 8787 * Mute/unmute the stream by AudioService 8788 * @param state the new mute state 8789 * @return true if the mute state was changed 8790 */ muteInternally(boolean state)8791 public boolean muteInternally(boolean state) { 8792 boolean changed = false; 8793 synchronized (VolumeStreamState.class) { 8794 if (state != mIsMutedInternally) { 8795 changed = true; 8796 mIsMutedInternally = state; 8797 // mute immediately to avoid delay and preemption when using a message. 8798 applyAllVolumes(); 8799 } 8800 } 8801 if (changed) { 8802 sVolumeLogger.enqueue(new VolumeEvent( 8803 VolumeEvent.VOL_MUTE_STREAM_INT, mStreamType, state)); 8804 } 8805 return changed; 8806 } 8807 8808 @GuardedBy("VolumeStreamState.class") isFullyMuted()8809 public boolean isFullyMuted() { 8810 return mIsMuted || mIsMutedInternally; 8811 } 8812 8813 isMutable()8814 private boolean isMutable() { 8815 return isStreamAffectedByMute(mStreamType) 8816 && (mIndexMin == 0 || isCallStream(mStreamType)); 8817 } 8818 8819 /** 8820 * Mute/unmute the stream 8821 * @param state the new mute state 8822 * @param apply true to propagate to HW, or false just to update the cache. May be needed 8823 * to mute a stream and its aliases as applyAllVolume will force settings to aliases. 8824 * It prevents unnecessary calls to {@see AudioSystem#setStreamVolume} 8825 * @return true if the mute state was changed 8826 */ mute(boolean state, boolean apply, String src)8827 public boolean mute(boolean state, boolean apply, String src) { 8828 synchronized (VolumeStreamState.class) { 8829 boolean changed = state != mIsMuted; 8830 if (changed) { 8831 sMuteLogger.enqueue( 8832 new AudioServiceEvents.StreamMuteEvent(mStreamType, state, src)); 8833 // check to see if unmuting should not have happened due to ringer muted streams 8834 if (!state && isStreamMutedByRingerOrZenMode(mStreamType)) { 8835 Log.e(TAG, "Unmuting stream " + mStreamType 8836 + " despite ringer-zen muted stream 0x" 8837 + Integer.toHexString(AudioService.sRingerAndZenModeMutedStreams), 8838 new Exception()); // this will put a stack trace in the logs 8839 sMuteLogger.enqueue(new AudioServiceEvents.StreamUnmuteErrorEvent( 8840 mStreamType, AudioService.sRingerAndZenModeMutedStreams)); 8841 } 8842 mIsMuted = state; 8843 if (apply) { 8844 doMute(); 8845 } 8846 } 8847 return changed; 8848 } 8849 } 8850 doMute()8851 public void doMute() { 8852 synchronized (VolumeStreamState.class) { 8853 // If associated to volume group, update group cache 8854 updateVolumeGroupIndex(getDeviceForStream(mStreamType), /* forceMuteState= */ true); 8855 8856 // Set the new mute volume. This propagates the values to 8857 // the audio system, otherwise the volume won't be changed 8858 // at the lower level. 8859 sendMsg(mAudioHandler, 8860 MSG_SET_ALL_VOLUMES, 8861 SENDMSG_QUEUE, 8862 0, 8863 0, 8864 this, 0); 8865 } 8866 } 8867 getStreamType()8868 public int getStreamType() { 8869 return mStreamType; 8870 } 8871 checkFixedVolumeDevices()8872 public void checkFixedVolumeDevices() { 8873 synchronized (VolumeStreamState.class) { 8874 // ignore settings for fixed volume devices: volume should always be at max or 0 8875 if (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_MUSIC) { 8876 for (int i = 0; i < mIndexMap.size(); i++) { 8877 int device = mIndexMap.keyAt(i); 8878 int index = mIndexMap.valueAt(i); 8879 if (isFullVolumeDevice(device) 8880 || (isFixedVolumeDevice(device) && index != 0)) { 8881 mIndexMap.put(device, mIndexMax); 8882 } 8883 applyDeviceVolume_syncVSS(device); 8884 } 8885 } 8886 } 8887 } 8888 getValidIndex(int index, boolean hasModifyAudioSettings)8889 private int getValidIndex(int index, boolean hasModifyAudioSettings) { 8890 final int indexMin = hasModifyAudioSettings ? mIndexMin : mIndexMinNoPerm; 8891 if (index < indexMin) { 8892 return indexMin; 8893 } else if (mUseFixedVolume || index > mIndexMax) { 8894 return mIndexMax; 8895 } 8896 8897 return index; 8898 } 8899 dump(PrintWriter pw)8900 private void dump(PrintWriter pw) { 8901 pw.print(" Muted: "); 8902 pw.println(mIsMuted); 8903 pw.print(" Muted Internally: "); 8904 pw.println(mIsMutedInternally); 8905 pw.print(" Min: "); 8906 pw.print((mIndexMin + 5) / 10); 8907 if (mIndexMin != mIndexMinNoPerm) { 8908 pw.print(" w/o perm:"); 8909 pw.println((mIndexMinNoPerm + 5) / 10); 8910 } else { 8911 pw.println(); 8912 } 8913 pw.print(" Max: "); 8914 pw.println((mIndexMax + 5) / 10); 8915 pw.print(" streamVolume:"); pw.println(getStreamVolume(mStreamType)); 8916 pw.print(" Current: "); 8917 for (int i = 0; i < mIndexMap.size(); i++) { 8918 if (i > 0) { 8919 pw.print(", "); 8920 } 8921 final int device = mIndexMap.keyAt(i); 8922 pw.print(Integer.toHexString(device)); 8923 final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 8924 : AudioSystem.getOutputDeviceName(device); 8925 if (!deviceName.isEmpty()) { 8926 pw.print(" ("); 8927 pw.print(deviceName); 8928 pw.print(")"); 8929 } 8930 pw.print(": "); 8931 final int index = (mIndexMap.valueAt(i) + 5) / 10; 8932 pw.print(index); 8933 } 8934 pw.println(); 8935 pw.print(" Devices: "); 8936 pw.print(AudioSystem.deviceSetToString(getDeviceSetForStream(mStreamType))); 8937 pw.println(); 8938 pw.print(" Volume Group: "); 8939 pw.println(mVolumeGroupState != null ? mVolumeGroupState.name() : "n/a"); 8940 } 8941 } 8942 8943 /** Thread that handles native AudioSystem control. */ 8944 private class AudioSystemThread extends Thread { AudioSystemThread()8945 AudioSystemThread() { 8946 super("AudioService"); 8947 } 8948 8949 @Override run()8950 public void run() { 8951 // Set this thread up so the handler will work on it 8952 Looper.prepare(); 8953 8954 synchronized(AudioService.this) { 8955 mAudioHandler = new AudioHandler(); 8956 8957 // Notify that the handler has been created 8958 AudioService.this.notify(); 8959 } 8960 8961 // Listen for volume change requests that are set by VolumePanel 8962 Looper.loop(); 8963 } 8964 } 8965 8966 private static final class DeviceVolumeUpdate { 8967 final int mStreamType; 8968 final int mDevice; 8969 final @NonNull String mCaller; 8970 private static final int NO_NEW_INDEX = -2049; 8971 private final int mVssVolIndex; 8972 8973 // Constructor with volume index, meant to cause this volume to be set and applied for the 8974 // given stream type on the given device DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller)8975 DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller) { 8976 mStreamType = streamType; 8977 mVssVolIndex = vssVolIndex; 8978 mDevice = device; 8979 mCaller = caller; 8980 } 8981 8982 // Constructor with no volume index, meant to cause re-apply of volume for the given 8983 // stream type on the given device DeviceVolumeUpdate(int streamType, int device, @NonNull String caller)8984 DeviceVolumeUpdate(int streamType, int device, @NonNull String caller) { 8985 mStreamType = streamType; 8986 mVssVolIndex = NO_NEW_INDEX; 8987 mDevice = device; 8988 mCaller = caller; 8989 } 8990 hasVolumeIndex()8991 boolean hasVolumeIndex() { 8992 return mVssVolIndex != NO_NEW_INDEX; 8993 } 8994 getVolumeIndex()8995 int getVolumeIndex() throws IllegalStateException { 8996 Preconditions.checkState(mVssVolIndex != NO_NEW_INDEX); 8997 return mVssVolIndex; 8998 } 8999 } 9000 9001 /** only public for mocking/spying, do not call outside of AudioService */ 9002 @VisibleForTesting postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, String caller)9003 public void postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, 9004 String caller) { 9005 sendMsg(mAudioHandler, 9006 MSG_SET_DEVICE_STREAM_VOLUME, 9007 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/, 9008 new DeviceVolumeUpdate(streamType, vssVolIndex, device, caller), 9009 0 /*delay*/); 9010 } 9011 postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller)9012 /*package*/ void postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller) { 9013 sendMsg(mAudioHandler, 9014 MSG_SET_DEVICE_STREAM_VOLUME, 9015 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/, 9016 new DeviceVolumeUpdate(streamType, device, caller), 9017 0 /*delay*/); 9018 } 9019 onSetVolumeIndexOnDevice(@onNull DeviceVolumeUpdate update)9020 private void onSetVolumeIndexOnDevice(@NonNull DeviceVolumeUpdate update) { 9021 final VolumeStreamState streamState = mStreamStates[update.mStreamType]; 9022 if (update.hasVolumeIndex()) { 9023 int index = update.getVolumeIndex(); 9024 if (mSoundDoseHelper.checkSafeMediaVolume(update.mStreamType, index, update.mDevice)) { 9025 index = mSoundDoseHelper.safeMediaVolumeIndex(update.mDevice); 9026 } 9027 streamState.setIndex(index, update.mDevice, update.mCaller, 9028 // trusted as index is always validated before message is posted 9029 true /*hasModifyAudioSettings*/); 9030 sVolumeLogger.enqueue(new EventLogger.StringEvent(update.mCaller + " dev:0x" 9031 + Integer.toHexString(update.mDevice) + " volIdx:" + index)); 9032 } else { 9033 sVolumeLogger.enqueue(new EventLogger.StringEvent(update.mCaller 9034 + " update vol on dev:0x" + Integer.toHexString(update.mDevice))); 9035 } 9036 setDeviceVolume(streamState, update.mDevice); 9037 } 9038 setDeviceVolume(VolumeStreamState streamState, int device)9039 /*package*/ void setDeviceVolume(VolumeStreamState streamState, int device) { 9040 9041 synchronized (VolumeStreamState.class) { 9042 sendMsg(mAudioHandler, SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION, SENDMSG_REPLACE, 9043 device, (isAbsoluteVolumeDevice(device) || isA2dpAbsoluteVolumeDevice(device) 9044 || AudioSystem.isLeAudioDeviceType(device) ? 1 : 0), 9045 streamState, /*delay=*/0); 9046 // Apply volume 9047 streamState.applyDeviceVolume_syncVSS(device); 9048 9049 // Apply change to all streams using this one as alias 9050 int numStreamTypes = AudioSystem.getNumStreamTypes(); 9051 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 9052 if (streamType != streamState.mStreamType && 9053 mStreamVolumeAlias[streamType] == streamState.mStreamType) { 9054 // Make sure volume is also maxed out on A2DP device for aliased stream 9055 // that may have a different device selected 9056 int streamDevice = getDeviceForStream(streamType); 9057 if ((device != streamDevice) 9058 && (isAbsoluteVolumeDevice(device) 9059 || isA2dpAbsoluteVolumeDevice(device) 9060 || AudioSystem.isLeAudioDeviceType(device))) { 9061 mStreamStates[streamType].applyDeviceVolume_syncVSS(device); 9062 } 9063 mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice); 9064 } 9065 } 9066 } 9067 // Post a persist volume msg 9068 sendMsg(mAudioHandler, 9069 MSG_PERSIST_VOLUME, 9070 SENDMSG_QUEUE, 9071 device, 9072 0, 9073 streamState, 9074 PERSIST_DELAY); 9075 9076 } 9077 9078 /** Handles internal volume messages in separate volume thread. */ 9079 /*package*/ class AudioHandler extends Handler { 9080 AudioHandler()9081 AudioHandler() { 9082 super(); 9083 } 9084 AudioHandler(Looper looper)9085 AudioHandler(Looper looper) { 9086 super(looper); 9087 } 9088 setAllVolumes(VolumeStreamState streamState)9089 private void setAllVolumes(VolumeStreamState streamState) { 9090 9091 // Apply volume 9092 streamState.applyAllVolumes(); 9093 9094 // Apply change to all streams using this one as alias 9095 int numStreamTypes = AudioSystem.getNumStreamTypes(); 9096 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 9097 if (streamType != streamState.mStreamType && 9098 mStreamVolumeAlias[streamType] == streamState.mStreamType) { 9099 mStreamStates[streamType].applyAllVolumes(); 9100 } 9101 } 9102 } 9103 persistVolume(VolumeStreamState streamState, int device)9104 private void persistVolume(VolumeStreamState streamState, int device) { 9105 if (mUseFixedVolume) { 9106 return; 9107 } 9108 if (mIsSingleVolume && (streamState.mStreamType != AudioSystem.STREAM_MUSIC)) { 9109 return; 9110 } 9111 if (streamState.hasValidSettingsName()) { 9112 mSettings.putSystemIntForUser(mContentResolver, 9113 streamState.getSettingNameForDevice(device), 9114 (streamState.getIndex(device) + 5) / 10, 9115 UserHandle.USER_CURRENT); 9116 } 9117 } 9118 persistRingerMode(int ringerMode)9119 private void persistRingerMode(int ringerMode) { 9120 if (mUseFixedVolume) { 9121 return; 9122 } 9123 mSettings.putGlobalInt(mContentResolver, Settings.Global.MODE_RINGER, ringerMode); 9124 } 9125 onNotifyVolumeEvent(@onNull IAudioPolicyCallback apc, @AudioManager.VolumeAdjustment int direction)9126 private void onNotifyVolumeEvent(@NonNull IAudioPolicyCallback apc, 9127 @AudioManager.VolumeAdjustment int direction) { 9128 try { 9129 apc.notifyVolumeAdjust(direction); 9130 } catch(Exception e) { 9131 // nothing we can do about this. Do not log error, too much potential for spam 9132 } 9133 } 9134 9135 @Override handleMessage(Message msg)9136 public void handleMessage(Message msg) { 9137 switch (msg.what) { 9138 9139 case MSG_SET_DEVICE_VOLUME: 9140 setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1); 9141 break; 9142 9143 case MSG_SET_ALL_VOLUMES: 9144 setAllVolumes((VolumeStreamState) msg.obj); 9145 break; 9146 9147 case MSG_PERSIST_VOLUME: 9148 persistVolume((VolumeStreamState) msg.obj, msg.arg1); 9149 break; 9150 9151 case MSG_PERSIST_VOLUME_GROUP: 9152 final VolumeGroupState vgs = (VolumeGroupState) msg.obj; 9153 vgs.persistVolumeGroup(msg.arg1); 9154 break; 9155 9156 case MSG_PERSIST_RINGER_MODE: 9157 // note that the value persisted is the current ringer mode, not the 9158 // value of ringer mode as of the time the request was made to persist 9159 persistRingerMode(getRingerModeInternal()); 9160 break; 9161 9162 case MSG_AUDIO_SERVER_DIED: 9163 onAudioServerDied(); 9164 break; 9165 9166 case MSG_DISPATCH_AUDIO_SERVER_STATE: 9167 onDispatchAudioServerStateChange(msg.arg1 == 1); 9168 break; 9169 9170 case MSG_UNLOAD_SOUND_EFFECTS: 9171 mSfxHelper.unloadSoundEffects(); 9172 break; 9173 9174 case MSG_LOAD_SOUND_EFFECTS: 9175 { 9176 LoadSoundEffectReply reply = (LoadSoundEffectReply) msg.obj; 9177 if (mSystemReady) { 9178 mSfxHelper.loadSoundEffects(reply); 9179 } else { 9180 Log.w(TAG, "[schedule]loadSoundEffects() called before boot complete"); 9181 if (reply != null) { 9182 reply.run(false); 9183 } 9184 } 9185 } 9186 break; 9187 9188 case MSG_PLAY_SOUND_EFFECT: 9189 mSfxHelper.playSoundEffect(msg.arg1, msg.arg2); 9190 break; 9191 9192 case MSG_SET_FORCE_USE: 9193 { 9194 final String eventSource = (String) msg.obj; 9195 final int useCase = msg.arg1; 9196 final int config = msg.arg2; 9197 if (useCase == AudioSystem.FOR_MEDIA) { 9198 Log.wtf(TAG, "Invalid force use FOR_MEDIA in AudioService from " 9199 + eventSource); 9200 break; 9201 } 9202 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE 9203 + MediaMetrics.SEPARATOR + AudioSystem.forceUseUsageToString(useCase)) 9204 .set(MediaMetrics.Property.EVENT, "setForceUse") 9205 .set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource) 9206 .set(MediaMetrics.Property.FORCE_USE_MODE, 9207 AudioSystem.forceUseConfigToString(config)) 9208 .record(); 9209 sForceUseLogger.enqueue( 9210 new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource)); 9211 mAudioSystem.setForceUse(useCase, config); 9212 } 9213 break; 9214 9215 case MSG_DISABLE_AUDIO_FOR_UID: 9216 mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */, 9217 msg.arg2 /* uid */); 9218 mAudioEventWakeLock.release(); 9219 break; 9220 9221 case MSG_INIT_STREAMS_VOLUMES: 9222 onInitStreamsAndVolumes(); 9223 mAudioEventWakeLock.release(); 9224 break; 9225 9226 case MSG_INIT_ADI_DEVICE_STATES: 9227 onInitAdiDeviceStates(); 9228 mAudioEventWakeLock.release(); 9229 break; 9230 9231 case MSG_INIT_SPATIALIZER: 9232 onInitSpatializer(); 9233 mAudioEventWakeLock.release(); 9234 break; 9235 9236 case MSG_INIT_HEADTRACKING_SENSORS: 9237 mSpatializerHelper.onInitSensors(); 9238 break; 9239 9240 case MSG_RESET_SPATIALIZER: 9241 mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect); 9242 break; 9243 9244 case MSG_SYSTEM_READY: 9245 onSystemReady(); 9246 break; 9247 9248 case MSG_INDICATE_SYSTEM_READY: 9249 onIndicateSystemReady(); 9250 break; 9251 9252 case MSG_ACCESSORY_PLUG_MEDIA_UNMUTE: 9253 onAccessoryPlugMediaUnmute(msg.arg1); 9254 break; 9255 9256 case MSG_UNMUTE_STREAM: 9257 onUnmuteStream(msg.arg1, msg.arg2); 9258 break; 9259 9260 case MSG_DYN_POLICY_MIX_STATE_UPDATE: 9261 onDynPolicyMixStateUpdate((String) msg.obj, msg.arg1); 9262 break; 9263 9264 case MSG_NOTIFY_VOL_EVENT: 9265 onNotifyVolumeEvent((IAudioPolicyCallback) msg.obj, msg.arg1); 9266 break; 9267 9268 case MSG_ENABLE_SURROUND_FORMATS: 9269 onEnableSurroundFormats((ArrayList<Integer>) msg.obj); 9270 break; 9271 9272 case MSG_UPDATE_RINGER_MODE: 9273 onUpdateRingerModeServiceInt(); 9274 break; 9275 9276 case MSG_SET_DEVICE_STREAM_VOLUME: 9277 onSetVolumeIndexOnDevice((DeviceVolumeUpdate) msg.obj); 9278 break; 9279 9280 case MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS: 9281 onObserveDevicesForAllStreams(/*skipStream*/ msg.arg1); 9282 break; 9283 9284 case MSG_HDMI_VOLUME_CHECK: 9285 onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj); 9286 break; 9287 9288 case MSG_PLAYBACK_CONFIG_CHANGE: 9289 onPlaybackConfigChange((List<AudioPlaybackConfiguration>) msg.obj); 9290 break; 9291 case MSG_RECORDING_CONFIG_CHANGE: 9292 onRecordingConfigChange((List<AudioRecordingConfiguration>) msg.obj); 9293 break; 9294 9295 case MSG_BROADCAST_MICROPHONE_MUTE: 9296 mSystemServer.sendMicrophoneMuteChangedIntent(); 9297 break; 9298 9299 case MSG_CHECK_MODE_FOR_UID: 9300 synchronized (mDeviceBroker.mSetModeLock) { 9301 if (msg.obj == null) { 9302 break; 9303 } 9304 // Update active playback/recording for apps requesting IN_COMMUNICATION 9305 // mode after a grace period following the mode change 9306 SetModeDeathHandler h = (SetModeDeathHandler) msg.obj; 9307 if (mSetModeDeathHandlers.indexOf(h) < 0) { 9308 break; 9309 } 9310 boolean wasActive = h.isActive(); 9311 h.setPlaybackActive(isPlaybackActiveForUid(h.getUid())); 9312 h.setRecordingActive(isRecordingActiveForUid(h.getUid())); 9313 if (wasActive != h.isActive()) { 9314 onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(), 9315 mContext.getPackageName(), false /*force*/); 9316 } 9317 } 9318 break; 9319 9320 case MSG_STREAM_DEVICES_CHANGED: 9321 final SomeArgs args = (SomeArgs) msg.obj; 9322 final Intent intent = (Intent) args.arg1; 9323 final Bundle options = (Bundle) args.arg2; 9324 args.recycle(); 9325 sendBroadcastToAll(intent 9326 .putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_DEVICES, msg.arg1) 9327 .putExtra(AudioManager.EXTRA_VOLUME_STREAM_DEVICES, msg.arg2), 9328 options); 9329 break; 9330 9331 case MSG_UPDATE_VOLUME_STATES_FOR_DEVICE: 9332 onUpdateVolumeStatesForAudioDevice(msg.arg1, (String) msg.obj); 9333 break; 9334 9335 case MSG_REINIT_VOLUMES: 9336 onReinitVolumes((String) msg.obj); 9337 break; 9338 9339 case MSG_UPDATE_A11Y_SERVICE_UIDS: 9340 onUpdateAccessibilityServiceUids(); 9341 break; 9342 9343 case MSG_UPDATE_AUDIO_MODE: 9344 synchronized (mDeviceBroker.mSetModeLock) { 9345 onUpdateAudioMode(msg.arg1, msg.arg2, (String) msg.obj, false /*force*/); 9346 } 9347 break; 9348 9349 case MSG_BT_DEV_CHANGED: 9350 mDeviceBroker.queueOnBluetoothActiveDeviceChanged( 9351 (AudioDeviceBroker.BtDeviceChangedData) msg.obj); 9352 break; 9353 9354 case MSG_DISPATCH_AUDIO_MODE: 9355 dispatchMode(msg.arg1); 9356 break; 9357 9358 case MSG_ROUTING_UPDATED: 9359 onRoutingUpdatedFromAudioThread(); 9360 break; 9361 9362 case MSG_ADD_ASSISTANT_SERVICE_UID: 9363 onAddAssistantServiceUids(new int[]{msg.arg1}); 9364 break; 9365 9366 case MSG_REMOVE_ASSISTANT_SERVICE_UID: 9367 onRemoveAssistantServiceUids(new int[]{msg.arg1}); 9368 break; 9369 case MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID: 9370 updateActiveAssistantServiceUids(); 9371 break; 9372 9373 case MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR: 9374 dispatchDeviceVolumeBehavior((AudioDeviceAttributes) msg.obj, msg.arg1); 9375 break; 9376 9377 case MSG_ROTATION_UPDATE: 9378 // rotation parameter format: "rotation=x" where x is one of 0, 90, 180, 270 9379 mAudioSystem.setParameters((String) msg.obj); 9380 break; 9381 9382 case MSG_FOLD_UPDATE: 9383 // fold parameter format: "device_folded=x" where x is one of on, off 9384 mAudioSystem.setParameters((String) msg.obj); 9385 break; 9386 9387 case MSG_NO_LOG_FOR_PLAYER_I: 9388 mPlaybackMonitor.ignorePlayerIId(msg.arg1); 9389 break; 9390 9391 case MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES: 9392 onDispatchPreferredMixerAttributesChanged(msg.getData(), msg.arg1); 9393 break; 9394 9395 case MSG_LOWER_VOLUME_TO_RS1: 9396 onLowerVolumeToRs1(); 9397 break; 9398 9399 case MSG_CONFIGURATION_CHANGED: 9400 onConfigurationChanged(); 9401 break; 9402 9403 default: 9404 if (msg.what >= SAFE_MEDIA_VOLUME_MSG_START) { 9405 // msg could be for the SoundDoseHelper 9406 mSoundDoseHelper.handleMessage(msg); 9407 } 9408 } 9409 } 9410 } 9411 9412 private class SettingsObserver extends ContentObserver { 9413 SettingsObserver()9414 SettingsObserver() { 9415 super(new Handler()); 9416 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9417 Settings.Global.ZEN_MODE), false, this); 9418 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9419 Settings.Global.ZEN_MODE_CONFIG_ETAG), false, this); 9420 mContentResolver.registerContentObserver(Settings.System.getUriFor( 9421 Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this); 9422 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9423 Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this); 9424 mContentResolver.registerContentObserver(Settings.System.getUriFor( 9425 Settings.System.MASTER_MONO), false, this); 9426 mContentResolver.registerContentObserver(Settings.System.getUriFor( 9427 Settings.System.MASTER_BALANCE), false, this); 9428 9429 mEncodedSurroundMode = mSettings.getGlobalInt( 9430 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT, 9431 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 9432 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9433 Settings.Global.ENCODED_SURROUND_OUTPUT), false, this); 9434 mEnabledSurroundFormats = mSettings.getGlobalString( 9435 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 9436 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9437 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS), false, this); 9438 9439 mContentResolver.registerContentObserver(Settings.Secure.getUriFor( 9440 Settings.Secure.VOICE_INTERACTION_SERVICE), false, this); 9441 } 9442 9443 @Override onChange(boolean selfChange)9444 public void onChange(boolean selfChange) { 9445 super.onChange(selfChange); 9446 // FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode. 9447 // However there appear to be some missing locks around sRingerAndZenModeMutedStreams 9448 // and mRingerModeAffectedStreams, so will leave this synchronized for now. 9449 // sRingerAndZenModeMutedStreams and mMuteAffectedStreams are safe (only accessed once). 9450 synchronized (mSettingsLock) { 9451 if (updateRingerAndZenModeAffectedStreams()) { 9452 /* 9453 * Ensure all stream types that should be affected by ringer mode 9454 * are in the proper state. 9455 */ 9456 setRingerModeInt(getRingerModeInternal(), false); 9457 } 9458 readDockAudioSettings(mContentResolver); 9459 updateMasterMono(mContentResolver); 9460 updateMasterBalance(mContentResolver); 9461 updateEncodedSurroundOutput(); 9462 sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged); 9463 updateAssistantUIdLocked(/* forceUpdate= */ false); 9464 } 9465 } 9466 updateEncodedSurroundOutput()9467 private void updateEncodedSurroundOutput() { 9468 int newSurroundMode = mSettings.getGlobalInt( 9469 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT, 9470 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 9471 // Did it change? 9472 if (mEncodedSurroundMode != newSurroundMode) { 9473 // Send to AudioPolicyManager 9474 sendEncodedSurroundMode(newSurroundMode, "SettingsObserver"); 9475 mDeviceBroker.toggleHdmiIfConnected_Async(); 9476 mEncodedSurroundMode = newSurroundMode; 9477 mSurroundModeChanged = true; 9478 } else { 9479 mSurroundModeChanged = false; 9480 } 9481 } 9482 } 9483 avrcpSupportsAbsoluteVolume(String address, boolean support)9484 private void avrcpSupportsAbsoluteVolume(String address, boolean support) { 9485 // address is not used for now, but may be used when multiple a2dp devices are supported 9486 sVolumeLogger.enqueue(new EventLogger.StringEvent("avrcpSupportsAbsoluteVolume addr=" 9487 + address + " support=" + support).printLog(TAG)); 9488 mDeviceBroker.setAvrcpAbsoluteVolumeSupported(support); 9489 setAvrcpAbsoluteVolumeSupported(support); 9490 } 9491 setAvrcpAbsoluteVolumeSupported(boolean support)9492 /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean support) { 9493 mAvrcpAbsVolSupported = support; 9494 sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE, 9495 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, 9496 mStreamStates[AudioSystem.STREAM_MUSIC], 0); 9497 } 9498 9499 /** 9500 * @return true if there is currently a registered dynamic mixing policy that affects media 9501 * and is not a render + loopback policy 9502 */ 9503 // only public for mocking/spying 9504 @VisibleForTesting hasMediaDynamicPolicy()9505 public boolean hasMediaDynamicPolicy() { 9506 synchronized (mAudioPolicies) { 9507 if (mAudioPolicies.isEmpty()) { 9508 return false; 9509 } 9510 final Collection<AudioPolicyProxy> appColl = mAudioPolicies.values(); 9511 for (AudioPolicyProxy app : appColl) { 9512 if (app.hasMixAffectingUsage(AudioAttributes.USAGE_MEDIA, 9513 AudioMix.ROUTE_FLAG_LOOP_BACK_RENDER)) { 9514 return true; 9515 } 9516 } 9517 return false; 9518 } 9519 } 9520 9521 /** only public for mocking/spying, do not call outside of AudioService */ 9522 @VisibleForTesting checkMusicActive(int deviceType, String caller)9523 public void checkMusicActive(int deviceType, String caller) { 9524 if (mSoundDoseHelper.safeDevicesContains(deviceType)) { 9525 mSoundDoseHelper.scheduleMusicActiveCheck(); 9526 } 9527 } 9528 9529 /** 9530 * Receiver for misc intent broadcasts the Phone app cares about. 9531 */ 9532 private class AudioServiceBroadcastReceiver extends BroadcastReceiver { 9533 @Override onReceive(Context context, Intent intent)9534 public void onReceive(Context context, Intent intent) { 9535 final String action = intent.getAction(); 9536 int outDevice; 9537 int inDevice; 9538 int state; 9539 9540 if (action.equals(Intent.ACTION_DOCK_EVENT)) { 9541 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 9542 Intent.EXTRA_DOCK_STATE_UNDOCKED); 9543 int config; 9544 switch (dockState) { 9545 case Intent.EXTRA_DOCK_STATE_DESK: 9546 config = AudioSystem.FORCE_BT_DESK_DOCK; 9547 break; 9548 case Intent.EXTRA_DOCK_STATE_CAR: 9549 config = AudioSystem.FORCE_BT_CAR_DOCK; 9550 break; 9551 case Intent.EXTRA_DOCK_STATE_LE_DESK: 9552 config = AudioSystem.FORCE_ANALOG_DOCK; 9553 break; 9554 case Intent.EXTRA_DOCK_STATE_HE_DESK: 9555 config = AudioSystem.FORCE_DIGITAL_DOCK; 9556 break; 9557 case Intent.EXTRA_DOCK_STATE_UNDOCKED: 9558 default: 9559 config = AudioSystem.FORCE_NONE; 9560 } 9561 // Low end docks have a menu to enable or disable audio 9562 // (see mDockAudioMediaEnabled) 9563 if (!((dockState == Intent.EXTRA_DOCK_STATE_LE_DESK) 9564 || ((dockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) 9565 && (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK)))) { 9566 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, config, 9567 "ACTION_DOCK_EVENT intent"); 9568 } 9569 mDockState = dockState; 9570 } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED) 9571 || action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { 9572 mDeviceBroker.postReceiveBtEvent(intent); 9573 } else if (action.equals(Intent.ACTION_SCREEN_ON)) { 9574 if (mMonitorRotation) { 9575 RotationHelper.enable(); 9576 } 9577 AudioSystem.setParameters("screen_state=on"); 9578 } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { 9579 if (mMonitorRotation) { 9580 //reduce wakeups (save current) by only listening when display is on 9581 RotationHelper.disable(); 9582 } 9583 AudioSystem.setParameters("screen_state=off"); 9584 } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) { 9585 sendMsg(mAudioHandler, 9586 MSG_CONFIGURATION_CHANGED, 9587 SENDMSG_REPLACE, 9588 0, 9589 0, 9590 null, 0); 9591 } else if (action.equals(Intent.ACTION_USER_SWITCHED)) { 9592 if (mUserSwitchedReceived) { 9593 // attempt to stop music playback for background user except on first user 9594 // switch (i.e. first boot) 9595 mDeviceBroker.postBroadcastBecomingNoisy(); 9596 } 9597 mUserSwitchedReceived = true; 9598 // the current audio focus owner is no longer valid 9599 mMediaFocusControl.discardAudioFocusOwner(); 9600 9601 if (mSupportsMicPrivacyToggle) { 9602 mMicMuteFromPrivacyToggle = mSensorPrivacyManagerInternal 9603 .isSensorPrivacyEnabled(getCurrentUserId(), 9604 SensorPrivacyManager.Sensors.MICROPHONE); 9605 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); 9606 } 9607 9608 // load volume settings for new user 9609 readAudioSettings(true /*userSwitch*/); 9610 // preserve STREAM_MUSIC volume from one user to the next. 9611 sendMsg(mAudioHandler, 9612 MSG_SET_ALL_VOLUMES, 9613 SENDMSG_QUEUE, 9614 0, 9615 0, 9616 mStreamStates[AudioSystem.STREAM_MUSIC], 0); 9617 } else if (action.equals(Intent.ACTION_USER_BACKGROUND)) { 9618 // Disable audio recording for the background user/profile 9619 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 9620 if (userId >= 0) { 9621 // TODO Kill recording streams instead of killing processes holding permission 9622 UserInfo userInfo = UserManagerService.getInstance().getUserInfo(userId); 9623 killBackgroundUserProcessesWithRecordAudioPermission(userInfo); 9624 } 9625 try { 9626 UserManagerService.getInstance().setUserRestriction( 9627 UserManager.DISALLOW_RECORD_AUDIO, true, userId); 9628 } catch (IllegalArgumentException e) { 9629 Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e); 9630 } 9631 } else if (action.equals(Intent.ACTION_USER_FOREGROUND)) { 9632 // Enable audio recording for foreground user/profile 9633 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 9634 try { 9635 UserManagerService.getInstance().setUserRestriction( 9636 UserManager.DISALLOW_RECORD_AUDIO, false, userId); 9637 } catch (IllegalArgumentException e) { 9638 Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e); 9639 } 9640 } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) || 9641 action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) { 9642 handleAudioEffectBroadcast(context, intent); 9643 } else if (action.equals(Intent.ACTION_PACKAGES_SUSPENDED)) { 9644 final int[] suspendedUids = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST); 9645 final String[] suspendedPackages = 9646 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 9647 if (suspendedPackages == null || suspendedUids == null 9648 || suspendedPackages.length != suspendedUids.length) { 9649 return; 9650 } 9651 for (int i = 0; i < suspendedUids.length; i++) { 9652 if (!TextUtils.isEmpty(suspendedPackages[i])) { 9653 mMediaFocusControl.noFocusForSuspendedApp( 9654 suspendedPackages[i], suspendedUids[i]); 9655 } 9656 } 9657 } else if (action.equals(ACTION_CHECK_MUSIC_ACTIVE)) { 9658 mSoundDoseHelper.onCheckMusicActive(ACTION_CHECK_MUSIC_ACTIVE, 9659 mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)); 9660 } 9661 } 9662 } // end class AudioServiceBroadcastReceiver 9663 9664 private class AudioServiceUserRestrictionsListener implements UserRestrictionsListener { 9665 9666 @Override onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions)9667 public void onUserRestrictionsChanged(int userId, Bundle newRestrictions, 9668 Bundle prevRestrictions) { 9669 // Update mic mute state. 9670 { 9671 final boolean wasRestricted = 9672 prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE); 9673 final boolean isRestricted = 9674 newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE); 9675 if (wasRestricted != isRestricted) { 9676 mMicMuteFromRestrictions = isRestricted; 9677 setMicrophoneMuteNoCallerCheck(userId); 9678 } 9679 } 9680 9681 // Update speaker mute state. 9682 { 9683 final boolean wasRestricted = 9684 prevRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME) 9685 || prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE); 9686 final boolean isRestricted = 9687 newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME) 9688 || newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE); 9689 if (wasRestricted != isRestricted) { 9690 setMasterMuteInternalNoCallerCheck(isRestricted, /* flags =*/ 0, userId); 9691 } 9692 } 9693 } 9694 } // end class AudioServiceUserRestrictionsListener 9695 handleAudioEffectBroadcast(Context context, Intent intent)9696 private void handleAudioEffectBroadcast(Context context, Intent intent) { 9697 String target = intent.getPackage(); 9698 if (target != null) { 9699 Log.w(TAG, "effect broadcast already targeted to " + target); 9700 return; 9701 } 9702 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 9703 // TODO this should target a user-selected panel 9704 List<ResolveInfo> ril = context.getPackageManager().queryBroadcastReceivers( 9705 intent, 0 /* flags */); 9706 if (ril != null && ril.size() != 0) { 9707 ResolveInfo ri = ril.get(0); 9708 if (ri != null && ri.activityInfo != null && ri.activityInfo.packageName != null) { 9709 intent.setPackage(ri.activityInfo.packageName); 9710 context.sendBroadcastAsUser(intent, UserHandle.ALL); 9711 return; 9712 } 9713 } 9714 Log.w(TAG, "couldn't find receiver package for effect intent"); 9715 } 9716 killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser)9717 private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) { 9718 PackageManager pm = mContext.getPackageManager(); 9719 // Find the home activity of the user. It should not be killed to avoid expensive restart, 9720 // when the user switches back. For managed profiles, we should kill all recording apps 9721 ComponentName homeActivityName = null; 9722 if (!oldUser.isManagedProfile()) { 9723 homeActivityName = LocalServices.getService( 9724 ActivityTaskManagerInternal.class).getHomeActivityForUser(oldUser.id); 9725 } 9726 final String[] permissions = { Manifest.permission.RECORD_AUDIO }; 9727 List<PackageInfo> packages; 9728 try { 9729 packages = AppGlobals.getPackageManager() 9730 .getPackagesHoldingPermissions(permissions, 0, oldUser.id).getList(); 9731 } catch (RemoteException e) { 9732 throw new AndroidRuntimeException(e); 9733 } 9734 for (int j = packages.size() - 1; j >= 0; j--) { 9735 PackageInfo pkg = packages.get(j); 9736 // Skip system processes 9737 if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) { 9738 continue; 9739 } 9740 // Skip packages that have permission to interact across users 9741 if (pm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS, pkg.packageName) 9742 == PackageManager.PERMISSION_GRANTED) { 9743 continue; 9744 } 9745 if (homeActivityName != null 9746 && pkg.packageName.equals(homeActivityName.getPackageName()) 9747 && pkg.applicationInfo.isSystemApp()) { 9748 continue; 9749 } 9750 try { 9751 final int uid = pkg.applicationInfo.uid; 9752 ActivityManager.getService().killUid(UserHandle.getAppId(uid), 9753 UserHandle.getUserId(uid), 9754 "killBackgroundUserProcessesWithAudioRecordPermission"); 9755 } catch (RemoteException e) { 9756 Log.w(TAG, "Error calling killUid", e); 9757 } 9758 } 9759 } 9760 9761 9762 //========================================================================================== 9763 // Audio Focus 9764 //========================================================================================== 9765 /** 9766 * Returns whether a focus request is eligible to force ducking. 9767 * Will return true if: 9768 * - the AudioAttributes have a usage of USAGE_ASSISTANCE_ACCESSIBILITY, 9769 * - the focus request is AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 9770 * - the associated Bundle has KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING set to true, 9771 * - the uid of the requester is a known accessibility service or root. 9772 * @param aa AudioAttributes of the focus request 9773 * @param uid uid of the focus requester 9774 * @return true if ducking is to be forced 9775 */ forceFocusDuckingForAccessibility(@ullable AudioAttributes aa, int request, int uid)9776 private boolean forceFocusDuckingForAccessibility(@Nullable AudioAttributes aa, 9777 int request, int uid) { 9778 if (aa == null || aa.getUsage() != AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY 9779 || request != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) { 9780 return false; 9781 } 9782 final Bundle extraInfo = aa.getBundle(); 9783 if (extraInfo == null || 9784 !extraInfo.getBoolean(AudioFocusRequest.KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING)) { 9785 return false; 9786 } 9787 if (uid == 0) { 9788 return true; 9789 } 9790 synchronized (mAccessibilityServiceUidsLock) { 9791 if (mAccessibilityServiceUids != null) { 9792 int callingUid = Binder.getCallingUid(); 9793 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 9794 if (mAccessibilityServiceUids[i] == callingUid) { 9795 return true; 9796 } 9797 } 9798 } 9799 } 9800 return false; 9801 } 9802 isSupportedSystemUsage(@udioAttributes.AttributeUsage int usage)9803 private boolean isSupportedSystemUsage(@AudioAttributes.AttributeUsage int usage) { 9804 synchronized (mSupportedSystemUsagesLock) { 9805 for (int i = 0; i < mSupportedSystemUsages.length; i++) { 9806 if (mSupportedSystemUsages[i] == usage) { 9807 return true; 9808 } 9809 } 9810 return false; 9811 } 9812 } 9813 validateAudioAttributesUsage(@onNull AudioAttributes audioAttributes)9814 private void validateAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) { 9815 @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage(); 9816 if (AudioAttributes.isSystemUsage(usage)) { 9817 if ((usage == AudioAttributes.USAGE_CALL_ASSISTANT 9818 && (audioAttributes.getAllFlags() & AudioAttributes.FLAG_CALL_REDIRECTION) != 0 9819 && callerHasPermission(Manifest.permission.CALL_AUDIO_INTERCEPTION)) 9820 || callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)) { 9821 if (!isSupportedSystemUsage(usage)) { 9822 throw new IllegalArgumentException( 9823 "Unsupported usage " + AudioAttributes.usageToString(usage)); 9824 } 9825 } else { 9826 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission"); 9827 } 9828 } 9829 } 9830 isValidAudioAttributesUsage(@onNull AudioAttributes audioAttributes)9831 private boolean isValidAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) { 9832 @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage(); 9833 if (AudioAttributes.isSystemUsage(usage)) { 9834 return isSupportedSystemUsage(usage) 9835 && ((usage == AudioAttributes.USAGE_CALL_ASSISTANT 9836 && (audioAttributes.getAllFlags() 9837 & AudioAttributes.FLAG_CALL_REDIRECTION) != 0 9838 && callerHasPermission(Manifest.permission.CALL_AUDIO_INTERCEPTION)) 9839 || callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)); 9840 } 9841 return true; 9842 } 9843 requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk)9844 public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, 9845 IAudioFocusDispatcher fd, String clientId, String callingPackageName, 9846 String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk) { 9847 if ((flags & AudioManager.AUDIOFOCUS_FLAG_TEST) != 0) { 9848 throw new IllegalArgumentException("Invalid test flag"); 9849 } 9850 final int uid = Binder.getCallingUid(); 9851 MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus") 9852 .setUid(uid) 9853 //.putInt("durationHint", durationHint) 9854 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) 9855 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 9856 .set(MediaMetrics.Property.EVENT, "requestAudioFocus") 9857 .set(MediaMetrics.Property.FLAGS, flags); 9858 9859 // permission checks 9860 if (aa != null && !isValidAudioAttributesUsage(aa)) { 9861 final String reason = "Request using unsupported usage"; 9862 Log.w(TAG, reason); 9863 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 9864 .record(); 9865 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9866 } 9867 if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) { 9868 if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) { 9869 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 9870 android.Manifest.permission.MODIFY_PHONE_STATE)) { 9871 final String reason = "Invalid permission to (un)lock audio focus"; 9872 Log.e(TAG, reason, new Exception()); 9873 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 9874 .record(); 9875 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9876 } 9877 } else { 9878 // only a registered audio policy can be used to lock focus 9879 synchronized (mAudioPolicies) { 9880 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 9881 final String reason = 9882 "Invalid unregistered AudioPolicy to (un)lock audio focus"; 9883 Log.e(TAG, reason); 9884 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 9885 .record(); 9886 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9887 } 9888 } 9889 } 9890 } 9891 9892 if (callingPackageName == null || clientId == null || aa == null) { 9893 final String reason = "Invalid null parameter to request audio focus"; 9894 Log.e(TAG, reason); 9895 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 9896 .record(); 9897 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9898 } 9899 mmi.record(); 9900 return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd, 9901 clientId, callingPackageName, attributionTag, flags, sdk, 9902 forceFocusDuckingForAccessibility(aa, durationHint, uid), -1 /*testUid, ignored*/); 9903 } 9904 9905 /** 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)9906 public int requestAudioFocusForTest(AudioAttributes aa, int durationHint, IBinder cb, 9907 IAudioFocusDispatcher fd, String clientId, String callingPackageName, 9908 int flags, int fakeUid, int sdk) { 9909 if (!enforceQueryAudioStateForTest("focus request")) { 9910 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9911 } 9912 if (callingPackageName == null || clientId == null || aa == null) { 9913 final String reason = "Invalid null parameter to request audio focus"; 9914 Log.e(TAG, reason); 9915 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9916 } 9917 return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd, 9918 clientId, callingPackageName, null, flags, 9919 sdk, false /*forceDuck*/, fakeUid); 9920 } 9921 abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)9922 public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, 9923 String callingPackageName) { 9924 MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus") 9925 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) 9926 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 9927 .set(MediaMetrics.Property.EVENT, "abandonAudioFocus"); 9928 9929 if (aa != null && !isValidAudioAttributesUsage(aa)) { 9930 Log.w(TAG, "Request using unsupported usage."); 9931 mmi.set(MediaMetrics.Property.EARLY_RETURN, "unsupported usage").record(); 9932 9933 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9934 } 9935 mmi.record(); 9936 return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName); 9937 } 9938 9939 /** see {@link AudioManager#abandonAudioFocusForTest(AudioFocusRequest, String)} */ abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)9940 public int abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, 9941 AudioAttributes aa, String callingPackageName) { 9942 if (!enforceQueryAudioStateForTest("focus abandon")) { 9943 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9944 } 9945 return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName); 9946 } 9947 unregisterAudioFocusClient(String clientId)9948 public void unregisterAudioFocusClient(String clientId) { 9949 new MediaMetrics.Item(mMetricsId + "focus") 9950 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 9951 .set(MediaMetrics.Property.EVENT, "unregisterAudioFocusClient") 9952 .record(); 9953 mMediaFocusControl.unregisterAudioFocusClient(clientId); 9954 } 9955 getCurrentAudioFocus()9956 public int getCurrentAudioFocus() { 9957 return mMediaFocusControl.getCurrentAudioFocus(); 9958 } 9959 getFocusRampTimeMs(int focusGain, AudioAttributes attr)9960 public int getFocusRampTimeMs(int focusGain, AudioAttributes attr) { 9961 return mMediaFocusControl.getFocusRampTimeMs(focusGain, attr); 9962 } 9963 9964 /** only public for mocking/spying, do not call outside of AudioService */ 9965 @VisibleForTesting hasAudioFocusUsers()9966 public boolean hasAudioFocusUsers() { 9967 return mMediaFocusControl.hasAudioFocusUsers(); 9968 } 9969 9970 /** see {@link AudioManager#getFadeOutDurationOnFocusLossMillis(AudioAttributes)} */ getFadeOutDurationOnFocusLossMillis(AudioAttributes aa)9971 public long getFadeOutDurationOnFocusLossMillis(AudioAttributes aa) { 9972 if (!enforceQueryAudioStateForTest("fade out duration")) { 9973 return 0; 9974 } 9975 return mMediaFocusControl.getFadeOutDurationOnFocusLossMillis(aa); 9976 } 9977 enforceQueryAudioStateForTest(String mssg)9978 private boolean enforceQueryAudioStateForTest(String mssg) { 9979 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 9980 Manifest.permission.QUERY_AUDIO_STATE)) { 9981 final String reason = "Doesn't have QUERY_AUDIO_STATE permission for " 9982 + mssg + " test API"; 9983 Log.e(TAG, reason, new Exception()); 9984 return false; 9985 } 9986 return true; 9987 } 9988 9989 //========================================================================================== 9990 private final @NonNull SpatializerHelper mSpatializerHelper; 9991 /** 9992 * Initialized from property ro.audio.spatializer_enabled 9993 * Should only be 1 when the device ships with a Spatializer effect 9994 */ 9995 private final boolean mHasSpatializerEffect; 9996 /** 9997 * Default value for the spatial audio feature 9998 */ 9999 private static final boolean SPATIAL_AUDIO_ENABLED_DEFAULT = true; 10000 enforceModifyDefaultAudioEffectsPermission()10001 private void enforceModifyDefaultAudioEffectsPermission() { 10002 if (mContext.checkCallingOrSelfPermission( 10003 android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10004 != PackageManager.PERMISSION_GRANTED) { 10005 throw new SecurityException("Missing MODIFY_DEFAULT_AUDIO_EFFECTS permission"); 10006 } 10007 } 10008 10009 /** 10010 * Returns the immersive audio level that the platform is capable of 10011 * @see Spatializer#getImmersiveAudioLevel() 10012 */ getSpatializerImmersiveAudioLevel()10013 public int getSpatializerImmersiveAudioLevel() { 10014 return mSpatializerHelper.getCapableImmersiveAudioLevel(); 10015 } 10016 10017 /** @see Spatializer#isEnabled() */ isSpatializerEnabled()10018 public boolean isSpatializerEnabled() { 10019 return mSpatializerHelper.isEnabled(); 10020 } 10021 10022 /** @see Spatializer#isAvailable() */ isSpatializerAvailable()10023 public boolean isSpatializerAvailable() { 10024 return mSpatializerHelper.isAvailable(); 10025 } 10026 10027 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10028 /** @see Spatializer#isAvailableForDevice(AudioDeviceAttributes) */ isSpatializerAvailableForDevice(@onNull AudioDeviceAttributes device)10029 public boolean isSpatializerAvailableForDevice(@NonNull AudioDeviceAttributes device) { 10030 super.isSpatializerAvailableForDevice_enforcePermission(); 10031 10032 return mSpatializerHelper.isAvailableForDevice(Objects.requireNonNull(device)); 10033 } 10034 10035 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10036 /** @see Spatializer#hasHeadTracker(AudioDeviceAttributes) */ hasHeadTracker(@onNull AudioDeviceAttributes device)10037 public boolean hasHeadTracker(@NonNull AudioDeviceAttributes device) { 10038 super.hasHeadTracker_enforcePermission(); 10039 10040 return mSpatializerHelper.hasHeadTracker(Objects.requireNonNull(device)); 10041 } 10042 10043 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10044 /** @see Spatializer#setHeadTrackerEnabled(boolean, AudioDeviceAttributes) */ setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device)10045 public void setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device) { 10046 super.setHeadTrackerEnabled_enforcePermission(); 10047 10048 mSpatializerHelper.setHeadTrackerEnabled(enabled, Objects.requireNonNull(device)); 10049 } 10050 10051 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10052 /** @see Spatializer#isHeadTrackerEnabled(AudioDeviceAttributes) */ isHeadTrackerEnabled(@onNull AudioDeviceAttributes device)10053 public boolean isHeadTrackerEnabled(@NonNull AudioDeviceAttributes device) { 10054 super.isHeadTrackerEnabled_enforcePermission(); 10055 10056 return mSpatializerHelper.isHeadTrackerEnabled(Objects.requireNonNull(device)); 10057 } 10058 10059 /** @see Spatializer#isHeadTrackerAvailable() */ isHeadTrackerAvailable()10060 public boolean isHeadTrackerAvailable() { 10061 return mSpatializerHelper.isHeadTrackerAvailable(); 10062 } 10063 10064 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10065 /** @see Spatializer#setSpatializerEnabled(boolean) */ setSpatializerEnabled(boolean enabled)10066 public void setSpatializerEnabled(boolean enabled) { 10067 super.setSpatializerEnabled_enforcePermission(); 10068 10069 mSpatializerHelper.setFeatureEnabled(enabled); 10070 } 10071 10072 /** @see Spatializer#canBeSpatialized() */ canBeSpatialized( @onNull AudioAttributes attributes, @NonNull AudioFormat format)10073 public boolean canBeSpatialized( 10074 @NonNull AudioAttributes attributes, @NonNull AudioFormat format) { 10075 Objects.requireNonNull(attributes); 10076 Objects.requireNonNull(format); 10077 return mSpatializerHelper.canBeSpatialized(attributes, format); 10078 } 10079 10080 /** @see Spatializer.SpatializerInfoDispatcherStub */ registerSpatializerCallback( @onNull ISpatializerCallback cb)10081 public void registerSpatializerCallback( 10082 @NonNull ISpatializerCallback cb) { 10083 Objects.requireNonNull(cb); 10084 mSpatializerHelper.registerStateCallback(cb); 10085 } 10086 10087 /** @see Spatializer.SpatializerInfoDispatcherStub */ unregisterSpatializerCallback( @onNull ISpatializerCallback cb)10088 public void unregisterSpatializerCallback( 10089 @NonNull ISpatializerCallback cb) { 10090 Objects.requireNonNull(cb); 10091 mSpatializerHelper.unregisterStateCallback(cb); 10092 } 10093 10094 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10095 /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */ registerSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)10096 public void registerSpatializerHeadTrackingCallback( 10097 @NonNull ISpatializerHeadTrackingModeCallback cb) { 10098 super.registerSpatializerHeadTrackingCallback_enforcePermission(); 10099 10100 Objects.requireNonNull(cb); 10101 mSpatializerHelper.registerHeadTrackingModeCallback(cb); 10102 } 10103 10104 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10105 /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */ unregisterSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)10106 public void unregisterSpatializerHeadTrackingCallback( 10107 @NonNull ISpatializerHeadTrackingModeCallback cb) { 10108 super.unregisterSpatializerHeadTrackingCallback_enforcePermission(); 10109 10110 Objects.requireNonNull(cb); 10111 mSpatializerHelper.unregisterHeadTrackingModeCallback(cb); 10112 } 10113 10114 /** @see Spatializer.SpatializerHeadTrackerAvailableDispatcherStub */ registerSpatializerHeadTrackerAvailableCallback( @onNull ISpatializerHeadTrackerAvailableCallback cb, boolean register)10115 public void registerSpatializerHeadTrackerAvailableCallback( 10116 @NonNull ISpatializerHeadTrackerAvailableCallback cb, boolean register) { 10117 Objects.requireNonNull(cb); 10118 mSpatializerHelper.registerHeadTrackerAvailableCallback(cb, register); 10119 } 10120 10121 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10122 /** @see Spatializer#setOnHeadToSoundstagePoseUpdatedListener */ registerHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)10123 public void registerHeadToSoundstagePoseCallback( 10124 @NonNull ISpatializerHeadToSoundStagePoseCallback cb) { 10125 super.registerHeadToSoundstagePoseCallback_enforcePermission(); 10126 10127 Objects.requireNonNull(cb); 10128 mSpatializerHelper.registerHeadToSoundstagePoseCallback(cb); 10129 } 10130 10131 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10132 /** @see Spatializer#clearOnHeadToSoundstagePoseUpdatedListener */ unregisterHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)10133 public void unregisterHeadToSoundstagePoseCallback( 10134 @NonNull ISpatializerHeadToSoundStagePoseCallback cb) { 10135 super.unregisterHeadToSoundstagePoseCallback_enforcePermission(); 10136 10137 Objects.requireNonNull(cb); 10138 mSpatializerHelper.unregisterHeadToSoundstagePoseCallback(cb); 10139 } 10140 10141 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10142 /** @see Spatializer#getSpatializerCompatibleAudioDevices() */ getSpatializerCompatibleAudioDevices()10143 public @NonNull List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices() { 10144 super.getSpatializerCompatibleAudioDevices_enforcePermission(); 10145 10146 return mSpatializerHelper.getCompatibleAudioDevices(); 10147 } 10148 10149 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10150 /** @see Spatializer#addSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */ addSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)10151 public void addSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { 10152 super.addSpatializerCompatibleAudioDevice_enforcePermission(); 10153 10154 Objects.requireNonNull(ada); 10155 mSpatializerHelper.addCompatibleAudioDevice(ada); 10156 } 10157 10158 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10159 /** @see Spatializer#removeSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */ removeSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)10160 public void removeSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { 10161 super.removeSpatializerCompatibleAudioDevice_enforcePermission(); 10162 10163 Objects.requireNonNull(ada); 10164 mSpatializerHelper.removeCompatibleAudioDevice(ada); 10165 } 10166 10167 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10168 /** @see Spatializer#getSupportedHeadTrackingModes() */ getSupportedHeadTrackingModes()10169 public int[] getSupportedHeadTrackingModes() { 10170 super.getSupportedHeadTrackingModes_enforcePermission(); 10171 10172 return mSpatializerHelper.getSupportedHeadTrackingModes(); 10173 } 10174 10175 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10176 /** @see Spatializer#getHeadTrackingMode() */ getActualHeadTrackingMode()10177 public int getActualHeadTrackingMode() { 10178 super.getActualHeadTrackingMode_enforcePermission(); 10179 10180 return mSpatializerHelper.getActualHeadTrackingMode(); 10181 } 10182 10183 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10184 /** @see Spatializer#getDesiredHeadTrackingMode() */ getDesiredHeadTrackingMode()10185 public int getDesiredHeadTrackingMode() { 10186 super.getDesiredHeadTrackingMode_enforcePermission(); 10187 10188 return mSpatializerHelper.getDesiredHeadTrackingMode(); 10189 } 10190 10191 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10192 /** @see Spatializer#setGlobalTransform */ setSpatializerGlobalTransform(@onNull float[] transform)10193 public void setSpatializerGlobalTransform(@NonNull float[] transform) { 10194 super.setSpatializerGlobalTransform_enforcePermission(); 10195 10196 Objects.requireNonNull(transform); 10197 mSpatializerHelper.setGlobalTransform(transform); 10198 } 10199 10200 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10201 /** @see Spatializer#recenterHeadTracker() */ recenterHeadTracker()10202 public void recenterHeadTracker() { 10203 super.recenterHeadTracker_enforcePermission(); 10204 10205 mSpatializerHelper.recenterHeadTracker(); 10206 } 10207 10208 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10209 /** @see Spatializer#setDesiredHeadTrackingMode */ setDesiredHeadTrackingMode(@patializer.HeadTrackingModeSet int mode)10210 public void setDesiredHeadTrackingMode(@Spatializer.HeadTrackingModeSet int mode) { 10211 super.setDesiredHeadTrackingMode_enforcePermission(); 10212 10213 switch(mode) { 10214 case Spatializer.HEAD_TRACKING_MODE_DISABLED: 10215 case Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD: 10216 case Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE: 10217 break; 10218 default: 10219 return; 10220 } 10221 mSpatializerHelper.setDesiredHeadTrackingMode(mode); 10222 } 10223 10224 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10225 /** @see Spatializer#setEffectParameter */ setSpatializerParameter(int key, @NonNull byte[] value)10226 public void setSpatializerParameter(int key, @NonNull byte[] value) { 10227 super.setSpatializerParameter_enforcePermission(); 10228 10229 Objects.requireNonNull(value); 10230 mSpatializerHelper.setEffectParameter(key, value); 10231 } 10232 10233 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10234 /** @see Spatializer#getEffectParameter */ getSpatializerParameter(int key, @NonNull byte[] value)10235 public void getSpatializerParameter(int key, @NonNull byte[] value) { 10236 super.getSpatializerParameter_enforcePermission(); 10237 10238 Objects.requireNonNull(value); 10239 mSpatializerHelper.getEffectParameter(key, value); 10240 } 10241 10242 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10243 /** @see Spatializer#getOutput */ getSpatializerOutput()10244 public int getSpatializerOutput() { 10245 super.getSpatializerOutput_enforcePermission(); 10246 10247 return mSpatializerHelper.getOutput(); 10248 } 10249 10250 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10251 /** @see Spatializer#setOnSpatializerOutputChangedListener */ registerSpatializerOutputCallback(ISpatializerOutputCallback cb)10252 public void registerSpatializerOutputCallback(ISpatializerOutputCallback cb) { 10253 super.registerSpatializerOutputCallback_enforcePermission(); 10254 10255 Objects.requireNonNull(cb); 10256 mSpatializerHelper.registerSpatializerOutputCallback(cb); 10257 } 10258 10259 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 10260 /** @see Spatializer#clearOnSpatializerOutputChangedListener */ unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb)10261 public void unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb) { 10262 super.unregisterSpatializerOutputCallback_enforcePermission(); 10263 10264 Objects.requireNonNull(cb); 10265 mSpatializerHelper.unregisterSpatializerOutputCallback(cb); 10266 } 10267 10268 /** 10269 * post a message to schedule init/release of head tracking sensors 10270 * whether to initialize or release sensors is based on the state of spatializer 10271 */ postInitSpatializerHeadTrackingSensors()10272 void postInitSpatializerHeadTrackingSensors() { 10273 sendMsg(mAudioHandler, 10274 MSG_INIT_HEADTRACKING_SENSORS, 10275 SENDMSG_REPLACE, 10276 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0); 10277 } 10278 10279 /** 10280 * post a message to schedule a reset of the spatializer state 10281 */ postResetSpatializer()10282 void postResetSpatializer() { 10283 sendMsg(mAudioHandler, 10284 MSG_RESET_SPATIALIZER, 10285 SENDMSG_REPLACE, 10286 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0); 10287 } 10288 onInitAdiDeviceStates()10289 void onInitAdiDeviceStates() { 10290 mDeviceBroker.onReadAudioDeviceSettings(); 10291 mSoundDoseHelper.initCachedAudioDeviceCategories( 10292 mDeviceBroker.getImmutableDeviceInventory()); 10293 } 10294 onInitSpatializer()10295 void onInitSpatializer() { 10296 mSpatializerHelper.init(/*effectExpected*/ mHasSpatializerEffect); 10297 mSpatializerHelper.setFeatureEnabled(mHasSpatializerEffect); 10298 } 10299 10300 //========================================================================================== 10301 10302 // camera sound is forced if any of the resources corresponding to one active SIM 10303 // demands it. readCameraSoundForced()10304 private boolean readCameraSoundForced() { 10305 if (SystemProperties.getBoolean("audio.camerasound.force", false) 10306 || mContext.getResources().getBoolean( 10307 com.android.internal.R.bool.config_camera_sound_forced)) { 10308 return true; 10309 } 10310 10311 SubscriptionManager subscriptionManager = mContext.getSystemService( 10312 SubscriptionManager.class); 10313 if (subscriptionManager == null) { 10314 Log.e(TAG, "readCameraSoundForced cannot create SubscriptionManager!"); 10315 return false; 10316 } 10317 int[] subscriptionIds = subscriptionManager.getActiveSubscriptionIdList(false); 10318 for (int subId : subscriptionIds) { 10319 if (SubscriptionManager.getResourcesForSubId(mContext, subId).getBoolean( 10320 com.android.internal.R.bool.config_camera_sound_forced)) { 10321 return true; 10322 } 10323 } 10324 return false; 10325 } 10326 10327 //========================================================================================== 10328 private final Object mMuteAwaitConnectionLock = new Object(); 10329 10330 /** 10331 * The device that is expected to be connected soon, and causes players to be muted until 10332 * its connection, or it times out. 10333 * Null when no active muting command, or it has timed out. 10334 */ 10335 @GuardedBy("mMuteAwaitConnectionLock") 10336 private AudioDeviceAttributes mMutingExpectedDevice; 10337 @GuardedBy("mMuteAwaitConnectionLock") 10338 private @Nullable int[] mMutedUsagesAwaitingConnection; 10339 10340 /** @see AudioManager#muteAwaitConnection */ 10341 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection muteAwaitConnection(@onNull int[] usages, @NonNull AudioDeviceAttributes device, long timeOutMs)10342 public void muteAwaitConnection(@NonNull int[] usages, 10343 @NonNull AudioDeviceAttributes device, long timeOutMs) { 10344 Objects.requireNonNull(usages); 10345 Objects.requireNonNull(device); 10346 enforceModifyAudioRoutingPermission(); 10347 if (timeOutMs <= 0 || usages.length == 0) { 10348 throw new IllegalArgumentException("Invalid timeOutMs/usagesToMute"); 10349 } 10350 Log.i(TAG, "muteAwaitConnection dev:" + device + " timeOutMs:" + timeOutMs 10351 + " usages:" + Arrays.toString(usages)); 10352 10353 if (mDeviceBroker.isDeviceConnected(device)) { 10354 // not throwing an exception as there could be a race between a connection (server-side, 10355 // notification of connection in flight) and a mute operation (client-side) 10356 Log.i(TAG, "muteAwaitConnection ignored, device (" + device + ") already connected"); 10357 return; 10358 } 10359 synchronized (mMuteAwaitConnectionLock) { 10360 if (mMutingExpectedDevice != null) { 10361 Log.e(TAG, "muteAwaitConnection ignored, another in progress for device:" 10362 + mMutingExpectedDevice); 10363 throw new IllegalStateException("muteAwaitConnection already in progress"); 10364 } 10365 mMutingExpectedDevice = device; 10366 mMutedUsagesAwaitingConnection = usages; 10367 mPlaybackMonitor.muteAwaitConnection(usages, device, timeOutMs); 10368 } 10369 dispatchMuteAwaitConnection(cb -> { try { 10370 cb.dispatchOnMutedUntilConnection(device, usages); } catch (RemoteException e) { } }); 10371 } 10372 10373 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 10374 /** @see AudioManager#getMutingExpectedDevice */ getMutingExpectedDevice()10375 public @Nullable AudioDeviceAttributes getMutingExpectedDevice() { 10376 super.getMutingExpectedDevice_enforcePermission(); 10377 10378 synchronized (mMuteAwaitConnectionLock) { 10379 return mMutingExpectedDevice; 10380 } 10381 } 10382 10383 /** @see AudioManager#cancelMuteAwaitConnection */ 10384 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection cancelMuteAwaitConnection(@onNull AudioDeviceAttributes device)10385 public void cancelMuteAwaitConnection(@NonNull AudioDeviceAttributes device) { 10386 Objects.requireNonNull(device); 10387 enforceModifyAudioRoutingPermission(); 10388 Log.i(TAG, "cancelMuteAwaitConnection for device:" + device); 10389 final int[] mutedUsages; 10390 synchronized (mMuteAwaitConnectionLock) { 10391 if (mMutingExpectedDevice == null) { 10392 // not throwing an exception as there could be a race between a timeout 10393 // (server-side) and a cancel operation (client-side) 10394 Log.i(TAG, "cancelMuteAwaitConnection ignored, no expected device"); 10395 return; 10396 } 10397 if (!device.equalTypeAddress(mMutingExpectedDevice)) { 10398 Log.e(TAG, "cancelMuteAwaitConnection ignored, got " + device 10399 + "] but expected device is" + mMutingExpectedDevice); 10400 throw new IllegalStateException("cancelMuteAwaitConnection for wrong device"); 10401 } 10402 mutedUsages = mMutedUsagesAwaitingConnection; 10403 mMutingExpectedDevice = null; 10404 mMutedUsagesAwaitingConnection = null; 10405 mPlaybackMonitor.cancelMuteAwaitConnection("cancelMuteAwaitConnection dev:" + device); 10406 } 10407 dispatchMuteAwaitConnection(cb -> { try { cb.dispatchOnUnmutedEvent( 10408 AudioManager.MuteAwaitConnectionCallback.EVENT_CANCEL, device, mutedUsages); 10409 } catch (RemoteException e) { } }); 10410 } 10411 10412 final RemoteCallbackList<IMuteAwaitConnectionCallback> mMuteAwaitConnectionDispatchers = 10413 new RemoteCallbackList<IMuteAwaitConnectionCallback>(); 10414 10415 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 10416 /** @see AudioManager#registerMuteAwaitConnectionCallback */ registerMuteAwaitConnectionDispatcher(@onNull IMuteAwaitConnectionCallback cb, boolean register)10417 public void registerMuteAwaitConnectionDispatcher(@NonNull IMuteAwaitConnectionCallback cb, 10418 boolean register) { 10419 super.registerMuteAwaitConnectionDispatcher_enforcePermission(); 10420 10421 if (register) { 10422 mMuteAwaitConnectionDispatchers.register(cb); 10423 } else { 10424 mMuteAwaitConnectionDispatchers.unregister(cb); 10425 } 10426 } 10427 10428 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection checkMuteAwaitConnection()10429 void checkMuteAwaitConnection() { 10430 final AudioDeviceAttributes device; 10431 final int[] mutedUsages; 10432 synchronized (mMuteAwaitConnectionLock) { 10433 if (mMutingExpectedDevice == null) { 10434 return; 10435 } 10436 device = mMutingExpectedDevice; 10437 mutedUsages = mMutedUsagesAwaitingConnection; 10438 if (!mDeviceBroker.isDeviceConnected(device)) { 10439 return; 10440 } 10441 mMutingExpectedDevice = null; 10442 mMutedUsagesAwaitingConnection = null; 10443 mPlaybackMonitor.cancelMuteAwaitConnection( 10444 "checkMuteAwaitConnection device " + device + " connected, unmuting"); 10445 } 10446 dispatchMuteAwaitConnection(cb -> { try { cb.dispatchOnUnmutedEvent( 10447 AudioManager.MuteAwaitConnectionCallback.EVENT_CONNECTION, device, mutedUsages); 10448 } catch (RemoteException e) { } }); 10449 } 10450 10451 /** 10452 * Called by PlaybackActivityMonitor when the timeout hit for the mute on device connection 10453 */ 10454 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection onMuteAwaitConnectionTimeout(@onNull AudioDeviceAttributes timedOutDevice)10455 void onMuteAwaitConnectionTimeout(@NonNull AudioDeviceAttributes timedOutDevice) { 10456 final int[] mutedUsages; 10457 synchronized (mMuteAwaitConnectionLock) { 10458 if (!timedOutDevice.equals(mMutingExpectedDevice)) { 10459 return; 10460 } 10461 Log.i(TAG, "muteAwaitConnection timeout, clearing expected device " 10462 + mMutingExpectedDevice); 10463 mutedUsages = mMutedUsagesAwaitingConnection; 10464 mMutingExpectedDevice = null; 10465 mMutedUsagesAwaitingConnection = null; 10466 } 10467 dispatchMuteAwaitConnection(cb -> { try { 10468 cb.dispatchOnUnmutedEvent( 10469 AudioManager.MuteAwaitConnectionCallback.EVENT_TIMEOUT, 10470 timedOutDevice, mutedUsages); 10471 } catch (RemoteException e) { } }); 10472 } 10473 dispatchMuteAwaitConnection( java.util.function.Consumer<IMuteAwaitConnectionCallback> callback)10474 private void dispatchMuteAwaitConnection( 10475 java.util.function.Consumer<IMuteAwaitConnectionCallback> callback) { 10476 final int nbDispatchers = mMuteAwaitConnectionDispatchers.beginBroadcast(); 10477 // lazy initialization as errors unlikely 10478 ArrayList<IMuteAwaitConnectionCallback> errorList = null; 10479 for (int i = 0; i < nbDispatchers; i++) { 10480 try { 10481 callback.accept(mMuteAwaitConnectionDispatchers.getBroadcastItem(i)); 10482 } catch (Exception e) { 10483 if (errorList == null) { 10484 errorList = new ArrayList<>(1); 10485 } 10486 errorList.add(mMuteAwaitConnectionDispatchers.getBroadcastItem(i)); 10487 } 10488 } 10489 if (errorList != null) { 10490 for (IMuteAwaitConnectionCallback errorItem : errorList) { 10491 mMuteAwaitConnectionDispatchers.unregister(errorItem); 10492 } 10493 } 10494 mMuteAwaitConnectionDispatchers.finishBroadcast(); 10495 } 10496 10497 final RemoteCallbackList<IDeviceVolumeBehaviorDispatcher> mDeviceVolumeBehaviorDispatchers = 10498 new RemoteCallbackList<IDeviceVolumeBehaviorDispatcher>(); 10499 10500 /** 10501 * @see AudioDeviceVolumeManager#addOnDeviceVolumeBehaviorChangedListener and 10502 * AudioDeviceVolumeManager#removeOnDeviceVolumeBehaviorChangedListener 10503 */ registerDeviceVolumeBehaviorDispatcher(boolean register, @NonNull IDeviceVolumeBehaviorDispatcher dispatcher)10504 public void registerDeviceVolumeBehaviorDispatcher(boolean register, 10505 @NonNull IDeviceVolumeBehaviorDispatcher dispatcher) { 10506 enforceQueryStateOrModifyRoutingPermission(); 10507 Objects.requireNonNull(dispatcher); 10508 if (register) { 10509 mDeviceVolumeBehaviorDispatchers.register(dispatcher); 10510 } else { 10511 mDeviceVolumeBehaviorDispatchers.unregister(dispatcher); 10512 } 10513 } 10514 dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior)10515 private void dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior) { 10516 final int dispatchers = mDeviceVolumeBehaviorDispatchers.beginBroadcast(); 10517 for (int i = 0; i < dispatchers; i++) { 10518 try { 10519 mDeviceVolumeBehaviorDispatchers.getBroadcastItem(i) 10520 .dispatchDeviceVolumeBehaviorChanged(device, volumeBehavior); 10521 } catch (RemoteException e) { 10522 } 10523 } 10524 mDeviceVolumeBehaviorDispatchers.finishBroadcast(); 10525 } 10526 10527 //========================================================================================== 10528 // Device orientation 10529 //========================================================================================== 10530 /** 10531 * Handles device configuration changes that may map to a change in rotation. 10532 * Monitoring rotation is optional, and is defined by the definition and value 10533 * of the "ro.audio.monitorRotation" system property. 10534 */ onConfigurationChanged()10535 private void onConfigurationChanged() { 10536 try { 10537 // reading new configuration "safely" (i.e. under try catch) in case anything 10538 // goes wrong. 10539 Configuration config = mContext.getResources().getConfiguration(); 10540 mSoundDoseHelper.configureSafeMedia(/*forced*/false, TAG); 10541 10542 boolean cameraSoundForced = readCameraSoundForced(); 10543 synchronized (mSettingsLock) { 10544 final boolean cameraSoundForcedChanged = (cameraSoundForced != mCameraSoundForced); 10545 mCameraSoundForced = cameraSoundForced; 10546 if (cameraSoundForcedChanged) { 10547 if (!mIsSingleVolume) { 10548 synchronized (VolumeStreamState.class) { 10549 VolumeStreamState s = mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED]; 10550 if (cameraSoundForced) { 10551 s.setAllIndexesToMax(); 10552 mRingerModeAffectedStreams &= 10553 ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 10554 } else { 10555 s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM], TAG); 10556 mRingerModeAffectedStreams |= 10557 (1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 10558 } 10559 } 10560 // take new state into account for streams muted by ringer mode 10561 setRingerModeInt(getRingerModeInternal(), false); 10562 } 10563 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, 10564 cameraSoundForced ? 10565 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE, 10566 "onConfigurationChanged"); 10567 sendMsg(mAudioHandler, 10568 MSG_SET_ALL_VOLUMES, 10569 SENDMSG_QUEUE, 10570 0, 10571 0, 10572 mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED], 0); 10573 10574 } 10575 } 10576 mVolumeController.setLayoutDirection(config.getLayoutDirection()); 10577 } catch (Exception e) { 10578 Log.e(TAG, "Error handling configuration change: ", e); 10579 } 10580 } 10581 10582 @Override setRingtonePlayer(IRingtonePlayer player)10583 public void setRingtonePlayer(IRingtonePlayer player) { 10584 mContext.enforceCallingOrSelfPermission(REMOTE_AUDIO_PLAYBACK, null); 10585 mRingtonePlayer = player; 10586 } 10587 10588 @Override getRingtonePlayer()10589 public IRingtonePlayer getRingtonePlayer() { 10590 return mRingtonePlayer; 10591 } 10592 10593 @Override startWatchingRoutes(IAudioRoutesObserver observer)10594 public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) { 10595 return mDeviceBroker.startWatchingRoutes(observer); 10596 } 10597 10598 @Override disableSafeMediaVolume(String callingPackage)10599 public void disableSafeMediaVolume(String callingPackage) { 10600 enforceVolumeController("disable the safe media volume"); 10601 mSoundDoseHelper.disableSafeMediaVolume(callingPackage); 10602 } 10603 10604 @Override lowerVolumeToRs1(String callingPackage)10605 public void lowerVolumeToRs1(String callingPackage) { 10606 enforceVolumeController("lowerVolumeToRs1"); 10607 postLowerVolumeToRs1(); 10608 } 10609 postLowerVolumeToRs1()10610 /*package*/ void postLowerVolumeToRs1() { 10611 sendMsg(mAudioHandler, MSG_LOWER_VOLUME_TO_RS1, SENDMSG_QUEUE, 10612 // no params, no delay 10613 0, 0, null, 0); 10614 } 10615 10616 /** 10617 * Called when handling MSG_LOWER_VOLUME_TO_RS1 10618 */ onLowerVolumeToRs1()10619 private void onLowerVolumeToRs1() { 10620 final ArrayList<AudioDeviceAttributes> devices = getDevicesForAttributesInt( 10621 new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(), true); 10622 final int nativeDeviceType; 10623 final AudioDeviceAttributes ada; 10624 if (!devices.isEmpty()) { 10625 ada = devices.get(0); 10626 nativeDeviceType = ada.getInternalType(); 10627 } else { 10628 nativeDeviceType = AudioSystem.DEVICE_OUT_USB_HEADSET; 10629 ada = new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_USB_HEADSET, ""); 10630 } 10631 final int index = mSoundDoseHelper.safeMediaVolumeIndex(nativeDeviceType); 10632 setStreamVolumeWithAttributionInt(STREAM_MUSIC, index, /*flags*/ 0, ada, 10633 "com.android.server.audio", "AudioService"); 10634 } 10635 10636 @Override 10637 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) getOutputRs2UpperBound()10638 public float getOutputRs2UpperBound() { 10639 super.getOutputRs2UpperBound_enforcePermission(); 10640 return mSoundDoseHelper.getOutputRs2UpperBound(); 10641 } 10642 10643 @Override 10644 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setOutputRs2UpperBound(float rs2Value)10645 public void setOutputRs2UpperBound(float rs2Value) { 10646 super.setOutputRs2UpperBound_enforcePermission(); 10647 mSoundDoseHelper.setOutputRs2UpperBound(rs2Value); 10648 } 10649 10650 @Override 10651 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) getCsd()10652 public float getCsd() { 10653 super.getCsd_enforcePermission(); 10654 return mSoundDoseHelper.getCsd(); 10655 } 10656 10657 @Override 10658 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setCsd(float csd)10659 public void setCsd(float csd) { 10660 super.setCsd_enforcePermission(); 10661 if (csd < 0.0f) { 10662 mSoundDoseHelper.resetCsdTimeouts(); 10663 } else { 10664 mSoundDoseHelper.setCsd(csd); 10665 } 10666 } 10667 10668 @Override 10669 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) forceUseFrameworkMel(boolean useFrameworkMel)10670 public void forceUseFrameworkMel(boolean useFrameworkMel) { 10671 super.forceUseFrameworkMel_enforcePermission(); 10672 mSoundDoseHelper.forceUseFrameworkMel(useFrameworkMel); 10673 } 10674 10675 @Override 10676 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices)10677 public void forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices) { 10678 super.forceComputeCsdOnAllDevices_enforcePermission(); 10679 mSoundDoseHelper.forceComputeCsdOnAllDevices(computeCsdOnAllDevices); 10680 } 10681 10682 @Override 10683 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isCsdEnabled()10684 public boolean isCsdEnabled() { 10685 super.isCsdEnabled_enforcePermission(); 10686 return mSoundDoseHelper.isCsdEnabled(); 10687 } 10688 10689 @Override 10690 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isCsdAsAFeatureAvailable()10691 public boolean isCsdAsAFeatureAvailable() { 10692 super.isCsdAsAFeatureAvailable_enforcePermission(); 10693 return mSoundDoseHelper.isCsdAsAFeatureAvailable(); 10694 } 10695 10696 @Override 10697 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isCsdAsAFeatureEnabled()10698 public boolean isCsdAsAFeatureEnabled() { 10699 super.isCsdAsAFeatureEnabled_enforcePermission(); 10700 return mSoundDoseHelper.isCsdAsAFeatureEnabled(); 10701 } 10702 10703 @Override 10704 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setCsdAsAFeatureEnabled(boolean csdToggleValue)10705 public void setCsdAsAFeatureEnabled(boolean csdToggleValue) { 10706 super.setCsdAsAFeatureEnabled_enforcePermission(); 10707 mSoundDoseHelper.setCsdAsAFeatureEnabled(csdToggleValue); 10708 } 10709 10710 @Override 10711 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setBluetoothAudioDeviceCategory(@onNull String address, boolean isBle, @AudioDeviceCategory int btAudioDeviceCategory)10712 public void setBluetoothAudioDeviceCategory(@NonNull String address, boolean isBle, 10713 @AudioDeviceCategory int btAudioDeviceCategory) { 10714 super.setBluetoothAudioDeviceCategory_enforcePermission(); 10715 10716 final String addr = Objects.requireNonNull(address); 10717 10718 AdiDeviceState deviceState = mDeviceBroker.findBtDeviceStateForAddress(addr, isBle); 10719 10720 int internalType = !isBle ? DEVICE_OUT_BLUETOOTH_A2DP 10721 : ((btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES) 10722 ? DEVICE_OUT_BLE_HEADSET : DEVICE_OUT_BLE_SPEAKER); 10723 int deviceType = !isBle ? TYPE_BLUETOOTH_A2DP 10724 : ((btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES) ? TYPE_BLE_HEADSET 10725 : TYPE_BLE_SPEAKER); 10726 10727 if (deviceState == null) { 10728 deviceState = new AdiDeviceState(deviceType, internalType, addr); 10729 } 10730 10731 deviceState.setAudioDeviceCategory(btAudioDeviceCategory); 10732 10733 mDeviceBroker.addOrUpdateBtAudioDeviceCategoryInInventory(deviceState); 10734 mDeviceBroker.persistAudioDeviceSettings(); 10735 10736 mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes()); 10737 mSoundDoseHelper.setAudioDeviceCategory(addr, internalType, 10738 btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES); 10739 } 10740 10741 @Override 10742 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) 10743 @AudioDeviceCategory getBluetoothAudioDeviceCategory(@onNull String address, boolean isBle)10744 public int getBluetoothAudioDeviceCategory(@NonNull String address, boolean isBle) { 10745 super.getBluetoothAudioDeviceCategory_enforcePermission(); 10746 10747 final AdiDeviceState deviceState = mDeviceBroker.findBtDeviceStateForAddress( 10748 Objects.requireNonNull(address), isBle); 10749 if (deviceState == null) { 10750 return AUDIO_DEVICE_CATEGORY_UNKNOWN; 10751 } 10752 10753 return deviceState.getAudioDeviceCategory(); 10754 } 10755 10756 //========================================================================================== 10757 // Hdmi CEC: 10758 // - System audio mode: 10759 // If Hdmi Cec's system audio mode is on, audio service should send the volume change 10760 // to HdmiControlService so that the audio receiver can handle it. 10761 // - CEC sink: 10762 // OUT_HDMI becomes a "full volume device", i.e. output is always at maximum level 10763 // and volume changes won't be taken into account on this device. Volume adjustments 10764 // are transformed into key events for the HDMI playback client. 10765 //========================================================================================== 10766 10767 @GuardedBy("mHdmiClientLock") updateHdmiCecSinkLocked(boolean hdmiCecSink)10768 private void updateHdmiCecSinkLocked(boolean hdmiCecSink) { 10769 if (!hasDeviceVolumeBehavior(AudioSystem.DEVICE_OUT_HDMI)) { 10770 if (hdmiCecSink) { 10771 if (DEBUG_VOL) { 10772 Log.d(TAG, "CEC sink: setting HDMI as full vol device"); 10773 } 10774 setDeviceVolumeBehaviorInternal( 10775 new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""), 10776 AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL, 10777 "AudioService.updateHdmiCecSinkLocked()"); 10778 } else { 10779 if (DEBUG_VOL) { 10780 Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device"); 10781 } 10782 // Android TV devices without CEC service apply software volume on 10783 // HDMI output 10784 setDeviceVolumeBehaviorInternal( 10785 new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""), 10786 AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE, 10787 "AudioService.updateHdmiCecSinkLocked()"); 10788 } 10789 postUpdateVolumeStatesForAudioDevice(AudioSystem.DEVICE_OUT_HDMI, 10790 "HdmiPlaybackClient.DisplayStatusCallback"); 10791 } 10792 } 10793 10794 private class MyHdmiControlStatusChangeListenerCallback 10795 implements HdmiControlManager.HdmiControlStatusChangeListener { onStatusChange(@dmiControlManager.HdmiCecControl int isCecEnabled, boolean isCecAvailable)10796 public void onStatusChange(@HdmiControlManager.HdmiCecControl int isCecEnabled, 10797 boolean isCecAvailable) { 10798 synchronized (mHdmiClientLock) { 10799 if (mHdmiManager == null) return; 10800 boolean cecEnabled = isCecEnabled == HdmiControlManager.HDMI_CEC_CONTROL_ENABLED; 10801 updateHdmiCecSinkLocked(cecEnabled ? isCecAvailable : false); 10802 } 10803 } 10804 }; 10805 10806 private class MyHdmiCecVolumeControlFeatureListener 10807 implements HdmiControlManager.HdmiCecVolumeControlFeatureListener { onHdmiCecVolumeControlFeature( @dmiControlManager.VolumeControl int hdmiCecVolumeControl)10808 public void onHdmiCecVolumeControlFeature( 10809 @HdmiControlManager.VolumeControl int hdmiCecVolumeControl) { 10810 synchronized (mHdmiClientLock) { 10811 if (mHdmiManager == null) return; 10812 mHdmiCecVolumeControlEnabled = 10813 hdmiCecVolumeControl == HdmiControlManager.VOLUME_CONTROL_ENABLED; 10814 } 10815 } 10816 }; 10817 10818 private final Object mHdmiClientLock = new Object(); 10819 10820 // If HDMI-CEC system audio is supported 10821 // Note that for CEC volume commands mHdmiCecVolumeControlEnabled will play a role on volume 10822 // commands 10823 private boolean mHdmiSystemAudioSupported = false; 10824 // Set only when device is tv. 10825 @GuardedBy("mHdmiClientLock") 10826 private HdmiTvClient mHdmiTvClient; 10827 // true if the device has system feature PackageManager.FEATURE_LEANBACK. 10828 // cached HdmiControlManager interface 10829 @GuardedBy("mHdmiClientLock") 10830 private HdmiControlManager mHdmiManager; 10831 // Set only when device is a set-top box. 10832 @GuardedBy("mHdmiClientLock") 10833 private HdmiPlaybackClient mHdmiPlaybackClient; 10834 // Set only when device is an audio system. 10835 @GuardedBy("mHdmiClientLock") 10836 private HdmiAudioSystemClient mHdmiAudioSystemClient; 10837 // True when volume control over HDMI CEC is used when CEC is enabled (meaningless otherwise) 10838 @GuardedBy("mHdmiClientLock") 10839 private boolean mHdmiCecVolumeControlEnabled; 10840 10841 private MyHdmiControlStatusChangeListenerCallback mHdmiControlStatusChangeListenerCallback = 10842 new MyHdmiControlStatusChangeListenerCallback(); 10843 10844 private MyHdmiCecVolumeControlFeatureListener mMyHdmiCecVolumeControlFeatureListener = 10845 new MyHdmiCecVolumeControlFeatureListener(); 10846 10847 @Override setHdmiSystemAudioSupported(boolean on)10848 public int setHdmiSystemAudioSupported(boolean on) { 10849 int device = AudioSystem.DEVICE_NONE; 10850 synchronized (mHdmiClientLock) { 10851 if (mHdmiManager != null) { 10852 if (mHdmiTvClient == null && mHdmiAudioSystemClient == null) { 10853 Log.w(TAG, "Only Hdmi-Cec enabled TV or audio system device supports" 10854 + "system audio mode."); 10855 return device; 10856 } 10857 if (mHdmiSystemAudioSupported != on) { 10858 mHdmiSystemAudioSupported = on; 10859 final int config = on ? AudioSystem.FORCE_HDMI_SYSTEM_AUDIO_ENFORCED : 10860 AudioSystem.FORCE_NONE; 10861 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_HDMI_SYSTEM_AUDIO, config, 10862 "setHdmiSystemAudioSupported"); 10863 } 10864 // TODO(b/185386781): Update AudioManager API to use device list. 10865 // So far, this value appears to be advisory for debug log. 10866 device = getDeviceMaskForStream(AudioSystem.STREAM_MUSIC); 10867 } 10868 } 10869 return device; 10870 } 10871 10872 @Override isHdmiSystemAudioSupported()10873 public boolean isHdmiSystemAudioSupported() { 10874 return mHdmiSystemAudioSupported; 10875 } 10876 10877 //========================================================================================== 10878 // Accessibility 10879 initA11yMonitoring()10880 private void initA11yMonitoring() { 10881 final AccessibilityManager accessibilityManager = 10882 (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); 10883 updateDefaultStreamOverrideDelay(accessibilityManager.isTouchExplorationEnabled()); 10884 updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive()); 10885 accessibilityManager.addTouchExplorationStateChangeListener(this, null); 10886 accessibilityManager.addAccessibilityServicesStateChangeListener(this); 10887 } 10888 10889 //--------------------------------------------------------------------------------- 10890 // A11y: taking touch exploration into account for selecting the default 10891 // stream override timeout when adjusting volume 10892 //--------------------------------------------------------------------------------- 10893 10894 // - STREAM_NOTIFICATION on tablets during this period after a notification stopped 10895 // - STREAM_RING on phones during this period after a notification stopped 10896 // - STREAM_MUSIC otherwise 10897 10898 private static final int DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS = 0; 10899 private static final int TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS = 1000; 10900 10901 private static int sStreamOverrideDelayMs; 10902 10903 @Override onTouchExplorationStateChanged(boolean enabled)10904 public void onTouchExplorationStateChanged(boolean enabled) { 10905 updateDefaultStreamOverrideDelay(enabled); 10906 } 10907 updateDefaultStreamOverrideDelay(boolean touchExploreEnabled)10908 private void updateDefaultStreamOverrideDelay(boolean touchExploreEnabled) { 10909 if (touchExploreEnabled) { 10910 sStreamOverrideDelayMs = TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS; 10911 } else { 10912 sStreamOverrideDelayMs = DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS; 10913 } 10914 if (DEBUG_VOL) Log.d(TAG, "Touch exploration enabled=" + touchExploreEnabled 10915 + " stream override delay is now " + sStreamOverrideDelayMs + " ms"); 10916 } 10917 10918 //--------------------------------------------------------------------------------- 10919 // A11y: taking a11y state into account for the handling of a11y prompts volume 10920 //--------------------------------------------------------------------------------- 10921 10922 private static boolean sIndependentA11yVolume = false; 10923 10924 // implementation of AccessibilityServicesStateChangeListener 10925 @Override onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager)10926 public void onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager) { 10927 updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive()); 10928 } 10929 updateA11yVolumeAlias(boolean a11VolEnabled)10930 private void updateA11yVolumeAlias(boolean a11VolEnabled) { 10931 if (DEBUG_VOL) Log.d(TAG, "Accessibility volume enabled = " + a11VolEnabled); 10932 if (sIndependentA11yVolume != a11VolEnabled) { 10933 sIndependentA11yVolume = a11VolEnabled; 10934 // update the volume mapping scheme 10935 updateStreamVolumeAlias(true /*updateVolumes*/, TAG); 10936 // update the volume controller behavior 10937 mVolumeController.setA11yMode(sIndependentA11yVolume ? 10938 VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME : 10939 VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME); 10940 mVolumeController.postVolumeChanged(AudioManager.STREAM_ACCESSIBILITY, 0); 10941 } 10942 } 10943 10944 //========================================================================================== 10945 // Camera shutter sound policy. 10946 // config_camera_sound_forced configuration option in config.xml defines if the camera shutter 10947 // sound is forced (sound even if the device is in silent mode) or not. This option is false by 10948 // default and can be overridden by country specific overlay in values-mccXXX/config.xml. 10949 //========================================================================================== 10950 10951 // cached value of com.android.internal.R.bool.config_camera_sound_forced 10952 @GuardedBy("mSettingsLock") 10953 private boolean mCameraSoundForced; 10954 10955 // called by android.hardware.Camera to populate CameraInfo.canDisableShutterSound isCameraSoundForced()10956 public boolean isCameraSoundForced() { 10957 synchronized (mSettingsLock) { 10958 return mCameraSoundForced; 10959 } 10960 } 10961 10962 //========================================================================================== 10963 // AudioService logging and dumpsys 10964 //========================================================================================== 10965 static final int LOG_NB_EVENTS_LIFECYCLE = 20; 10966 static final int LOG_NB_EVENTS_PHONE_STATE = 20; 10967 static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 50; 10968 static final int LOG_NB_EVENTS_FORCE_USE = 20; 10969 static final int LOG_NB_EVENTS_VOLUME = 100; 10970 static final int LOG_NB_EVENTS_DYN_POLICY = 10; 10971 static final int LOG_NB_EVENTS_SPATIAL = 30; 10972 static final int LOG_NB_EVENTS_SOUND_DOSE = 30; 10973 10974 static final EventLogger 10975 sLifecycleLogger = new EventLogger(LOG_NB_EVENTS_LIFECYCLE, 10976 "audio services lifecycle"); 10977 10978 static final EventLogger sMuteLogger = new EventLogger(30, 10979 "mute commands"); 10980 10981 final private EventLogger 10982 mModeLogger = new EventLogger(LOG_NB_EVENTS_PHONE_STATE, 10983 "phone state (logged after successful call to AudioSystem.setPhoneState(int, int))"); 10984 10985 // logs for wired + A2DP device connections: 10986 // - wired: logged before onSetWiredDeviceConnectionState() is executed 10987 // - A2DP: logged at reception of method call 10988 /*package*/ static final EventLogger 10989 sDeviceLogger = new EventLogger( 10990 LOG_NB_EVENTS_DEVICE_CONNECTION, "wired/A2DP/hearing aid device connection"); 10991 10992 static final EventLogger 10993 sForceUseLogger = new EventLogger( 10994 LOG_NB_EVENTS_FORCE_USE, 10995 "force use (logged before setForceUse() is executed)"); 10996 10997 static final EventLogger 10998 sVolumeLogger = new EventLogger(LOG_NB_EVENTS_VOLUME, 10999 "volume changes (logged when command received by AudioService)"); 11000 11001 static final EventLogger 11002 sSpatialLogger = new EventLogger(LOG_NB_EVENTS_SPATIAL, 11003 "spatial audio"); 11004 11005 final private EventLogger 11006 mDynPolicyLogger = new EventLogger(LOG_NB_EVENTS_DYN_POLICY, 11007 "dynamic policy events (logged when command received by AudioService)"); 11008 11009 private static final String[] RINGER_MODE_NAMES = new String[] { 11010 "SILENT", 11011 "VIBRATE", 11012 "NORMAL" 11013 }; 11014 dumpRingerMode(PrintWriter pw)11015 private void dumpRingerMode(PrintWriter pw) { 11016 pw.println("\nRinger mode: "); 11017 pw.println("- mode (internal) = " + RINGER_MODE_NAMES[mRingerMode]); 11018 pw.println("- mode (external) = " + RINGER_MODE_NAMES[mRingerModeExternal]); 11019 pw.println("- zen mode:" + Settings.Global.zenModeToString(mNm.getZenMode())); 11020 dumpRingerModeStreams(pw, "affected", mRingerModeAffectedStreams); 11021 dumpRingerModeStreams(pw, "muted", sRingerAndZenModeMutedStreams); 11022 pw.print("- delegate = "); pw.println(mRingerModeDelegate); 11023 } 11024 dumpRingerModeStreams(PrintWriter pw, String type, int streams)11025 private void dumpRingerModeStreams(PrintWriter pw, String type, int streams) { 11026 pw.print("- ringer mode "); pw.print(type); pw.print(" streams = 0x"); 11027 pw.print(Integer.toHexString(streams)); 11028 if (streams != 0) { 11029 pw.print(" ("); 11030 boolean first = true; 11031 for (int i = 0; i < AudioSystem.STREAM_NAMES.length; i++) { 11032 final int stream = (1 << i); 11033 if ((streams & stream) != 0) { 11034 if (!first) pw.print(','); 11035 pw.print(AudioSystem.STREAM_NAMES[i]); 11036 streams &= ~stream; 11037 first = false; 11038 } 11039 } 11040 if (streams != 0) { 11041 if (!first) pw.print(','); 11042 pw.print(streams); 11043 } 11044 pw.print(')'); 11045 } 11046 pw.println(); 11047 } 11048 getAbsoluteVolumeDevicesWithBehavior(int behavior)11049 private Set<Integer> getAbsoluteVolumeDevicesWithBehavior(int behavior) { 11050 return mAbsoluteVolumeDeviceInfoMap.entrySet().stream() 11051 .filter(entry -> entry.getValue().mDeviceVolumeBehavior == behavior) 11052 .map(Map.Entry::getKey) 11053 .collect(Collectors.toSet()); 11054 } 11055 dumpDeviceTypes(@onNull Set<Integer> deviceTypes)11056 private String dumpDeviceTypes(@NonNull Set<Integer> deviceTypes) { 11057 Iterator<Integer> it = deviceTypes.iterator(); 11058 if (!it.hasNext()) { 11059 return ""; 11060 } 11061 final StringBuilder sb = new StringBuilder(); 11062 sb.append("0x" + Integer.toHexString(it.next())); 11063 while (it.hasNext()) { 11064 sb.append("," + "0x" + Integer.toHexString(it.next())); 11065 } 11066 return sb.toString(); 11067 } 11068 11069 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)11070 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11071 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 11072 11073 sLifecycleLogger.dump(pw); 11074 if (mAudioHandler != null) { 11075 pw.println("\nMessage handler (watch for unhandled messages):"); 11076 mAudioHandler.dump(new PrintWriterPrinter(pw), " "); 11077 } else { 11078 pw.println("\nMessage handler is null"); 11079 } 11080 mMediaFocusControl.dump(pw); 11081 dumpStreamStates(pw); 11082 dumpVolumeGroups(pw); 11083 dumpRingerMode(pw); 11084 dumpAudioMode(pw); 11085 pw.println("\nAudio routes:"); 11086 pw.print(" mMainType=0x"); pw.println(Integer.toHexString( 11087 mDeviceBroker.getCurAudioRoutes().mainType)); 11088 pw.print(" mBluetoothName="); pw.println(mDeviceBroker.getCurAudioRoutes().bluetoothName); 11089 11090 pw.println("\nOther state:"); 11091 pw.print(" mUseVolumeGroupAliases="); pw.println(mUseVolumeGroupAliases); 11092 pw.print(" mVolumeController="); pw.println(mVolumeController); 11093 mSoundDoseHelper.dump(pw); 11094 pw.print(" sIndependentA11yVolume="); pw.println(sIndependentA11yVolume); 11095 pw.print(" mCameraSoundForced="); pw.println(isCameraSoundForced()); 11096 pw.print(" mHasVibrator="); pw.println(mHasVibrator); 11097 pw.print(" mVolumePolicy="); pw.println(mVolumePolicy); 11098 pw.print(" mAvrcpAbsVolSupported="); pw.println(mAvrcpAbsVolSupported); 11099 pw.print(" mBtScoOnByApp="); pw.println(mBtScoOnByApp); 11100 pw.print(" mIsSingleVolume="); pw.println(mIsSingleVolume); 11101 pw.print(" mUseFixedVolume="); pw.println(mUseFixedVolume); 11102 pw.print(" mNotifAliasRing="); pw.println(mNotifAliasRing); 11103 pw.print(" mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices)); 11104 pw.print(" mFullVolumeDevices="); pw.println(dumpDeviceTypes(mFullVolumeDevices)); 11105 pw.print(" absolute volume devices="); pw.println(dumpDeviceTypes( 11106 getAbsoluteVolumeDevicesWithBehavior( 11107 AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE))); 11108 pw.print(" adjust-only absolute volume devices="); pw.println(dumpDeviceTypes( 11109 getAbsoluteVolumeDevicesWithBehavior( 11110 AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY))); 11111 pw.print(" mExtVolumeController="); pw.println(mExtVolumeController); 11112 pw.print(" mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient); 11113 pw.print(" mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient); 11114 pw.print(" mHdmiTvClient="); pw.println(mHdmiTvClient); 11115 pw.print(" mHdmiSystemAudioSupported="); pw.println(mHdmiSystemAudioSupported); 11116 synchronized (mHdmiClientLock) { 11117 pw.print(" mHdmiCecVolumeControlEnabled="); pw.println(mHdmiCecVolumeControlEnabled); 11118 } 11119 pw.print(" mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported); 11120 pw.print(" mic mute FromSwitch=" + mMicMuteFromSwitch 11121 + " FromRestrictions=" + mMicMuteFromRestrictions 11122 + " FromApi=" + mMicMuteFromApi 11123 + " from system=" + mMicMuteFromSystemCached); 11124 dumpAccessibilityServiceUids(pw); 11125 dumpAssistantServicesUids(pw); 11126 11127 pw.print(" supportsBluetoothVariableLatency="); 11128 pw.println(AudioSystem.supportsBluetoothVariableLatency()); 11129 pw.print(" isBluetoothVariableLatencyEnabled="); 11130 pw.println(AudioSystem.isBluetoothVariableLatencyEnabled()); 11131 11132 dumpAudioPolicies(pw); 11133 mDynPolicyLogger.dump(pw); 11134 mPlaybackMonitor.dump(pw); 11135 mRecordMonitor.dump(pw); 11136 11137 pw.println("\nAudioDeviceBroker:"); 11138 mDeviceBroker.dump(pw, " "); 11139 pw.println("\nSoundEffects:"); 11140 mSfxHelper.dump(pw, " "); 11141 11142 pw.println("\n"); 11143 pw.println("\nEvent logs:"); 11144 mModeLogger.dump(pw); 11145 pw.println("\n"); 11146 sDeviceLogger.dump(pw); 11147 pw.println("\n"); 11148 sForceUseLogger.dump(pw); 11149 pw.println("\n"); 11150 sVolumeLogger.dump(pw); 11151 pw.println("\n"); 11152 sMuteLogger.dump(pw); 11153 pw.println("\n"); 11154 dumpSupportedSystemUsage(pw); 11155 11156 pw.println("\n"); 11157 pw.println("\nSpatial audio:"); 11158 pw.println("mHasSpatializerEffect:" + mHasSpatializerEffect + " (effect present)"); 11159 pw.println("isSpatializerEnabled:" + isSpatializerEnabled() + " (routing dependent)"); 11160 mSpatializerHelper.dump(pw); 11161 sSpatialLogger.dump(pw); 11162 11163 mAudioSystem.dump(pw); 11164 } 11165 dumpSupportedSystemUsage(PrintWriter pw)11166 private void dumpSupportedSystemUsage(PrintWriter pw) { 11167 pw.println("Supported System Usages:"); 11168 synchronized (mSupportedSystemUsagesLock) { 11169 for (int i = 0; i < mSupportedSystemUsages.length; i++) { 11170 pw.printf("\t%s\n", AudioAttributes.usageToString(mSupportedSystemUsages[i])); 11171 } 11172 } 11173 } 11174 dumpAssistantServicesUids(PrintWriter pw)11175 private void dumpAssistantServicesUids(PrintWriter pw) { 11176 synchronized (mSettingsLock) { 11177 if (mAssistantUids.size() > 0) { 11178 pw.println(" Assistant service UIDs:"); 11179 for (int uid : mAssistantUids) { 11180 pw.println(" - " + uid); 11181 } 11182 } else { 11183 pw.println(" No Assistant service Uids."); 11184 } 11185 } 11186 } 11187 dumpAccessibilityServiceUids(PrintWriter pw)11188 private void dumpAccessibilityServiceUids(PrintWriter pw) { 11189 synchronized (mSupportedSystemUsagesLock) { 11190 if (mAccessibilityServiceUids != null && mAccessibilityServiceUids.length > 0) { 11191 pw.println(" Accessibility service Uids:"); 11192 for (int uid : mAccessibilityServiceUids) { 11193 pw.println(" - " + uid); 11194 } 11195 } else { 11196 pw.println(" No accessibility service Uids."); 11197 } 11198 } 11199 } 11200 11201 /** 11202 * Audio Analytics ids. 11203 */ 11204 private static final String mMetricsId = MediaMetrics.Name.AUDIO_SERVICE 11205 + MediaMetrics.SEPARATOR; 11206 11207 // Inform AudioFlinger of our device's low RAM attribute readAndSetLowRamDevice()11208 private static void readAndSetLowRamDevice() 11209 { 11210 boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic(); 11211 long totalMemory = 1024 * 1024 * 1024; // 1GB is the default if ActivityManager fails. 11212 11213 try { 11214 final ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo(); 11215 ActivityManager.getService().getMemoryInfo(info); 11216 totalMemory = info.totalMem; 11217 } catch (RemoteException e) { 11218 Log.w(TAG, "Cannot obtain MemoryInfo from ActivityManager, assume low memory device"); 11219 isLowRamDevice = true; 11220 } 11221 11222 final int status = AudioSystem.setLowRamDevice(isLowRamDevice, totalMemory); 11223 if (status != 0) { 11224 Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status); 11225 } 11226 } 11227 enforceVolumeController(String action)11228 private void enforceVolumeController(String action) { 11229 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE, 11230 "Only SystemUI can " + action); 11231 } 11232 11233 @Override setVolumeController(final IVolumeController controller)11234 public void setVolumeController(final IVolumeController controller) { 11235 enforceVolumeController("set the volume controller"); 11236 11237 // return early if things are not actually changing 11238 if (mVolumeController.isSameBinder(controller)) { 11239 return; 11240 } 11241 11242 // dismiss the old volume controller 11243 mVolumeController.postDismiss(); 11244 if (controller != null) { 11245 // we are about to register a new controller, listen for its death 11246 try { 11247 controller.asBinder().linkToDeath(new DeathRecipient() { 11248 @Override 11249 public void binderDied() { 11250 if (mVolumeController.isSameBinder(controller)) { 11251 Log.w(TAG, "Current remote volume controller died, unregistering"); 11252 setVolumeController(null); 11253 } 11254 } 11255 }, 0); 11256 } catch (RemoteException e) { 11257 // noop 11258 } 11259 } 11260 mVolumeController.setController(controller); 11261 if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController); 11262 } 11263 11264 @Override 11265 @Nullable getVolumeController()11266 public IVolumeController getVolumeController() { 11267 enforceVolumeController("get the volume controller"); 11268 if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController); 11269 11270 return mVolumeController.getController(); 11271 } 11272 11273 @Override notifyVolumeControllerVisible(final IVolumeController controller, boolean visible)11274 public void notifyVolumeControllerVisible(final IVolumeController controller, boolean visible) { 11275 enforceVolumeController("notify about volume controller visibility"); 11276 11277 // return early if the controller is not current 11278 if (!mVolumeController.isSameBinder(controller)) { 11279 return; 11280 } 11281 11282 mVolumeController.setVisible(visible); 11283 if (DEBUG_VOL) Log.d(TAG, "Volume controller visible: " + visible); 11284 } 11285 11286 @Override setVolumePolicy(VolumePolicy policy)11287 public void setVolumePolicy(VolumePolicy policy) { 11288 enforceVolumeController("set volume policy"); 11289 if (policy != null && !policy.equals(mVolumePolicy)) { 11290 mVolumePolicy = policy; 11291 if (DEBUG_VOL) Log.d(TAG, "Volume policy changed: " + mVolumePolicy); 11292 } 11293 } 11294 11295 /** Interface used for enforcing the safe hearing standard. */ 11296 public interface ISafeHearingVolumeController { 11297 /** Displays an instructional safeguard as required by the safe hearing standard. */ postDisplaySafeVolumeWarning(int flags)11298 void postDisplaySafeVolumeWarning(int flags); 11299 11300 /** Displays a warning about transient exposure to high level playback */ postDisplayCsdWarning(@udioManager.CsdWarning int csdEvent, int displayDurationMs)11301 void postDisplayCsdWarning(@AudioManager.CsdWarning int csdEvent, int displayDurationMs); 11302 } 11303 11304 /** Wrapper which encapsulates the {@link IVolumeController} functionality. */ 11305 public class VolumeController implements ISafeHearingVolumeController { 11306 private static final String TAG = "VolumeController"; 11307 11308 private IVolumeController mController; 11309 private boolean mVisible; 11310 private long mNextLongPress; 11311 private int mLongPressTimeout; 11312 setController(IVolumeController controller)11313 public void setController(IVolumeController controller) { 11314 mController = controller; 11315 mVisible = false; 11316 } 11317 getController()11318 public IVolumeController getController() { 11319 return mController; 11320 } 11321 loadSettings(ContentResolver cr)11322 public void loadSettings(ContentResolver cr) { 11323 mLongPressTimeout = mSettings.getSecureIntForUser(cr, 11324 Settings.Secure.LONG_PRESS_TIMEOUT, 500, UserHandle.USER_CURRENT); 11325 } 11326 suppressAdjustment(int resolvedStream, int flags, boolean isMute)11327 public boolean suppressAdjustment(int resolvedStream, int flags, boolean isMute) { 11328 if (isMute) { 11329 return false; 11330 } 11331 boolean suppress = false; 11332 // Intended behavior: 11333 // 1/ if the stream is not the default UI stream, do not suppress (as it is not involved 11334 // in bringing up the UI) 11335 // 2/ if the resolved and default stream is MUSIC, and media is playing, do not suppress 11336 // 3/ otherwise suppress the first adjustments that occur during the "long press 11337 // timeout" interval. Note this is true regardless of whether this is a "real long 11338 // press" (where the user keeps pressing on the volume button), or repeated single 11339 // presses (here we don't know if we are in a real long press, or repeated fast 11340 // button presses). 11341 // Once the long press timeout occurs (mNextLongPress reset to 0), do not suppress. 11342 // Example: for a default and resolved stream of MUSIC, this allows modifying rapidly 11343 // the volume when media is playing (whether by long press or repeated individual 11344 // presses), or to bring up the volume UI when media is not playing, in order to make 11345 // another change (e.g. switch ringer modes) without changing media volume. 11346 if (resolvedStream == DEFAULT_VOL_STREAM_NO_PLAYBACK && mController != null) { 11347 // never suppress media vol adjustement during media playback 11348 if (resolvedStream == AudioSystem.STREAM_MUSIC 11349 && mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, mLongPressTimeout)) 11350 { 11351 // media is playing, adjust the volume right away 11352 return false; 11353 } 11354 11355 final long now = SystemClock.uptimeMillis(); 11356 if ((flags & AudioManager.FLAG_SHOW_UI) != 0 && !mVisible) { 11357 // UI is not visible yet, adjustment is ignored 11358 if (mNextLongPress < now) { 11359 mNextLongPress = now + mLongPressTimeout; 11360 } 11361 suppress = true; 11362 } else if (mNextLongPress > 0) { // in a long-press 11363 if (now > mNextLongPress) { 11364 // long press triggered, no more suppression 11365 mNextLongPress = 0; 11366 } else { 11367 // keep suppressing until the long press triggers 11368 suppress = true; 11369 } 11370 } 11371 } 11372 return suppress; 11373 } 11374 setVisible(boolean visible)11375 public void setVisible(boolean visible) { 11376 mVisible = visible; 11377 } 11378 isSameBinder(IVolumeController controller)11379 public boolean isSameBinder(IVolumeController controller) { 11380 return Objects.equals(asBinder(), binder(controller)); 11381 } 11382 asBinder()11383 public IBinder asBinder() { 11384 return binder(mController); 11385 } 11386 binder(IVolumeController controller)11387 private IBinder binder(IVolumeController controller) { 11388 return controller == null ? null : controller.asBinder(); 11389 } 11390 11391 @Override toString()11392 public String toString() { 11393 return "VolumeController(" + asBinder() + ",mVisible=" + mVisible + ")"; 11394 } 11395 11396 @Override postDisplaySafeVolumeWarning(int flags)11397 public void postDisplaySafeVolumeWarning(int flags) { 11398 if (mController == null) 11399 return; 11400 flags = flags | AudioManager.FLAG_SHOW_UI; 11401 try { 11402 mController.displaySafeVolumeWarning(flags); 11403 } catch (RemoteException e) { 11404 Log.w(TAG, "Error calling displaySafeVolumeWarning", e); 11405 } 11406 } 11407 11408 @Override postDisplayCsdWarning( @udioManager.CsdWarning int csdWarning, int displayDurationMs)11409 public void postDisplayCsdWarning( 11410 @AudioManager.CsdWarning int csdWarning, int displayDurationMs) { 11411 if (mController == null) { 11412 Log.e(TAG, "Unable to display CSD warning, no controller"); 11413 return; 11414 } 11415 try { 11416 mController.displayCsdWarning(csdWarning, displayDurationMs); 11417 } catch (RemoteException e) { 11418 Log.w(TAG, "Error calling displayCsdWarning for warning " + csdWarning, e); 11419 } 11420 } 11421 postVolumeChanged(int streamType, int flags)11422 public void postVolumeChanged(int streamType, int flags) { 11423 if (mController == null) 11424 return; 11425 try { 11426 mController.volumeChanged(streamType, flags); 11427 } catch (RemoteException e) { 11428 Log.w(TAG, "Error calling volumeChanged", e); 11429 } 11430 } 11431 postMasterMuteChanged(int flags)11432 public void postMasterMuteChanged(int flags) { 11433 if (mController == null) 11434 return; 11435 try { 11436 mController.masterMuteChanged(flags); 11437 } catch (RemoteException e) { 11438 Log.w(TAG, "Error calling masterMuteChanged", e); 11439 } 11440 } 11441 setLayoutDirection(int layoutDirection)11442 public void setLayoutDirection(int layoutDirection) { 11443 if (mController == null) 11444 return; 11445 try { 11446 mController.setLayoutDirection(layoutDirection); 11447 } catch (RemoteException e) { 11448 Log.w(TAG, "Error calling setLayoutDirection", e); 11449 } 11450 } 11451 postDismiss()11452 public void postDismiss() { 11453 if (mController == null) 11454 return; 11455 try { 11456 mController.dismiss(); 11457 } catch (RemoteException e) { 11458 Log.w(TAG, "Error calling dismiss", e); 11459 } 11460 } 11461 setA11yMode(int a11yMode)11462 public void setA11yMode(int a11yMode) { 11463 if (mController == null) 11464 return; 11465 try { 11466 mController.setA11yMode(a11yMode); 11467 } catch (RemoteException e) { 11468 Log.w(TAG, "Error calling setA11Mode", e); 11469 } 11470 } 11471 } 11472 11473 /** 11474 * Interface for system components to get some extra functionality through 11475 * LocalServices. 11476 */ 11477 final class AudioServiceInternal extends AudioManagerInternal { 11478 @Override setRingerModeDelegate(RingerModeDelegate delegate)11479 public void setRingerModeDelegate(RingerModeDelegate delegate) { 11480 mRingerModeDelegate = delegate; 11481 if (mRingerModeDelegate != null) { 11482 synchronized (mSettingsLock) { 11483 updateRingerAndZenModeAffectedStreams(); 11484 } 11485 setRingerModeInternal(getRingerModeInternal(), TAG + ".setRingerModeDelegate"); 11486 } 11487 } 11488 11489 @Override getRingerModeInternal()11490 public int getRingerModeInternal() { 11491 return AudioService.this.getRingerModeInternal(); 11492 } 11493 11494 @Override setRingerModeInternal(int ringerMode, String caller)11495 public void setRingerModeInternal(int ringerMode, String caller) { 11496 AudioService.this.setRingerModeInternal(ringerMode, caller); 11497 } 11498 11499 @Override silenceRingerModeInternal(String caller)11500 public void silenceRingerModeInternal(String caller) { 11501 AudioService.this.silenceRingerModeInternal(caller); 11502 } 11503 11504 @Override updateRingerModeAffectedStreamsInternal()11505 public void updateRingerModeAffectedStreamsInternal() { 11506 synchronized (mSettingsLock) { 11507 if (updateRingerAndZenModeAffectedStreams()) { 11508 setRingerModeInt(getRingerModeInternal(), false); 11509 } 11510 } 11511 } 11512 11513 @Override addAssistantServiceUid(int uid)11514 public void addAssistantServiceUid(int uid) { 11515 sendMsg(mAudioHandler, MSG_ADD_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE, 11516 uid, 0, null, 0); 11517 } 11518 11519 @Override removeAssistantServiceUid(int uid)11520 public void removeAssistantServiceUid(int uid) { 11521 sendMsg(mAudioHandler, MSG_REMOVE_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE, 11522 uid, 0, null, 0); 11523 } 11524 11525 @Override setActiveAssistantServicesUids(IntArray activeUids)11526 public void setActiveAssistantServicesUids(IntArray activeUids) { 11527 synchronized (mSettingsLock) { 11528 if (activeUids.size() == 0) { 11529 mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS; 11530 } else { 11531 boolean changed = (mActiveAssistantServiceUids == null) 11532 || (mActiveAssistantServiceUids.length != activeUids.size()); 11533 if (!changed) { 11534 for (int i = 0; i < mActiveAssistantServiceUids.length; i++) { 11535 if (activeUids.get(i) != mActiveAssistantServiceUids[i]) { 11536 changed = true; 11537 break; 11538 } 11539 } 11540 } 11541 if (changed) { 11542 mActiveAssistantServiceUids = activeUids.toArray(); 11543 } 11544 } 11545 } 11546 sendMsg(mAudioHandler, MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID, SENDMSG_REPLACE, 11547 0, 0, null, 0); 11548 } 11549 11550 @Override setAccessibilityServiceUids(IntArray uids)11551 public void setAccessibilityServiceUids(IntArray uids) { 11552 // TODO(b/233287010): Fix voice interaction and a11y concurrency in audio policy service 11553 if (isPlatformAutomotive()) { 11554 return; 11555 } 11556 11557 synchronized (mAccessibilityServiceUidsLock) { 11558 if (uids.size() == 0) { 11559 mAccessibilityServiceUids = null; 11560 } else { 11561 boolean changed = (mAccessibilityServiceUids == null) 11562 || (mAccessibilityServiceUids.length != uids.size()); 11563 if (!changed) { 11564 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 11565 if (uids.get(i) != mAccessibilityServiceUids[i]) { 11566 changed = true; 11567 break; 11568 } 11569 } 11570 } 11571 if (changed) { 11572 mAccessibilityServiceUids = uids.toArray(); 11573 } 11574 } 11575 sendMsg(mAudioHandler, MSG_UPDATE_A11Y_SERVICE_UIDS, SENDMSG_REPLACE, 11576 0, 0, null, 0); 11577 } 11578 } 11579 11580 /** 11581 * {@inheritDoc} 11582 */ 11583 @Override setInputMethodServiceUid(int uid)11584 public void setInputMethodServiceUid(int uid) { 11585 synchronized (mInputMethodServiceUidLock) { 11586 if (mInputMethodServiceUid != uid) { 11587 mAudioSystem.setCurrentImeUid(uid); 11588 mInputMethodServiceUid = uid; 11589 } 11590 } 11591 } 11592 } 11593 onUpdateAccessibilityServiceUids()11594 private void onUpdateAccessibilityServiceUids() { 11595 int[] accessibilityServiceUids; 11596 synchronized (mAccessibilityServiceUidsLock) { 11597 accessibilityServiceUids = mAccessibilityServiceUids; 11598 } 11599 AudioSystem.setA11yServicesUids(accessibilityServiceUids); 11600 } 11601 11602 //========================================================================================== 11603 // Audio policy management 11604 //========================================================================================== registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)11605 public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, 11606 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, 11607 boolean isVolumeController, IMediaProjection projection) { 11608 AudioSystem.setDynamicPolicyCallback(mDynPolicyCallback); 11609 11610 if (!isPolicyRegisterAllowed(policyConfig, 11611 isFocusPolicy || isTestFocusPolicy || hasFocusListener, 11612 isVolumeController, 11613 projection)) { 11614 Slog.w(TAG, "Permission denied to register audio policy for pid " 11615 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid() 11616 + ", need system permission or a MediaProjection that can project audio"); 11617 return null; 11618 } 11619 11620 String regId = null; 11621 synchronized (mAudioPolicies) { 11622 if (mAudioPolicies.containsKey(pcb.asBinder())) { 11623 Slog.e(TAG, "Cannot re-register policy"); 11624 return null; 11625 } 11626 try { 11627 AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, pcb, hasFocusListener, 11628 isFocusPolicy, isTestFocusPolicy, isVolumeController, projection); 11629 pcb.asBinder().linkToDeath(app, 0/*flags*/); 11630 11631 // logging after registration so we have the registration id 11632 mDynPolicyLogger.enqueue((new EventLogger.StringEvent("registerAudioPolicy for " 11633 + pcb.asBinder() + " u/pid:" + Binder.getCallingUid() + "/" 11634 + Binder.getCallingPid() + " with config:" + app.toCompactLogString())) 11635 .printLog(TAG)); 11636 11637 regId = app.getRegistrationId(); 11638 mAudioPolicies.put(pcb.asBinder(), app); 11639 } catch (RemoteException e) { 11640 // audio policy owner has already died! 11641 Slog.w(TAG, "Audio policy registration failed, could not link to " + pcb + 11642 " binder death", e); 11643 return null; 11644 } catch (IllegalStateException e) { 11645 Slog.w(TAG, "Audio policy registration failed for binder " + pcb, e); 11646 return null; 11647 } 11648 } 11649 return regId; 11650 } 11651 11652 /** 11653 * Called by an AudioPolicyProxy when the client dies. 11654 * Checks if an active playback for media use case is currently routed to one of the 11655 * remote submix devices owned by this dynamic policy and broadcasts a becoming noisy 11656 * intend in this case. 11657 * @param addresses list of remote submix device addresses to check. 11658 */ onPolicyClientDeath(List<String> addresses)11659 private void onPolicyClientDeath(List<String> addresses) { 11660 for (String address : addresses) { 11661 if (mPlaybackMonitor.hasActiveMediaPlaybackOnSubmixWithAddress(address)) { 11662 mDeviceBroker.postBroadcastBecomingNoisy(); 11663 return; 11664 } 11665 } 11666 } 11667 /** 11668 * Apps with MODIFY_AUDIO_ROUTING can register any policy. 11669 * Apps with an audio capable MediaProjection are allowed to register a RENDER|LOOPBACK policy 11670 * as those policy do not modify the audio routing. 11671 */ isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, boolean hasFocusAccess, boolean isVolumeController, IMediaProjection projection)11672 private boolean isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, 11673 boolean hasFocusAccess, 11674 boolean isVolumeController, 11675 IMediaProjection projection) { 11676 11677 boolean requireValidProjection = false; 11678 boolean requireCaptureAudioOrMediaOutputPerm = false; 11679 boolean requireModifyRouting = false; 11680 boolean requireCallAudioInterception = false; 11681 ArrayList<AudioMix> voiceCommunicationCaptureMixes = null; 11682 11683 11684 if (hasFocusAccess || isVolumeController) { 11685 requireModifyRouting |= true; 11686 } else if (policyConfig.getMixes().isEmpty()) { 11687 // An empty policy could be used to lock the focus or add mixes later 11688 requireModifyRouting |= true; 11689 } 11690 for (AudioMix mix : policyConfig.getMixes()) { 11691 // If mix is requesting privileged capture 11692 if (mix.getRule().allowPrivilegedMediaPlaybackCapture()) { 11693 // then its format must be low quality enough 11694 String privilegedMediaCaptureError = 11695 mix.canBeUsedForPrivilegedMediaCapture(mix.getFormat()); 11696 if (privilegedMediaCaptureError != null) { 11697 Log.e(TAG, privilegedMediaCaptureError); 11698 return false; 11699 } 11700 // and it must have CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT permission 11701 requireCaptureAudioOrMediaOutputPerm |= true; 11702 11703 } 11704 // If mix is trying to explicitly capture USAGE_VOICE_COMMUNICATION 11705 if (mix.containsMatchAttributeRuleForUsage( 11706 AudioAttributes.USAGE_VOICE_COMMUNICATION) 11707 && (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER)) { 11708 // It must have CAPTURE_USAGE_VOICE_COMMUNICATION_OUTPUT permission 11709 // Note that for UID, USERID or EXCLDUE rules, the capture will be silenced 11710 // in AudioPolicyMix 11711 if (voiceCommunicationCaptureMixes == null) { 11712 voiceCommunicationCaptureMixes = new ArrayList<AudioMix>(); 11713 } 11714 voiceCommunicationCaptureMixes.add(mix); 11715 } 11716 11717 // If mix is RENDER|LOOPBACK, then an audio MediaProjection is enough 11718 // otherwise MODIFY_AUDIO_ROUTING permission is required 11719 if (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER && projection != null) { 11720 requireValidProjection |= true; 11721 } else if (mix.isForCallRedirection()) { 11722 requireCallAudioInterception |= true; 11723 } else if (mix.containsMatchAttributeRuleForUsage( 11724 AudioAttributes.USAGE_VOICE_COMMUNICATION)) { 11725 requireModifyRouting |= true; 11726 } 11727 } 11728 11729 if (requireCaptureAudioOrMediaOutputPerm 11730 && !callerHasPermission(android.Manifest.permission.CAPTURE_MEDIA_OUTPUT) 11731 && !callerHasPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT)) { 11732 Log.e(TAG, "Privileged audio capture requires CAPTURE_MEDIA_OUTPUT or " 11733 + "CAPTURE_AUDIO_OUTPUT system permission"); 11734 return false; 11735 } 11736 11737 if (voiceCommunicationCaptureMixes != null && voiceCommunicationCaptureMixes.size() > 0) { 11738 if (!callerHasPermission( 11739 android.Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT)) { 11740 Log.e(TAG, "Audio capture for voice communication requires " 11741 + "CAPTURE_VOICE_COMMUNICATION_OUTPUT system permission"); 11742 return false; 11743 } 11744 11745 // If permission check succeeded, we set the flag in each of the mixing rules 11746 for (AudioMix mix : voiceCommunicationCaptureMixes) { 11747 mix.getRule().setVoiceCommunicationCaptureAllowed(true); 11748 } 11749 } 11750 11751 if (requireValidProjection && !canProjectAudio(projection)) { 11752 return false; 11753 } 11754 11755 if (requireModifyRouting 11756 && !callerHasPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)) { 11757 Log.e(TAG, "Can not capture audio without MODIFY_AUDIO_ROUTING"); 11758 return false; 11759 } 11760 11761 if (requireCallAudioInterception 11762 && !callerHasPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION)) { 11763 Log.e(TAG, "Can not capture audio without CALL_AUDIO_INTERCEPTION"); 11764 return false; 11765 } 11766 11767 return true; 11768 } 11769 callerHasPermission(String permission)11770 private boolean callerHasPermission(String permission) { 11771 return mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED; 11772 } 11773 11774 /** @return true if projection is a valid MediaProjection that can project audio. */ canProjectAudio(IMediaProjection projection)11775 private boolean canProjectAudio(IMediaProjection projection) { 11776 if (projection == null) { 11777 Log.e(TAG, "MediaProjection is null"); 11778 return false; 11779 } 11780 11781 IMediaProjectionManager projectionService = getProjectionService(); 11782 if (projectionService == null) { 11783 Log.e(TAG, "Can't get service IMediaProjectionManager"); 11784 return false; 11785 } 11786 11787 final long token = Binder.clearCallingIdentity(); 11788 try { 11789 if (!projectionService.isCurrentProjection(projection)) { 11790 Log.w(TAG, "App passed invalid MediaProjection token"); 11791 return false; 11792 } 11793 } catch (RemoteException e) { 11794 Log.e(TAG, "Can't call .isCurrentProjection() on IMediaProjectionManager" 11795 + projectionService.asBinder(), e); 11796 return false; 11797 } finally { 11798 Binder.restoreCallingIdentity(token); 11799 } 11800 11801 try { 11802 if (!projection.canProjectAudio()) { 11803 Log.w(TAG, "App passed MediaProjection that can not project audio"); 11804 return false; 11805 } 11806 } catch (RemoteException e) { 11807 Log.e(TAG, "Can't call .canProjectAudio() on valid IMediaProjection" 11808 + projection.asBinder(), e); 11809 return false; 11810 } 11811 11812 return true; 11813 } 11814 getProjectionService()11815 private IMediaProjectionManager getProjectionService() { 11816 if (mProjectionService == null) { 11817 IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE); 11818 mProjectionService = IMediaProjectionManager.Stub.asInterface(b); 11819 } 11820 return mProjectionService; 11821 } 11822 11823 /** 11824 * See {@link AudioManager#unregisterAudioPolicyAsync(AudioPolicy)} 11825 * Declared oneway 11826 * @param pcb nullable because on service interface 11827 */ unregisterAudioPolicyAsync(@ullable IAudioPolicyCallback pcb)11828 public void unregisterAudioPolicyAsync(@Nullable IAudioPolicyCallback pcb) { 11829 if (pcb == null) { 11830 return; 11831 } 11832 unregisterAudioPolicyInt(pcb, "unregisterAudioPolicyAsync"); 11833 } 11834 11835 /** 11836 * See {@link AudioManager#unregisterAudioPolicy(AudioPolicy)} 11837 * @param pcb nullable because on service interface 11838 */ unregisterAudioPolicy(@ullable IAudioPolicyCallback pcb)11839 public void unregisterAudioPolicy(@Nullable IAudioPolicyCallback pcb) { 11840 if (pcb == null) { 11841 return; 11842 } 11843 unregisterAudioPolicyInt(pcb, "unregisterAudioPolicy"); 11844 } 11845 11846 unregisterAudioPolicyInt(@onNull IAudioPolicyCallback pcb, String operationName)11847 private void unregisterAudioPolicyInt(@NonNull IAudioPolicyCallback pcb, String operationName) { 11848 mDynPolicyLogger.enqueue((new EventLogger.StringEvent(operationName + " for " 11849 + pcb.asBinder()).printLog(TAG))); 11850 synchronized (mAudioPolicies) { 11851 AudioPolicyProxy app = mAudioPolicies.remove(pcb.asBinder()); 11852 if (app == null) { 11853 Slog.w(TAG, "Trying to unregister unknown audio policy for pid " 11854 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()); 11855 return; 11856 } else { 11857 pcb.asBinder().unlinkToDeath(app, 0/*flags*/); 11858 } 11859 app.release(); 11860 } 11861 // TODO implement clearing mix attribute matching info in native audio policy 11862 } 11863 11864 /** 11865 * Checks whether caller has MODIFY_AUDIO_ROUTING permission, and the policy is registered. 11866 * @param errorMsg log warning if permission check failed. 11867 * @return null if the operation on the audio mixes should be cancelled. 11868 */ 11869 @GuardedBy("mAudioPolicies") checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg)11870 private AudioPolicyProxy checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg) { 11871 // permission check 11872 final boolean hasPermissionForPolicy = 11873 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 11874 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 11875 if (!hasPermissionForPolicy) { 11876 Slog.w(TAG, errorMsg + " for pid " + 11877 + Binder.getCallingPid() + " / uid " 11878 + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING"); 11879 return null; 11880 } 11881 // policy registered? 11882 final AudioPolicyProxy app = mAudioPolicies.get(pcb.asBinder()); 11883 if (app == null) { 11884 Slog.w(TAG, errorMsg + " for pid " + 11885 + Binder.getCallingPid() + " / uid " 11886 + Binder.getCallingUid() + ", unregistered policy"); 11887 return null; 11888 } 11889 return app; 11890 } 11891 addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)11892 public int addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) { 11893 if (DEBUG_AP) { Log.d(TAG, "addMixForPolicy for " + pcb.asBinder() 11894 + " with config:" + policyConfig); } 11895 synchronized (mAudioPolicies) { 11896 final AudioPolicyProxy app = 11897 checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy"); 11898 if (app == null){ 11899 return AudioManager.ERROR; 11900 } 11901 return app.addMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS 11902 ? AudioManager.SUCCESS : AudioManager.ERROR; 11903 } 11904 } 11905 removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)11906 public int removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) { 11907 if (DEBUG_AP) { Log.d(TAG, "removeMixForPolicy for " + pcb.asBinder() 11908 + " with config:" + policyConfig); } 11909 synchronized (mAudioPolicies) { 11910 final AudioPolicyProxy app = 11911 checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy"); 11912 if (app == null) { 11913 return AudioManager.ERROR; 11914 } 11915 return app.removeMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS 11916 ? AudioManager.SUCCESS : AudioManager.ERROR; 11917 } 11918 } 11919 11920 /** see AudioPolicy.setUidDeviceAffinity() */ setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)11921 public int setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, 11922 @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) { 11923 if (DEBUG_AP) { 11924 Log.d(TAG, "setUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid); 11925 } 11926 synchronized (mAudioPolicies) { 11927 final AudioPolicyProxy app = 11928 checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy"); 11929 if (app == null) { 11930 return AudioManager.ERROR; 11931 } 11932 if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) { 11933 return AudioManager.ERROR; 11934 } 11935 return app.setUidDeviceAffinities(uid, deviceTypes, deviceAddresses); 11936 } 11937 } 11938 11939 /** see AudioPolicy.setUserIdDeviceAffinity() */ setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)11940 public int setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, 11941 @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) { 11942 if (DEBUG_AP) { 11943 Log.d(TAG, "setUserIdDeviceAffinity for " + pcb.asBinder() + " user:" + userId); 11944 } 11945 11946 synchronized (mAudioPolicies) { 11947 final AudioPolicyProxy app = 11948 checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy"); 11949 if (app == null) { 11950 return AudioManager.ERROR; 11951 } 11952 if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) { 11953 return AudioManager.ERROR; 11954 } 11955 return app.setUserIdDeviceAffinities(userId, deviceTypes, deviceAddresses); 11956 } 11957 } 11958 11959 /** see AudioPolicy.removeUidDeviceAffinity() */ removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid)11960 public int removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid) { 11961 if (DEBUG_AP) { 11962 Log.d(TAG, "removeUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid); 11963 } 11964 synchronized (mAudioPolicies) { 11965 final AudioPolicyProxy app = 11966 checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy"); 11967 if (app == null) { 11968 return AudioManager.ERROR; 11969 } 11970 return app.removeUidDeviceAffinities(uid); 11971 } 11972 } 11973 11974 /** see AudioPolicy.removeUserIdDeviceAffinity() */ removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId)11975 public int removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId) { 11976 if (DEBUG_AP) { 11977 Log.d(TAG, "removeUserIdDeviceAffinity for " + pcb.asBinder() 11978 + " userId:" + userId); 11979 } 11980 synchronized (mAudioPolicies) { 11981 final AudioPolicyProxy app = 11982 checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy"); 11983 if (app == null) { 11984 return AudioManager.ERROR; 11985 } 11986 return app.removeUserIdDeviceAffinities(userId); 11987 } 11988 } 11989 setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb)11990 public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) { 11991 if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior 11992 + " policy " + pcb.asBinder()); 11993 synchronized (mAudioPolicies) { 11994 final AudioPolicyProxy app = 11995 checkUpdateForPolicy(pcb, "Cannot change audio policy focus properties"); 11996 if (app == null){ 11997 return AudioManager.ERROR; 11998 } 11999 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 12000 Slog.e(TAG, "Cannot change audio policy focus properties, unregistered policy"); 12001 return AudioManager.ERROR; 12002 } 12003 if (duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 12004 // is there already one policy managing ducking? 12005 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 12006 if (policy.mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 12007 Slog.e(TAG, "Cannot change audio policy ducking behavior, already handled"); 12008 return AudioManager.ERROR; 12009 } 12010 } 12011 } 12012 app.mFocusDuckBehavior = duckingBehavior; 12013 mMediaFocusControl.setDuckingInExtPolicyAvailable( 12014 duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY); 12015 } 12016 return AudioManager.SUCCESS; 12017 } 12018 12019 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 12020 /** @see AudioPolicy#getFocusStack() */ getFocusStack()12021 public List<AudioFocusInfo> getFocusStack() { 12022 super.getFocusStack_enforcePermission(); 12023 12024 return mMediaFocusControl.getFocusStack(); 12025 } 12026 12027 /** @see AudioPolicy#sendFocusLoss */ sendFocusLoss(@onNull AudioFocusInfo focusLoser, @NonNull IAudioPolicyCallback apcb)12028 public boolean sendFocusLoss(@NonNull AudioFocusInfo focusLoser, 12029 @NonNull IAudioPolicyCallback apcb) { 12030 Objects.requireNonNull(focusLoser); 12031 Objects.requireNonNull(apcb); 12032 enforceModifyAudioRoutingPermission(); 12033 if (!mAudioPolicies.containsKey(apcb.asBinder())) { 12034 throw new IllegalStateException("Only registered AudioPolicy can change focus"); 12035 } 12036 if (!mAudioPolicies.get(apcb.asBinder()).mHasFocusListener) { 12037 throw new IllegalStateException("AudioPolicy must have focus listener to change focus"); 12038 } 12039 return mMediaFocusControl.sendFocusLoss(focusLoser); 12040 } 12041 12042 /** 12043 * @see AudioManager#getHalVersion 12044 */ getHalVersion()12045 public @Nullable AudioHalVersionInfo getHalVersion() { 12046 for (AudioHalVersionInfo version : AudioHalVersionInfo.VERSIONS) { 12047 try { 12048 // TODO: check AIDL service. 12049 String versionStr = version.getMajorVersion() + "." + version.getMinorVersion(); 12050 HwBinder.getService( 12051 String.format("android.hardware.audio@%s::IDevicesFactory", versionStr), 12052 "default"); 12053 return version; 12054 } catch (NoSuchElementException e) { 12055 // Ignore, the specified HAL interface is not found. 12056 } catch (RemoteException re) { 12057 Log.e(TAG, "Remote exception when getting hardware audio service:", re); 12058 } 12059 } 12060 return null; 12061 } 12062 12063 /** see AudioManager.hasRegisteredDynamicPolicy */ hasRegisteredDynamicPolicy()12064 public boolean hasRegisteredDynamicPolicy() { 12065 synchronized (mAudioPolicies) { 12066 return !mAudioPolicies.isEmpty(); 12067 } 12068 } 12069 12070 /** 12071 * @see AudioManager#setPreferredMixerAttributes( 12072 * AudioAttributes, AudioDeviceInfo, AudioMixerAttributes) 12073 */ setPreferredMixerAttributes(AudioAttributes attributes, int portId, AudioMixerAttributes mixerAttributes)12074 public int setPreferredMixerAttributes(AudioAttributes attributes, 12075 int portId, AudioMixerAttributes mixerAttributes) { 12076 Objects.requireNonNull(attributes); 12077 Objects.requireNonNull(mixerAttributes); 12078 if (!checkAudioSettingsPermission("setPreferredMixerAttributes()")) { 12079 return AudioSystem.PERMISSION_DENIED; 12080 } 12081 final int uid = Binder.getCallingUid(); 12082 final int pid = Binder.getCallingPid(); 12083 int status = AudioSystem.SUCCESS; 12084 final long token = Binder.clearCallingIdentity(); 12085 try { 12086 final String logString = TextUtils.formatSimple( 12087 "setPreferredMixerAttributes u/pid:%d/%d attr:%s mixerAttributes:%s portId:%d", 12088 uid, pid, attributes.toString(), mixerAttributes.toString(), portId); 12089 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 12090 12091 status = mAudioSystem.setPreferredMixerAttributes( 12092 attributes, portId, uid, mixerAttributes); 12093 if (status == AudioSystem.SUCCESS) { 12094 dispatchPreferredMixerAttributesChanged(attributes, portId, mixerAttributes); 12095 } else { 12096 Log.e(TAG, TextUtils.formatSimple("Error %d in %s)", status, logString)); 12097 } 12098 } finally { 12099 Binder.restoreCallingIdentity(token); 12100 } 12101 return status; 12102 } 12103 12104 /** 12105 * @see AudioManager#clearPreferredMixerAttributes(AudioAttributes, AudioDeviceInfo) 12106 */ clearPreferredMixerAttributes(AudioAttributes attributes, int portId)12107 public int clearPreferredMixerAttributes(AudioAttributes attributes, int portId) { 12108 Objects.requireNonNull(attributes); 12109 if (!checkAudioSettingsPermission("clearPreferredMixerAttributes()")) { 12110 return AudioSystem.PERMISSION_DENIED; 12111 } 12112 final int uid = Binder.getCallingUid(); 12113 final int pid = Binder.getCallingPid(); 12114 int status = AudioSystem.SUCCESS; 12115 final long token = Binder.clearCallingIdentity(); 12116 try { 12117 final String logString = TextUtils.formatSimple( 12118 "clearPreferredMixerAttributes u/pid:%d/%d attr:%s", 12119 uid, pid, attributes.toString()); 12120 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 12121 12122 status = mAudioSystem.clearPreferredMixerAttributes(attributes, portId, uid); 12123 if (status == AudioSystem.SUCCESS) { 12124 dispatchPreferredMixerAttributesChanged(attributes, portId, null /*mixerAttr*/); 12125 } else { 12126 Log.e(TAG, TextUtils.formatSimple("Error %d in %s)", status, logString)); 12127 } 12128 } finally { 12129 Binder.restoreCallingIdentity(token); 12130 } 12131 return status; 12132 } 12133 dispatchPreferredMixerAttributesChanged( AudioAttributes attr, int deviceId, AudioMixerAttributes mixerAttr)12134 void dispatchPreferredMixerAttributesChanged( 12135 AudioAttributes attr, int deviceId, AudioMixerAttributes mixerAttr) { 12136 Bundle bundle = new Bundle(); 12137 bundle.putParcelable(KEY_AUDIO_ATTRIBUTES, attr); 12138 bundle.putParcelable(KEY_AUDIO_MIXER_ATTRIBUTES, mixerAttr); 12139 sendBundleMsg(mAudioHandler, MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES, SENDMSG_QUEUE, 12140 deviceId, 0, null, bundle, 0); 12141 } 12142 12143 final RemoteCallbackList<IPreferredMixerAttributesDispatcher> mPrefMixerAttrDispatcher = 12144 new RemoteCallbackList<IPreferredMixerAttributesDispatcher>(); 12145 private static final String KEY_AUDIO_ATTRIBUTES = "audio_attributes"; 12146 private static final String KEY_AUDIO_MIXER_ATTRIBUTES = "audio_mixer_attributes"; 12147 12148 /** @see AudioManager#addOnPreferredMixerAttributesChangedListener( 12149 * Executor, AudioManager.OnPreferredMixerAttributesChangedListener) 12150 */ registerPreferredMixerAttributesDispatcher( @ullable IPreferredMixerAttributesDispatcher dispatcher)12151 public void registerPreferredMixerAttributesDispatcher( 12152 @Nullable IPreferredMixerAttributesDispatcher dispatcher) { 12153 if (dispatcher == null) { 12154 return; 12155 } 12156 mPrefMixerAttrDispatcher.register(dispatcher); 12157 } 12158 12159 /** @see AudioManager#removeOnPreferredMixerAttributesChangedListener( 12160 * AudioManager.OnPreferredMixerAttributesChangedListener) 12161 */ unregisterPreferredMixerAttributesDispatcher( @ullable IPreferredMixerAttributesDispatcher dispatcher)12162 public void unregisterPreferredMixerAttributesDispatcher( 12163 @Nullable IPreferredMixerAttributesDispatcher dispatcher) { 12164 if (dispatcher == null) { 12165 return; 12166 } 12167 mPrefMixerAttrDispatcher.unregister(dispatcher); 12168 } 12169 onDispatchPreferredMixerAttributesChanged(Bundle data, int deviceId)12170 protected void onDispatchPreferredMixerAttributesChanged(Bundle data, int deviceId) { 12171 final int nbDispathers = mPrefMixerAttrDispatcher.beginBroadcast(); 12172 final AudioAttributes attr = data.getParcelable( 12173 KEY_AUDIO_ATTRIBUTES, AudioAttributes.class); 12174 final AudioMixerAttributes mixerAttr = data.getParcelable( 12175 KEY_AUDIO_MIXER_ATTRIBUTES, AudioMixerAttributes.class); 12176 for (int i = 0; i < nbDispathers; i++) { 12177 try { 12178 mPrefMixerAttrDispatcher.getBroadcastItem(i) 12179 .dispatchPrefMixerAttributesChanged(attr, deviceId, mixerAttr); 12180 } catch (RemoteException e) { 12181 Log.e(TAG, "Can't call dispatchPrefMixerAttributesChanged() " 12182 + "IPreferredMixerAttributesDispatcher " 12183 + mPrefMixerAttrDispatcher.getBroadcastItem(i).asBinder(), e); 12184 } 12185 } 12186 mPrefMixerAttrDispatcher.finishBroadcast(); 12187 } 12188 12189 12190 /** @see AudioManager#supportsBluetoothVariableLatency() */ 12191 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) supportsBluetoothVariableLatency()12192 public boolean supportsBluetoothVariableLatency() { 12193 super.supportsBluetoothVariableLatency_enforcePermission(); 12194 try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { 12195 return AudioSystem.supportsBluetoothVariableLatency(); 12196 } 12197 } 12198 12199 /** @see AudioManager#setBluetoothVariableLatencyEnabled(boolean) */ 12200 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) setBluetoothVariableLatencyEnabled(boolean enabled)12201 public void setBluetoothVariableLatencyEnabled(boolean enabled) { 12202 super.setBluetoothVariableLatencyEnabled_enforcePermission(); 12203 try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { 12204 AudioSystem.setBluetoothVariableLatencyEnabled(enabled); 12205 } 12206 } 12207 12208 /** @see AudioManager#isBluetoothVariableLatencyEnabled(boolean) */ 12209 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) isBluetoothVariableLatencyEnabled()12210 public boolean isBluetoothVariableLatencyEnabled() { 12211 super.isBluetoothVariableLatencyEnabled_enforcePermission(); 12212 try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { 12213 return AudioSystem.isBluetoothVariableLatencyEnabled(); 12214 } 12215 } 12216 12217 private final Object mExtVolumeControllerLock = new Object(); 12218 private IAudioPolicyCallback mExtVolumeController; setExtVolumeController(IAudioPolicyCallback apc)12219 private void setExtVolumeController(IAudioPolicyCallback apc) { 12220 if (!mContext.getResources().getBoolean( 12221 com.android.internal.R.bool.config_handleVolumeKeysInWindowManager)) { 12222 Log.e(TAG, "Cannot set external volume controller: device not set for volume keys" + 12223 " handled in PhoneWindowManager"); 12224 return; 12225 } 12226 synchronized (mExtVolumeControllerLock) { 12227 if (mExtVolumeController != null && !mExtVolumeController.asBinder().pingBinder()) { 12228 Log.e(TAG, "Cannot set external volume controller: existing controller"); 12229 } 12230 mExtVolumeController = apc; 12231 } 12232 } 12233 dumpAudioPolicies(PrintWriter pw)12234 private void dumpAudioPolicies(PrintWriter pw) { 12235 pw.println("\nAudio policies:"); 12236 synchronized (mAudioPolicies) { 12237 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 12238 pw.println(policy.toLogFriendlyString()); 12239 } 12240 } 12241 } 12242 12243 //====================== 12244 // Audio policy callbacks from AudioSystem for dynamic policies 12245 //====================== 12246 private final AudioSystem.DynamicPolicyCallback mDynPolicyCallback = 12247 new AudioSystem.DynamicPolicyCallback() { 12248 public void onDynamicPolicyMixStateUpdate(String regId, int state) { 12249 if (!TextUtils.isEmpty(regId)) { 12250 sendMsg(mAudioHandler, MSG_DYN_POLICY_MIX_STATE_UPDATE, SENDMSG_QUEUE, 12251 state /*arg1*/, 0 /*arg2 ignored*/, regId /*obj*/, 0 /*delay*/); 12252 } 12253 } 12254 }; 12255 onDynPolicyMixStateUpdate(String regId, int state)12256 private void onDynPolicyMixStateUpdate(String regId, int state) { 12257 if (DEBUG_AP) Log.d(TAG, "onDynamicPolicyMixStateUpdate("+ regId + ", " + state +")"); 12258 synchronized (mAudioPolicies) { 12259 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 12260 for (AudioMix mix : policy.getMixes()) { 12261 if (mix.getRegistration().equals(regId)) { 12262 try { 12263 policy.mPolicyCallback.notifyMixStateUpdate(regId, state); 12264 } catch (RemoteException e) { 12265 Log.e(TAG, "Can't call notifyMixStateUpdate() on IAudioPolicyCallback " 12266 + policy.mPolicyCallback.asBinder(), e); 12267 } 12268 return; 12269 } 12270 } 12271 } 12272 } 12273 } 12274 12275 //====================== 12276 // Audio policy callbacks from AudioSystem for recording configuration updates 12277 //====================== 12278 private final RecordingActivityMonitor mRecordMonitor; 12279 registerRecordingCallback(IRecordingConfigDispatcher rcdb)12280 public void registerRecordingCallback(IRecordingConfigDispatcher rcdb) { 12281 final boolean isPrivileged = 12282 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 12283 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 12284 mRecordMonitor.registerRecordingCallback(rcdb, isPrivileged); 12285 } 12286 unregisterRecordingCallback(IRecordingConfigDispatcher rcdb)12287 public void unregisterRecordingCallback(IRecordingConfigDispatcher rcdb) { 12288 mRecordMonitor.unregisterRecordingCallback(rcdb); 12289 } 12290 getActiveRecordingConfigurations()12291 public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() { 12292 final boolean isPrivileged = Binder.getCallingUid() == Process.SYSTEM_UID 12293 || (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 12294 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 12295 return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged); 12296 } 12297 12298 //====================== 12299 // Audio recording state notification from clients 12300 //====================== 12301 /** 12302 * Track a recorder provided by the client 12303 */ trackRecorder(IBinder recorder)12304 public int trackRecorder(IBinder recorder) { 12305 return mRecordMonitor.trackRecorder(recorder); 12306 } 12307 12308 /** 12309 * Receive an event from the client about a tracked recorder 12310 */ recorderEvent(int riid, int event)12311 public void recorderEvent(int riid, int event) { 12312 mRecordMonitor.recorderEvent(riid, event); 12313 } 12314 12315 /** 12316 * Stop tracking the recorder 12317 */ releaseRecorder(int riid)12318 public void releaseRecorder(int riid) { 12319 mRecordMonitor.releaseRecorder(riid); 12320 } 12321 12322 //====================== 12323 // Audio playback notification 12324 //====================== 12325 private final PlaybackActivityMonitor mPlaybackMonitor; 12326 registerPlaybackCallback(IPlaybackConfigDispatcher pcdb)12327 public void registerPlaybackCallback(IPlaybackConfigDispatcher pcdb) { 12328 final boolean isPrivileged = 12329 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 12330 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 12331 mPlaybackMonitor.registerPlaybackCallback(pcdb, isPrivileged); 12332 } 12333 unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb)12334 public void unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb) { 12335 mPlaybackMonitor.unregisterPlaybackCallback(pcdb); 12336 } 12337 getActivePlaybackConfigurations()12338 public List<AudioPlaybackConfiguration> getActivePlaybackConfigurations() { 12339 final boolean isPrivileged = 12340 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 12341 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 12342 return mPlaybackMonitor.getActivePlaybackConfigurations(isPrivileged); 12343 } 12344 trackPlayer(PlayerBase.PlayerIdCard pic)12345 public int trackPlayer(PlayerBase.PlayerIdCard pic) { 12346 if (pic != null && pic.mAttributes != null) { 12347 validateAudioAttributesUsage(pic.mAttributes); 12348 } 12349 return mPlaybackMonitor.trackPlayer(pic); 12350 } 12351 playerAttributes(int piid, AudioAttributes attr)12352 public void playerAttributes(int piid, AudioAttributes attr) { 12353 if (attr != null) { 12354 validateAudioAttributesUsage(attr); 12355 } 12356 mPlaybackMonitor.playerAttributes(piid, attr, Binder.getCallingUid()); 12357 } 12358 12359 /** 12360 * Update player session ID 12361 * @param piid Player id to update 12362 * @param sessionId The new audio session ID 12363 */ playerSessionId(int piid, int sessionId)12364 public void playerSessionId(int piid, int sessionId) { 12365 if (sessionId <= AudioSystem.AUDIO_SESSION_ALLOCATE) { 12366 throw new IllegalArgumentException("invalid session Id " + sessionId); 12367 } 12368 mPlaybackMonitor.playerSessionId(piid, sessionId, Binder.getCallingUid()); 12369 } 12370 12371 /** 12372 * Update player event 12373 * @param piid Player id to update 12374 * @param event The new player event 12375 * @param eventValue The value associated with this event 12376 */ playerEvent(int piid, int event, int eventValue)12377 public void playerEvent(int piid, int event, int eventValue) { 12378 mPlaybackMonitor.playerEvent(piid, event, eventValue, Binder.getCallingUid()); 12379 } 12380 12381 /** 12382 * Update event for port id 12383 * @param portId Port id to update 12384 * @param event The new event for the given port 12385 * @param extras Bundle of extra values to describe the event 12386 */ portEvent(int portId, int event, @Nullable PersistableBundle extras)12387 public void portEvent(int portId, int event, @Nullable PersistableBundle extras) { 12388 mPlaybackMonitor.portEvent(portId, event, extras, Binder.getCallingUid()); 12389 } 12390 playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio)12391 public void playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio) { 12392 mPlaybackMonitor.playerHasOpPlayAudio(piid, hasOpPlayAudio, Binder.getCallingUid()); 12393 } 12394 releasePlayer(int piid)12395 public void releasePlayer(int piid) { 12396 mPlaybackMonitor.releasePlayer(piid, Binder.getCallingUid()); 12397 } 12398 12399 /** 12400 * Specifies whether the audio played by this app may or may not be captured by other apps or 12401 * the system. 12402 * 12403 * @param capturePolicy one of 12404 * {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}, 12405 * {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM}, 12406 * {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}. 12407 * @return AudioSystem.AUDIO_STATUS_OK if set allowed capture policy succeed. 12408 * @throws IllegalArgumentException if the argument is not a valid value. 12409 */ setAllowedCapturePolicy(int capturePolicy)12410 public int setAllowedCapturePolicy(int capturePolicy) { 12411 int callingUid = Binder.getCallingUid(); 12412 int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0); 12413 final long identity = Binder.clearCallingIdentity(); 12414 try { 12415 synchronized (mPlaybackMonitor) { 12416 int result = mAudioSystem.setAllowedCapturePolicy(callingUid, flags); 12417 if (result == AudioSystem.AUDIO_STATUS_OK) { 12418 mPlaybackMonitor.setAllowedCapturePolicy(callingUid, capturePolicy); 12419 } 12420 return result; 12421 } 12422 } finally { 12423 Binder.restoreCallingIdentity(identity); 12424 } 12425 } 12426 12427 /** 12428 * Return the capture policy. 12429 * @return the cached capture policy for the calling uid. 12430 */ getAllowedCapturePolicy()12431 public int getAllowedCapturePolicy() { 12432 int callingUid = Binder.getCallingUid(); 12433 final long identity = Binder.clearCallingIdentity(); 12434 try { 12435 return mPlaybackMonitor.getAllowedCapturePolicy(callingUid); 12436 } finally { 12437 Binder.restoreCallingIdentity(identity); 12438 } 12439 } 12440 12441 /* package */ isPlaybackActiveForUid(int uid)12442 boolean isPlaybackActiveForUid(int uid) { 12443 return mPlaybackMonitor.isPlaybackActiveForUid(uid); 12444 } 12445 12446 /* package */ isRecordingActiveForUid(int uid)12447 boolean isRecordingActiveForUid(int uid) { 12448 return mRecordMonitor.isRecordingActiveForUid(uid); 12449 } 12450 12451 //====================== 12452 // Audio device management 12453 //====================== 12454 private final AudioDeviceBroker mDeviceBroker; 12455 12456 //====================== 12457 // Audio policy proxy 12458 //====================== 12459 private static final class AudioDeviceArray { 12460 final @NonNull int[] mDeviceTypes; 12461 final @NonNull String[] mDeviceAddresses; AudioDeviceArray(@onNull int[] types, @NonNull String[] addresses)12462 AudioDeviceArray(@NonNull int[] types, @NonNull String[] addresses) { 12463 mDeviceTypes = types; 12464 mDeviceAddresses = addresses; 12465 } 12466 } 12467 12468 /** 12469 * This internal class inherits from AudioPolicyConfig, each instance contains all the 12470 * mixes of an AudioPolicy and their configurations. 12471 */ 12472 public class AudioPolicyProxy extends AudioPolicyConfig implements IBinder.DeathRecipient { 12473 private static final String TAG = "AudioPolicyProxy"; 12474 final IAudioPolicyCallback mPolicyCallback; 12475 final boolean mHasFocusListener; 12476 final boolean mIsVolumeController; 12477 final HashMap<Integer, AudioDeviceArray> mUidDeviceAffinities = 12478 new HashMap<Integer, AudioDeviceArray>(); 12479 12480 final HashMap<Integer, AudioDeviceArray> mUserIdDeviceAffinities = 12481 new HashMap<>(); 12482 12483 final IMediaProjection mProjection; 12484 private final class UnregisterOnStopCallback extends IMediaProjectionCallback.Stub { onStop()12485 public void onStop() { 12486 unregisterAudioPolicyAsync(mPolicyCallback); 12487 } 12488 12489 @Override onCapturedContentResize(int width, int height)12490 public void onCapturedContentResize(int width, int height) { 12491 // Ignore resize of the captured content. 12492 } 12493 12494 @Override onCapturedContentVisibilityChanged(boolean isVisible)12495 public void onCapturedContentVisibilityChanged(boolean isVisible) { 12496 // Ignore visibility changes of the captured content. 12497 } 12498 }; 12499 UnregisterOnStopCallback mProjectionCallback; 12500 12501 /** 12502 * Audio focus ducking behavior for an audio policy. 12503 * This variable reflects the value that was successfully set in 12504 * {@link AudioService#setFocusPropertiesForPolicy(int, IAudioPolicyCallback)}. This 12505 * implies that a value of FOCUS_POLICY_DUCKING_IN_POLICY means the corresponding policy 12506 * is handling ducking for audio focus. 12507 */ 12508 int mFocusDuckBehavior = AudioPolicy.FOCUS_POLICY_DUCKING_DEFAULT; 12509 boolean mIsFocusPolicy = false; 12510 boolean mIsTestFocusPolicy = false; 12511 AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)12512 AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, 12513 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, 12514 boolean isVolumeController, IMediaProjection projection) { 12515 super(config); 12516 setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++)); 12517 mPolicyCallback = token; 12518 mHasFocusListener = hasFocusListener; 12519 mIsVolumeController = isVolumeController; 12520 mProjection = projection; 12521 if (mHasFocusListener) { 12522 mMediaFocusControl.addFocusFollower(mPolicyCallback); 12523 // can only ever be true if there is a focus listener 12524 if (isFocusPolicy) { 12525 mIsFocusPolicy = true; 12526 mIsTestFocusPolicy = isTestFocusPolicy; 12527 mMediaFocusControl.setFocusPolicy(mPolicyCallback, mIsTestFocusPolicy); 12528 } 12529 } 12530 if (mIsVolumeController) { 12531 setExtVolumeController(mPolicyCallback); 12532 } 12533 if (mProjection != null) { 12534 mProjectionCallback = new UnregisterOnStopCallback(); 12535 try { 12536 mProjection.registerCallback(mProjectionCallback); 12537 } catch (RemoteException e) { 12538 release(); 12539 throw new IllegalStateException("MediaProjection callback registration failed, " 12540 + "could not link to " + projection + " binder death", e); 12541 } 12542 } 12543 int status = connectMixes(); 12544 if (status != AudioSystem.SUCCESS) { 12545 release(); 12546 throw new IllegalStateException("Could not connect mix, error: " + status); 12547 } 12548 } 12549 binderDied()12550 public void binderDied() { 12551 mDynPolicyLogger.enqueue((new EventLogger.StringEvent("AudioPolicy " 12552 + mPolicyCallback.asBinder() + " died").printLog(TAG))); 12553 12554 List<String> addresses = new ArrayList<>(); 12555 for (AudioMix mix : mMixes) { 12556 addresses.add(mix.getRegistration()); 12557 } 12558 onPolicyClientDeath(addresses); 12559 12560 release(); 12561 } 12562 getRegistrationId()12563 String getRegistrationId() { 12564 return getRegistration(); 12565 } 12566 release()12567 void release() { 12568 if (mIsFocusPolicy) { 12569 mMediaFocusControl.unsetFocusPolicy(mPolicyCallback, mIsTestFocusPolicy); 12570 } 12571 if (mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 12572 mMediaFocusControl.setDuckingInExtPolicyAvailable(false); 12573 } 12574 if (mHasFocusListener) { 12575 mMediaFocusControl.removeFocusFollower(mPolicyCallback); 12576 } 12577 if (mProjectionCallback != null) { 12578 try { 12579 mProjection.unregisterCallback(mProjectionCallback); 12580 } catch (RemoteException e) { 12581 Log.e(TAG, "Fail to unregister Audiopolicy callback from MediaProjection"); 12582 } 12583 } 12584 if (mIsVolumeController) { 12585 synchronized (mExtVolumeControllerLock) { 12586 mExtVolumeController = null; 12587 } 12588 } 12589 final long identity = Binder.clearCallingIdentity(); 12590 try { 12591 mAudioSystem.registerPolicyMixes(mMixes, false); 12592 } finally { 12593 Binder.restoreCallingIdentity(identity); 12594 } 12595 synchronized (mAudioPolicies) { 12596 mAudioPolicies.remove(mPolicyCallback.asBinder()); 12597 } 12598 try { 12599 mPolicyCallback.notifyUnregistration(); 12600 } catch (RemoteException e) { } 12601 } 12602 hasMixAffectingUsage(int usage, int excludedFlags)12603 boolean hasMixAffectingUsage(int usage, int excludedFlags) { 12604 for (AudioMix mix : mMixes) { 12605 if (mix.isAffectingUsage(usage) 12606 && ((mix.getRouteFlags() & excludedFlags) != excludedFlags)) { 12607 return true; 12608 } 12609 } 12610 return false; 12611 } 12612 12613 // Verify all the devices in the array are served by mixes defined in this policy hasMixRoutedToDevices(@onNull int[] deviceTypes, @NonNull String[] deviceAddresses)12614 boolean hasMixRoutedToDevices(@NonNull int[] deviceTypes, 12615 @NonNull String[] deviceAddresses) { 12616 for (int i = 0; i < deviceTypes.length; i++) { 12617 boolean hasDevice = false; 12618 for (AudioMix mix : mMixes) { 12619 // this will check both that the mix has ROUTE_FLAG_RENDER and the device 12620 // is reached by this mix 12621 if (mix.isRoutedToDevice(deviceTypes[i], deviceAddresses[i])) { 12622 hasDevice = true; 12623 break; 12624 } 12625 } 12626 if (!hasDevice) { 12627 return false; 12628 } 12629 } 12630 return true; 12631 } 12632 addMixes(@onNull ArrayList<AudioMix> mixes)12633 int addMixes(@NonNull ArrayList<AudioMix> mixes) { 12634 synchronized (mMixes) { 12635 this.add(mixes); 12636 return mAudioSystem.registerPolicyMixes(mixes, true); 12637 } 12638 } 12639 removeMixes(@onNull ArrayList<AudioMix> mixes)12640 int removeMixes(@NonNull ArrayList<AudioMix> mixes) { 12641 synchronized (mMixes) { 12642 this.remove(mixes); 12643 return mAudioSystem.registerPolicyMixes(mixes, false); 12644 } 12645 } 12646 connectMixes()12647 @AudioSystem.AudioSystemError int connectMixes() { 12648 final long identity = Binder.clearCallingIdentity(); 12649 try { 12650 return mAudioSystem.registerPolicyMixes(mMixes, true); 12651 } finally { 12652 Binder.restoreCallingIdentity(identity); 12653 } 12654 12655 } 12656 setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses)12657 int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) { 12658 final Integer Uid = new Integer(uid); 12659 if (mUidDeviceAffinities.remove(Uid) != null) { 12660 if (removeUidDeviceAffinitiesFromSystem(uid) != AudioSystem.SUCCESS) { 12661 Log.e(TAG, "AudioSystem. removeUidDeviceAffinities(" + uid + ") failed, " 12662 + " cannot call AudioSystem.setUidDeviceAffinities"); 12663 return AudioManager.ERROR; 12664 } 12665 } 12666 AudioDeviceArray deviceArray = new AudioDeviceArray(types, addresses); 12667 if (setUidDeviceAffinitiesOnSystem(uid, deviceArray) == AudioSystem.SUCCESS) { 12668 mUidDeviceAffinities.put(Uid, deviceArray); 12669 return AudioManager.SUCCESS; 12670 } 12671 Log.e(TAG, "AudioSystem. setUidDeviceAffinities(" + uid + ") failed"); 12672 return AudioManager.ERROR; 12673 } 12674 removeUidDeviceAffinities(int uid)12675 int removeUidDeviceAffinities(int uid) { 12676 if (mUidDeviceAffinities.remove(new Integer(uid)) != null) { 12677 if (removeUidDeviceAffinitiesFromSystem(uid) == AudioSystem.SUCCESS) { 12678 return AudioManager.SUCCESS; 12679 } 12680 } 12681 Log.e(TAG, "AudioSystem. removeUidDeviceAffinities failed"); 12682 return AudioManager.ERROR; 12683 } 12684 removeUidDeviceAffinitiesFromSystem(int uid)12685 @AudioSystem.AudioSystemError private int removeUidDeviceAffinitiesFromSystem(int uid) { 12686 final long identity = Binder.clearCallingIdentity(); 12687 try { 12688 return mAudioSystem.removeUidDeviceAffinities(uid); 12689 } finally { 12690 Binder.restoreCallingIdentity(identity); 12691 } 12692 } 12693 setUidDeviceAffinitiesOnSystem(int uid, AudioDeviceArray deviceArray)12694 @AudioSystem.AudioSystemError private int setUidDeviceAffinitiesOnSystem(int uid, 12695 AudioDeviceArray deviceArray) { 12696 final long identity = Binder.clearCallingIdentity(); 12697 try { 12698 return mAudioSystem.setUidDeviceAffinities(uid, deviceArray.mDeviceTypes, 12699 deviceArray.mDeviceAddresses); 12700 } finally { 12701 Binder.restoreCallingIdentity(identity); 12702 } 12703 } 12704 setUserIdDeviceAffinities(int userId, @NonNull int[] types, @NonNull String[] addresses)12705 int setUserIdDeviceAffinities(int userId, 12706 @NonNull int[] types, @NonNull String[] addresses) { 12707 final Integer UserId = new Integer(userId); 12708 if (mUserIdDeviceAffinities.remove(UserId) != null) { 12709 if (removeUserIdDeviceAffinitiesFromSystem(userId) != AudioSystem.SUCCESS) { 12710 Log.e(TAG, "AudioSystem. removeUserIdDeviceAffinities(" 12711 + UserId + ") failed, " 12712 + " cannot call AudioSystem.setUserIdDeviceAffinities"); 12713 return AudioManager.ERROR; 12714 } 12715 } 12716 AudioDeviceArray audioDeviceArray = new AudioDeviceArray(types, addresses); 12717 if (setUserIdDeviceAffinitiesOnSystem(userId, audioDeviceArray) 12718 == AudioSystem.SUCCESS) { 12719 mUserIdDeviceAffinities.put(UserId, audioDeviceArray); 12720 return AudioManager.SUCCESS; 12721 } 12722 Log.e(TAG, "AudioSystem.setUserIdDeviceAffinities(" + userId + ") failed"); 12723 return AudioManager.ERROR; 12724 } 12725 removeUserIdDeviceAffinities(int userId)12726 int removeUserIdDeviceAffinities(int userId) { 12727 if (mUserIdDeviceAffinities.remove(new Integer(userId)) != null) { 12728 if (removeUserIdDeviceAffinitiesFromSystem(userId) == AudioSystem.SUCCESS) { 12729 return AudioManager.SUCCESS; 12730 } 12731 } 12732 Log.e(TAG, "AudioSystem.removeUserIdDeviceAffinities failed"); 12733 return AudioManager.ERROR; 12734 } 12735 removeUserIdDeviceAffinitiesFromSystem( @serIdInt int userId)12736 @AudioSystem.AudioSystemError private int removeUserIdDeviceAffinitiesFromSystem( 12737 @UserIdInt int userId) { 12738 final long identity = Binder.clearCallingIdentity(); 12739 try { 12740 return mAudioSystem.removeUserIdDeviceAffinities(userId); 12741 } finally { 12742 Binder.restoreCallingIdentity(identity); 12743 } 12744 } 12745 setUserIdDeviceAffinitiesOnSystem( @serIdInt int userId, AudioDeviceArray deviceArray)12746 @AudioSystem.AudioSystemError private int setUserIdDeviceAffinitiesOnSystem( 12747 @UserIdInt int userId, AudioDeviceArray deviceArray) { 12748 final long identity = Binder.clearCallingIdentity(); 12749 try { 12750 return mAudioSystem.setUserIdDeviceAffinities(userId, deviceArray.mDeviceTypes, 12751 deviceArray.mDeviceAddresses); 12752 } finally { 12753 Binder.restoreCallingIdentity(identity); 12754 } 12755 } 12756 setupDeviceAffinities()12757 @AudioSystem.AudioSystemError int setupDeviceAffinities() { 12758 for (Map.Entry<Integer, AudioDeviceArray> uidEntry : mUidDeviceAffinities.entrySet()) { 12759 int uidStatus = removeUidDeviceAffinitiesFromSystem(uidEntry.getKey()); 12760 if (uidStatus != AudioSystem.SUCCESS) { 12761 Log.e(TAG, 12762 "setupDeviceAffinities failed to remove device affinity for uid " 12763 + uidEntry.getKey()); 12764 return uidStatus; 12765 } 12766 uidStatus = setUidDeviceAffinitiesOnSystem(uidEntry.getKey(), uidEntry.getValue()); 12767 if (uidStatus != AudioSystem.SUCCESS) { 12768 Log.e(TAG, 12769 "setupDeviceAffinities failed to set device affinity for uid " 12770 + uidEntry.getKey()); 12771 return uidStatus; 12772 } 12773 } 12774 12775 for (Map.Entry<Integer, AudioDeviceArray> userIdEntry : 12776 mUserIdDeviceAffinities.entrySet()) { 12777 int userIdStatus = removeUserIdDeviceAffinitiesFromSystem(userIdEntry.getKey()); 12778 if (userIdStatus != AudioSystem.SUCCESS) { 12779 Log.e(TAG, 12780 "setupDeviceAffinities failed to remove device affinity for userId " 12781 + userIdEntry.getKey()); 12782 return userIdStatus; 12783 } 12784 userIdStatus = setUserIdDeviceAffinitiesOnSystem(userIdEntry.getKey(), 12785 userIdEntry.getValue()); 12786 if (userIdStatus != AudioSystem.SUCCESS) { 12787 Log.e(TAG, 12788 "setupDeviceAffinities failed to set device affinity for userId " 12789 + userIdEntry.getKey()); 12790 return userIdStatus; 12791 } 12792 } 12793 return AudioSystem.SUCCESS; 12794 } 12795 12796 /** @return human readable debug informations summarizing the state of the object. */ toLogFriendlyString()12797 public String toLogFriendlyString() { 12798 String textDump = super.toLogFriendlyString(); 12799 textDump += " Uid Device Affinities:\n"; 12800 String spacer = " "; 12801 textDump += logFriendlyAttributeDeviceArrayMap("Uid", 12802 mUidDeviceAffinities, spacer); 12803 textDump += " UserId Device Affinities:\n"; 12804 textDump += logFriendlyAttributeDeviceArrayMap("UserId", 12805 mUserIdDeviceAffinities, spacer); 12806 textDump += " Proxy:\n"; 12807 textDump += " is focus policy= " + mIsFocusPolicy + "\n"; 12808 if (mIsFocusPolicy) { 12809 textDump += " focus duck behaviour= " + mFocusDuckBehavior + "\n"; 12810 textDump += " is test focus policy= " + mIsTestFocusPolicy + "\n"; 12811 textDump += " has focus listener= " + mHasFocusListener + "\n"; 12812 } 12813 textDump += " media projection= " + mProjection + "\n"; 12814 return textDump; 12815 } 12816 logFriendlyAttributeDeviceArrayMap(String attribute, Map<Integer, AudioDeviceArray> map, String spacer)12817 private String logFriendlyAttributeDeviceArrayMap(String attribute, 12818 Map<Integer, AudioDeviceArray> map, String spacer) { 12819 final StringBuilder stringBuilder = new StringBuilder(); 12820 for (Map.Entry<Integer, AudioDeviceArray> mapEntry : map.entrySet()) { 12821 stringBuilder.append(spacer).append(attribute).append(": ") 12822 .append(mapEntry.getKey()).append("\n"); 12823 AudioDeviceArray deviceArray = mapEntry.getValue(); 12824 String deviceSpacer = spacer + " "; 12825 for (int i = 0; i < deviceArray.mDeviceTypes.length; i++) { 12826 stringBuilder.append(deviceSpacer).append("Type: 0x") 12827 .append(Integer.toHexString(deviceArray.mDeviceTypes[i])) 12828 .append(" Address: ").append(deviceArray.mDeviceAddresses[i]) 12829 .append("\n"); 12830 } 12831 } 12832 return stringBuilder.toString(); 12833 } 12834 }; 12835 12836 //====================== 12837 // Audio policy: focus 12838 //====================== 12839 /** */ dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb)12840 public int dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb) { 12841 if (afi == null) { 12842 throw new IllegalArgumentException("Illegal null AudioFocusInfo"); 12843 } 12844 if (pcb == null) { 12845 throw new IllegalArgumentException("Illegal null AudioPolicy callback"); 12846 } 12847 synchronized (mAudioPolicies) { 12848 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 12849 throw new IllegalStateException("Unregistered AudioPolicy for focus dispatch"); 12850 } 12851 return mMediaFocusControl.dispatchFocusChange(afi, focusChange); 12852 } 12853 } 12854 setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, IAudioPolicyCallback pcb)12855 public void setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, 12856 IAudioPolicyCallback pcb) { 12857 if (afi == null) { 12858 throw new IllegalArgumentException("Illegal null AudioFocusInfo"); 12859 } 12860 if (pcb == null) { 12861 throw new IllegalArgumentException("Illegal null AudioPolicy callback"); 12862 } 12863 synchronized (mAudioPolicies) { 12864 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 12865 throw new IllegalStateException("Unregistered AudioPolicy for external focus"); 12866 } 12867 mMediaFocusControl.setFocusRequestResultFromExtPolicy(afi, requestResult); 12868 } 12869 } 12870 12871 12872 //====================== 12873 // Audioserver state dispatch 12874 //====================== 12875 private class AsdProxy implements IBinder.DeathRecipient { 12876 private final IAudioServerStateDispatcher mAsd; 12877 AsdProxy(IAudioServerStateDispatcher asd)12878 AsdProxy(IAudioServerStateDispatcher asd) { 12879 mAsd = asd; 12880 } 12881 binderDied()12882 public void binderDied() { 12883 synchronized (mAudioServerStateListeners) { 12884 mAudioServerStateListeners.remove(mAsd.asBinder()); 12885 } 12886 } 12887 callback()12888 IAudioServerStateDispatcher callback() { 12889 return mAsd; 12890 } 12891 } 12892 12893 private final HashMap<IBinder, AsdProxy> mAudioServerStateListeners = 12894 new HashMap<IBinder, AsdProxy>(); 12895 checkMonitorAudioServerStatePermission()12896 private void checkMonitorAudioServerStatePermission() { 12897 if (!(mContext.checkCallingOrSelfPermission( 12898 android.Manifest.permission.MODIFY_PHONE_STATE) == 12899 PackageManager.PERMISSION_GRANTED || 12900 mContext.checkCallingOrSelfPermission( 12901 android.Manifest.permission.MODIFY_AUDIO_ROUTING) == 12902 PackageManager.PERMISSION_GRANTED)) { 12903 throw new SecurityException("Not allowed to monitor audioserver state"); 12904 } 12905 } 12906 registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd)12907 public void registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd) { 12908 checkMonitorAudioServerStatePermission(); 12909 synchronized (mAudioServerStateListeners) { 12910 if (mAudioServerStateListeners.containsKey(asd.asBinder())) { 12911 Slog.w(TAG, "Cannot re-register audio server state dispatcher"); 12912 return; 12913 } 12914 AsdProxy asdp = new AsdProxy(asd); 12915 try { 12916 asd.asBinder().linkToDeath(asdp, 0/*flags*/); 12917 } catch (RemoteException e) { 12918 12919 } 12920 mAudioServerStateListeners.put(asd.asBinder(), asdp); 12921 } 12922 } 12923 unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd)12924 public void unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd) { 12925 checkMonitorAudioServerStatePermission(); 12926 synchronized (mAudioServerStateListeners) { 12927 AsdProxy asdp = mAudioServerStateListeners.remove(asd.asBinder()); 12928 if (asdp == null) { 12929 Slog.w(TAG, "Trying to unregister unknown audioserver state dispatcher for pid " 12930 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()); 12931 return; 12932 } else { 12933 asd.asBinder().unlinkToDeath(asdp, 0/*flags*/); 12934 } 12935 } 12936 } 12937 isAudioServerRunning()12938 public boolean isAudioServerRunning() { 12939 checkMonitorAudioServerStatePermission(); 12940 return (AudioSystem.checkAudioFlinger() == AudioSystem.AUDIO_STATUS_OK); 12941 } 12942 12943 //====================== 12944 // Audio HAL process dump 12945 //====================== 12946 12947 private static final String AUDIO_HAL_SERVICE_PREFIX = "android.hardware.audio"; 12948 getAudioAidlHalPids(HashSet<Integer> pids)12949 private void getAudioAidlHalPids(HashSet<Integer> pids) { 12950 try { 12951 ServiceDebugInfo[] infos = ServiceManager.getServiceDebugInfo(); 12952 if (infos == null) return; 12953 for (ServiceDebugInfo info : infos) { 12954 if (info.debugPid > 0 && info.name.startsWith(AUDIO_HAL_SERVICE_PREFIX)) { 12955 pids.add(info.debugPid); 12956 } 12957 } 12958 } catch (RuntimeException e) { 12959 // ignored, pid hashset does not change 12960 } 12961 } 12962 getAudioHalHidlPids(HashSet<Integer> pids)12963 private void getAudioHalHidlPids(HashSet<Integer> pids) { 12964 try { 12965 IServiceManager serviceManager = IServiceManager.getService(); 12966 ArrayList<IServiceManager.InstanceDebugInfo> dump = 12967 serviceManager.debugDump(); 12968 for (IServiceManager.InstanceDebugInfo info : dump) { 12969 if (info.pid != IServiceManager.PidConstant.NO_PID 12970 && info.interfaceName != null 12971 && info.interfaceName.startsWith(AUDIO_HAL_SERVICE_PREFIX)) { 12972 pids.add(info.pid); 12973 } 12974 } 12975 } catch (RemoteException | RuntimeException e) { 12976 // ignored, pid hashset does not change 12977 } 12978 } 12979 getAudioHalPids()12980 private Set<Integer> getAudioHalPids() { 12981 HashSet<Integer> pids = new HashSet<>(); 12982 getAudioAidlHalPids(pids); 12983 getAudioHalHidlPids(pids); 12984 return pids; 12985 } 12986 updateAudioHalPids()12987 private void updateAudioHalPids() { 12988 Set<Integer> pidsSet = getAudioHalPids(); 12989 if (pidsSet.isEmpty()) { 12990 Slog.w(TAG, "Could not retrieve audio HAL service pids"); 12991 return; 12992 } 12993 int[] pidsArray = pidsSet.stream().mapToInt(Integer::intValue).toArray(); 12994 AudioSystem.setAudioHalPids(pidsArray); 12995 } 12996 12997 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 12998 //====================== 12999 // Multi Audio Focus 13000 //====================== setMultiAudioFocusEnabled(boolean enabled)13001 public void setMultiAudioFocusEnabled(boolean enabled) { 13002 super.setMultiAudioFocusEnabled_enforcePermission(); 13003 13004 if (mMediaFocusControl != null) { 13005 boolean mafEnabled = mMediaFocusControl.getMultiAudioFocusEnabled(); 13006 if (mafEnabled != enabled) { 13007 mMediaFocusControl.updateMultiAudioFocus(enabled); 13008 if (!enabled) { 13009 mDeviceBroker.postBroadcastBecomingNoisy(); 13010 } 13011 } 13012 } 13013 } 13014 13015 /** 13016 * @hide 13017 * Sets an additional audio output device delay in milliseconds. 13018 * 13019 * The additional output delay is a request to the output device to 13020 * delay audio presentation (generally with respect to video presentation for better 13021 * synchronization). 13022 * It may not be supported by all output devices, 13023 * and typically increases the audio latency by the amount of additional 13024 * audio delay requested. 13025 * 13026 * If additional audio delay is supported by an audio output device, 13027 * it is expected to be supported for all output streams (and configurations) 13028 * opened on that device. 13029 * 13030 * @param deviceType 13031 * @param address 13032 * @param delayMillis delay in milliseconds desired. This should be in range of {@code 0} 13033 * to the value returned by {@link #getMaxAdditionalOutputDeviceDelay()}. 13034 * @return true if successful, false if the device does not support output device delay 13035 * or the delay is not in range of {@link #getMaxAdditionalOutputDeviceDelay()}. 13036 */ 13037 @Override 13038 //@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) setAdditionalOutputDeviceDelay( @onNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis)13039 public boolean setAdditionalOutputDeviceDelay( 13040 @NonNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis) { 13041 Objects.requireNonNull(device, "device must not be null"); 13042 enforceModifyAudioRoutingPermission(); 13043 final String getterKey = "additional_output_device_delay=" 13044 + device.getInternalType() + "," + device.getAddress(); // "getter" key as an id. 13045 final String setterKey = getterKey + "," + delayMillis; // append the delay for setter 13046 return mRestorableParameters.setParameters(getterKey, setterKey) 13047 == AudioSystem.AUDIO_STATUS_OK; 13048 } 13049 13050 /** 13051 * @hide 13052 * Returns the current additional audio output device delay in milliseconds. 13053 * 13054 * @param deviceType 13055 * @param address 13056 * @return the additional output device delay. This is a non-negative number. 13057 * {@code 0} is returned if unsupported. 13058 */ 13059 @Override 13060 @IntRange(from = 0) getAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)13061 public long getAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) { 13062 Objects.requireNonNull(device, "device must not be null"); 13063 final String key = "additional_output_device_delay"; 13064 final String reply = AudioSystem.getParameters( 13065 key + "=" + device.getInternalType() + "," + device.getAddress()); 13066 long delayMillis; 13067 try { 13068 delayMillis = Long.parseLong(reply.substring(key.length() + 1)); 13069 } catch (NullPointerException e) { 13070 delayMillis = 0; 13071 } 13072 return delayMillis; 13073 } 13074 13075 /** 13076 * @hide 13077 * Returns the maximum additional audio output device delay in milliseconds. 13078 * 13079 * @param deviceType 13080 * @param address 13081 * @return the maximum output device delay in milliseconds that can be set. 13082 * This is a non-negative number 13083 * representing the additional audio delay supported for the device. 13084 * {@code 0} is returned if unsupported. 13085 */ 13086 @Override 13087 @IntRange(from = 0) getMaxAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)13088 public long getMaxAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) { 13089 Objects.requireNonNull(device, "device must not be null"); 13090 final String key = "max_additional_output_device_delay"; 13091 final String reply = AudioSystem.getParameters( 13092 key + "=" + device.getInternalType() + "," + device.getAddress()); 13093 long delayMillis; 13094 try { 13095 delayMillis = Long.parseLong(reply.substring(key.length() + 1)); 13096 } catch (NullPointerException e) { 13097 delayMillis = 0; 13098 } 13099 return delayMillis; 13100 } 13101 13102 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 13103 /** @see AudioManager#addAssistantServicesUids(int []) */ 13104 @Override addAssistantServicesUids(int [] assistantUids)13105 public void addAssistantServicesUids(int [] assistantUids) { 13106 super.addAssistantServicesUids_enforcePermission(); 13107 13108 Objects.requireNonNull(assistantUids); 13109 13110 synchronized (mSettingsLock) { 13111 addAssistantServiceUidsLocked(assistantUids); 13112 } 13113 } 13114 13115 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 13116 /** @see AudioManager#removeAssistantServicesUids(int []) */ 13117 @Override removeAssistantServicesUids(int [] assistantUids)13118 public void removeAssistantServicesUids(int [] assistantUids) { 13119 super.removeAssistantServicesUids_enforcePermission(); 13120 13121 Objects.requireNonNull(assistantUids); 13122 synchronized (mSettingsLock) { 13123 removeAssistantServiceUidsLocked(assistantUids); 13124 } 13125 } 13126 13127 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 13128 /** @see AudioManager#getAssistantServicesUids() */ 13129 @Override getAssistantServicesUids()13130 public int[] getAssistantServicesUids() { 13131 super.getAssistantServicesUids_enforcePermission(); 13132 13133 int [] assistantUids; 13134 synchronized (mSettingsLock) { 13135 assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray(); 13136 } 13137 return assistantUids; 13138 } 13139 13140 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 13141 /** @see AudioManager#setActiveAssistantServiceUids(int []) */ 13142 @Override setActiveAssistantServiceUids(int [] activeAssistantUids)13143 public void setActiveAssistantServiceUids(int [] activeAssistantUids) { 13144 super.setActiveAssistantServiceUids_enforcePermission(); 13145 13146 Objects.requireNonNull(activeAssistantUids); 13147 synchronized (mSettingsLock) { 13148 mActiveAssistantServiceUids = activeAssistantUids; 13149 } 13150 updateActiveAssistantServiceUids(); 13151 } 13152 13153 @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 13154 /** @see AudioManager#getActiveAssistantServiceUids() */ 13155 @Override getActiveAssistantServiceUids()13156 public int[] getActiveAssistantServiceUids() { 13157 super.getActiveAssistantServiceUids_enforcePermission(); 13158 13159 int [] activeAssistantUids; 13160 synchronized (mSettingsLock) { 13161 activeAssistantUids = mActiveAssistantServiceUids.clone(); 13162 } 13163 return activeAssistantUids; 13164 } 13165 getDeviceSensorUuid(AudioDeviceAttributes device)13166 UUID getDeviceSensorUuid(AudioDeviceAttributes device) { 13167 return mDeviceBroker.getDeviceSensorUuid(device); 13168 } 13169 13170 //====================== 13171 // misc 13172 //====================== 13173 private final HashMap<IBinder, AudioPolicyProxy> mAudioPolicies = 13174 new HashMap<IBinder, AudioPolicyProxy>(); 13175 @GuardedBy("mAudioPolicies") 13176 private int mAudioPolicyCounter = 0; 13177 13178 //====================== 13179 // Helper functions for full and fixed volume device 13180 //====================== isFixedVolumeDevice(int deviceType)13181 private boolean isFixedVolumeDevice(int deviceType) { 13182 if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX 13183 && mRecordMonitor.isLegacyRemoteSubmixActive()) { 13184 return false; 13185 } 13186 return mFixedVolumeDevices.contains(deviceType); 13187 } 13188 isFullVolumeDevice(int deviceType)13189 private boolean isFullVolumeDevice(int deviceType) { 13190 if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX 13191 && mRecordMonitor.isLegacyRemoteSubmixActive()) { 13192 return false; 13193 } 13194 return mFullVolumeDevices.contains(deviceType); 13195 } 13196 13197 /** 13198 * Returns whether the input device uses absolute volume behavior, including its variants. 13199 * For included volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}. 13200 * 13201 * This is distinct from Bluetooth A2DP absolute volume behavior 13202 * ({@link #isA2dpAbsoluteVolumeDevice}). 13203 */ isAbsoluteVolumeDevice(int deviceType)13204 private boolean isAbsoluteVolumeDevice(int deviceType) { 13205 return mAbsoluteVolumeDeviceInfoMap.containsKey(deviceType); 13206 } 13207 13208 /** 13209 * Returns whether the input device is a Bluetooth A2dp device that uses absolute volume 13210 * behavior. This is distinct from the general implementation of absolute volume behavior 13211 * ({@link #isAbsoluteVolumeDevice}). 13212 */ isA2dpAbsoluteVolumeDevice(int deviceType)13213 private boolean isA2dpAbsoluteVolumeDevice(int deviceType) { 13214 return mAvrcpAbsVolSupported && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType); 13215 } 13216 13217 //==================== 13218 // Helper functions for {set,get}DeviceVolumeBehavior 13219 //==================== getSettingsNameForDeviceVolumeBehavior(int deviceType)13220 private static String getSettingsNameForDeviceVolumeBehavior(int deviceType) { 13221 return "AudioService_DeviceVolumeBehavior_" + AudioSystem.getOutputDeviceName(deviceType); 13222 } 13223 persistDeviceVolumeBehavior(int deviceType, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior)13224 private void persistDeviceVolumeBehavior(int deviceType, 13225 @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) { 13226 if (DEBUG_VOL) { 13227 Log.d(TAG, "Persisting Volume Behavior for DeviceType: " + deviceType); 13228 } 13229 final long callingIdentity = Binder.clearCallingIdentity(); 13230 try { 13231 mSettings.putSystemIntForUser(mContentResolver, 13232 getSettingsNameForDeviceVolumeBehavior(deviceType), 13233 deviceVolumeBehavior, 13234 UserHandle.USER_CURRENT); 13235 } finally { 13236 Binder.restoreCallingIdentity(callingIdentity); 13237 } 13238 } 13239 13240 @AudioManager.DeviceVolumeBehaviorState retrieveStoredDeviceVolumeBehavior(int deviceType)13241 private int retrieveStoredDeviceVolumeBehavior(int deviceType) { 13242 return mSettings.getSystemIntForUser(mContentResolver, 13243 getSettingsNameForDeviceVolumeBehavior(deviceType), 13244 AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET, 13245 UserHandle.USER_CURRENT); 13246 } 13247 restoreDeviceVolumeBehavior()13248 private void restoreDeviceVolumeBehavior() { 13249 for (int deviceType : AudioSystem.DEVICE_OUT_ALL_SET) { 13250 if (DEBUG_VOL) { 13251 Log.d(TAG, "Retrieving Volume Behavior for DeviceType: " + deviceType); 13252 } 13253 int deviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(deviceType); 13254 if (deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) { 13255 if (DEBUG_VOL) { 13256 Log.d(TAG, "Skipping Setting Volume Behavior for DeviceType: " + deviceType); 13257 } 13258 continue; 13259 } 13260 13261 setDeviceVolumeBehaviorInternal(new AudioDeviceAttributes(deviceType, ""), 13262 deviceVolumeBehavior, "AudioService.restoreDeviceVolumeBehavior()"); 13263 } 13264 } 13265 13266 /** 13267 * @param audioSystemDeviceOut one of AudioSystem.DEVICE_OUT_* 13268 * @return whether {@code audioSystemDeviceOut} has previously been set to a specific volume 13269 * behavior 13270 */ hasDeviceVolumeBehavior( int audioSystemDeviceOut)13271 private boolean hasDeviceVolumeBehavior( 13272 int audioSystemDeviceOut) { 13273 return retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut) 13274 != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET; 13275 } 13276 addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut)13277 private boolean addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut) { 13278 if (DEBUG_VOL) { 13279 Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 13280 + " to mFixedVolumeDevices"); 13281 } 13282 return mFixedVolumeDevices.add(audioSystemDeviceOut); 13283 } 13284 removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut)13285 private boolean removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut) { 13286 if (DEBUG_VOL) { 13287 Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 13288 + " from mFixedVolumeDevices"); 13289 } 13290 return mFixedVolumeDevices.remove(audioSystemDeviceOut); 13291 } 13292 addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut)13293 private boolean addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut) { 13294 if (DEBUG_VOL) { 13295 Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 13296 + " to mFullVolumeDevices"); 13297 } 13298 return mFullVolumeDevices.add(audioSystemDeviceOut); 13299 } 13300 removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut)13301 private boolean removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut) { 13302 if (DEBUG_VOL) { 13303 Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 13304 + " from mFullVolumeDevices"); 13305 } 13306 return mFullVolumeDevices.remove(audioSystemDeviceOut); 13307 } 13308 addAudioSystemDeviceOutToAbsVolumeDevices(int audioSystemDeviceOut, AbsoluteVolumeDeviceInfo info)13309 private void addAudioSystemDeviceOutToAbsVolumeDevices(int audioSystemDeviceOut, 13310 AbsoluteVolumeDeviceInfo info) { 13311 if (DEBUG_VOL) { 13312 Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 13313 + " to mAbsoluteVolumeDeviceInfoMap with behavior " 13314 + AudioDeviceVolumeManager.volumeBehaviorName(info.mDeviceVolumeBehavior) 13315 ); 13316 } 13317 mAbsoluteVolumeDeviceInfoMap.put(audioSystemDeviceOut, info); 13318 } 13319 removeAudioSystemDeviceOutFromAbsVolumeDevices( int audioSystemDeviceOut)13320 private AbsoluteVolumeDeviceInfo removeAudioSystemDeviceOutFromAbsVolumeDevices( 13321 int audioSystemDeviceOut) { 13322 if (DEBUG_VOL) { 13323 Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 13324 + " from mAbsoluteVolumeDeviceInfoMap"); 13325 } 13326 return mAbsoluteVolumeDeviceInfoMap.remove(audioSystemDeviceOut); 13327 } 13328 13329 //==================== 13330 // Helper functions for app ops 13331 //==================== 13332 /** 13333 * Validates, and notes an app op for a given uid and package name. 13334 * Validation comes from exception catching: a security exception indicates the package 13335 * doesn't exist, an IAE indicates the uid and package don't match. The code only checks 13336 * if exception was thrown for robustness to code changes in op validation 13337 * @param op the app op to check 13338 * @param uid the uid of the caller 13339 * @param packageName the package to check 13340 * @return true if the origin of the call is valid (no uid / package mismatch) and the caller 13341 * is allowed to perform the operation 13342 */ checkNoteAppOp(int op, int uid, String packageName, String attributionTag)13343 private boolean checkNoteAppOp(int op, int uid, String packageName, String attributionTag) { 13344 try { 13345 if (mAppOps.noteOp(op, uid, packageName, attributionTag, null) 13346 != AppOpsManager.MODE_ALLOWED) { 13347 return false; 13348 } 13349 } catch (Exception e) { 13350 Log.e(TAG, "Error noting op:" + op + " on uid:" + uid + " for package:" 13351 + packageName, e); 13352 return false; 13353 } 13354 return true; 13355 } 13356 } 13357