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.REMOTE_AUDIO_PLAYBACK; 20 import static android.media.AudioManager.RINGER_MODE_NORMAL; 21 import static android.media.AudioManager.RINGER_MODE_SILENT; 22 import static android.media.AudioManager.RINGER_MODE_VIBRATE; 23 import static android.media.AudioManager.STREAM_SYSTEM; 24 import static android.os.Process.FIRST_APPLICATION_UID; 25 import static android.os.Process.INVALID_UID; 26 import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE; 27 import static android.provider.Settings.Secure.VOLUME_HUSH_OFF; 28 import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE; 29 30 import static com.android.server.audio.AudioEventLogger.Event.ALOGE; 31 import static com.android.server.audio.AudioEventLogger.Event.ALOGI; 32 import static com.android.server.audio.AudioEventLogger.Event.ALOGW; 33 34 import android.Manifest; 35 import android.annotation.IntDef; 36 import android.annotation.IntRange; 37 import android.annotation.NonNull; 38 import android.annotation.Nullable; 39 import android.annotation.RequiresPermission; 40 import android.annotation.SuppressLint; 41 import android.annotation.UserIdInt; 42 import android.app.ActivityManager; 43 import android.app.ActivityManagerInternal; 44 import android.app.ActivityThread; 45 import android.app.AlarmManager; 46 import android.app.AppGlobals; 47 import android.app.AppOpsManager; 48 import android.app.IUidObserver; 49 import android.app.NotificationManager; 50 import android.app.PendingIntent; 51 import android.app.role.OnRoleHoldersChangedListener; 52 import android.app.role.RoleManager; 53 import android.bluetooth.BluetoothAdapter; 54 import android.bluetooth.BluetoothDevice; 55 import android.bluetooth.BluetoothHeadset; 56 import android.bluetooth.BluetoothProfile; 57 import android.content.BroadcastReceiver; 58 import android.content.ComponentName; 59 import android.content.ContentResolver; 60 import android.content.Context; 61 import android.content.Intent; 62 import android.content.IntentFilter; 63 import android.content.pm.ApplicationInfo; 64 import android.content.pm.PackageInfo; 65 import android.content.pm.PackageManager; 66 import android.content.pm.ResolveInfo; 67 import android.content.pm.UserInfo; 68 import android.content.res.Configuration; 69 import android.content.res.Resources; 70 import android.database.ContentObserver; 71 import android.hardware.SensorPrivacyManager; 72 import android.hardware.SensorPrivacyManagerInternal; 73 import android.hardware.hdmi.HdmiAudioSystemClient; 74 import android.hardware.hdmi.HdmiClient; 75 import android.hardware.hdmi.HdmiControlManager; 76 import android.hardware.hdmi.HdmiPlaybackClient; 77 import android.hardware.hdmi.HdmiTvClient; 78 import android.hardware.input.InputManager; 79 import android.hardware.usb.UsbManager; 80 import android.hidl.manager.V1_0.IServiceManager; 81 import android.media.AudioAttributes; 82 import android.media.AudioAttributes.AttributeSystemUsage; 83 import android.media.AudioDeviceAttributes; 84 import android.media.AudioDeviceInfo; 85 import android.media.AudioDeviceVolumeManager; 86 import android.media.AudioFocusInfo; 87 import android.media.AudioFocusRequest; 88 import android.media.AudioFormat; 89 import android.media.AudioManager; 90 import android.media.AudioManagerInternal; 91 import android.media.AudioPlaybackConfiguration; 92 import android.media.AudioRecordingConfiguration; 93 import android.media.AudioRoutesInfo; 94 import android.media.AudioSystem; 95 import android.media.BluetoothProfileConnectionInfo; 96 import android.media.IAudioDeviceVolumeDispatcher; 97 import android.media.IAudioFocusDispatcher; 98 import android.media.IAudioModeDispatcher; 99 import android.media.IAudioRoutesObserver; 100 import android.media.IAudioServerStateDispatcher; 101 import android.media.IAudioService; 102 import android.media.ICapturePresetDevicesRoleDispatcher; 103 import android.media.ICommunicationDeviceDispatcher; 104 import android.media.IDeviceVolumeBehaviorDispatcher; 105 import android.media.IMuteAwaitConnectionCallback; 106 import android.media.IPlaybackConfigDispatcher; 107 import android.media.IRecordingConfigDispatcher; 108 import android.media.IRingtonePlayer; 109 import android.media.ISpatializerCallback; 110 import android.media.ISpatializerHeadToSoundStagePoseCallback; 111 import android.media.ISpatializerHeadTrackerAvailableCallback; 112 import android.media.ISpatializerHeadTrackingModeCallback; 113 import android.media.ISpatializerOutputCallback; 114 import android.media.IStrategyPreferredDevicesDispatcher; 115 import android.media.IVolumeController; 116 import android.media.MediaMetrics; 117 import android.media.MediaRecorder.AudioSource; 118 import android.media.PlayerBase; 119 import android.media.Spatializer; 120 import android.media.VolumeInfo; 121 import android.media.VolumePolicy; 122 import android.media.audiofx.AudioEffect; 123 import android.media.audiopolicy.AudioMix; 124 import android.media.audiopolicy.AudioPolicy; 125 import android.media.audiopolicy.AudioPolicyConfig; 126 import android.media.audiopolicy.AudioProductStrategy; 127 import android.media.audiopolicy.AudioVolumeGroup; 128 import android.media.audiopolicy.IAudioPolicyCallback; 129 import android.media.projection.IMediaProjection; 130 import android.media.projection.IMediaProjectionCallback; 131 import android.media.projection.IMediaProjectionManager; 132 import android.net.Uri; 133 import android.os.Binder; 134 import android.os.Build; 135 import android.os.Bundle; 136 import android.os.Handler; 137 import android.os.HwBinder; 138 import android.os.IBinder; 139 import android.os.Looper; 140 import android.os.Message; 141 import android.os.PowerManager; 142 import android.os.Process; 143 import android.os.RemoteCallbackList; 144 import android.os.RemoteException; 145 import android.os.ResultReceiver; 146 import android.os.ServiceManager; 147 import android.os.ShellCallback; 148 import android.os.SystemClock; 149 import android.os.SystemProperties; 150 import android.os.UserHandle; 151 import android.os.UserManager; 152 import android.os.VibrationAttributes; 153 import android.os.VibrationEffect; 154 import android.os.Vibrator; 155 import android.os.VibratorManager; 156 import android.provider.DeviceConfig; 157 import android.provider.Settings; 158 import android.provider.Settings.System; 159 import android.service.notification.ZenModeConfig; 160 import android.telecom.TelecomManager; 161 import android.text.TextUtils; 162 import android.util.AndroidRuntimeException; 163 import android.util.ArrayMap; 164 import android.util.ArraySet; 165 import android.util.IntArray; 166 import android.util.Log; 167 import android.util.MathUtils; 168 import android.util.PrintWriterPrinter; 169 import android.util.Slog; 170 import android.util.SparseArray; 171 import android.util.SparseIntArray; 172 import android.view.KeyEvent; 173 import android.view.accessibility.AccessibilityManager; 174 import android.widget.Toast; 175 176 import com.android.internal.annotations.GuardedBy; 177 import com.android.internal.annotations.VisibleForTesting; 178 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; 179 import com.android.internal.util.DumpUtils; 180 import com.android.internal.util.Preconditions; 181 import com.android.server.EventLogTags; 182 import com.android.server.LocalServices; 183 import com.android.server.SystemService; 184 import com.android.server.audio.AudioServiceEvents.DeviceVolumeEvent; 185 import com.android.server.audio.AudioServiceEvents.PhoneStateEvent; 186 import com.android.server.audio.AudioServiceEvents.VolChangedBroadcastEvent; 187 import com.android.server.audio.AudioServiceEvents.VolumeEvent; 188 import com.android.server.pm.UserManagerInternal; 189 import com.android.server.pm.UserManagerInternal.UserRestrictionsListener; 190 import com.android.server.pm.UserManagerService; 191 import com.android.server.wm.ActivityTaskManagerInternal; 192 193 import java.io.FileDescriptor; 194 import java.io.PrintWriter; 195 import java.lang.annotation.Retention; 196 import java.lang.annotation.RetentionPolicy; 197 import java.text.SimpleDateFormat; 198 import java.util.ArrayList; 199 import java.util.Arrays; 200 import java.util.Collection; 201 import java.util.Date; 202 import java.util.HashMap; 203 import java.util.HashSet; 204 import java.util.Iterator; 205 import java.util.LinkedHashMap; 206 import java.util.List; 207 import java.util.Map; 208 import java.util.NoSuchElementException; 209 import java.util.Objects; 210 import java.util.Set; 211 import java.util.TreeSet; 212 import java.util.UUID; 213 import java.util.concurrent.Executor; 214 import java.util.concurrent.atomic.AtomicBoolean; 215 import java.util.concurrent.atomic.AtomicInteger; 216 import java.util.function.BooleanSupplier; 217 import java.util.stream.Collectors; 218 219 /** 220 * The implementation of the audio service for volume, audio focus, device management... 221 * <p> 222 * This implementation focuses on delivering a responsive UI. Most methods are 223 * asynchronous to external calls. For example, the task of setting a volume 224 * will update our internal state, but in a separate thread will set the system 225 * volume and later persist to the database. Similarly, setting the ringer mode 226 * will update the state and broadcast a change and in a separate thread later 227 * persist the ringer mode. 228 * 229 * @hide 230 */ 231 public class AudioService extends IAudioService.Stub 232 implements AccessibilityManager.TouchExplorationStateChangeListener, 233 AccessibilityManager.AccessibilityServicesStateChangeListener, 234 AudioSystemAdapter.OnRoutingUpdatedListener, 235 AudioSystemAdapter.OnVolRangeInitRequestListener { 236 237 private static final String TAG = "AS.AudioService"; 238 private static final boolean CONFIG_DEFAULT_VAL = false; 239 240 private final AudioSystemAdapter mAudioSystem; 241 private final SystemServerAdapter mSystemServer; 242 private final SettingsAdapter mSettings; 243 244 /** Debug audio mode */ 245 protected static final boolean DEBUG_MODE = false; 246 247 /** Debug audio policy feature */ 248 protected static final boolean DEBUG_AP = false; 249 250 /** Debug volumes */ 251 protected static final boolean DEBUG_VOL = false; 252 253 /** debug calls to devices APIs */ 254 protected static final boolean DEBUG_DEVICES = false; 255 256 /** Debug communication route */ 257 protected static final boolean DEBUG_COMM_RTE = false; 258 259 /** Debug log sound fx (touchsounds...) in dumpsys */ 260 protected static final boolean DEBUG_LOG_SOUND_FX = false; 261 262 /** How long to delay before persisting a change in volume/ringer mode. */ 263 private static final int PERSIST_DELAY = 500; 264 265 /** How long to delay after a volume down event before unmuting a stream */ 266 private static final int UNMUTE_STREAM_DELAY = 350; 267 268 /** 269 * Delay before disconnecting a device that would cause BECOMING_NOISY intent to be sent, 270 * to give a chance to applications to pause. 271 */ 272 @VisibleForTesting 273 public static final int BECOMING_NOISY_DELAY_MS = 1000; 274 275 /** 276 * Only used in the result from {@link #checkForRingerModeChange(int, int, int)} 277 */ 278 private static final int FLAG_ADJUST_VOLUME = 1; 279 280 final Context mContext; 281 private final ContentResolver mContentResolver; 282 private final AppOpsManager mAppOps; 283 284 // the platform type affects volume and silent mode behavior 285 private final int mPlatformType; 286 287 // indicates whether the system maps all streams to a single stream. 288 private final boolean mIsSingleVolume; 289 290 /** 291 * indicates whether STREAM_NOTIFICATION is aliased to STREAM_RING 292 * not final due to test method, see {@link #setNotifAliasRingForTest(boolean)}. 293 */ 294 private boolean mNotifAliasRing; 295 296 /** 297 * Test method to temporarily override whether STREAM_NOTIFICATION is aliased to STREAM_RING, 298 * volumes will be updated in case of a change. 299 * @param alias if true, STREAM_NOTIFICATION is aliased to STREAM_RING 300 */ setNotifAliasRingForTest(boolean alias)301 /*package*/ void setNotifAliasRingForTest(boolean alias) { 302 boolean update = (mNotifAliasRing != alias); 303 mNotifAliasRing = alias; 304 if (update) { 305 updateStreamVolumeAlias(true, "AudioServiceTest"); 306 } 307 } 308 isPlatformVoice()309 /*package*/ boolean isPlatformVoice() { 310 return mPlatformType == AudioSystem.PLATFORM_VOICE; 311 } 312 isPlatformTelevision()313 /*package*/ boolean isPlatformTelevision() { 314 return mPlatformType == AudioSystem.PLATFORM_TELEVISION; 315 } 316 isPlatformAutomotive()317 /*package*/ boolean isPlatformAutomotive() { 318 return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); 319 } 320 321 /** The controller for the volume UI. */ 322 private final VolumeController mVolumeController = new VolumeController(); 323 324 // sendMsg() flags 325 /** If the msg is already queued, replace it with this one. */ 326 private static final int SENDMSG_REPLACE = 0; 327 /** If the msg is already queued, ignore this one and leave the old. */ 328 private static final int SENDMSG_NOOP = 1; 329 /** If the msg is already queued, queue this one and leave the old. */ 330 private static final int SENDMSG_QUEUE = 2; 331 332 // AudioHandler messages 333 private static final int MSG_SET_DEVICE_VOLUME = 0; 334 private static final int MSG_PERSIST_VOLUME = 1; 335 private static final int MSG_PERSIST_VOLUME_GROUP = 2; 336 private static final int MSG_PERSIST_RINGER_MODE = 3; 337 private static final int MSG_AUDIO_SERVER_DIED = 4; 338 private static final int MSG_PLAY_SOUND_EFFECT = 5; 339 private static final int MSG_LOAD_SOUND_EFFECTS = 7; 340 private static final int MSG_SET_FORCE_USE = 8; 341 private static final int MSG_BT_HEADSET_CNCT_FAILED = 9; 342 private static final int MSG_SET_ALL_VOLUMES = 10; 343 private static final int MSG_CHECK_MUSIC_ACTIVE = 11; 344 private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 12; 345 private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 13; 346 private static final int MSG_PERSIST_SAFE_VOLUME_STATE = 14; 347 private static final int MSG_UNLOAD_SOUND_EFFECTS = 15; 348 private static final int MSG_SYSTEM_READY = 16; 349 private static final int MSG_PERSIST_MUSIC_ACTIVE_MS = 17; 350 private static final int MSG_UNMUTE_STREAM = 18; 351 private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 19; 352 private static final int MSG_INDICATE_SYSTEM_READY = 20; 353 private static final int MSG_ACCESSORY_PLUG_MEDIA_UNMUTE = 21; 354 private static final int MSG_NOTIFY_VOL_EVENT = 22; 355 private static final int MSG_DISPATCH_AUDIO_SERVER_STATE = 23; 356 private static final int MSG_ENABLE_SURROUND_FORMATS = 24; 357 private static final int MSG_UPDATE_RINGER_MODE = 25; 358 private static final int MSG_SET_DEVICE_STREAM_VOLUME = 26; 359 private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27; 360 private static final int MSG_HDMI_VOLUME_CHECK = 28; 361 private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29; 362 private static final int MSG_BROADCAST_MICROPHONE_MUTE = 30; 363 private static final int MSG_CHECK_MODE_FOR_UID = 31; 364 private static final int MSG_STREAM_DEVICES_CHANGED = 32; 365 private static final int MSG_UPDATE_VOLUME_STATES_FOR_DEVICE = 33; 366 private static final int MSG_REINIT_VOLUMES = 34; 367 private static final int MSG_UPDATE_A11Y_SERVICE_UIDS = 35; 368 private static final int MSG_UPDATE_AUDIO_MODE = 36; 369 private static final int MSG_RECORDING_CONFIG_CHANGE = 37; 370 private static final int MSG_BT_DEV_CHANGED = 38; 371 372 private static final int MSG_DISPATCH_AUDIO_MODE = 40; 373 private static final int MSG_ROUTING_UPDATED = 41; 374 private static final int MSG_INIT_HEADTRACKING_SENSORS = 42; 375 private static final int MSG_PERSIST_SPATIAL_AUDIO_DEVICE_SETTINGS = 43; 376 private static final int MSG_ADD_ASSISTANT_SERVICE_UID = 44; 377 private static final int MSG_REMOVE_ASSISTANT_SERVICE_UID = 45; 378 private static final int MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID = 46; 379 private static final int MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR = 47; 380 private static final int MSG_ROTATION_UPDATE = 48; 381 private static final int MSG_FOLD_UPDATE = 49; 382 private static final int MSG_RESET_SPATIALIZER = 50; 383 private static final int MSG_NO_LOG_FOR_PLAYER_I = 51; 384 385 // start of messages handled under wakelock 386 // these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(), 387 // and not with sendMsg(..., ..., SENDMSG_QUEUE, ...) 388 private static final int MSG_DISABLE_AUDIO_FOR_UID = 100; 389 private static final int MSG_INIT_STREAMS_VOLUMES = 101; 390 private static final int MSG_INIT_SPATIALIZER = 102; 391 392 // end of messages handled under wakelock 393 394 // retry delay in case of failure to indicate system ready to AudioFlinger 395 private static final int INDICATE_SYSTEM_READY_RETRY_DELAY_MS = 1000; 396 397 // List of empty UIDs used to reset the active assistant list 398 private static final int[] NO_ACTIVE_ASSISTANT_SERVICE_UIDS = new int[0]; 399 400 /** @see AudioSystemThread */ 401 private AudioSystemThread mAudioSystemThread; 402 /** @see AudioHandler */ 403 private AudioHandler mAudioHandler; 404 /** @see VolumeStreamState */ 405 private VolumeStreamState[] mStreamStates; 406 getVssVolumeForDevice(int stream, int device)407 /*package*/ int getVssVolumeForDevice(int stream, int device) { 408 return mStreamStates[stream].getIndex(device); 409 } 410 getMaxVssVolumeForStream(int stream)411 /*package*/ int getMaxVssVolumeForStream(int stream) { 412 return mStreamStates[stream].getMaxIndex(); 413 } 414 415 private SettingsObserver mSettingsObserver; 416 417 private AtomicInteger mMode = new AtomicInteger(AudioSystem.MODE_NORMAL); 418 419 // protects mRingerMode 420 private final Object mSettingsLock = new Object(); 421 422 /** Maximum volume index values for audio streams */ 423 protected static int[] MAX_STREAM_VOLUME = new int[] { 424 5, // STREAM_VOICE_CALL 425 7, // STREAM_SYSTEM 426 7, // STREAM_RING // configured by config_audio_ring_vol_steps 427 15, // STREAM_MUSIC 428 7, // STREAM_ALARM 429 7, // STREAM_NOTIFICATION // configured by config_audio_notif_vol_steps 430 15, // STREAM_BLUETOOTH_SCO 431 7, // STREAM_SYSTEM_ENFORCED 432 15, // STREAM_DTMF 433 15, // STREAM_TTS 434 15, // STREAM_ACCESSIBILITY 435 15 // STREAM_ASSISTANT 436 }; 437 438 /** Minimum volume index values for audio streams */ 439 protected static int[] MIN_STREAM_VOLUME = new int[] { 440 1, // STREAM_VOICE_CALL 441 0, // STREAM_SYSTEM 442 0, // STREAM_RING 443 0, // STREAM_MUSIC 444 1, // STREAM_ALARM 445 0, // STREAM_NOTIFICATION 446 0, // STREAM_BLUETOOTH_SCO 447 0, // STREAM_SYSTEM_ENFORCED 448 0, // STREAM_DTMF 449 0, // STREAM_TTS 450 1, // STREAM_ACCESSIBILITY 451 0 // STREAM_ASSISTANT 452 }; 453 454 /* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings 455 * of another stream: This avoids multiplying the volume settings for hidden 456 * stream types that follow other stream behavior for volume settings 457 * NOTE: do not create loops in aliases! 458 * Some streams alias to different streams according to device category (phone or tablet) or 459 * use case (in call vs off call...). See updateStreamVolumeAlias() for more details. 460 * mStreamVolumeAlias contains STREAM_VOLUME_ALIAS_VOICE aliases for a voice capable device 461 * (phone), STREAM_VOLUME_ALIAS_TELEVISION for a television or set-top box and 462 * STREAM_VOLUME_ALIAS_DEFAULT for other devices (e.g. tablets).*/ 463 private final int[] STREAM_VOLUME_ALIAS_VOICE = new int[] { 464 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 465 AudioSystem.STREAM_RING, // STREAM_SYSTEM 466 AudioSystem.STREAM_RING, // STREAM_RING 467 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 468 AudioSystem.STREAM_ALARM, // STREAM_ALARM 469 AudioSystem.STREAM_RING, // STREAM_NOTIFICATION 470 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 471 AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED 472 AudioSystem.STREAM_RING, // STREAM_DTMF 473 AudioSystem.STREAM_MUSIC, // STREAM_TTS 474 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 475 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 476 }; 477 private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] { 478 AudioSystem.STREAM_MUSIC, // STREAM_VOICE_CALL 479 AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM 480 AudioSystem.STREAM_MUSIC, // STREAM_RING 481 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 482 AudioSystem.STREAM_MUSIC, // STREAM_ALARM 483 AudioSystem.STREAM_MUSIC, // STREAM_NOTIFICATION 484 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 485 AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM_ENFORCED 486 AudioSystem.STREAM_MUSIC, // STREAM_DTMF 487 AudioSystem.STREAM_MUSIC, // STREAM_TTS 488 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 489 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 490 }; 491 /** 492 * Using Volume groups configuration allows to control volume per attributes 493 * and group definition may differ from stream aliases. 494 * So, do not alias any stream on one another when using volume groups. 495 * TODO(b/181140246): volume group definition hosting alias definition. 496 */ 497 private final int[] STREAM_VOLUME_ALIAS_NONE = new int[] { 498 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 499 AudioSystem.STREAM_SYSTEM, // STREAM_SYSTEM 500 AudioSystem.STREAM_RING, // STREAM_RING 501 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 502 AudioSystem.STREAM_ALARM, // STREAM_ALARM 503 AudioSystem.STREAM_NOTIFICATION, // STREAM_NOTIFICATION 504 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 505 AudioSystem.STREAM_SYSTEM_ENFORCED, // STREAM_SYSTEM_ENFORCED 506 AudioSystem.STREAM_DTMF, // STREAM_DTMF 507 AudioSystem.STREAM_TTS, // STREAM_TTS 508 AudioSystem.STREAM_ACCESSIBILITY, // STREAM_ACCESSIBILITY 509 AudioSystem.STREAM_ASSISTANT // STREAM_ASSISTANT 510 }; 511 private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] { 512 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 513 AudioSystem.STREAM_RING, // STREAM_SYSTEM 514 AudioSystem.STREAM_RING, // STREAM_RING 515 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 516 AudioSystem.STREAM_ALARM, // STREAM_ALARM 517 AudioSystem.STREAM_RING, // STREAM_NOTIFICATION 518 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 519 AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED 520 AudioSystem.STREAM_RING, // STREAM_DTMF 521 AudioSystem.STREAM_MUSIC, // STREAM_TTS 522 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 523 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 524 }; 525 protected static int[] mStreamVolumeAlias; 526 private static final int UNSET_INDEX = -1; 527 528 /** 529 * Map AudioSystem.STREAM_* constants to app ops. This should be used 530 * after mapping through mStreamVolumeAlias. 531 */ 532 private static final int[] STREAM_VOLUME_OPS = new int[] { 533 AppOpsManager.OP_AUDIO_VOICE_VOLUME, // STREAM_VOICE_CALL 534 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_SYSTEM 535 AppOpsManager.OP_AUDIO_RING_VOLUME, // STREAM_RING 536 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_MUSIC 537 AppOpsManager.OP_AUDIO_ALARM_VOLUME, // STREAM_ALARM 538 AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME, // STREAM_NOTIFICATION 539 AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME, // STREAM_BLUETOOTH_SCO 540 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_SYSTEM_ENFORCED 541 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_DTMF 542 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_TTS 543 AppOpsManager.OP_AUDIO_ACCESSIBILITY_VOLUME, // STREAM_ACCESSIBILITY 544 AppOpsManager.OP_AUDIO_MEDIA_VOLUME // STREAM_ASSISTANT 545 }; 546 547 private final boolean mUseFixedVolume; 548 private final boolean mUseVolumeGroupAliases; 549 550 // If absolute volume is supported in AVRCP device 551 private volatile boolean mAvrcpAbsVolSupported = false; 552 553 /** 554 * Default stream type used for volume control in the absence of playback 555 * e.g. user on homescreen, no app playing anything, presses hardware volume buttons, this 556 * stream type is controlled. 557 */ 558 protected static final int DEFAULT_VOL_STREAM_NO_PLAYBACK = AudioSystem.STREAM_MUSIC; 559 560 private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() { 561 public void onError(int error) { 562 switch (error) { 563 case AudioSystem.AUDIO_STATUS_SERVER_DIED: 564 // check for null in case error callback is called during instance creation 565 if (mRecordMonitor != null) { 566 mRecordMonitor.onAudioServerDied(); 567 } 568 sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, 569 SENDMSG_NOOP, 0, 0, null, 0); 570 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE, 571 SENDMSG_QUEUE, 0, 0, null, 0); 572 break; 573 default: 574 break; 575 } 576 } 577 }; 578 579 /** 580 * Current ringer mode from one of {@link AudioManager#RINGER_MODE_NORMAL}, 581 * {@link AudioManager#RINGER_MODE_SILENT}, or 582 * {@link AudioManager#RINGER_MODE_VIBRATE}. 583 */ 584 @GuardedBy("mSettingsLock") 585 private int mRingerMode; // internal ringer mode, affects muting of underlying streams 586 @GuardedBy("mSettingsLock") 587 private int mRingerModeExternal = -1; // reported ringer mode to outside clients (AudioManager) 588 589 /** @see System#MODE_RINGER_STREAMS_AFFECTED */ 590 private int mRingerModeAffectedStreams = 0; 591 592 private int mZenModeAffectedStreams = 0; 593 594 // Streams currently muted by ringer mode and dnd 595 private int mRingerAndZenModeMutedStreams; 596 597 /** Streams that can be muted. Do not resolve to aliases when checking. 598 * @see System#MUTE_STREAMS_AFFECTED */ 599 private int mMuteAffectedStreams; 600 601 @NonNull 602 private SoundEffectsHelper mSfxHelper; 603 604 /** 605 * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated. 606 * mVibrateSetting is just maintained during deprecation period but vibration policy is 607 * now only controlled by mHasVibrator and mRingerMode 608 */ 609 private int mVibrateSetting; 610 611 // Is there a vibrator 612 private final boolean mHasVibrator; 613 // Used to play vibrations 614 private Vibrator mVibrator; 615 private static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES = 616 VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH); 617 618 // Broadcast receiver for device connections intent broadcasts 619 private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver(); 620 621 private IMediaProjectionManager mProjectionService; // to validate projection token 622 623 /** Interface for UserManagerService. */ 624 private final UserManagerInternal mUserManagerInternal; 625 private final ActivityManagerInternal mActivityManagerInternal; 626 private final SensorPrivacyManagerInternal mSensorPrivacyManagerInternal; 627 628 private final UserRestrictionsListener mUserRestrictionsListener = 629 new AudioServiceUserRestrictionsListener(); 630 631 // List of binder death handlers for setMode() client processes. 632 // The last process to have called setMode() is at the top of the list. 633 // package-private so it can be accessed in AudioDeviceBroker.getSetModeDeathHandlers 634 //TODO candidate to be moved to separate class that handles synchronization 635 @GuardedBy("mDeviceBroker.mSetModeLock") 636 /*package*/ final ArrayList<SetModeDeathHandler> mSetModeDeathHandlers = 637 new ArrayList<SetModeDeathHandler>(); 638 639 // true if boot sequence has been completed 640 private boolean mSystemReady; 641 // true if Intent.ACTION_USER_SWITCHED has ever been received 642 private boolean mUserSwitchedReceived; 643 // previous volume adjustment direction received by checkForRingerModeChange() 644 private int mPrevVolDirection = AudioManager.ADJUST_SAME; 645 // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume 646 // is controlled by Vol keys. 647 private int mVolumeControlStream = -1; 648 // interpretation of whether the volume stream has been selected by the user by clicking on a 649 // volume slider to change which volume is controlled by the volume keys. Is false 650 // when mVolumeControlStream is -1. 651 private boolean mUserSelectedVolumeControlStream = false; 652 private final Object mForceControlStreamLock = new Object(); 653 // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system 654 // server process so in theory it is not necessary to monitor the client death. 655 // However it is good to be ready for future evolutions. 656 private ForceControlStreamClient mForceControlStreamClient = null; 657 // Used to play ringtones outside system_server 658 private volatile IRingtonePlayer mRingtonePlayer; 659 660 // Devices for which the volume is fixed (volume is either max or muted) 661 Set<Integer> mFixedVolumeDevices = new HashSet<>(Arrays.asList( 662 AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, 663 AudioSystem.DEVICE_OUT_AUX_LINE)); 664 // Devices for which the volume is always max, no volume panel 665 Set<Integer> mFullVolumeDevices = new HashSet<>(Arrays.asList( 666 AudioSystem.DEVICE_OUT_HDMI_ARC, 667 AudioSystem.DEVICE_OUT_HDMI_EARC 668 )); 669 670 // Devices where the framework sends a full scale audio signal, and controls the volume of 671 // the external audio system separately. 672 Map<Integer, AbsoluteVolumeDeviceInfo> mAbsoluteVolumeDeviceInfoMap = new ArrayMap<>(); 673 674 /** 675 * Stores information about a device using absolute volume behavior. 676 */ 677 private static final class AbsoluteVolumeDeviceInfo { 678 private final AudioDeviceAttributes mDevice; 679 private final List<VolumeInfo> mVolumeInfos; 680 private final IAudioDeviceVolumeDispatcher mCallback; 681 private final boolean mHandlesVolumeAdjustment; 682 AbsoluteVolumeDeviceInfo(AudioDeviceAttributes device, List<VolumeInfo> volumeInfos, IAudioDeviceVolumeDispatcher callback, boolean handlesVolumeAdjustment)683 private AbsoluteVolumeDeviceInfo(AudioDeviceAttributes device, List<VolumeInfo> volumeInfos, 684 IAudioDeviceVolumeDispatcher callback, boolean handlesVolumeAdjustment) { 685 this.mDevice = device; 686 this.mVolumeInfos = volumeInfos; 687 this.mCallback = callback; 688 this.mHandlesVolumeAdjustment = handlesVolumeAdjustment; 689 } 690 691 /** 692 * Given a stream type, returns a matching VolumeInfo. 693 */ 694 @Nullable getMatchingVolumeInfoForStream(int streamType)695 private VolumeInfo getMatchingVolumeInfoForStream(int streamType) { 696 for (VolumeInfo volumeInfo : mVolumeInfos) { 697 boolean streamTypeMatches = volumeInfo.hasStreamType() 698 && volumeInfo.getStreamType() == streamType; 699 boolean volumeGroupMatches = volumeInfo.hasVolumeGroup() 700 && Arrays.stream(volumeInfo.getVolumeGroup().getLegacyStreamTypes()) 701 .anyMatch(s -> s == streamType); 702 if (streamTypeMatches || volumeGroupMatches) { 703 return volumeInfo; 704 } 705 } 706 return null; 707 } 708 } 709 710 // Devices for the which use the "absolute volume" concept (framework sends audio signal 711 // full scale, and volume control separately) and can be used for multiple use cases reflected 712 // by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL). 713 Set<Integer> mAbsVolumeMultiModeCaseDevices = new HashSet<>( 714 Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID)); 715 716 private final boolean mMonitorRotation; 717 718 private boolean mDockAudioMediaEnabled = true; 719 720 /** 721 * RestorableParameters is a thread-safe class used to store a 722 * first-in first-out history of parameters for replay / restoration. 723 * 724 * The idealized implementation of restoration would have a list of setting methods and 725 * values to be called for restoration. Explicitly managing such setters and 726 * values would be tedious - a simpler method is to store the values and the 727 * method implicitly by lambda capture (the values must be immutable or synchronization 728 * needs to be taken). 729 * 730 * We provide queueRestoreWithRemovalIfTrue() to allow 731 * the caller to provide a BooleanSupplier lambda, which conveniently packages 732 * the setter and its parameters needed for restoration. If during restoration, 733 * the BooleanSupplier returns true, e.g. on error, it is removed from the mMap 734 * so as not to be called on a subsequent restore. 735 * 736 * We provide a setParameters() method as an example helper method. 737 */ 738 private static class RestorableParameters { 739 /** 740 * Sets a parameter and queues for restoration if successful. 741 * 742 * @param id a string handle associated with this parameter. 743 * @param parameter the actual parameter string. 744 * @return the result of AudioSystem.setParameters 745 */ setParameters(@onNull String id, @NonNull String parameter)746 public int setParameters(@NonNull String id, @NonNull String parameter) { 747 Objects.requireNonNull(id, "id must not be null"); 748 Objects.requireNonNull(parameter, "parameter must not be null"); 749 synchronized (mMap) { 750 final int status = AudioSystem.setParameters(parameter); 751 if (status == AudioSystem.AUDIO_STATUS_OK) { // Java uses recursive mutexes. 752 queueRestoreWithRemovalIfTrue(id, () -> { // remove me if set fails. 753 return AudioSystem.setParameters(parameter) != AudioSystem.AUDIO_STATUS_OK; 754 }); 755 } 756 // Implementation detail: We do not mMap.remove(id); on failure. 757 return status; 758 } 759 } 760 761 /** 762 * Queues a restore method which is executed on restoreAll(). 763 * 764 * If the supplier null, the id is removed from the restore map. 765 * 766 * Note: When the BooleanSupplier restore method is executed 767 * during restoreAll, if it returns true, it is removed from the 768 * restore map. 769 * 770 * @param id a unique tag associated with the restore method. 771 * @param supplier is a BooleanSupplier lambda. 772 */ queueRestoreWithRemovalIfTrue( @onNull String id, @Nullable BooleanSupplier supplier)773 public void queueRestoreWithRemovalIfTrue( 774 @NonNull String id, @Nullable BooleanSupplier supplier) { 775 Objects.requireNonNull(id, "id must not be null"); 776 synchronized (mMap) { 777 if (supplier != null) { 778 mMap.put(id, supplier); 779 } else { 780 mMap.remove(id); 781 } 782 } 783 } 784 785 /** 786 * Restore all parameters 787 * 788 * During restoration after audioserver death, any BooleanSupplier that returns 789 * true, for example on parameter restoration error, will be removed from mMap 790 * so as not to be executed on a subsequent restoreAll(). 791 */ restoreAll()792 public void restoreAll() { 793 synchronized (mMap) { 794 // Note: removing from values() also removes from the backing map. 795 // TODO: Consider catching exceptions? 796 mMap.values().removeIf(v -> { 797 return v.getAsBoolean(); // this iterates the setters(). 798 }); 799 } 800 } 801 802 /** 803 * mMap is a LinkedHashMap<Key, Value> of parameters restored by restore(). 804 * The Key is a unique id tag for identification. 805 * The Value is a lambda expression which returns true if the entry is to 806 * be removed. 807 * 808 * 1) For memory limitation purposes, mMap keeps the latest MAX_ENTRIES 809 * accessed in the map. 810 * 2) Parameters are restored in order of queuing, first in first out, 811 * from earliest to latest. 812 */ 813 @GuardedBy("mMap") 814 private Map</* @NonNull */ String, /* @NonNull */ BooleanSupplier> mMap = 815 new LinkedHashMap<>() { 816 // TODO: do we need this memory limitation? 817 private static final int MAX_ENTRIES = 1000; // limit our memory for now. 818 @Override 819 protected boolean removeEldestEntry(Map.Entry eldest) { 820 if (size() <= MAX_ENTRIES) return false; 821 Log.w(TAG, "Parameter map exceeds " 822 + MAX_ENTRIES + " removing " + eldest.getKey()); // don't silently remove. 823 return true; 824 } 825 }; 826 } 827 828 // We currently have one instance for mRestorableParameters used for 829 // setAdditionalOutputDeviceDelay(). Other methods requiring restoration could share this 830 // or use their own instance. 831 private RestorableParameters mRestorableParameters = new RestorableParameters(); 832 833 private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; 834 835 // Used when safe volume warning message display is requested by setStreamVolume(). In this 836 // case, the new requested volume, stream type and device are stored in mPendingVolumeCommand 837 // and used later when/if disableSafeMediaVolume() is called. 838 private StreamVolumeCommand mPendingVolumeCommand; 839 840 private PowerManager.WakeLock mAudioEventWakeLock; 841 842 private final MediaFocusControl mMediaFocusControl; 843 844 // Pre-scale for Bluetooth Absolute Volume 845 private float[] mPrescaleAbsoluteVolume = new float[] { 846 0.6f, // Pre-scale for index 1 847 0.8f, // Pre-scale for index 2 848 0.9f, // Pre-scale for index 3 849 }; 850 851 private NotificationManager mNm; 852 private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate; 853 private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT; 854 private long mLoweredFromNormalToVibrateTime; 855 856 // Array of Uids of valid assistant services to check if caller is one of them 857 @GuardedBy("mSettingsLock") 858 private final ArraySet<Integer> mAssistantUids = new ArraySet<>(); 859 @GuardedBy("mSettingsLock") 860 private int mPrimaryAssistantUid = INVALID_UID; 861 862 // Array of Uids of valid active assistant service to check if caller is one of them 863 @GuardedBy("mSettingsLock") 864 private int[] mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS; 865 866 // Array of Uids of valid accessibility services to check if caller is one of them 867 private final Object mAccessibilityServiceUidsLock = new Object(); 868 @GuardedBy("mAccessibilityServiceUidsLock") 869 private int[] mAccessibilityServiceUids; 870 871 // Uid of the active input method service to check if caller is the one or not. 872 private int mInputMethodServiceUid = android.os.Process.INVALID_UID; 873 private final Object mInputMethodServiceUidLock = new Object(); 874 875 private int mEncodedSurroundMode; 876 private String mEnabledSurroundFormats; 877 private boolean mSurroundModeChanged; 878 879 private boolean mSupportsMicPrivacyToggle; 880 881 private boolean mMicMuteFromSwitch; 882 private boolean mMicMuteFromApi; 883 private boolean mMicMuteFromRestrictions; 884 private boolean mMicMuteFromPrivacyToggle; 885 // caches the value returned by AudioSystem.isMicrophoneMuted() 886 private boolean mMicMuteFromSystemCached; 887 888 private boolean mNavigationRepeatSoundEffectsEnabled; 889 private boolean mHomeSoundEffectEnabled; 890 891 @GuardedBy("mSettingsLock") 892 private int mCurrentImeUid; 893 894 private final Object mSupportedSystemUsagesLock = new Object(); 895 @GuardedBy("mSupportedSystemUsagesLock") 896 private @AttributeSystemUsage int[] mSupportedSystemUsages = 897 new int[]{AudioAttributes.USAGE_CALL_ASSISTANT}; 898 899 // Defines the format for the connection "address" for ALSA devices makeAlsaAddressString(int card, int device)900 public static String makeAlsaAddressString(int card, int device) { 901 return "card=" + card + ";device=" + device + ";"; 902 } 903 904 public static final class Lifecycle extends SystemService { 905 private AudioService mService; 906 Lifecycle(Context context)907 public Lifecycle(Context context) { 908 super(context); 909 mService = new AudioService(context); 910 } 911 912 @Override onStart()913 public void onStart() { 914 publishBinderService(Context.AUDIO_SERVICE, mService); 915 } 916 917 @Override onBootPhase(int phase)918 public void onBootPhase(int phase) { 919 if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { 920 mService.systemReady(); 921 } 922 } 923 } 924 925 final private IUidObserver mUidObserver = new IUidObserver.Stub() { 926 @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, 927 int capability) { 928 } 929 930 @Override public void onUidGone(int uid, boolean disabled) { 931 // Once the uid is no longer running, no need to keep trying to disable its audio. 932 disableAudioForUid(false, uid); 933 } 934 935 @Override public void onUidActive(int uid) throws RemoteException { 936 } 937 938 @Override public void onUidIdle(int uid, boolean disabled) { 939 } 940 941 @Override public void onUidCachedChanged(int uid, boolean cached) { 942 disableAudioForUid(cached, uid); 943 } 944 945 @Override public void onUidProcAdjChanged(int uid) { 946 } 947 948 private void disableAudioForUid(boolean disable, int uid) { 949 queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID, 950 disable ? 1 : 0 /* arg1 */, uid /* arg2 */, 951 null /* obj */, 0 /* delay */); 952 } 953 }; 954 955 @GuardedBy("mSettingsLock") 956 private boolean mRttEnabled = false; 957 958 /////////////////////////////////////////////////////////////////////////// 959 // Construction 960 /////////////////////////////////////////////////////////////////////////// 961 962 /** @hide */ AudioService(Context context)963 public AudioService(Context context) { 964 this(context, 965 AudioSystemAdapter.getDefaultAdapter(), 966 SystemServerAdapter.getDefaultAdapter(context), 967 SettingsAdapter.getDefaultAdapter(), 968 null); 969 } 970 971 /** 972 * @param context 973 * @param audioSystem Adapter for {@link AudioSystem} 974 * @param systemServer Adapter for privilieged functionality for system server components 975 * @param settings Adapter for {@link Settings} 976 * @param looper Looper to use for the service's message handler. If this is null, an 977 * {@link AudioSystemThread} is created as the messaging thread instead. 978 */ AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer, SettingsAdapter settings, @Nullable Looper looper)979 public AudioService(Context context, AudioSystemAdapter audioSystem, 980 SystemServerAdapter systemServer, SettingsAdapter settings, @Nullable Looper looper) { 981 this (context, audioSystem, systemServer, settings, looper, 982 context.getSystemService(AppOpsManager.class)); 983 } 984 985 /** 986 * @param context 987 * @param audioSystem Adapter for {@link AudioSystem} 988 * @param systemServer Adapter for privilieged functionality for system server components 989 * @param settings Adapter for {@link Settings} 990 * @param looper Looper to use for the service's message handler. If this is null, an 991 * {@link AudioSystemThread} is created as the messaging thread instead. 992 */ 993 @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer, SettingsAdapter settings, @Nullable Looper looper, AppOpsManager appOps)994 public AudioService(Context context, AudioSystemAdapter audioSystem, 995 SystemServerAdapter systemServer, SettingsAdapter settings, @Nullable Looper looper, 996 AppOpsManager appOps) { 997 sLifecycleLogger.log(new AudioEventLogger.StringEvent("AudioService()")); 998 mContext = context; 999 mContentResolver = context.getContentResolver(); 1000 mAppOps = appOps; 1001 1002 mAudioSystem = audioSystem; 1003 mSystemServer = systemServer; 1004 mSettings = settings; 1005 1006 mPlatformType = AudioSystem.getPlatformType(context); 1007 1008 mIsSingleVolume = AudioSystem.isSingleVolume(context); 1009 1010 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 1011 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); 1012 mSensorPrivacyManagerInternal = 1013 LocalServices.getService(SensorPrivacyManagerInternal.class); 1014 1015 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 1016 mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent"); 1017 1018 mSfxHelper = new SoundEffectsHelper(mContext, playerBase -> ignorePlayerLogs(playerBase)); 1019 1020 final boolean binauralEnabledDefault = SystemProperties.getBoolean( 1021 "ro.audio.spatializer_binaural_enabled_default", true); 1022 final boolean transauralEnabledDefault = SystemProperties.getBoolean( 1023 "ro.audio.spatializer_transaural_enabled_default", true); 1024 final boolean headTrackingEnabledDefault = mContext.getResources().getBoolean( 1025 com.android.internal.R.bool.config_spatial_audio_head_tracking_enabled_default); 1026 mSpatializerHelper = new SpatializerHelper(this, mAudioSystem, 1027 binauralEnabledDefault, transauralEnabledDefault, headTrackingEnabledDefault); 1028 1029 mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); 1030 mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator(); 1031 1032 mSupportsMicPrivacyToggle = context.getSystemService(SensorPrivacyManager.class) 1033 .supportsSensorToggle(SensorPrivacyManager.Sensors.MICROPHONE); 1034 1035 mUseVolumeGroupAliases = mContext.getResources().getBoolean( 1036 com.android.internal.R.bool.config_handleVolumeAliasesUsingVolumeGroups); 1037 1038 mNotifAliasRing = !DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI, 1039 SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, false); 1040 1041 DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI, 1042 ActivityThread.currentApplication().getMainExecutor(), 1043 this::onDeviceConfigChange); 1044 1045 // Initialize volume 1046 // Priority 1 - Android Property 1047 // Priority 2 - Audio Policy Service 1048 // Priority 3 - Default Value 1049 if (AudioProductStrategy.getAudioProductStrategies().size() > 0) { 1050 int numStreamTypes = AudioSystem.getNumStreamTypes(); 1051 1052 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 1053 AudioAttributes attr = 1054 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType( 1055 streamType); 1056 int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr); 1057 if (maxVolume != -1) { 1058 MAX_STREAM_VOLUME[streamType] = maxVolume; 1059 } 1060 int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr); 1061 if (minVolume != -1) { 1062 MIN_STREAM_VOLUME[streamType] = minVolume; 1063 } 1064 } 1065 if (mUseVolumeGroupAliases) { 1066 // Set all default to uninitialized. 1067 for (int stream = 0; stream < AudioSystem.DEFAULT_STREAM_VOLUME.length; stream++) { 1068 AudioSystem.DEFAULT_STREAM_VOLUME[stream] = UNSET_INDEX; 1069 } 1070 } 1071 } 1072 1073 int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1); 1074 if (maxCallVolume != -1) { 1075 MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume; 1076 } 1077 1078 int defaultCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_default", -1); 1079 if (defaultCallVolume != -1 && 1080 defaultCallVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] && 1081 defaultCallVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) { 1082 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume; 1083 } else { 1084 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = 1085 (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4; 1086 } 1087 1088 int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1); 1089 if (maxMusicVolume != -1) { 1090 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume; 1091 } 1092 1093 int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1); 1094 if (defaultMusicVolume != -1 && 1095 defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] && 1096 defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) { 1097 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume; 1098 } else { 1099 if (isPlatformTelevision()) { 1100 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = 1101 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4; 1102 } else { 1103 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = 1104 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3; 1105 } 1106 } 1107 1108 int maxAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_steps", -1); 1109 if (maxAlarmVolume != -1) { 1110 MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = maxAlarmVolume; 1111 } 1112 1113 int defaultAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_default", -1); 1114 if (defaultAlarmVolume != -1 && 1115 defaultAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) { 1116 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = defaultAlarmVolume; 1117 } else { 1118 // Default is 6 out of 7 (default maximum), so scale accordingly. 1119 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = 1120 6 * MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] / 7; 1121 } 1122 1123 int maxSystemVolume = SystemProperties.getInt("ro.config.system_vol_steps", -1); 1124 if (maxSystemVolume != -1) { 1125 MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = maxSystemVolume; 1126 } 1127 1128 int defaultSystemVolume = SystemProperties.getInt("ro.config.system_vol_default", -1); 1129 if (defaultSystemVolume != -1 && 1130 defaultSystemVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]) { 1131 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = defaultSystemVolume; 1132 } else { 1133 // Default is to use maximum. 1134 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = 1135 MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]; 1136 } 1137 1138 // Read following properties to configure max volume (number of steps) and default volume 1139 // for STREAM_NOTIFICATION and STREAM_RING: 1140 // config_audio_notif_vol_default 1141 // config_audio_notif_vol_steps 1142 // config_audio_ring_vol_default 1143 // config_audio_ring_vol_steps 1144 int[] streams = { AudioSystem.STREAM_NOTIFICATION, AudioSystem.STREAM_RING }; 1145 int[] stepsResId = { com.android.internal.R.integer.config_audio_notif_vol_steps, 1146 com.android.internal.R.integer.config_audio_ring_vol_steps }; 1147 int[] defaultResId = { com.android.internal.R.integer.config_audio_notif_vol_default, 1148 com.android.internal.R.integer.config_audio_ring_vol_default }; 1149 for (int s = 0; s < streams.length; s++) { 1150 try { 1151 final int maxVol = mContext.getResources().getInteger(stepsResId[s]); 1152 if (maxVol <= 0) { 1153 throw new IllegalArgumentException("Invalid negative max volume for stream " 1154 + streams[s]); 1155 } 1156 Log.i(TAG, "Stream " + streams[s] + ": using max vol of " + maxVol); 1157 MAX_STREAM_VOLUME[streams[s]] = maxVol; 1158 } catch (Resources.NotFoundException e) { 1159 Log.e(TAG, "Error querying max vol for stream type " + streams[s], e); 1160 } 1161 try { 1162 final int defaultVol = mContext.getResources().getInteger(defaultResId[s]); 1163 if (defaultVol > MAX_STREAM_VOLUME[streams[s]]) { 1164 throw new IllegalArgumentException("Invalid default volume (" + defaultVol 1165 + ") for stream " + streams[s] + ", greater than max volume of " 1166 + MAX_STREAM_VOLUME[streams[s]]); 1167 } 1168 if (defaultVol < MIN_STREAM_VOLUME[streams[s]]) { 1169 throw new IllegalArgumentException("Invalid default volume (" + defaultVol 1170 + ") for stream " + streams[s] + ", lower than min volume of " 1171 + MIN_STREAM_VOLUME[streams[s]]); 1172 } 1173 Log.i(TAG, "Stream " + streams[s] + ": using default vol of " + defaultVol); 1174 AudioSystem.DEFAULT_STREAM_VOLUME[streams[s]] = defaultVol; 1175 } catch (Resources.NotFoundException e) { 1176 Log.e(TAG, "Error querying default vol for stream type " + streams[s], e); 1177 } 1178 } 1179 1180 if (looper == null) { 1181 createAudioSystemThread(); 1182 } else { 1183 mAudioHandler = new AudioHandler(looper); 1184 } 1185 1186 AudioSystem.setErrorCallback(mAudioSystemCallback); 1187 1188 updateAudioHalPids(); 1189 1190 boolean cameraSoundForced = readCameraSoundForced(); 1191 mCameraSoundForced = new Boolean(cameraSoundForced); 1192 sendMsg(mAudioHandler, 1193 MSG_SET_FORCE_USE, 1194 SENDMSG_QUEUE, 1195 AudioSystem.FOR_SYSTEM, 1196 cameraSoundForced ? 1197 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE, 1198 new String("AudioService ctor"), 1199 0); 1200 1201 mSafeMediaVolumeState = mSettings.getGlobalInt(mContentResolver, 1202 Settings.Global.AUDIO_SAFE_VOLUME_STATE, 1203 SAFE_MEDIA_VOLUME_NOT_CONFIGURED); 1204 // The default safe volume index read here will be replaced by the actual value when 1205 // the mcc is read by onConfigureSafeVolume() 1206 mSafeMediaVolumeIndex = mContext.getResources().getInteger( 1207 com.android.internal.R.integer.config_safe_media_volume_index) * 10; 1208 1209 mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); 1210 1211 mUseFixedVolume = mContext.getResources().getBoolean( 1212 com.android.internal.R.bool.config_useFixedVolume); 1213 1214 mDeviceBroker = new AudioDeviceBroker(mContext, this, mAudioSystem); 1215 1216 mRecordMonitor = new RecordingActivityMonitor(mContext); 1217 mRecordMonitor.registerRecordingCallback(mVoiceRecordingActivityMonitor, true); 1218 1219 // must be called before readPersistedSettings() which needs a valid mStreamVolumeAlias[] 1220 // array initialized by updateStreamVolumeAlias() 1221 updateStreamVolumeAlias(false /*updateVolumes*/, TAG); 1222 readPersistedSettings(); 1223 readUserRestrictions(); 1224 1225 mPlaybackMonitor = 1226 new PlaybackActivityMonitor(context, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM], 1227 device -> onMuteAwaitConnectionTimeout(device)); 1228 mPlaybackMonitor.registerPlaybackCallback(mPlaybackActivityMonitor, true); 1229 1230 mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor); 1231 1232 readAndSetLowRamDevice(); 1233 1234 mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported(); 1235 1236 if (mSystemServer.isPrivileged()) { 1237 LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal()); 1238 1239 mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener); 1240 1241 mRecordMonitor.initMonitor(); 1242 } 1243 1244 mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false); 1245 1246 mHasSpatializerEffect = SystemProperties.getBoolean("ro.audio.spatializer_enabled", false); 1247 1248 // monitor routing updates coming from native 1249 mAudioSystem.setRoutingListener(this); 1250 // monitor requests for volume range initialization coming from native (typically when 1251 // errors are found by AudioPolicyManager 1252 mAudioSystem.setVolRangeInitReqListener(this); 1253 1254 // done with service initialization, continue additional work in our Handler thread 1255 queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES, 1256 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */); 1257 queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_SPATIALIZER, 1258 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */); 1259 } 1260 initVolumeStreamStates()1261 private void initVolumeStreamStates() { 1262 int numStreamTypes = AudioSystem.getNumStreamTypes(); 1263 synchronized (VolumeStreamState.class) { 1264 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 1265 VolumeStreamState streamState = mStreamStates[streamType]; 1266 int groupId = getVolumeGroupForStreamType(streamType); 1267 if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP 1268 && sVolumeGroupStates.indexOfKey(groupId) >= 0) { 1269 streamState.setVolumeGroupState(sVolumeGroupStates.get(groupId)); 1270 } 1271 } 1272 } 1273 } 1274 1275 /** 1276 * Separating notification volume from ring is NOT of aliasing the corresponding streams 1277 * @param properties 1278 */ onDeviceConfigChange(DeviceConfig.Properties properties)1279 private void onDeviceConfigChange(DeviceConfig.Properties properties) { 1280 Set<String> changeSet = properties.getKeyset(); 1281 if (changeSet.contains(SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION)) { 1282 boolean newNotifAliasRing = !properties.getBoolean( 1283 SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, CONFIG_DEFAULT_VAL); 1284 if (mNotifAliasRing != newNotifAliasRing) { 1285 mNotifAliasRing = newNotifAliasRing; 1286 updateStreamVolumeAlias(true, TAG); 1287 } 1288 } 1289 } 1290 1291 /** 1292 * Called by handling of MSG_INIT_STREAMS_VOLUMES 1293 */ onInitStreamsAndVolumes()1294 private void onInitStreamsAndVolumes() { 1295 createStreamStates(); 1296 1297 // must be called after createStreamStates() as it uses MUSIC volume as default if no 1298 // persistent data 1299 initVolumeGroupStates(); 1300 1301 // mSafeUsbMediaVolumeIndex must be initialized after createStreamStates() because it 1302 // relies on audio policy having correct ranges for volume indexes. 1303 mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex(); 1304 // Link VGS on VSS 1305 initVolumeStreamStates(); 1306 1307 // Call setRingerModeInt() to apply correct mute 1308 // state on streams affected by ringer mode. 1309 mRingerAndZenModeMutedStreams = 0; 1310 setRingerModeInt(getRingerModeInternal(), false); 1311 1312 final float[] preScale = new float[3]; 1313 preScale[0] = mContext.getResources().getFraction( 1314 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1, 1315 1, 1); 1316 preScale[1] = mContext.getResources().getFraction( 1317 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index2, 1318 1, 1); 1319 preScale[2] = mContext.getResources().getFraction( 1320 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index3, 1321 1, 1); 1322 for (int i = 0; i < preScale.length; i++) { 1323 if (0.0f <= preScale[i] && preScale[i] <= 1.0f) { 1324 mPrescaleAbsoluteVolume[i] = preScale[i]; 1325 } 1326 } 1327 1328 initExternalEventReceivers(); 1329 1330 // check on volume initialization 1331 checkVolumeRangeInitialization("AudioService()"); 1332 } 1333 1334 /** 1335 * Initialize intent receives and settings observers for this service. 1336 * Must be called after createStreamStates() as the handling of some events 1337 * may affect or need volumes, e.g. BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED 1338 * (for intent receiver), or Settings.Global.ZEN_MODE (for settings observer) 1339 */ initExternalEventReceivers()1340 private void initExternalEventReceivers() { 1341 mSettingsObserver = new SettingsObserver(); 1342 1343 // Register for device connection intent broadcasts. 1344 IntentFilter intentFilter = 1345 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); 1346 intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED); 1347 intentFilter.addAction(Intent.ACTION_DOCK_EVENT); 1348 intentFilter.addAction(Intent.ACTION_SCREEN_ON); 1349 intentFilter.addAction(Intent.ACTION_SCREEN_OFF); 1350 intentFilter.addAction(Intent.ACTION_USER_SWITCHED); 1351 intentFilter.addAction(Intent.ACTION_USER_BACKGROUND); 1352 intentFilter.addAction(Intent.ACTION_USER_FOREGROUND); 1353 intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); 1354 intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); 1355 intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED); 1356 1357 intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); 1358 if (mMonitorRotation) { 1359 RotationHelper.init(mContext, mAudioHandler, 1360 rotation -> onRotationUpdate(rotation), 1361 foldState -> onFoldStateUpdate(foldState)); 1362 } 1363 1364 intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION); 1365 intentFilter.addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION); 1366 intentFilter.addAction(ACTION_CHECK_MUSIC_ACTIVE); 1367 1368 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null, 1369 Context.RECEIVER_EXPORTED); 1370 1371 } 1372 systemReady()1373 public void systemReady() { 1374 sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE, 1375 0, 0, null, 0); 1376 if (false) { 1377 // This is turned off for now, because it is racy and thus causes apps to break. 1378 // Currently banning a uid means that if an app tries to start playing an audio 1379 // stream, that will be preventing, and unbanning it will not allow that stream 1380 // to resume. However these changes in uid state are racy with what the app is doing, 1381 // so that after taking a process out of the cached state we can't guarantee that 1382 // we will unban the uid before the app actually tries to start playing audio. 1383 // (To do that, the activity manager would need to wait until it knows for sure 1384 // that the ban has been removed, before telling the app to do whatever it is 1385 // supposed to do that caused it to go out of the cached state.) 1386 try { 1387 ActivityManager.getService().registerUidObserver(mUidObserver, 1388 ActivityManager.UID_OBSERVER_CACHED | ActivityManager.UID_OBSERVER_GONE, 1389 ActivityManager.PROCESS_STATE_UNKNOWN, null); 1390 } catch (RemoteException e) { 1391 // ignored; both services live in system_server 1392 } 1393 } 1394 } 1395 updateVibratorInfos()1396 private void updateVibratorInfos() { 1397 VibratorManager vibratorManager = mContext.getSystemService(VibratorManager.class); 1398 if (vibratorManager == null) { 1399 Slog.e(TAG, "Vibrator manager is not found"); 1400 return; 1401 } 1402 int[] vibratorIds = vibratorManager.getVibratorIds(); 1403 if (vibratorIds.length == 0) { 1404 Slog.d(TAG, "No vibrator found"); 1405 return; 1406 } 1407 List<Vibrator> vibrators = new ArrayList<>(vibratorIds.length); 1408 for (int id : vibratorIds) { 1409 Vibrator vibrator = vibratorManager.getVibrator(id); 1410 if (vibrator != null) { 1411 vibrators.add(vibrator); 1412 } else { 1413 Slog.w(TAG, "Vibrator(" + id + ") is not found"); 1414 } 1415 } 1416 if (vibrators.isEmpty()) { 1417 Slog.w(TAG, "Cannot find any available vibrator"); 1418 return; 1419 } 1420 AudioSystem.setVibratorInfos(vibrators); 1421 } 1422 onSystemReady()1423 public void onSystemReady() { 1424 mSystemReady = true; 1425 scheduleLoadSoundEffects(); 1426 1427 mDeviceBroker.onSystemReady(); 1428 1429 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) { 1430 synchronized (mHdmiClientLock) { 1431 mHdmiManager = mContext.getSystemService(HdmiControlManager.class); 1432 if (mHdmiManager != null) { 1433 mHdmiManager.addHdmiControlStatusChangeListener( 1434 mHdmiControlStatusChangeListenerCallback); 1435 mHdmiManager.addHdmiCecVolumeControlFeatureListener(mContext.getMainExecutor(), 1436 mMyHdmiCecVolumeControlFeatureListener); 1437 } 1438 mHdmiTvClient = mHdmiManager.getTvClient(); 1439 if (mHdmiTvClient != null) { 1440 mFixedVolumeDevices.removeAll( 1441 AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET); 1442 } 1443 mHdmiPlaybackClient = mHdmiManager.getPlaybackClient(); 1444 mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient(); 1445 } 1446 } 1447 1448 if (mSupportsMicPrivacyToggle) { 1449 mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers( 1450 SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> { 1451 if (userId == getCurrentUserId()) { 1452 mMicMuteFromPrivacyToggle = enabled; 1453 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); 1454 } 1455 }); 1456 } 1457 1458 mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 1459 1460 sendMsg(mAudioHandler, 1461 MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED, 1462 SENDMSG_REPLACE, 1463 0, 1464 0, 1465 TAG, 1466 SystemProperties.getBoolean("audio.safemedia.bypass", false) ? 1467 0 : SAFE_VOLUME_CONFIGURE_TIMEOUT_MS); 1468 1469 initA11yMonitoring(); 1470 1471 mRoleObserver = new RoleObserver(); 1472 mRoleObserver.register(); 1473 1474 onIndicateSystemReady(); 1475 1476 mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted(); 1477 setMicMuteFromSwitchInput(); 1478 1479 initMinStreamVolumeWithoutModifyAudioSettings(); 1480 1481 updateVibratorInfos(); 1482 1483 synchronized (mSupportedSystemUsagesLock) { 1484 AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages); 1485 } 1486 } 1487 1488 //----------------------------------------------------------------- 1489 // routing monitoring from AudioSystemAdapter 1490 @Override onRoutingUpdatedFromNative()1491 public void onRoutingUpdatedFromNative() { 1492 sendMsg(mAudioHandler, 1493 MSG_ROUTING_UPDATED, 1494 SENDMSG_REPLACE, 0, 0, null, 1495 /*delay*/ 0); 1496 } 1497 1498 /** 1499 * called when handling MSG_ROUTING_UPDATED 1500 */ onRoutingUpdatedFromAudioThread()1501 void onRoutingUpdatedFromAudioThread() { 1502 if (mHasSpatializerEffect) { 1503 mSpatializerHelper.onRoutingUpdated(); 1504 } 1505 checkMuteAwaitConnection(); 1506 } 1507 1508 //----------------------------------------------------------------- 1509 // rotation/fold updates coming from RotationHelper onRotationUpdate(Integer rotation)1510 void onRotationUpdate(Integer rotation) { 1511 mSpatializerHelper.setDisplayOrientation((float) (rotation * Math.PI / 180.)); 1512 // use REPLACE as only the last rotation matters 1513 final String rotationParameter = "rotation=" + rotation; 1514 sendMsg(mAudioHandler, MSG_ROTATION_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0, 1515 /*obj*/ rotationParameter, /*delay*/ 0); 1516 } 1517 onFoldStateUpdate(Boolean foldState)1518 void onFoldStateUpdate(Boolean foldState) { 1519 mSpatializerHelper.setFoldState(foldState); 1520 // use REPLACE as only the last fold state matters 1521 final String foldStateParameter = "device_folded=" + (foldState ? "on" : "off"); 1522 sendMsg(mAudioHandler, MSG_FOLD_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0, 1523 /*obj*/ foldStateParameter, /*delay*/ 0); 1524 } 1525 1526 //----------------------------------------------------------------- 1527 // Communicate to PlayackActivityMonitor whether to log or not 1528 // the sound FX activity (useful for removing touch sounds in the activity logs) ignorePlayerLogs(@onNull PlayerBase playerToIgnore)1529 void ignorePlayerLogs(@NonNull PlayerBase playerToIgnore) { 1530 if (DEBUG_LOG_SOUND_FX) { 1531 return; 1532 } 1533 sendMsg(mAudioHandler, MSG_NO_LOG_FOR_PLAYER_I, SENDMSG_REPLACE, 1534 /*arg1, piid of the player*/ playerToIgnore.getPlayerIId(), 1535 /*arg2 ignored*/ 0, /*obj ignored*/ null, /*delay*/ 0); 1536 } 1537 1538 //----------------------------------------------------------------- 1539 // monitoring requests for volume range initialization 1540 @Override // AudioSystemAdapter.OnVolRangeInitRequestListener onVolumeRangeInitRequestFromNative()1541 public void onVolumeRangeInitRequestFromNative() { 1542 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_REPLACE, 0, 0, 1543 "onVolumeRangeInitRequestFromNative" /*obj: caller, for dumpsys*/, /*delay*/ 0); 1544 } 1545 1546 //----------------------------------------------------------------- 1547 RoleObserver mRoleObserver; 1548 1549 class RoleObserver implements OnRoleHoldersChangedListener { 1550 private RoleManager mRm; 1551 private final Executor mExecutor; 1552 RoleObserver()1553 RoleObserver() { 1554 mExecutor = mContext.getMainExecutor(); 1555 } 1556 register()1557 public void register() { 1558 mRm = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE); 1559 if (mRm != null) { 1560 mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL); 1561 synchronized (mSettingsLock) { 1562 updateAssistantUIdLocked(/* forceUpdate= */ true); 1563 } 1564 } 1565 } 1566 1567 @Override onRoleHoldersChanged(@onNull String roleName, @NonNull UserHandle user)1568 public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) { 1569 if (RoleManager.ROLE_ASSISTANT.equals(roleName)) { 1570 synchronized (mSettingsLock) { 1571 updateAssistantUIdLocked(/* forceUpdate= */ false); 1572 } 1573 } 1574 } 1575 getAssistantRoleHolder()1576 public String getAssistantRoleHolder() { 1577 String assitantPackage = ""; 1578 if (mRm != null) { 1579 List<String> assistants = mRm.getRoleHolders(RoleManager.ROLE_ASSISTANT); 1580 assitantPackage = assistants.size() == 0 ? "" : assistants.get(0); 1581 } 1582 return assitantPackage; 1583 } 1584 } 1585 onIndicateSystemReady()1586 void onIndicateSystemReady() { 1587 if (AudioSystem.systemReady() == AudioSystem.SUCCESS) { 1588 return; 1589 } 1590 sendMsg(mAudioHandler, 1591 MSG_INDICATE_SYSTEM_READY, 1592 SENDMSG_REPLACE, 1593 0, 1594 0, 1595 null, 1596 INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 1597 } 1598 onAudioServerDied()1599 public void onAudioServerDied() { 1600 if (!mSystemReady || 1601 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) { 1602 Log.e(TAG, "Audioserver died."); 1603 sLifecycleLogger.log(new AudioEventLogger.StringEvent( 1604 "onAudioServerDied() audioserver died")); 1605 sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0, 1606 null, 500); 1607 return; 1608 } 1609 Log.i(TAG, "Audioserver started."); 1610 sLifecycleLogger.log(new AudioEventLogger.StringEvent( 1611 "onAudioServerDied() audioserver started")); 1612 1613 updateAudioHalPids(); 1614 1615 // indicate to audio HAL that we start the reconfiguration phase after a media 1616 // server crash 1617 // Note that we only execute this when the media server 1618 // process restarts after a crash, not the first time it is started. 1619 AudioSystem.setParameters("restarting=true"); 1620 1621 readAndSetLowRamDevice(); 1622 1623 mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported(); 1624 1625 // Restore device connection states, BT state 1626 mDeviceBroker.onAudioServerDied(); 1627 1628 // Restore call state 1629 synchronized (mDeviceBroker.mSetModeLock) { 1630 onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(), 1631 mContext.getPackageName(), true /*force*/); 1632 } 1633 final int forSys; 1634 synchronized (mSettingsLock) { 1635 forSys = mCameraSoundForced ? 1636 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE; 1637 } 1638 1639 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, forSys, "onAudioServerDied"); 1640 1641 // Restore stream volumes 1642 onReinitVolumes("after audioserver restart"); 1643 1644 // Restore audio volume groups 1645 restoreVolumeGroups(); 1646 1647 // Restore mono mode 1648 updateMasterMono(mContentResolver); 1649 1650 // Restore audio balance 1651 updateMasterBalance(mContentResolver); 1652 1653 // Restore ringer mode 1654 setRingerModeInt(getRingerModeInternal(), false); 1655 1656 // Reset device rotation (if monitored for this device) 1657 if (mMonitorRotation) { 1658 RotationHelper.updateOrientation(); 1659 } 1660 1661 // Restore setParameters and other queued setters. 1662 mRestorableParameters.restoreAll(); 1663 1664 synchronized (mSettingsLock) { 1665 final int forDock = mDockAudioMediaEnabled ? 1666 AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE; 1667 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, forDock, "onAudioServerDied"); 1668 sendEncodedSurroundMode(mContentResolver, "onAudioServerDied"); 1669 sendEnabledSurroundFormats(mContentResolver, true); 1670 AudioSystem.setRttEnabled(mRttEnabled); 1671 resetAssistantServicesUidsLocked(); 1672 } 1673 1674 synchronized (mAccessibilityServiceUidsLock) { 1675 AudioSystem.setA11yServicesUids(mAccessibilityServiceUids); 1676 } 1677 synchronized (mInputMethodServiceUidLock) { 1678 mAudioSystem.setCurrentImeUid(mInputMethodServiceUid); 1679 } 1680 synchronized (mHdmiClientLock) { 1681 if (mHdmiManager != null && mHdmiTvClient != null) { 1682 setHdmiSystemAudioSupported(mHdmiSystemAudioSupported); 1683 } 1684 } 1685 1686 synchronized (mSupportedSystemUsagesLock) { 1687 AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages); 1688 } 1689 1690 synchronized (mAudioPolicies) { 1691 ArrayList<AudioPolicyProxy> invalidProxies = new ArrayList<>(); 1692 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 1693 final int status = policy.connectMixes(); 1694 if (status != AudioSystem.SUCCESS) { 1695 // note that PERMISSION_DENIED may also indicate trouble getting to APService 1696 Log.e(TAG, "onAudioServerDied: error " 1697 + AudioSystem.audioSystemErrorToString(status) 1698 + " when connecting mixes for policy " + policy.toLogFriendlyString()); 1699 invalidProxies.add(policy); 1700 } else { 1701 final int deviceAffinitiesStatus = policy.setupDeviceAffinities(); 1702 if (deviceAffinitiesStatus != AudioSystem.SUCCESS) { 1703 Log.e(TAG, "onAudioServerDied: error " 1704 + AudioSystem.audioSystemErrorToString(deviceAffinitiesStatus) 1705 + " when connecting device affinities for policy " 1706 + policy.toLogFriendlyString()); 1707 invalidProxies.add(policy); 1708 } 1709 } 1710 } 1711 invalidProxies.forEach((policy) -> policy.release()); 1712 1713 } 1714 1715 // Restore capture policies 1716 synchronized (mPlaybackMonitor) { 1717 HashMap<Integer, Integer> allowedCapturePolicies = 1718 mPlaybackMonitor.getAllAllowedCapturePolicies(); 1719 for (HashMap.Entry<Integer, Integer> entry : allowedCapturePolicies.entrySet()) { 1720 int result = mAudioSystem.setAllowedCapturePolicy( 1721 entry.getKey(), 1722 AudioAttributes.capturePolicyToFlags(entry.getValue(), 0x0)); 1723 if (result != AudioSystem.AUDIO_STATUS_OK) { 1724 Log.e(TAG, "Failed to restore capture policy, uid: " 1725 + entry.getKey() + ", capture policy: " + entry.getValue() 1726 + ", result: " + result); 1727 // When restoring capture policy failed, set the capture policy as 1728 // ALLOW_CAPTURE_BY_ALL, which will result in removing the cached 1729 // capture policy in PlaybackActivityMonitor. 1730 mPlaybackMonitor.setAllowedCapturePolicy( 1731 entry.getKey(), AudioAttributes.ALLOW_CAPTURE_BY_ALL); 1732 } 1733 } 1734 } 1735 1736 mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect); 1737 1738 // Restore rotation information. 1739 if (mMonitorRotation) { 1740 RotationHelper.forceUpdate(); 1741 } 1742 1743 onIndicateSystemReady(); 1744 // indicate the end of reconfiguration phase to audio HAL 1745 AudioSystem.setParameters("restarting=false"); 1746 1747 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE, 1748 SENDMSG_QUEUE, 1, 0, null, 0); 1749 1750 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); // will also update the mic mute cache 1751 setMicMuteFromSwitchInput(); 1752 1753 // Restore vibrator info 1754 updateVibratorInfos(); 1755 } 1756 onRemoveAssistantServiceUids(int[] uids)1757 private void onRemoveAssistantServiceUids(int[] uids) { 1758 synchronized (mSettingsLock) { 1759 removeAssistantServiceUidsLocked(uids); 1760 } 1761 } 1762 1763 @GuardedBy("mSettingsLock") removeAssistantServiceUidsLocked(int[] uids)1764 private void removeAssistantServiceUidsLocked(int[] uids) { 1765 boolean changed = false; 1766 for (int index = 0; index < uids.length; index++) { 1767 if (!mAssistantUids.remove(uids[index])) { 1768 Slog.e(TAG, TextUtils.formatSimple( 1769 "Cannot remove assistant service, uid(%d) not present", uids[index])); 1770 continue; 1771 } 1772 changed = true; 1773 } 1774 if (changed) { 1775 updateAssistantServicesUidsLocked(); 1776 } 1777 } 1778 onAddAssistantServiceUids(int[] uids)1779 private void onAddAssistantServiceUids(int[] uids) { 1780 synchronized (mSettingsLock) { 1781 addAssistantServiceUidsLocked(uids); 1782 } 1783 } 1784 1785 @GuardedBy("mSettingsLock") addAssistantServiceUidsLocked(int[] uids)1786 private void addAssistantServiceUidsLocked(int[] uids) { 1787 boolean changed = false; 1788 for (int index = 0; index < uids.length; index++) { 1789 if (uids[index] == INVALID_UID) { 1790 continue; 1791 } 1792 if (!mAssistantUids.add(uids[index])) { 1793 Slog.e(TAG, TextUtils.formatSimple( 1794 "Cannot add assistant service, uid(%d) already present", 1795 uids[index])); 1796 continue; 1797 } 1798 changed = true; 1799 } 1800 if (changed) { 1801 updateAssistantServicesUidsLocked(); 1802 } 1803 } 1804 1805 @GuardedBy("mSettingsLock") resetAssistantServicesUidsLocked()1806 private void resetAssistantServicesUidsLocked() { 1807 mAssistantUids.clear(); 1808 updateAssistantUIdLocked(/* forceUpdate= */ true); 1809 } 1810 1811 @GuardedBy("mSettingsLock") updateAssistantServicesUidsLocked()1812 private void updateAssistantServicesUidsLocked() { 1813 int[] assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray(); 1814 AudioSystem.setAssistantServicesUids(assistantUids); 1815 } 1816 updateActiveAssistantServiceUids()1817 private void updateActiveAssistantServiceUids() { 1818 int [] activeAssistantServiceUids; 1819 synchronized (mSettingsLock) { 1820 activeAssistantServiceUids = mActiveAssistantServiceUids; 1821 } 1822 AudioSystem.setActiveAssistantServicesUids(activeAssistantServiceUids); 1823 } 1824 onReinitVolumes(@onNull String caller)1825 private void onReinitVolumes(@NonNull String caller) { 1826 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 1827 // keep track of any error during stream volume initialization 1828 int status = AudioSystem.AUDIO_STATUS_OK; 1829 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 1830 VolumeStreamState streamState = mStreamStates[streamType]; 1831 final int res = AudioSystem.initStreamVolume( 1832 streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10); 1833 if (res != AudioSystem.AUDIO_STATUS_OK) { 1834 status = res; 1835 Log.e(TAG, "Failed to initStreamVolume (" + res + ") for stream " + streamType); 1836 // stream volume initialization failed, no need to try the others, it will be 1837 // attempted again when MSG_REINIT_VOLUMES is handled 1838 break; 1839 } 1840 streamState.applyAllVolumes(); 1841 } 1842 1843 // did it work? check based on status 1844 if (status != AudioSystem.AUDIO_STATUS_OK) { 1845 sLifecycleLogger.log(new AudioEventLogger.StringEvent( 1846 caller + ": initStreamVolume failed with " + status + " will retry") 1847 .printLog(ALOGE, TAG)); 1848 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 1849 caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 1850 return; 1851 } 1852 1853 // did it work? check based on min/max values of some basic streams 1854 if (!checkVolumeRangeInitialization(caller)) { 1855 return; 1856 } 1857 1858 // success 1859 sLifecycleLogger.log(new AudioEventLogger.StringEvent( 1860 caller + ": initStreamVolume succeeded").printLog(ALOGI, TAG)); 1861 } 1862 1863 /** 1864 * Check volume ranges were properly initialized 1865 * @return true if volume ranges were successfully initialized 1866 */ checkVolumeRangeInitialization(String caller)1867 private boolean checkVolumeRangeInitialization(String caller) { 1868 boolean success = true; 1869 final int[] basicStreams = { AudioSystem.STREAM_ALARM, AudioSystem.STREAM_RING, 1870 AudioSystem.STREAM_MUSIC, AudioSystem.STREAM_VOICE_CALL, 1871 AudioSystem.STREAM_ACCESSIBILITY }; 1872 for (int streamType : basicStreams) { 1873 final AudioAttributes aa = new AudioAttributes.Builder() 1874 .setInternalLegacyStreamType(streamType).build(); 1875 if (AudioSystem.getMaxVolumeIndexForAttributes(aa) < 0 1876 || AudioSystem.getMinVolumeIndexForAttributes(aa) < 0) { 1877 success = false; 1878 break; 1879 } 1880 } 1881 if (!success) { 1882 sLifecycleLogger.log(new AudioEventLogger.StringEvent( 1883 caller + ": initStreamVolume succeeded but invalid mix/max levels, will retry") 1884 .printLog(ALOGW, TAG)); 1885 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 1886 caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 1887 } 1888 return success; 1889 } 1890 onDispatchAudioServerStateChange(boolean state)1891 private void onDispatchAudioServerStateChange(boolean state) { 1892 synchronized (mAudioServerStateListeners) { 1893 for (AsdProxy asdp : mAudioServerStateListeners.values()) { 1894 try { 1895 asdp.callback().dispatchAudioServerStateChange(state); 1896 } catch (RemoteException e) { 1897 Log.w(TAG, "Could not call dispatchAudioServerStateChange()", e); 1898 } 1899 } 1900 } 1901 } 1902 createAudioSystemThread()1903 private void createAudioSystemThread() { 1904 mAudioSystemThread = new AudioSystemThread(); 1905 mAudioSystemThread.start(); 1906 waitForAudioHandlerCreation(); 1907 } 1908 1909 /** Waits for the volume handler to be created by the other thread. */ waitForAudioHandlerCreation()1910 private void waitForAudioHandlerCreation() { 1911 synchronized(this) { 1912 while (mAudioHandler == null) { 1913 try { 1914 // Wait for mAudioHandler to be set by the other thread 1915 wait(); 1916 } catch (InterruptedException e) { 1917 Log.e(TAG, "Interrupted while waiting on volume handler."); 1918 } 1919 } 1920 } 1921 } 1922 1923 /** 1924 * @see AudioManager#setSupportedSystemUsages(int[]) 1925 */ setSupportedSystemUsages(@onNull @ttributeSystemUsage int[] systemUsages)1926 public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) { 1927 enforceModifyAudioRoutingPermission(); 1928 verifySystemUsages(systemUsages); 1929 1930 synchronized (mSupportedSystemUsagesLock) { 1931 AudioSystem.setSupportedSystemUsages(systemUsages); 1932 mSupportedSystemUsages = systemUsages; 1933 } 1934 } 1935 1936 /** 1937 * @see AudioManager#getSupportedSystemUsages() 1938 */ getSupportedSystemUsages()1939 public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() { 1940 enforceModifyAudioRoutingPermission(); 1941 synchronized (mSupportedSystemUsagesLock) { 1942 return Arrays.copyOf(mSupportedSystemUsages, mSupportedSystemUsages.length); 1943 } 1944 } 1945 verifySystemUsages(@onNull int[] systemUsages)1946 private void verifySystemUsages(@NonNull int[] systemUsages) { 1947 for (int i = 0; i < systemUsages.length; i++) { 1948 if (!AudioAttributes.isSystemUsage(systemUsages[i])) { 1949 throw new IllegalArgumentException("Non-system usage provided: " + systemUsages[i]); 1950 } 1951 } 1952 } 1953 1954 /** 1955 * @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the 1956 * platform configuration file. 1957 */ 1958 @NonNull getAudioProductStrategies()1959 public List<AudioProductStrategy> getAudioProductStrategies() { 1960 // verify permissions 1961 enforceModifyAudioRoutingPermission(); 1962 return AudioProductStrategy.getAudioProductStrategies(); 1963 } 1964 1965 /** 1966 * @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the 1967 * platform configuration file. 1968 */ 1969 @NonNull getAudioVolumeGroups()1970 public List<AudioVolumeGroup> getAudioVolumeGroups() { 1971 // verify permissions 1972 enforceModifyAudioRoutingPermission(); 1973 return AudioVolumeGroup.getAudioVolumeGroups(); 1974 } 1975 checkAllAliasStreamVolumes()1976 private void checkAllAliasStreamVolumes() { 1977 synchronized (mSettingsLock) { 1978 synchronized (VolumeStreamState.class) { 1979 int numStreamTypes = AudioSystem.getNumStreamTypes(); 1980 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 1981 mStreamStates[streamType] 1982 .setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]], TAG); 1983 // apply stream volume 1984 if (!mStreamStates[streamType].mIsMuted) { 1985 mStreamStates[streamType].applyAllVolumes(); 1986 } 1987 } 1988 } 1989 } 1990 } 1991 1992 1993 /** 1994 * Called from AudioDeviceBroker when DEVICE_OUT_HDMI is connected or disconnected. 1995 */ postCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)1996 /*package*/ void postCheckVolumeCecOnHdmiConnection( 1997 @AudioService.ConnectionState int state, String caller) { 1998 sendMsg(mAudioHandler, MSG_HDMI_VOLUME_CHECK, SENDMSG_REPLACE, 1999 state /*arg1*/, 0 /*arg2 ignored*/, caller /*obj*/, 0 /*delay*/); 2000 } 2001 onCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2002 private void onCheckVolumeCecOnHdmiConnection( 2003 @AudioService.ConnectionState int state, String caller) { 2004 if (state == AudioService.CONNECTION_STATE_CONNECTED) { 2005 // DEVICE_OUT_HDMI is now connected 2006 if (mSafeMediaVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)) { 2007 scheduleMusicActiveCheck(); 2008 } 2009 2010 if (isPlatformTelevision()) { 2011 synchronized (mHdmiClientLock) { 2012 if (mHdmiManager != null && mHdmiPlaybackClient != null) { 2013 updateHdmiCecSinkLocked( 2014 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)); 2015 } 2016 } 2017 } 2018 sendEnabledSurroundFormats(mContentResolver, true); 2019 } else { 2020 // DEVICE_OUT_HDMI disconnected 2021 if (isPlatformTelevision()) { 2022 synchronized (mHdmiClientLock) { 2023 if (mHdmiManager != null) { 2024 updateHdmiCecSinkLocked( 2025 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)); 2026 } 2027 } 2028 } 2029 } 2030 } 2031 2032 /** 2033 * Asynchronously update volume states for the given device. 2034 * 2035 * @param device a single audio device, ensure that this is not a devices bitmask 2036 * @param caller caller of this method 2037 */ postUpdateVolumeStatesForAudioDevice(int device, String caller)2038 private void postUpdateVolumeStatesForAudioDevice(int device, String caller) { 2039 sendMsg(mAudioHandler, 2040 MSG_UPDATE_VOLUME_STATES_FOR_DEVICE, 2041 SENDMSG_QUEUE, device /*arg1*/, 0 /*arg2*/, caller /*obj*/, 2042 0 /*delay*/); 2043 } 2044 2045 /** 2046 * Update volume states for the given device. 2047 * 2048 * This will initialize the volume index if no volume index is available. 2049 * If the device is the currently routed device, fixed/full volume policies will be applied. 2050 * 2051 * @param device a single audio device, ensure that this is not a devices bitmask 2052 * @param caller caller of this method 2053 */ onUpdateVolumeStatesForAudioDevice(int device, String caller)2054 private void onUpdateVolumeStatesForAudioDevice(int device, String caller) { 2055 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 2056 synchronized (mSettingsLock) { 2057 synchronized (VolumeStreamState.class) { 2058 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 2059 updateVolumeStates(device, streamType, caller); 2060 } 2061 } 2062 } 2063 } 2064 2065 /** 2066 * Update volume states for the given device and given stream. 2067 * 2068 * This will initialize the volume index if no volume index is available. 2069 * If the device is the currently routed device, fixed/full volume policies will be applied. 2070 * 2071 * @param device a single audio device, ensure that this is not a devices bitmask 2072 * @param streamType streamType to be updated 2073 * @param caller caller of this method 2074 */ updateVolumeStates(int device, int streamType, String caller)2075 private void updateVolumeStates(int device, int streamType, String caller) { 2076 // Handle device volume aliasing of SPEAKER_SAFE. 2077 if (device == AudioSystem.DEVICE_OUT_SPEAKER_SAFE) { 2078 device = AudioSystem.DEVICE_OUT_SPEAKER; 2079 } 2080 if (!mStreamStates[streamType].hasIndexForDevice(device)) { 2081 // set the default value, if device is affected by a full/fix/abs volume rule, it 2082 // will taken into account in checkFixedVolumeDevices() 2083 mStreamStates[streamType].setIndex( 2084 mStreamStates[mStreamVolumeAlias[streamType]] 2085 .getIndex(AudioSystem.DEVICE_OUT_DEFAULT), 2086 device, caller, true /*hasModifyAudioSettings*/); 2087 } 2088 2089 // Check if device to be updated is routed for the given audio stream 2090 // This may include devices such as SPEAKER_SAFE. 2091 List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributesInt( 2092 new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build(), 2093 true /* forVolume */); 2094 for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) { 2095 if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType( 2096 device)) { 2097 mStreamStates[streamType].checkFixedVolumeDevices(); 2098 2099 // Unmute streams if required and device is full volume 2100 if (isStreamMute(streamType) && mFullVolumeDevices.contains(device)) { 2101 mStreamStates[streamType].mute(false); 2102 } 2103 } 2104 } 2105 } 2106 checkAllFixedVolumeDevices()2107 private void checkAllFixedVolumeDevices() 2108 { 2109 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2110 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 2111 mStreamStates[streamType].checkFixedVolumeDevices(); 2112 } 2113 } 2114 checkAllFixedVolumeDevices(int streamType)2115 private void checkAllFixedVolumeDevices(int streamType) { 2116 mStreamStates[streamType].checkFixedVolumeDevices(); 2117 } 2118 checkMuteAffectedStreams()2119 private void checkMuteAffectedStreams() { 2120 // any stream with a min level > 0 is not muteable by definition 2121 // STREAM_VOICE_CALL and STREAM_BLUETOOTH_SCO can be muted by applications 2122 // that has the the MODIFY_PHONE_STATE permission. 2123 for (int i = 0; i < mStreamStates.length; i++) { 2124 final VolumeStreamState vss = mStreamStates[i]; 2125 if (vss.mIndexMin > 0 && 2126 (vss.mStreamType != AudioSystem.STREAM_VOICE_CALL && 2127 vss.mStreamType != AudioSystem.STREAM_BLUETOOTH_SCO)) { 2128 mMuteAffectedStreams &= ~(1 << vss.mStreamType); 2129 } 2130 } 2131 } 2132 createStreamStates()2133 private void createStreamStates() { 2134 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2135 VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes]; 2136 2137 for (int i = 0; i < numStreamTypes; i++) { 2138 streams[i] = 2139 new VolumeStreamState(System.VOLUME_SETTINGS_INT[mStreamVolumeAlias[i]], i); 2140 } 2141 2142 checkAllFixedVolumeDevices(); 2143 checkAllAliasStreamVolumes(); 2144 checkMuteAffectedStreams(); 2145 updateDefaultVolumes(); 2146 } 2147 2148 /** 2149 * Update default indexes from aliased streams. Must be called after mStreamStates is created 2150 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for default 2151 * index. Need to make default index configurable and independent of streams. 2152 * Fallback on music stream for default initialization to take benefit of property based default 2153 * initialization. 2154 * For other volume groups not linked to any streams, default music stream index is considered. 2155 */ updateDefaultVolumes()2156 private void updateDefaultVolumes() { 2157 for (int stream = 0; stream < mStreamStates.length; stream++) { 2158 int streamVolumeAlias = mStreamVolumeAlias[stream]; 2159 if (mUseVolumeGroupAliases) { 2160 if (AudioSystem.DEFAULT_STREAM_VOLUME[stream] != UNSET_INDEX) { 2161 // Already initialized through default property based mecanism. 2162 continue; 2163 } 2164 streamVolumeAlias = AudioSystem.STREAM_MUSIC; 2165 int defaultAliasVolume = getUiDefaultRescaledIndex(streamVolumeAlias, stream); 2166 if ((defaultAliasVolume >= MIN_STREAM_VOLUME[stream]) 2167 && (defaultAliasVolume <= MAX_STREAM_VOLUME[stream])) { 2168 AudioSystem.DEFAULT_STREAM_VOLUME[stream] = defaultAliasVolume; 2169 continue; 2170 } 2171 } 2172 if (stream != streamVolumeAlias) { 2173 AudioSystem.DEFAULT_STREAM_VOLUME[stream] = 2174 getUiDefaultRescaledIndex(streamVolumeAlias, stream); 2175 } 2176 } 2177 } 2178 getUiDefaultRescaledIndex(int srcStream, int dstStream)2179 private int getUiDefaultRescaledIndex(int srcStream, int dstStream) { 2180 return (rescaleIndex(AudioSystem.DEFAULT_STREAM_VOLUME[srcStream] * 10, 2181 srcStream, dstStream) + 5) / 10; 2182 } 2183 dumpStreamStates(PrintWriter pw)2184 private void dumpStreamStates(PrintWriter pw) { 2185 pw.println("\nStream volumes (device: index)"); 2186 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2187 for (int i = 0; i < numStreamTypes; i++) { 2188 StringBuilder alias = new StringBuilder(); 2189 if (mStreamVolumeAlias[i] != i) { 2190 alias.append(" (aliased to: ") 2191 .append(AudioSystem.STREAM_NAMES[mStreamVolumeAlias[i]]) 2192 .append(")"); 2193 } 2194 pw.println("- " + AudioSystem.STREAM_NAMES[i] + alias + ":"); 2195 mStreamStates[i].dump(pw); 2196 pw.println(""); 2197 } 2198 pw.print("\n- mute affected streams = 0x"); 2199 pw.println(Integer.toHexString(mMuteAffectedStreams)); 2200 } 2201 updateStreamVolumeAlias(boolean updateVolumes, String caller)2202 private void updateStreamVolumeAlias(boolean updateVolumes, String caller) { 2203 int dtmfStreamAlias; 2204 final int a11yStreamAlias = sIndependentA11yVolume ? 2205 AudioSystem.STREAM_ACCESSIBILITY : AudioSystem.STREAM_MUSIC; 2206 final int assistantStreamAlias = mContext.getResources().getBoolean( 2207 com.android.internal.R.bool.config_useAssistantVolume) ? 2208 AudioSystem.STREAM_ASSISTANT : AudioSystem.STREAM_MUSIC; 2209 2210 if (mIsSingleVolume) { 2211 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION.clone(); 2212 dtmfStreamAlias = AudioSystem.STREAM_MUSIC; 2213 } else if (mUseVolumeGroupAliases) { 2214 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_NONE.clone(); 2215 dtmfStreamAlias = AudioSystem.STREAM_DTMF; 2216 } else { 2217 switch (mPlatformType) { 2218 case AudioSystem.PLATFORM_VOICE: 2219 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_VOICE.clone(); 2220 dtmfStreamAlias = AudioSystem.STREAM_RING; 2221 break; 2222 default: 2223 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_DEFAULT.clone(); 2224 dtmfStreamAlias = AudioSystem.STREAM_MUSIC; 2225 } 2226 if (!mNotifAliasRing) { 2227 mStreamVolumeAlias[AudioSystem.STREAM_NOTIFICATION] = 2228 AudioSystem.STREAM_NOTIFICATION; 2229 } 2230 } 2231 2232 if (mIsSingleVolume) { 2233 mRingerModeAffectedStreams = 0; 2234 } else { 2235 if (isInCommunication()) { 2236 dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL; 2237 mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF); 2238 } else { 2239 mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF); 2240 } 2241 } 2242 2243 mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias; 2244 mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias; 2245 mStreamVolumeAlias[AudioSystem.STREAM_ASSISTANT] = assistantStreamAlias; 2246 2247 if (updateVolumes && mStreamStates != null) { 2248 updateDefaultVolumes(); 2249 2250 synchronized (mSettingsLock) { 2251 synchronized (VolumeStreamState.class) { 2252 mStreamStates[AudioSystem.STREAM_DTMF] 2253 .setAllIndexes(mStreamStates[dtmfStreamAlias], caller); 2254 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setSettingName( 2255 System.VOLUME_SETTINGS_INT[a11yStreamAlias]); 2256 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setAllIndexes( 2257 mStreamStates[a11yStreamAlias], caller); 2258 } 2259 } 2260 if (sIndependentA11yVolume) { 2261 // restore the a11y values from the settings 2262 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].readSettings(); 2263 } 2264 2265 // apply stream mute states according to new value of mRingerModeAffectedStreams 2266 setRingerModeInt(getRingerModeInternal(), false); 2267 sendMsg(mAudioHandler, 2268 MSG_SET_ALL_VOLUMES, 2269 SENDMSG_QUEUE, 2270 0, 2271 0, 2272 mStreamStates[AudioSystem.STREAM_DTMF], 0); 2273 sendMsg(mAudioHandler, 2274 MSG_SET_ALL_VOLUMES, 2275 SENDMSG_QUEUE, 2276 0, 2277 0, 2278 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY], 0); 2279 } 2280 } 2281 readDockAudioSettings(ContentResolver cr)2282 private void readDockAudioSettings(ContentResolver cr) 2283 { 2284 mDockAudioMediaEnabled = mSettings.getGlobalInt( 2285 cr, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED, 0) == 1; 2286 2287 sendMsg(mAudioHandler, 2288 MSG_SET_FORCE_USE, 2289 SENDMSG_QUEUE, 2290 AudioSystem.FOR_DOCK, 2291 mDockAudioMediaEnabled ? 2292 AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE, 2293 new String("readDockAudioSettings"), 2294 0); 2295 2296 } 2297 2298 updateMasterMono(ContentResolver cr)2299 private void updateMasterMono(ContentResolver cr) 2300 { 2301 final boolean masterMono = mSettings.getSystemIntForUser( 2302 cr, System.MASTER_MONO, 0 /* default */, UserHandle.USER_CURRENT) == 1; 2303 if (DEBUG_VOL) { 2304 Log.d(TAG, String.format("Master mono %b", masterMono)); 2305 } 2306 AudioSystem.setMasterMono(masterMono); 2307 } 2308 updateMasterBalance(ContentResolver cr)2309 private void updateMasterBalance(ContentResolver cr) { 2310 final float masterBalance = System.getFloatForUser( 2311 cr, System.MASTER_BALANCE, 0.f /* default */, UserHandle.USER_CURRENT); 2312 if (DEBUG_VOL) { 2313 Log.d(TAG, String.format("Master balance %f", masterBalance)); 2314 } 2315 if (AudioSystem.setMasterBalance(masterBalance) != 0) { 2316 Log.e(TAG, String.format("setMasterBalance failed for %f", masterBalance)); 2317 } 2318 } 2319 sendEncodedSurroundMode(ContentResolver cr, String eventSource)2320 private void sendEncodedSurroundMode(ContentResolver cr, String eventSource) 2321 { 2322 final int encodedSurroundMode = mSettings.getGlobalInt( 2323 cr, Settings.Global.ENCODED_SURROUND_OUTPUT, 2324 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 2325 sendEncodedSurroundMode(encodedSurroundMode, eventSource); 2326 } 2327 sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)2328 private void sendEncodedSurroundMode(int encodedSurroundMode, String eventSource) 2329 { 2330 // initialize to guaranteed bad value 2331 int forceSetting = AudioSystem.NUM_FORCE_CONFIG; 2332 switch (encodedSurroundMode) { 2333 case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO: 2334 forceSetting = AudioSystem.FORCE_NONE; 2335 break; 2336 case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER: 2337 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_NEVER; 2338 break; 2339 case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS: 2340 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_ALWAYS; 2341 break; 2342 case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL: 2343 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_MANUAL; 2344 break; 2345 default: 2346 Log.e(TAG, "updateSurroundSoundSettings: illegal value " 2347 + encodedSurroundMode); 2348 break; 2349 } 2350 if (forceSetting != AudioSystem.NUM_FORCE_CONFIG) { 2351 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_ENCODED_SURROUND, forceSetting, 2352 eventSource); 2353 } 2354 } 2355 2356 @Override // Binder call onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)2357 public void onShellCommand(FileDescriptor in, FileDescriptor out, 2358 FileDescriptor err, String[] args, ShellCallback callback, 2359 ResultReceiver resultReceiver) { 2360 if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_AUDIO_POLICY) 2361 != PackageManager.PERMISSION_GRANTED) { 2362 throw new SecurityException("Missing MANAGE_AUDIO_POLICY permission"); 2363 } 2364 new AudioManagerShellCommand(AudioService.this).exec(this, in, out, err, 2365 args, callback, resultReceiver); 2366 } 2367 2368 /** @see AudioManager#getSurroundFormats() */ 2369 @Override getSurroundFormats()2370 public Map<Integer, Boolean> getSurroundFormats() { 2371 Map<Integer, Boolean> surroundFormats = new HashMap<>(); 2372 int status = AudioSystem.getSurroundFormats(surroundFormats); 2373 if (status != AudioManager.SUCCESS) { 2374 // fail and bail! 2375 Log.e(TAG, "getSurroundFormats failed:" + status); 2376 return new HashMap<>(); // Always return a map. 2377 } 2378 return surroundFormats; 2379 } 2380 2381 /** @see AudioManager#getReportedSurroundFormats() */ 2382 @Override getReportedSurroundFormats()2383 public List<Integer> getReportedSurroundFormats() { 2384 ArrayList<Integer> reportedSurroundFormats = new ArrayList<>(); 2385 int status = AudioSystem.getReportedSurroundFormats(reportedSurroundFormats); 2386 if (status != AudioManager.SUCCESS) { 2387 // fail and bail! 2388 Log.e(TAG, "getReportedSurroundFormats failed:" + status); 2389 return new ArrayList<>(); // Always return a list. 2390 } 2391 return reportedSurroundFormats; 2392 } 2393 2394 /** @see AudioManager#isSurroundFormatEnabled(int) */ 2395 @Override isSurroundFormatEnabled(int audioFormat)2396 public boolean isSurroundFormatEnabled(int audioFormat) { 2397 if (!isSurroundFormat(audioFormat)) { 2398 Log.w(TAG, "audioFormat to enable is not a surround format."); 2399 return false; 2400 } 2401 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS) 2402 != PackageManager.PERMISSION_GRANTED) { 2403 throw new SecurityException("Missing WRITE_SETTINGS permission"); 2404 } 2405 2406 final long token = Binder.clearCallingIdentity(); 2407 try { 2408 synchronized (mSettingsLock) { 2409 HashSet<Integer> enabledFormats = getEnabledFormats(); 2410 return enabledFormats.contains(audioFormat); 2411 } 2412 } finally { 2413 Binder.restoreCallingIdentity(token); 2414 } 2415 } 2416 2417 /** @see AudioManager#setSurroundFormatEnabled(int, boolean) */ 2418 @Override setSurroundFormatEnabled(int audioFormat, boolean enabled)2419 public boolean setSurroundFormatEnabled(int audioFormat, boolean enabled) { 2420 if (!isSurroundFormat(audioFormat)) { 2421 Log.w(TAG, "audioFormat to enable is not a surround format."); 2422 return false; 2423 } 2424 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS) 2425 != PackageManager.PERMISSION_GRANTED) { 2426 throw new SecurityException("Missing WRITE_SETTINGS permission"); 2427 } 2428 2429 HashSet<Integer> enabledFormats = getEnabledFormats(); 2430 if (enabled) { 2431 enabledFormats.add(audioFormat); 2432 } else { 2433 enabledFormats.remove(audioFormat); 2434 } 2435 final long token = Binder.clearCallingIdentity(); 2436 try { 2437 synchronized (mSettingsLock) { 2438 mSettings.putGlobalString(mContentResolver, 2439 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS, 2440 TextUtils.join(",", enabledFormats)); 2441 } 2442 } finally { 2443 Binder.restoreCallingIdentity(token); 2444 } 2445 return true; 2446 } 2447 2448 /** @see AudioManager#setEncodedSurroundMode(int) */ 2449 @Override setEncodedSurroundMode(@udioManager.EncodedSurroundOutputMode int mode)2450 public boolean setEncodedSurroundMode(@AudioManager.EncodedSurroundOutputMode int mode) { 2451 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS) 2452 != PackageManager.PERMISSION_GRANTED) { 2453 throw new SecurityException("Missing WRITE_SETTINGS permission"); 2454 } 2455 2456 final long token = Binder.clearCallingIdentity(); 2457 try { 2458 synchronized (mSettingsLock) { 2459 mSettings.putGlobalInt(mContentResolver, 2460 Settings.Global.ENCODED_SURROUND_OUTPUT, 2461 toEncodedSurroundSetting(mode)); 2462 } 2463 } finally { 2464 Binder.restoreCallingIdentity(token); 2465 } 2466 return true; 2467 } 2468 2469 /** @see AudioManager#getEncodedSurroundMode() */ 2470 @Override getEncodedSurroundMode(int targetSdkVersion)2471 public int getEncodedSurroundMode(int targetSdkVersion) { 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 int encodedSurroundSetting = mSettings.getGlobalInt(mContentResolver, 2481 Settings.Global.ENCODED_SURROUND_OUTPUT, 2482 AudioManager.ENCODED_SURROUND_OUTPUT_AUTO); 2483 return toEncodedSurroundOutputMode(encodedSurroundSetting, targetSdkVersion); 2484 } 2485 } finally { 2486 Binder.restoreCallingIdentity(token); 2487 } 2488 } 2489 2490 /** @return the formats that are enabled in global settings */ getEnabledFormats()2491 private HashSet<Integer> getEnabledFormats() { 2492 HashSet<Integer> formats = new HashSet<>(); 2493 String enabledFormats = mSettings.getGlobalString(mContentResolver, 2494 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 2495 if (enabledFormats != null) { 2496 try { 2497 Arrays.stream(TextUtils.split(enabledFormats, ",")) 2498 .mapToInt(Integer::parseInt) 2499 .forEach(formats::add); 2500 } catch (NumberFormatException e) { 2501 Log.w(TAG, "ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS misformatted.", e); 2502 } 2503 } 2504 return formats; 2505 } 2506 2507 @SuppressWarnings("AndroidFrameworkCompatChange") 2508 @AudioManager.EncodedSurroundOutputMode toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion)2509 private int toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion) { 2510 if (targetSdkVersion <= Build.VERSION_CODES.S 2511 && encodedSurroundSetting > Settings.Global.ENCODED_SURROUND_SC_MAX) { 2512 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN; 2513 } 2514 switch (encodedSurroundSetting) { 2515 case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO: 2516 return AudioManager.ENCODED_SURROUND_OUTPUT_AUTO; 2517 case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER: 2518 return AudioManager.ENCODED_SURROUND_OUTPUT_NEVER; 2519 case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS: 2520 return AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS; 2521 case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL: 2522 return AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL; 2523 default: 2524 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN; 2525 } 2526 } 2527 toEncodedSurroundSetting( @udioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode)2528 private int toEncodedSurroundSetting( 2529 @AudioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode) { 2530 switch (encodedSurroundOutputMode) { 2531 case AudioManager.ENCODED_SURROUND_OUTPUT_NEVER: 2532 return Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER; 2533 case AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS: 2534 return Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS; 2535 case AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL: 2536 return Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL; 2537 default: 2538 return Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO; 2539 } 2540 } 2541 isSurroundFormat(int audioFormat)2542 private boolean isSurroundFormat(int audioFormat) { 2543 for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) { 2544 if (sf == audioFormat) { 2545 return true; 2546 } 2547 } 2548 return false; 2549 } 2550 sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate)2551 private void sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate) { 2552 if (mEncodedSurroundMode != Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL) { 2553 // Manually enable surround formats only when the setting is in manual mode. 2554 return; 2555 } 2556 String enabledSurroundFormats = mSettings.getGlobalString( 2557 cr, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 2558 if (enabledSurroundFormats == null) { 2559 // Never allow enabledSurroundFormats as a null, which could happen when 2560 // ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS is not appear in settings DB. 2561 enabledSurroundFormats = ""; 2562 } 2563 if (!forceUpdate && TextUtils.equals(enabledSurroundFormats, mEnabledSurroundFormats)) { 2564 // Update enabled surround formats to AudioPolicyManager only when forceUpdate 2565 // is true or enabled surround formats changed. 2566 return; 2567 } 2568 2569 mEnabledSurroundFormats = enabledSurroundFormats; 2570 String[] surroundFormats = TextUtils.split(enabledSurroundFormats, ","); 2571 ArrayList<Integer> formats = new ArrayList<>(); 2572 for (String format : surroundFormats) { 2573 try { 2574 int audioFormat = Integer.valueOf(format); 2575 if (isSurroundFormat(audioFormat) && !formats.contains(audioFormat)) { 2576 formats.add(audioFormat); 2577 } 2578 } catch (Exception e) { 2579 Log.e(TAG, "Invalid enabled surround format:" + format); 2580 } 2581 } 2582 // Set filtered surround formats to settings DB in case 2583 // there are invalid surround formats in original settings. 2584 mSettings.putGlobalString(mContext.getContentResolver(), 2585 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS, 2586 TextUtils.join(",", formats)); 2587 sendMsg(mAudioHandler, MSG_ENABLE_SURROUND_FORMATS, SENDMSG_QUEUE, 0, 0, formats, 0); 2588 } 2589 onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats)2590 private void onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats) { 2591 // Set surround format enabled accordingly. 2592 for (int surroundFormat : AudioFormat.SURROUND_SOUND_ENCODING) { 2593 boolean enabled = enabledSurroundFormats.contains(surroundFormat); 2594 int ret = AudioSystem.setSurroundFormatEnabled(surroundFormat, enabled); 2595 Log.i(TAG, "enable surround format:" + surroundFormat + " " + enabled + " " + ret); 2596 } 2597 } 2598 2599 @GuardedBy("mSettingsLock") updateAssistantUIdLocked(boolean forceUpdate)2600 private void updateAssistantUIdLocked(boolean forceUpdate) { 2601 int assistantUid = INVALID_UID; 2602 // Consider assistants in the following order of priority: 2603 // 1) apk in assistant role 2604 // 2) voice interaction service 2605 // 3) assistant service 2606 2607 String packageName = ""; 2608 if (mRoleObserver != null) { 2609 packageName = mRoleObserver.getAssistantRoleHolder(); 2610 } 2611 if (TextUtils.isEmpty(packageName)) { 2612 String assistantName = mSettings.getSecureStringForUser( 2613 mContentResolver, 2614 Settings.Secure.VOICE_INTERACTION_SERVICE, UserHandle.USER_CURRENT); 2615 if (TextUtils.isEmpty(assistantName)) { 2616 assistantName = mSettings.getSecureStringForUser( 2617 mContentResolver, 2618 Settings.Secure.ASSISTANT, UserHandle.USER_CURRENT); 2619 } 2620 if (!TextUtils.isEmpty(assistantName)) { 2621 ComponentName componentName = ComponentName.unflattenFromString(assistantName); 2622 if (componentName == null) { 2623 Slog.w(TAG, "Invalid service name for " 2624 + Settings.Secure.VOICE_INTERACTION_SERVICE + ": " + assistantName); 2625 return; 2626 } 2627 packageName = componentName.getPackageName(); 2628 } 2629 } 2630 if (!TextUtils.isEmpty(packageName)) { 2631 PackageManager pm = mContext.getPackageManager(); 2632 ActivityManager am = 2633 (ActivityManager) mContext.getSystemService(mContext.ACTIVITY_SERVICE); 2634 2635 if (pm.checkPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD, packageName) 2636 == PackageManager.PERMISSION_GRANTED) { 2637 try { 2638 assistantUid = pm.getPackageUidAsUser(packageName, am.getCurrentUser()); 2639 } catch (PackageManager.NameNotFoundException e) { 2640 Log.e(TAG, 2641 "updateAssistantUId() could not find UID for package: " + packageName); 2642 } 2643 } 2644 } 2645 if ((mPrimaryAssistantUid != assistantUid) || forceUpdate) { 2646 mAssistantUids.remove(mPrimaryAssistantUid); 2647 mPrimaryAssistantUid = assistantUid; 2648 addAssistantServiceUidsLocked(new int[]{mPrimaryAssistantUid}); 2649 } 2650 } 2651 readPersistedSettings()2652 private void readPersistedSettings() { 2653 if (!mSystemServer.isPrivileged()) { 2654 return; 2655 } 2656 final ContentResolver cr = mContentResolver; 2657 2658 int ringerModeFromSettings = 2659 mSettings.getGlobalInt( 2660 cr, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL); 2661 int ringerMode = ringerModeFromSettings; 2662 // validity check in case the settings are restored from a device with incompatible 2663 // ringer modes 2664 if (!isValidRingerMode(ringerMode)) { 2665 ringerMode = AudioManager.RINGER_MODE_NORMAL; 2666 } 2667 if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { 2668 ringerMode = AudioManager.RINGER_MODE_SILENT; 2669 } 2670 if (ringerMode != ringerModeFromSettings) { 2671 mSettings.putGlobalInt(cr, Settings.Global.MODE_RINGER, ringerMode); 2672 } 2673 if (mUseFixedVolume || mIsSingleVolume) { 2674 ringerMode = AudioManager.RINGER_MODE_NORMAL; 2675 } 2676 synchronized(mSettingsLock) { 2677 mRingerMode = ringerMode; 2678 if (mRingerModeExternal == -1) { 2679 mRingerModeExternal = mRingerMode; 2680 } 2681 2682 // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting 2683 // are still needed while setVibrateSetting() and getVibrateSetting() are being 2684 // deprecated. 2685 mVibrateSetting = AudioSystem.getValueForVibrateSetting(0, 2686 AudioManager.VIBRATE_TYPE_NOTIFICATION, 2687 mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT 2688 : AudioManager.VIBRATE_SETTING_OFF); 2689 mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, 2690 AudioManager.VIBRATE_TYPE_RINGER, 2691 mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT 2692 : AudioManager.VIBRATE_SETTING_OFF); 2693 2694 updateRingerAndZenModeAffectedStreams(); 2695 readDockAudioSettings(cr); 2696 sendEncodedSurroundMode(cr, "readPersistedSettings"); 2697 sendEnabledSurroundFormats(cr, true); 2698 updateAssistantUIdLocked(/* forceUpdate= */ true); 2699 resetActiveAssistantUidsLocked(); 2700 AudioSystem.setRttEnabled(mRttEnabled); 2701 } 2702 2703 mMuteAffectedStreams = mSettings.getSystemIntForUser(cr, 2704 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED, 2705 UserHandle.USER_CURRENT); 2706 2707 updateMasterMono(cr); 2708 2709 updateMasterBalance(cr); 2710 2711 // Each stream will read its own persisted settings 2712 2713 // Broadcast the sticky intents 2714 broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal); 2715 broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode); 2716 2717 // Broadcast vibrate settings 2718 broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER); 2719 broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION); 2720 2721 // Load settings for the volume controller 2722 mVolumeController.loadSettings(cr); 2723 } 2724 2725 @GuardedBy("mSettingsLock") resetActiveAssistantUidsLocked()2726 private void resetActiveAssistantUidsLocked() { 2727 mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS; 2728 updateActiveAssistantServiceUids(); 2729 } 2730 readUserRestrictions()2731 private void readUserRestrictions() { 2732 if (!mSystemServer.isPrivileged()) { 2733 return; 2734 } 2735 final int currentUser = getCurrentUserId(); 2736 2737 // Check the current user restriction. 2738 boolean masterMute = 2739 mUserManagerInternal.getUserRestriction(currentUser, 2740 UserManager.DISALLOW_UNMUTE_DEVICE) 2741 || mUserManagerInternal.getUserRestriction(currentUser, 2742 UserManager.DISALLOW_ADJUST_VOLUME); 2743 if (mUseFixedVolume) { 2744 masterMute = false; 2745 AudioSystem.setMasterVolume(1.0f); 2746 } 2747 if (DEBUG_VOL) { 2748 Log.d(TAG, String.format("Master mute %s, user=%d", masterMute, currentUser)); 2749 } 2750 AudioSystem.setMasterMute(masterMute); 2751 broadcastMasterMuteStatus(masterMute); 2752 2753 mMicMuteFromRestrictions = mUserManagerInternal.getUserRestriction( 2754 currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE); 2755 if (DEBUG_VOL) { 2756 Log.d(TAG, String.format("Mic mute %b, user=%d", mMicMuteFromRestrictions, 2757 currentUser)); 2758 } 2759 setMicrophoneMuteNoCallerCheck(currentUser); 2760 } 2761 getIndexRange(int streamType)2762 private int getIndexRange(int streamType) { 2763 return (mStreamStates[streamType].getMaxIndex() - mStreamStates[streamType].getMinIndex()); 2764 } 2765 rescaleIndex(VolumeInfo volumeInfo, int dstStream)2766 private int rescaleIndex(VolumeInfo volumeInfo, int dstStream) { 2767 if (volumeInfo.getVolumeIndex() == VolumeInfo.INDEX_NOT_SET 2768 || volumeInfo.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET 2769 || volumeInfo.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) { 2770 Log.e(TAG, "rescaleIndex: volumeInfo has invalid index or range"); 2771 return mStreamStates[dstStream].getMinIndex(); 2772 } 2773 return rescaleIndex(volumeInfo.getVolumeIndex(), 2774 volumeInfo.getMinVolumeIndex(), volumeInfo.getMaxVolumeIndex(), 2775 mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex()); 2776 } 2777 rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo)2778 private int rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo) { 2779 int dstMin = dstVolumeInfo.getMinVolumeIndex(); 2780 int dstMax = dstVolumeInfo.getMaxVolumeIndex(); 2781 // Don't rescale index if the VolumeInfo is missing a min or max index 2782 if (dstMin == VolumeInfo.INDEX_NOT_SET || dstMax == VolumeInfo.INDEX_NOT_SET) { 2783 return index; 2784 } 2785 return rescaleIndex(index, 2786 mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(), 2787 dstMin, dstMax); 2788 } 2789 rescaleIndex(int index, int srcStream, int dstStream)2790 private int rescaleIndex(int index, int srcStream, int dstStream) { 2791 return rescaleIndex(index, 2792 mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(), 2793 mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex()); 2794 } 2795 rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax)2796 private int rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax) { 2797 int srcRange = srcMax - srcMin; 2798 int dstRange = dstMax - dstMin; 2799 if (srcRange == 0) { 2800 Log.e(TAG, "rescaleIndex : index range should not be zero"); 2801 return dstMin; 2802 } 2803 return dstMin + ((index - srcMin) * dstRange + srcRange / 2) / srcRange; 2804 } 2805 rescaleStep(int step, int srcStream, int dstStream)2806 private int rescaleStep(int step, int srcStream, int dstStream) { 2807 int srcRange = getIndexRange(srcStream); 2808 int dstRange = getIndexRange(dstStream); 2809 if (srcRange == 0) { 2810 Log.e(TAG, "rescaleStep : index range should not be zero"); 2811 return 0; 2812 } 2813 2814 return ((step * dstRange + srcRange / 2) / srcRange); 2815 } 2816 2817 /////////////////////////////////////////////////////////////////////////// 2818 // IPC methods 2819 /////////////////////////////////////////////////////////////////////////// 2820 /** 2821 * @see AudioManager#setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes) 2822 * @see AudioManager#setPreferredDevicesForStrategy(AudioProductStrategy, 2823 * List<AudioDeviceAttributes>) 2824 */ setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices)2825 public int setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices) { 2826 if (devices == null) { 2827 return AudioSystem.ERROR; 2828 } 2829 enforceModifyAudioRoutingPermission(); 2830 final String logString = String.format( 2831 "setPreferredDeviceForStrategy u/pid:%d/%d strat:%d dev:%s", 2832 Binder.getCallingUid(), Binder.getCallingPid(), strategy, 2833 devices.stream().map(e -> e.toString()).collect(Collectors.joining(","))); 2834 sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG)); 2835 if (devices.stream().anyMatch(device -> 2836 device.getRole() == AudioDeviceAttributes.ROLE_INPUT)) { 2837 Log.e(TAG, "Unsupported input routing in " + logString); 2838 return AudioSystem.ERROR; 2839 } 2840 2841 final int status = mDeviceBroker.setPreferredDevicesForStrategySync(strategy, devices); 2842 if (status != AudioSystem.SUCCESS) { 2843 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 2844 } 2845 2846 return status; 2847 } 2848 2849 /** @see AudioManager#removePreferredDeviceForStrategy(AudioProductStrategy) */ removePreferredDevicesForStrategy(int strategy)2850 public int removePreferredDevicesForStrategy(int strategy) { 2851 enforceModifyAudioRoutingPermission(); 2852 final String logString = 2853 String.format("removePreferredDeviceForStrategy strat:%d", strategy); 2854 sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG)); 2855 2856 final int status = mDeviceBroker.removePreferredDevicesForStrategySync(strategy); 2857 if (status != AudioSystem.SUCCESS) { 2858 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 2859 } 2860 return status; 2861 } 2862 2863 /** 2864 * @see AudioManager#getPreferredDeviceForStrategy(AudioProductStrategy) 2865 * @see AudioManager#getPreferredDevicesForStrategy(AudioProductStrategy) 2866 */ getPreferredDevicesForStrategy(int strategy)2867 public List<AudioDeviceAttributes> getPreferredDevicesForStrategy(int strategy) { 2868 enforceModifyAudioRoutingPermission(); 2869 List<AudioDeviceAttributes> devices = new ArrayList<>(); 2870 final long identity = Binder.clearCallingIdentity(); 2871 final int status = AudioSystem.getDevicesForRoleAndStrategy( 2872 strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices); 2873 Binder.restoreCallingIdentity(identity); 2874 if (status != AudioSystem.SUCCESS) { 2875 Log.e(TAG, String.format("Error %d in getPreferredDeviceForStrategy(%d)", 2876 status, strategy)); 2877 return new ArrayList<AudioDeviceAttributes>(); 2878 } else { 2879 return devices; 2880 } 2881 } 2882 2883 /** @see AudioManager#addOnPreferredDevicesForStrategyChangedListener( 2884 * Executor, AudioManager.OnPreferredDevicesForStrategyChangedListener) 2885 */ registerStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)2886 public void registerStrategyPreferredDevicesDispatcher( 2887 @Nullable IStrategyPreferredDevicesDispatcher dispatcher) { 2888 if (dispatcher == null) { 2889 return; 2890 } 2891 enforceModifyAudioRoutingPermission(); 2892 mDeviceBroker.registerStrategyPreferredDevicesDispatcher(dispatcher); 2893 } 2894 2895 /** @see AudioManager#removeOnPreferredDevicesForStrategyChangedListener( 2896 * AudioManager.OnPreferredDevicesForStrategyChangedListener) 2897 */ unregisterStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)2898 public void unregisterStrategyPreferredDevicesDispatcher( 2899 @Nullable IStrategyPreferredDevicesDispatcher dispatcher) { 2900 if (dispatcher == null) { 2901 return; 2902 } 2903 enforceModifyAudioRoutingPermission(); 2904 mDeviceBroker.unregisterStrategyPreferredDevicesDispatcher(dispatcher); 2905 } 2906 2907 /** 2908 * @see AudioManager#setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes) 2909 */ setPreferredDevicesForCapturePreset( int capturePreset, List<AudioDeviceAttributes> devices)2910 public int setPreferredDevicesForCapturePreset( 2911 int capturePreset, List<AudioDeviceAttributes> devices) { 2912 if (devices == null) { 2913 return AudioSystem.ERROR; 2914 } 2915 enforceModifyAudioRoutingPermission(); 2916 final String logString = String.format( 2917 "setPreferredDevicesForCapturePreset u/pid:%d/%d source:%d dev:%s", 2918 Binder.getCallingUid(), Binder.getCallingPid(), capturePreset, 2919 devices.stream().map(e -> e.toString()).collect(Collectors.joining(","))); 2920 sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG)); 2921 if (devices.stream().anyMatch(device -> 2922 device.getRole() == AudioDeviceAttributes.ROLE_OUTPUT)) { 2923 Log.e(TAG, "Unsupported output routing in " + logString); 2924 return AudioSystem.ERROR; 2925 } 2926 2927 final int status = mDeviceBroker.setPreferredDevicesForCapturePresetSync( 2928 capturePreset, devices); 2929 if (status != AudioSystem.SUCCESS) { 2930 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 2931 } 2932 2933 return status; 2934 } 2935 2936 /** @see AudioManager#clearPreferredDevicesForCapturePreset(int) */ clearPreferredDevicesForCapturePreset(int capturePreset)2937 public int clearPreferredDevicesForCapturePreset(int capturePreset) { 2938 enforceModifyAudioRoutingPermission(); 2939 final String logString = String.format( 2940 "removePreferredDeviceForCapturePreset source:%d", capturePreset); 2941 sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG)); 2942 2943 final int status = mDeviceBroker.clearPreferredDevicesForCapturePresetSync(capturePreset); 2944 if (status != AudioSystem.SUCCESS) { 2945 Log.e(TAG, String.format("Error %d in %s", status, logString)); 2946 } 2947 return status; 2948 } 2949 2950 /** 2951 * @see AudioManager#getPreferredDevicesForCapturePreset(int) 2952 */ getPreferredDevicesForCapturePreset(int capturePreset)2953 public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) { 2954 enforceModifyAudioRoutingPermission(); 2955 List<AudioDeviceAttributes> devices = new ArrayList<>(); 2956 final long identity = Binder.clearCallingIdentity(); 2957 final int status = AudioSystem.getDevicesForRoleAndCapturePreset( 2958 capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices); 2959 Binder.restoreCallingIdentity(identity); 2960 if (status != AudioSystem.SUCCESS) { 2961 Log.e(TAG, String.format("Error %d in getPreferredDeviceForCapturePreset(%d)", 2962 status, capturePreset)); 2963 return new ArrayList<AudioDeviceAttributes>(); 2964 } else { 2965 return devices; 2966 } 2967 } 2968 2969 /** 2970 * @see AudioManager#addOnPreferredDevicesForCapturePresetChangedListener( 2971 * Executor, OnPreferredDevicesForCapturePresetChangedListener) 2972 */ registerCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)2973 public void registerCapturePresetDevicesRoleDispatcher( 2974 @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) { 2975 if (dispatcher == null) { 2976 return; 2977 } 2978 enforceModifyAudioRoutingPermission(); 2979 mDeviceBroker.registerCapturePresetDevicesRoleDispatcher(dispatcher); 2980 } 2981 2982 /** 2983 * @see AudioManager#removeOnPreferredDevicesForCapturePresetChangedListener( 2984 * AudioManager.OnPreferredDevicesForCapturePresetChangedListener) 2985 */ unregisterCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)2986 public void unregisterCapturePresetDevicesRoleDispatcher( 2987 @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) { 2988 if (dispatcher == null) { 2989 return; 2990 } 2991 enforceModifyAudioRoutingPermission(); 2992 mDeviceBroker.unregisterCapturePresetDevicesRoleDispatcher(dispatcher); 2993 } 2994 2995 /** @see AudioManager#getDevicesForAttributes(AudioAttributes) */ getDevicesForAttributes( @onNull AudioAttributes attributes)2996 public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes( 2997 @NonNull AudioAttributes attributes) { 2998 enforceQueryStateOrModifyRoutingPermission(); 2999 return getDevicesForAttributesInt(attributes, false /* forVolume */); 3000 } 3001 3002 /** @see AudioManager#getAudioDevicesForAttributes(AudioAttributes) 3003 * This method is similar with AudioService#getDevicesForAttributes, 3004 * only it doesn't enforce permissions because it is used by an unprivileged public API 3005 * instead of the system API. 3006 */ getDevicesForAttributesUnprotected( @onNull AudioAttributes attributes)3007 public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesUnprotected( 3008 @NonNull AudioAttributes attributes) { 3009 return getDevicesForAttributesInt(attributes, false /* forVolume */); 3010 } 3011 3012 /** 3013 * @see AudioManager#isMusicActive() 3014 * @param remotely true if query is for remote playback (cast), false for local playback. 3015 */ isMusicActive(boolean remotely)3016 public boolean isMusicActive(boolean remotely) { 3017 // no permission required 3018 final long token = Binder.clearCallingIdentity(); 3019 try { 3020 if (remotely) { 3021 return AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, 0); 3022 } else { 3023 return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0); 3024 } 3025 } finally { 3026 Binder.restoreCallingIdentity(token); 3027 } 3028 } 3029 getDevicesForAttributesInt( @onNull AudioAttributes attributes, boolean forVolume)3030 protected @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesInt( 3031 @NonNull AudioAttributes attributes, boolean forVolume) { 3032 Objects.requireNonNull(attributes); 3033 return mAudioSystem.getDevicesForAttributes(attributes, forVolume); 3034 } 3035 3036 // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP, 3037 // KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE handleVolumeKey(@onNull KeyEvent event, boolean isOnTv, @NonNull String callingPackage, @NonNull String caller)3038 public void handleVolumeKey(@NonNull KeyEvent event, boolean isOnTv, 3039 @NonNull String callingPackage, @NonNull String caller) { 3040 int keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_NORMAL; 3041 if (isOnTv) { 3042 if (event.getAction() == KeyEvent.ACTION_DOWN) { 3043 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_START; 3044 } else { // may catch more than ACTION_UP, but will end vol adjustement 3045 // the vol key is either released (ACTION_UP), or multiple keys are pressed 3046 // (ACTION_MULTIPLE) and we don't know what to do for volume control on CEC, end 3047 // the repeated volume adjustement 3048 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_END; 3049 } 3050 } else if (event.getAction() != KeyEvent.ACTION_DOWN) { 3051 return; 3052 } 3053 3054 int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND 3055 | AudioManager.FLAG_FROM_KEY; 3056 3057 switch (event.getKeyCode()) { 3058 case KeyEvent.KEYCODE_VOLUME_UP: 3059 adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE, 3060 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 3061 Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode); 3062 break; 3063 case KeyEvent.KEYCODE_VOLUME_DOWN: 3064 adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER, 3065 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 3066 Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode); 3067 break; 3068 case KeyEvent.KEYCODE_VOLUME_MUTE: 3069 if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 3070 adjustSuggestedStreamVolume(AudioManager.ADJUST_TOGGLE_MUTE, 3071 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 3072 Binder.getCallingUid(), Binder.getCallingPid(), 3073 true, AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 3074 } 3075 break; 3076 default: 3077 Log.e(TAG, "Invalid key code " + event.getKeyCode() + " sent by " + callingPackage); 3078 return; // not needed but added if code gets added below this switch statement 3079 } 3080 } 3081 setNavigationRepeatSoundEffectsEnabled(boolean enabled)3082 public void setNavigationRepeatSoundEffectsEnabled(boolean enabled) { 3083 mNavigationRepeatSoundEffectsEnabled = enabled; 3084 } 3085 3086 /** 3087 * @return true if the fast scroll sound effects are enabled 3088 */ areNavigationRepeatSoundEffectsEnabled()3089 public boolean areNavigationRepeatSoundEffectsEnabled() { 3090 return mNavigationRepeatSoundEffectsEnabled; 3091 } 3092 setHomeSoundEffectEnabled(boolean enabled)3093 public void setHomeSoundEffectEnabled(boolean enabled) { 3094 mHomeSoundEffectEnabled = enabled; 3095 } 3096 3097 /** 3098 * @return true if the home sound effect is enabled 3099 */ isHomeSoundEffectEnabled()3100 public boolean isHomeSoundEffectEnabled() { 3101 return mHomeSoundEffectEnabled; 3102 } 3103 3104 /** 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)3105 private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, 3106 String callingPackage, String caller, int uid, int pid, boolean hasModifyAudioSettings, 3107 int keyEventMode) { 3108 if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType 3109 + ", flags=" + flags + ", caller=" + caller 3110 + ", volControlStream=" + mVolumeControlStream 3111 + ", userSelect=" + mUserSelectedVolumeControlStream); 3112 if (direction != AudioManager.ADJUST_SAME) { 3113 sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType, 3114 direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage) 3115 .append("/").append(caller).append(" uid:").append(uid).toString())); 3116 } 3117 3118 boolean hasExternalVolumeController = notifyExternalVolumeController(direction); 3119 3120 new MediaMetrics.Item(mMetricsId + "adjustSuggestedStreamVolume") 3121 .setUid(Binder.getCallingUid()) 3122 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage) 3123 .set(MediaMetrics.Property.CLIENT_NAME, caller) 3124 .set(MediaMetrics.Property.DIRECTION, direction > 0 3125 ? MediaMetrics.Value.UP : MediaMetrics.Value.DOWN) 3126 .set(MediaMetrics.Property.EXTERNAL, hasExternalVolumeController 3127 ? MediaMetrics.Value.YES : MediaMetrics.Value.NO) 3128 .set(MediaMetrics.Property.FLAGS, flags) 3129 .record(); 3130 3131 if (hasExternalVolumeController) { 3132 return; 3133 } 3134 3135 final int streamType; 3136 synchronized (mForceControlStreamLock) { 3137 // Request lock in case mVolumeControlStream is changed by other thread. 3138 if (mUserSelectedVolumeControlStream) { // implies mVolumeControlStream != -1 3139 streamType = mVolumeControlStream; 3140 } else { 3141 final int maybeActiveStreamType = getActiveStreamType(suggestedStreamType); 3142 final boolean activeForReal; 3143 if (maybeActiveStreamType == AudioSystem.STREAM_RING 3144 || maybeActiveStreamType == AudioSystem.STREAM_NOTIFICATION) { 3145 activeForReal = wasStreamActiveRecently(maybeActiveStreamType, 0); 3146 } else { 3147 activeForReal = mAudioSystem.isStreamActive(maybeActiveStreamType, 0); 3148 } 3149 if (activeForReal || mVolumeControlStream == -1) { 3150 streamType = maybeActiveStreamType; 3151 } else { 3152 streamType = mVolumeControlStream; 3153 } 3154 } 3155 } 3156 3157 final boolean isMute = isMuteAdjust(direction); 3158 3159 ensureValidStreamType(streamType); 3160 final int resolvedStream = mStreamVolumeAlias[streamType]; 3161 3162 // Play sounds on STREAM_RING only. 3163 if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 && 3164 resolvedStream != AudioSystem.STREAM_RING) { 3165 flags &= ~AudioManager.FLAG_PLAY_SOUND; 3166 } 3167 3168 // For notifications/ring, show the ui before making any adjustments 3169 // Don't suppress mute/unmute requests 3170 // Don't suppress adjustments for single volume device 3171 if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute) 3172 && !mIsSingleVolume) { 3173 direction = 0; 3174 flags &= ~AudioManager.FLAG_PLAY_SOUND; 3175 flags &= ~AudioManager.FLAG_VIBRATE; 3176 if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment"); 3177 } 3178 3179 adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid, pid, 3180 null, hasModifyAudioSettings, keyEventMode); 3181 } 3182 notifyExternalVolumeController(int direction)3183 private boolean notifyExternalVolumeController(int direction) { 3184 final IAudioPolicyCallback externalVolumeController; 3185 synchronized (mExtVolumeControllerLock) { 3186 externalVolumeController = mExtVolumeController; 3187 } 3188 if (externalVolumeController == null) { 3189 return false; 3190 } 3191 3192 sendMsg(mAudioHandler, MSG_NOTIFY_VOL_EVENT, SENDMSG_QUEUE, 3193 direction, 0 /*ignored*/, 3194 externalVolumeController, 0 /*delay*/); 3195 return true; 3196 } 3197 3198 /** Retain API for unsupported app usage */ adjustStreamVolume(int streamType, int direction, int flags, String callingPackage)3199 public void adjustStreamVolume(int streamType, int direction, int flags, 3200 String callingPackage) { 3201 adjustStreamVolumeWithAttribution(streamType, direction, flags, callingPackage, null); 3202 } 3203 3204 /** @see AudioManager#adjustStreamVolume(int, int, int) 3205 * Part of service interface, check permissions here */ adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, String callingPackage, String attributionTag)3206 public void adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, 3207 String callingPackage, String attributionTag) { 3208 if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { 3209 Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without" 3210 + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage); 3211 return; 3212 } 3213 3214 sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType, 3215 direction/*val1*/, flags/*val2*/, callingPackage)); 3216 adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage, 3217 Binder.getCallingUid(), Binder.getCallingPid(), attributionTag, 3218 callingHasAudioSettingsPermission(), AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 3219 } 3220 adjustStreamVolume(int streamType, int direction, int flags, String callingPackage, String caller, int uid, int pid, String attributionTag, boolean hasModifyAudioSettings, int keyEventMode)3221 protected void adjustStreamVolume(int streamType, int direction, int flags, 3222 String callingPackage, String caller, int uid, int pid, String attributionTag, 3223 boolean hasModifyAudioSettings, int keyEventMode) { 3224 if (mUseFixedVolume) { 3225 return; 3226 } 3227 if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction 3228 + ", flags=" + flags + ", caller=" + caller); 3229 3230 ensureValidDirection(direction); 3231 ensureValidStreamType(streamType); 3232 3233 boolean isMuteAdjust = isMuteAdjust(direction); 3234 3235 if (isMuteAdjust && !isStreamAffectedByMute(streamType)) { 3236 return; 3237 } 3238 3239 // If adjust is mute and the stream is STREAM_VOICE_CALL or STREAM_BLUETOOTH_SCO, make sure 3240 // that the calling app have the MODIFY_PHONE_STATE permission. 3241 if (isMuteAdjust && 3242 (streamType == AudioSystem.STREAM_VOICE_CALL || 3243 streamType == AudioSystem.STREAM_BLUETOOTH_SCO) && 3244 mContext.checkPermission(android.Manifest.permission.MODIFY_PHONE_STATE, pid, uid) 3245 != PackageManager.PERMISSION_GRANTED) { 3246 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: adjustStreamVolume from pid=" 3247 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 3248 return; 3249 } 3250 3251 // If the stream is STREAM_ASSISTANT, 3252 // make sure that the calling app have the MODIFY_AUDIO_ROUTING permission. 3253 if (streamType == AudioSystem.STREAM_ASSISTANT && 3254 mContext.checkPermission( 3255 android.Manifest.permission.MODIFY_AUDIO_ROUTING, pid, uid) 3256 != PackageManager.PERMISSION_GRANTED) { 3257 Log.w(TAG, "MODIFY_AUDIO_ROUTING Permission Denial: adjustStreamVolume from pid=" 3258 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 3259 return; 3260 } 3261 3262 // use stream type alias here so that streams with same alias have the same behavior, 3263 // including with regard to silent mode control (e.g the use of STREAM_RING below and in 3264 // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION) 3265 int streamTypeAlias = mStreamVolumeAlias[streamType]; 3266 3267 VolumeStreamState streamState = mStreamStates[streamTypeAlias]; 3268 3269 final int device = getDeviceForStream(streamTypeAlias); 3270 3271 int aliasIndex = streamState.getIndex(device); 3272 boolean adjustVolume = true; 3273 int step; 3274 3275 // skip a2dp absolute volume control request when the device 3276 // is neither an a2dp device nor BLE device 3277 if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 3278 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device)) 3279 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { 3280 return; 3281 } 3282 3283 // If we are being called by the system (e.g. hardware keys) check for current user 3284 // so we handle user restrictions correctly. 3285 if (uid == android.os.Process.SYSTEM_UID) { 3286 uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); 3287 } 3288 // validate calling package and app op 3289 if (!checkNoteAppOp( 3290 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) { 3291 return; 3292 } 3293 3294 // reset any pending volume command 3295 synchronized (mSafeMediaVolumeStateLock) { 3296 mPendingVolumeCommand = null; 3297 } 3298 3299 flags &= ~AudioManager.FLAG_FIXED_VOLUME; 3300 if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) { 3301 flags |= AudioManager.FLAG_FIXED_VOLUME; 3302 3303 // Always toggle between max safe volume and 0 for fixed volume devices where safe 3304 // volume is enforced, and max and 0 for the others. 3305 // This is simulated by stepping by the full allowed volume range 3306 if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE && 3307 mSafeMediaVolumeDevices.contains(device)) { 3308 step = safeMediaVolumeIndex(device); 3309 } else { 3310 step = streamState.getMaxIndex(); 3311 } 3312 if (aliasIndex != 0) { 3313 aliasIndex = step; 3314 } 3315 } else { 3316 // convert one UI step (+/-1) into a number of internal units on the stream alias 3317 step = rescaleStep(10, streamType, streamTypeAlias); 3318 } 3319 3320 // If either the client forces allowing ringer modes for this adjustment, 3321 // or the stream type is one that is affected by ringer modes 3322 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 3323 (isUiSoundsStreamType(streamTypeAlias))) { 3324 int ringerMode = getRingerModeInternal(); 3325 // do not vibrate if already in vibrate mode 3326 if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { 3327 flags &= ~AudioManager.FLAG_VIBRATE; 3328 } 3329 // Check if the ringer mode handles this adjustment. If it does we don't 3330 // need to adjust the volume further. 3331 final int result = checkForRingerModeChange(aliasIndex, direction, step, 3332 streamState.mIsMuted, callingPackage, flags); 3333 adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0; 3334 // If suppressing a volume adjustment in silent mode, display the UI hint 3335 if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) { 3336 flags |= AudioManager.FLAG_SHOW_SILENT_HINT; 3337 } 3338 // If suppressing a volume down adjustment in vibrate mode, display the UI hint 3339 if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) { 3340 flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT; 3341 } 3342 } 3343 3344 // If the ringer mode or zen is muting the stream, do not change stream unless 3345 // it'll cause us to exit dnd 3346 if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) { 3347 adjustVolume = false; 3348 } 3349 int oldIndex = mStreamStates[streamType].getIndex(device); 3350 3351 // Check if the volume adjustment should be handled by an absolute volume controller instead 3352 if (isAbsoluteVolumeDevice(device) 3353 && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) { 3354 AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device); 3355 if (info.mHandlesVolumeAdjustment) { 3356 dispatchAbsoluteVolumeAdjusted(streamType, info, oldIndex, direction, 3357 keyEventMode); 3358 return; 3359 } 3360 } 3361 3362 if (adjustVolume && (direction != AudioManager.ADJUST_SAME) 3363 && (keyEventMode != AudioDeviceVolumeManager.ADJUST_MODE_END)) { 3364 mAudioHandler.removeMessages(MSG_UNMUTE_STREAM); 3365 3366 if (isMuteAdjust && !mFullVolumeDevices.contains(device)) { 3367 boolean state; 3368 if (direction == AudioManager.ADJUST_TOGGLE_MUTE) { 3369 state = !streamState.mIsMuted; 3370 } else { 3371 state = direction == AudioManager.ADJUST_MUTE; 3372 } 3373 muteAliasStreams(streamTypeAlias, state); 3374 } else if ((direction == AudioManager.ADJUST_RAISE) && 3375 !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) { 3376 Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex); 3377 mVolumeController.postDisplaySafeVolumeWarning(flags); 3378 } else if (!isFullVolumeDevice(device) 3379 && (streamState.adjustIndex(direction * step, device, caller, 3380 hasModifyAudioSettings) 3381 || streamState.mIsMuted)) { 3382 // Post message to set system volume (it in turn will post a 3383 // message to persist). 3384 if (streamState.mIsMuted) { 3385 // Unmute the stream if it was previously muted 3386 if (direction == AudioManager.ADJUST_RAISE) { 3387 // unmute immediately for volume up 3388 muteAliasStreams(streamTypeAlias, false); 3389 } else if (direction == AudioManager.ADJUST_LOWER) { 3390 if (mIsSingleVolume) { 3391 sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE, 3392 streamTypeAlias, flags, null, UNMUTE_STREAM_DELAY); 3393 } 3394 } 3395 } 3396 sendMsg(mAudioHandler, 3397 MSG_SET_DEVICE_VOLUME, 3398 SENDMSG_QUEUE, 3399 device, 3400 0, 3401 streamState, 3402 0); 3403 } 3404 3405 int newIndex = mStreamStates[streamType].getIndex(device); 3406 3407 // Check if volume update should be send to AVRCP 3408 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 3409 && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 3410 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 3411 if (DEBUG_VOL) { 3412 Log.d(TAG, "adjustSreamVolume: postSetAvrcpAbsoluteVolumeIndex index=" 3413 + newIndex + "stream=" + streamType); 3414 } 3415 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10); 3416 } else if (isAbsoluteVolumeDevice(device) 3417 && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) { 3418 AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device); 3419 dispatchAbsoluteVolumeChanged(streamType, info, newIndex); 3420 } 3421 3422 if (AudioSystem.isLeAudioDeviceType(device) 3423 && streamType == getBluetoothContextualVolumeStream() 3424 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 3425 if (DEBUG_VOL) { 3426 Log.d(TAG, "adjustSreamVolume postSetLeAudioVolumeIndex index=" 3427 + newIndex + " stream=" + streamType); 3428 } 3429 mDeviceBroker.postSetLeAudioVolumeIndex(newIndex, 3430 mStreamStates[streamType].getMaxIndex(), streamType); 3431 } 3432 3433 // Check if volume update should be send to Hearing Aid 3434 if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 3435 // only modify the hearing aid attenuation when the stream to modify matches 3436 // the one expected by the hearing aid 3437 if (streamType == getBluetoothContextualVolumeStream()) { 3438 if (DEBUG_VOL) { 3439 Log.d(TAG, "adjustSreamVolume postSetHearingAidVolumeIndex index=" 3440 + newIndex + " stream=" + streamType); 3441 } 3442 mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType); 3443 } 3444 } 3445 } 3446 3447 final int newIndex = mStreamStates[streamType].getIndex(device); 3448 3449 if (adjustVolume) { 3450 synchronized (mHdmiClientLock) { 3451 if (mHdmiManager != null) { 3452 // At most one of mHdmiPlaybackClient and mHdmiTvClient should be non-null 3453 HdmiClient fullVolumeHdmiClient = mHdmiPlaybackClient; 3454 if (mHdmiTvClient != null) { 3455 fullVolumeHdmiClient = mHdmiTvClient; 3456 } 3457 3458 if (fullVolumeHdmiClient != null 3459 && mHdmiCecVolumeControlEnabled 3460 && streamTypeAlias == AudioSystem.STREAM_MUSIC 3461 // vol change on a full volume device 3462 && isFullVolumeDevice(device)) { 3463 int keyCode = KeyEvent.KEYCODE_UNKNOWN; 3464 switch (direction) { 3465 case AudioManager.ADJUST_RAISE: 3466 keyCode = KeyEvent.KEYCODE_VOLUME_UP; 3467 break; 3468 case AudioManager.ADJUST_LOWER: 3469 keyCode = KeyEvent.KEYCODE_VOLUME_DOWN; 3470 break; 3471 case AudioManager.ADJUST_TOGGLE_MUTE: 3472 case AudioManager.ADJUST_MUTE: 3473 case AudioManager.ADJUST_UNMUTE: 3474 // Many CEC devices only support toggle mute. Therefore, we send the 3475 // same keycode for all three mute options. 3476 keyCode = KeyEvent.KEYCODE_VOLUME_MUTE; 3477 break; 3478 default: 3479 break; 3480 } 3481 if (keyCode != KeyEvent.KEYCODE_UNKNOWN) { 3482 final long ident = Binder.clearCallingIdentity(); 3483 try { 3484 switch (keyEventMode) { 3485 case AudioDeviceVolumeManager.ADJUST_MODE_NORMAL: 3486 fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, true); 3487 fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, false); 3488 break; 3489 case AudioDeviceVolumeManager.ADJUST_MODE_START: 3490 fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, true); 3491 break; 3492 case AudioDeviceVolumeManager.ADJUST_MODE_END: 3493 fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, false); 3494 break; 3495 default: 3496 Log.e(TAG, "Invalid keyEventMode " + keyEventMode); 3497 } 3498 } finally { 3499 Binder.restoreCallingIdentity(ident); 3500 } 3501 } 3502 } 3503 3504 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 3505 && (oldIndex != newIndex || isMuteAdjust)) { 3506 maybeSendSystemAudioStatusCommand(isMuteAdjust); 3507 } 3508 } 3509 } 3510 } 3511 sendVolumeUpdate(streamType, oldIndex, newIndex, flags, device); 3512 } 3513 3514 /** 3515 * Loops on aliasted stream, update the mute cache attribute of each 3516 * {@see AudioService#VolumeStreamState}, and then apply the change. 3517 * It prevents to unnecessary {@see AudioSystem#setStreamVolume} done for each stream 3518 * and aliases before mute change changed and after. 3519 */ muteAliasStreams(int streamAlias, boolean state)3520 private void muteAliasStreams(int streamAlias, boolean state) { 3521 synchronized (VolumeStreamState.class) { 3522 List<Integer> streamsToMute = new ArrayList<>(); 3523 for (int stream = 0; stream < mStreamStates.length; stream++) { 3524 VolumeStreamState vss = mStreamStates[stream]; 3525 if (streamAlias == mStreamVolumeAlias[stream] && vss.isMutable()) { 3526 if (!(readCameraSoundForced() 3527 && (vss.getStreamType() 3528 == AudioSystem.STREAM_SYSTEM_ENFORCED))) { 3529 boolean changed = vss.mute(state, /* apply= */ false); 3530 if (changed) { 3531 streamsToMute.add(stream); 3532 } 3533 } 3534 } 3535 } 3536 streamsToMute.forEach(streamToMute -> { 3537 mStreamStates[streamToMute].doMute(); 3538 broadcastMuteSetting(streamToMute, state); 3539 }); 3540 } 3541 } 3542 broadcastMuteSetting(int streamType, boolean isMuted)3543 private void broadcastMuteSetting(int streamType, boolean isMuted) { 3544 // Stream mute changed, fire the intent. 3545 Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION); 3546 intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType); 3547 intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, isMuted); 3548 sendBroadcastToAll(intent); 3549 } 3550 3551 // Called after a delay when volume down is pressed while muted onUnmuteStream(int stream, int flags)3552 private void onUnmuteStream(int stream, int flags) { 3553 boolean wasMuted; 3554 synchronized (VolumeStreamState.class) { 3555 final VolumeStreamState streamState = mStreamStates[stream]; 3556 wasMuted = streamState.mute(false); // if unmuting causes a change, it was muted 3557 3558 final int device = getDeviceForStream(stream); 3559 final int index = streamState.getIndex(device); 3560 sendVolumeUpdate(stream, index, index, flags, device); 3561 } 3562 if (stream == AudioSystem.STREAM_MUSIC && wasMuted) { 3563 synchronized (mHdmiClientLock) { 3564 maybeSendSystemAudioStatusCommand(true); 3565 } 3566 } 3567 } 3568 3569 @GuardedBy("mHdmiClientLock") maybeSendSystemAudioStatusCommand(boolean isMuteAdjust)3570 private void maybeSendSystemAudioStatusCommand(boolean isMuteAdjust) { 3571 if (mHdmiAudioSystemClient == null 3572 || !mHdmiSystemAudioSupported 3573 || !mHdmiCecVolumeControlEnabled) { 3574 return; 3575 } 3576 3577 final long identity = Binder.clearCallingIdentity(); 3578 mHdmiAudioSystemClient.sendReportAudioStatusCecCommand( 3579 isMuteAdjust, getStreamVolume(AudioSystem.STREAM_MUSIC), 3580 getStreamMaxVolume(AudioSystem.STREAM_MUSIC), 3581 isStreamMute(AudioSystem.STREAM_MUSIC)); 3582 Binder.restoreCallingIdentity(identity); 3583 } 3584 3585 // StreamVolumeCommand contains the information needed to defer the process of 3586 // setStreamVolume() in case the user has to acknowledge the safe volume warning message. 3587 static class StreamVolumeCommand { 3588 public final int mStreamType; 3589 public final int mIndex; 3590 public final int mFlags; 3591 public final int mDevice; 3592 StreamVolumeCommand(int streamType, int index, int flags, int device)3593 StreamVolumeCommand(int streamType, int index, int flags, int device) { 3594 mStreamType = streamType; 3595 mIndex = index; 3596 mFlags = flags; 3597 mDevice = device; 3598 } 3599 3600 @Override toString()3601 public String toString() { 3602 return new StringBuilder().append("{streamType=").append(mStreamType).append(",index=") 3603 .append(mIndex).append(",flags=").append(mFlags).append(",device=") 3604 .append(mDevice).append('}').toString(); 3605 } 3606 } 3607 getNewRingerMode(int stream, int index, int flags)3608 private int getNewRingerMode(int stream, int index, int flags) { 3609 // setRingerMode does nothing if the device is single volume,so the value would be unchanged 3610 if (mIsSingleVolume) { 3611 return getRingerModeExternal(); 3612 } 3613 3614 // setting volume on ui sounds stream type also controls silent mode 3615 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 3616 (stream == getUiSoundsStreamType())) { 3617 int newRingerMode; 3618 if (index == 0) { 3619 newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE 3620 : mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT 3621 : AudioManager.RINGER_MODE_NORMAL; 3622 } else { 3623 newRingerMode = AudioManager.RINGER_MODE_NORMAL; 3624 } 3625 return newRingerMode; 3626 } 3627 return getRingerModeExternal(); 3628 } 3629 isAndroidNPlus(String caller)3630 private boolean isAndroidNPlus(String caller) { 3631 try { 3632 final ApplicationInfo applicationInfo = 3633 mContext.getPackageManager().getApplicationInfoAsUser( 3634 caller, 0, UserHandle.getUserId(Binder.getCallingUid())); 3635 if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) { 3636 return true; 3637 } 3638 return false; 3639 } catch (PackageManager.NameNotFoundException e) { 3640 return true; 3641 } 3642 } 3643 wouldToggleZenMode(int newMode)3644 private boolean wouldToggleZenMode(int newMode) { 3645 if (getRingerModeExternal() == AudioManager.RINGER_MODE_SILENT 3646 && newMode != AudioManager.RINGER_MODE_SILENT) { 3647 return true; 3648 } else if (getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT 3649 && newMode == AudioManager.RINGER_MODE_SILENT) { 3650 return true; 3651 } 3652 return false; 3653 } 3654 3655 /** 3656 * Update stream volume, ringer mode and mute status after a volume index change 3657 * @param streamType 3658 * @param index 3659 * @param flags 3660 * @param device the device for which the volume is changed 3661 * @param caller 3662 * @param hasModifyAudioSettings 3663 * @param canChangeMute true if the origin of this event is one where the mute state should be 3664 * updated following the change in volume index 3665 */ onSetStreamVolume(int streamType, int index, int flags, int device, String caller, boolean hasModifyAudioSettings, boolean canChangeMute)3666 private void onSetStreamVolume(int streamType, int index, int flags, int device, 3667 String caller, boolean hasModifyAudioSettings, boolean canChangeMute) { 3668 final int stream = mStreamVolumeAlias[streamType]; 3669 setStreamVolumeInt(stream, index, device, false, caller, hasModifyAudioSettings); 3670 // setting volume on ui sounds stream type also controls silent mode 3671 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 3672 (stream == getUiSoundsStreamType())) { 3673 setRingerMode(getNewRingerMode(stream, index, flags), 3674 TAG + ".onSetStreamVolume", false /*external*/); 3675 } 3676 // setting non-zero volume for a muted stream unmutes the stream and vice versa 3677 // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements 3678 if ((streamType != AudioSystem.STREAM_BLUETOOTH_SCO) && canChangeMute) { 3679 // As adjustStreamVolume with muteAdjust flags mute/unmutes stream and aliased streams. 3680 muteAliasStreams(stream, index == 0); 3681 } 3682 } 3683 enforceModifyAudioRoutingPermission()3684 private void enforceModifyAudioRoutingPermission() { 3685 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 3686 != PackageManager.PERMISSION_GRANTED) { 3687 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission"); 3688 } 3689 } 3690 3691 // TODO enforce MODIFY_AUDIO_SYSTEM_SETTINGS when defined enforceModifyAudioRoutingOrSystemSettingsPermission()3692 private void enforceModifyAudioRoutingOrSystemSettingsPermission() { 3693 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 3694 != PackageManager.PERMISSION_GRANTED 3695 /*&& mContext.checkCallingOrSelfPermission( 3696 android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS) 3697 != PackageManager.PERMISSION_DENIED*/) { 3698 throw new SecurityException( 3699 "Missing MODIFY_AUDIO_ROUTING or MODIFY_AUDIO_SYSTEM_SETTINGS permission"); 3700 } 3701 } 3702 enforceAccessUltrasoundPermission()3703 private void enforceAccessUltrasoundPermission() { 3704 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.ACCESS_ULTRASOUND) 3705 != PackageManager.PERMISSION_GRANTED) { 3706 throw new SecurityException("Missing ACCESS_ULTRASOUND permission"); 3707 } 3708 } 3709 enforceQueryStatePermission()3710 private void enforceQueryStatePermission() { 3711 if (mContext.checkCallingOrSelfPermission(Manifest.permission.QUERY_AUDIO_STATE) 3712 != PackageManager.PERMISSION_GRANTED) { 3713 throw new SecurityException("Missing QUERY_AUDIO_STATE permissions"); 3714 } 3715 } 3716 enforceQueryStateOrModifyRoutingPermission()3717 private void enforceQueryStateOrModifyRoutingPermission() { 3718 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 3719 != PackageManager.PERMISSION_GRANTED 3720 && mContext.checkCallingOrSelfPermission(Manifest.permission.QUERY_AUDIO_STATE) 3721 != PackageManager.PERMISSION_GRANTED) { 3722 throw new SecurityException( 3723 "Missing MODIFY_AUDIO_ROUTING or QUERY_AUDIO_STATE permissions"); 3724 } 3725 } 3726 enforceCallAudioInterceptionPermission()3727 private void enforceCallAudioInterceptionPermission() { 3728 if (mContext.checkCallingOrSelfPermission( 3729 android.Manifest.permission.CALL_AUDIO_INTERCEPTION) 3730 != PackageManager.PERMISSION_GRANTED) { 3731 throw new SecurityException("Missing CALL_AUDIO_INTERCEPTION permission"); 3732 } 3733 } 3734 3735 3736 /** @see AudioManager#setVolumeGroupVolumeIndex(int, int, int) */ setVolumeGroupVolumeIndex(int groupId, int index, int flags, String callingPackage, String attributionTag)3737 public void setVolumeGroupVolumeIndex(int groupId, int index, int flags, 3738 String callingPackage, String attributionTag) { 3739 enforceModifyAudioRoutingPermission(); 3740 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 3741 Log.e(TAG, ": no volume group found for id " + groupId); 3742 return; 3743 } 3744 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 3745 3746 sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, vgs.name(), 3747 index, flags, callingPackage + ", user " + getCurrentUserId())); 3748 3749 vgs.setVolumeIndex(index, flags); 3750 3751 // For legacy reason, propagate to all streams associated to this volume group 3752 for (int groupedStream : vgs.getLegacyStreamTypes()) { 3753 try { 3754 ensureValidStreamType(groupedStream); 3755 } catch (IllegalArgumentException e) { 3756 Log.d(TAG, "volume group " + groupId + " has internal streams (" + groupedStream 3757 + "), do not change associated stream volume"); 3758 continue; 3759 } 3760 setStreamVolume(groupedStream, index, flags, /*device*/ null, 3761 callingPackage, callingPackage, 3762 attributionTag, Binder.getCallingUid(), true /*hasModifyAudioSettings*/); 3763 } 3764 } 3765 3766 @Nullable getAudioVolumeGroupById(int volumeGroupId)3767 private AudioVolumeGroup getAudioVolumeGroupById(int volumeGroupId) { 3768 for (AudioVolumeGroup avg : AudioVolumeGroup.getAudioVolumeGroups()) { 3769 if (avg.getId() == volumeGroupId) { 3770 return avg; 3771 } 3772 } 3773 3774 Log.e(TAG, ": invalid volume group id: " + volumeGroupId + " requested"); 3775 return null; 3776 } 3777 3778 /** @see AudioManager#getVolumeGroupVolumeIndex(int) */ getVolumeGroupVolumeIndex(int groupId)3779 public int getVolumeGroupVolumeIndex(int groupId) { 3780 enforceModifyAudioRoutingPermission(); 3781 synchronized (VolumeStreamState.class) { 3782 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 3783 throw new IllegalArgumentException("No volume group for id " + groupId); 3784 } 3785 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 3786 // Return 0 when muted, not min index since for e.g. Voice Call, it has a non zero 3787 // min but it mutable on permission condition. 3788 return vgs.isMuted() ? 0 : vgs.getVolumeIndex(); 3789 } 3790 } 3791 3792 /** @see AudioManager#getVolumeGroupMaxVolumeIndex(int) */ getVolumeGroupMaxVolumeIndex(int groupId)3793 public int getVolumeGroupMaxVolumeIndex(int groupId) { 3794 enforceModifyAudioRoutingPermission(); 3795 synchronized (VolumeStreamState.class) { 3796 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 3797 throw new IllegalArgumentException("No volume group for id " + groupId); 3798 } 3799 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 3800 return vgs.getMaxIndex(); 3801 } 3802 } 3803 3804 /** @see AudioManager#getVolumeGroupMinVolumeIndex(int) */ getVolumeGroupMinVolumeIndex(int groupId)3805 public int getVolumeGroupMinVolumeIndex(int groupId) { 3806 enforceModifyAudioRoutingPermission(); 3807 synchronized (VolumeStreamState.class) { 3808 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 3809 throw new IllegalArgumentException("No volume group for id " + groupId); 3810 } 3811 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 3812 return vgs.getMinIndex(); 3813 } 3814 } 3815 3816 /** @see AudioDeviceVolumeManager#setDeviceVolume(VolumeInfo, AudioDeviceAttributes) 3817 * Part of service interface, check permissions and parameters here 3818 * Note calling package is for logging purposes only, not to be trusted 3819 */ setDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)3820 public void setDeviceVolume(@NonNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, 3821 @NonNull String callingPackage) { 3822 enforceModifyAudioRoutingOrSystemSettingsPermission(); 3823 Objects.requireNonNull(vi); 3824 Objects.requireNonNull(ada); 3825 Objects.requireNonNull(callingPackage); 3826 3827 if (!vi.hasStreamType()) { 3828 Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception()); 3829 return; 3830 } 3831 3832 int index = vi.getVolumeIndex(); 3833 if (index == VolumeInfo.INDEX_NOT_SET && !vi.hasMuteCommand()) { 3834 throw new IllegalArgumentException( 3835 "changing device volume requires a volume index or mute command"); 3836 } 3837 3838 // force a cache clear to force reevaluating stream type to audio device selection 3839 // that can interfere with the sending of the VOLUME_CHANGED_ACTION intent 3840 // TODO change cache management to not rely only on invalidation, but on "do not trust" 3841 // moments when routing is in flux. 3842 mAudioSystem.clearRoutingCache(); 3843 3844 // log the current device that will be used when evaluating the sending of the 3845 // VOLUME_CHANGED_ACTION intent to see if the current device is the one being modified 3846 final int currDev = getDeviceForStream(vi.getStreamType()); 3847 3848 final boolean skipping = (currDev == ada.getInternalType()); 3849 3850 AudioService.sVolumeLogger.log(new DeviceVolumeEvent(vi.getStreamType(), index, ada, 3851 currDev, callingPackage, skipping)); 3852 3853 if (skipping) { 3854 // setDeviceVolume was called on a device currently being used 3855 return; 3856 } 3857 3858 // TODO handle unmuting of current audio device 3859 // if a stream is not muted but the VolumeInfo is for muting, set the volume index 3860 // for the device to min volume 3861 if (vi.hasMuteCommand() && vi.isMuted() && !isStreamMute(vi.getStreamType())) { 3862 setStreamVolumeWithAttributionInt(vi.getStreamType(), 3863 mStreamStates[vi.getStreamType()].getMinIndex(), 3864 /*flags*/ 0, 3865 ada, callingPackage, null); 3866 return; 3867 } 3868 3869 if (vi.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET 3870 || vi.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) { 3871 // assume index meant to be in stream type range, validate 3872 if ((index * 10) < mStreamStates[vi.getStreamType()].getMinIndex() 3873 || (index * 10) > mStreamStates[vi.getStreamType()].getMaxIndex()) { 3874 throw new IllegalArgumentException("invalid volume index " + index 3875 + " not between min/max for stream " + vi.getStreamType()); 3876 } 3877 } else { 3878 // check if index needs to be rescaled 3879 final int min = (mStreamStates[vi.getStreamType()].getMinIndex() + 5) / 10; 3880 final int max = (mStreamStates[vi.getStreamType()].getMaxIndex() + 5) / 10; 3881 if (vi.getMinVolumeIndex() != min || vi.getMaxVolumeIndex() != max) { 3882 index = rescaleIndex(index, 3883 /*srcMin*/ vi.getMinVolumeIndex(), /*srcMax*/ vi.getMaxVolumeIndex(), 3884 /*dstMin*/ min, /*dstMax*/ max); 3885 } 3886 } 3887 setStreamVolumeWithAttributionInt(vi.getStreamType(), index, /*flags*/ 0, 3888 ada, callingPackage, null); 3889 } 3890 3891 /** Retain API for unsupported app usage */ setStreamVolume(int streamType, int index, int flags, String callingPackage)3892 public void setStreamVolume(int streamType, int index, int flags, String callingPackage) { 3893 setStreamVolumeWithAttribution(streamType, index, flags, 3894 callingPackage, /*attributionTag*/ null); 3895 } 3896 3897 /** @see AudioManager#adjustVolumeGroupVolume(int, int, int) */ adjustVolumeGroupVolume(int groupId, int direction, int flags, String callingPackage)3898 public void adjustVolumeGroupVolume(int groupId, int direction, int flags, 3899 String callingPackage) { 3900 ensureValidDirection(direction); 3901 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 3902 Log.e(TAG, ": no volume group found for id " + groupId); 3903 return; 3904 } 3905 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 3906 // For compatibility reason, use stream API if group linked to a valid stream 3907 boolean fallbackOnStream = false; 3908 for (int stream : vgs.getLegacyStreamTypes()) { 3909 try { 3910 ensureValidStreamType(stream); 3911 } catch (IllegalArgumentException e) { 3912 Log.d(TAG, "volume group " + groupId + " has internal streams (" + stream 3913 + "), do not change associated stream volume"); 3914 continue; 3915 } 3916 // Note: Group and Stream does not share same convention, 0 is mute for stream, 3917 // min index is acting as mute for Groups 3918 if (vgs.isVssMuteBijective(stream)) { 3919 adjustStreamVolume(stream, direction, flags, callingPackage); 3920 if (isMuteAdjust(direction)) { 3921 // will be propagated to all aliased streams 3922 return; 3923 } 3924 fallbackOnStream = true; 3925 } 3926 } 3927 if (fallbackOnStream) { 3928 // Handled by at least one stream, will be propagated to group, bailing out. 3929 return; 3930 } 3931 sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_GROUP_VOL, vgs.name(), 3932 direction, flags, callingPackage)); 3933 vgs.adjustVolume(direction, flags); 3934 } 3935 3936 /** @see AudioManager#getLastAudibleVolumeGroupVolume(int) */ getLastAudibleVolumeGroupVolume(int groupId)3937 public int getLastAudibleVolumeGroupVolume(int groupId) { 3938 enforceQueryStatePermission(); 3939 synchronized (VolumeStreamState.class) { 3940 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 3941 Log.e(TAG, ": no volume group found for id " + groupId); 3942 return 0; 3943 } 3944 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 3945 return vgs.getVolumeIndex(); 3946 } 3947 } 3948 3949 /** @see AudioManager#isVolumeGroupMuted(int) */ isVolumeGroupMuted(int groupId)3950 public boolean isVolumeGroupMuted(int groupId) { 3951 synchronized (VolumeStreamState.class) { 3952 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 3953 Log.e(TAG, ": no volume group found for id " + groupId); 3954 return false; 3955 } 3956 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 3957 return vgs.isMuted(); 3958 } 3959 } 3960 3961 /** @see AudioManager#setStreamVolume(int, int, int) 3962 * Part of service interface, check permissions here */ setStreamVolumeWithAttribution(int streamType, int index, int flags, String callingPackage, String attributionTag)3963 public void setStreamVolumeWithAttribution(int streamType, int index, int flags, 3964 String callingPackage, String attributionTag) { 3965 setStreamVolumeWithAttributionInt(streamType, index, flags, /*device*/ null, 3966 callingPackage, attributionTag); 3967 } 3968 3969 /** 3970 * Internal method for a stream type volume change. Can be used to change the volume on a 3971 * given device only 3972 * @param streamType the stream type whose volume is to be changed 3973 * @param index the volume index 3974 * @param flags options for volume handling 3975 * @param device null when controlling volume for the current routing, otherwise the device 3976 * for which volume is being changed 3977 * @param callingPackage client side-provided package name of caller, not to be trusted 3978 * @param attributionTag client side-provided attribution name, not to be trusted 3979 */ setStreamVolumeWithAttributionInt(int streamType, int index, int flags, @Nullable AudioDeviceAttributes device, String callingPackage, String attributionTag)3980 protected void setStreamVolumeWithAttributionInt(int streamType, int index, int flags, 3981 @Nullable AudioDeviceAttributes device, 3982 String callingPackage, String attributionTag) { 3983 if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { 3984 Log.w(TAG, "Trying to call setStreamVolume() for a11y without" 3985 + " CHANGE_ACCESSIBILITY_VOLUME callingPackage=" + callingPackage); 3986 return; 3987 } 3988 if ((streamType == AudioManager.STREAM_VOICE_CALL) && (index == 0) 3989 && (mContext.checkCallingOrSelfPermission( 3990 android.Manifest.permission.MODIFY_PHONE_STATE) 3991 != PackageManager.PERMISSION_GRANTED)) { 3992 Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL and index 0 without" 3993 + " MODIFY_PHONE_STATE callingPackage=" + callingPackage); 3994 return; 3995 } 3996 if ((streamType == AudioManager.STREAM_ASSISTANT) 3997 && (mContext.checkCallingOrSelfPermission( 3998 android.Manifest.permission.MODIFY_AUDIO_ROUTING) 3999 != PackageManager.PERMISSION_GRANTED)) { 4000 Log.w(TAG, "Trying to call setStreamVolume() for STREAM_ASSISTANT without" 4001 + " MODIFY_AUDIO_ROUTING callingPackage=" + callingPackage); 4002 return; 4003 } 4004 4005 if (device == null) { 4006 // call was already logged in setDeviceVolume() 4007 sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType, 4008 index/*val1*/, flags/*val2*/, callingPackage)); 4009 } 4010 setStreamVolume(streamType, index, flags, device, 4011 callingPackage, callingPackage, attributionTag, 4012 Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission()); 4013 } 4014 4015 /** @see AudioManager#isUltrasoundSupported() */ isUltrasoundSupported()4016 public boolean isUltrasoundSupported() { 4017 enforceAccessUltrasoundPermission(); 4018 return AudioSystem.isUltrasoundSupported(); 4019 } 4020 canChangeAccessibilityVolume()4021 private boolean canChangeAccessibilityVolume() { 4022 synchronized (mAccessibilityServiceUidsLock) { 4023 if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 4024 android.Manifest.permission.CHANGE_ACCESSIBILITY_VOLUME)) { 4025 return true; 4026 } 4027 if (mAccessibilityServiceUids != null) { 4028 int callingUid = Binder.getCallingUid(); 4029 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 4030 if (mAccessibilityServiceUids[i] == callingUid) { 4031 return true; 4032 } 4033 } 4034 } 4035 return false; 4036 } 4037 } 4038 getBluetoothContextualVolumeStream()4039 /*package*/ int getBluetoothContextualVolumeStream() { 4040 return getBluetoothContextualVolumeStream(mMode.get()); 4041 } 4042 getBluetoothContextualVolumeStream(int mode)4043 private int getBluetoothContextualVolumeStream(int mode) { 4044 switch (mode) { 4045 case AudioSystem.MODE_IN_COMMUNICATION: 4046 case AudioSystem.MODE_IN_CALL: 4047 return AudioSystem.STREAM_VOICE_CALL; 4048 case AudioSystem.MODE_NORMAL: 4049 default: 4050 // other conditions will influence the stream type choice, read on... 4051 break; 4052 } 4053 if (mVoicePlaybackActive.get()) { 4054 return AudioSystem.STREAM_VOICE_CALL; 4055 } 4056 return AudioSystem.STREAM_MUSIC; 4057 } 4058 4059 private AtomicBoolean mVoicePlaybackActive = new AtomicBoolean(false); 4060 private AtomicBoolean mMediaPlaybackActive = new AtomicBoolean(false); 4061 4062 private final IPlaybackConfigDispatcher mPlaybackActivityMonitor = 4063 new IPlaybackConfigDispatcher.Stub() { 4064 @Override 4065 public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs, 4066 boolean flush) { 4067 sendMsg(mAudioHandler, MSG_PLAYBACK_CONFIG_CHANGE, SENDMSG_REPLACE, 4068 0 /*arg1 ignored*/, 0 /*arg2 ignored*/, 4069 configs /*obj*/, 0 /*delay*/); 4070 } 4071 }; 4072 onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs)4073 private void onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) { 4074 boolean voiceActive = false; 4075 boolean mediaActive = false; 4076 for (AudioPlaybackConfiguration config : configs) { 4077 final int usage = config.getAudioAttributes().getUsage(); 4078 if (!config.isActive()) { 4079 continue; 4080 } 4081 if (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION 4082 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) { 4083 voiceActive = true; 4084 } 4085 if (usage == AudioAttributes.USAGE_MEDIA || usage == AudioAttributes.USAGE_GAME) { 4086 mediaActive = true; 4087 } 4088 } 4089 if (mVoicePlaybackActive.getAndSet(voiceActive) != voiceActive) { 4090 updateHearingAidVolumeOnVoiceActivityUpdate(); 4091 } 4092 if (mMediaPlaybackActive.getAndSet(mediaActive) != mediaActive && mediaActive) { 4093 scheduleMusicActiveCheck(); 4094 } 4095 // Update playback active state for all apps in audio mode stack. 4096 // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE 4097 // and request an audio mode update immediately. Upon any other change, queue the message 4098 // and request an audio mode update after a grace period. 4099 synchronized (mDeviceBroker.mSetModeLock) { 4100 boolean updateAudioMode = false; 4101 int existingMsgPolicy = SENDMSG_QUEUE; 4102 int delay = CHECK_MODE_FOR_UID_PERIOD_MS; 4103 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 4104 boolean wasActive = h.isActive(); 4105 h.setPlaybackActive(false); 4106 for (AudioPlaybackConfiguration config : configs) { 4107 final int usage = config.getAudioAttributes().getUsage(); 4108 if (config.getClientUid() == h.getUid() 4109 && (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION 4110 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) 4111 && config.getPlayerState() 4112 == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) { 4113 h.setPlaybackActive(true); 4114 break; 4115 } 4116 } 4117 if (wasActive != h.isActive()) { 4118 updateAudioMode = true; 4119 if (h.isActive() && h == getAudioModeOwnerHandler()) { 4120 existingMsgPolicy = SENDMSG_REPLACE; 4121 delay = 0; 4122 } 4123 } 4124 } 4125 if (updateAudioMode) { 4126 sendMsg(mAudioHandler, 4127 MSG_UPDATE_AUDIO_MODE, 4128 existingMsgPolicy, 4129 AudioSystem.MODE_CURRENT, 4130 android.os.Process.myPid(), 4131 mContext.getPackageName(), 4132 delay); 4133 } 4134 } 4135 } 4136 4137 private final IRecordingConfigDispatcher mVoiceRecordingActivityMonitor = 4138 new IRecordingConfigDispatcher.Stub() { 4139 @Override 4140 public void dispatchRecordingConfigChange(List<AudioRecordingConfiguration> configs) { 4141 sendMsg(mAudioHandler, MSG_RECORDING_CONFIG_CHANGE, SENDMSG_REPLACE, 4142 0 /*arg1 ignored*/, 0 /*arg2 ignored*/, 4143 configs /*obj*/, 0 /*delay*/); 4144 } 4145 }; 4146 onRecordingConfigChange(List<AudioRecordingConfiguration> configs)4147 private void onRecordingConfigChange(List<AudioRecordingConfiguration> configs) { 4148 // Update recording active state for all apps in audio mode stack. 4149 // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE 4150 // and request an audio mode update immediately. Upon any other change, queue the message 4151 // and request an audio mode update after a grace period. 4152 synchronized (mDeviceBroker.mSetModeLock) { 4153 boolean updateAudioMode = false; 4154 int existingMsgPolicy = SENDMSG_QUEUE; 4155 int delay = CHECK_MODE_FOR_UID_PERIOD_MS; 4156 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 4157 boolean wasActive = h.isActive(); 4158 h.setRecordingActive(false); 4159 for (AudioRecordingConfiguration config : configs) { 4160 if (config.getClientUid() == h.getUid() 4161 && config.getAudioSource() == AudioSource.VOICE_COMMUNICATION) { 4162 h.setRecordingActive(true); 4163 break; 4164 } 4165 } 4166 if (wasActive != h.isActive()) { 4167 updateAudioMode = true; 4168 if (h.isActive() && h == getAudioModeOwnerHandler()) { 4169 existingMsgPolicy = SENDMSG_REPLACE; 4170 delay = 0; 4171 } 4172 } 4173 } 4174 if (updateAudioMode) { 4175 sendMsg(mAudioHandler, 4176 MSG_UPDATE_AUDIO_MODE, 4177 existingMsgPolicy, 4178 AudioSystem.MODE_CURRENT, 4179 android.os.Process.myPid(), 4180 mContext.getPackageName(), 4181 delay); 4182 } 4183 } 4184 } 4185 dumpAudioMode(PrintWriter pw)4186 private void dumpAudioMode(PrintWriter pw) { 4187 pw.println("\nAudio mode: "); 4188 pw.println("- Requested mode = " + AudioSystem.modeToString(getMode())); 4189 pw.println("- Actual mode = " + AudioSystem.modeToString(mMode.get())); 4190 pw.println("- Mode owner: "); 4191 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 4192 if (hdlr != null) { 4193 hdlr.dump(pw, -1); 4194 } else { 4195 pw.println(" None"); 4196 } 4197 pw.println("- Mode owner stack: "); 4198 if (mSetModeDeathHandlers.isEmpty()) { 4199 pw.println(" Empty"); 4200 } else { 4201 for (int i = 0; i < mSetModeDeathHandlers.size(); i++) { 4202 mSetModeDeathHandlers.get(i).dump(pw, i); 4203 } 4204 } 4205 } 4206 updateHearingAidVolumeOnVoiceActivityUpdate()4207 private void updateHearingAidVolumeOnVoiceActivityUpdate() { 4208 final int streamType = getBluetoothContextualVolumeStream(); 4209 final int index = getStreamVolume(streamType); 4210 sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_HEARING_AID, 4211 mVoicePlaybackActive.get(), streamType, index)); 4212 mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType); 4213 4214 } 4215 4216 /** 4217 * Manage an audio mode change for audio devices that use an "absolute volume" model, 4218 * i.e. the framework sends the full scale signal, and the actual volume for the use case 4219 * is communicated separately. 4220 */ updateAbsVolumeMultiModeDevices(int oldMode, int newMode)4221 void updateAbsVolumeMultiModeDevices(int oldMode, int newMode) { 4222 if (oldMode == newMode) { 4223 return; 4224 } 4225 switch (newMode) { 4226 case AudioSystem.MODE_IN_COMMUNICATION: 4227 case AudioSystem.MODE_IN_CALL: 4228 case AudioSystem.MODE_NORMAL: 4229 case AudioSystem.MODE_CALL_SCREENING: 4230 case AudioSystem.MODE_CALL_REDIRECT: 4231 case AudioSystem.MODE_COMMUNICATION_REDIRECT: 4232 break; 4233 default: 4234 // no-op is enough for all other values 4235 return; 4236 } 4237 4238 int streamType = getBluetoothContextualVolumeStream(newMode); 4239 4240 final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType); 4241 final Set<Integer> absVolumeMultiModeCaseDevices = AudioSystem.intersectionAudioDeviceTypes( 4242 mAbsVolumeMultiModeCaseDevices, deviceTypes); 4243 if (absVolumeMultiModeCaseDevices.isEmpty()) { 4244 return; 4245 } 4246 4247 // handling of specific interfaces goes here: 4248 if (AudioSystem.isSingleAudioDeviceType( 4249 absVolumeMultiModeCaseDevices, AudioSystem.DEVICE_OUT_HEARING_AID)) { 4250 final int index = getStreamVolume(streamType); 4251 sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID, 4252 newMode, streamType, index)); 4253 mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType); 4254 } 4255 } 4256 setLeAudioVolumeOnModeUpdate(int mode, int device)4257 private void setLeAudioVolumeOnModeUpdate(int mode, int device) { 4258 switch (mode) { 4259 case AudioSystem.MODE_IN_COMMUNICATION: 4260 case AudioSystem.MODE_IN_CALL: 4261 case AudioSystem.MODE_NORMAL: 4262 case AudioSystem.MODE_CALL_SCREENING: 4263 case AudioSystem.MODE_CALL_REDIRECT: 4264 case AudioSystem.MODE_COMMUNICATION_REDIRECT: 4265 break; 4266 default: 4267 // no-op is enough for all other values 4268 return; 4269 } 4270 4271 // Forcefully set LE audio volume as a workaround, since in some cases 4272 // (like the outgoing call) the value of 'device' is not DEVICE_OUT_BLE_* 4273 // even when BLE is connected. 4274 if (!AudioSystem.isLeAudioDeviceType(device)) { 4275 device = AudioSystem.DEVICE_OUT_BLE_HEADSET; 4276 } 4277 4278 final int streamType = getBluetoothContextualVolumeStream(mode); 4279 final int index = mStreamStates[streamType].getIndex(device); 4280 final int maxIndex = mStreamStates[streamType].getMaxIndex(); 4281 4282 if (DEBUG_VOL) { 4283 Log.d(TAG, "setLeAudioVolumeOnModeUpdate postSetLeAudioVolumeIndex index=" 4284 + index + " maxIndex=" + maxIndex + " streamType=" + streamType); 4285 } 4286 mDeviceBroker.postSetLeAudioVolumeIndex(index, maxIndex, streamType); 4287 mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "setLeAudioVolumeOnModeUpdate"); 4288 } 4289 setStreamVolume(int streamType, int index, int flags, @Nullable AudioDeviceAttributes ada, String callingPackage, String caller, String attributionTag, int uid, boolean hasModifyAudioSettings)4290 private void setStreamVolume(int streamType, int index, int flags, 4291 @Nullable AudioDeviceAttributes ada, 4292 String callingPackage, String caller, String attributionTag, int uid, 4293 boolean hasModifyAudioSettings) { 4294 if (DEBUG_VOL) { 4295 Log.d(TAG, "setStreamVolume(stream=" + streamType+", index=" + index 4296 + ", dev=" + ada 4297 + ", calling=" + callingPackage + ")"); 4298 } 4299 if (mUseFixedVolume) { 4300 return; 4301 } 4302 4303 ensureValidStreamType(streamType); 4304 int streamTypeAlias = mStreamVolumeAlias[streamType]; 4305 VolumeStreamState streamState = mStreamStates[streamTypeAlias]; 4306 4307 final int device = (ada == null) 4308 ? getDeviceForStream(streamType) 4309 : ada.getInternalType(); 4310 int oldIndex; 4311 4312 // skip a2dp absolute volume control request when the device 4313 // is neither an a2dp device nor BLE device 4314 if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 4315 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device)) 4316 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { 4317 return; 4318 } 4319 // If we are being called by the system (e.g. hardware keys) check for current user 4320 // so we handle user restrictions correctly. 4321 if (uid == android.os.Process.SYSTEM_UID) { 4322 uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); 4323 } 4324 if (!checkNoteAppOp( 4325 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) { 4326 return; 4327 } 4328 4329 if (isAndroidNPlus(callingPackage) 4330 && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags)) 4331 && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) { 4332 throw new SecurityException("Not allowed to change Do Not Disturb state"); 4333 } 4334 4335 if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) { 4336 return; 4337 } 4338 4339 synchronized (mSafeMediaVolumeStateLock) { 4340 // reset any pending volume command 4341 mPendingVolumeCommand = null; 4342 4343 oldIndex = streamState.getIndex(device); 4344 4345 index = rescaleIndex(index * 10, streamType, streamTypeAlias); 4346 4347 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 4348 && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 4349 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 4350 if (DEBUG_VOL) { 4351 Log.d(TAG, "setStreamVolume postSetAvrcpAbsoluteVolumeIndex index=" + index 4352 + "stream=" + streamType); 4353 } 4354 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10); 4355 } else if (isAbsoluteVolumeDevice(device) 4356 && ((flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0)) { 4357 AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device); 4358 4359 dispatchAbsoluteVolumeChanged(streamType, info, index); 4360 } 4361 4362 if (AudioSystem.isLeAudioDeviceType(device) 4363 && streamType == getBluetoothContextualVolumeStream() 4364 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 4365 if (DEBUG_VOL) { 4366 Log.d(TAG, "adjustSreamVolume postSetLeAudioVolumeIndex index=" 4367 + index + " stream=" + streamType); 4368 } 4369 mDeviceBroker.postSetLeAudioVolumeIndex(index, 4370 mStreamStates[streamType].getMaxIndex(), streamType); 4371 } 4372 4373 if (device == AudioSystem.DEVICE_OUT_HEARING_AID 4374 && streamType == getBluetoothContextualVolumeStream()) { 4375 Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index 4376 + " stream=" + streamType); 4377 mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType); 4378 } 4379 4380 flags &= ~AudioManager.FLAG_FIXED_VOLUME; 4381 if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) { 4382 flags |= AudioManager.FLAG_FIXED_VOLUME; 4383 4384 // volume is either 0 or max allowed for fixed volume devices 4385 if (index != 0) { 4386 if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE && 4387 mSafeMediaVolumeDevices.contains(device)) { 4388 index = safeMediaVolumeIndex(device); 4389 } else { 4390 index = streamState.getMaxIndex(); 4391 } 4392 } 4393 } 4394 4395 if (!checkSafeMediaVolume(streamTypeAlias, index, device)) { 4396 mVolumeController.postDisplaySafeVolumeWarning(flags); 4397 mPendingVolumeCommand = new StreamVolumeCommand( 4398 streamType, index, flags, device); 4399 } else { 4400 onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings, 4401 // ada is non-null when called from setDeviceVolume, 4402 // which shouldn't update the mute state 4403 ada == null /*canChangeMute*/); 4404 index = mStreamStates[streamType].getIndex(device); 4405 } 4406 } 4407 synchronized (mHdmiClientLock) { 4408 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 4409 && (oldIndex != index)) { 4410 maybeSendSystemAudioStatusCommand(false); 4411 } 4412 } 4413 if (ada == null) { 4414 // only non-null when coming here from setDeviceVolume 4415 // TODO change test to check early if device is current device or not 4416 sendVolumeUpdate(streamType, oldIndex, index, flags, device); 4417 } 4418 } 4419 dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index)4420 private void dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, 4421 int index) { 4422 VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType); 4423 if (volumeInfo != null) { 4424 try { 4425 deviceInfo.mCallback.dispatchDeviceVolumeChanged(deviceInfo.mDevice, 4426 new VolumeInfo.Builder(volumeInfo) 4427 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo)) 4428 .build()); 4429 } catch (RemoteException e) { 4430 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume change"); 4431 } 4432 } 4433 } 4434 dispatchAbsoluteVolumeAdjusted(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode)4435 private void dispatchAbsoluteVolumeAdjusted(int streamType, 4436 AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode) { 4437 VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType); 4438 if (volumeInfo != null) { 4439 try { 4440 deviceInfo.mCallback.dispatchDeviceVolumeAdjusted(deviceInfo.mDevice, 4441 new VolumeInfo.Builder(volumeInfo) 4442 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo)) 4443 .build(), 4444 direction, 4445 mode); 4446 } catch (RemoteException e) { 4447 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume adjustment"); 4448 } 4449 } 4450 } 4451 4452 // No ringer or zen muted stream volumes can be changed unless it'll exit dnd volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags)4453 private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) { 4454 switch (mNm.getZenMode()) { 4455 case Settings.Global.ZEN_MODE_OFF: 4456 return true; 4457 case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: 4458 case Settings.Global.ZEN_MODE_ALARMS: 4459 case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: 4460 return !isStreamMutedByRingerOrZenMode(streamTypeAlias) 4461 || isUiSoundsStreamType(streamTypeAlias) 4462 || (flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0; 4463 } 4464 4465 return true; 4466 } 4467 4468 /** @see AudioManager#forceVolumeControlStream(int) */ forceVolumeControlStream(int streamType, IBinder cb)4469 public void forceVolumeControlStream(int streamType, IBinder cb) { 4470 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) 4471 != PackageManager.PERMISSION_GRANTED) { 4472 return; 4473 } 4474 if (DEBUG_VOL) { Log.d(TAG, String.format("forceVolumeControlStream(%d)", streamType)); } 4475 synchronized(mForceControlStreamLock) { 4476 if (mVolumeControlStream != -1 && streamType != -1) { 4477 mUserSelectedVolumeControlStream = true; 4478 } 4479 mVolumeControlStream = streamType; 4480 if (mVolumeControlStream == -1) { 4481 if (mForceControlStreamClient != null) { 4482 mForceControlStreamClient.release(); 4483 mForceControlStreamClient = null; 4484 } 4485 mUserSelectedVolumeControlStream = false; 4486 } else { 4487 if (null == mForceControlStreamClient) { 4488 mForceControlStreamClient = new ForceControlStreamClient(cb); 4489 } else { 4490 if (mForceControlStreamClient.getBinder() == cb) { 4491 Log.d(TAG, "forceVolumeControlStream cb:" + cb + " is already linked."); 4492 } else { 4493 mForceControlStreamClient.release(); 4494 mForceControlStreamClient = new ForceControlStreamClient(cb); 4495 } 4496 } 4497 } 4498 } 4499 } 4500 4501 private class ForceControlStreamClient implements IBinder.DeathRecipient { 4502 private IBinder mCb; // To be notified of client's death 4503 ForceControlStreamClient(IBinder cb)4504 ForceControlStreamClient(IBinder cb) { 4505 if (cb != null) { 4506 try { 4507 cb.linkToDeath(this, 0); 4508 } catch (RemoteException e) { 4509 // Client has died! 4510 Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death"); 4511 cb = null; 4512 } 4513 } 4514 mCb = cb; 4515 } 4516 binderDied()4517 public void binderDied() { 4518 synchronized(mForceControlStreamLock) { 4519 Log.w(TAG, "SCO client died"); 4520 if (mForceControlStreamClient != this) { 4521 Log.w(TAG, "unregistered control stream client died"); 4522 } else { 4523 mForceControlStreamClient = null; 4524 mVolumeControlStream = -1; 4525 mUserSelectedVolumeControlStream = false; 4526 } 4527 } 4528 } 4529 release()4530 public void release() { 4531 if (mCb != null) { 4532 mCb.unlinkToDeath(this, 0); 4533 mCb = null; 4534 } 4535 } 4536 getBinder()4537 public IBinder getBinder() { 4538 return mCb; 4539 } 4540 } 4541 sendBroadcastToAll(Intent intent)4542 private void sendBroadcastToAll(Intent intent) { 4543 if (!mSystemServer.isPrivileged()) { 4544 return; 4545 } 4546 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 4547 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 4548 final long ident = Binder.clearCallingIdentity(); 4549 try { 4550 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 4551 } finally { 4552 Binder.restoreCallingIdentity(ident); 4553 } 4554 } 4555 sendStickyBroadcastToAll(Intent intent)4556 private void sendStickyBroadcastToAll(Intent intent) { 4557 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 4558 final long ident = Binder.clearCallingIdentity(); 4559 try { 4560 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 4561 } finally { 4562 Binder.restoreCallingIdentity(ident); 4563 } 4564 } 4565 getCurrentUserId()4566 private int getCurrentUserId() { 4567 final long ident = Binder.clearCallingIdentity(); 4568 try { 4569 UserInfo currentUser = ActivityManager.getService().getCurrentUser(); 4570 return currentUser.id; 4571 } catch (RemoteException e) { 4572 // Activity manager not running, nothing we can do assume user 0. 4573 } finally { 4574 Binder.restoreCallingIdentity(ident); 4575 } 4576 return UserHandle.USER_SYSTEM; 4577 } 4578 4579 // UI update and Broadcast Intent sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)4580 protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device) 4581 { 4582 streamType = mStreamVolumeAlias[streamType]; 4583 4584 if (streamType == AudioSystem.STREAM_MUSIC && isFullVolumeDevice(device)) { 4585 flags &= ~AudioManager.FLAG_SHOW_UI; 4586 } 4587 mVolumeController.postVolumeChanged(streamType, flags); 4588 } 4589 4590 // Don't show volume UI when: 4591 // - Hdmi-CEC system audio mode is on and we are a TV panel updateFlagsForTvPlatform(int flags)4592 private int updateFlagsForTvPlatform(int flags) { 4593 synchronized (mHdmiClientLock) { 4594 if (mHdmiTvClient != null && mHdmiSystemAudioSupported 4595 && mHdmiCecVolumeControlEnabled) { 4596 flags &= ~AudioManager.FLAG_SHOW_UI; 4597 } 4598 } 4599 return flags; 4600 } 4601 // UI update and Broadcast Intent sendMasterMuteUpdate(boolean muted, int flags)4602 private void sendMasterMuteUpdate(boolean muted, int flags) { 4603 mVolumeController.postMasterMuteChanged(updateFlagsForTvPlatform(flags)); 4604 broadcastMasterMuteStatus(muted); 4605 } 4606 broadcastMasterMuteStatus(boolean muted)4607 private void broadcastMasterMuteStatus(boolean muted) { 4608 Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION); 4609 intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, muted); 4610 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 4611 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 4612 sendStickyBroadcastToAll(intent); 4613 } 4614 4615 /** 4616 * Sets the stream state's index, and posts a message to set system volume. 4617 * This will not call out to the UI. Assumes a valid stream type. 4618 * 4619 * @param streamType Type of the stream 4620 * @param index Desired volume index of the stream 4621 * @param device the device whose volume must be changed 4622 * @param force If true, set the volume even if the desired volume is same 4623 * @param caller 4624 * @param hasModifyAudioSettings true if the caller is granted MODIFY_AUDIO_SETTINGS or 4625 * MODIFY_AUDIO_ROUTING permission 4626 * as the current volume. 4627 */ setStreamVolumeInt(int streamType, int index, int device, boolean force, String caller, boolean hasModifyAudioSettings)4628 private void setStreamVolumeInt(int streamType, 4629 int index, 4630 int device, 4631 boolean force, 4632 String caller, boolean hasModifyAudioSettings) { 4633 if (isFullVolumeDevice(device)) { 4634 return; 4635 } 4636 VolumeStreamState streamState = mStreamStates[streamType]; 4637 4638 if (streamState.setIndex(index, device, caller, hasModifyAudioSettings) || force) { 4639 // Post message to set system volume (it in turn will post a message 4640 // to persist). 4641 sendMsg(mAudioHandler, 4642 MSG_SET_DEVICE_VOLUME, 4643 SENDMSG_QUEUE, 4644 device, 4645 0, 4646 streamState, 4647 0); 4648 } 4649 } 4650 4651 /** get stream mute state. */ isStreamMute(int streamType)4652 public boolean isStreamMute(int streamType) { 4653 if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 4654 streamType = getActiveStreamType(streamType); 4655 } 4656 synchronized (VolumeStreamState.class) { 4657 ensureValidStreamType(streamType); 4658 return mStreamStates[streamType].mIsMuted; 4659 } 4660 } 4661 4662 private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient { 4663 private IBinder mICallback; // To be notified of client's death 4664 RmtSbmxFullVolDeathHandler(IBinder cb)4665 RmtSbmxFullVolDeathHandler(IBinder cb) { 4666 mICallback = cb; 4667 try { 4668 cb.linkToDeath(this, 0/*flags*/); 4669 } catch (RemoteException e) { 4670 Log.e(TAG, "can't link to death", e); 4671 } 4672 } 4673 isHandlerFor(IBinder cb)4674 boolean isHandlerFor(IBinder cb) { 4675 return mICallback.equals(cb); 4676 } 4677 forget()4678 void forget() { 4679 try { 4680 mICallback.unlinkToDeath(this, 0/*flags*/); 4681 } catch (NoSuchElementException e) { 4682 Log.e(TAG, "error unlinking to death", e); 4683 } 4684 } 4685 binderDied()4686 public void binderDied() { 4687 Log.w(TAG, "Recorder with remote submix at full volume died " + mICallback); 4688 forceRemoteSubmixFullVolume(false, mICallback); 4689 } 4690 } 4691 4692 /** 4693 * call must be synchronized on mRmtSbmxFullVolDeathHandlers 4694 * @return true if there is a registered death handler, false otherwise */ discardRmtSbmxFullVolDeathHandlerFor(IBinder cb)4695 private boolean discardRmtSbmxFullVolDeathHandlerFor(IBinder cb) { 4696 Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator(); 4697 while (it.hasNext()) { 4698 final RmtSbmxFullVolDeathHandler handler = it.next(); 4699 if (handler.isHandlerFor(cb)) { 4700 handler.forget(); 4701 mRmtSbmxFullVolDeathHandlers.remove(handler); 4702 return true; 4703 } 4704 } 4705 return false; 4706 } 4707 4708 /** call synchronized on mRmtSbmxFullVolDeathHandlers */ hasRmtSbmxFullVolDeathHandlerFor(IBinder cb)4709 private boolean hasRmtSbmxFullVolDeathHandlerFor(IBinder cb) { 4710 Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator(); 4711 while (it.hasNext()) { 4712 if (it.next().isHandlerFor(cb)) { 4713 return true; 4714 } 4715 } 4716 return false; 4717 } 4718 4719 private int mRmtSbmxFullVolRefCount = 0; 4720 private final ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers = 4721 new ArrayList<RmtSbmxFullVolDeathHandler>(); 4722 forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb)4723 public void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb) { 4724 if (cb == null) { 4725 return; 4726 } 4727 if ((PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 4728 android.Manifest.permission.CAPTURE_AUDIO_OUTPUT))) { 4729 Log.w(TAG, "Trying to call forceRemoteSubmixFullVolume() without CAPTURE_AUDIO_OUTPUT"); 4730 return; 4731 } 4732 synchronized(mRmtSbmxFullVolDeathHandlers) { 4733 boolean applyRequired = false; 4734 if (startForcing) { 4735 if (!hasRmtSbmxFullVolDeathHandlerFor(cb)) { 4736 mRmtSbmxFullVolDeathHandlers.add(new RmtSbmxFullVolDeathHandler(cb)); 4737 if (mRmtSbmxFullVolRefCount == 0) { 4738 mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 4739 mFixedVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 4740 applyRequired = true; 4741 } 4742 mRmtSbmxFullVolRefCount++; 4743 } 4744 } else { 4745 if (discardRmtSbmxFullVolDeathHandlerFor(cb) && (mRmtSbmxFullVolRefCount > 0)) { 4746 mRmtSbmxFullVolRefCount--; 4747 if (mRmtSbmxFullVolRefCount == 0) { 4748 mFullVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 4749 mFixedVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 4750 applyRequired = true; 4751 } 4752 } 4753 } 4754 if (applyRequired) { 4755 // Assumes only STREAM_MUSIC going through DEVICE_OUT_REMOTE_SUBMIX 4756 checkAllFixedVolumeDevices(AudioSystem.STREAM_MUSIC); 4757 mStreamStates[AudioSystem.STREAM_MUSIC].applyAllVolumes(); 4758 } 4759 } 4760 } 4761 setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, int userId, int pid, String attributionTag)4762 private void setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, 4763 int userId, int pid, String attributionTag) { 4764 // If we are being called by the system check for user we are going to change 4765 // so we handle user restrictions correctly. 4766 if (uid == android.os.Process.SYSTEM_UID) { 4767 uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 4768 } 4769 // If OP_AUDIO_MASTER_VOLUME is set, disallow unmuting. 4770 if (!mute && !checkNoteAppOp( 4771 AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage, attributionTag)) { 4772 return; 4773 } 4774 if (userId != UserHandle.getCallingUserId() && 4775 mContext.checkPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4776 pid, uid) 4777 != PackageManager.PERMISSION_GRANTED) { 4778 return; 4779 } 4780 setMasterMuteInternalNoCallerCheck(mute, flags, userId); 4781 } 4782 setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId)4783 private void setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId) { 4784 if (DEBUG_VOL) { 4785 Log.d(TAG, String.format("Master mute %s, %d, user=%d", mute, flags, userId)); 4786 } 4787 if (!isPlatformAutomotive() && mUseFixedVolume) { 4788 // If using fixed volume, we don't mute. 4789 // TODO: remove the isPlatformAutomotive check here. 4790 // The isPlatformAutomotive check is added for safety but may not be necessary. 4791 return; 4792 } 4793 // For automotive, 4794 // - the car service is always running as system user 4795 // - foreground users are non-system users 4796 // Car service is in charge of dispatching the key event include global mute to Android. 4797 // Therefore, the getCurrentUser() is always different to the foreground user. 4798 if ((isPlatformAutomotive() && userId == UserHandle.USER_SYSTEM) 4799 || (getCurrentUserId() == userId)) { 4800 if (mute != AudioSystem.getMasterMute()) { 4801 AudioSystem.setMasterMute(mute); 4802 sendMasterMuteUpdate(mute, flags); 4803 } 4804 } 4805 } 4806 4807 /** get global mute state. */ isMasterMute()4808 public boolean isMasterMute() { 4809 return AudioSystem.getMasterMute(); 4810 } 4811 4812 /** @see AudioManager#setMasterMute(boolean, int) */ setMasterMute(boolean mute, int flags, String callingPackage, int userId, String attributionTag)4813 public void setMasterMute(boolean mute, int flags, String callingPackage, int userId, 4814 String attributionTag) { 4815 enforceModifyAudioRoutingPermission(); 4816 setMasterMuteInternal(mute, flags, callingPackage, 4817 Binder.getCallingUid(), userId, Binder.getCallingPid(), attributionTag); 4818 } 4819 4820 /** @see AudioManager#getStreamVolume(int) */ getStreamVolume(int streamType)4821 public int getStreamVolume(int streamType) { 4822 ensureValidStreamType(streamType); 4823 int device = getDeviceForStream(streamType); 4824 synchronized (VolumeStreamState.class) { 4825 int index = mStreamStates[streamType].getIndex(device); 4826 4827 // by convention getStreamVolume() returns 0 when a stream is muted. 4828 if (mStreamStates[streamType].mIsMuted) { 4829 index = 0; 4830 } 4831 if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) && 4832 isFixedVolumeDevice(device)) { 4833 index = mStreamStates[streamType].getMaxIndex(); 4834 } 4835 return (index + 5) / 10; 4836 } 4837 } 4838 4839 /** 4840 * @see AudioDeviceVolumeManager#getDeviceVolume(VolumeInfo, AudioDeviceAttributes) 4841 */ getDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)4842 public @NonNull VolumeInfo getDeviceVolume(@NonNull VolumeInfo vi, 4843 @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage) { 4844 enforceModifyAudioRoutingOrSystemSettingsPermission(); 4845 Objects.requireNonNull(vi); 4846 Objects.requireNonNull(ada); 4847 Objects.requireNonNull(callingPackage); 4848 if (!vi.hasStreamType()) { 4849 Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception()); 4850 return getDefaultVolumeInfo(); 4851 } 4852 4853 int streamType = vi.getStreamType(); 4854 final VolumeInfo.Builder vib = new VolumeInfo.Builder(vi); 4855 vib.setMinVolumeIndex((mStreamStates[streamType].mIndexMin + 5) / 10); 4856 vib.setMaxVolumeIndex((mStreamStates[streamType].mIndexMax + 5) / 10); 4857 synchronized (VolumeStreamState.class) { 4858 final int index; 4859 if (isFixedVolumeDevice(ada.getInternalType())) { 4860 index = (mStreamStates[streamType].mIndexMax + 5) / 10; 4861 } else { 4862 index = (mStreamStates[streamType].getIndex(ada.getInternalType()) + 5) / 10; 4863 } 4864 vib.setVolumeIndex(index); 4865 // only set as a mute command if stream muted 4866 if (mStreamStates[streamType].mIsMuted) { 4867 vib.setMuted(true); 4868 } 4869 return vib.build(); 4870 } 4871 } 4872 4873 /** @see AudioManager#getStreamMaxVolume(int) */ getStreamMaxVolume(int streamType)4874 public int getStreamMaxVolume(int streamType) { 4875 ensureValidStreamType(streamType); 4876 return (mStreamStates[streamType].getMaxIndex() + 5) / 10; 4877 } 4878 4879 /** @see AudioManager#getStreamMinVolumeInt(int) 4880 * Part of service interface, check permissions here */ getStreamMinVolume(int streamType)4881 public int getStreamMinVolume(int streamType) { 4882 ensureValidStreamType(streamType); 4883 final boolean isPrivileged = 4884 Binder.getCallingUid() == Process.SYSTEM_UID 4885 || callingHasAudioSettingsPermission() 4886 || (mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_ROUTING) 4887 == PackageManager.PERMISSION_GRANTED); 4888 return (mStreamStates[streamType].getMinIndex(isPrivileged) + 5) / 10; 4889 } 4890 4891 /** Get last audible volume before stream was muted. */ getLastAudibleStreamVolume(int streamType)4892 public int getLastAudibleStreamVolume(int streamType) { 4893 enforceQueryStatePermission(); 4894 ensureValidStreamType(streamType); 4895 int device = getDeviceForStream(streamType); 4896 return (mStreamStates[streamType].getIndex(device) + 5) / 10; 4897 } 4898 4899 /** 4900 * Default VolumeInfo returned by {@link VolumeInfo#getDefaultVolumeInfo()} 4901 * Lazily initialized in {@link #getDefaultVolumeInfo()} 4902 */ 4903 static VolumeInfo sDefaultVolumeInfo; 4904 4905 /** @see VolumeInfo#getDefaultVolumeInfo() */ getDefaultVolumeInfo()4906 public VolumeInfo getDefaultVolumeInfo() { 4907 if (sDefaultVolumeInfo == null) { 4908 sDefaultVolumeInfo = new VolumeInfo.Builder(AudioSystem.STREAM_MUSIC) 4909 .setMinVolumeIndex(getStreamMinVolume(AudioSystem.STREAM_MUSIC)) 4910 .setMaxVolumeIndex(getStreamMaxVolume(AudioSystem.STREAM_MUSIC)) 4911 .build(); 4912 } 4913 return sDefaultVolumeInfo; 4914 } 4915 4916 /** @see AudioManager#getUiSoundsStreamType() 4917 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for 4918 * UI Sounds identification. 4919 * Fallback on Voice configuration to ensure correct behavior of DnD feature. 4920 */ getUiSoundsStreamType()4921 public int getUiSoundsStreamType() { 4922 return mUseVolumeGroupAliases ? STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM] 4923 : mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM]; 4924 } 4925 4926 /** 4927 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for 4928 * UI Sounds identification. 4929 * Fallback on Voice configuration to ensure correct behavior of DnD feature. 4930 */ isUiSoundsStreamType(int aliasStreamType)4931 private boolean isUiSoundsStreamType(int aliasStreamType) { 4932 return mUseVolumeGroupAliases 4933 ? STREAM_VOLUME_ALIAS_VOICE[aliasStreamType] 4934 == STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM] 4935 : aliasStreamType == mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM]; 4936 } 4937 4938 /** @see AudioManager#setMicrophoneMute(boolean) */ 4939 @Override setMicrophoneMute(boolean on, String callingPackage, int userId, String attributionTag)4940 public void setMicrophoneMute(boolean on, String callingPackage, int userId, 4941 String attributionTag) { 4942 // If we are being called by the system check for user we are going to change 4943 // so we handle user restrictions correctly. 4944 int uid = Binder.getCallingUid(); 4945 if (uid == android.os.Process.SYSTEM_UID) { 4946 uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 4947 } 4948 MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 4949 .setUid(uid) 4950 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage) 4951 .set(MediaMetrics.Property.EVENT, "setMicrophoneMute") 4952 .set(MediaMetrics.Property.REQUEST, on 4953 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE); 4954 4955 // If OP_MUTE_MICROPHONE is set, disallow unmuting. 4956 if (!on && !checkNoteAppOp( 4957 AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage, attributionTag)) { 4958 mmi.set(MediaMetrics.Property.EARLY_RETURN, "disallow unmuting").record(); 4959 return; 4960 } 4961 if (!checkAudioSettingsPermission("setMicrophoneMute()")) { 4962 mmi.set(MediaMetrics.Property.EARLY_RETURN, "!checkAudioSettingsPermission").record(); 4963 return; 4964 } 4965 if (userId != UserHandle.getCallingUserId() && 4966 mContext.checkCallingOrSelfPermission( 4967 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 4968 != PackageManager.PERMISSION_GRANTED) { 4969 mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission").record(); 4970 return; 4971 } 4972 mMicMuteFromApi = on; 4973 mmi.record(); // record now, the no caller check will set the mute state. 4974 setMicrophoneMuteNoCallerCheck(userId); 4975 } 4976 4977 /** @see AudioManager#setMicrophoneMuteFromSwitch(boolean) */ setMicrophoneMuteFromSwitch(boolean on)4978 public void setMicrophoneMuteFromSwitch(boolean on) { 4979 int userId = Binder.getCallingUid(); 4980 if (userId != android.os.Process.SYSTEM_UID) { 4981 Log.e(TAG, "setMicrophoneMuteFromSwitch() called from non system user!"); 4982 return; 4983 } 4984 mMicMuteFromSwitch = on; 4985 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 4986 .setUid(userId) 4987 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteFromSwitch") 4988 .set(MediaMetrics.Property.REQUEST, on 4989 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE) 4990 .record(); 4991 setMicrophoneMuteNoCallerCheck(userId); 4992 } 4993 setMicMuteFromSwitchInput()4994 private void setMicMuteFromSwitchInput() { 4995 InputManager im = mContext.getSystemService(InputManager.class); 4996 final int isMicMuted = im.isMicMuted(); 4997 if (isMicMuted != InputManager.SWITCH_STATE_UNKNOWN) { 4998 setMicrophoneMuteFromSwitch(im.isMicMuted() != InputManager.SWITCH_STATE_OFF); 4999 } 5000 } 5001 5002 /** 5003 * Returns the microphone mute state as seen from the native audio system 5004 * @return true if microphone is reported as muted by primary HAL 5005 */ isMicrophoneMuted()5006 public boolean isMicrophoneMuted() { 5007 return mMicMuteFromSystemCached 5008 && (!mMicMuteFromPrivacyToggle 5009 || mMicMuteFromApi || mMicMuteFromRestrictions || mMicMuteFromSwitch); 5010 } 5011 isMicrophoneSupposedToBeMuted()5012 private boolean isMicrophoneSupposedToBeMuted() { 5013 return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi 5014 || mMicMuteFromPrivacyToggle; 5015 } 5016 setMicrophoneMuteNoCallerCheck(int userId)5017 private void setMicrophoneMuteNoCallerCheck(int userId) { 5018 final boolean muted = isMicrophoneSupposedToBeMuted(); 5019 if (DEBUG_VOL) { 5020 Log.d(TAG, String.format("Mic mute %b, user=%d", muted, userId)); 5021 } 5022 // only mute for the current user 5023 if (getCurrentUserId() == userId || userId == android.os.Process.SYSTEM_UID) { 5024 final boolean currentMute = mAudioSystem.isMicrophoneMuted(); 5025 final long identity = Binder.clearCallingIdentity(); 5026 final int ret = mAudioSystem.muteMicrophone(muted); 5027 5028 // update cache with the real state independently from what was set 5029 mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted(); 5030 if (ret != AudioSystem.AUDIO_STATUS_OK) { 5031 Log.e(TAG, "Error changing mic mute state to " + muted + " current:" 5032 + mMicMuteFromSystemCached); 5033 } 5034 5035 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 5036 .setUid(userId) 5037 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteNoCallerCheck") 5038 .set(MediaMetrics.Property.MUTE, mMicMuteFromSystemCached 5039 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 5040 .set(MediaMetrics.Property.REQUEST, muted 5041 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE) 5042 .set(MediaMetrics.Property.STATUS, ret) 5043 .record(); 5044 5045 try { 5046 // send the intent even if there was a failure to change the actual mute state: 5047 // the AudioManager.setMicrophoneMute API doesn't have a return value to 5048 // indicate if the call failed to successfully change the mute state, and receiving 5049 // the intent may be the only time an application can resynchronize its mic mute 5050 // state with the actual system mic mute state 5051 if (muted != currentMute) { 5052 sendMsg(mAudioHandler, MSG_BROADCAST_MICROPHONE_MUTE, 5053 SENDMSG_NOOP, 0, 0, null, 0); 5054 } 5055 } finally { 5056 Binder.restoreCallingIdentity(identity); 5057 } 5058 } 5059 } 5060 5061 @Override getRingerModeExternal()5062 public int getRingerModeExternal() { 5063 synchronized(mSettingsLock) { 5064 return mRingerModeExternal; 5065 } 5066 } 5067 5068 @Override getRingerModeInternal()5069 public int getRingerModeInternal() { 5070 synchronized(mSettingsLock) { 5071 return mRingerMode; 5072 } 5073 } 5074 ensureValidRingerMode(int ringerMode)5075 private void ensureValidRingerMode(int ringerMode) { 5076 if (!isValidRingerMode(ringerMode)) { 5077 throw new IllegalArgumentException("Bad ringer mode " + ringerMode); 5078 } 5079 } 5080 5081 /** @see AudioManager#isValidRingerMode(int) */ isValidRingerMode(int ringerMode)5082 public boolean isValidRingerMode(int ringerMode) { 5083 return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX; 5084 } 5085 setRingerModeExternal(int ringerMode, String caller)5086 public void setRingerModeExternal(int ringerMode, String caller) { 5087 if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode) 5088 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)) { 5089 throw new SecurityException("Not allowed to change Do Not Disturb state"); 5090 } 5091 5092 setRingerMode(ringerMode, caller, true /*external*/); 5093 } 5094 setRingerModeInternal(int ringerMode, String caller)5095 public void setRingerModeInternal(int ringerMode, String caller) { 5096 enforceVolumeController("setRingerModeInternal"); 5097 setRingerMode(ringerMode, caller, false /*external*/); 5098 } 5099 silenceRingerModeInternal(String reason)5100 public void silenceRingerModeInternal(String reason) { 5101 VibrationEffect effect = null; 5102 int ringerMode = AudioManager.RINGER_MODE_SILENT; 5103 int toastText = 0; 5104 5105 int silenceRingerSetting = Settings.Secure.VOLUME_HUSH_OFF; 5106 if (mContext.getResources() 5107 .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) { 5108 silenceRingerSetting = mSettings.getSecureIntForUser(mContentResolver, 5109 Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF, 5110 UserHandle.USER_CURRENT); 5111 } 5112 5113 switch(silenceRingerSetting) { 5114 case VOLUME_HUSH_MUTE: 5115 effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK); 5116 ringerMode = AudioManager.RINGER_MODE_SILENT; 5117 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent; 5118 break; 5119 case VOLUME_HUSH_VIBRATE: 5120 effect = VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK); 5121 ringerMode = AudioManager.RINGER_MODE_VIBRATE; 5122 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate; 5123 break; 5124 } 5125 maybeVibrate(effect, reason); 5126 setRingerModeInternal(ringerMode, reason); 5127 Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT).show(); 5128 } 5129 maybeVibrate(VibrationEffect effect, String reason)5130 private boolean maybeVibrate(VibrationEffect effect, String reason) { 5131 if (!mHasVibrator) { 5132 return false; 5133 } 5134 if (effect == null) { 5135 return false; 5136 } 5137 mVibrator.vibrate(Binder.getCallingUid(), mContext.getOpPackageName(), effect, 5138 reason, TOUCH_VIBRATION_ATTRIBUTES); 5139 return true; 5140 } 5141 setRingerMode(int ringerMode, String caller, boolean external)5142 private void setRingerMode(int ringerMode, String caller, boolean external) { 5143 if (mUseFixedVolume || mIsSingleVolume || mUseVolumeGroupAliases) { 5144 return; 5145 } 5146 if (caller == null || caller.length() == 0) { 5147 throw new IllegalArgumentException("Bad caller: " + caller); 5148 } 5149 ensureValidRingerMode(ringerMode); 5150 if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { 5151 ringerMode = AudioManager.RINGER_MODE_SILENT; 5152 } 5153 final long identity = Binder.clearCallingIdentity(); 5154 try { 5155 synchronized (mSettingsLock) { 5156 final int ringerModeInternal = getRingerModeInternal(); 5157 final int ringerModeExternal = getRingerModeExternal(); 5158 if (external) { 5159 setRingerModeExt(ringerMode); 5160 if (mRingerModeDelegate != null) { 5161 ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal, 5162 ringerMode, caller, ringerModeInternal, mVolumePolicy); 5163 } 5164 if (ringerMode != ringerModeInternal) { 5165 setRingerModeInt(ringerMode, true /*persist*/); 5166 } 5167 } else /*internal*/ { 5168 if (ringerMode != ringerModeInternal) { 5169 setRingerModeInt(ringerMode, true /*persist*/); 5170 } 5171 if (mRingerModeDelegate != null) { 5172 ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal, 5173 ringerMode, caller, ringerModeExternal, mVolumePolicy); 5174 } 5175 setRingerModeExt(ringerMode); 5176 } 5177 } 5178 } finally { 5179 Binder.restoreCallingIdentity(identity); 5180 } 5181 } 5182 setRingerModeExt(int ringerMode)5183 private void setRingerModeExt(int ringerMode) { 5184 synchronized(mSettingsLock) { 5185 if (ringerMode == mRingerModeExternal) return; 5186 mRingerModeExternal = ringerMode; 5187 } 5188 // Send sticky broadcast 5189 broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode); 5190 } 5191 5192 @GuardedBy("mSettingsLock") muteRingerModeStreams()5193 private void muteRingerModeStreams() { 5194 // Mute stream if not previously muted by ringer mode and (ringer mode 5195 // is not RINGER_MODE_NORMAL OR stream is zen muted) and stream is affected by ringer mode. 5196 // Unmute stream if previously muted by ringer/zen mode and ringer mode 5197 // is RINGER_MODE_NORMAL or stream is not affected by ringer mode. 5198 int numStreamTypes = AudioSystem.getNumStreamTypes(); 5199 5200 if (mNm == null) { 5201 mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 5202 } 5203 5204 final int ringerMode = mRingerMode; // Read ringer mode as reading primitives is atomic 5205 final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE 5206 || ringerMode == AudioManager.RINGER_MODE_SILENT; 5207 final boolean shouldRingSco = ringerMode == AudioManager.RINGER_MODE_VIBRATE 5208 && mDeviceBroker.isBluetoothScoActive(); 5209 // Ask audio policy engine to force use Bluetooth SCO channel if needed 5210 final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid() 5211 + "/" + Binder.getCallingPid(); 5212 sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, AudioSystem.FOR_VIBRATE_RINGING, 5213 shouldRingSco ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE, eventSource, 0); 5214 5215 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 5216 final boolean isMuted = isStreamMutedByRingerOrZenMode(streamType); 5217 final boolean muteAllowedBySco = 5218 !(shouldRingSco && streamType == AudioSystem.STREAM_RING); 5219 final boolean shouldZenMute = shouldZenMuteStream(streamType); 5220 final boolean shouldMute = shouldZenMute || (ringerModeMute 5221 && isStreamAffectedByRingerMode(streamType) && muteAllowedBySco); 5222 if (isMuted == shouldMute) continue; 5223 if (!shouldMute) { 5224 // unmute 5225 // ring and notifications volume should never be 0 when not silenced 5226 if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING 5227 || mStreamVolumeAlias[streamType] == AudioSystem.STREAM_NOTIFICATION) { 5228 synchronized (VolumeStreamState.class) { 5229 final VolumeStreamState vss = mStreamStates[streamType]; 5230 for (int i = 0; i < vss.mIndexMap.size(); i++) { 5231 int device = vss.mIndexMap.keyAt(i); 5232 int value = vss.mIndexMap.valueAt(i); 5233 if (value == 0) { 5234 vss.setIndex(10, device, TAG, true /*hasModifyAudioSettings*/); 5235 } 5236 } 5237 // Persist volume for stream ring when it is changed here 5238 final int device = getDeviceForStream(streamType); 5239 sendMsg(mAudioHandler, 5240 MSG_PERSIST_VOLUME, 5241 SENDMSG_QUEUE, 5242 device, 5243 0, 5244 mStreamStates[streamType], 5245 PERSIST_DELAY); 5246 } 5247 } 5248 mStreamStates[streamType].mute(false); 5249 mRingerAndZenModeMutedStreams &= ~(1 << streamType); 5250 } else { 5251 // mute 5252 mStreamStates[streamType].mute(true); 5253 mRingerAndZenModeMutedStreams |= (1 << streamType); 5254 } 5255 } 5256 } 5257 isAlarm(int streamType)5258 private boolean isAlarm(int streamType) { 5259 return streamType == AudioSystem.STREAM_ALARM; 5260 } 5261 isNotificationOrRinger(int streamType)5262 private boolean isNotificationOrRinger(int streamType) { 5263 return streamType == AudioSystem.STREAM_NOTIFICATION 5264 || streamType == AudioSystem.STREAM_RING; 5265 } 5266 isMedia(int streamType)5267 private boolean isMedia(int streamType) { 5268 return streamType == AudioSystem.STREAM_MUSIC; 5269 } 5270 5271 isSystem(int streamType)5272 private boolean isSystem(int streamType) { 5273 return streamType == AudioSystem.STREAM_SYSTEM; 5274 } 5275 setRingerModeInt(int ringerMode, boolean persist)5276 private void setRingerModeInt(int ringerMode, boolean persist) { 5277 final boolean change; 5278 synchronized(mSettingsLock) { 5279 change = mRingerMode != ringerMode; 5280 mRingerMode = ringerMode; 5281 muteRingerModeStreams(); 5282 } 5283 5284 // Post a persist ringer mode msg 5285 if (persist) { 5286 sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE, 5287 SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY); 5288 } 5289 if (change) { 5290 // Send sticky broadcast 5291 broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, ringerMode); 5292 } 5293 } 5294 postUpdateRingerModeServiceInt()5295 /*package*/ void postUpdateRingerModeServiceInt() { 5296 sendMsg(mAudioHandler, MSG_UPDATE_RINGER_MODE, SENDMSG_QUEUE, 0, 0, null, 0); 5297 } 5298 onUpdateRingerModeServiceInt()5299 private void onUpdateRingerModeServiceInt() { 5300 setRingerModeInt(getRingerModeInternal(), false); 5301 } 5302 5303 /** @see AudioManager#shouldVibrate(int) */ shouldVibrate(int vibrateType)5304 public boolean shouldVibrate(int vibrateType) { 5305 if (!mHasVibrator) return false; 5306 5307 switch (getVibrateSetting(vibrateType)) { 5308 5309 case AudioManager.VIBRATE_SETTING_ON: 5310 return getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT; 5311 5312 case AudioManager.VIBRATE_SETTING_ONLY_SILENT: 5313 return getRingerModeExternal() == AudioManager.RINGER_MODE_VIBRATE; 5314 5315 case AudioManager.VIBRATE_SETTING_OFF: 5316 // return false, even for incoming calls 5317 return false; 5318 5319 default: 5320 return false; 5321 } 5322 } 5323 5324 /** @see AudioManager#getVibrateSetting(int) */ getVibrateSetting(int vibrateType)5325 public int getVibrateSetting(int vibrateType) { 5326 if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF; 5327 return (mVibrateSetting >> (vibrateType * 2)) & 3; 5328 } 5329 5330 /** @see AudioManager#setVibrateSetting(int, int) */ setVibrateSetting(int vibrateType, int vibrateSetting)5331 public void setVibrateSetting(int vibrateType, int vibrateSetting) { 5332 5333 if (!mHasVibrator) return; 5334 5335 mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, vibrateType, 5336 vibrateSetting); 5337 5338 // Broadcast change 5339 broadcastVibrateSetting(vibrateType); 5340 5341 } 5342 5343 private class SetModeDeathHandler implements IBinder.DeathRecipient { 5344 private final IBinder mCb; // To be notified of client's death 5345 private final int mPid; 5346 private final int mUid; 5347 private final boolean mIsPrivileged; 5348 private final String mPackage; 5349 private int mMode; 5350 private long mUpdateTime; 5351 private boolean mPlaybackActive = false; 5352 private boolean mRecordingActive = false; 5353 SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, String caller, int mode)5354 SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, 5355 String caller, int mode) { 5356 mMode = mode; 5357 mCb = cb; 5358 mPid = pid; 5359 mUid = uid; 5360 mPackage = caller; 5361 mIsPrivileged = isPrivileged; 5362 mUpdateTime = java.lang.System.currentTimeMillis(); 5363 } 5364 binderDied()5365 public void binderDied() { 5366 synchronized (mDeviceBroker.mSetModeLock) { 5367 Log.w(TAG, "SetModeDeathHandler client died"); 5368 int index = mSetModeDeathHandlers.indexOf(this); 5369 if (index < 0) { 5370 Log.w(TAG, "unregistered SetModeDeathHandler client died"); 5371 } else { 5372 SetModeDeathHandler h = mSetModeDeathHandlers.get(index); 5373 mSetModeDeathHandlers.remove(index); 5374 sendMsg(mAudioHandler, 5375 MSG_UPDATE_AUDIO_MODE, 5376 SENDMSG_QUEUE, 5377 AudioSystem.MODE_CURRENT, 5378 android.os.Process.myPid(), 5379 mContext.getPackageName(), 5380 0); 5381 } 5382 } 5383 } 5384 getPid()5385 public int getPid() { 5386 return mPid; 5387 } 5388 setMode(int mode)5389 public void setMode(int mode) { 5390 mMode = mode; 5391 mUpdateTime = java.lang.System.currentTimeMillis(); 5392 } 5393 getMode()5394 public int getMode() { 5395 return mMode; 5396 } 5397 getBinder()5398 public IBinder getBinder() { 5399 return mCb; 5400 } 5401 getUid()5402 public int getUid() { 5403 return mUid; 5404 } 5405 getPackage()5406 public String getPackage() { 5407 return mPackage; 5408 } 5409 isPrivileged()5410 public boolean isPrivileged() { 5411 return mIsPrivileged; 5412 } 5413 getUpdateTime()5414 public long getUpdateTime() { 5415 return mUpdateTime; 5416 } 5417 setPlaybackActive(boolean active)5418 public void setPlaybackActive(boolean active) { 5419 mPlaybackActive = active; 5420 } 5421 setRecordingActive(boolean active)5422 public void setRecordingActive(boolean active) { 5423 mRecordingActive = active; 5424 } 5425 5426 /** 5427 * An app is considered active if: 5428 * - It is privileged (has MODIFY_PHONE_STATE permission) 5429 * or 5430 * - It requests mode MODE_IN_COMMUNICATION, and it is either playing 5431 * or recording for VOICE_COMMUNICATION. 5432 * or 5433 * - It requests a mode different from MODE_IN_COMMUNICATION or MODE_NORMAL 5434 * Note: only privileged apps can request MODE_IN_CALL, MODE_CALL_REDIRECT 5435 * or MODE_COMMUNICATION_REDIRECT. 5436 */ isActive()5437 public boolean isActive() { 5438 return mIsPrivileged 5439 || ((mMode == AudioSystem.MODE_IN_COMMUNICATION) 5440 && (mRecordingActive || mPlaybackActive)) 5441 || mMode == AudioSystem.MODE_RINGTONE 5442 || mMode == AudioSystem.MODE_CALL_SCREENING; 5443 } 5444 dump(PrintWriter pw, int index)5445 public void dump(PrintWriter pw, int index) { 5446 SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss:SSS"); 5447 5448 if (index >= 0) { 5449 pw.println(" Requester # " + (index + 1) + ":"); 5450 } 5451 pw.println(" - Mode: " + AudioSystem.modeToString(mMode)); 5452 pw.println(" - Binder: " + mCb); 5453 pw.println(" - Pid: " + mPid); 5454 pw.println(" - Uid: " + mUid); 5455 pw.println(" - Package: " + mPackage); 5456 pw.println(" - Privileged: " + mIsPrivileged); 5457 pw.println(" - Active: " + isActive()); 5458 pw.println(" Playback active: " + mPlaybackActive); 5459 pw.println(" Recording active: " + mRecordingActive); 5460 pw.println(" - update time: " + format.format(new Date(mUpdateTime))); 5461 } 5462 } 5463 5464 @GuardedBy("mDeviceBroker.mSetModeLock") getAudioModeOwnerHandler()5465 private SetModeDeathHandler getAudioModeOwnerHandler() { 5466 // The Audio mode owner is: 5467 // 1) the most recent privileged app in the stack 5468 // 2) the most recent active app in the tack 5469 SetModeDeathHandler modeOwner = null; 5470 SetModeDeathHandler privilegedModeOwner = null; 5471 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 5472 if (h.isActive()) { 5473 // privileged apps are always active 5474 if (h.isPrivileged()) { 5475 if (privilegedModeOwner == null 5476 || h.getUpdateTime() > privilegedModeOwner.getUpdateTime()) { 5477 privilegedModeOwner = h; 5478 } 5479 } else { 5480 if (modeOwner == null 5481 || h.getUpdateTime() > modeOwner.getUpdateTime()) { 5482 modeOwner = h; 5483 } 5484 } 5485 } 5486 } 5487 return privilegedModeOwner != null ? privilegedModeOwner : modeOwner; 5488 } 5489 5490 /** 5491 * Return information on the current audio mode owner 5492 * @return 0 if nobody owns the mode 5493 */ 5494 @GuardedBy("mDeviceBroker.mSetModeLock") getAudioModeOwner()5495 /*package*/ AudioDeviceBroker.AudioModeInfo getAudioModeOwner() { 5496 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 5497 if (hdlr != null) { 5498 return new AudioDeviceBroker.AudioModeInfo( 5499 hdlr.getMode(), hdlr.getPid(), hdlr.getUid()); 5500 } 5501 return new AudioDeviceBroker.AudioModeInfo(AudioSystem.MODE_NORMAL, 0 , 0); 5502 } 5503 5504 /** 5505 * Return the uid of the current audio mode owner 5506 * @return 0 if nobody owns the mode 5507 */ 5508 @GuardedBy("mDeviceBroker.mSetModeLock") getModeOwnerUid()5509 /*package*/ int getModeOwnerUid() { 5510 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 5511 if (hdlr != null) { 5512 return hdlr.getUid(); 5513 } 5514 return 0; 5515 } 5516 5517 /** @see AudioManager#setMode(int) */ setMode(int mode, IBinder cb, String callingPackage)5518 public void setMode(int mode, IBinder cb, String callingPackage) { 5519 int pid = Binder.getCallingPid(); 5520 int uid = Binder.getCallingUid(); 5521 if (DEBUG_MODE) { 5522 Log.v(TAG, "setMode(mode=" + mode + ", pid=" + pid 5523 + ", uid=" + uid + ", caller=" + callingPackage + ")"); 5524 } 5525 if (!checkAudioSettingsPermission("setMode()")) { 5526 return; 5527 } 5528 if (cb == null) { 5529 Log.e(TAG, "setMode() called with null binder"); 5530 return; 5531 } 5532 if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) { 5533 Log.w(TAG, "setMode() invalid mode: " + mode); 5534 return; 5535 } 5536 5537 if (mode == AudioSystem.MODE_CURRENT) { 5538 mode = getMode(); 5539 } 5540 5541 if (mode == AudioSystem.MODE_CALL_SCREENING && !mIsCallScreeningModeSupported) { 5542 Log.w(TAG, "setMode(MODE_CALL_SCREENING) not permitted " 5543 + "when call screening is not supported"); 5544 return; 5545 } 5546 5547 final boolean hasModifyPhoneStatePermission = mContext.checkCallingOrSelfPermission( 5548 android.Manifest.permission.MODIFY_PHONE_STATE) 5549 == PackageManager.PERMISSION_GRANTED; 5550 if ((mode == AudioSystem.MODE_IN_CALL 5551 || mode == AudioSystem.MODE_CALL_REDIRECT 5552 || mode == AudioSystem.MODE_COMMUNICATION_REDIRECT) 5553 && !hasModifyPhoneStatePermission) { 5554 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setMode(" 5555 + AudioSystem.modeToString(mode) + ") from pid=" + pid 5556 + ", uid=" + Binder.getCallingUid()); 5557 return; 5558 } 5559 5560 SetModeDeathHandler currentModeHandler = null; 5561 synchronized (mDeviceBroker.mSetModeLock) { 5562 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 5563 if (h.getPid() == pid) { 5564 currentModeHandler = h; 5565 break; 5566 } 5567 } 5568 5569 if (mode == AudioSystem.MODE_NORMAL) { 5570 if (currentModeHandler != null) { 5571 if (!currentModeHandler.isPrivileged() 5572 && currentModeHandler.getMode() == AudioSystem.MODE_IN_COMMUNICATION) { 5573 mAudioHandler.removeEqualMessages( 5574 MSG_CHECK_MODE_FOR_UID, currentModeHandler); 5575 } 5576 mSetModeDeathHandlers.remove(currentModeHandler); 5577 if (DEBUG_MODE) { 5578 Log.v(TAG, "setMode(" + mode + ") removing hldr for pid: " + pid); 5579 } 5580 try { 5581 currentModeHandler.getBinder().unlinkToDeath(currentModeHandler, 0); 5582 } catch (NoSuchElementException e) { 5583 Log.w(TAG, "setMode link does not exist ..."); 5584 } 5585 } 5586 } else { 5587 if (currentModeHandler != null) { 5588 currentModeHandler.setMode(mode); 5589 if (DEBUG_MODE) { 5590 Log.v(TAG, "setMode(" + mode + ") updating hldr for pid: " + pid); 5591 } 5592 } else { 5593 currentModeHandler = new SetModeDeathHandler(cb, pid, uid, 5594 hasModifyPhoneStatePermission, callingPackage, mode); 5595 // Register for client death notification 5596 try { 5597 cb.linkToDeath(currentModeHandler, 0); 5598 } catch (RemoteException e) { 5599 // Client has died! 5600 Log.w(TAG, "setMode() could not link to " + cb + " binder death"); 5601 return; 5602 } 5603 mSetModeDeathHandlers.add(currentModeHandler); 5604 if (DEBUG_MODE) { 5605 Log.v(TAG, "setMode(" + mode + ") adding handler for pid=" + pid); 5606 } 5607 } 5608 if (mode == AudioSystem.MODE_IN_COMMUNICATION) { 5609 // Force active state when entering/updating the stack to avoid glitches when 5610 // an app starts playing/recording after settng the audio mode, 5611 // and send a reminder to check activity after a grace period. 5612 if (!currentModeHandler.isPrivileged()) { 5613 currentModeHandler.setPlaybackActive(true); 5614 currentModeHandler.setRecordingActive(true); 5615 sendMsg(mAudioHandler, 5616 MSG_CHECK_MODE_FOR_UID, 5617 SENDMSG_QUEUE, 5618 0, 5619 0, 5620 currentModeHandler, 5621 CHECK_MODE_FOR_UID_PERIOD_MS); 5622 } 5623 } 5624 } 5625 5626 sendMsg(mAudioHandler, 5627 MSG_UPDATE_AUDIO_MODE, 5628 SENDMSG_REPLACE, 5629 mode, 5630 pid, 5631 callingPackage, 5632 0); 5633 } 5634 } 5635 5636 @GuardedBy("mDeviceBroker.mSetModeLock") onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, boolean force)5637 void onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, 5638 boolean force) { 5639 if (requestedMode == AudioSystem.MODE_CURRENT) { 5640 requestedMode = getMode(); 5641 } 5642 int mode = AudioSystem.MODE_NORMAL; 5643 int uid = 0; 5644 int pid = 0; 5645 SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler(); 5646 if (currentModeHandler != null) { 5647 mode = currentModeHandler.getMode(); 5648 uid = currentModeHandler.getUid(); 5649 pid = currentModeHandler.getPid(); 5650 } 5651 if (DEBUG_MODE) { 5652 Log.v(TAG, "onUpdateAudioMode() new mode: " + mode + ", current mode: " 5653 + mMode.get() + " requested mode: " + requestedMode); 5654 } 5655 if (mode != mMode.get() || force) { 5656 final long identity = Binder.clearCallingIdentity(); 5657 int status = mAudioSystem.setPhoneState(mode, uid); 5658 Binder.restoreCallingIdentity(identity); 5659 if (status == AudioSystem.AUDIO_STATUS_OK) { 5660 if (DEBUG_MODE) { 5661 Log.v(TAG, "onUpdateAudioMode: mode successfully set to " + mode); 5662 } 5663 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_MODE, SENDMSG_REPLACE, mode, 0, 5664 /*obj*/ null, /*delay*/ 0); 5665 int previousMode = mMode.getAndSet(mode); 5666 // Note: newModeOwnerPid is always 0 when actualMode is MODE_NORMAL 5667 mModeLogger.log(new PhoneStateEvent(requesterPackage, requesterPid, 5668 requestedMode, pid, mode)); 5669 5670 int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE); 5671 int device = getDeviceForStream(streamType); 5672 int index = mStreamStates[mStreamVolumeAlias[streamType]].getIndex(device); 5673 setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, true, 5674 requesterPackage, true /*hasModifyAudioSettings*/); 5675 5676 updateStreamVolumeAlias(true /*updateVolumes*/, requesterPackage); 5677 5678 // change of mode may require volume to be re-applied on some devices 5679 updateAbsVolumeMultiModeDevices(previousMode, mode); 5680 5681 setLeAudioVolumeOnModeUpdate(mode, device); 5682 5683 // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO 5684 // connections not started by the application changing the mode when pid changes 5685 mDeviceBroker.postSetModeOwner(mode, pid, uid); 5686 } else { 5687 Log.w(TAG, "onUpdateAudioMode: failed to set audio mode to: " + mode); 5688 } 5689 } 5690 } 5691 5692 /** @see AudioManager#getMode() */ getMode()5693 public int getMode() { 5694 synchronized (mDeviceBroker.mSetModeLock) { 5695 SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler(); 5696 if (currentModeHandler != null) { 5697 return currentModeHandler.getMode(); 5698 } 5699 return AudioSystem.MODE_NORMAL; 5700 } 5701 } 5702 5703 /** cached value read from audiopolicy manager after initialization. */ 5704 private boolean mIsCallScreeningModeSupported = false; 5705 5706 /** @see AudioManager#isCallScreeningModeSupported() */ isCallScreeningModeSupported()5707 public boolean isCallScreeningModeSupported() { 5708 return mIsCallScreeningModeSupported; 5709 } 5710 dispatchMode(int mode)5711 protected void dispatchMode(int mode) { 5712 final int nbDispatchers = mModeDispatchers.beginBroadcast(); 5713 for (int i = 0; i < nbDispatchers; i++) { 5714 try { 5715 mModeDispatchers.getBroadcastItem(i).dispatchAudioModeChanged(mode); 5716 } catch (RemoteException e) { 5717 } 5718 } 5719 mModeDispatchers.finishBroadcast(); 5720 } 5721 5722 final RemoteCallbackList<IAudioModeDispatcher> mModeDispatchers = 5723 new RemoteCallbackList<IAudioModeDispatcher>(); 5724 5725 /** 5726 * @see {@link AudioManager#addOnModeChangedListener(Executor, AudioManager.OnModeChangedListener)} 5727 * @param dispatcher 5728 */ registerModeDispatcher( @onNull IAudioModeDispatcher dispatcher)5729 public void registerModeDispatcher( 5730 @NonNull IAudioModeDispatcher dispatcher) { 5731 mModeDispatchers.register(dispatcher); 5732 } 5733 5734 /** 5735 * @see {@link AudioManager#removeOnModeChangedListener(AudioManager.OnModeChangedListener)} 5736 * @param dispatcher 5737 */ unregisterModeDispatcher( @onNull IAudioModeDispatcher dispatcher)5738 public void unregisterModeDispatcher( 5739 @NonNull IAudioModeDispatcher dispatcher) { 5740 mModeDispatchers.unregister(dispatcher); 5741 } 5742 5743 /** @see AudioManager#isPstnCallAudioInterceptable() */ isPstnCallAudioInterceptable()5744 public boolean isPstnCallAudioInterceptable() { 5745 enforceCallAudioInterceptionPermission(); 5746 5747 boolean uplinkDeviceFound = false; 5748 boolean downlinkDeviceFound = false; 5749 AudioDeviceInfo[] devices = AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_ALL); 5750 for (AudioDeviceInfo device : devices) { 5751 if (device.getInternalType() == AudioSystem.DEVICE_OUT_TELEPHONY_TX) { 5752 uplinkDeviceFound = true; 5753 } else if (device.getInternalType() == AudioSystem.DEVICE_IN_TELEPHONY_RX) { 5754 downlinkDeviceFound = true; 5755 } 5756 if (uplinkDeviceFound && downlinkDeviceFound) { 5757 return true; 5758 } 5759 } 5760 return false; 5761 } 5762 5763 /** @see AudioManager#setRttEnabled() */ 5764 @Override setRttEnabled(boolean rttEnabled)5765 public void setRttEnabled(boolean rttEnabled) { 5766 if (mContext.checkCallingOrSelfPermission( 5767 android.Manifest.permission.MODIFY_PHONE_STATE) 5768 != PackageManager.PERMISSION_GRANTED) { 5769 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setRttEnabled from pid=" 5770 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 5771 return; 5772 } 5773 synchronized (mSettingsLock) { 5774 mRttEnabled = rttEnabled; 5775 final long identity = Binder.clearCallingIdentity(); 5776 try { 5777 AudioSystem.setRttEnabled(rttEnabled); 5778 } finally { 5779 Binder.restoreCallingIdentity(identity); 5780 } 5781 } 5782 } 5783 5784 /** @see AudioManager#adjustSuggestedStreamVolumeForUid(int, int, int, String, int, int, int) */ 5785 @Override adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)5786 public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, 5787 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 5788 int targetSdkVersion) { 5789 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 5790 throw new SecurityException("Should only be called from system process"); 5791 } 5792 5793 // direction and stream type swap here because the public 5794 // adjustSuggested has a different order than the other methods. 5795 adjustSuggestedStreamVolume(direction, streamType, flags, packageName, packageName, 5796 uid, pid, hasAudioSettingsPermission(uid, pid), 5797 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 5798 } 5799 5800 /** @see AudioManager#adjustStreamVolumeForUid(int, int, int, String, int, int, int) */ 5801 @Override adjustStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)5802 public void adjustStreamVolumeForUid(int streamType, int direction, int flags, 5803 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 5804 int targetSdkVersion) { 5805 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 5806 throw new SecurityException("Should only be called from system process"); 5807 } 5808 5809 if (direction != AudioManager.ADJUST_SAME) { 5810 sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType, 5811 direction/*val1*/, flags/*val2*/, 5812 new StringBuilder(packageName).append(" uid:").append(uid) 5813 .toString())); 5814 } 5815 5816 adjustStreamVolume(streamType, direction, flags, packageName, packageName, uid, pid, 5817 null, hasAudioSettingsPermission(uid, pid), 5818 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 5819 } 5820 5821 /** @see AudioManager#setStreamVolumeForUid(int, int, int, String, int, int, int) */ 5822 @Override setStreamVolumeForUid(int streamType, int index, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)5823 public void setStreamVolumeForUid(int streamType, int index, int flags, 5824 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 5825 int targetSdkVersion) { 5826 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 5827 throw new SecurityException("Should only be called from system process"); 5828 } 5829 5830 setStreamVolume(streamType, index, flags, /*device*/ null, 5831 packageName, packageName, null, uid, 5832 hasAudioSettingsPermission(uid, pid)); 5833 } 5834 5835 //========================================================================================== 5836 // Sound Effects 5837 //========================================================================================== 5838 private static final class LoadSoundEffectReply 5839 implements SoundEffectsHelper.OnEffectsLoadCompleteHandler { 5840 private static final int SOUND_EFFECTS_LOADING = 1; 5841 private static final int SOUND_EFFECTS_LOADED = 0; 5842 private static final int SOUND_EFFECTS_ERROR = -1; 5843 private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000; 5844 5845 private int mStatus = SOUND_EFFECTS_LOADING; 5846 5847 @Override run(boolean success)5848 public synchronized void run(boolean success) { 5849 mStatus = success ? SOUND_EFFECTS_LOADED : SOUND_EFFECTS_ERROR; 5850 notify(); 5851 } 5852 waitForLoaded(int attempts)5853 public synchronized boolean waitForLoaded(int attempts) { 5854 while ((mStatus == SOUND_EFFECTS_LOADING) && (attempts-- > 0)) { 5855 try { 5856 wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS); 5857 } catch (InterruptedException e) { 5858 Log.w(TAG, "Interrupted while waiting sound pool loaded."); 5859 } 5860 } 5861 return mStatus == SOUND_EFFECTS_LOADED; 5862 } 5863 } 5864 5865 /** @see AudioManager#playSoundEffect(int, int) */ playSoundEffect(int effectType, int userId)5866 public void playSoundEffect(int effectType, int userId) { 5867 if (querySoundEffectsEnabled(userId)) { 5868 playSoundEffectVolume(effectType, -1.0f); 5869 } 5870 } 5871 5872 /** 5873 * Settings has an in memory cache, so this is fast. 5874 */ querySoundEffectsEnabled(int user)5875 private boolean querySoundEffectsEnabled(int user) { 5876 return mSettings.getSystemIntForUser(getContentResolver(), 5877 Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0; 5878 } 5879 5880 /** @see AudioManager#playSoundEffect(int, float) */ playSoundEffectVolume(int effectType, float volume)5881 public void playSoundEffectVolume(int effectType, float volume) { 5882 // do not try to play the sound effect if the system stream is muted 5883 if (isStreamMute(STREAM_SYSTEM)) { 5884 return; 5885 } 5886 5887 if (effectType >= AudioManager.NUM_SOUND_EFFECTS || effectType < 0) { 5888 Log.w(TAG, "AudioService effectType value " + effectType + " out of range"); 5889 return; 5890 } 5891 5892 sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE, 5893 effectType, (int) (volume * 1000), null, 0); 5894 } 5895 5896 /** 5897 * Loads samples into the soundpool. 5898 * This method must be called at first when sound effects are enabled 5899 */ loadSoundEffects()5900 public boolean loadSoundEffects() { 5901 LoadSoundEffectReply reply = new LoadSoundEffectReply(); 5902 sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0); 5903 return reply.waitForLoaded(3 /*attempts*/); 5904 } 5905 5906 /** 5907 * Schedule loading samples into the soundpool. 5908 * This method can be overridden to schedule loading at a later time. 5909 */ scheduleLoadSoundEffects()5910 protected void scheduleLoadSoundEffects() { 5911 sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0); 5912 } 5913 5914 /** 5915 * Unloads samples from the sound pool. 5916 * This method can be called to free some memory when 5917 * sound effects are disabled. 5918 */ unloadSoundEffects()5919 public void unloadSoundEffects() { 5920 sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0); 5921 } 5922 5923 /** @see AudioManager#reloadAudioSettings() */ reloadAudioSettings()5924 public void reloadAudioSettings() { 5925 readAudioSettings(false /*userSwitch*/); 5926 } 5927 readAudioSettings(boolean userSwitch)5928 private void readAudioSettings(boolean userSwitch) { 5929 // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings 5930 readPersistedSettings(); 5931 readUserRestrictions(); 5932 5933 // restore volume settings 5934 int numStreamTypes = AudioSystem.getNumStreamTypes(); 5935 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 5936 VolumeStreamState streamState = mStreamStates[streamType]; 5937 5938 if (userSwitch && mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) { 5939 continue; 5940 } 5941 5942 streamState.readSettings(); 5943 synchronized (VolumeStreamState.class) { 5944 // unmute stream that was muted but is not affect by mute anymore 5945 if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) && 5946 !isStreamMutedByRingerOrZenMode(streamType)) || mUseFixedVolume)) { 5947 streamState.mIsMuted = false; 5948 } 5949 } 5950 } 5951 5952 readVolumeGroupsSettings(userSwitch); 5953 5954 // apply new ringer mode before checking volume for alias streams so that streams 5955 // muted by ringer mode have the correct volume 5956 setRingerModeInt(getRingerModeInternal(), false); 5957 5958 checkAllFixedVolumeDevices(); 5959 checkAllAliasStreamVolumes(); 5960 checkMuteAffectedStreams(); 5961 5962 synchronized (mSafeMediaVolumeStateLock) { 5963 mMusicActiveMs = MathUtils.constrain(mSettings.getSecureIntForUser(mContentResolver, 5964 Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS, 0, UserHandle.USER_CURRENT), 5965 0, UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX); 5966 if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) { 5967 enforceSafeMediaVolume(TAG); 5968 } 5969 } 5970 5971 if (DEBUG_VOL) { 5972 Log.d(TAG, "Restoring device volume behavior"); 5973 } 5974 restoreDeviceVolumeBehavior(); 5975 } 5976 5977 /** @see AudioManager#getAvailableCommunicationDevices(int) */ getAvailableCommunicationDeviceIds()5978 public int[] getAvailableCommunicationDeviceIds() { 5979 List<AudioDeviceInfo> commDevices = AudioDeviceBroker.getAvailableCommunicationDevices(); 5980 return commDevices.stream().mapToInt(AudioDeviceInfo::getId).toArray(); 5981 } 5982 5983 /** 5984 * @see AudioManager#setCommunicationDevice(int) 5985 * @see AudioManager#clearCommunicationDevice() 5986 */ setCommunicationDevice(IBinder cb, int portId)5987 public boolean setCommunicationDevice(IBinder cb, int portId) { 5988 final int uid = Binder.getCallingUid(); 5989 final int pid = Binder.getCallingPid(); 5990 5991 AudioDeviceInfo device = null; 5992 if (portId != 0) { 5993 device = AudioManager.getDeviceForPortId(portId, AudioManager.GET_DEVICES_OUTPUTS); 5994 if (device == null) { 5995 Log.w(TAG, "setCommunicationDevice: invalid portID " + portId); 5996 return false; 5997 } 5998 if (!AudioDeviceBroker.isValidCommunicationDevice(device)) { 5999 throw new IllegalArgumentException("invalid device type " + device.getType()); 6000 } 6001 } 6002 final String eventSource = new StringBuilder() 6003 .append(device == null ? "clearCommunicationDevice(" : "setCommunicationDevice(") 6004 .append(") from u/pid:").append(uid).append("/") 6005 .append(pid).toString(); 6006 6007 int deviceType = AudioSystem.DEVICE_OUT_DEFAULT; 6008 String deviceAddress = null; 6009 if (device != null) { 6010 deviceType = device.getPort().type(); 6011 deviceAddress = device.getAddress(); 6012 } else { 6013 AudioDeviceInfo curDevice = mDeviceBroker.getCommunicationDevice(); 6014 if (curDevice != null) { 6015 deviceType = curDevice.getPort().type(); 6016 deviceAddress = curDevice.getAddress(); 6017 } 6018 } 6019 // do not log metrics if clearing communication device while no communication device 6020 // was selected 6021 if (deviceType != AudioSystem.DEVICE_OUT_DEFAULT) { 6022 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 6023 + MediaMetrics.SEPARATOR + "setCommunicationDevice") 6024 .set(MediaMetrics.Property.DEVICE, 6025 AudioSystem.getDeviceName(deviceType)) 6026 .set(MediaMetrics.Property.ADDRESS, deviceAddress) 6027 .set(MediaMetrics.Property.STATE, device != null 6028 ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED) 6029 .record(); 6030 } 6031 6032 final long ident = Binder.clearCallingIdentity(); 6033 boolean status = 6034 mDeviceBroker.setCommunicationDevice(cb, pid, device, eventSource); 6035 Binder.restoreCallingIdentity(ident); 6036 return status; 6037 } 6038 6039 /** @see AudioManager#getCommunicationDevice() */ getCommunicationDevice()6040 public int getCommunicationDevice() { 6041 int deviceId = 0; 6042 final long ident = Binder.clearCallingIdentity(); 6043 try { 6044 AudioDeviceInfo device = mDeviceBroker.getCommunicationDevice(); 6045 deviceId = device != null ? device.getId() : 0; 6046 } finally { 6047 Binder.restoreCallingIdentity(ident); 6048 } 6049 return deviceId; 6050 } 6051 6052 /** @see AudioManager#addOnCommunicationDeviceChangedListener( 6053 * Executor, AudioManager.OnCommunicationDeviceChangedListener) 6054 */ registerCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)6055 public void registerCommunicationDeviceDispatcher( 6056 @Nullable ICommunicationDeviceDispatcher dispatcher) { 6057 if (dispatcher == null) { 6058 return; 6059 } 6060 mDeviceBroker.registerCommunicationDeviceDispatcher(dispatcher); 6061 } 6062 6063 /** @see AudioManager#removeOnCommunicationDeviceChangedListener( 6064 * AudioManager.OnCommunicationDeviceChangedListener) 6065 */ unregisterCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)6066 public void unregisterCommunicationDeviceDispatcher( 6067 @Nullable ICommunicationDeviceDispatcher dispatcher) { 6068 if (dispatcher == null) { 6069 return; 6070 } 6071 mDeviceBroker.unregisterCommunicationDeviceDispatcher(dispatcher); 6072 } 6073 6074 /** @see AudioManager#setSpeakerphoneOn(boolean) */ setSpeakerphoneOn(IBinder cb, boolean on)6075 public void setSpeakerphoneOn(IBinder cb, boolean on) { 6076 if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) { 6077 return; 6078 } 6079 6080 // for logging only 6081 final int uid = Binder.getCallingUid(); 6082 final int pid = Binder.getCallingPid(); 6083 6084 final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on) 6085 .append(") from u/pid:").append(uid).append("/") 6086 .append(pid).toString(); 6087 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 6088 + MediaMetrics.SEPARATOR + "setSpeakerphoneOn") 6089 .setUid(uid) 6090 .setPid(pid) 6091 .set(MediaMetrics.Property.STATE, on 6092 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 6093 .record(); 6094 final long ident = Binder.clearCallingIdentity(); 6095 mDeviceBroker.setSpeakerphoneOn(cb, pid, on, eventSource); 6096 Binder.restoreCallingIdentity(ident); 6097 } 6098 6099 /** @see AudioManager#isSpeakerphoneOn() */ isSpeakerphoneOn()6100 public boolean isSpeakerphoneOn() { 6101 return mDeviceBroker.isSpeakerphoneOn(); 6102 } 6103 6104 6105 /** BT SCO audio state seen by apps using the deprecated API setBluetoothScoOn(). 6106 * @see isBluetoothScoOn() */ 6107 private boolean mBtScoOnByApp; 6108 6109 /** @see AudioManager#setBluetoothScoOn(boolean) */ setBluetoothScoOn(boolean on)6110 public void setBluetoothScoOn(boolean on) { 6111 if (!checkAudioSettingsPermission("setBluetoothScoOn()")) { 6112 return; 6113 } 6114 6115 // Only enable calls from system components 6116 if (UserHandle.getCallingAppId() >= FIRST_APPLICATION_UID) { 6117 mBtScoOnByApp = on; 6118 return; 6119 } 6120 6121 // for logging only 6122 final int uid = Binder.getCallingUid(); 6123 final int pid = Binder.getCallingPid(); 6124 final String eventSource = new StringBuilder("setBluetoothScoOn(").append(on) 6125 .append(") from u/pid:").append(uid).append("/").append(pid).toString(); 6126 6127 //bt sco 6128 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 6129 + MediaMetrics.SEPARATOR + "setBluetoothScoOn") 6130 .setUid(uid) 6131 .setPid(pid) 6132 .set(MediaMetrics.Property.STATE, on 6133 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 6134 .record(); 6135 6136 mDeviceBroker.setBluetoothScoOn(on, eventSource); 6137 } 6138 6139 /** @see AudioManager#isBluetoothScoOn() 6140 * Note that it doesn't report internal state, but state seen by apps (which may have 6141 * called setBluetoothScoOn() */ isBluetoothScoOn()6142 public boolean isBluetoothScoOn() { 6143 return mBtScoOnByApp || mDeviceBroker.isBluetoothScoOn(); 6144 } 6145 6146 // TODO investigate internal users due to deprecation of SDK API 6147 /** @see AudioManager#setBluetoothA2dpOn(boolean) */ setBluetoothA2dpOn(boolean on)6148 public void setBluetoothA2dpOn(boolean on) { 6149 if (!checkAudioSettingsPermission("setBluetoothA2dpOn()")) { 6150 return; 6151 } 6152 6153 // for logging only 6154 final int uid = Binder.getCallingUid(); 6155 final int pid = Binder.getCallingPid(); 6156 final String eventSource = new StringBuilder("setBluetoothA2dpOn(").append(on) 6157 .append(") from u/pid:").append(uid).append("/") 6158 .append(pid).toString(); 6159 6160 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 6161 + MediaMetrics.SEPARATOR + "setBluetoothA2dpOn") 6162 .setUid(uid) 6163 .setPid(pid) 6164 .set(MediaMetrics.Property.STATE, on 6165 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 6166 .record(); 6167 6168 mDeviceBroker.setBluetoothA2dpOn_Async(on, eventSource); 6169 } 6170 6171 /** @see AudioManager#isBluetoothA2dpOn() */ isBluetoothA2dpOn()6172 public boolean isBluetoothA2dpOn() { 6173 return mDeviceBroker.isBluetoothA2dpOn(); 6174 } 6175 6176 /** @see AudioManager#startBluetoothSco() */ startBluetoothSco(IBinder cb, int targetSdkVersion)6177 public void startBluetoothSco(IBinder cb, int targetSdkVersion) { 6178 if (!checkAudioSettingsPermission("startBluetoothSco()")) { 6179 return; 6180 } 6181 6182 final int uid = Binder.getCallingUid(); 6183 final int pid = Binder.getCallingPid(); 6184 final int scoAudioMode = 6185 (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ? 6186 BtHelper.SCO_MODE_VIRTUAL_CALL : BtHelper.SCO_MODE_UNDEFINED; 6187 final String eventSource = new StringBuilder("startBluetoothSco()") 6188 .append(") from u/pid:").append(uid).append("/") 6189 .append(pid).toString(); 6190 6191 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 6192 .setUid(uid) 6193 .setPid(pid) 6194 .set(MediaMetrics.Property.EVENT, "startBluetoothSco") 6195 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 6196 BtHelper.scoAudioModeToString(scoAudioMode)) 6197 .record(); 6198 startBluetoothScoInt(cb, pid, scoAudioMode, eventSource); 6199 6200 } 6201 6202 /** @see AudioManager#startBluetoothScoVirtualCall() */ startBluetoothScoVirtualCall(IBinder cb)6203 public void startBluetoothScoVirtualCall(IBinder cb) { 6204 if (!checkAudioSettingsPermission("startBluetoothScoVirtualCall()")) { 6205 return; 6206 } 6207 6208 final int uid = Binder.getCallingUid(); 6209 final int pid = Binder.getCallingPid(); 6210 final String eventSource = new StringBuilder("startBluetoothScoVirtualCall()") 6211 .append(") from u/pid:").append(uid).append("/") 6212 .append(pid).toString(); 6213 6214 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 6215 .setUid(uid) 6216 .setPid(pid) 6217 .set(MediaMetrics.Property.EVENT, "startBluetoothScoVirtualCall") 6218 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 6219 BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_VIRTUAL_CALL)) 6220 .record(); 6221 startBluetoothScoInt(cb, pid, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource); 6222 } 6223 startBluetoothScoInt(IBinder cb, int pid, int scoAudioMode, @NonNull String eventSource)6224 void startBluetoothScoInt(IBinder cb, int pid, int scoAudioMode, @NonNull String eventSource) { 6225 MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 6226 .set(MediaMetrics.Property.EVENT, "startBluetoothScoInt") 6227 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 6228 BtHelper.scoAudioModeToString(scoAudioMode)); 6229 6230 if (!checkAudioSettingsPermission("startBluetoothSco()") || 6231 !mSystemReady) { 6232 mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission or systemReady").record(); 6233 return; 6234 } 6235 final long ident = Binder.clearCallingIdentity(); 6236 mDeviceBroker.startBluetoothScoForClient(cb, pid, scoAudioMode, eventSource); 6237 Binder.restoreCallingIdentity(ident); 6238 mmi.record(); 6239 } 6240 6241 /** @see AudioManager#stopBluetoothSco() */ stopBluetoothSco(IBinder cb)6242 public void stopBluetoothSco(IBinder cb){ 6243 if (!checkAudioSettingsPermission("stopBluetoothSco()") || 6244 !mSystemReady) { 6245 return; 6246 } 6247 final int uid = Binder.getCallingUid(); 6248 final int pid = Binder.getCallingPid(); 6249 final String eventSource = new StringBuilder("stopBluetoothSco()") 6250 .append(") from u/pid:").append(uid).append("/") 6251 .append(pid).toString(); 6252 final long ident = Binder.clearCallingIdentity(); 6253 mDeviceBroker.stopBluetoothScoForClient(cb, pid, eventSource); 6254 Binder.restoreCallingIdentity(ident); 6255 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 6256 .setUid(uid) 6257 .setPid(pid) 6258 .set(MediaMetrics.Property.EVENT, "stopBluetoothSco") 6259 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 6260 BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_UNDEFINED)) 6261 .record(); 6262 } 6263 6264 getContentResolver()6265 /*package*/ ContentResolver getContentResolver() { 6266 return mContentResolver; 6267 } 6268 scheduleMusicActiveCheck()6269 private void scheduleMusicActiveCheck() { 6270 synchronized (mSafeMediaVolumeStateLock) { 6271 cancelMusicActiveCheck(); 6272 mMusicActiveIntent = PendingIntent.getBroadcast(mContext, 6273 REQUEST_CODE_CHECK_MUSIC_ACTIVE, 6274 new Intent(ACTION_CHECK_MUSIC_ACTIVE), 6275 PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); 6276 mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, 6277 SystemClock.elapsedRealtime() 6278 + MUSIC_ACTIVE_POLL_PERIOD_MS, mMusicActiveIntent); 6279 } 6280 } 6281 cancelMusicActiveCheck()6282 private void cancelMusicActiveCheck() { 6283 synchronized (mSafeMediaVolumeStateLock) { 6284 if (mMusicActiveIntent != null) { 6285 mAlarmManager.cancel(mMusicActiveIntent); 6286 mMusicActiveIntent = null; 6287 } 6288 } 6289 } onCheckMusicActive(String caller)6290 private void onCheckMusicActive(String caller) { 6291 synchronized (mSafeMediaVolumeStateLock) { 6292 if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) { 6293 int device = getDeviceForStream(AudioSystem.STREAM_MUSIC); 6294 if (mSafeMediaVolumeDevices.contains(device) 6295 && mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)) { 6296 scheduleMusicActiveCheck(); 6297 int index = mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(device); 6298 if (index > safeMediaVolumeIndex(device)) { 6299 // Approximate cumulative active music time 6300 long curTimeMs = SystemClock.elapsedRealtime(); 6301 if (mLastMusicActiveTimeMs != 0) { 6302 mMusicActiveMs += (int) (curTimeMs - mLastMusicActiveTimeMs); 6303 } 6304 mLastMusicActiveTimeMs = curTimeMs; 6305 Log.i(TAG, "onCheckMusicActive() mMusicActiveMs: " + mMusicActiveMs); 6306 if (mMusicActiveMs > UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX) { 6307 setSafeMediaVolumeEnabled(true, caller); 6308 mMusicActiveMs = 0; 6309 } 6310 saveMusicActiveMs(); 6311 } 6312 } else { 6313 cancelMusicActiveCheck(); 6314 mLastMusicActiveTimeMs = 0; 6315 } 6316 } 6317 } 6318 } 6319 saveMusicActiveMs()6320 private void saveMusicActiveMs() { 6321 mAudioHandler.obtainMessage(MSG_PERSIST_MUSIC_ACTIVE_MS, mMusicActiveMs, 0).sendToTarget(); 6322 } 6323 getSafeUsbMediaVolumeIndex()6324 private int getSafeUsbMediaVolumeIndex() { 6325 // determine UI volume index corresponding to the wanted safe gain in dBFS 6326 int min = MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]; 6327 int max = MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]; 6328 6329 mSafeUsbMediaVolumeDbfs = mContext.getResources().getInteger( 6330 com.android.internal.R.integer.config_safe_media_volume_usb_mB) / 100.0f; 6331 6332 while (Math.abs(max - min) > 1) { 6333 int index = (max + min) / 2; 6334 float gainDB = AudioSystem.getStreamVolumeDB( 6335 AudioSystem.STREAM_MUSIC, index, AudioSystem.DEVICE_OUT_USB_HEADSET); 6336 if (Float.isNaN(gainDB)) { 6337 //keep last min in case of read error 6338 break; 6339 } else if (gainDB == mSafeUsbMediaVolumeDbfs) { 6340 min = index; 6341 break; 6342 } else if (gainDB < mSafeUsbMediaVolumeDbfs) { 6343 min = index; 6344 } else { 6345 max = index; 6346 } 6347 } 6348 return min * 10; 6349 } 6350 onConfigureSafeVolume(boolean force, String caller)6351 private void onConfigureSafeVolume(boolean force, String caller) { 6352 synchronized (mSafeMediaVolumeStateLock) { 6353 int mcc = mContext.getResources().getConfiguration().mcc; 6354 if ((mMcc != mcc) || ((mMcc == 0) && force)) { 6355 mSafeMediaVolumeIndex = mContext.getResources().getInteger( 6356 com.android.internal.R.integer.config_safe_media_volume_index) * 10; 6357 6358 mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex(); 6359 6360 boolean safeMediaVolumeEnabled = 6361 SystemProperties.getBoolean("audio.safemedia.force", false) 6362 || mContext.getResources().getBoolean( 6363 com.android.internal.R.bool.config_safe_media_volume_enabled); 6364 6365 boolean safeMediaVolumeBypass = 6366 SystemProperties.getBoolean("audio.safemedia.bypass", false); 6367 6368 // The persisted state is either "disabled" or "active": this is the state applied 6369 // next time we boot and cannot be "inactive" 6370 int persistedState; 6371 if (safeMediaVolumeEnabled && !safeMediaVolumeBypass) { 6372 persistedState = SAFE_MEDIA_VOLUME_ACTIVE; 6373 // The state can already be "inactive" here if the user has forced it before 6374 // the 30 seconds timeout for forced configuration. In this case we don't reset 6375 // it to "active". 6376 if (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_INACTIVE) { 6377 if (mMusicActiveMs == 0) { 6378 mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE; 6379 enforceSafeMediaVolume(caller); 6380 } else { 6381 // We have existing playback time recorded, already confirmed. 6382 mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE; 6383 mLastMusicActiveTimeMs = 0; 6384 } 6385 } 6386 } else { 6387 persistedState = SAFE_MEDIA_VOLUME_DISABLED; 6388 mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED; 6389 } 6390 mMcc = mcc; 6391 sendMsg(mAudioHandler, 6392 MSG_PERSIST_SAFE_VOLUME_STATE, 6393 SENDMSG_QUEUE, 6394 persistedState, 6395 0, 6396 null, 6397 0); 6398 } 6399 } 6400 } 6401 6402 /////////////////////////////////////////////////////////////////////////// 6403 // Internal methods 6404 /////////////////////////////////////////////////////////////////////////// 6405 6406 /** 6407 * Checks if the adjustment should change ringer mode instead of just 6408 * adjusting volume. If so, this will set the proper ringer mode and volume 6409 * indices on the stream states. 6410 */ checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, String caller, int flags)6411 private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, 6412 String caller, int flags) { 6413 int result = FLAG_ADJUST_VOLUME; 6414 if (isPlatformTelevision() || mIsSingleVolume) { 6415 return result; 6416 } 6417 6418 int ringerMode = getRingerModeInternal(); 6419 6420 switch (ringerMode) { 6421 case RINGER_MODE_NORMAL: 6422 if (direction == AudioManager.ADJUST_LOWER) { 6423 if (mHasVibrator) { 6424 // "step" is the delta in internal index units corresponding to a 6425 // change of 1 in UI index units. 6426 // Because of rounding when rescaling from one stream index range to its alias 6427 // index range, we cannot simply test oldIndex == step: 6428 // (step <= oldIndex < 2 * step) is equivalent to: (old UI index == 1) 6429 if (step <= oldIndex && oldIndex < 2 * step) { 6430 ringerMode = RINGER_MODE_VIBRATE; 6431 mLoweredFromNormalToVibrateTime = SystemClock.uptimeMillis(); 6432 } 6433 } else { 6434 if (oldIndex == step && mVolumePolicy.volumeDownToEnterSilent) { 6435 ringerMode = RINGER_MODE_SILENT; 6436 } 6437 } 6438 } else if (mIsSingleVolume && (direction == AudioManager.ADJUST_TOGGLE_MUTE 6439 || direction == AudioManager.ADJUST_MUTE)) { 6440 if (mHasVibrator) { 6441 ringerMode = RINGER_MODE_VIBRATE; 6442 } else { 6443 ringerMode = RINGER_MODE_SILENT; 6444 } 6445 // Setting the ringer mode will toggle mute 6446 result &= ~FLAG_ADJUST_VOLUME; 6447 } 6448 break; 6449 case RINGER_MODE_VIBRATE: 6450 if (!mHasVibrator) { 6451 Log.e(TAG, "checkForRingerModeChange() current ringer mode is vibrate" + 6452 "but no vibrator is present"); 6453 break; 6454 } 6455 if ((direction == AudioManager.ADJUST_LOWER)) { 6456 // This is the case we were muted with the volume turned up 6457 if (mIsSingleVolume && oldIndex >= 2 * step && isMuted) { 6458 ringerMode = RINGER_MODE_NORMAL; 6459 } else if (mPrevVolDirection != AudioManager.ADJUST_LOWER) { 6460 if (mVolumePolicy.volumeDownToEnterSilent) { 6461 final long diff = SystemClock.uptimeMillis() 6462 - mLoweredFromNormalToVibrateTime; 6463 if (diff > mVolumePolicy.vibrateToSilentDebounce 6464 && mRingerModeDelegate.canVolumeDownEnterSilent()) { 6465 ringerMode = RINGER_MODE_SILENT; 6466 } 6467 } else { 6468 result |= AudioManager.FLAG_SHOW_VIBRATE_HINT; 6469 } 6470 } 6471 } else if (direction == AudioManager.ADJUST_RAISE 6472 || direction == AudioManager.ADJUST_TOGGLE_MUTE 6473 || direction == AudioManager.ADJUST_UNMUTE) { 6474 ringerMode = RINGER_MODE_NORMAL; 6475 } 6476 result &= ~FLAG_ADJUST_VOLUME; 6477 break; 6478 case RINGER_MODE_SILENT: 6479 if (mIsSingleVolume && direction == AudioManager.ADJUST_LOWER && oldIndex >= 2 * step && isMuted) { 6480 // This is the case we were muted with the volume turned up 6481 ringerMode = RINGER_MODE_NORMAL; 6482 } else if (direction == AudioManager.ADJUST_RAISE 6483 || direction == AudioManager.ADJUST_TOGGLE_MUTE 6484 || direction == AudioManager.ADJUST_UNMUTE) { 6485 if (!mVolumePolicy.volumeUpToExitSilent) { 6486 result |= AudioManager.FLAG_SHOW_SILENT_HINT; 6487 } else { 6488 if (mHasVibrator && direction == AudioManager.ADJUST_RAISE) { 6489 ringerMode = RINGER_MODE_VIBRATE; 6490 } else { 6491 // If we don't have a vibrator or they were toggling mute 6492 // go straight back to normal. 6493 ringerMode = RINGER_MODE_NORMAL; 6494 } 6495 } 6496 } 6497 result &= ~FLAG_ADJUST_VOLUME; 6498 break; 6499 default: 6500 Log.e(TAG, "checkForRingerModeChange() wrong ringer mode: "+ringerMode); 6501 break; 6502 } 6503 6504 if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode) 6505 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller) 6506 && (flags & AudioManager.FLAG_FROM_KEY) == 0) { 6507 throw new SecurityException("Not allowed to change Do Not Disturb state"); 6508 } 6509 6510 setRingerMode(ringerMode, TAG + ".checkForRingerModeChange", false /*external*/); 6511 6512 mPrevVolDirection = direction; 6513 6514 return result; 6515 } 6516 6517 @Override isStreamAffectedByRingerMode(int streamType)6518 public boolean isStreamAffectedByRingerMode(int streamType) { 6519 return (mRingerModeAffectedStreams & (1 << streamType)) != 0; 6520 } 6521 shouldZenMuteStream(int streamType)6522 private boolean shouldZenMuteStream(int streamType) { 6523 if (mNm.getZenMode() != Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { 6524 return false; 6525 } 6526 6527 NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy(); 6528 final boolean muteAlarms = (zenPolicy.priorityCategories 6529 & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0; 6530 final boolean muteMedia = (zenPolicy.priorityCategories 6531 & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0; 6532 final boolean muteSystem = (zenPolicy.priorityCategories 6533 & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0; 6534 final boolean muteNotificationAndRing = ZenModeConfig 6535 .areAllPriorityOnlyRingerSoundsMuted(zenPolicy); 6536 return muteAlarms && isAlarm(streamType) 6537 || muteMedia && isMedia(streamType) 6538 || muteSystem && isSystem(streamType) 6539 || muteNotificationAndRing && isNotificationOrRinger(streamType); 6540 } 6541 isStreamMutedByRingerOrZenMode(int streamType)6542 private boolean isStreamMutedByRingerOrZenMode(int streamType) { 6543 return (mRingerAndZenModeMutedStreams & (1 << streamType)) != 0; 6544 } 6545 6546 /** 6547 * Notifications, ringer and system sounds are controlled by the ringer: 6548 * {@link ZenModeHelper.RingerModeDelegate#getRingerModeAffectedStreams(int)} but can 6549 * also be muted by DND based on the DND mode: 6550 * DND total silence: media and alarms streams can be muted by DND 6551 * DND alarms only: no streams additionally controlled by DND 6552 * DND priority only: alarms, media, system, ringer and notification streams can be muted by 6553 * DND. The current applied zenPolicy determines which streams will be muted by DND. 6554 * @return true if changed, else false 6555 */ updateZenModeAffectedStreams()6556 private boolean updateZenModeAffectedStreams() { 6557 if (!mSystemReady) { 6558 return false; 6559 } 6560 6561 int zenModeAffectedStreams = 0; 6562 final int zenMode = mNm.getZenMode(); 6563 6564 if (zenMode == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS) { 6565 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM; 6566 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC; 6567 } else if (zenMode == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { 6568 NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy(); 6569 if ((zenPolicy.priorityCategories 6570 & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0) { 6571 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM; 6572 } 6573 6574 if ((zenPolicy.priorityCategories 6575 & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0) { 6576 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC; 6577 } 6578 6579 // even if zen isn't muting the system stream, the ringer mode can still mute 6580 // the system stream 6581 if ((zenPolicy.priorityCategories 6582 & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) { 6583 zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM; 6584 } 6585 6586 if (ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(zenPolicy)) { 6587 zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION; 6588 zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING; 6589 } 6590 } 6591 6592 if (mZenModeAffectedStreams != zenModeAffectedStreams) { 6593 mZenModeAffectedStreams = zenModeAffectedStreams; 6594 return true; 6595 } 6596 6597 return false; 6598 } 6599 6600 @GuardedBy("mSettingsLock") updateRingerAndZenModeAffectedStreams()6601 private boolean updateRingerAndZenModeAffectedStreams() { 6602 boolean updatedZenModeAffectedStreams = updateZenModeAffectedStreams(); 6603 int ringerModeAffectedStreams = mSettings.getSystemIntForUser(mContentResolver, 6604 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 6605 ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)| 6606 (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)), 6607 UserHandle.USER_CURRENT); 6608 6609 if (mIsSingleVolume) { 6610 ringerModeAffectedStreams = 0; 6611 } else if (mRingerModeDelegate != null) { 6612 ringerModeAffectedStreams = mRingerModeDelegate 6613 .getRingerModeAffectedStreams(ringerModeAffectedStreams); 6614 } 6615 if (mCameraSoundForced) { 6616 ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 6617 } else { 6618 ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 6619 } 6620 if (mStreamVolumeAlias[AudioSystem.STREAM_DTMF] == AudioSystem.STREAM_RING) { 6621 ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF); 6622 } else { 6623 ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF); 6624 } 6625 6626 if (ringerModeAffectedStreams != mRingerModeAffectedStreams) { 6627 mSettings.putSystemIntForUser(mContentResolver, 6628 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 6629 ringerModeAffectedStreams, 6630 UserHandle.USER_CURRENT); 6631 mRingerModeAffectedStreams = ringerModeAffectedStreams; 6632 return true; 6633 } 6634 return updatedZenModeAffectedStreams; 6635 } 6636 6637 @Override isStreamAffectedByMute(int streamType)6638 public boolean isStreamAffectedByMute(int streamType) { 6639 return (mMuteAffectedStreams & (1 << streamType)) != 0; 6640 } 6641 ensureValidDirection(int direction)6642 private void ensureValidDirection(int direction) { 6643 switch (direction) { 6644 case AudioManager.ADJUST_LOWER: 6645 case AudioManager.ADJUST_RAISE: 6646 case AudioManager.ADJUST_SAME: 6647 case AudioManager.ADJUST_MUTE: 6648 case AudioManager.ADJUST_UNMUTE: 6649 case AudioManager.ADJUST_TOGGLE_MUTE: 6650 break; 6651 default: 6652 throw new IllegalArgumentException("Bad direction " + direction); 6653 } 6654 } 6655 ensureValidStreamType(int streamType)6656 private void ensureValidStreamType(int streamType) { 6657 if (streamType < 0 || streamType >= mStreamStates.length) { 6658 throw new IllegalArgumentException("Bad stream type " + streamType); 6659 } 6660 } 6661 isMuteAdjust(int adjust)6662 private boolean isMuteAdjust(int adjust) { 6663 return adjust == AudioManager.ADJUST_MUTE || adjust == AudioManager.ADJUST_UNMUTE 6664 || adjust == AudioManager.ADJUST_TOGGLE_MUTE; 6665 } 6666 6667 /** only public for mocking/spying, do not call outside of AudioService */ 6668 @VisibleForTesting isInCommunication()6669 public boolean isInCommunication() { 6670 boolean IsInCall = false; 6671 6672 TelecomManager telecomManager = 6673 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 6674 6675 final long ident = Binder.clearCallingIdentity(); 6676 IsInCall = telecomManager.isInCall(); 6677 Binder.restoreCallingIdentity(ident); 6678 6679 int mode = mMode.get(); 6680 return (IsInCall 6681 || mode == AudioManager.MODE_IN_COMMUNICATION 6682 || mode == AudioManager.MODE_IN_CALL); 6683 } 6684 6685 /** 6686 * For code clarity for getActiveStreamType(int) 6687 * @param delay_ms max time since last stream activity to consider 6688 * @return true if stream is active in streams handled by AudioFlinger now or 6689 * in the last "delay_ms" ms. 6690 */ wasStreamActiveRecently(int stream, int delay_ms)6691 private boolean wasStreamActiveRecently(int stream, int delay_ms) { 6692 return mAudioSystem.isStreamActive(stream, delay_ms) 6693 || mAudioSystem.isStreamActiveRemotely(stream, delay_ms); 6694 } 6695 getActiveStreamType(int suggestedStreamType)6696 private int getActiveStreamType(int suggestedStreamType) { 6697 if (mIsSingleVolume 6698 && suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 6699 return AudioSystem.STREAM_MUSIC; 6700 } 6701 6702 switch (mPlatformType) { 6703 case AudioSystem.PLATFORM_VOICE: 6704 if (isInCommunication()) { 6705 if (mDeviceBroker.isBluetoothScoActive()) { 6706 // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO..."); 6707 return AudioSystem.STREAM_BLUETOOTH_SCO; 6708 } else { 6709 // Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL..."); 6710 return AudioSystem.STREAM_VOICE_CALL; 6711 } 6712 } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 6713 if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 6714 if (DEBUG_VOL) 6715 Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active"); 6716 return AudioSystem.STREAM_RING; 6717 } else if (wasStreamActiveRecently( 6718 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 6719 if (DEBUG_VOL) 6720 Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active"); 6721 return AudioSystem.STREAM_NOTIFICATION; 6722 } else { 6723 if (DEBUG_VOL) { 6724 Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK(" 6725 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default"); 6726 } 6727 return DEFAULT_VOL_STREAM_NO_PLAYBACK; 6728 } 6729 } else if ( 6730 wasStreamActiveRecently(AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 6731 if (DEBUG_VOL) 6732 Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active"); 6733 return AudioSystem.STREAM_NOTIFICATION; 6734 } else if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 6735 if (DEBUG_VOL) 6736 Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active"); 6737 return AudioSystem.STREAM_RING; 6738 } 6739 default: 6740 if (isInCommunication()) { 6741 if (mDeviceBroker.isBluetoothScoActive()) { 6742 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO"); 6743 return AudioSystem.STREAM_BLUETOOTH_SCO; 6744 } else { 6745 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL"); 6746 return AudioSystem.STREAM_VOICE_CALL; 6747 } 6748 } else if (mAudioSystem.isStreamActive( 6749 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 6750 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION"); 6751 return AudioSystem.STREAM_NOTIFICATION; 6752 } else if (mAudioSystem.isStreamActive( 6753 AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 6754 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING"); 6755 return AudioSystem.STREAM_RING; 6756 } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 6757 if (mAudioSystem.isStreamActive( 6758 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 6759 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION"); 6760 return AudioSystem.STREAM_NOTIFICATION; 6761 } 6762 if (mAudioSystem.isStreamActive( 6763 AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 6764 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING"); 6765 return AudioSystem.STREAM_RING; 6766 } 6767 if (DEBUG_VOL) { 6768 Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK(" 6769 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default"); 6770 } 6771 return DEFAULT_VOL_STREAM_NO_PLAYBACK; 6772 } 6773 break; 6774 } 6775 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Returning suggested type " 6776 + suggestedStreamType); 6777 return suggestedStreamType; 6778 } 6779 broadcastRingerMode(String action, int ringerMode)6780 private void broadcastRingerMode(String action, int ringerMode) { 6781 if (!mSystemServer.isPrivileged()) { 6782 return; 6783 } 6784 // Send sticky broadcast 6785 Intent broadcast = new Intent(action); 6786 broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, ringerMode); 6787 broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 6788 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 6789 sendStickyBroadcastToAll(broadcast); 6790 } 6791 broadcastVibrateSetting(int vibrateType)6792 private void broadcastVibrateSetting(int vibrateType) { 6793 if (!mSystemServer.isPrivileged()) { 6794 return; 6795 } 6796 // Send broadcast 6797 if (mActivityManagerInternal.isSystemReady()) { 6798 Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION); 6799 broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType); 6800 broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType)); 6801 sendBroadcastToAll(broadcast); 6802 } 6803 } 6804 6805 // Message helper methods 6806 /** 6807 * Queue a message on the given handler's message queue, after acquiring the service wake lock. 6808 * Note that the wake lock needs to be released after the message has been handled. 6809 */ queueMsgUnderWakeLock(Handler handler, int msg, int arg1, int arg2, Object obj, int delay)6810 private void queueMsgUnderWakeLock(Handler handler, int msg, 6811 int arg1, int arg2, Object obj, int delay) { 6812 final long ident = Binder.clearCallingIdentity(); 6813 // Always acquire the wake lock as AudioService because it is released by the 6814 // message handler. 6815 mAudioEventWakeLock.acquire(); 6816 Binder.restoreCallingIdentity(ident); 6817 sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay); 6818 } 6819 sendMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, int delay)6820 private static void sendMsg(Handler handler, int msg, 6821 int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) { 6822 if (existingMsgPolicy == SENDMSG_REPLACE) { 6823 handler.removeMessages(msg); 6824 } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) { 6825 return; 6826 } 6827 6828 final long time = SystemClock.uptimeMillis() + delay; 6829 handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time); 6830 } 6831 checkAudioSettingsPermission(String method)6832 boolean checkAudioSettingsPermission(String method) { 6833 if (callingOrSelfHasAudioSettingsPermission()) { 6834 return true; 6835 } 6836 String msg = "Audio Settings Permission Denial: " + method + " from pid=" 6837 + Binder.getCallingPid() 6838 + ", uid=" + Binder.getCallingUid(); 6839 Log.w(TAG, msg); 6840 return false; 6841 } 6842 callingOrSelfHasAudioSettingsPermission()6843 private boolean callingOrSelfHasAudioSettingsPermission() { 6844 return mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS) 6845 == PackageManager.PERMISSION_GRANTED; 6846 } 6847 callingHasAudioSettingsPermission()6848 private boolean callingHasAudioSettingsPermission() { 6849 return mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS) 6850 == PackageManager.PERMISSION_GRANTED; 6851 } 6852 hasAudioSettingsPermission(int uid, int pid)6853 private boolean hasAudioSettingsPermission(int uid, int pid) { 6854 return mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid) 6855 == PackageManager.PERMISSION_GRANTED; 6856 } 6857 6858 /** 6859 * Minimum attenuation that can be set for alarms over speaker by an application that 6860 * doesn't have the MODIFY_AUDIO_SETTINGS permission. 6861 */ 6862 protected static final float MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB = -36.0f; 6863 6864 /** 6865 * Configures the VolumeStreamState instances for minimum stream index that can be accessed 6866 * without MODIFY_AUDIO_SETTINGS permission. 6867 * Can only be done successfully once audio policy has finished reading its configuration files 6868 * for the volume curves. If not, getStreamVolumeDB will return NaN, and the min value will 6869 * remain at the stream min index value. 6870 */ initMinStreamVolumeWithoutModifyAudioSettings()6871 protected void initMinStreamVolumeWithoutModifyAudioSettings() { 6872 int idx; 6873 int deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER_SAFE; 6874 if (Float.isNaN(AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, 6875 MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM], deviceForAlarm))) { 6876 deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER; 6877 } 6878 for (idx = MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; 6879 idx >= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; idx--) { 6880 if (AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, idx, deviceForAlarm) 6881 < MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB) { 6882 break; 6883 } 6884 } 6885 final int safeIndex = idx <= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM] 6886 ? MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM] 6887 : Math.min(idx + 1, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]); 6888 // update the VolumeStreamState for STREAM_ALARM and its aliases 6889 for (int stream : mStreamVolumeAlias) { 6890 if (mStreamVolumeAlias[stream] == AudioSystem.STREAM_ALARM) { 6891 mStreamStates[stream].updateNoPermMinIndex(safeIndex); 6892 } 6893 } 6894 } 6895 6896 /** 6897 * Returns device associated with the stream volume. 6898 * 6899 * Only public for mocking/spying, do not call outside of AudioService. 6900 * Device volume aliasing means DEVICE_OUT_SPEAKER may be returned for 6901 * DEVICE_OUT_SPEAKER_SAFE. 6902 */ 6903 @VisibleForTesting getDeviceForStream(int stream)6904 public int getDeviceForStream(int stream) { 6905 return selectOneAudioDevice(getDeviceSetForStream(stream)); 6906 } 6907 6908 /* 6909 * Must match native apm_extract_one_audio_device() used in getDeviceForVolume() 6910 * or the wrong device volume may be adjusted. 6911 */ selectOneAudioDevice(Set<Integer> deviceSet)6912 private int selectOneAudioDevice(Set<Integer> deviceSet) { 6913 if (deviceSet.isEmpty()) { 6914 return AudioSystem.DEVICE_NONE; 6915 } else if (deviceSet.size() == 1) { 6916 return deviceSet.iterator().next(); 6917 } else { 6918 // Multiple device selection is either: 6919 // - speaker + one other device: give priority to speaker in this case. 6920 // - one A2DP device + another device: happens with duplicated output. In this case 6921 // retain the device on the A2DP output as the other must not correspond to an active 6922 // selection if not the speaker. 6923 // - HDMI-CEC system audio mode only output: give priority to available item in order. 6924 6925 if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER)) { 6926 return AudioSystem.DEVICE_OUT_SPEAKER; 6927 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER_SAFE)) { 6928 // Note: DEVICE_OUT_SPEAKER_SAFE not present in getDeviceSetForStreamDirect 6929 return AudioSystem.DEVICE_OUT_SPEAKER_SAFE; 6930 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_ARC)) { 6931 return AudioSystem.DEVICE_OUT_HDMI_ARC; 6932 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_EARC)) { 6933 return AudioSystem.DEVICE_OUT_HDMI_EARC; 6934 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_AUX_LINE)) { 6935 return AudioSystem.DEVICE_OUT_AUX_LINE; 6936 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPDIF)) { 6937 return AudioSystem.DEVICE_OUT_SPDIF; 6938 } else { 6939 // At this point, deviceSet should contain exactly one A2DP device; 6940 // regardless, return the first A2DP device in numeric order. 6941 // If there is no A2DP device, this falls through to log an error. 6942 for (int deviceType : deviceSet) { 6943 if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType)) { 6944 return deviceType; 6945 } 6946 } 6947 } 6948 } 6949 Log.w(TAG, "selectOneAudioDevice returning DEVICE_NONE from invalid device combination " 6950 + AudioSystem.deviceSetToString(deviceSet)); 6951 return AudioSystem.DEVICE_NONE; 6952 } 6953 6954 /** 6955 * @see AudioManager#getDevicesForStream(int) 6956 * @deprecated on {@link android.os.Build.VERSION_CODES#T} as new devices 6957 * will have multi-bit device types since S. 6958 * Use {@link #getDevicesForAttributes()} instead. 6959 */ 6960 @Override 6961 @Deprecated getDeviceMaskForStream(int streamType)6962 public int getDeviceMaskForStream(int streamType) { 6963 ensureValidStreamType(streamType); 6964 // no permission required 6965 final long token = Binder.clearCallingIdentity(); 6966 try { 6967 return AudioSystem.getDeviceMaskFromSet( 6968 getDeviceSetForStreamDirect(streamType)); 6969 } finally { 6970 Binder.restoreCallingIdentity(token); 6971 } 6972 } 6973 6974 /** 6975 * Returns the devices associated with a stream type. 6976 * 6977 * SPEAKER_SAFE will alias to SPEAKER. 6978 */ 6979 @NonNull getDeviceSetForStreamDirect(int stream)6980 private Set<Integer> getDeviceSetForStreamDirect(int stream) { 6981 final AudioAttributes attr = 6982 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream); 6983 Set<Integer> deviceSet = 6984 AudioSystem.generateAudioDeviceTypesSet( 6985 getDevicesForAttributesInt(attr, true /* forVolume */)); 6986 return deviceSet; 6987 } 6988 6989 /** 6990 * Returns a reference to the list of devices for the stream, do not modify. 6991 * 6992 * The device returned may be aliased to the actual device whose volume curve 6993 * will be used. For example DEVICE_OUT_SPEAKER_SAFE aliases to DEVICE_OUT_SPEAKER. 6994 */ 6995 @NonNull getDeviceSetForStream(int stream)6996 public Set<Integer> getDeviceSetForStream(int stream) { 6997 ensureValidStreamType(stream); 6998 synchronized (VolumeStreamState.class) { 6999 return mStreamStates[stream].observeDevicesForStream_syncVSS(true); 7000 } 7001 } 7002 onObserveDevicesForAllStreams(int skipStream)7003 private void onObserveDevicesForAllStreams(int skipStream) { 7004 synchronized (mSettingsLock) { 7005 synchronized (VolumeStreamState.class) { 7006 for (int stream = 0; stream < mStreamStates.length; stream++) { 7007 if (stream != skipStream) { 7008 Set<Integer> deviceSet = 7009 mStreamStates[stream].observeDevicesForStream_syncVSS( 7010 false /*checkOthers*/); 7011 for (Integer device : deviceSet) { 7012 // Update volume states for devices routed for the stream 7013 updateVolumeStates(device, stream, 7014 "AudioService#onObserveDevicesForAllStreams"); 7015 } 7016 } 7017 } 7018 } 7019 } 7020 } 7021 7022 /** only public for mocking/spying, do not call outside of AudioService */ 7023 @VisibleForTesting postObserveDevicesForAllStreams()7024 public void postObserveDevicesForAllStreams() { 7025 postObserveDevicesForAllStreams(-1); 7026 } 7027 7028 /** only public for mocking/spying, do not call outside of AudioService */ 7029 @VisibleForTesting postObserveDevicesForAllStreams(int skipStream)7030 public void postObserveDevicesForAllStreams(int skipStream) { 7031 sendMsg(mAudioHandler, 7032 MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS, 7033 SENDMSG_QUEUE, skipStream /*arg1*/, 0 /*arg2*/, null /*obj*/, 7034 0 /*delay*/); 7035 } 7036 7037 /** 7038 * @see AudioDeviceVolumeManager#setDeviceAbsoluteMultiVolumeBehavior 7039 * 7040 * @param register Whether the listener is to be registered or unregistered. If false, the 7041 * device adopts variable volume behavior. 7042 */ 7043 @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING, 7044 android.Manifest.permission.BLUETOOTH_PRIVILEGED }) registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register, IAudioDeviceVolumeDispatcher cb, String packageName, AudioDeviceAttributes device, List<VolumeInfo> volumes, boolean handlesVolumeAdjustment)7045 public void registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register, 7046 IAudioDeviceVolumeDispatcher cb, String packageName, 7047 AudioDeviceAttributes device, List<VolumeInfo> volumes, 7048 boolean handlesVolumeAdjustment) { 7049 // verify permissions 7050 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 7051 != PackageManager.PERMISSION_GRANTED 7052 && mContext.checkCallingOrSelfPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) 7053 != PackageManager.PERMISSION_GRANTED) { 7054 throw new SecurityException( 7055 "Missing MODIFY_AUDIO_ROUTING or BLUETOOTH_PRIVILEGED permissions"); 7056 } 7057 // verify arguments 7058 Objects.requireNonNull(device); 7059 Objects.requireNonNull(volumes); 7060 7061 int deviceOut = device.getInternalType(); 7062 if (register) { 7063 AbsoluteVolumeDeviceInfo info = new AbsoluteVolumeDeviceInfo( 7064 device, volumes, cb, handlesVolumeAdjustment); 7065 boolean volumeBehaviorChanged = 7066 removeAudioSystemDeviceOutFromFullVolumeDevices(deviceOut) 7067 | removeAudioSystemDeviceOutFromFixedVolumeDevices(deviceOut) 7068 | (addAudioSystemDeviceOutToAbsVolumeDevices(deviceOut, info) == null); 7069 if (volumeBehaviorChanged) { 7070 dispatchDeviceVolumeBehavior(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE); 7071 } 7072 // Update stream volumes to the given device, if specified in a VolumeInfo. 7073 // Mute state is not updated because it is stream-wide - the only way to mute a 7074 // stream's output to a particular device is to set the volume index to zero. 7075 for (VolumeInfo volumeInfo : volumes) { 7076 if (volumeInfo.getVolumeIndex() != VolumeInfo.INDEX_NOT_SET 7077 && volumeInfo.getMinVolumeIndex() != VolumeInfo.INDEX_NOT_SET 7078 && volumeInfo.getMaxVolumeIndex() != VolumeInfo.INDEX_NOT_SET) { 7079 if (volumeInfo.hasStreamType()) { 7080 setStreamVolumeInt(volumeInfo.getStreamType(), 7081 rescaleIndex(volumeInfo, volumeInfo.getStreamType()), 7082 deviceOut, false /*force*/, packageName, 7083 true /*hasModifyAudioSettings*/); 7084 } else { 7085 for (int streamType : volumeInfo.getVolumeGroup().getLegacyStreamTypes()) { 7086 setStreamVolumeInt(streamType, rescaleIndex(volumeInfo, streamType), 7087 deviceOut, false /*force*/, packageName, 7088 true /*hasModifyAudioSettings*/); 7089 } 7090 } 7091 } 7092 } 7093 } else { 7094 boolean wasAbsVol = removeAudioSystemDeviceOutFromAbsVolumeDevices(deviceOut) != null; 7095 if (wasAbsVol) { 7096 dispatchDeviceVolumeBehavior(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE); 7097 } 7098 } 7099 } 7100 7101 /** 7102 * @see AudioManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int) 7103 * @param device the audio device to be affected 7104 * @param deviceVolumeBehavior one of the device behaviors 7105 */ setDeviceVolumeBehavior(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName)7106 public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device, 7107 @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName) { 7108 // verify permissions 7109 enforceModifyAudioRoutingPermission(); 7110 // verify arguments 7111 Objects.requireNonNull(device); 7112 AudioManager.enforceValidVolumeBehavior(deviceVolumeBehavior); 7113 sVolumeLogger.log(new AudioEventLogger.StringEvent("setDeviceVolumeBehavior: dev:" 7114 + AudioSystem.getOutputDeviceName(device.getInternalType()) + " addr:" 7115 + device.getAddress() + " behavior:" 7116 + AudioDeviceVolumeManager.volumeBehaviorName(deviceVolumeBehavior) 7117 + " pack:" + pkgName).printLog(TAG)); 7118 if (pkgName == null) { 7119 pkgName = ""; 7120 } 7121 if (device.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP) { 7122 avrcpSupportsAbsoluteVolume(device.getAddress(), 7123 deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE); 7124 return; 7125 } 7126 7127 setDeviceVolumeBehaviorInternal(device, deviceVolumeBehavior, pkgName); 7128 persistDeviceVolumeBehavior(device.getInternalType(), deviceVolumeBehavior); 7129 } 7130 setDeviceVolumeBehaviorInternal(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller)7131 private void setDeviceVolumeBehaviorInternal(@NonNull AudioDeviceAttributes device, 7132 @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller) { 7133 int audioSystemDeviceOut = device.getInternalType(); 7134 boolean volumeBehaviorChanged = false; 7135 // update device masks based on volume behavior 7136 switch (deviceVolumeBehavior) { 7137 case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE: 7138 volumeBehaviorChanged |= 7139 removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut) 7140 | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut) 7141 | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut) 7142 != null); 7143 break; 7144 case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED: 7145 volumeBehaviorChanged |= 7146 removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut) 7147 | addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut) 7148 | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut) 7149 != null); 7150 break; 7151 case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL: 7152 volumeBehaviorChanged |= 7153 addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut) 7154 | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut) 7155 | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut) 7156 != null); 7157 break; 7158 case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE: 7159 case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE: 7160 throw new IllegalArgumentException("Absolute volume unsupported for now"); 7161 } 7162 7163 if (volumeBehaviorChanged) { 7164 sendMsg(mAudioHandler, MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR, SENDMSG_QUEUE, 7165 deviceVolumeBehavior, 0, device, /*delay*/ 0); 7166 } 7167 7168 // log event and caller 7169 sDeviceLogger.log(new AudioEventLogger.StringEvent( 7170 "Volume behavior " + deviceVolumeBehavior + " for dev=0x" 7171 + Integer.toHexString(audioSystemDeviceOut) + " from:" + caller)); 7172 // make sure we have a volume entry for this device, and that volume is updated according 7173 // to volume behavior 7174 postUpdateVolumeStatesForAudioDevice(audioSystemDeviceOut, 7175 "setDeviceVolumeBehavior:" + caller); 7176 } 7177 7178 /** 7179 * @see AudioManager#getDeviceVolumeBehavior(AudioDeviceAttributes) 7180 * @param device the audio output device type 7181 * @return the volume behavior for the device 7182 */ 7183 public @AudioManager.DeviceVolumeBehavior getDeviceVolumeBehavior(@onNull AudioDeviceAttributes device)7184 int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) { 7185 Objects.requireNonNull(device); 7186 // verify permissions 7187 enforceQueryStateOrModifyRoutingPermission(); 7188 7189 return getDeviceVolumeBehaviorInt(device); 7190 } 7191 7192 private @AudioManager.DeviceVolumeBehavior getDeviceVolumeBehaviorInt(@onNull AudioDeviceAttributes device)7193 int getDeviceVolumeBehaviorInt(@NonNull AudioDeviceAttributes device) { 7194 // Get the internal type set by the AudioDeviceAttributes constructor which is always more 7195 // exact (avoids double conversions) than a conversion from SDK type via 7196 // AudioDeviceInfo.convertDeviceTypeToInternalDevice() 7197 final int audioSystemDeviceOut = device.getInternalType(); 7198 7199 int setDeviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut); 7200 if (setDeviceVolumeBehavior != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) { 7201 return setDeviceVolumeBehavior; 7202 } 7203 7204 // setDeviceVolumeBehavior has not been explicitly called for the device type. Deduce the 7205 // current volume behavior. 7206 if (mFullVolumeDevices.contains(audioSystemDeviceOut)) { 7207 return AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL; 7208 } 7209 if (mFixedVolumeDevices.contains(audioSystemDeviceOut)) { 7210 return AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED; 7211 } 7212 if (mAbsVolumeMultiModeCaseDevices.contains(audioSystemDeviceOut)) { 7213 return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE; 7214 } 7215 if (isAbsoluteVolumeDevice(audioSystemDeviceOut) 7216 || isA2dpAbsoluteVolumeDevice(audioSystemDeviceOut) 7217 || AudioSystem.isLeAudioDeviceType(audioSystemDeviceOut)) { 7218 return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE; 7219 } 7220 return AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE; 7221 } 7222 7223 /** 7224 * @see AudioManager#isVolumeFixed() 7225 * Note there are no permission checks on this operation, as this is part of API 21 7226 * @return true if the current device's volume behavior for media is 7227 * DEVICE_VOLUME_BEHAVIOR_FIXED 7228 */ isVolumeFixed()7229 public boolean isVolumeFixed() { 7230 if (mUseFixedVolume) { 7231 return true; 7232 } 7233 final AudioAttributes attributes = new AudioAttributes.Builder() 7234 .setUsage(AudioAttributes.USAGE_MEDIA) 7235 .build(); 7236 // calling getDevice*Int to bypass permission check 7237 final List<AudioDeviceAttributes> devices = 7238 getDevicesForAttributesInt(attributes, true /* forVolume */); 7239 for (AudioDeviceAttributes device : devices) { 7240 if (getDeviceVolumeBehaviorInt(device) == AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED) { 7241 return true; 7242 } 7243 } 7244 return false; 7245 } 7246 7247 /*package*/ static final int CONNECTION_STATE_DISCONNECTED = 0; 7248 /*package*/ static final int CONNECTION_STATE_CONNECTED = 1; 7249 /** 7250 * The states that can be used with AudioService.setWiredDeviceConnectionState() 7251 * Attention: those values differ from those in BluetoothProfile, follow annotations to 7252 * distinguish between @ConnectionState and @BtProfileConnectionState 7253 */ 7254 @IntDef({ 7255 CONNECTION_STATE_DISCONNECTED, 7256 CONNECTION_STATE_CONNECTED, 7257 }) 7258 @Retention(RetentionPolicy.SOURCE) 7259 public @interface ConnectionState {} 7260 7261 /** 7262 * see AudioManager.setWiredDeviceConnectionState() 7263 */ setWiredDeviceConnectionState(AudioDeviceAttributes attributes, @ConnectionState int state, String caller)7264 public void setWiredDeviceConnectionState(AudioDeviceAttributes attributes, 7265 @ConnectionState int state, String caller) { 7266 enforceModifyAudioRoutingPermission(); 7267 if (state != CONNECTION_STATE_CONNECTED 7268 && state != CONNECTION_STATE_DISCONNECTED) { 7269 throw new IllegalArgumentException("Invalid state " + state); 7270 } 7271 new MediaMetrics.Item(mMetricsId + "setWiredDeviceConnectionState") 7272 .set(MediaMetrics.Property.ADDRESS, attributes.getAddress()) 7273 .set(MediaMetrics.Property.CLIENT_NAME, caller) 7274 .set(MediaMetrics.Property.DEVICE, 7275 AudioSystem.getDeviceName(attributes.getInternalType())) 7276 .set(MediaMetrics.Property.NAME, attributes.getName()) 7277 .set(MediaMetrics.Property.STATE, 7278 state == CONNECTION_STATE_CONNECTED ? "connected" : "disconnected") 7279 .record(); 7280 mDeviceBroker.setWiredDeviceConnectionState(attributes, state, caller); 7281 } 7282 7283 /** @see AudioManager#setTestDeviceConnectionState(AudioDeviceAttributes, boolean) */ setTestDeviceConnectionState(@onNull AudioDeviceAttributes device, boolean connected)7284 public void setTestDeviceConnectionState(@NonNull AudioDeviceAttributes device, 7285 boolean connected) { 7286 Objects.requireNonNull(device); 7287 enforceModifyAudioRoutingPermission(); 7288 mDeviceBroker.setTestDeviceConnectionState(device, 7289 connected ? CONNECTION_STATE_CONNECTED : CONNECTION_STATE_DISCONNECTED); 7290 // simulate a routing update from native 7291 sendMsg(mAudioHandler, 7292 MSG_ROUTING_UPDATED, 7293 SENDMSG_REPLACE, 0, 0, null, 7294 /*delay*/ 0); 7295 } 7296 7297 /** 7298 * @hide 7299 * The states that can be used with AudioService.setBluetoothHearingAidDeviceConnectionState() 7300 * and AudioService.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent() 7301 */ 7302 @IntDef({ 7303 BluetoothProfile.STATE_DISCONNECTED, 7304 BluetoothProfile.STATE_CONNECTED, 7305 }) 7306 @Retention(RetentionPolicy.SOURCE) 7307 public @interface BtProfileConnectionState {} 7308 7309 /** 7310 * @hide 7311 * The profiles that can be used with AudioService.handleBluetoothActiveDeviceChanged() 7312 */ 7313 @IntDef({ 7314 BluetoothProfile.HEARING_AID, 7315 BluetoothProfile.A2DP, 7316 BluetoothProfile.A2DP_SINK, 7317 BluetoothProfile.LE_AUDIO, 7318 BluetoothProfile.LE_AUDIO_BROADCAST, 7319 }) 7320 @Retention(RetentionPolicy.SOURCE) 7321 public @interface BtProfile {} 7322 7323 7324 /** 7325 * See AudioManager.handleBluetoothActiveDeviceChanged(...) 7326 */ handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice, BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info)7327 public void handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice, 7328 BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info) { 7329 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.BLUETOOTH_STACK) 7330 != PackageManager.PERMISSION_GRANTED) { 7331 throw new SecurityException("Bluetooth is the only caller allowed"); 7332 } 7333 if (info == null) { 7334 throw new IllegalArgumentException("Illegal null BluetoothProfileConnectionInfo for" 7335 + " device " + previousDevice + " -> " + newDevice); 7336 } 7337 final int profile = info.getProfile(); 7338 if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK 7339 && profile != BluetoothProfile.LE_AUDIO 7340 && profile != BluetoothProfile.LE_AUDIO_BROADCAST 7341 && profile != BluetoothProfile.HEARING_AID) { 7342 throw new IllegalArgumentException("Illegal BluetoothProfile profile for device " 7343 + previousDevice + " -> " + newDevice + ". Got: " + profile); 7344 } 7345 AudioDeviceBroker.BtDeviceChangedData data = 7346 new AudioDeviceBroker.BtDeviceChangedData(newDevice, previousDevice, info, 7347 "AudioService"); 7348 sendMsg(mAudioHandler, MSG_BT_DEV_CHANGED, SENDMSG_QUEUE, 0, 0, 7349 /*obj*/ data, /*delay*/ 0); 7350 } 7351 7352 /** only public for mocking/spying, do not call outside of AudioService */ 7353 @VisibleForTesting setMusicMute(boolean mute)7354 public void setMusicMute(boolean mute) { 7355 mStreamStates[AudioSystem.STREAM_MUSIC].muteInternally(mute); 7356 } 7357 7358 private static final Set<Integer> DEVICE_MEDIA_UNMUTED_ON_PLUG_SET; 7359 static { 7360 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET = new HashSet<>(); 7361 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADSET); 7362 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE); 7363 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_LINE); 7364 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_A2DP_SET); 7365 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_USB_SET); 7366 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_HDMI); 7367 } 7368 7369 /** only public for mocking/spying, do not call outside of AudioService */ 7370 @VisibleForTesting postAccessoryPlugMediaUnmute(int newDevice)7371 public void postAccessoryPlugMediaUnmute(int newDevice) { 7372 sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE, 7373 newDevice, 0, null, 0); 7374 } 7375 onAccessoryPlugMediaUnmute(int newDevice)7376 private void onAccessoryPlugMediaUnmute(int newDevice) { 7377 if (DEBUG_VOL) { 7378 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute newDevice=%d [%s]", 7379 newDevice, AudioSystem.getOutputDeviceName(newDevice))); 7380 } 7381 7382 if (mNm.getZenMode() != Settings.Global.ZEN_MODE_NO_INTERRUPTIONS 7383 && !isStreamMutedByRingerOrZenMode(AudioSystem.STREAM_MUSIC) 7384 && DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.contains(newDevice) 7385 && mStreamStates[AudioSystem.STREAM_MUSIC].mIsMuted 7386 && mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(newDevice) != 0 7387 && getDeviceSetForStreamDirect(AudioSystem.STREAM_MUSIC).contains(newDevice)) { 7388 if (DEBUG_VOL) { 7389 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute unmuting device=%d [%s]", 7390 newDevice, AudioSystem.getOutputDeviceName(newDevice))); 7391 } 7392 mStreamStates[AudioSystem.STREAM_MUSIC].mute(false); 7393 } 7394 } 7395 7396 /** 7397 * See AudioManager.hasHapticChannels(Context, Uri). 7398 */ hasHapticChannels(Uri uri)7399 public boolean hasHapticChannels(Uri uri) { 7400 return AudioManager.hasHapticChannelsImpl(mContext, uri); 7401 } 7402 7403 /////////////////////////////////////////////////////////////////////////// 7404 // Inner classes 7405 /////////////////////////////////////////////////////////////////////////// 7406 /** 7407 * Key is the AudioManager VolumeGroupId 7408 * Value is the VolumeGroupState 7409 */ 7410 private static final SparseArray<VolumeGroupState> sVolumeGroupStates = new SparseArray<>(); 7411 initVolumeGroupStates()7412 private void initVolumeGroupStates() { 7413 for (final AudioVolumeGroup avg : getAudioVolumeGroups()) { 7414 try { 7415 // if no valid attributes, this volume group is not controllable, throw exception 7416 ensureValidAttributes(avg); 7417 sVolumeGroupStates.append(avg.getId(), new VolumeGroupState(avg)); 7418 } catch (IllegalArgumentException e) { 7419 // Volume Groups without attributes are not controllable through set/get volume 7420 // using attributes. Do not append them. 7421 if (DEBUG_VOL) { 7422 Log.d(TAG, "volume group " + avg.name() + " for internal policy needs"); 7423 } 7424 continue; 7425 } 7426 } 7427 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 7428 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 7429 vgs.applyAllVolumes(/* userSwitch= */ false); 7430 } 7431 } 7432 ensureValidAttributes(AudioVolumeGroup avg)7433 private void ensureValidAttributes(AudioVolumeGroup avg) { 7434 boolean hasAtLeastOneValidAudioAttributes = avg.getAudioAttributes().stream() 7435 .anyMatch(aa -> !aa.equals(AudioProductStrategy.getDefaultAttributes())); 7436 if (!hasAtLeastOneValidAudioAttributes) { 7437 throw new IllegalArgumentException("Volume Group " + avg.name() 7438 + " has no valid audio attributes"); 7439 } 7440 } 7441 readVolumeGroupsSettings(boolean userSwitch)7442 private void readVolumeGroupsSettings(boolean userSwitch) { 7443 synchronized (mSettingsLock) { 7444 synchronized (VolumeStreamState.class) { 7445 if (DEBUG_VOL) { 7446 Log.d(TAG, "readVolumeGroupsSettings userSwitch=" + userSwitch); 7447 } 7448 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 7449 VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 7450 // as for STREAM_MUSIC, preserve volume from one user to the next. 7451 if (!(userSwitch && vgs.isMusic())) { 7452 vgs.clearIndexCache(); 7453 vgs.readSettings(); 7454 } 7455 vgs.applyAllVolumes(userSwitch); 7456 } 7457 } 7458 } 7459 } 7460 7461 // Called upon crash of AudioServer restoreVolumeGroups()7462 private void restoreVolumeGroups() { 7463 if (DEBUG_VOL) { 7464 Log.v(TAG, "restoreVolumeGroups"); 7465 } 7466 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 7467 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 7468 vgs.applyAllVolumes(false/*userSwitch*/); 7469 } 7470 } 7471 dumpVolumeGroups(PrintWriter pw)7472 private void dumpVolumeGroups(PrintWriter pw) { 7473 pw.println("\nVolume Groups (device: index)"); 7474 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 7475 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 7476 vgs.dump(pw); 7477 pw.println(""); 7478 } 7479 } 7480 isCallStream(int stream)7481 private static boolean isCallStream(int stream) { 7482 return stream == AudioSystem.STREAM_VOICE_CALL 7483 || stream == AudioSystem.STREAM_BLUETOOTH_SCO; 7484 } 7485 getVolumeGroupForStreamType(int stream)7486 private static int getVolumeGroupForStreamType(int stream) { 7487 AudioAttributes attributes = 7488 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream); 7489 if (attributes.equals(new AudioAttributes.Builder().build())) { 7490 return AudioVolumeGroup.DEFAULT_VOLUME_GROUP; 7491 } 7492 return AudioProductStrategy.getVolumeGroupIdForAudioAttributes( 7493 attributes, /* fallbackOnDefault= */ false); 7494 } 7495 7496 // NOTE: Locking order for synchronized objects related to volume management: 7497 // 1 mSettingsLock 7498 // 2 VolumeStreamState.class 7499 private class VolumeGroupState { 7500 private final AudioVolumeGroup mAudioVolumeGroup; 7501 private final SparseIntArray mIndexMap = new SparseIntArray(8); 7502 private int mIndexMin; 7503 private int mIndexMax; 7504 private boolean mHasValidStreamType = false; 7505 private int mPublicStreamType = AudioSystem.STREAM_MUSIC; 7506 private AudioAttributes mAudioAttributes = AudioProductStrategy.getDefaultAttributes(); 7507 private boolean mIsMuted = false; 7508 private String mSettingName; 7509 7510 // No API in AudioSystem to get a device from strategy or from attributes. 7511 // Need a valid public stream type to use current API getDeviceForStream getDeviceForVolume()7512 private int getDeviceForVolume() { 7513 return getDeviceForStream(mPublicStreamType); 7514 } 7515 VolumeGroupState(AudioVolumeGroup avg)7516 private VolumeGroupState(AudioVolumeGroup avg) { 7517 mAudioVolumeGroup = avg; 7518 if (DEBUG_VOL) { 7519 Log.v(TAG, "VolumeGroupState for " + avg.toString()); 7520 } 7521 // mAudioAttributes is the default at this point 7522 for (AudioAttributes aa : avg.getAudioAttributes()) { 7523 if (!aa.equals(mAudioAttributes)) { 7524 mAudioAttributes = aa; 7525 break; 7526 } 7527 } 7528 int[] streamTypes = mAudioVolumeGroup.getLegacyStreamTypes(); 7529 String streamSettingName = ""; 7530 if (streamTypes.length != 0) { 7531 // Uses already initialized MIN / MAX if a stream type is attached to group 7532 for (int streamType : streamTypes) { 7533 if (streamType != AudioSystem.STREAM_DEFAULT 7534 && streamType < AudioSystem.getNumStreamTypes()) { 7535 mPublicStreamType = streamType; 7536 mHasValidStreamType = true; 7537 streamSettingName = System.VOLUME_SETTINGS_INT[mPublicStreamType]; 7538 break; 7539 } 7540 } 7541 mIndexMin = MIN_STREAM_VOLUME[mPublicStreamType]; 7542 mIndexMax = MAX_STREAM_VOLUME[mPublicStreamType]; 7543 } else if (!avg.getAudioAttributes().isEmpty()) { 7544 mIndexMin = AudioSystem.getMinVolumeIndexForAttributes(mAudioAttributes); 7545 mIndexMax = AudioSystem.getMaxVolumeIndexForAttributes(mAudioAttributes); 7546 } else { 7547 throw new IllegalArgumentException("volume group: " + mAudioVolumeGroup.name() 7548 + " has neither valid attributes nor valid stream types assigned"); 7549 } 7550 mSettingName = !streamSettingName.isEmpty() ? streamSettingName : ("volume_" + name()); 7551 // Load volume indexes from data base 7552 readSettings(); 7553 } 7554 getLegacyStreamTypes()7555 public @NonNull int[] getLegacyStreamTypes() { 7556 return mAudioVolumeGroup.getLegacyStreamTypes(); 7557 } 7558 name()7559 public String name() { 7560 return mAudioVolumeGroup.name(); 7561 } 7562 7563 /** 7564 * Volume group with non null minimum index are considered as non mutable, thus 7565 * bijectivity is broken with potential associated stream type. 7566 * VOICE_CALL stream has minVolumeIndex > 0 but can be muted directly by an 7567 * app that has MODIFY_PHONE_STATE permission. 7568 */ isVssMuteBijective(int stream)7569 private boolean isVssMuteBijective(int stream) { 7570 return isStreamAffectedByMute(stream) 7571 && (getMinIndex() == (mStreamStates[stream].mIndexMin + 5) / 10) 7572 && (getMinIndex() == 0 || isCallStream(stream)); 7573 } 7574 isMutable()7575 private boolean isMutable() { 7576 return mIndexMin == 0 || (mHasValidStreamType && isVssMuteBijective(mPublicStreamType)); 7577 } 7578 /** 7579 * Mute/unmute the volume group 7580 * @param muted the new mute state 7581 */ 7582 @GuardedBy("AudioService.VolumeStreamState.class") mute(boolean muted)7583 public boolean mute(boolean muted) { 7584 if (!isMutable()) { 7585 // Non mutable volume group 7586 if (DEBUG_VOL) { 7587 Log.d(TAG, "invalid mute on unmutable volume group " + name()); 7588 } 7589 return false; 7590 } 7591 boolean changed = (mIsMuted != muted); 7592 // As for VSS, mute shall apply minIndex to all devices found in IndexMap and default. 7593 if (changed) { 7594 mIsMuted = muted; 7595 applyAllVolumes(false /*userSwitch*/); 7596 } 7597 return changed; 7598 } 7599 isMuted()7600 public boolean isMuted() { 7601 return mIsMuted; 7602 } 7603 adjustVolume(int direction, int flags)7604 public void adjustVolume(int direction, int flags) { 7605 synchronized (VolumeStreamState.class) { 7606 int device = getDeviceForVolume(); 7607 int previousIndex = getIndex(device); 7608 if (isMuteAdjust(direction) && !isMutable()) { 7609 // Non mutable volume group 7610 if (DEBUG_VOL) { 7611 Log.d(TAG, "invalid mute on unmutable volume group " + name()); 7612 } 7613 return; 7614 } 7615 switch (direction) { 7616 case AudioManager.ADJUST_TOGGLE_MUTE: { 7617 // Note: If muted by volume 0, unmute will restore volume 0. 7618 mute(!mIsMuted); 7619 break; 7620 } 7621 case AudioManager.ADJUST_UNMUTE: 7622 // Note: If muted by volume 0, unmute will restore volume 0. 7623 mute(false); 7624 break; 7625 case AudioManager.ADJUST_MUTE: 7626 // May be already muted by setvolume 0, prevent from setting same value 7627 if (previousIndex != 0) { 7628 // bypass persist 7629 mute(true); 7630 } 7631 mIsMuted = true; 7632 break; 7633 case AudioManager.ADJUST_RAISE: 7634 // As for stream, RAISE during mute will increment the index 7635 setVolumeIndex(Math.min(previousIndex + 1, mIndexMax), device, flags); 7636 break; 7637 case AudioManager.ADJUST_LOWER: 7638 // For stream, ADJUST_LOWER on a muted VSS is a no-op 7639 // If we decide to unmute on ADJUST_LOWER, cannot fallback on 7640 // adjustStreamVolume for group associated to legacy stream type 7641 if (isMuted() && previousIndex != 0) { 7642 mute(false); 7643 } else { 7644 int newIndex = Math.max(previousIndex - 1, mIndexMin); 7645 setVolumeIndex(newIndex, device, flags); 7646 } 7647 break; 7648 } 7649 } 7650 } 7651 getVolumeIndex()7652 public int getVolumeIndex() { 7653 synchronized (VolumeStreamState.class) { 7654 return getIndex(getDeviceForVolume()); 7655 } 7656 } 7657 setVolumeIndex(int index, int flags)7658 public void setVolumeIndex(int index, int flags) { 7659 synchronized (VolumeStreamState.class) { 7660 if (mUseFixedVolume) { 7661 return; 7662 } 7663 setVolumeIndex(index, getDeviceForVolume(), flags); 7664 } 7665 } 7666 7667 @GuardedBy("AudioService.VolumeStreamState.class") setVolumeIndex(int index, int device, int flags)7668 private void setVolumeIndex(int index, int device, int flags) { 7669 // Update cache & persist (muted by volume 0 shall be persisted) 7670 updateVolumeIndex(index, device); 7671 // setting non-zero volume for a muted stream unmutes the stream and vice versa, 7672 boolean changed = mute(index == 0); 7673 if (!changed) { 7674 // Set the volume index only if mute operation is a no-op 7675 index = getValidIndex(index); 7676 setVolumeIndexInt(index, device, flags); 7677 } 7678 } 7679 7680 @GuardedBy("AudioService.VolumeStreamState.class") updateVolumeIndex(int index, int device)7681 public void updateVolumeIndex(int index, int device) { 7682 // Filter persistency if already exist and the index has not changed 7683 if (mIndexMap.indexOfKey(device) < 0 || mIndexMap.get(device) != index) { 7684 // Update local cache 7685 mIndexMap.put(device, getValidIndex(index)); 7686 7687 // update data base - post a persist volume group msg 7688 sendMsg(mAudioHandler, 7689 MSG_PERSIST_VOLUME_GROUP, 7690 SENDMSG_QUEUE, 7691 device, 7692 0, 7693 this, 7694 PERSIST_DELAY); 7695 } 7696 } 7697 7698 @GuardedBy("AudioService.VolumeStreamState.class") setVolumeIndexInt(int index, int device, int flags)7699 private void setVolumeIndexInt(int index, int device, int flags) { 7700 // Reflect mute state of corresponding stream by forcing index to 0 if muted 7701 // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted. 7702 // This allows RX path muting by the audio HAL only when explicitly muted but not when 7703 // index is just set to 0 to repect BT requirements 7704 if (mHasValidStreamType && isVssMuteBijective(mPublicStreamType) 7705 && mStreamStates[mPublicStreamType].isFullyMuted()) { 7706 index = 0; 7707 } else if (mPublicStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0) { 7708 index = 1; 7709 } 7710 // Set the volume index 7711 AudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, device); 7712 } 7713 7714 @GuardedBy("AudioService.VolumeStreamState.class") getIndex(int device)7715 private int getIndex(int device) { 7716 int index = mIndexMap.get(device, -1); 7717 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT 7718 return (index != -1) ? index : mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); 7719 } 7720 7721 @GuardedBy("AudioService.VolumeStreamState.class") hasIndexForDevice(int device)7722 private boolean hasIndexForDevice(int device) { 7723 return (mIndexMap.get(device, -1) != -1); 7724 } 7725 getMaxIndex()7726 public int getMaxIndex() { 7727 return mIndexMax; 7728 } 7729 getMinIndex()7730 public int getMinIndex() { 7731 return mIndexMin; 7732 } 7733 isValidStream(int stream)7734 private boolean isValidStream(int stream) { 7735 return (stream != AudioSystem.STREAM_DEFAULT) && (stream < mStreamStates.length); 7736 } 7737 isMusic()7738 public boolean isMusic() { 7739 return mHasValidStreamType && mPublicStreamType == AudioSystem.STREAM_MUSIC; 7740 } 7741 applyAllVolumes(boolean userSwitch)7742 public void applyAllVolumes(boolean userSwitch) { 7743 String caller = "from vgs"; 7744 synchronized (VolumeStreamState.class) { 7745 // apply device specific volumes first 7746 for (int i = 0; i < mIndexMap.size(); i++) { 7747 int device = mIndexMap.keyAt(i); 7748 int index = mIndexMap.valueAt(i); 7749 boolean synced = false; 7750 if (device != AudioSystem.DEVICE_OUT_DEFAULT) { 7751 for (int stream : getLegacyStreamTypes()) { 7752 if (isValidStream(stream)) { 7753 boolean streamMuted = mStreamStates[stream].mIsMuted; 7754 int deviceForStream = getDeviceForStream(stream); 7755 int indexForStream = 7756 (mStreamStates[stream].getIndex(deviceForStream) + 5) / 10; 7757 if (device == deviceForStream) { 7758 if (indexForStream == index && (isMuted() == streamMuted) 7759 && isVssMuteBijective(stream)) { 7760 synced = true; 7761 continue; 7762 } 7763 if (indexForStream != index) { 7764 mStreamStates[stream].setIndex(index * 10, device, caller, 7765 true /*hasModifyAudioSettings*/); 7766 } 7767 if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) { 7768 mStreamStates[stream].mute(isMuted()); 7769 } 7770 } 7771 } 7772 } 7773 if (!synced) { 7774 if (DEBUG_VOL) { 7775 Log.d(TAG, "applyAllVolumes: apply index " + index + ", group " 7776 + mAudioVolumeGroup.name() + " and device " 7777 + AudioSystem.getOutputDeviceName(device)); 7778 } 7779 setVolumeIndexInt(isMuted() ? 0 : index, device, 0 /*flags*/); 7780 } 7781 } 7782 } 7783 // apply default volume last: by convention , default device volume will be used 7784 // by audio policy manager if no explicit volume is present for a given device type 7785 int index = getIndex(AudioSystem.DEVICE_OUT_DEFAULT); 7786 boolean synced = false; 7787 int deviceForVolume = getDeviceForVolume(); 7788 boolean forceDeviceSync = userSwitch && (mIndexMap.indexOfKey(deviceForVolume) < 0); 7789 for (int stream : getLegacyStreamTypes()) { 7790 if (isValidStream(stream)) { 7791 boolean streamMuted = mStreamStates[stream].mIsMuted; 7792 int defaultStreamIndex = (mStreamStates[stream].getIndex( 7793 AudioSystem.DEVICE_OUT_DEFAULT) + 5) / 10; 7794 if (forceDeviceSync) { 7795 mStreamStates[stream].setIndex(index * 10, deviceForVolume, caller, 7796 true /*hasModifyAudioSettings*/); 7797 } 7798 if (defaultStreamIndex == index && (isMuted() == streamMuted) 7799 && isVssMuteBijective(stream)) { 7800 synced = true; 7801 continue; 7802 } 7803 if (defaultStreamIndex != index) { 7804 mStreamStates[stream].setIndex( 7805 index * 10, AudioSystem.DEVICE_OUT_DEFAULT, caller, 7806 true /*hasModifyAudioSettings*/); 7807 } 7808 if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) { 7809 mStreamStates[stream].mute(isMuted()); 7810 } 7811 } 7812 } 7813 if (!synced) { 7814 if (DEBUG_VOL) { 7815 Log.d(TAG, "applyAllVolumes: apply default device index " + index 7816 + ", group " + mAudioVolumeGroup.name()); 7817 } 7818 setVolumeIndexInt( 7819 isMuted() ? 0 : index, AudioSystem.DEVICE_OUT_DEFAULT, 0 /*flags*/); 7820 } 7821 if (forceDeviceSync) { 7822 if (DEBUG_VOL) { 7823 Log.d(TAG, "applyAllVolumes: forceDeviceSync index " + index 7824 + ", device " + AudioSystem.getOutputDeviceName(deviceForVolume) 7825 + ", group " + mAudioVolumeGroup.name()); 7826 } 7827 setVolumeIndexInt(isMuted() ? 0 : index, deviceForVolume, 0); 7828 } 7829 } 7830 } 7831 clearIndexCache()7832 public void clearIndexCache() { 7833 mIndexMap.clear(); 7834 } 7835 persistVolumeGroup(int device)7836 private void persistVolumeGroup(int device) { 7837 // No need to persist the index if the volume group is backed up 7838 // by a public stream type as this is redundant 7839 if (mUseFixedVolume || mHasValidStreamType) { 7840 return; 7841 } 7842 if (DEBUG_VOL) { 7843 Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) + " for group " 7844 + mAudioVolumeGroup.name() 7845 + ", device " + AudioSystem.getOutputDeviceName(device) 7846 + " and User=" + getCurrentUserId() 7847 + " mSettingName: " + mSettingName); 7848 } 7849 7850 boolean success = mSettings.putSystemIntForUser(mContentResolver, 7851 getSettingNameForDevice(device), 7852 getIndex(device), 7853 isMusic() ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT); 7854 if (!success) { 7855 Log.e(TAG, "persistVolumeGroup failed for group " + mAudioVolumeGroup.name()); 7856 } 7857 } 7858 readSettings()7859 public void readSettings() { 7860 synchronized (VolumeStreamState.class) { 7861 // force maximum volume on all streams if fixed volume property is set 7862 if (mUseFixedVolume) { 7863 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax); 7864 return; 7865 } 7866 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 7867 // retrieve current volume for device 7868 // if no volume stored for current volume group and device, use default volume 7869 // if default device, continue otherwise 7870 int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) 7871 ? AudioSystem.DEFAULT_STREAM_VOLUME[mPublicStreamType] : -1; 7872 int index; 7873 String name = getSettingNameForDevice(device); 7874 index = mSettings.getSystemIntForUser( 7875 mContentResolver, name, defaultIndex, 7876 isMusic() ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT); 7877 if (index == -1) { 7878 continue; 7879 } 7880 if (mPublicStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED 7881 && mCameraSoundForced) { 7882 index = mIndexMax; 7883 } 7884 if (DEBUG_VOL) { 7885 Log.v(TAG, "readSettings: found stored index " + getValidIndex(index) 7886 + " for group " + mAudioVolumeGroup.name() + ", device: " + name 7887 + ", User=" + getCurrentUserId()); 7888 } 7889 mIndexMap.put(device, getValidIndex(index)); 7890 } 7891 } 7892 } 7893 7894 @GuardedBy("AudioService.VolumeStreamState.class") getValidIndex(int index)7895 private int getValidIndex(int index) { 7896 if (index < mIndexMin) { 7897 return mIndexMin; 7898 } else if (mUseFixedVolume || index > mIndexMax) { 7899 return mIndexMax; 7900 } 7901 return index; 7902 } 7903 getSettingNameForDevice(int device)7904 public @NonNull String getSettingNameForDevice(int device) { 7905 String suffix = AudioSystem.getOutputDeviceName(device); 7906 if (suffix.isEmpty()) { 7907 return mSettingName; 7908 } 7909 return mSettingName + "_" + AudioSystem.getOutputDeviceName(device); 7910 } 7911 setSettingName(String settingName)7912 void setSettingName(String settingName) { 7913 mSettingName = settingName; 7914 } 7915 getSettingName()7916 String getSettingName() { 7917 return mSettingName; 7918 } 7919 dump(PrintWriter pw)7920 private void dump(PrintWriter pw) { 7921 pw.println("- VOLUME GROUP " + mAudioVolumeGroup.name() + ":"); 7922 pw.print(" Muted: "); 7923 pw.println(mIsMuted); 7924 pw.print(" Min: "); 7925 pw.println(mIndexMin); 7926 pw.print(" Max: "); 7927 pw.println(mIndexMax); 7928 pw.print(" Current: "); 7929 for (int i = 0; i < mIndexMap.size(); i++) { 7930 if (i > 0) { 7931 pw.print(", "); 7932 } 7933 int device = mIndexMap.keyAt(i); 7934 pw.print(Integer.toHexString(device)); 7935 String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 7936 : AudioSystem.getOutputDeviceName(device); 7937 if (!deviceName.isEmpty()) { 7938 pw.print(" ("); 7939 pw.print(deviceName); 7940 pw.print(")"); 7941 } 7942 pw.print(": "); 7943 pw.print(mIndexMap.valueAt(i)); 7944 } 7945 pw.println(); 7946 pw.print(" Devices: "); 7947 int n = 0; 7948 int devices = getDeviceForVolume(); 7949 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 7950 if ((devices & device) == device) { 7951 if (n++ > 0) { 7952 pw.print(", "); 7953 } 7954 pw.print(AudioSystem.getOutputDeviceName(device)); 7955 } 7956 } 7957 pw.println(); 7958 pw.print(" Streams: "); 7959 Arrays.stream(getLegacyStreamTypes()) 7960 .forEach(stream -> pw.print(AudioSystem.streamToString(stream) + " ")); 7961 } 7962 } 7963 7964 7965 // NOTE: Locking order for synchronized objects related to volume or ringer mode management: 7966 // 1 mScoclient OR mSafeMediaVolumeState 7967 // 2 mSetModeLock 7968 // 3 mSettingsLock 7969 // 4 VolumeStreamState.class 7970 private class VolumeStreamState { 7971 private final int mStreamType; 7972 private VolumeGroupState mVolumeGroupState = null; 7973 private int mIndexMin; 7974 // min index when user doesn't have permission to change audio settings 7975 private int mIndexMinNoPerm; 7976 private int mIndexMax; 7977 7978 private boolean mIsMuted = false; 7979 private boolean mIsMutedInternally = false; 7980 private String mVolumeIndexSettingName; 7981 @NonNull private Set<Integer> mObservedDeviceSet = new TreeSet<>(); 7982 7983 private final SparseIntArray mIndexMap = new SparseIntArray(8) { 7984 @Override 7985 public void put(int key, int value) { 7986 super.put(key, value); 7987 record("put", key, value); 7988 } 7989 @Override 7990 public void setValueAt(int index, int value) { 7991 super.setValueAt(index, value); 7992 record("setValueAt", keyAt(index), value); 7993 } 7994 7995 // Record all changes in the VolumeStreamState 7996 private void record(String event, int key, int value) { 7997 final String device = key == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 7998 : AudioSystem.getOutputDeviceName(key); 7999 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME + MediaMetrics.SEPARATOR 8000 + AudioSystem.streamToString(mStreamType) 8001 + "." + device) 8002 .set(MediaMetrics.Property.EVENT, event) 8003 .set(MediaMetrics.Property.INDEX, value) 8004 .set(MediaMetrics.Property.MIN_INDEX, mIndexMin) 8005 .set(MediaMetrics.Property.MAX_INDEX, mIndexMax) 8006 .record(); 8007 } 8008 }; 8009 private final Intent mVolumeChanged; 8010 private final Intent mStreamDevicesChanged; 8011 VolumeStreamState(String settingName, int streamType)8012 private VolumeStreamState(String settingName, int streamType) { 8013 mVolumeIndexSettingName = settingName; 8014 8015 mStreamType = streamType; 8016 mIndexMin = MIN_STREAM_VOLUME[streamType] * 10; 8017 mIndexMinNoPerm = mIndexMin; // may be overwritten later in updateNoPermMinIndex() 8018 mIndexMax = MAX_STREAM_VOLUME[streamType] * 10; 8019 final int status = AudioSystem.initStreamVolume( 8020 streamType, mIndexMin / 10, mIndexMax / 10); 8021 if (status != AudioSystem.AUDIO_STATUS_OK) { 8022 sLifecycleLogger.log(new AudioEventLogger.StringEvent( 8023 "VSS() stream:" + streamType + " initStreamVolume=" + status) 8024 .printLog(ALOGE, TAG)); 8025 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 8026 "VSS()" /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 8027 } 8028 8029 readSettings(); 8030 mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION); 8031 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 8032 mStreamDevicesChanged = new Intent(AudioManager.STREAM_DEVICES_CHANGED_ACTION); 8033 mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 8034 } 8035 8036 /** 8037 * Associate a {@link volumeGroupState} on the {@link VolumeStreamState}. 8038 * <p> It helps to synchronize the index, mute attributes on the maching 8039 * {@link volumeGroupState} 8040 * @param volumeGroupState matching the {@link VolumeStreamState} 8041 */ setVolumeGroupState(VolumeGroupState volumeGroupState)8042 public void setVolumeGroupState(VolumeGroupState volumeGroupState) { 8043 mVolumeGroupState = volumeGroupState; 8044 if (mVolumeGroupState != null) { 8045 mVolumeGroupState.setSettingName(mVolumeIndexSettingName); 8046 } 8047 } 8048 /** 8049 * Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission 8050 * @param index minimum index expressed in "UI units", i.e. no 10x factor 8051 */ updateNoPermMinIndex(int index)8052 public void updateNoPermMinIndex(int index) { 8053 mIndexMinNoPerm = index * 10; 8054 if (mIndexMinNoPerm < mIndexMin) { 8055 Log.e(TAG, "Invalid mIndexMinNoPerm for stream " + mStreamType); 8056 mIndexMinNoPerm = mIndexMin; 8057 } 8058 } 8059 8060 /** 8061 * Returns a list of devices associated with the stream type. 8062 * 8063 * This is a reference to the local list, do not modify. 8064 */ 8065 @GuardedBy("VolumeStreamState.class") 8066 @NonNull observeDevicesForStream_syncVSS( boolean checkOthers)8067 public Set<Integer> observeDevicesForStream_syncVSS( 8068 boolean checkOthers) { 8069 if (!mSystemServer.isPrivileged()) { 8070 return new TreeSet<Integer>(); 8071 } 8072 final Set<Integer> deviceSet = 8073 getDeviceSetForStreamDirect(mStreamType); 8074 if (deviceSet.equals(mObservedDeviceSet)) { 8075 return mObservedDeviceSet; 8076 } 8077 8078 // Use legacy bit masks for message signalling. 8079 // TODO(b/185386781): message needs update since it uses devices bit-mask. 8080 final int devices = AudioSystem.getDeviceMaskFromSet(deviceSet); 8081 final int prevDevices = AudioSystem.getDeviceMaskFromSet(mObservedDeviceSet); 8082 8083 mObservedDeviceSet = deviceSet; 8084 if (checkOthers) { 8085 // one stream's devices have changed, check the others 8086 postObserveDevicesForAllStreams(mStreamType); 8087 } 8088 // log base stream changes to the event log 8089 if (mStreamVolumeAlias[mStreamType] == mStreamType) { 8090 EventLogTags.writeStreamDevicesChanged(mStreamType, prevDevices, devices); 8091 } 8092 // send STREAM_DEVICES_CHANGED_ACTION on the message handler so it is scheduled after 8093 // the postObserveDevicesForStreams is handled 8094 sendMsg(mAudioHandler, 8095 MSG_STREAM_DEVICES_CHANGED, 8096 SENDMSG_QUEUE, prevDevices /*arg1*/, devices /*arg2*/, 8097 // ok to send reference to this object, it is final 8098 mStreamDevicesChanged /*obj*/, 0 /*delay*/); 8099 return mObservedDeviceSet; 8100 } 8101 getSettingNameForDevice(int device)8102 public @Nullable String getSettingNameForDevice(int device) { 8103 if (!hasValidSettingsName()) { 8104 return null; 8105 } 8106 final String suffix = AudioSystem.getOutputDeviceName(device); 8107 if (suffix.isEmpty()) { 8108 return mVolumeIndexSettingName; 8109 } 8110 return mVolumeIndexSettingName + "_" + suffix; 8111 } 8112 hasValidSettingsName()8113 private boolean hasValidSettingsName() { 8114 return (mVolumeIndexSettingName != null && !mVolumeIndexSettingName.isEmpty()); 8115 } 8116 setSettingName(String settingName)8117 void setSettingName(String settingName) { 8118 mVolumeIndexSettingName = settingName; 8119 if (mVolumeGroupState != null) { 8120 mVolumeGroupState.setSettingName(mVolumeIndexSettingName); 8121 } 8122 } 8123 getSettingName()8124 String getSettingName() { 8125 return mVolumeIndexSettingName; 8126 } 8127 readSettings()8128 public void readSettings() { 8129 synchronized (mSettingsLock) { 8130 synchronized (VolumeStreamState.class) { 8131 // force maximum volume on all streams if fixed volume property is set 8132 if (mUseFixedVolume) { 8133 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax); 8134 return; 8135 } 8136 // do not read system stream volume from settings: this stream is always aliased 8137 // to another stream type and its volume is never persisted. Values in settings can 8138 // only be stale values 8139 if ((mStreamType == AudioSystem.STREAM_SYSTEM) || 8140 (mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)) { 8141 int index = 10 * AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType]; 8142 if (mCameraSoundForced) { 8143 index = mIndexMax; 8144 } 8145 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, index); 8146 return; 8147 } 8148 } 8149 } 8150 synchronized (VolumeStreamState.class) { 8151 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 8152 8153 // retrieve current volume for device 8154 // if no volume stored for current stream and device, use default volume if default 8155 // device, continue otherwise 8156 int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ? 8157 AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType] : -1; 8158 int index; 8159 if (!hasValidSettingsName()) { 8160 index = defaultIndex; 8161 } else { 8162 String name = getSettingNameForDevice(device); 8163 index = mSettings.getSystemIntForUser( 8164 mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT); 8165 } 8166 if (index == -1) { 8167 continue; 8168 } 8169 8170 mIndexMap.put(device, getValidIndex(10 * index, 8171 true /*hasModifyAudioSettings*/)); 8172 } 8173 } 8174 } 8175 getAbsoluteVolumeIndex(int index)8176 private int getAbsoluteVolumeIndex(int index) { 8177 /* Special handling for Bluetooth Absolute Volume scenario 8178 * If we send full audio gain, some accessories are too loud even at its lowest 8179 * volume. We are not able to enumerate all such accessories, so here is the 8180 * workaround from phone side. 8181 * Pre-scale volume at lowest volume steps 1 2 and 3. 8182 * For volume step 0, set audio gain to 0 as some accessories won't mute on their end. 8183 */ 8184 if (index == 0) { 8185 // 0% for volume 0 8186 index = 0; 8187 } else if (index > 0 && index <= 3) { 8188 // Pre-scale for volume steps 1 2 and 3 8189 index = (int) (mIndexMax * mPrescaleAbsoluteVolume[index - 1]) / 10; 8190 } else { 8191 // otherwise, full gain 8192 index = (mIndexMax + 5) / 10; 8193 } 8194 return index; 8195 } 8196 setStreamVolumeIndex(int index, int device)8197 private void setStreamVolumeIndex(int index, int device) { 8198 // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted. 8199 // This allows RX path muting by the audio HAL only when explicitly muted but not when 8200 // index is just set to 0 to repect BT requirements 8201 if (mStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0 8202 && !isFullyMuted()) { 8203 index = 1; 8204 } 8205 mAudioSystem.setStreamVolumeIndexAS(mStreamType, index, device); 8206 } 8207 8208 // must be called while synchronized VolumeStreamState.class applyDeviceVolume_syncVSS(int device)8209 /*package*/ void applyDeviceVolume_syncVSS(int device) { 8210 int index; 8211 if (isFullyMuted()) { 8212 index = 0; 8213 } else if (isAbsoluteVolumeDevice(device) 8214 || isA2dpAbsoluteVolumeDevice(device) 8215 || AudioSystem.isLeAudioDeviceType(device)) { 8216 index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10); 8217 } else if (isFullVolumeDevice(device)) { 8218 index = (mIndexMax + 5)/10; 8219 } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 8220 index = (mIndexMax + 5)/10; 8221 } else { 8222 index = (getIndex(device) + 5)/10; 8223 } 8224 setStreamVolumeIndex(index, device); 8225 } 8226 applyAllVolumes()8227 public void applyAllVolumes() { 8228 synchronized (VolumeStreamState.class) { 8229 // apply device specific volumes first 8230 int index; 8231 for (int i = 0; i < mIndexMap.size(); i++) { 8232 final int device = mIndexMap.keyAt(i); 8233 if (device != AudioSystem.DEVICE_OUT_DEFAULT) { 8234 if (isFullyMuted()) { 8235 index = 0; 8236 } else if (isAbsoluteVolumeDevice(device) 8237 || isA2dpAbsoluteVolumeDevice(device) 8238 || AudioSystem.isLeAudioDeviceType(device)) { 8239 index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10); 8240 } else if (isFullVolumeDevice(device)) { 8241 index = (mIndexMax + 5)/10; 8242 } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 8243 index = (mIndexMax + 5)/10; 8244 } else { 8245 index = (mIndexMap.valueAt(i) + 5)/10; 8246 } 8247 setStreamVolumeIndex(index, device); 8248 } 8249 } 8250 // apply default volume last: by convention , default device volume will be used 8251 // by audio policy manager if no explicit volume is present for a given device type 8252 if (isFullyMuted()) { 8253 index = 0; 8254 } else { 8255 index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10; 8256 } 8257 setStreamVolumeIndex(index, AudioSystem.DEVICE_OUT_DEFAULT); 8258 } 8259 } 8260 adjustIndex(int deltaIndex, int device, String caller, boolean hasModifyAudioSettings)8261 public boolean adjustIndex(int deltaIndex, int device, String caller, 8262 boolean hasModifyAudioSettings) { 8263 return setIndex(getIndex(device) + deltaIndex, device, caller, 8264 hasModifyAudioSettings); 8265 } 8266 setIndex(int index, int device, String caller, boolean hasModifyAudioSettings)8267 public boolean setIndex(int index, int device, String caller, 8268 boolean hasModifyAudioSettings) { 8269 boolean changed; 8270 int oldIndex; 8271 final boolean isCurrentDevice; 8272 synchronized (mSettingsLock) { 8273 synchronized (VolumeStreamState.class) { 8274 oldIndex = getIndex(device); 8275 index = getValidIndex(index, hasModifyAudioSettings); 8276 if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) && mCameraSoundForced) { 8277 index = mIndexMax; 8278 } 8279 mIndexMap.put(device, index); 8280 8281 changed = oldIndex != index; 8282 // Apply change to all streams using this one as alias if: 8283 // - the index actually changed OR 8284 // - there is no volume index stored for this device on alias stream. 8285 // If changing volume of current device, also change volume of current 8286 // device on aliased stream 8287 isCurrentDevice = (device == getDeviceForStream(mStreamType)); 8288 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 8289 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 8290 final VolumeStreamState aliasStreamState = mStreamStates[streamType]; 8291 if (streamType != mStreamType && 8292 mStreamVolumeAlias[streamType] == mStreamType && 8293 (changed || !aliasStreamState.hasIndexForDevice(device))) { 8294 final int scaledIndex = rescaleIndex(index, mStreamType, streamType); 8295 aliasStreamState.setIndex(scaledIndex, device, caller, 8296 hasModifyAudioSettings); 8297 if (isCurrentDevice) { 8298 aliasStreamState.setIndex(scaledIndex, 8299 getDeviceForStream(streamType), caller, 8300 hasModifyAudioSettings); 8301 } 8302 } 8303 } 8304 // Mirror changes in SPEAKER ringtone volume on SCO when 8305 if (changed && mStreamType == AudioSystem.STREAM_RING 8306 && device == AudioSystem.DEVICE_OUT_SPEAKER) { 8307 for (int i = 0; i < mIndexMap.size(); i++) { 8308 int otherDevice = mIndexMap.keyAt(i); 8309 if (AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(otherDevice)) { 8310 mIndexMap.put(otherDevice, index); 8311 } 8312 } 8313 } 8314 } 8315 } 8316 if (changed) { 8317 // If associated to volume group, update group cache 8318 updateVolumeGroupIndex(device, /* forceMuteState= */ false); 8319 8320 oldIndex = (oldIndex + 5) / 10; 8321 index = (index + 5) / 10; 8322 // log base stream changes to the event log 8323 if (mStreamVolumeAlias[mStreamType] == mStreamType) { 8324 if (caller == null) { 8325 Log.w(TAG, "No caller for volume_changed event", new Throwable()); 8326 } 8327 EventLogTags.writeVolumeChanged(mStreamType, oldIndex, index, mIndexMax / 10, 8328 caller); 8329 } 8330 // fire changed intents for all streams, but only when the device it changed on 8331 // is the current device 8332 if ((index != oldIndex) && isCurrentDevice) { 8333 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index); 8334 mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex); 8335 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS, 8336 mStreamVolumeAlias[mStreamType]); 8337 AudioService.sVolumeLogger.log(new VolChangedBroadcastEvent( 8338 mStreamType, mStreamVolumeAlias[mStreamType], index)); 8339 sendBroadcastToAll(mVolumeChanged); 8340 } 8341 } 8342 return changed; 8343 } 8344 getIndex(int device)8345 public int getIndex(int device) { 8346 synchronized (VolumeStreamState.class) { 8347 int index = mIndexMap.get(device, -1); 8348 if (index == -1) { 8349 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT 8350 index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); 8351 } 8352 return index; 8353 } 8354 } 8355 hasIndexForDevice(int device)8356 public boolean hasIndexForDevice(int device) { 8357 synchronized (VolumeStreamState.class) { 8358 return (mIndexMap.get(device, -1) != -1); 8359 } 8360 } 8361 getMaxIndex()8362 public int getMaxIndex() { 8363 return mIndexMax; 8364 } 8365 8366 /** 8367 * @return the lowest index regardless of permissions 8368 */ getMinIndex()8369 public int getMinIndex() { 8370 return mIndexMin; 8371 } 8372 8373 /** 8374 * @param isPrivileged true if the caller is privileged and not subject to minimum 8375 * volume index thresholds 8376 * @return the lowest index that this caller can set or adjust to 8377 */ getMinIndex(boolean isPrivileged)8378 public int getMinIndex(boolean isPrivileged) { 8379 return isPrivileged ? mIndexMin : mIndexMinNoPerm; 8380 } 8381 8382 /** 8383 * Copies all device/index pairs from the given VolumeStreamState after initializing 8384 * them with the volume for DEVICE_OUT_DEFAULT. No-op if the source VolumeStreamState 8385 * has the same stream type as this instance. 8386 * @param srcStream 8387 * @param caller 8388 */ 8389 // must be sync'd on mSettingsLock before VolumeStreamState.class 8390 @GuardedBy("VolumeStreamState.class") setAllIndexes(VolumeStreamState srcStream, String caller)8391 public void setAllIndexes(VolumeStreamState srcStream, String caller) { 8392 if (mStreamType == srcStream.mStreamType) { 8393 return; 8394 } 8395 int srcStreamType = srcStream.getStreamType(); 8396 // apply default device volume from source stream to all devices first in case 8397 // some devices are present in this stream state but not in source stream state 8398 int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT); 8399 index = rescaleIndex(index, srcStreamType, mStreamType); 8400 for (int i = 0; i < mIndexMap.size(); i++) { 8401 mIndexMap.put(mIndexMap.keyAt(i), index); 8402 } 8403 // Now apply actual volume for devices in source stream state 8404 SparseIntArray srcMap = srcStream.mIndexMap; 8405 for (int i = 0; i < srcMap.size(); i++) { 8406 int device = srcMap.keyAt(i); 8407 index = srcMap.valueAt(i); 8408 index = rescaleIndex(index, srcStreamType, mStreamType); 8409 8410 setIndex(index, device, caller, true /*hasModifyAudioSettings*/); 8411 } 8412 } 8413 8414 // must be sync'd on mSettingsLock before VolumeStreamState.class 8415 @GuardedBy("VolumeStreamState.class") setAllIndexesToMax()8416 public void setAllIndexesToMax() { 8417 for (int i = 0; i < mIndexMap.size(); i++) { 8418 mIndexMap.put(mIndexMap.keyAt(i), mIndexMax); 8419 } 8420 } 8421 8422 // If associated to volume group, update group cache updateVolumeGroupIndex(int device, boolean forceMuteState)8423 private void updateVolumeGroupIndex(int device, boolean forceMuteState) { 8424 synchronized (VolumeStreamState.class) { 8425 if (mVolumeGroupState != null) { 8426 int groupIndex = (getIndex(device) + 5) / 10; 8427 if (DEBUG_VOL) { 8428 Log.d(TAG, "updateVolumeGroupIndex for stream " + mStreamType 8429 + ", muted=" + mIsMuted + ", device=" + device + ", index=" 8430 + getIndex(device) + ", group " + mVolumeGroupState.name() 8431 + " Muted=" + mVolumeGroupState.isMuted() + ", Index=" + groupIndex 8432 + ", forceMuteState=" + forceMuteState); 8433 } 8434 mVolumeGroupState.updateVolumeIndex(groupIndex, device); 8435 // Only propage mute of stream when applicable 8436 if (isMutable()) { 8437 // For call stream, align mute only when muted, not when index is set to 0 8438 mVolumeGroupState.mute( 8439 forceMuteState ? mIsMuted : 8440 (groupIndex == 0 && !isCallStream(mStreamType)) 8441 || mIsMuted); 8442 } 8443 } 8444 } 8445 } 8446 8447 /** 8448 * Mute/unmute the stream 8449 * @param state the new mute state 8450 * @return true if the mute state was changed 8451 */ mute(boolean state)8452 public boolean mute(boolean state) { 8453 boolean changed = false; 8454 synchronized (VolumeStreamState.class) { 8455 changed = mute(state, true); 8456 } 8457 if (changed) { 8458 broadcastMuteSetting(mStreamType, state); 8459 } 8460 return changed; 8461 } 8462 8463 /** 8464 * Mute/unmute the stream by AudioService 8465 * @param state the new mute state 8466 * @return true if the mute state was changed 8467 */ muteInternally(boolean state)8468 public boolean muteInternally(boolean state) { 8469 boolean changed = false; 8470 synchronized (VolumeStreamState.class) { 8471 if (state != mIsMutedInternally) { 8472 changed = true; 8473 mIsMutedInternally = state; 8474 // mute immediately to avoid delay and preemption when using a message. 8475 applyAllVolumes(); 8476 } 8477 } 8478 if (changed) { 8479 sVolumeLogger.log(new VolumeEvent( 8480 VolumeEvent.VOL_MUTE_STREAM_INT, mStreamType, state)); 8481 } 8482 return changed; 8483 } 8484 8485 @GuardedBy("VolumeStreamState.class") isFullyMuted()8486 public boolean isFullyMuted() { 8487 return mIsMuted || mIsMutedInternally; 8488 } 8489 8490 isMutable()8491 private boolean isMutable() { 8492 return isStreamAffectedByMute(mStreamType) 8493 && (mIndexMin == 0 || isCallStream(mStreamType)); 8494 } 8495 8496 /** 8497 * Mute/unmute the stream 8498 * @param state the new mute state 8499 * @param apply true to propagate to HW, or false just to update the cache. May be needed 8500 * to mute a stream and its aliases as applyAllVolume will force settings to aliases. 8501 * It prevents unnecessary calls to {@see AudioSystem#setStreamVolume} 8502 * @return true if the mute state was changed 8503 */ mute(boolean state, boolean apply)8504 public boolean mute(boolean state, boolean apply) { 8505 synchronized (VolumeStreamState.class) { 8506 boolean changed = state != mIsMuted; 8507 if (changed) { 8508 mIsMuted = state; 8509 if (apply) { 8510 doMute(); 8511 } 8512 } 8513 return changed; 8514 } 8515 } 8516 doMute()8517 public void doMute() { 8518 synchronized (VolumeStreamState.class) { 8519 // If associated to volume group, update group cache 8520 updateVolumeGroupIndex(getDeviceForStream(mStreamType), /* forceMuteState= */ true); 8521 8522 // Set the new mute volume. This propagates the values to 8523 // the audio system, otherwise the volume won't be changed 8524 // at the lower level. 8525 sendMsg(mAudioHandler, 8526 MSG_SET_ALL_VOLUMES, 8527 SENDMSG_QUEUE, 8528 0, 8529 0, 8530 this, 0); 8531 } 8532 } 8533 getStreamType()8534 public int getStreamType() { 8535 return mStreamType; 8536 } 8537 checkFixedVolumeDevices()8538 public void checkFixedVolumeDevices() { 8539 synchronized (VolumeStreamState.class) { 8540 // ignore settings for fixed volume devices: volume should always be at max or 0 8541 if (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_MUSIC) { 8542 for (int i = 0; i < mIndexMap.size(); i++) { 8543 int device = mIndexMap.keyAt(i); 8544 int index = mIndexMap.valueAt(i); 8545 if (isFullVolumeDevice(device) 8546 || (isFixedVolumeDevice(device) && index != 0)) { 8547 mIndexMap.put(device, mIndexMax); 8548 } 8549 applyDeviceVolume_syncVSS(device); 8550 } 8551 } 8552 } 8553 } 8554 getValidIndex(int index, boolean hasModifyAudioSettings)8555 private int getValidIndex(int index, boolean hasModifyAudioSettings) { 8556 final int indexMin = hasModifyAudioSettings ? mIndexMin : mIndexMinNoPerm; 8557 if (index < indexMin) { 8558 return indexMin; 8559 } else if (mUseFixedVolume || index > mIndexMax) { 8560 return mIndexMax; 8561 } 8562 8563 return index; 8564 } 8565 dump(PrintWriter pw)8566 private void dump(PrintWriter pw) { 8567 pw.print(" Muted: "); 8568 pw.println(mIsMuted); 8569 pw.print(" Muted Internally: "); 8570 pw.println(mIsMutedInternally); 8571 pw.print(" Min: "); 8572 pw.print((mIndexMin + 5) / 10); 8573 if (mIndexMin != mIndexMinNoPerm) { 8574 pw.print(" w/o perm:"); 8575 pw.println((mIndexMinNoPerm + 5) / 10); 8576 } else { 8577 pw.println(); 8578 } 8579 pw.print(" Max: "); 8580 pw.println((mIndexMax + 5) / 10); 8581 pw.print(" streamVolume:"); pw.println(getStreamVolume(mStreamType)); 8582 pw.print(" Current: "); 8583 for (int i = 0; i < mIndexMap.size(); i++) { 8584 if (i > 0) { 8585 pw.print(", "); 8586 } 8587 final int device = mIndexMap.keyAt(i); 8588 pw.print(Integer.toHexString(device)); 8589 final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 8590 : AudioSystem.getOutputDeviceName(device); 8591 if (!deviceName.isEmpty()) { 8592 pw.print(" ("); 8593 pw.print(deviceName); 8594 pw.print(")"); 8595 } 8596 pw.print(": "); 8597 final int index = (mIndexMap.valueAt(i) + 5) / 10; 8598 pw.print(index); 8599 } 8600 pw.println(); 8601 pw.print(" Devices: "); 8602 pw.print(AudioSystem.deviceSetToString(getDeviceSetForStream(mStreamType))); 8603 pw.println(); 8604 pw.print(" Volume Group: "); 8605 pw.println(mVolumeGroupState != null ? mVolumeGroupState.name() : "n/a"); 8606 } 8607 } 8608 8609 /** Thread that handles native AudioSystem control. */ 8610 private class AudioSystemThread extends Thread { AudioSystemThread()8611 AudioSystemThread() { 8612 super("AudioService"); 8613 } 8614 8615 @Override run()8616 public void run() { 8617 // Set this thread up so the handler will work on it 8618 Looper.prepare(); 8619 8620 synchronized(AudioService.this) { 8621 mAudioHandler = new AudioHandler(); 8622 8623 // Notify that the handler has been created 8624 AudioService.this.notify(); 8625 } 8626 8627 // Listen for volume change requests that are set by VolumePanel 8628 Looper.loop(); 8629 } 8630 } 8631 8632 private static final class DeviceVolumeUpdate { 8633 final int mStreamType; 8634 final int mDevice; 8635 final @NonNull String mCaller; 8636 private static final int NO_NEW_INDEX = -2049; 8637 private final int mVssVolIndex; 8638 8639 // Constructor with volume index, meant to cause this volume to be set and applied for the 8640 // given stream type on the given device DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller)8641 DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller) { 8642 mStreamType = streamType; 8643 mVssVolIndex = vssVolIndex; 8644 mDevice = device; 8645 mCaller = caller; 8646 } 8647 8648 // Constructor with no volume index, meant to cause re-apply of volume for the given 8649 // stream type on the given device DeviceVolumeUpdate(int streamType, int device, @NonNull String caller)8650 DeviceVolumeUpdate(int streamType, int device, @NonNull String caller) { 8651 mStreamType = streamType; 8652 mVssVolIndex = NO_NEW_INDEX; 8653 mDevice = device; 8654 mCaller = caller; 8655 } 8656 hasVolumeIndex()8657 boolean hasVolumeIndex() { 8658 return mVssVolIndex != NO_NEW_INDEX; 8659 } 8660 getVolumeIndex()8661 int getVolumeIndex() throws IllegalStateException { 8662 Preconditions.checkState(mVssVolIndex != NO_NEW_INDEX); 8663 return mVssVolIndex; 8664 } 8665 } 8666 8667 /** only public for mocking/spying, do not call outside of AudioService */ 8668 @VisibleForTesting postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, String caller)8669 public void postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, 8670 String caller) { 8671 sendMsg(mAudioHandler, 8672 MSG_SET_DEVICE_STREAM_VOLUME, 8673 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/, 8674 new DeviceVolumeUpdate(streamType, vssVolIndex, device, caller), 8675 0 /*delay*/); 8676 } 8677 postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller)8678 /*package*/ void postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller) { 8679 sendMsg(mAudioHandler, 8680 MSG_SET_DEVICE_STREAM_VOLUME, 8681 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/, 8682 new DeviceVolumeUpdate(streamType, device, caller), 8683 0 /*delay*/); 8684 } 8685 onSetVolumeIndexOnDevice(@onNull DeviceVolumeUpdate update)8686 private void onSetVolumeIndexOnDevice(@NonNull DeviceVolumeUpdate update) { 8687 final VolumeStreamState streamState = mStreamStates[update.mStreamType]; 8688 if (update.hasVolumeIndex()) { 8689 int index = update.getVolumeIndex(); 8690 if (!checkSafeMediaVolume(update.mStreamType, index, update.mDevice)) { 8691 index = safeMediaVolumeIndex(update.mDevice); 8692 } 8693 streamState.setIndex(index, update.mDevice, update.mCaller, 8694 // trusted as index is always validated before message is posted 8695 true /*hasModifyAudioSettings*/); 8696 sVolumeLogger.log(new AudioEventLogger.StringEvent(update.mCaller + " dev:0x" 8697 + Integer.toHexString(update.mDevice) + " volIdx:" + index)); 8698 } else { 8699 sVolumeLogger.log(new AudioEventLogger.StringEvent(update.mCaller 8700 + " update vol on dev:0x" + Integer.toHexString(update.mDevice))); 8701 } 8702 setDeviceVolume(streamState, update.mDevice); 8703 } 8704 setDeviceVolume(VolumeStreamState streamState, int device)8705 /*package*/ void setDeviceVolume(VolumeStreamState streamState, int device) { 8706 8707 synchronized (VolumeStreamState.class) { 8708 // Apply volume 8709 streamState.applyDeviceVolume_syncVSS(device); 8710 8711 // Apply change to all streams using this one as alias 8712 int numStreamTypes = AudioSystem.getNumStreamTypes(); 8713 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 8714 if (streamType != streamState.mStreamType && 8715 mStreamVolumeAlias[streamType] == streamState.mStreamType) { 8716 // Make sure volume is also maxed out on A2DP device for aliased stream 8717 // that may have a different device selected 8718 int streamDevice = getDeviceForStream(streamType); 8719 if ((device != streamDevice) 8720 && (isAbsoluteVolumeDevice(device) 8721 || isA2dpAbsoluteVolumeDevice(device) 8722 || AudioSystem.isLeAudioDeviceType(device))) { 8723 mStreamStates[streamType].applyDeviceVolume_syncVSS(device); 8724 } 8725 mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice); 8726 } 8727 } 8728 } 8729 // Post a persist volume msg 8730 sendMsg(mAudioHandler, 8731 MSG_PERSIST_VOLUME, 8732 SENDMSG_QUEUE, 8733 device, 8734 0, 8735 streamState, 8736 PERSIST_DELAY); 8737 8738 } 8739 8740 /** Handles internal volume messages in separate volume thread. */ 8741 private class AudioHandler extends Handler { 8742 AudioHandler()8743 AudioHandler() { 8744 super(); 8745 } 8746 AudioHandler(Looper looper)8747 AudioHandler(Looper looper) { 8748 super(looper); 8749 } 8750 setAllVolumes(VolumeStreamState streamState)8751 private void setAllVolumes(VolumeStreamState streamState) { 8752 8753 // Apply volume 8754 streamState.applyAllVolumes(); 8755 8756 // Apply change to all streams using this one as alias 8757 int numStreamTypes = AudioSystem.getNumStreamTypes(); 8758 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 8759 if (streamType != streamState.mStreamType && 8760 mStreamVolumeAlias[streamType] == streamState.mStreamType) { 8761 mStreamStates[streamType].applyAllVolumes(); 8762 } 8763 } 8764 } 8765 persistVolume(VolumeStreamState streamState, int device)8766 private void persistVolume(VolumeStreamState streamState, int device) { 8767 if (mUseFixedVolume) { 8768 return; 8769 } 8770 if (mIsSingleVolume && (streamState.mStreamType != AudioSystem.STREAM_MUSIC)) { 8771 return; 8772 } 8773 if (streamState.hasValidSettingsName()) { 8774 mSettings.putSystemIntForUser(mContentResolver, 8775 streamState.getSettingNameForDevice(device), 8776 (streamState.getIndex(device) + 5) / 10, 8777 UserHandle.USER_CURRENT); 8778 } 8779 } 8780 persistRingerMode(int ringerMode)8781 private void persistRingerMode(int ringerMode) { 8782 if (mUseFixedVolume) { 8783 return; 8784 } 8785 mSettings.putGlobalInt(mContentResolver, Settings.Global.MODE_RINGER, ringerMode); 8786 } 8787 onPersistSafeVolumeState(int state)8788 private void onPersistSafeVolumeState(int state) { 8789 mSettings.putGlobalInt(mContentResolver, 8790 Settings.Global.AUDIO_SAFE_VOLUME_STATE, 8791 state); 8792 } 8793 onNotifyVolumeEvent(@onNull IAudioPolicyCallback apc, @AudioManager.VolumeAdjustment int direction)8794 private void onNotifyVolumeEvent(@NonNull IAudioPolicyCallback apc, 8795 @AudioManager.VolumeAdjustment int direction) { 8796 try { 8797 apc.notifyVolumeAdjust(direction); 8798 } catch(Exception e) { 8799 // nothing we can do about this. Do not log error, too much potential for spam 8800 } 8801 } 8802 8803 @Override handleMessage(Message msg)8804 public void handleMessage(Message msg) { 8805 switch (msg.what) { 8806 8807 case MSG_SET_DEVICE_VOLUME: 8808 setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1); 8809 break; 8810 8811 case MSG_SET_ALL_VOLUMES: 8812 setAllVolumes((VolumeStreamState) msg.obj); 8813 break; 8814 8815 case MSG_PERSIST_VOLUME: 8816 persistVolume((VolumeStreamState) msg.obj, msg.arg1); 8817 break; 8818 8819 case MSG_PERSIST_VOLUME_GROUP: 8820 final VolumeGroupState vgs = (VolumeGroupState) msg.obj; 8821 vgs.persistVolumeGroup(msg.arg1); 8822 break; 8823 8824 case MSG_PERSIST_RINGER_MODE: 8825 // note that the value persisted is the current ringer mode, not the 8826 // value of ringer mode as of the time the request was made to persist 8827 persistRingerMode(getRingerModeInternal()); 8828 break; 8829 8830 case MSG_AUDIO_SERVER_DIED: 8831 onAudioServerDied(); 8832 break; 8833 8834 case MSG_DISPATCH_AUDIO_SERVER_STATE: 8835 onDispatchAudioServerStateChange(msg.arg1 == 1); 8836 break; 8837 8838 case MSG_UNLOAD_SOUND_EFFECTS: 8839 mSfxHelper.unloadSoundEffects(); 8840 break; 8841 8842 case MSG_LOAD_SOUND_EFFECTS: 8843 { 8844 LoadSoundEffectReply reply = (LoadSoundEffectReply) msg.obj; 8845 if (mSystemReady) { 8846 mSfxHelper.loadSoundEffects(reply); 8847 } else { 8848 Log.w(TAG, "[schedule]loadSoundEffects() called before boot complete"); 8849 if (reply != null) { 8850 reply.run(false); 8851 } 8852 } 8853 } 8854 break; 8855 8856 case MSG_PLAY_SOUND_EFFECT: 8857 mSfxHelper.playSoundEffect(msg.arg1, msg.arg2); 8858 break; 8859 8860 case MSG_SET_FORCE_USE: 8861 { 8862 final String eventSource = (String) msg.obj; 8863 final int useCase = msg.arg1; 8864 final int config = msg.arg2; 8865 if (useCase == AudioSystem.FOR_MEDIA) { 8866 Log.wtf(TAG, "Invalid force use FOR_MEDIA in AudioService from " 8867 + eventSource); 8868 break; 8869 } 8870 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE 8871 + MediaMetrics.SEPARATOR + AudioSystem.forceUseUsageToString(useCase)) 8872 .set(MediaMetrics.Property.EVENT, "setForceUse") 8873 .set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource) 8874 .set(MediaMetrics.Property.FORCE_USE_MODE, 8875 AudioSystem.forceUseConfigToString(config)) 8876 .record(); 8877 sForceUseLogger.log( 8878 new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource)); 8879 mAudioSystem.setForceUse(useCase, config); 8880 } 8881 break; 8882 8883 case MSG_DISABLE_AUDIO_FOR_UID: 8884 mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */, 8885 msg.arg2 /* uid */); 8886 mAudioEventWakeLock.release(); 8887 break; 8888 8889 case MSG_INIT_STREAMS_VOLUMES: 8890 onInitStreamsAndVolumes(); 8891 mAudioEventWakeLock.release(); 8892 break; 8893 8894 case MSG_INIT_SPATIALIZER: 8895 onInitSpatializer(); 8896 mAudioEventWakeLock.release(); 8897 break; 8898 8899 case MSG_INIT_HEADTRACKING_SENSORS: 8900 mSpatializerHelper.onInitSensors(); 8901 break; 8902 8903 case MSG_PERSIST_SPATIAL_AUDIO_DEVICE_SETTINGS: 8904 onPersistSpatialAudioDeviceSettings(); 8905 break; 8906 8907 case MSG_RESET_SPATIALIZER: 8908 mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect); 8909 break; 8910 8911 case MSG_CHECK_MUSIC_ACTIVE: 8912 onCheckMusicActive((String) msg.obj); 8913 break; 8914 8915 case MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED: 8916 case MSG_CONFIGURE_SAFE_MEDIA_VOLUME: 8917 onConfigureSafeVolume((msg.what == MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED), 8918 (String) msg.obj); 8919 break; 8920 case MSG_PERSIST_SAFE_VOLUME_STATE: 8921 onPersistSafeVolumeState(msg.arg1); 8922 break; 8923 8924 case MSG_SYSTEM_READY: 8925 onSystemReady(); 8926 break; 8927 8928 case MSG_INDICATE_SYSTEM_READY: 8929 onIndicateSystemReady(); 8930 break; 8931 8932 case MSG_ACCESSORY_PLUG_MEDIA_UNMUTE: 8933 onAccessoryPlugMediaUnmute(msg.arg1); 8934 break; 8935 8936 case MSG_PERSIST_MUSIC_ACTIVE_MS: 8937 final int musicActiveMs = msg.arg1; 8938 mSettings.putSecureIntForUser(mContentResolver, 8939 Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS, musicActiveMs, 8940 UserHandle.USER_CURRENT); 8941 break; 8942 8943 case MSG_UNMUTE_STREAM: 8944 onUnmuteStream(msg.arg1, msg.arg2); 8945 break; 8946 8947 case MSG_DYN_POLICY_MIX_STATE_UPDATE: 8948 onDynPolicyMixStateUpdate((String) msg.obj, msg.arg1); 8949 break; 8950 8951 case MSG_NOTIFY_VOL_EVENT: 8952 onNotifyVolumeEvent((IAudioPolicyCallback) msg.obj, msg.arg1); 8953 break; 8954 8955 case MSG_ENABLE_SURROUND_FORMATS: 8956 onEnableSurroundFormats((ArrayList<Integer>) msg.obj); 8957 break; 8958 8959 case MSG_UPDATE_RINGER_MODE: 8960 onUpdateRingerModeServiceInt(); 8961 break; 8962 8963 case MSG_SET_DEVICE_STREAM_VOLUME: 8964 onSetVolumeIndexOnDevice((DeviceVolumeUpdate) msg.obj); 8965 break; 8966 8967 case MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS: 8968 onObserveDevicesForAllStreams(/*skipStream*/ msg.arg1); 8969 break; 8970 8971 case MSG_HDMI_VOLUME_CHECK: 8972 onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj); 8973 break; 8974 8975 case MSG_PLAYBACK_CONFIG_CHANGE: 8976 onPlaybackConfigChange((List<AudioPlaybackConfiguration>) msg.obj); 8977 break; 8978 case MSG_RECORDING_CONFIG_CHANGE: 8979 onRecordingConfigChange((List<AudioRecordingConfiguration>) msg.obj); 8980 break; 8981 8982 case MSG_BROADCAST_MICROPHONE_MUTE: 8983 mSystemServer.sendMicrophoneMuteChangedIntent(); 8984 break; 8985 8986 case MSG_CHECK_MODE_FOR_UID: 8987 synchronized (mDeviceBroker.mSetModeLock) { 8988 if (msg.obj == null) { 8989 break; 8990 } 8991 // Update active playback/recording for apps requesting IN_COMMUNICATION 8992 // mode after a grace period following the mode change 8993 SetModeDeathHandler h = (SetModeDeathHandler) msg.obj; 8994 if (mSetModeDeathHandlers.indexOf(h) < 0) { 8995 break; 8996 } 8997 boolean wasActive = h.isActive(); 8998 h.setPlaybackActive(mPlaybackMonitor.isPlaybackActiveForUid(h.getUid())); 8999 h.setRecordingActive(mRecordMonitor.isRecordingActiveForUid(h.getUid())); 9000 if (wasActive != h.isActive()) { 9001 onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(), 9002 mContext.getPackageName(), false /*force*/); 9003 } 9004 } 9005 break; 9006 9007 case MSG_STREAM_DEVICES_CHANGED: 9008 sendBroadcastToAll(((Intent) msg.obj) 9009 .putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_DEVICES, msg.arg1) 9010 .putExtra(AudioManager.EXTRA_VOLUME_STREAM_DEVICES, msg.arg2)); 9011 break; 9012 9013 case MSG_UPDATE_VOLUME_STATES_FOR_DEVICE: 9014 onUpdateVolumeStatesForAudioDevice(msg.arg1, (String) msg.obj); 9015 break; 9016 9017 case MSG_REINIT_VOLUMES: 9018 onReinitVolumes((String) msg.obj); 9019 break; 9020 9021 case MSG_UPDATE_A11Y_SERVICE_UIDS: 9022 onUpdateAccessibilityServiceUids(); 9023 break; 9024 9025 case MSG_UPDATE_AUDIO_MODE: 9026 synchronized (mDeviceBroker.mSetModeLock) { 9027 onUpdateAudioMode(msg.arg1, msg.arg2, (String) msg.obj, false /*force*/); 9028 } 9029 break; 9030 9031 case MSG_BT_DEV_CHANGED: 9032 mDeviceBroker.queueOnBluetoothActiveDeviceChanged( 9033 (AudioDeviceBroker.BtDeviceChangedData) msg.obj); 9034 break; 9035 9036 case MSG_DISPATCH_AUDIO_MODE: 9037 dispatchMode(msg.arg1); 9038 break; 9039 9040 case MSG_ROUTING_UPDATED: 9041 onRoutingUpdatedFromAudioThread(); 9042 break; 9043 9044 case MSG_ADD_ASSISTANT_SERVICE_UID: 9045 onAddAssistantServiceUids(new int[]{msg.arg1}); 9046 break; 9047 9048 case MSG_REMOVE_ASSISTANT_SERVICE_UID: 9049 onRemoveAssistantServiceUids(new int[]{msg.arg1}); 9050 break; 9051 case MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID: 9052 updateActiveAssistantServiceUids(); 9053 break; 9054 9055 case MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR: 9056 dispatchDeviceVolumeBehavior((AudioDeviceAttributes) msg.obj, msg.arg1); 9057 break; 9058 9059 case MSG_ROTATION_UPDATE: 9060 // rotation parameter format: "rotation=x" where x is one of 0, 90, 180, 270 9061 mAudioSystem.setParameters((String) msg.obj); 9062 break; 9063 9064 case MSG_FOLD_UPDATE: 9065 // fold parameter format: "device_folded=x" where x is one of on, off 9066 mAudioSystem.setParameters((String) msg.obj); 9067 break; 9068 9069 case MSG_NO_LOG_FOR_PLAYER_I: 9070 mPlaybackMonitor.ignorePlayerIId(msg.arg1); 9071 break; 9072 } 9073 } 9074 } 9075 9076 private class SettingsObserver extends ContentObserver { 9077 SettingsObserver()9078 SettingsObserver() { 9079 super(new Handler()); 9080 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9081 Settings.Global.ZEN_MODE), false, this); 9082 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9083 Settings.Global.ZEN_MODE_CONFIG_ETAG), false, this); 9084 mContentResolver.registerContentObserver(Settings.System.getUriFor( 9085 Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this); 9086 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9087 Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this); 9088 mContentResolver.registerContentObserver(Settings.System.getUriFor( 9089 Settings.System.MASTER_MONO), false, this); 9090 mContentResolver.registerContentObserver(Settings.System.getUriFor( 9091 Settings.System.MASTER_BALANCE), false, this); 9092 9093 mEncodedSurroundMode = mSettings.getGlobalInt( 9094 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT, 9095 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 9096 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9097 Settings.Global.ENCODED_SURROUND_OUTPUT), false, this); 9098 mEnabledSurroundFormats = mSettings.getGlobalString( 9099 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 9100 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 9101 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS), false, this); 9102 9103 mContentResolver.registerContentObserver(Settings.Secure.getUriFor( 9104 Settings.Secure.VOICE_INTERACTION_SERVICE), false, this); 9105 } 9106 9107 @Override onChange(boolean selfChange)9108 public void onChange(boolean selfChange) { 9109 super.onChange(selfChange); 9110 // FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode. 9111 // However there appear to be some missing locks around mRingerAndZenModeMutedStreams 9112 // and mRingerModeAffectedStreams, so will leave this synchronized for now. 9113 // mRingerAndZenModeMutedStreams and mMuteAffectedStreams are safe (only accessed once). 9114 synchronized (mSettingsLock) { 9115 if (updateRingerAndZenModeAffectedStreams()) { 9116 /* 9117 * Ensure all stream types that should be affected by ringer mode 9118 * are in the proper state. 9119 */ 9120 setRingerModeInt(getRingerModeInternal(), false); 9121 } 9122 readDockAudioSettings(mContentResolver); 9123 updateMasterMono(mContentResolver); 9124 updateMasterBalance(mContentResolver); 9125 updateEncodedSurroundOutput(); 9126 sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged); 9127 updateAssistantUIdLocked(/* forceUpdate= */ false); 9128 } 9129 } 9130 updateEncodedSurroundOutput()9131 private void updateEncodedSurroundOutput() { 9132 int newSurroundMode = mSettings.getGlobalInt( 9133 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT, 9134 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 9135 // Did it change? 9136 if (mEncodedSurroundMode != newSurroundMode) { 9137 // Send to AudioPolicyManager 9138 sendEncodedSurroundMode(newSurroundMode, "SettingsObserver"); 9139 mDeviceBroker.toggleHdmiIfConnected_Async(); 9140 mEncodedSurroundMode = newSurroundMode; 9141 mSurroundModeChanged = true; 9142 } else { 9143 mSurroundModeChanged = false; 9144 } 9145 } 9146 } 9147 avrcpSupportsAbsoluteVolume(String address, boolean support)9148 private void avrcpSupportsAbsoluteVolume(String address, boolean support) { 9149 // address is not used for now, but may be used when multiple a2dp devices are supported 9150 sVolumeLogger.log(new AudioEventLogger.StringEvent("avrcpSupportsAbsoluteVolume addr=" 9151 + address + " support=" + support).printLog(TAG)); 9152 mDeviceBroker.setAvrcpAbsoluteVolumeSupported(support); 9153 setAvrcpAbsoluteVolumeSupported(support); 9154 } 9155 setAvrcpAbsoluteVolumeSupported(boolean support)9156 /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean support) { 9157 mAvrcpAbsVolSupported = support; 9158 sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE, 9159 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, 9160 mStreamStates[AudioSystem.STREAM_MUSIC], 0); 9161 } 9162 9163 /** 9164 * @return true if there is currently a registered dynamic mixing policy that affects media 9165 * and is not a render + loopback policy 9166 */ 9167 // only public for mocking/spying 9168 @VisibleForTesting hasMediaDynamicPolicy()9169 public boolean hasMediaDynamicPolicy() { 9170 synchronized (mAudioPolicies) { 9171 if (mAudioPolicies.isEmpty()) { 9172 return false; 9173 } 9174 final Collection<AudioPolicyProxy> appColl = mAudioPolicies.values(); 9175 for (AudioPolicyProxy app : appColl) { 9176 if (app.hasMixAffectingUsage(AudioAttributes.USAGE_MEDIA, 9177 AudioMix.ROUTE_FLAG_LOOP_BACK_RENDER)) { 9178 return true; 9179 } 9180 } 9181 return false; 9182 } 9183 } 9184 9185 /** only public for mocking/spying, do not call outside of AudioService */ 9186 @VisibleForTesting checkMusicActive(int deviceType, String caller)9187 public void checkMusicActive(int deviceType, String caller) { 9188 if (mSafeMediaVolumeDevices.contains(deviceType)) { 9189 scheduleMusicActiveCheck(); 9190 } 9191 } 9192 9193 /** 9194 * Receiver for misc intent broadcasts the Phone app cares about. 9195 */ 9196 private class AudioServiceBroadcastReceiver extends BroadcastReceiver { 9197 @Override onReceive(Context context, Intent intent)9198 public void onReceive(Context context, Intent intent) { 9199 final String action = intent.getAction(); 9200 int outDevice; 9201 int inDevice; 9202 int state; 9203 9204 if (action.equals(Intent.ACTION_DOCK_EVENT)) { 9205 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 9206 Intent.EXTRA_DOCK_STATE_UNDOCKED); 9207 int config; 9208 switch (dockState) { 9209 case Intent.EXTRA_DOCK_STATE_DESK: 9210 config = AudioSystem.FORCE_BT_DESK_DOCK; 9211 break; 9212 case Intent.EXTRA_DOCK_STATE_CAR: 9213 config = AudioSystem.FORCE_BT_CAR_DOCK; 9214 break; 9215 case Intent.EXTRA_DOCK_STATE_LE_DESK: 9216 config = AudioSystem.FORCE_ANALOG_DOCK; 9217 break; 9218 case Intent.EXTRA_DOCK_STATE_HE_DESK: 9219 config = AudioSystem.FORCE_DIGITAL_DOCK; 9220 break; 9221 case Intent.EXTRA_DOCK_STATE_UNDOCKED: 9222 default: 9223 config = AudioSystem.FORCE_NONE; 9224 } 9225 // Low end docks have a menu to enable or disable audio 9226 // (see mDockAudioMediaEnabled) 9227 if (!((dockState == Intent.EXTRA_DOCK_STATE_LE_DESK) 9228 || ((dockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) 9229 && (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK)))) { 9230 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, config, 9231 "ACTION_DOCK_EVENT intent"); 9232 } 9233 mDockState = dockState; 9234 } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED) 9235 || action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { 9236 mDeviceBroker.receiveBtEvent(intent); 9237 } else if (action.equals(Intent.ACTION_SCREEN_ON)) { 9238 if (mMonitorRotation) { 9239 RotationHelper.enable(); 9240 } 9241 AudioSystem.setParameters("screen_state=on"); 9242 } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { 9243 if (mMonitorRotation) { 9244 //reduce wakeups (save current) by only listening when display is on 9245 RotationHelper.disable(); 9246 } 9247 AudioSystem.setParameters("screen_state=off"); 9248 } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) { 9249 handleConfigurationChanged(context); 9250 } else if (action.equals(Intent.ACTION_USER_SWITCHED)) { 9251 if (mUserSwitchedReceived) { 9252 // attempt to stop music playback for background user except on first user 9253 // switch (i.e. first boot) 9254 mDeviceBroker.postBroadcastBecomingNoisy(); 9255 } 9256 mUserSwitchedReceived = true; 9257 // the current audio focus owner is no longer valid 9258 mMediaFocusControl.discardAudioFocusOwner(); 9259 9260 if (mSupportsMicPrivacyToggle) { 9261 mMicMuteFromPrivacyToggle = mSensorPrivacyManagerInternal 9262 .isSensorPrivacyEnabled(getCurrentUserId(), 9263 SensorPrivacyManager.Sensors.MICROPHONE); 9264 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); 9265 } 9266 9267 // load volume settings for new user 9268 readAudioSettings(true /*userSwitch*/); 9269 // preserve STREAM_MUSIC volume from one user to the next. 9270 sendMsg(mAudioHandler, 9271 MSG_SET_ALL_VOLUMES, 9272 SENDMSG_QUEUE, 9273 0, 9274 0, 9275 mStreamStates[AudioSystem.STREAM_MUSIC], 0); 9276 } else if (action.equals(Intent.ACTION_USER_BACKGROUND)) { 9277 // Disable audio recording for the background user/profile 9278 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 9279 if (userId >= 0) { 9280 // TODO Kill recording streams instead of killing processes holding permission 9281 UserInfo userInfo = UserManagerService.getInstance().getUserInfo(userId); 9282 killBackgroundUserProcessesWithRecordAudioPermission(userInfo); 9283 } 9284 UserManagerService.getInstance().setUserRestriction( 9285 UserManager.DISALLOW_RECORD_AUDIO, true, userId); 9286 } else if (action.equals(Intent.ACTION_USER_FOREGROUND)) { 9287 // Enable audio recording for foreground user/profile 9288 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 9289 UserManagerService.getInstance().setUserRestriction( 9290 UserManager.DISALLOW_RECORD_AUDIO, false, userId); 9291 } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { 9292 state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); 9293 if (state == BluetoothAdapter.STATE_OFF || 9294 state == BluetoothAdapter.STATE_TURNING_OFF) { 9295 mDeviceBroker.disconnectAllBluetoothProfiles(); 9296 } 9297 } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) || 9298 action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) { 9299 handleAudioEffectBroadcast(context, intent); 9300 } else if (action.equals(Intent.ACTION_PACKAGES_SUSPENDED)) { 9301 final int[] suspendedUids = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST); 9302 final String[] suspendedPackages = 9303 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 9304 if (suspendedPackages == null || suspendedUids == null 9305 || suspendedPackages.length != suspendedUids.length) { 9306 return; 9307 } 9308 for (int i = 0; i < suspendedUids.length; i++) { 9309 if (!TextUtils.isEmpty(suspendedPackages[i])) { 9310 mMediaFocusControl.noFocusForSuspendedApp( 9311 suspendedPackages[i], suspendedUids[i]); 9312 } 9313 } 9314 } else if (action.equals(ACTION_CHECK_MUSIC_ACTIVE)) { 9315 onCheckMusicActive(ACTION_CHECK_MUSIC_ACTIVE); 9316 } 9317 } 9318 } // end class AudioServiceBroadcastReceiver 9319 9320 private class AudioServiceUserRestrictionsListener implements UserRestrictionsListener { 9321 9322 @Override onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions)9323 public void onUserRestrictionsChanged(int userId, Bundle newRestrictions, 9324 Bundle prevRestrictions) { 9325 // Update mic mute state. 9326 { 9327 final boolean wasRestricted = 9328 prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE); 9329 final boolean isRestricted = 9330 newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE); 9331 if (wasRestricted != isRestricted) { 9332 mMicMuteFromRestrictions = isRestricted; 9333 setMicrophoneMuteNoCallerCheck(userId); 9334 } 9335 } 9336 9337 // Update speaker mute state. 9338 { 9339 final boolean wasRestricted = 9340 prevRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME) 9341 || prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE); 9342 final boolean isRestricted = 9343 newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME) 9344 || newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE); 9345 if (wasRestricted != isRestricted) { 9346 setMasterMuteInternalNoCallerCheck(isRestricted, /* flags =*/ 0, userId); 9347 } 9348 } 9349 } 9350 } // end class AudioServiceUserRestrictionsListener 9351 handleAudioEffectBroadcast(Context context, Intent intent)9352 private void handleAudioEffectBroadcast(Context context, Intent intent) { 9353 String target = intent.getPackage(); 9354 if (target != null) { 9355 Log.w(TAG, "effect broadcast already targeted to " + target); 9356 return; 9357 } 9358 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 9359 // TODO this should target a user-selected panel 9360 List<ResolveInfo> ril = context.getPackageManager().queryBroadcastReceivers( 9361 intent, 0 /* flags */); 9362 if (ril != null && ril.size() != 0) { 9363 ResolveInfo ri = ril.get(0); 9364 if (ri != null && ri.activityInfo != null && ri.activityInfo.packageName != null) { 9365 intent.setPackage(ri.activityInfo.packageName); 9366 context.sendBroadcastAsUser(intent, UserHandle.ALL); 9367 return; 9368 } 9369 } 9370 Log.w(TAG, "couldn't find receiver package for effect intent"); 9371 } 9372 killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser)9373 private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) { 9374 PackageManager pm = mContext.getPackageManager(); 9375 // Find the home activity of the user. It should not be killed to avoid expensive restart, 9376 // when the user switches back. For managed profiles, we should kill all recording apps 9377 ComponentName homeActivityName = null; 9378 if (!oldUser.isManagedProfile()) { 9379 homeActivityName = LocalServices.getService( 9380 ActivityTaskManagerInternal.class).getHomeActivityForUser(oldUser.id); 9381 } 9382 final String[] permissions = { Manifest.permission.RECORD_AUDIO }; 9383 List<PackageInfo> packages; 9384 try { 9385 packages = AppGlobals.getPackageManager() 9386 .getPackagesHoldingPermissions(permissions, 0, oldUser.id).getList(); 9387 } catch (RemoteException e) { 9388 throw new AndroidRuntimeException(e); 9389 } 9390 for (int j = packages.size() - 1; j >= 0; j--) { 9391 PackageInfo pkg = packages.get(j); 9392 // Skip system processes 9393 if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) { 9394 continue; 9395 } 9396 // Skip packages that have permission to interact across users 9397 if (pm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS, pkg.packageName) 9398 == PackageManager.PERMISSION_GRANTED) { 9399 continue; 9400 } 9401 if (homeActivityName != null 9402 && pkg.packageName.equals(homeActivityName.getPackageName()) 9403 && pkg.applicationInfo.isSystemApp()) { 9404 continue; 9405 } 9406 try { 9407 final int uid = pkg.applicationInfo.uid; 9408 ActivityManager.getService().killUid(UserHandle.getAppId(uid), 9409 UserHandle.getUserId(uid), 9410 "killBackgroundUserProcessesWithAudioRecordPermission"); 9411 } catch (RemoteException e) { 9412 Log.w(TAG, "Error calling killUid", e); 9413 } 9414 } 9415 } 9416 9417 9418 //========================================================================================== 9419 // Audio Focus 9420 //========================================================================================== 9421 /** 9422 * Returns whether a focus request is eligible to force ducking. 9423 * Will return true if: 9424 * - the AudioAttributes have a usage of USAGE_ASSISTANCE_ACCESSIBILITY, 9425 * - the focus request is AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 9426 * - the associated Bundle has KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING set to true, 9427 * - the uid of the requester is a known accessibility service or root. 9428 * @param aa AudioAttributes of the focus request 9429 * @param uid uid of the focus requester 9430 * @return true if ducking is to be forced 9431 */ forceFocusDuckingForAccessibility(@ullable AudioAttributes aa, int request, int uid)9432 private boolean forceFocusDuckingForAccessibility(@Nullable AudioAttributes aa, 9433 int request, int uid) { 9434 if (aa == null || aa.getUsage() != AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY 9435 || request != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) { 9436 return false; 9437 } 9438 final Bundle extraInfo = aa.getBundle(); 9439 if (extraInfo == null || 9440 !extraInfo.getBoolean(AudioFocusRequest.KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING)) { 9441 return false; 9442 } 9443 if (uid == 0) { 9444 return true; 9445 } 9446 synchronized (mAccessibilityServiceUidsLock) { 9447 if (mAccessibilityServiceUids != null) { 9448 int callingUid = Binder.getCallingUid(); 9449 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 9450 if (mAccessibilityServiceUids[i] == callingUid) { 9451 return true; 9452 } 9453 } 9454 } 9455 } 9456 return false; 9457 } 9458 isSupportedSystemUsage(@udioAttributes.AttributeUsage int usage)9459 private boolean isSupportedSystemUsage(@AudioAttributes.AttributeUsage int usage) { 9460 synchronized (mSupportedSystemUsagesLock) { 9461 for (int i = 0; i < mSupportedSystemUsages.length; i++) { 9462 if (mSupportedSystemUsages[i] == usage) { 9463 return true; 9464 } 9465 } 9466 return false; 9467 } 9468 } 9469 validateAudioAttributesUsage(@onNull AudioAttributes audioAttributes)9470 private void validateAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) { 9471 @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage(); 9472 if (AudioAttributes.isSystemUsage(usage)) { 9473 if ((usage == AudioAttributes.USAGE_CALL_ASSISTANT 9474 && (audioAttributes.getAllFlags() & AudioAttributes.FLAG_CALL_REDIRECTION) != 0 9475 && callerHasPermission(Manifest.permission.CALL_AUDIO_INTERCEPTION)) 9476 || callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)) { 9477 if (!isSupportedSystemUsage(usage)) { 9478 throw new IllegalArgumentException( 9479 "Unsupported usage " + AudioAttributes.usageToString(usage)); 9480 } 9481 } else { 9482 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission"); 9483 } 9484 } 9485 } 9486 isValidAudioAttributesUsage(@onNull AudioAttributes audioAttributes)9487 private boolean isValidAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) { 9488 @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage(); 9489 if (AudioAttributes.isSystemUsage(usage)) { 9490 return isSupportedSystemUsage(usage) 9491 && ((usage == AudioAttributes.USAGE_CALL_ASSISTANT 9492 && (audioAttributes.getAllFlags() 9493 & AudioAttributes.FLAG_CALL_REDIRECTION) != 0 9494 && callerHasPermission(Manifest.permission.CALL_AUDIO_INTERCEPTION)) 9495 || callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)); 9496 } 9497 return true; 9498 } 9499 requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk)9500 public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, 9501 IAudioFocusDispatcher fd, String clientId, String callingPackageName, 9502 String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk) { 9503 if ((flags & AudioManager.AUDIOFOCUS_FLAG_TEST) != 0) { 9504 throw new IllegalArgumentException("Invalid test flag"); 9505 } 9506 final int uid = Binder.getCallingUid(); 9507 MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus") 9508 .setUid(uid) 9509 //.putInt("durationHint", durationHint) 9510 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) 9511 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 9512 .set(MediaMetrics.Property.EVENT, "requestAudioFocus") 9513 .set(MediaMetrics.Property.FLAGS, flags); 9514 9515 // permission checks 9516 if (aa != null && !isValidAudioAttributesUsage(aa)) { 9517 final String reason = "Request using unsupported usage"; 9518 Log.w(TAG, reason); 9519 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 9520 .record(); 9521 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9522 } 9523 if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) { 9524 if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) { 9525 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 9526 android.Manifest.permission.MODIFY_PHONE_STATE)) { 9527 final String reason = "Invalid permission to (un)lock audio focus"; 9528 Log.e(TAG, reason, new Exception()); 9529 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 9530 .record(); 9531 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9532 } 9533 } else { 9534 // only a registered audio policy can be used to lock focus 9535 synchronized (mAudioPolicies) { 9536 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 9537 final String reason = 9538 "Invalid unregistered AudioPolicy to (un)lock audio focus"; 9539 Log.e(TAG, reason); 9540 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 9541 .record(); 9542 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9543 } 9544 } 9545 } 9546 } 9547 9548 if (callingPackageName == null || clientId == null || aa == null) { 9549 final String reason = "Invalid null parameter to request audio focus"; 9550 Log.e(TAG, reason); 9551 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 9552 .record(); 9553 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9554 } 9555 mmi.record(); 9556 return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd, 9557 clientId, callingPackageName, attributionTag, flags, sdk, 9558 forceFocusDuckingForAccessibility(aa, durationHint, uid), -1 /*testUid, ignored*/); 9559 } 9560 9561 /** 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)9562 public int requestAudioFocusForTest(AudioAttributes aa, int durationHint, IBinder cb, 9563 IAudioFocusDispatcher fd, String clientId, String callingPackageName, 9564 int flags, int fakeUid, int sdk) { 9565 if (!enforceQueryAudioStateForTest("focus request")) { 9566 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9567 } 9568 if (callingPackageName == null || clientId == null || aa == null) { 9569 final String reason = "Invalid null parameter to request audio focus"; 9570 Log.e(TAG, reason); 9571 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9572 } 9573 return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd, 9574 clientId, callingPackageName, null, flags, 9575 sdk, false /*forceDuck*/, fakeUid); 9576 } 9577 abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)9578 public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, 9579 String callingPackageName) { 9580 MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus") 9581 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) 9582 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 9583 .set(MediaMetrics.Property.EVENT, "abandonAudioFocus"); 9584 9585 if (aa != null && !isValidAudioAttributesUsage(aa)) { 9586 Log.w(TAG, "Request using unsupported usage."); 9587 mmi.set(MediaMetrics.Property.EARLY_RETURN, "unsupported usage").record(); 9588 9589 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9590 } 9591 mmi.record(); 9592 return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName); 9593 } 9594 9595 /** see {@link AudioManager#abandonAudioFocusForTest(AudioFocusRequest, String)} */ abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)9596 public int abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, 9597 AudioAttributes aa, String callingPackageName) { 9598 if (!enforceQueryAudioStateForTest("focus abandon")) { 9599 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 9600 } 9601 return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName); 9602 } 9603 unregisterAudioFocusClient(String clientId)9604 public void unregisterAudioFocusClient(String clientId) { 9605 new MediaMetrics.Item(mMetricsId + "focus") 9606 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 9607 .set(MediaMetrics.Property.EVENT, "unregisterAudioFocusClient") 9608 .record(); 9609 mMediaFocusControl.unregisterAudioFocusClient(clientId); 9610 } 9611 getCurrentAudioFocus()9612 public int getCurrentAudioFocus() { 9613 return mMediaFocusControl.getCurrentAudioFocus(); 9614 } 9615 getFocusRampTimeMs(int focusGain, AudioAttributes attr)9616 public int getFocusRampTimeMs(int focusGain, AudioAttributes attr) { 9617 return mMediaFocusControl.getFocusRampTimeMs(focusGain, attr); 9618 } 9619 9620 /** only public for mocking/spying, do not call outside of AudioService */ 9621 @VisibleForTesting hasAudioFocusUsers()9622 public boolean hasAudioFocusUsers() { 9623 return mMediaFocusControl.hasAudioFocusUsers(); 9624 } 9625 9626 /** see {@link AudioManager#getFadeOutDurationOnFocusLossMillis(AudioAttributes)} */ getFadeOutDurationOnFocusLossMillis(AudioAttributes aa)9627 public long getFadeOutDurationOnFocusLossMillis(AudioAttributes aa) { 9628 if (!enforceQueryAudioStateForTest("fade out duration")) { 9629 return 0; 9630 } 9631 return mMediaFocusControl.getFadeOutDurationOnFocusLossMillis(aa); 9632 } 9633 enforceQueryAudioStateForTest(String mssg)9634 private boolean enforceQueryAudioStateForTest(String mssg) { 9635 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 9636 Manifest.permission.QUERY_AUDIO_STATE)) { 9637 final String reason = "Doesn't have QUERY_AUDIO_STATE permission for " 9638 + mssg + " test API"; 9639 Log.e(TAG, reason, new Exception()); 9640 return false; 9641 } 9642 return true; 9643 } 9644 9645 //========================================================================================== 9646 private final @NonNull SpatializerHelper mSpatializerHelper; 9647 /** 9648 * Initialized from property ro.audio.spatializer_enabled 9649 * Should only be 1 when the device ships with a Spatializer effect 9650 */ 9651 private final boolean mHasSpatializerEffect; 9652 /** 9653 * Default value for the spatial audio feature 9654 */ 9655 private static final boolean SPATIAL_AUDIO_ENABLED_DEFAULT = true; 9656 enforceModifyDefaultAudioEffectsPermission()9657 private void enforceModifyDefaultAudioEffectsPermission() { 9658 if (mContext.checkCallingOrSelfPermission( 9659 android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) 9660 != PackageManager.PERMISSION_GRANTED) { 9661 throw new SecurityException("Missing MODIFY_DEFAULT_AUDIO_EFFECTS permission"); 9662 } 9663 } 9664 9665 /** 9666 * Returns the immersive audio level that the platform is capable of 9667 * @see Spatializer#getImmersiveAudioLevel() 9668 */ getSpatializerImmersiveAudioLevel()9669 public int getSpatializerImmersiveAudioLevel() { 9670 return mSpatializerHelper.getCapableImmersiveAudioLevel(); 9671 } 9672 9673 /** @see Spatializer#isEnabled() */ isSpatializerEnabled()9674 public boolean isSpatializerEnabled() { 9675 return mSpatializerHelper.isEnabled(); 9676 } 9677 9678 /** @see Spatializer#isAvailable() */ isSpatializerAvailable()9679 public boolean isSpatializerAvailable() { 9680 return mSpatializerHelper.isAvailable(); 9681 } 9682 9683 /** @see Spatializer#isAvailableForDevice(AudioDeviceAttributes) */ isSpatializerAvailableForDevice(@onNull AudioDeviceAttributes device)9684 public boolean isSpatializerAvailableForDevice(@NonNull AudioDeviceAttributes device) { 9685 enforceModifyDefaultAudioEffectsPermission(); 9686 return mSpatializerHelper.isAvailableForDevice(Objects.requireNonNull(device)); 9687 } 9688 9689 /** @see Spatializer#hasHeadTracker(AudioDeviceAttributes) */ hasHeadTracker(@onNull AudioDeviceAttributes device)9690 public boolean hasHeadTracker(@NonNull AudioDeviceAttributes device) { 9691 enforceModifyDefaultAudioEffectsPermission(); 9692 return mSpatializerHelper.hasHeadTracker(Objects.requireNonNull(device)); 9693 } 9694 9695 /** @see Spatializer#setHeadTrackerEnabled(boolean, AudioDeviceAttributes) */ setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device)9696 public void setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device) { 9697 enforceModifyDefaultAudioEffectsPermission(); 9698 mSpatializerHelper.setHeadTrackerEnabled(enabled, Objects.requireNonNull(device)); 9699 } 9700 9701 /** @see Spatializer#isHeadTrackerEnabled(AudioDeviceAttributes) */ isHeadTrackerEnabled(@onNull AudioDeviceAttributes device)9702 public boolean isHeadTrackerEnabled(@NonNull AudioDeviceAttributes device) { 9703 enforceModifyDefaultAudioEffectsPermission(); 9704 return mSpatializerHelper.isHeadTrackerEnabled(Objects.requireNonNull(device)); 9705 } 9706 9707 /** @see Spatializer#isHeadTrackerAvailable() */ isHeadTrackerAvailable()9708 public boolean isHeadTrackerAvailable() { 9709 return mSpatializerHelper.isHeadTrackerAvailable(); 9710 } 9711 9712 /** @see Spatializer#setSpatializerEnabled(boolean) */ setSpatializerEnabled(boolean enabled)9713 public void setSpatializerEnabled(boolean enabled) { 9714 enforceModifyDefaultAudioEffectsPermission(); 9715 mSpatializerHelper.setFeatureEnabled(enabled); 9716 } 9717 9718 /** @see Spatializer#canBeSpatialized() */ canBeSpatialized( @onNull AudioAttributes attributes, @NonNull AudioFormat format)9719 public boolean canBeSpatialized( 9720 @NonNull AudioAttributes attributes, @NonNull AudioFormat format) { 9721 Objects.requireNonNull(attributes); 9722 Objects.requireNonNull(format); 9723 return mSpatializerHelper.canBeSpatialized(attributes, format); 9724 } 9725 9726 /** @see Spatializer.SpatializerInfoDispatcherStub */ registerSpatializerCallback( @onNull ISpatializerCallback cb)9727 public void registerSpatializerCallback( 9728 @NonNull ISpatializerCallback cb) { 9729 Objects.requireNonNull(cb); 9730 mSpatializerHelper.registerStateCallback(cb); 9731 } 9732 9733 /** @see Spatializer.SpatializerInfoDispatcherStub */ unregisterSpatializerCallback( @onNull ISpatializerCallback cb)9734 public void unregisterSpatializerCallback( 9735 @NonNull ISpatializerCallback cb) { 9736 Objects.requireNonNull(cb); 9737 mSpatializerHelper.unregisterStateCallback(cb); 9738 } 9739 9740 /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */ registerSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)9741 public void registerSpatializerHeadTrackingCallback( 9742 @NonNull ISpatializerHeadTrackingModeCallback cb) { 9743 enforceModifyDefaultAudioEffectsPermission(); 9744 Objects.requireNonNull(cb); 9745 mSpatializerHelper.registerHeadTrackingModeCallback(cb); 9746 } 9747 9748 /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */ unregisterSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)9749 public void unregisterSpatializerHeadTrackingCallback( 9750 @NonNull ISpatializerHeadTrackingModeCallback cb) { 9751 enforceModifyDefaultAudioEffectsPermission(); 9752 Objects.requireNonNull(cb); 9753 mSpatializerHelper.unregisterHeadTrackingModeCallback(cb); 9754 } 9755 9756 /** @see Spatializer.SpatializerHeadTrackerAvailableDispatcherStub */ registerSpatializerHeadTrackerAvailableCallback( @onNull ISpatializerHeadTrackerAvailableCallback cb, boolean register)9757 public void registerSpatializerHeadTrackerAvailableCallback( 9758 @NonNull ISpatializerHeadTrackerAvailableCallback cb, boolean register) { 9759 Objects.requireNonNull(cb); 9760 mSpatializerHelper.registerHeadTrackerAvailableCallback(cb, register); 9761 } 9762 9763 /** @see Spatializer#setOnHeadToSoundstagePoseUpdatedListener */ registerHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)9764 public void registerHeadToSoundstagePoseCallback( 9765 @NonNull ISpatializerHeadToSoundStagePoseCallback cb) { 9766 enforceModifyDefaultAudioEffectsPermission(); 9767 Objects.requireNonNull(cb); 9768 mSpatializerHelper.registerHeadToSoundstagePoseCallback(cb); 9769 } 9770 9771 /** @see Spatializer#clearOnHeadToSoundstagePoseUpdatedListener */ unregisterHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)9772 public void unregisterHeadToSoundstagePoseCallback( 9773 @NonNull ISpatializerHeadToSoundStagePoseCallback cb) { 9774 enforceModifyDefaultAudioEffectsPermission(); 9775 Objects.requireNonNull(cb); 9776 mSpatializerHelper.unregisterHeadToSoundstagePoseCallback(cb); 9777 } 9778 9779 /** @see Spatializer#getSpatializerCompatibleAudioDevices() */ getSpatializerCompatibleAudioDevices()9780 public @NonNull List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices() { 9781 enforceModifyDefaultAudioEffectsPermission(); 9782 return mSpatializerHelper.getCompatibleAudioDevices(); 9783 } 9784 9785 /** @see Spatializer#addSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */ addSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)9786 public void addSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { 9787 enforceModifyDefaultAudioEffectsPermission(); 9788 Objects.requireNonNull(ada); 9789 mSpatializerHelper.addCompatibleAudioDevice(ada); 9790 } 9791 9792 /** @see Spatializer#removeSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */ removeSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)9793 public void removeSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { 9794 enforceModifyDefaultAudioEffectsPermission(); 9795 Objects.requireNonNull(ada); 9796 mSpatializerHelper.removeCompatibleAudioDevice(ada); 9797 } 9798 9799 /** @see Spatializer#getSupportedHeadTrackingModes() */ getSupportedHeadTrackingModes()9800 public int[] getSupportedHeadTrackingModes() { 9801 enforceModifyDefaultAudioEffectsPermission(); 9802 return mSpatializerHelper.getSupportedHeadTrackingModes(); 9803 } 9804 9805 /** @see Spatializer#getHeadTrackingMode() */ getActualHeadTrackingMode()9806 public int getActualHeadTrackingMode() { 9807 enforceModifyDefaultAudioEffectsPermission(); 9808 return mSpatializerHelper.getActualHeadTrackingMode(); 9809 } 9810 9811 /** @see Spatializer#getDesiredHeadTrackingMode() */ getDesiredHeadTrackingMode()9812 public int getDesiredHeadTrackingMode() { 9813 enforceModifyDefaultAudioEffectsPermission(); 9814 return mSpatializerHelper.getDesiredHeadTrackingMode(); 9815 } 9816 9817 /** @see Spatializer#setGlobalTransform */ setSpatializerGlobalTransform(@onNull float[] transform)9818 public void setSpatializerGlobalTransform(@NonNull float[] transform) { 9819 enforceModifyDefaultAudioEffectsPermission(); 9820 Objects.requireNonNull(transform); 9821 mSpatializerHelper.setGlobalTransform(transform); 9822 } 9823 9824 /** @see Spatializer#recenterHeadTracker() */ recenterHeadTracker()9825 public void recenterHeadTracker() { 9826 enforceModifyDefaultAudioEffectsPermission(); 9827 mSpatializerHelper.recenterHeadTracker(); 9828 } 9829 9830 /** @see Spatializer#setDesiredHeadTrackingMode */ setDesiredHeadTrackingMode(@patializer.HeadTrackingModeSet int mode)9831 public void setDesiredHeadTrackingMode(@Spatializer.HeadTrackingModeSet int mode) { 9832 enforceModifyDefaultAudioEffectsPermission(); 9833 switch(mode) { 9834 case Spatializer.HEAD_TRACKING_MODE_DISABLED: 9835 case Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD: 9836 case Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE: 9837 break; 9838 default: 9839 return; 9840 } 9841 mSpatializerHelper.setDesiredHeadTrackingMode(mode); 9842 } 9843 9844 /** @see Spatializer#setEffectParameter */ setSpatializerParameter(int key, @NonNull byte[] value)9845 public void setSpatializerParameter(int key, @NonNull byte[] value) { 9846 enforceModifyDefaultAudioEffectsPermission(); 9847 Objects.requireNonNull(value); 9848 mSpatializerHelper.setEffectParameter(key, value); 9849 } 9850 9851 /** @see Spatializer#getEffectParameter */ getSpatializerParameter(int key, @NonNull byte[] value)9852 public void getSpatializerParameter(int key, @NonNull byte[] value) { 9853 enforceModifyDefaultAudioEffectsPermission(); 9854 Objects.requireNonNull(value); 9855 mSpatializerHelper.getEffectParameter(key, value); 9856 } 9857 9858 /** @see Spatializer#getOutput */ getSpatializerOutput()9859 public int getSpatializerOutput() { 9860 enforceModifyDefaultAudioEffectsPermission(); 9861 return mSpatializerHelper.getOutput(); 9862 } 9863 9864 /** @see Spatializer#setOnSpatializerOutputChangedListener */ registerSpatializerOutputCallback(ISpatializerOutputCallback cb)9865 public void registerSpatializerOutputCallback(ISpatializerOutputCallback cb) { 9866 enforceModifyDefaultAudioEffectsPermission(); 9867 Objects.requireNonNull(cb); 9868 mSpatializerHelper.registerSpatializerOutputCallback(cb); 9869 } 9870 9871 /** @see Spatializer#clearOnSpatializerOutputChangedListener */ unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb)9872 public void unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb) { 9873 enforceModifyDefaultAudioEffectsPermission(); 9874 Objects.requireNonNull(cb); 9875 mSpatializerHelper.unregisterSpatializerOutputCallback(cb); 9876 } 9877 9878 /** 9879 * post a message to schedule init/release of head tracking sensors 9880 * whether to initialize or release sensors is based on the state of spatializer 9881 */ postInitSpatializerHeadTrackingSensors()9882 void postInitSpatializerHeadTrackingSensors() { 9883 sendMsg(mAudioHandler, 9884 MSG_INIT_HEADTRACKING_SENSORS, 9885 SENDMSG_REPLACE, 9886 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0); 9887 } 9888 9889 /** 9890 * post a message to schedule a reset of the spatializer state 9891 */ postResetSpatializer()9892 void postResetSpatializer() { 9893 sendMsg(mAudioHandler, 9894 MSG_RESET_SPATIALIZER, 9895 SENDMSG_REPLACE, 9896 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0); 9897 } 9898 onInitSpatializer()9899 void onInitSpatializer() { 9900 final String settings = mSettings.getSecureStringForUser(mContentResolver, 9901 Settings.Secure.SPATIAL_AUDIO_ENABLED, UserHandle.USER_CURRENT); 9902 if (settings == null) { 9903 Log.e(TAG, "error reading spatial audio device settings"); 9904 } 9905 mSpatializerHelper.init(/*effectExpected*/ mHasSpatializerEffect, settings); 9906 mSpatializerHelper.setFeatureEnabled(mHasSpatializerEffect); 9907 } 9908 9909 /** 9910 * post a message to persist the spatial audio device settings. 9911 * Message is delayed by 1s on purpose in case of successive changes in quick succession (at 9912 * init time for instance) 9913 * Note this method is made public to work around a Mockito bug where it needs to be public 9914 * in order to be mocked by a test a the same package 9915 * (see https://code.google.com/archive/p/mockito/issues/127) 9916 */ persistSpatialAudioDeviceSettings()9917 public void persistSpatialAudioDeviceSettings() { 9918 sendMsg(mAudioHandler, 9919 MSG_PERSIST_SPATIAL_AUDIO_DEVICE_SETTINGS, 9920 SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0, TAG, 9921 /*delay*/ 1000); 9922 } 9923 onPersistSpatialAudioDeviceSettings()9924 void onPersistSpatialAudioDeviceSettings() { 9925 final String settings = mSpatializerHelper.getSADeviceSettings(); 9926 Log.v(TAG, "saving spatial audio device settings: " + settings); 9927 boolean res = mSettings.putSecureStringForUser(mContentResolver, 9928 Settings.Secure.SPATIAL_AUDIO_ENABLED, 9929 settings, UserHandle.USER_CURRENT); 9930 if (!res) { 9931 Log.e(TAG, "error saving spatial audio device settings: " + settings); 9932 } 9933 } 9934 9935 //========================================================================================== readCameraSoundForced()9936 private boolean readCameraSoundForced() { 9937 return SystemProperties.getBoolean("audio.camerasound.force", false) || 9938 mContext.getResources().getBoolean( 9939 com.android.internal.R.bool.config_camera_sound_forced); 9940 } 9941 9942 //========================================================================================== 9943 private final Object mMuteAwaitConnectionLock = new Object(); 9944 9945 /** 9946 * The device that is expected to be connected soon, and causes players to be muted until 9947 * its connection, or it times out. 9948 * Null when no active muting command, or it has timed out. 9949 */ 9950 @GuardedBy("mMuteAwaitConnectionLock") 9951 private AudioDeviceAttributes mMutingExpectedDevice; 9952 @GuardedBy("mMuteAwaitConnectionLock") 9953 private @Nullable int[] mMutedUsagesAwaitingConnection; 9954 9955 /** @see AudioManager#muteAwaitConnection */ 9956 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection muteAwaitConnection(@onNull int[] usages, @NonNull AudioDeviceAttributes device, long timeOutMs)9957 public void muteAwaitConnection(@NonNull int[] usages, 9958 @NonNull AudioDeviceAttributes device, long timeOutMs) { 9959 Objects.requireNonNull(usages); 9960 Objects.requireNonNull(device); 9961 enforceModifyAudioRoutingPermission(); 9962 if (timeOutMs <= 0 || usages.length == 0) { 9963 throw new IllegalArgumentException("Invalid timeOutMs/usagesToMute"); 9964 } 9965 Log.i(TAG, "muteAwaitConnection dev:" + device + " timeOutMs:" + timeOutMs 9966 + " usages:" + Arrays.toString(usages)); 9967 9968 if (mDeviceBroker.isDeviceConnected(device)) { 9969 // not throwing an exception as there could be a race between a connection (server-side, 9970 // notification of connection in flight) and a mute operation (client-side) 9971 Log.i(TAG, "muteAwaitConnection ignored, device (" + device + ") already connected"); 9972 return; 9973 } 9974 synchronized (mMuteAwaitConnectionLock) { 9975 if (mMutingExpectedDevice != null) { 9976 Log.e(TAG, "muteAwaitConnection ignored, another in progress for device:" 9977 + mMutingExpectedDevice); 9978 throw new IllegalStateException("muteAwaitConnection already in progress"); 9979 } 9980 mMutingExpectedDevice = device; 9981 mMutedUsagesAwaitingConnection = usages; 9982 mPlaybackMonitor.muteAwaitConnection(usages, device, timeOutMs); 9983 } 9984 dispatchMuteAwaitConnection(cb -> { try { 9985 cb.dispatchOnMutedUntilConnection(device, usages); } catch (RemoteException e) { } }); 9986 } 9987 9988 /** @see AudioManager#getMutingExpectedDevice */ getMutingExpectedDevice()9989 public @Nullable AudioDeviceAttributes getMutingExpectedDevice() { 9990 enforceModifyAudioRoutingPermission(); 9991 synchronized (mMuteAwaitConnectionLock) { 9992 return mMutingExpectedDevice; 9993 } 9994 } 9995 9996 /** @see AudioManager#cancelMuteAwaitConnection */ 9997 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection cancelMuteAwaitConnection(@onNull AudioDeviceAttributes device)9998 public void cancelMuteAwaitConnection(@NonNull AudioDeviceAttributes device) { 9999 Objects.requireNonNull(device); 10000 enforceModifyAudioRoutingPermission(); 10001 Log.i(TAG, "cancelMuteAwaitConnection for device:" + device); 10002 final int[] mutedUsages; 10003 synchronized (mMuteAwaitConnectionLock) { 10004 if (mMutingExpectedDevice == null) { 10005 // not throwing an exception as there could be a race between a timeout 10006 // (server-side) and a cancel operation (client-side) 10007 Log.i(TAG, "cancelMuteAwaitConnection ignored, no expected device"); 10008 return; 10009 } 10010 if (!device.equalTypeAddress(mMutingExpectedDevice)) { 10011 Log.e(TAG, "cancelMuteAwaitConnection ignored, got " + device 10012 + "] but expected device is" + mMutingExpectedDevice); 10013 throw new IllegalStateException("cancelMuteAwaitConnection for wrong device"); 10014 } 10015 mutedUsages = mMutedUsagesAwaitingConnection; 10016 mMutingExpectedDevice = null; 10017 mMutedUsagesAwaitingConnection = null; 10018 mPlaybackMonitor.cancelMuteAwaitConnection("cancelMuteAwaitConnection dev:" + device); 10019 } 10020 dispatchMuteAwaitConnection(cb -> { try { cb.dispatchOnUnmutedEvent( 10021 AudioManager.MuteAwaitConnectionCallback.EVENT_CANCEL, device, mutedUsages); 10022 } catch (RemoteException e) { } }); 10023 } 10024 10025 final RemoteCallbackList<IMuteAwaitConnectionCallback> mMuteAwaitConnectionDispatchers = 10026 new RemoteCallbackList<IMuteAwaitConnectionCallback>(); 10027 10028 /** @see AudioManager#registerMuteAwaitConnectionCallback */ registerMuteAwaitConnectionDispatcher(@onNull IMuteAwaitConnectionCallback cb, boolean register)10029 public void registerMuteAwaitConnectionDispatcher(@NonNull IMuteAwaitConnectionCallback cb, 10030 boolean register) { 10031 enforceModifyAudioRoutingPermission(); 10032 if (register) { 10033 mMuteAwaitConnectionDispatchers.register(cb); 10034 } else { 10035 mMuteAwaitConnectionDispatchers.unregister(cb); 10036 } 10037 } 10038 10039 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection checkMuteAwaitConnection()10040 void checkMuteAwaitConnection() { 10041 final AudioDeviceAttributes device; 10042 final int[] mutedUsages; 10043 synchronized (mMuteAwaitConnectionLock) { 10044 if (mMutingExpectedDevice == null) { 10045 return; 10046 } 10047 device = mMutingExpectedDevice; 10048 mutedUsages = mMutedUsagesAwaitingConnection; 10049 if (!mDeviceBroker.isDeviceConnected(device)) { 10050 return; 10051 } 10052 mMutingExpectedDevice = null; 10053 mMutedUsagesAwaitingConnection = null; 10054 mPlaybackMonitor.cancelMuteAwaitConnection( 10055 "checkMuteAwaitConnection device " + device + " connected, unmuting"); 10056 } 10057 dispatchMuteAwaitConnection(cb -> { try { cb.dispatchOnUnmutedEvent( 10058 AudioManager.MuteAwaitConnectionCallback.EVENT_CONNECTION, device, mutedUsages); 10059 } catch (RemoteException e) { } }); 10060 } 10061 10062 /** 10063 * Called by PlaybackActivityMonitor when the timeout hit for the mute on device connection 10064 */ 10065 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection onMuteAwaitConnectionTimeout(@onNull AudioDeviceAttributes timedOutDevice)10066 void onMuteAwaitConnectionTimeout(@NonNull AudioDeviceAttributes timedOutDevice) { 10067 final int[] mutedUsages; 10068 synchronized (mMuteAwaitConnectionLock) { 10069 if (!timedOutDevice.equals(mMutingExpectedDevice)) { 10070 return; 10071 } 10072 Log.i(TAG, "muteAwaitConnection timeout, clearing expected device " 10073 + mMutingExpectedDevice); 10074 mutedUsages = mMutedUsagesAwaitingConnection; 10075 mMutingExpectedDevice = null; 10076 mMutedUsagesAwaitingConnection = null; 10077 } 10078 dispatchMuteAwaitConnection(cb -> { try { 10079 cb.dispatchOnUnmutedEvent( 10080 AudioManager.MuteAwaitConnectionCallback.EVENT_TIMEOUT, 10081 timedOutDevice, mutedUsages); 10082 } catch (RemoteException e) { } }); 10083 } 10084 dispatchMuteAwaitConnection( java.util.function.Consumer<IMuteAwaitConnectionCallback> callback)10085 private void dispatchMuteAwaitConnection( 10086 java.util.function.Consumer<IMuteAwaitConnectionCallback> callback) { 10087 final int nbDispatchers = mMuteAwaitConnectionDispatchers.beginBroadcast(); 10088 // lazy initialization as errors unlikely 10089 ArrayList<IMuteAwaitConnectionCallback> errorList = null; 10090 for (int i = 0; i < nbDispatchers; i++) { 10091 try { 10092 callback.accept(mMuteAwaitConnectionDispatchers.getBroadcastItem(i)); 10093 } catch (Exception e) { 10094 if (errorList == null) { 10095 errorList = new ArrayList<>(1); 10096 } 10097 errorList.add(mMuteAwaitConnectionDispatchers.getBroadcastItem(i)); 10098 } 10099 } 10100 if (errorList != null) { 10101 for (IMuteAwaitConnectionCallback errorItem : errorList) { 10102 mMuteAwaitConnectionDispatchers.unregister(errorItem); 10103 } 10104 } 10105 mMuteAwaitConnectionDispatchers.finishBroadcast(); 10106 } 10107 10108 final RemoteCallbackList<IDeviceVolumeBehaviorDispatcher> mDeviceVolumeBehaviorDispatchers = 10109 new RemoteCallbackList<IDeviceVolumeBehaviorDispatcher>(); 10110 10111 /** 10112 * @see AudioDeviceVolumeManager#addOnDeviceVolumeBehaviorChangedListener and 10113 * AudioDeviceVolumeManager#removeOnDeviceVolumeBehaviorChangedListener 10114 */ registerDeviceVolumeBehaviorDispatcher(boolean register, @NonNull IDeviceVolumeBehaviorDispatcher dispatcher)10115 public void registerDeviceVolumeBehaviorDispatcher(boolean register, 10116 @NonNull IDeviceVolumeBehaviorDispatcher dispatcher) { 10117 enforceQueryStateOrModifyRoutingPermission(); 10118 Objects.requireNonNull(dispatcher); 10119 if (register) { 10120 mDeviceVolumeBehaviorDispatchers.register(dispatcher); 10121 } else { 10122 mDeviceVolumeBehaviorDispatchers.unregister(dispatcher); 10123 } 10124 } 10125 dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior)10126 private void dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior) { 10127 final int dispatchers = mDeviceVolumeBehaviorDispatchers.beginBroadcast(); 10128 for (int i = 0; i < dispatchers; i++) { 10129 try { 10130 mDeviceVolumeBehaviorDispatchers.getBroadcastItem(i) 10131 .dispatchDeviceVolumeBehaviorChanged(device, volumeBehavior); 10132 } catch (RemoteException e) { 10133 } 10134 } 10135 mDeviceVolumeBehaviorDispatchers.finishBroadcast(); 10136 } 10137 10138 //========================================================================================== 10139 // Device orientation 10140 //========================================================================================== 10141 /** 10142 * Handles device configuration changes that may map to a change in rotation. 10143 * Monitoring rotation is optional, and is defined by the definition and value 10144 * of the "ro.audio.monitorRotation" system property. 10145 */ handleConfigurationChanged(Context context)10146 private void handleConfigurationChanged(Context context) { 10147 try { 10148 // reading new configuration "safely" (i.e. under try catch) in case anything 10149 // goes wrong. 10150 Configuration config = context.getResources().getConfiguration(); 10151 sendMsg(mAudioHandler, 10152 MSG_CONFIGURE_SAFE_MEDIA_VOLUME, 10153 SENDMSG_REPLACE, 10154 0, 10155 0, 10156 TAG, 10157 0); 10158 10159 boolean cameraSoundForced = readCameraSoundForced(); 10160 synchronized (mSettingsLock) { 10161 final boolean cameraSoundForcedChanged = (cameraSoundForced != mCameraSoundForced); 10162 mCameraSoundForced = cameraSoundForced; 10163 if (cameraSoundForcedChanged) { 10164 if (!mIsSingleVolume) { 10165 synchronized (VolumeStreamState.class) { 10166 VolumeStreamState s = mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED]; 10167 if (cameraSoundForced) { 10168 s.setAllIndexesToMax(); 10169 mRingerModeAffectedStreams &= 10170 ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 10171 } else { 10172 s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM], TAG); 10173 mRingerModeAffectedStreams |= 10174 (1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 10175 } 10176 } 10177 // take new state into account for streams muted by ringer mode 10178 setRingerModeInt(getRingerModeInternal(), false); 10179 } 10180 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, 10181 cameraSoundForced ? 10182 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE, 10183 "handleConfigurationChanged"); 10184 sendMsg(mAudioHandler, 10185 MSG_SET_ALL_VOLUMES, 10186 SENDMSG_QUEUE, 10187 0, 10188 0, 10189 mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED], 0); 10190 10191 } 10192 } 10193 mVolumeController.setLayoutDirection(config.getLayoutDirection()); 10194 } catch (Exception e) { 10195 Log.e(TAG, "Error handling configuration change: ", e); 10196 } 10197 } 10198 10199 @Override setRingtonePlayer(IRingtonePlayer player)10200 public void setRingtonePlayer(IRingtonePlayer player) { 10201 mContext.enforceCallingOrSelfPermission(REMOTE_AUDIO_PLAYBACK, null); 10202 mRingtonePlayer = player; 10203 } 10204 10205 @Override getRingtonePlayer()10206 public IRingtonePlayer getRingtonePlayer() { 10207 return mRingtonePlayer; 10208 } 10209 10210 @Override startWatchingRoutes(IAudioRoutesObserver observer)10211 public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) { 10212 return mDeviceBroker.startWatchingRoutes(observer); 10213 } 10214 10215 10216 //========================================================================================== 10217 // Safe media volume management. 10218 // MUSIC stream volume level is limited when headphones are connected according to safety 10219 // regulation. When the user attempts to raise the volume above the limit, a warning is 10220 // displayed and the user has to acknowlegde before the volume is actually changed. 10221 // The volume index corresponding to the limit is stored in config_safe_media_volume_index 10222 // property. Platforms with a different limit must set this property accordingly in their 10223 // overlay. 10224 //========================================================================================== 10225 10226 // mSafeMediaVolumeState indicates whether the media volume is limited over headphones. 10227 // It is SAFE_MEDIA_VOLUME_NOT_CONFIGURED at boot time until a network service is connected 10228 // or the configure time is elapsed. It is then set to SAFE_MEDIA_VOLUME_ACTIVE or 10229 // SAFE_MEDIA_VOLUME_DISABLED according to country option. If not SAFE_MEDIA_VOLUME_DISABLED, it 10230 // can be set to SAFE_MEDIA_VOLUME_INACTIVE by calling AudioService.disableSafeMediaVolume() 10231 // (when user opts out). 10232 private static final int SAFE_MEDIA_VOLUME_NOT_CONFIGURED = 0; 10233 private static final int SAFE_MEDIA_VOLUME_DISABLED = 1; 10234 private static final int SAFE_MEDIA_VOLUME_INACTIVE = 2; // confirmed 10235 private static final int SAFE_MEDIA_VOLUME_ACTIVE = 3; // unconfirmed 10236 private int mSafeMediaVolumeState; 10237 private final Object mSafeMediaVolumeStateLock = new Object(); 10238 10239 private int mMcc = 0; 10240 // mSafeMediaVolumeIndex is the cached value of config_safe_media_volume_index property 10241 private int mSafeMediaVolumeIndex; 10242 // mSafeUsbMediaVolumeDbfs is the cached value of the config_safe_media_volume_usb_mB 10243 // property, divided by 100.0. 10244 private float mSafeUsbMediaVolumeDbfs; 10245 // mSafeUsbMediaVolumeIndex is used for USB Headsets and is the music volume UI index 10246 // corresponding to a gain of mSafeUsbMediaVolumeDbfs (defaulting to -37dB) in audio 10247 // flinger mixer. 10248 // We remove -22 dBs from the theoretical -15dB to account for the EQ + bass boost 10249 // amplification when both effects are on with all band gains at maximum. 10250 // This level corresponds to a loudness of 85 dB SPL for the warning to be displayed when 10251 // the headset is compliant to EN 60950 with a max loudness of 100dB SPL. 10252 private int mSafeUsbMediaVolumeIndex; 10253 // mSafeMediaVolumeDevices lists the devices for which safe media volume is enforced, 10254 /*package*/ final Set<Integer> mSafeMediaVolumeDevices = new HashSet<>( 10255 Arrays.asList(AudioSystem.DEVICE_OUT_WIRED_HEADSET, 10256 AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, AudioSystem.DEVICE_OUT_USB_HEADSET)); 10257 // mMusicActiveMs is the cumulative time of music activity since safe volume was disabled. 10258 // When this time reaches UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX, the safe media volume is re-enabled 10259 // automatically. mMusicActiveMs is rounded to a multiple of MUSIC_ACTIVE_POLL_PERIOD_MS. 10260 private int mMusicActiveMs; 10261 private long mLastMusicActiveTimeMs = 0; 10262 private PendingIntent mMusicActiveIntent = null; 10263 private AlarmManager mAlarmManager; 10264 10265 private static final int UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX = (20 * 3600 * 1000); // 20 hours 10266 private static final int MUSIC_ACTIVE_POLL_PERIOD_MS = 60000; // 1 minute polling interval 10267 private static final int SAFE_VOLUME_CONFIGURE_TIMEOUT_MS = 30000; // 30s after boot completed 10268 // check playback or record activity every 6 seconds for UIDs owning mode IN_COMMUNICATION 10269 private static final int CHECK_MODE_FOR_UID_PERIOD_MS = 6000; 10270 10271 private static final String ACTION_CHECK_MUSIC_ACTIVE = 10272 "com.android.server.audio.action.CHECK_MUSIC_ACTIVE"; 10273 private static final int REQUEST_CODE_CHECK_MUSIC_ACTIVE = 1; 10274 safeMediaVolumeIndex(int device)10275 private int safeMediaVolumeIndex(int device) { 10276 if (!mSafeMediaVolumeDevices.contains(device)) { 10277 return MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]; 10278 } 10279 if (device == AudioSystem.DEVICE_OUT_USB_HEADSET) { 10280 return mSafeUsbMediaVolumeIndex; 10281 } else { 10282 return mSafeMediaVolumeIndex; 10283 } 10284 } 10285 setSafeMediaVolumeEnabled(boolean on, String caller)10286 private void setSafeMediaVolumeEnabled(boolean on, String caller) { 10287 synchronized (mSafeMediaVolumeStateLock) { 10288 if ((mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_NOT_CONFIGURED) && 10289 (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_DISABLED)) { 10290 if (on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE)) { 10291 mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE; 10292 enforceSafeMediaVolume(caller); 10293 } else if (!on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE)) { 10294 mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE; 10295 mMusicActiveMs = 1; // nonzero = confirmed 10296 mLastMusicActiveTimeMs = 0; 10297 saveMusicActiveMs(); 10298 scheduleMusicActiveCheck(); 10299 } 10300 } 10301 } 10302 } 10303 enforceSafeMediaVolume(String caller)10304 private void enforceSafeMediaVolume(String caller) { 10305 VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC]; 10306 Set<Integer> devices = mSafeMediaVolumeDevices; 10307 10308 for (int device : devices) { 10309 int index = streamState.getIndex(device); 10310 if (index > safeMediaVolumeIndex(device)) { 10311 streamState.setIndex(safeMediaVolumeIndex(device), device, caller, 10312 true /*hasModifyAudioSettings*/); 10313 sendMsg(mAudioHandler, 10314 MSG_SET_DEVICE_VOLUME, 10315 SENDMSG_QUEUE, 10316 device, 10317 0, 10318 streamState, 10319 0); 10320 } 10321 } 10322 } 10323 checkSafeMediaVolume(int streamType, int index, int device)10324 private boolean checkSafeMediaVolume(int streamType, int index, int device) { 10325 synchronized (mSafeMediaVolumeStateLock) { 10326 if ((mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) 10327 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) 10328 && (mSafeMediaVolumeDevices.contains(device)) 10329 && (index > safeMediaVolumeIndex(device))) { 10330 return false; 10331 } 10332 return true; 10333 } 10334 } 10335 10336 @Override disableSafeMediaVolume(String callingPackage)10337 public void disableSafeMediaVolume(String callingPackage) { 10338 enforceVolumeController("disable the safe media volume"); 10339 synchronized (mSafeMediaVolumeStateLock) { 10340 final long identity = Binder.clearCallingIdentity(); 10341 setSafeMediaVolumeEnabled(false, callingPackage); 10342 Binder.restoreCallingIdentity(identity); 10343 if (mPendingVolumeCommand != null) { 10344 onSetStreamVolume(mPendingVolumeCommand.mStreamType, 10345 mPendingVolumeCommand.mIndex, 10346 mPendingVolumeCommand.mFlags, 10347 mPendingVolumeCommand.mDevice, 10348 callingPackage, true /*hasModifyAudioSettings*/, 10349 true /*canChangeMute*/); 10350 mPendingVolumeCommand = null; 10351 } 10352 } 10353 } 10354 10355 //========================================================================================== 10356 // Hdmi CEC: 10357 // - System audio mode: 10358 // If Hdmi Cec's system audio mode is on, audio service should send the volume change 10359 // to HdmiControlService so that the audio receiver can handle it. 10360 // - CEC sink: 10361 // OUT_HDMI becomes a "full volume device", i.e. output is always at maximum level 10362 // and volume changes won't be taken into account on this device. Volume adjustments 10363 // are transformed into key events for the HDMI playback client. 10364 //========================================================================================== 10365 10366 @GuardedBy("mHdmiClientLock") updateHdmiCecSinkLocked(boolean hdmiCecSink)10367 private void updateHdmiCecSinkLocked(boolean hdmiCecSink) { 10368 if (!hasDeviceVolumeBehavior(AudioSystem.DEVICE_OUT_HDMI)) { 10369 if (hdmiCecSink) { 10370 if (DEBUG_VOL) { 10371 Log.d(TAG, "CEC sink: setting HDMI as full vol device"); 10372 } 10373 setDeviceVolumeBehaviorInternal( 10374 new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""), 10375 AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL, 10376 "AudioService.updateHdmiCecSinkLocked()"); 10377 } else { 10378 if (DEBUG_VOL) { 10379 Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device"); 10380 } 10381 // Android TV devices without CEC service apply software volume on 10382 // HDMI output 10383 setDeviceVolumeBehaviorInternal( 10384 new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""), 10385 AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE, 10386 "AudioService.updateHdmiCecSinkLocked()"); 10387 } 10388 postUpdateVolumeStatesForAudioDevice(AudioSystem.DEVICE_OUT_HDMI, 10389 "HdmiPlaybackClient.DisplayStatusCallback"); 10390 } 10391 } 10392 10393 private class MyHdmiControlStatusChangeListenerCallback 10394 implements HdmiControlManager.HdmiControlStatusChangeListener { onStatusChange(@dmiControlManager.HdmiCecControl int isCecEnabled, boolean isCecAvailable)10395 public void onStatusChange(@HdmiControlManager.HdmiCecControl int isCecEnabled, 10396 boolean isCecAvailable) { 10397 synchronized (mHdmiClientLock) { 10398 if (mHdmiManager == null) return; 10399 boolean cecEnabled = isCecEnabled == HdmiControlManager.HDMI_CEC_CONTROL_ENABLED; 10400 updateHdmiCecSinkLocked(cecEnabled ? isCecAvailable : false); 10401 } 10402 } 10403 }; 10404 10405 private class MyHdmiCecVolumeControlFeatureListener 10406 implements HdmiControlManager.HdmiCecVolumeControlFeatureListener { onHdmiCecVolumeControlFeature( @dmiControlManager.VolumeControl int hdmiCecVolumeControl)10407 public void onHdmiCecVolumeControlFeature( 10408 @HdmiControlManager.VolumeControl int hdmiCecVolumeControl) { 10409 synchronized (mHdmiClientLock) { 10410 if (mHdmiManager == null) return; 10411 mHdmiCecVolumeControlEnabled = 10412 hdmiCecVolumeControl == HdmiControlManager.VOLUME_CONTROL_ENABLED; 10413 } 10414 } 10415 }; 10416 10417 private final Object mHdmiClientLock = new Object(); 10418 10419 // If HDMI-CEC system audio is supported 10420 // Note that for CEC volume commands mHdmiCecVolumeControlEnabled will play a role on volume 10421 // commands 10422 private boolean mHdmiSystemAudioSupported = false; 10423 // Set only when device is tv. 10424 @GuardedBy("mHdmiClientLock") 10425 private HdmiTvClient mHdmiTvClient; 10426 // true if the device has system feature PackageManager.FEATURE_LEANBACK. 10427 // cached HdmiControlManager interface 10428 @GuardedBy("mHdmiClientLock") 10429 private HdmiControlManager mHdmiManager; 10430 // Set only when device is a set-top box. 10431 @GuardedBy("mHdmiClientLock") 10432 private HdmiPlaybackClient mHdmiPlaybackClient; 10433 // Set only when device is an audio system. 10434 @GuardedBy("mHdmiClientLock") 10435 private HdmiAudioSystemClient mHdmiAudioSystemClient; 10436 // True when volume control over HDMI CEC is used when CEC is enabled (meaningless otherwise) 10437 @GuardedBy("mHdmiClientLock") 10438 private boolean mHdmiCecVolumeControlEnabled; 10439 10440 private MyHdmiControlStatusChangeListenerCallback mHdmiControlStatusChangeListenerCallback = 10441 new MyHdmiControlStatusChangeListenerCallback(); 10442 10443 private MyHdmiCecVolumeControlFeatureListener mMyHdmiCecVolumeControlFeatureListener = 10444 new MyHdmiCecVolumeControlFeatureListener(); 10445 10446 @Override setHdmiSystemAudioSupported(boolean on)10447 public int setHdmiSystemAudioSupported(boolean on) { 10448 int device = AudioSystem.DEVICE_NONE; 10449 synchronized (mHdmiClientLock) { 10450 if (mHdmiManager != null) { 10451 if (mHdmiTvClient == null && mHdmiAudioSystemClient == null) { 10452 Log.w(TAG, "Only Hdmi-Cec enabled TV or audio system device supports" 10453 + "system audio mode."); 10454 return device; 10455 } 10456 if (mHdmiSystemAudioSupported != on) { 10457 mHdmiSystemAudioSupported = on; 10458 final int config = on ? AudioSystem.FORCE_HDMI_SYSTEM_AUDIO_ENFORCED : 10459 AudioSystem.FORCE_NONE; 10460 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_HDMI_SYSTEM_AUDIO, config, 10461 "setHdmiSystemAudioSupported"); 10462 } 10463 // TODO(b/185386781): Update AudioManager API to use device list. 10464 // So far, this value appears to be advisory for debug log. 10465 device = getDeviceMaskForStream(AudioSystem.STREAM_MUSIC); 10466 } 10467 } 10468 return device; 10469 } 10470 10471 @Override isHdmiSystemAudioSupported()10472 public boolean isHdmiSystemAudioSupported() { 10473 return mHdmiSystemAudioSupported; 10474 } 10475 10476 //========================================================================================== 10477 // Accessibility 10478 initA11yMonitoring()10479 private void initA11yMonitoring() { 10480 final AccessibilityManager accessibilityManager = 10481 (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); 10482 updateDefaultStreamOverrideDelay(accessibilityManager.isTouchExplorationEnabled()); 10483 updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive()); 10484 accessibilityManager.addTouchExplorationStateChangeListener(this, null); 10485 accessibilityManager.addAccessibilityServicesStateChangeListener(this); 10486 } 10487 10488 //--------------------------------------------------------------------------------- 10489 // A11y: taking touch exploration into account for selecting the default 10490 // stream override timeout when adjusting volume 10491 //--------------------------------------------------------------------------------- 10492 10493 // - STREAM_NOTIFICATION on tablets during this period after a notification stopped 10494 // - STREAM_RING on phones during this period after a notification stopped 10495 // - STREAM_MUSIC otherwise 10496 10497 private static final int DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS = 0; 10498 private static final int TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS = 1000; 10499 10500 private static int sStreamOverrideDelayMs; 10501 10502 @Override onTouchExplorationStateChanged(boolean enabled)10503 public void onTouchExplorationStateChanged(boolean enabled) { 10504 updateDefaultStreamOverrideDelay(enabled); 10505 } 10506 updateDefaultStreamOverrideDelay(boolean touchExploreEnabled)10507 private void updateDefaultStreamOverrideDelay(boolean touchExploreEnabled) { 10508 if (touchExploreEnabled) { 10509 sStreamOverrideDelayMs = TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS; 10510 } else { 10511 sStreamOverrideDelayMs = DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS; 10512 } 10513 if (DEBUG_VOL) Log.d(TAG, "Touch exploration enabled=" + touchExploreEnabled 10514 + " stream override delay is now " + sStreamOverrideDelayMs + " ms"); 10515 } 10516 10517 //--------------------------------------------------------------------------------- 10518 // A11y: taking a11y state into account for the handling of a11y prompts volume 10519 //--------------------------------------------------------------------------------- 10520 10521 private static boolean sIndependentA11yVolume = false; 10522 10523 // implementation of AccessibilityServicesStateChangeListener 10524 @Override onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager)10525 public void onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager) { 10526 updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive()); 10527 } 10528 updateA11yVolumeAlias(boolean a11VolEnabled)10529 private void updateA11yVolumeAlias(boolean a11VolEnabled) { 10530 if (DEBUG_VOL) Log.d(TAG, "Accessibility volume enabled = " + a11VolEnabled); 10531 if (sIndependentA11yVolume != a11VolEnabled) { 10532 sIndependentA11yVolume = a11VolEnabled; 10533 // update the volume mapping scheme 10534 updateStreamVolumeAlias(true /*updateVolumes*/, TAG); 10535 // update the volume controller behavior 10536 mVolumeController.setA11yMode(sIndependentA11yVolume ? 10537 VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME : 10538 VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME); 10539 mVolumeController.postVolumeChanged(AudioManager.STREAM_ACCESSIBILITY, 0); 10540 } 10541 } 10542 10543 //========================================================================================== 10544 // Camera shutter sound policy. 10545 // config_camera_sound_forced configuration option in config.xml defines if the camera shutter 10546 // sound is forced (sound even if the device is in silent mode) or not. This option is false by 10547 // default and can be overridden by country specific overlay in values-mccXXX/config.xml. 10548 //========================================================================================== 10549 10550 // cached value of com.android.internal.R.bool.config_camera_sound_forced 10551 @GuardedBy("mSettingsLock") 10552 private boolean mCameraSoundForced; 10553 10554 // called by android.hardware.Camera to populate CameraInfo.canDisableShutterSound isCameraSoundForced()10555 public boolean isCameraSoundForced() { 10556 synchronized (mSettingsLock) { 10557 return mCameraSoundForced; 10558 } 10559 } 10560 10561 //========================================================================================== 10562 // AudioService logging and dumpsys 10563 //========================================================================================== 10564 static final int LOG_NB_EVENTS_LIFECYCLE = 20; 10565 static final int LOG_NB_EVENTS_PHONE_STATE = 20; 10566 static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 50; 10567 static final int LOG_NB_EVENTS_FORCE_USE = 20; 10568 static final int LOG_NB_EVENTS_VOLUME = 100; 10569 static final int LOG_NB_EVENTS_DYN_POLICY = 10; 10570 static final int LOG_NB_EVENTS_SPATIAL = 30; 10571 10572 static final AudioEventLogger sLifecycleLogger = new AudioEventLogger(LOG_NB_EVENTS_LIFECYCLE, 10573 "audio services lifecycle"); 10574 10575 final private AudioEventLogger mModeLogger = new AudioEventLogger(LOG_NB_EVENTS_PHONE_STATE, 10576 "phone state (logged after successful call to AudioSystem.setPhoneState(int, int))"); 10577 10578 // logs for wired + A2DP device connections: 10579 // - wired: logged before onSetWiredDeviceConnectionState() is executed 10580 // - A2DP: logged at reception of method call 10581 /*package*/ static final AudioEventLogger sDeviceLogger = new AudioEventLogger( 10582 LOG_NB_EVENTS_DEVICE_CONNECTION, "wired/A2DP/hearing aid device connection"); 10583 10584 static final AudioEventLogger sForceUseLogger = new AudioEventLogger( 10585 LOG_NB_EVENTS_FORCE_USE, 10586 "force use (logged before setForceUse() is executed)"); 10587 10588 static final AudioEventLogger sVolumeLogger = new AudioEventLogger(LOG_NB_EVENTS_VOLUME, 10589 "volume changes (logged when command received by AudioService)"); 10590 10591 static final AudioEventLogger sSpatialLogger = new AudioEventLogger(LOG_NB_EVENTS_SPATIAL, 10592 "spatial audio"); 10593 10594 final private AudioEventLogger mDynPolicyLogger = new AudioEventLogger(LOG_NB_EVENTS_DYN_POLICY, 10595 "dynamic policy events (logged when command received by AudioService)"); 10596 10597 private static final String[] RINGER_MODE_NAMES = new String[] { 10598 "SILENT", 10599 "VIBRATE", 10600 "NORMAL" 10601 }; 10602 dumpRingerMode(PrintWriter pw)10603 private void dumpRingerMode(PrintWriter pw) { 10604 pw.println("\nRinger mode: "); 10605 pw.println("- mode (internal) = " + RINGER_MODE_NAMES[mRingerMode]); 10606 pw.println("- mode (external) = " + RINGER_MODE_NAMES[mRingerModeExternal]); 10607 pw.println("- zen mode:" + Settings.Global.zenModeToString(mNm.getZenMode())); 10608 dumpRingerModeStreams(pw, "affected", mRingerModeAffectedStreams); 10609 dumpRingerModeStreams(pw, "muted", mRingerAndZenModeMutedStreams); 10610 pw.print("- delegate = "); pw.println(mRingerModeDelegate); 10611 } 10612 dumpRingerModeStreams(PrintWriter pw, String type, int streams)10613 private void dumpRingerModeStreams(PrintWriter pw, String type, int streams) { 10614 pw.print("- ringer mode "); pw.print(type); pw.print(" streams = 0x"); 10615 pw.print(Integer.toHexString(streams)); 10616 if (streams != 0) { 10617 pw.print(" ("); 10618 boolean first = true; 10619 for (int i = 0; i < AudioSystem.STREAM_NAMES.length; i++) { 10620 final int stream = (1 << i); 10621 if ((streams & stream) != 0) { 10622 if (!first) pw.print(','); 10623 pw.print(AudioSystem.STREAM_NAMES[i]); 10624 streams &= ~stream; 10625 first = false; 10626 } 10627 } 10628 if (streams != 0) { 10629 if (!first) pw.print(','); 10630 pw.print(streams); 10631 } 10632 pw.print(')'); 10633 } 10634 pw.println(); 10635 } 10636 dumpDeviceTypes(@onNull Set<Integer> deviceTypes)10637 private String dumpDeviceTypes(@NonNull Set<Integer> deviceTypes) { 10638 Iterator<Integer> it = deviceTypes.iterator(); 10639 if (!it.hasNext()) { 10640 return ""; 10641 } 10642 final StringBuilder sb = new StringBuilder(); 10643 sb.append("0x" + Integer.toHexString(it.next())); 10644 while (it.hasNext()) { 10645 sb.append("," + "0x" + Integer.toHexString(it.next())); 10646 } 10647 return sb.toString(); 10648 } 10649 10650 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)10651 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10652 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 10653 10654 sLifecycleLogger.dump(pw); 10655 if (mAudioHandler != null) { 10656 pw.println("\nMessage handler (watch for unhandled messages):"); 10657 mAudioHandler.dump(new PrintWriterPrinter(pw), " "); 10658 } else { 10659 pw.println("\nMessage handler is null"); 10660 } 10661 mMediaFocusControl.dump(pw); 10662 dumpStreamStates(pw); 10663 dumpVolumeGroups(pw); 10664 dumpRingerMode(pw); 10665 dumpAudioMode(pw); 10666 pw.println("\nAudio routes:"); 10667 pw.print(" mMainType=0x"); pw.println(Integer.toHexString( 10668 mDeviceBroker.getCurAudioRoutes().mainType)); 10669 pw.print(" mBluetoothName="); pw.println(mDeviceBroker.getCurAudioRoutes().bluetoothName); 10670 10671 pw.println("\nOther state:"); 10672 pw.print(" mVolumeController="); pw.println(mVolumeController); 10673 pw.print(" mSafeMediaVolumeState="); 10674 pw.println(safeMediaVolumeStateToString(mSafeMediaVolumeState)); 10675 pw.print(" mSafeMediaVolumeIndex="); pw.println(mSafeMediaVolumeIndex); 10676 pw.print(" mSafeUsbMediaVolumeIndex="); pw.println(mSafeUsbMediaVolumeIndex); 10677 pw.print(" mSafeUsbMediaVolumeDbfs="); pw.println(mSafeUsbMediaVolumeDbfs); 10678 pw.print(" sIndependentA11yVolume="); pw.println(sIndependentA11yVolume); 10679 pw.print(" mPendingVolumeCommand="); pw.println(mPendingVolumeCommand); 10680 pw.print(" mMusicActiveMs="); pw.println(mMusicActiveMs); 10681 pw.print(" mMcc="); pw.println(mMcc); 10682 pw.print(" mCameraSoundForced="); pw.println(isCameraSoundForced()); 10683 pw.print(" mHasVibrator="); pw.println(mHasVibrator); 10684 pw.print(" mVolumePolicy="); pw.println(mVolumePolicy); 10685 pw.print(" mAvrcpAbsVolSupported="); pw.println(mAvrcpAbsVolSupported); 10686 pw.print(" mBtScoOnByApp="); pw.println(mBtScoOnByApp); 10687 pw.print(" mIsSingleVolume="); pw.println(mIsSingleVolume); 10688 pw.print(" mUseFixedVolume="); pw.println(mUseFixedVolume); 10689 pw.print(" mNotifAliasRing="); pw.println(mNotifAliasRing); 10690 pw.print(" mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices)); 10691 pw.print(" mFullVolumeDevices="); pw.println(dumpDeviceTypes(mFullVolumeDevices)); 10692 pw.print(" mAbsoluteVolumeDevices.keySet()="); pw.println(dumpDeviceTypes( 10693 mAbsoluteVolumeDeviceInfoMap.keySet())); 10694 pw.print(" mExtVolumeController="); pw.println(mExtVolumeController); 10695 pw.print(" mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient); 10696 pw.print(" mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient); 10697 pw.print(" mHdmiTvClient="); pw.println(mHdmiTvClient); 10698 pw.print(" mHdmiSystemAudioSupported="); pw.println(mHdmiSystemAudioSupported); 10699 pw.print(" mHdmiCecVolumeControlEnabled="); pw.println(mHdmiCecVolumeControlEnabled); 10700 pw.print(" mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported); 10701 pw.print(" mic mute FromSwitch=" + mMicMuteFromSwitch 10702 + " FromRestrictions=" + mMicMuteFromRestrictions 10703 + " FromApi=" + mMicMuteFromApi 10704 + " from system=" + mMicMuteFromSystemCached); 10705 pw.print(" mCurrentImeUid="); pw.println(mCurrentImeUid); 10706 dumpAccessibilityServiceUids(pw); 10707 dumpAssistantServicesUids(pw); 10708 10709 dumpAudioPolicies(pw); 10710 mDynPolicyLogger.dump(pw); 10711 mPlaybackMonitor.dump(pw); 10712 mRecordMonitor.dump(pw); 10713 10714 pw.println("\nAudioDeviceBroker:"); 10715 mDeviceBroker.dump(pw, " "); 10716 pw.println("\nSoundEffects:"); 10717 mSfxHelper.dump(pw, " "); 10718 10719 pw.println("\n"); 10720 pw.println("\nEvent logs:"); 10721 mModeLogger.dump(pw); 10722 pw.println("\n"); 10723 sDeviceLogger.dump(pw); 10724 pw.println("\n"); 10725 sForceUseLogger.dump(pw); 10726 pw.println("\n"); 10727 sVolumeLogger.dump(pw); 10728 pw.println("\n"); 10729 dumpSupportedSystemUsage(pw); 10730 10731 pw.println("\n"); 10732 pw.println("\nSpatial audio:"); 10733 pw.println("mHasSpatializerEffect:" + mHasSpatializerEffect + " (effect present)"); 10734 pw.println("isSpatializerEnabled:" + isSpatializerEnabled() + " (routing dependent)"); 10735 mSpatializerHelper.dump(pw); 10736 sSpatialLogger.dump(pw); 10737 10738 mAudioSystem.dump(pw); 10739 } 10740 dumpSupportedSystemUsage(PrintWriter pw)10741 private void dumpSupportedSystemUsage(PrintWriter pw) { 10742 pw.println("Supported System Usages:"); 10743 synchronized (mSupportedSystemUsagesLock) { 10744 for (int i = 0; i < mSupportedSystemUsages.length; i++) { 10745 pw.printf("\t%s\n", AudioAttributes.usageToString(mSupportedSystemUsages[i])); 10746 } 10747 } 10748 } 10749 dumpAssistantServicesUids(PrintWriter pw)10750 private void dumpAssistantServicesUids(PrintWriter pw) { 10751 synchronized (mSettingsLock) { 10752 if (mAssistantUids.size() > 0) { 10753 pw.println(" Assistant service UIDs:"); 10754 for (int uid : mAssistantUids) { 10755 pw.println(" - " + uid); 10756 } 10757 } else { 10758 pw.println(" No Assistant service Uids."); 10759 } 10760 } 10761 } 10762 dumpAccessibilityServiceUids(PrintWriter pw)10763 private void dumpAccessibilityServiceUids(PrintWriter pw) { 10764 synchronized (mSupportedSystemUsagesLock) { 10765 if (mAccessibilityServiceUids != null && mAccessibilityServiceUids.length > 0) { 10766 pw.println(" Accessibility service Uids:"); 10767 for (int uid : mAccessibilityServiceUids) { 10768 pw.println(" - " + uid); 10769 } 10770 } else { 10771 pw.println(" No accessibility service Uids."); 10772 } 10773 } 10774 } 10775 10776 /** 10777 * Audio Analytics ids. 10778 */ 10779 private static final String mMetricsId = MediaMetrics.Name.AUDIO_SERVICE 10780 + MediaMetrics.SEPARATOR; 10781 safeMediaVolumeStateToString(int state)10782 private static String safeMediaVolumeStateToString(int state) { 10783 switch(state) { 10784 case SAFE_MEDIA_VOLUME_NOT_CONFIGURED: return "SAFE_MEDIA_VOLUME_NOT_CONFIGURED"; 10785 case SAFE_MEDIA_VOLUME_DISABLED: return "SAFE_MEDIA_VOLUME_DISABLED"; 10786 case SAFE_MEDIA_VOLUME_INACTIVE: return "SAFE_MEDIA_VOLUME_INACTIVE"; 10787 case SAFE_MEDIA_VOLUME_ACTIVE: return "SAFE_MEDIA_VOLUME_ACTIVE"; 10788 } 10789 return null; 10790 } 10791 10792 // Inform AudioFlinger of our device's low RAM attribute readAndSetLowRamDevice()10793 private static void readAndSetLowRamDevice() 10794 { 10795 boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic(); 10796 long totalMemory = 1024 * 1024 * 1024; // 1GB is the default if ActivityManager fails. 10797 10798 try { 10799 final ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo(); 10800 ActivityManager.getService().getMemoryInfo(info); 10801 totalMemory = info.totalMem; 10802 } catch (RemoteException e) { 10803 Log.w(TAG, "Cannot obtain MemoryInfo from ActivityManager, assume low memory device"); 10804 isLowRamDevice = true; 10805 } 10806 10807 final int status = AudioSystem.setLowRamDevice(isLowRamDevice, totalMemory); 10808 if (status != 0) { 10809 Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status); 10810 } 10811 } 10812 enforceVolumeController(String action)10813 private void enforceVolumeController(String action) { 10814 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE, 10815 "Only SystemUI can " + action); 10816 } 10817 10818 @Override setVolumeController(final IVolumeController controller)10819 public void setVolumeController(final IVolumeController controller) { 10820 enforceVolumeController("set the volume controller"); 10821 10822 // return early if things are not actually changing 10823 if (mVolumeController.isSameBinder(controller)) { 10824 return; 10825 } 10826 10827 // dismiss the old volume controller 10828 mVolumeController.postDismiss(); 10829 if (controller != null) { 10830 // we are about to register a new controller, listen for its death 10831 try { 10832 controller.asBinder().linkToDeath(new DeathRecipient() { 10833 @Override 10834 public void binderDied() { 10835 if (mVolumeController.isSameBinder(controller)) { 10836 Log.w(TAG, "Current remote volume controller died, unregistering"); 10837 setVolumeController(null); 10838 } 10839 } 10840 }, 0); 10841 } catch (RemoteException e) { 10842 // noop 10843 } 10844 } 10845 mVolumeController.setController(controller); 10846 if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController); 10847 } 10848 10849 @Override notifyVolumeControllerVisible(final IVolumeController controller, boolean visible)10850 public void notifyVolumeControllerVisible(final IVolumeController controller, boolean visible) { 10851 enforceVolumeController("notify about volume controller visibility"); 10852 10853 // return early if the controller is not current 10854 if (!mVolumeController.isSameBinder(controller)) { 10855 return; 10856 } 10857 10858 mVolumeController.setVisible(visible); 10859 if (DEBUG_VOL) Log.d(TAG, "Volume controller visible: " + visible); 10860 } 10861 10862 @Override setVolumePolicy(VolumePolicy policy)10863 public void setVolumePolicy(VolumePolicy policy) { 10864 enforceVolumeController("set volume policy"); 10865 if (policy != null && !policy.equals(mVolumePolicy)) { 10866 mVolumePolicy = policy; 10867 if (DEBUG_VOL) Log.d(TAG, "Volume policy changed: " + mVolumePolicy); 10868 } 10869 } 10870 10871 public class VolumeController { 10872 private static final String TAG = "VolumeController"; 10873 10874 private IVolumeController mController; 10875 private boolean mVisible; 10876 private long mNextLongPress; 10877 private int mLongPressTimeout; 10878 setController(IVolumeController controller)10879 public void setController(IVolumeController controller) { 10880 mController = controller; 10881 mVisible = false; 10882 } 10883 loadSettings(ContentResolver cr)10884 public void loadSettings(ContentResolver cr) { 10885 mLongPressTimeout = mSettings.getSecureIntForUser(cr, 10886 Settings.Secure.LONG_PRESS_TIMEOUT, 500, UserHandle.USER_CURRENT); 10887 } 10888 suppressAdjustment(int resolvedStream, int flags, boolean isMute)10889 public boolean suppressAdjustment(int resolvedStream, int flags, boolean isMute) { 10890 if (isMute) { 10891 return false; 10892 } 10893 boolean suppress = false; 10894 // Intended behavior: 10895 // 1/ if the stream is not the default UI stream, do not suppress (as it is not involved 10896 // in bringing up the UI) 10897 // 2/ if the resolved and default stream is MUSIC, and media is playing, do not suppress 10898 // 3/ otherwise suppress the first adjustments that occur during the "long press 10899 // timeout" interval. Note this is true regardless of whether this is a "real long 10900 // press" (where the user keeps pressing on the volume button), or repeated single 10901 // presses (here we don't know if we are in a real long press, or repeated fast 10902 // button presses). 10903 // Once the long press timeout occurs (mNextLongPress reset to 0), do not suppress. 10904 // Example: for a default and resolved stream of MUSIC, this allows modifying rapidly 10905 // the volume when media is playing (whether by long press or repeated individual 10906 // presses), or to bring up the volume UI when media is not playing, in order to make 10907 // another change (e.g. switch ringer modes) without changing media volume. 10908 if (resolvedStream == DEFAULT_VOL_STREAM_NO_PLAYBACK && mController != null) { 10909 // never suppress media vol adjustement during media playback 10910 if (resolvedStream == AudioSystem.STREAM_MUSIC 10911 && mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, mLongPressTimeout)) 10912 { 10913 // media is playing, adjust the volume right away 10914 return false; 10915 } 10916 10917 final long now = SystemClock.uptimeMillis(); 10918 if ((flags & AudioManager.FLAG_SHOW_UI) != 0 && !mVisible) { 10919 // UI is not visible yet, adjustment is ignored 10920 if (mNextLongPress < now) { 10921 mNextLongPress = now + mLongPressTimeout; 10922 } 10923 suppress = true; 10924 } else if (mNextLongPress > 0) { // in a long-press 10925 if (now > mNextLongPress) { 10926 // long press triggered, no more suppression 10927 mNextLongPress = 0; 10928 } else { 10929 // keep suppressing until the long press triggers 10930 suppress = true; 10931 } 10932 } 10933 } 10934 return suppress; 10935 } 10936 setVisible(boolean visible)10937 public void setVisible(boolean visible) { 10938 mVisible = visible; 10939 } 10940 isSameBinder(IVolumeController controller)10941 public boolean isSameBinder(IVolumeController controller) { 10942 return Objects.equals(asBinder(), binder(controller)); 10943 } 10944 asBinder()10945 public IBinder asBinder() { 10946 return binder(mController); 10947 } 10948 binder(IVolumeController controller)10949 private IBinder binder(IVolumeController controller) { 10950 return controller == null ? null : controller.asBinder(); 10951 } 10952 10953 @Override toString()10954 public String toString() { 10955 return "VolumeController(" + asBinder() + ",mVisible=" + mVisible + ")"; 10956 } 10957 postDisplaySafeVolumeWarning(int flags)10958 public void postDisplaySafeVolumeWarning(int flags) { 10959 if (mController == null) 10960 return; 10961 flags = flags | AudioManager.FLAG_SHOW_UI; 10962 try { 10963 mController.displaySafeVolumeWarning(flags); 10964 } catch (RemoteException e) { 10965 Log.w(TAG, "Error calling displaySafeVolumeWarning", e); 10966 } 10967 } 10968 postVolumeChanged(int streamType, int flags)10969 public void postVolumeChanged(int streamType, int flags) { 10970 if (mController == null) 10971 return; 10972 try { 10973 mController.volumeChanged(streamType, flags); 10974 } catch (RemoteException e) { 10975 Log.w(TAG, "Error calling volumeChanged", e); 10976 } 10977 } 10978 postMasterMuteChanged(int flags)10979 public void postMasterMuteChanged(int flags) { 10980 if (mController == null) 10981 return; 10982 try { 10983 mController.masterMuteChanged(flags); 10984 } catch (RemoteException e) { 10985 Log.w(TAG, "Error calling masterMuteChanged", e); 10986 } 10987 } 10988 setLayoutDirection(int layoutDirection)10989 public void setLayoutDirection(int layoutDirection) { 10990 if (mController == null) 10991 return; 10992 try { 10993 mController.setLayoutDirection(layoutDirection); 10994 } catch (RemoteException e) { 10995 Log.w(TAG, "Error calling setLayoutDirection", e); 10996 } 10997 } 10998 postDismiss()10999 public void postDismiss() { 11000 if (mController == null) 11001 return; 11002 try { 11003 mController.dismiss(); 11004 } catch (RemoteException e) { 11005 Log.w(TAG, "Error calling dismiss", e); 11006 } 11007 } 11008 setA11yMode(int a11yMode)11009 public void setA11yMode(int a11yMode) { 11010 if (mController == null) 11011 return; 11012 try { 11013 mController.setA11yMode(a11yMode); 11014 } catch (RemoteException e) { 11015 Log.w(TAG, "Error calling setA11Mode", e); 11016 } 11017 } 11018 } 11019 11020 /** 11021 * Interface for system components to get some extra functionality through 11022 * LocalServices. 11023 */ 11024 final class AudioServiceInternal extends AudioManagerInternal { 11025 @Override setRingerModeDelegate(RingerModeDelegate delegate)11026 public void setRingerModeDelegate(RingerModeDelegate delegate) { 11027 mRingerModeDelegate = delegate; 11028 if (mRingerModeDelegate != null) { 11029 synchronized (mSettingsLock) { 11030 updateRingerAndZenModeAffectedStreams(); 11031 } 11032 setRingerModeInternal(getRingerModeInternal(), TAG + ".setRingerModeDelegate"); 11033 } 11034 } 11035 11036 @Override getRingerModeInternal()11037 public int getRingerModeInternal() { 11038 return AudioService.this.getRingerModeInternal(); 11039 } 11040 11041 @Override setRingerModeInternal(int ringerMode, String caller)11042 public void setRingerModeInternal(int ringerMode, String caller) { 11043 AudioService.this.setRingerModeInternal(ringerMode, caller); 11044 } 11045 11046 @Override silenceRingerModeInternal(String caller)11047 public void silenceRingerModeInternal(String caller) { 11048 AudioService.this.silenceRingerModeInternal(caller); 11049 } 11050 11051 @Override updateRingerModeAffectedStreamsInternal()11052 public void updateRingerModeAffectedStreamsInternal() { 11053 synchronized (mSettingsLock) { 11054 if (updateRingerAndZenModeAffectedStreams()) { 11055 setRingerModeInt(getRingerModeInternal(), false); 11056 } 11057 } 11058 } 11059 11060 @Override addAssistantServiceUid(int uid)11061 public void addAssistantServiceUid(int uid) { 11062 sendMsg(mAudioHandler, MSG_ADD_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE, 11063 uid, 0, null, 0); 11064 } 11065 11066 @Override removeAssistantServiceUid(int uid)11067 public void removeAssistantServiceUid(int uid) { 11068 sendMsg(mAudioHandler, MSG_REMOVE_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE, 11069 uid, 0, null, 0); 11070 } 11071 11072 @Override setActiveAssistantServicesUids(IntArray activeUids)11073 public void setActiveAssistantServicesUids(IntArray activeUids) { 11074 synchronized (mSettingsLock) { 11075 if (activeUids.size() == 0) { 11076 mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS; 11077 } else { 11078 boolean changed = (mActiveAssistantServiceUids == null) 11079 || (mActiveAssistantServiceUids.length != activeUids.size()); 11080 if (!changed) { 11081 for (int i = 0; i < mActiveAssistantServiceUids.length; i++) { 11082 if (activeUids.get(i) != mActiveAssistantServiceUids[i]) { 11083 changed = true; 11084 break; 11085 } 11086 } 11087 } 11088 if (changed) { 11089 mActiveAssistantServiceUids = activeUids.toArray(); 11090 } 11091 } 11092 } 11093 sendMsg(mAudioHandler, MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID, SENDMSG_REPLACE, 11094 0, 0, null, 0); 11095 } 11096 11097 @Override setAccessibilityServiceUids(IntArray uids)11098 public void setAccessibilityServiceUids(IntArray uids) { 11099 // TODO(b/233287010): Fix voice interaction and a11y concurrency in audio policy service 11100 if (isPlatformAutomotive()) { 11101 return; 11102 } 11103 11104 synchronized (mAccessibilityServiceUidsLock) { 11105 if (uids.size() == 0) { 11106 mAccessibilityServiceUids = null; 11107 } else { 11108 boolean changed = (mAccessibilityServiceUids == null) 11109 || (mAccessibilityServiceUids.length != uids.size()); 11110 if (!changed) { 11111 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 11112 if (uids.get(i) != mAccessibilityServiceUids[i]) { 11113 changed = true; 11114 break; 11115 } 11116 } 11117 } 11118 if (changed) { 11119 mAccessibilityServiceUids = uids.toArray(); 11120 } 11121 } 11122 sendMsg(mAudioHandler, MSG_UPDATE_A11Y_SERVICE_UIDS, SENDMSG_REPLACE, 11123 0, 0, null, 0); 11124 } 11125 } 11126 11127 /** 11128 * {@inheritDoc} 11129 */ 11130 @Override setInputMethodServiceUid(int uid)11131 public void setInputMethodServiceUid(int uid) { 11132 synchronized (mInputMethodServiceUidLock) { 11133 if (mInputMethodServiceUid != uid) { 11134 mAudioSystem.setCurrentImeUid(uid); 11135 mInputMethodServiceUid = uid; 11136 } 11137 } 11138 } 11139 } 11140 onUpdateAccessibilityServiceUids()11141 private void onUpdateAccessibilityServiceUids() { 11142 int[] accessibilityServiceUids; 11143 synchronized (mAccessibilityServiceUidsLock) { 11144 accessibilityServiceUids = mAccessibilityServiceUids; 11145 } 11146 AudioSystem.setA11yServicesUids(accessibilityServiceUids); 11147 } 11148 11149 //========================================================================================== 11150 // Audio policy management 11151 //========================================================================================== registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)11152 public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, 11153 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, 11154 boolean isVolumeController, IMediaProjection projection) { 11155 AudioSystem.setDynamicPolicyCallback(mDynPolicyCallback); 11156 11157 if (!isPolicyRegisterAllowed(policyConfig, 11158 isFocusPolicy || isTestFocusPolicy || hasFocusListener, 11159 isVolumeController, 11160 projection)) { 11161 Slog.w(TAG, "Permission denied to register audio policy for pid " 11162 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid() 11163 + ", need system permission or a MediaProjection that can project audio"); 11164 return null; 11165 } 11166 11167 String regId = null; 11168 synchronized (mAudioPolicies) { 11169 if (mAudioPolicies.containsKey(pcb.asBinder())) { 11170 Slog.e(TAG, "Cannot re-register policy"); 11171 return null; 11172 } 11173 try { 11174 AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, pcb, hasFocusListener, 11175 isFocusPolicy, isTestFocusPolicy, isVolumeController, projection); 11176 pcb.asBinder().linkToDeath(app, 0/*flags*/); 11177 11178 // logging after registration so we have the registration id 11179 mDynPolicyLogger.log((new AudioEventLogger.StringEvent("registerAudioPolicy for " 11180 + pcb.asBinder() + " u/pid:" + Binder.getCallingUid() + "/" 11181 + Binder.getCallingPid() + " with config:" + app.toCompactLogString())) 11182 .printLog(TAG)); 11183 11184 regId = app.getRegistrationId(); 11185 mAudioPolicies.put(pcb.asBinder(), app); 11186 } catch (RemoteException e) { 11187 // audio policy owner has already died! 11188 Slog.w(TAG, "Audio policy registration failed, could not link to " + pcb + 11189 " binder death", e); 11190 return null; 11191 } catch (IllegalStateException e) { 11192 Slog.w(TAG, "Audio policy registration failed for binder " + pcb, e); 11193 return null; 11194 } 11195 } 11196 return regId; 11197 } 11198 11199 /** 11200 * Apps with MODIFY_AUDIO_ROUTING can register any policy. 11201 * Apps with an audio capable MediaProjection are allowed to register a RENDER|LOOPBACK policy 11202 * as those policy do not modify the audio routing. 11203 */ isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, boolean hasFocusAccess, boolean isVolumeController, IMediaProjection projection)11204 private boolean isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, 11205 boolean hasFocusAccess, 11206 boolean isVolumeController, 11207 IMediaProjection projection) { 11208 11209 boolean requireValidProjection = false; 11210 boolean requireCaptureAudioOrMediaOutputPerm = false; 11211 boolean requireModifyRouting = false; 11212 boolean requireCallAudioInterception = false; 11213 ArrayList<AudioMix> voiceCommunicationCaptureMixes = null; 11214 11215 11216 if (hasFocusAccess || isVolumeController) { 11217 requireModifyRouting |= true; 11218 } else if (policyConfig.getMixes().isEmpty()) { 11219 // An empty policy could be used to lock the focus or add mixes later 11220 requireModifyRouting |= true; 11221 } 11222 for (AudioMix mix : policyConfig.getMixes()) { 11223 // If mix is requesting privileged capture 11224 if (mix.getRule().allowPrivilegedMediaPlaybackCapture()) { 11225 // then its format must be low quality enough 11226 String privilegedMediaCaptureError = 11227 mix.canBeUsedForPrivilegedMediaCapture(mix.getFormat()); 11228 if (privilegedMediaCaptureError != null) { 11229 Log.e(TAG, privilegedMediaCaptureError); 11230 return false; 11231 } 11232 // and it must have CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT permission 11233 requireCaptureAudioOrMediaOutputPerm |= true; 11234 11235 } 11236 // If mix is trying to explicitly capture USAGE_VOICE_COMMUNICATION 11237 if (mix.containsMatchAttributeRuleForUsage( 11238 AudioAttributes.USAGE_VOICE_COMMUNICATION) 11239 && (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER)) { 11240 // It must have CAPTURE_USAGE_VOICE_COMMUNICATION_OUTPUT permission 11241 // Note that for UID, USERID or EXCLDUE rules, the capture will be silenced 11242 // in AudioPolicyMix 11243 if (voiceCommunicationCaptureMixes == null) { 11244 voiceCommunicationCaptureMixes = new ArrayList<AudioMix>(); 11245 } 11246 voiceCommunicationCaptureMixes.add(mix); 11247 } 11248 11249 // If mix is RENDER|LOOPBACK, then an audio MediaProjection is enough 11250 // otherwise MODIFY_AUDIO_ROUTING permission is required 11251 if (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER && projection != null) { 11252 requireValidProjection |= true; 11253 } else if (mix.isForCallRedirection()) { 11254 requireCallAudioInterception |= true; 11255 } else if (mix.containsMatchAttributeRuleForUsage( 11256 AudioAttributes.USAGE_VOICE_COMMUNICATION)) { 11257 requireModifyRouting |= true; 11258 } 11259 } 11260 11261 if (requireCaptureAudioOrMediaOutputPerm 11262 && !callerHasPermission(android.Manifest.permission.CAPTURE_MEDIA_OUTPUT) 11263 && !callerHasPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT)) { 11264 Log.e(TAG, "Privileged audio capture requires CAPTURE_MEDIA_OUTPUT or " 11265 + "CAPTURE_AUDIO_OUTPUT system permission"); 11266 return false; 11267 } 11268 11269 if (voiceCommunicationCaptureMixes != null && voiceCommunicationCaptureMixes.size() > 0) { 11270 if (!callerHasPermission( 11271 android.Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT)) { 11272 Log.e(TAG, "Audio capture for voice communication requires " 11273 + "CAPTURE_VOICE_COMMUNICATION_OUTPUT system permission"); 11274 return false; 11275 } 11276 11277 // If permission check succeeded, we set the flag in each of the mixing rules 11278 for (AudioMix mix : voiceCommunicationCaptureMixes) { 11279 mix.getRule().setVoiceCommunicationCaptureAllowed(true); 11280 } 11281 } 11282 11283 if (requireValidProjection && !canProjectAudio(projection)) { 11284 return false; 11285 } 11286 11287 if (requireModifyRouting 11288 && !callerHasPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)) { 11289 Log.e(TAG, "Can not capture audio without MODIFY_AUDIO_ROUTING"); 11290 return false; 11291 } 11292 11293 if (requireCallAudioInterception 11294 && !callerHasPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION)) { 11295 Log.e(TAG, "Can not capture audio without CALL_AUDIO_INTERCEPTION"); 11296 return false; 11297 } 11298 11299 return true; 11300 } 11301 callerHasPermission(String permission)11302 private boolean callerHasPermission(String permission) { 11303 return mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED; 11304 } 11305 11306 /** @return true if projection is a valid MediaProjection that can project audio. */ canProjectAudio(IMediaProjection projection)11307 private boolean canProjectAudio(IMediaProjection projection) { 11308 if (projection == null) { 11309 Log.e(TAG, "MediaProjection is null"); 11310 return false; 11311 } 11312 11313 IMediaProjectionManager projectionService = getProjectionService(); 11314 if (projectionService == null) { 11315 Log.e(TAG, "Can't get service IMediaProjectionManager"); 11316 return false; 11317 } 11318 11319 try { 11320 if (!projectionService.isValidMediaProjection(projection)) { 11321 Log.w(TAG, "App passed invalid MediaProjection token"); 11322 return false; 11323 } 11324 } catch (RemoteException e) { 11325 Log.e(TAG, "Can't call .isValidMediaProjection() on IMediaProjectionManager" 11326 + projectionService.asBinder(), e); 11327 return false; 11328 } 11329 11330 try { 11331 if (!projection.canProjectAudio()) { 11332 Log.w(TAG, "App passed MediaProjection that can not project audio"); 11333 return false; 11334 } 11335 } catch (RemoteException e) { 11336 Log.e(TAG, "Can't call .canProjectAudio() on valid IMediaProjection" 11337 + projection.asBinder(), e); 11338 return false; 11339 } 11340 11341 return true; 11342 } 11343 getProjectionService()11344 private IMediaProjectionManager getProjectionService() { 11345 if (mProjectionService == null) { 11346 IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE); 11347 mProjectionService = IMediaProjectionManager.Stub.asInterface(b); 11348 } 11349 return mProjectionService; 11350 } 11351 11352 /** 11353 * See {@link AudioManager#unregisterAudioPolicyAsync(AudioPolicy)} 11354 * Declared oneway 11355 * @param pcb nullable because on service interface 11356 */ unregisterAudioPolicyAsync(@ullable IAudioPolicyCallback pcb)11357 public void unregisterAudioPolicyAsync(@Nullable IAudioPolicyCallback pcb) { 11358 if (pcb == null) { 11359 return; 11360 } 11361 unregisterAudioPolicyInt(pcb, "unregisterAudioPolicyAsync"); 11362 } 11363 11364 /** 11365 * See {@link AudioManager#unregisterAudioPolicy(AudioPolicy)} 11366 * @param pcb nullable because on service interface 11367 */ unregisterAudioPolicy(@ullable IAudioPolicyCallback pcb)11368 public void unregisterAudioPolicy(@Nullable IAudioPolicyCallback pcb) { 11369 if (pcb == null) { 11370 return; 11371 } 11372 unregisterAudioPolicyInt(pcb, "unregisterAudioPolicy"); 11373 } 11374 11375 unregisterAudioPolicyInt(@onNull IAudioPolicyCallback pcb, String operationName)11376 private void unregisterAudioPolicyInt(@NonNull IAudioPolicyCallback pcb, String operationName) { 11377 mDynPolicyLogger.log((new AudioEventLogger.StringEvent(operationName + " for " 11378 + pcb.asBinder()).printLog(TAG))); 11379 synchronized (mAudioPolicies) { 11380 AudioPolicyProxy app = mAudioPolicies.remove(pcb.asBinder()); 11381 if (app == null) { 11382 Slog.w(TAG, "Trying to unregister unknown audio policy for pid " 11383 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()); 11384 return; 11385 } else { 11386 pcb.asBinder().unlinkToDeath(app, 0/*flags*/); 11387 } 11388 app.release(); 11389 } 11390 // TODO implement clearing mix attribute matching info in native audio policy 11391 } 11392 11393 /** 11394 * Checks whether caller has MODIFY_AUDIO_ROUTING permission, and the policy is registered. 11395 * @param errorMsg log warning if permission check failed. 11396 * @return null if the operation on the audio mixes should be cancelled. 11397 */ 11398 @GuardedBy("mAudioPolicies") checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg)11399 private AudioPolicyProxy checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg) { 11400 // permission check 11401 final boolean hasPermissionForPolicy = 11402 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 11403 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 11404 if (!hasPermissionForPolicy) { 11405 Slog.w(TAG, errorMsg + " for pid " + 11406 + Binder.getCallingPid() + " / uid " 11407 + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING"); 11408 return null; 11409 } 11410 // policy registered? 11411 final AudioPolicyProxy app = mAudioPolicies.get(pcb.asBinder()); 11412 if (app == null) { 11413 Slog.w(TAG, errorMsg + " for pid " + 11414 + Binder.getCallingPid() + " / uid " 11415 + Binder.getCallingUid() + ", unregistered policy"); 11416 return null; 11417 } 11418 return app; 11419 } 11420 addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)11421 public int addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) { 11422 if (DEBUG_AP) { Log.d(TAG, "addMixForPolicy for " + pcb.asBinder() 11423 + " with config:" + policyConfig); } 11424 synchronized (mAudioPolicies) { 11425 final AudioPolicyProxy app = 11426 checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy"); 11427 if (app == null){ 11428 return AudioManager.ERROR; 11429 } 11430 return app.addMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS 11431 ? AudioManager.SUCCESS : AudioManager.ERROR; 11432 } 11433 } 11434 removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)11435 public int removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) { 11436 if (DEBUG_AP) { Log.d(TAG, "removeMixForPolicy for " + pcb.asBinder() 11437 + " with config:" + policyConfig); } 11438 synchronized (mAudioPolicies) { 11439 final AudioPolicyProxy app = 11440 checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy"); 11441 if (app == null) { 11442 return AudioManager.ERROR; 11443 } 11444 return app.removeMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS 11445 ? AudioManager.SUCCESS : AudioManager.ERROR; 11446 } 11447 } 11448 11449 /** see AudioPolicy.setUidDeviceAffinity() */ setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)11450 public int setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, 11451 @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) { 11452 if (DEBUG_AP) { 11453 Log.d(TAG, "setUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid); 11454 } 11455 synchronized (mAudioPolicies) { 11456 final AudioPolicyProxy app = 11457 checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy"); 11458 if (app == null) { 11459 return AudioManager.ERROR; 11460 } 11461 if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) { 11462 return AudioManager.ERROR; 11463 } 11464 return app.setUidDeviceAffinities(uid, deviceTypes, deviceAddresses); 11465 } 11466 } 11467 11468 /** see AudioPolicy.setUserIdDeviceAffinity() */ setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)11469 public int setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, 11470 @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) { 11471 if (DEBUG_AP) { 11472 Log.d(TAG, "setUserIdDeviceAffinity for " + pcb.asBinder() + " user:" + userId); 11473 } 11474 11475 synchronized (mAudioPolicies) { 11476 final AudioPolicyProxy app = 11477 checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy"); 11478 if (app == null) { 11479 return AudioManager.ERROR; 11480 } 11481 if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) { 11482 return AudioManager.ERROR; 11483 } 11484 return app.setUserIdDeviceAffinities(userId, deviceTypes, deviceAddresses); 11485 } 11486 } 11487 11488 /** see AudioPolicy.removeUidDeviceAffinity() */ removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid)11489 public int removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid) { 11490 if (DEBUG_AP) { 11491 Log.d(TAG, "removeUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid); 11492 } 11493 synchronized (mAudioPolicies) { 11494 final AudioPolicyProxy app = 11495 checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy"); 11496 if (app == null) { 11497 return AudioManager.ERROR; 11498 } 11499 return app.removeUidDeviceAffinities(uid); 11500 } 11501 } 11502 11503 /** see AudioPolicy.removeUserIdDeviceAffinity() */ removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId)11504 public int removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId) { 11505 if (DEBUG_AP) { 11506 Log.d(TAG, "removeUserIdDeviceAffinity for " + pcb.asBinder() 11507 + " userId:" + userId); 11508 } 11509 synchronized (mAudioPolicies) { 11510 final AudioPolicyProxy app = 11511 checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy"); 11512 if (app == null) { 11513 return AudioManager.ERROR; 11514 } 11515 return app.removeUserIdDeviceAffinities(userId); 11516 } 11517 } 11518 setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb)11519 public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) { 11520 if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior 11521 + " policy " + pcb.asBinder()); 11522 synchronized (mAudioPolicies) { 11523 final AudioPolicyProxy app = 11524 checkUpdateForPolicy(pcb, "Cannot change audio policy focus properties"); 11525 if (app == null){ 11526 return AudioManager.ERROR; 11527 } 11528 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 11529 Slog.e(TAG, "Cannot change audio policy focus properties, unregistered policy"); 11530 return AudioManager.ERROR; 11531 } 11532 if (duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 11533 // is there already one policy managing ducking? 11534 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 11535 if (policy.mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 11536 Slog.e(TAG, "Cannot change audio policy ducking behavior, already handled"); 11537 return AudioManager.ERROR; 11538 } 11539 } 11540 } 11541 app.mFocusDuckBehavior = duckingBehavior; 11542 mMediaFocusControl.setDuckingInExtPolicyAvailable( 11543 duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY); 11544 } 11545 return AudioManager.SUCCESS; 11546 } 11547 11548 /** @see AudioPolicy#getFocusStack() */ getFocusStack()11549 public List<AudioFocusInfo> getFocusStack() { 11550 enforceModifyAudioRoutingPermission(); 11551 return mMediaFocusControl.getFocusStack(); 11552 } 11553 11554 /** @see AudioPolicy#sendFocusLoss */ sendFocusLoss(@onNull AudioFocusInfo focusLoser, @NonNull IAudioPolicyCallback apcb)11555 public boolean sendFocusLoss(@NonNull AudioFocusInfo focusLoser, 11556 @NonNull IAudioPolicyCallback apcb) { 11557 Objects.requireNonNull(focusLoser); 11558 Objects.requireNonNull(apcb); 11559 enforceModifyAudioRoutingPermission(); 11560 if (!mAudioPolicies.containsKey(apcb.asBinder())) { 11561 throw new IllegalStateException("Only registered AudioPolicy can change focus"); 11562 } 11563 if (!mAudioPolicies.get(apcb.asBinder()).mHasFocusListener) { 11564 throw new IllegalStateException("AudioPolicy must have focus listener to change focus"); 11565 } 11566 return mMediaFocusControl.sendFocusLoss(focusLoser); 11567 } 11568 11569 private static final String[] HAL_VERSIONS = 11570 new String[] {"7.1", "7.0", "6.0", "5.0", "4.0", "2.0"}; 11571 11572 /** @see AudioManager#getHalVersion */ getHalVersion()11573 public @Nullable String getHalVersion() { 11574 for (String version : HAL_VERSIONS) { 11575 try { 11576 HwBinder.getService( 11577 String.format("android.hardware.audio@%s::IDevicesFactory", version), 11578 "default"); 11579 return version; 11580 } catch (NoSuchElementException e) { 11581 // Ignore, the specified HAL interface is not found. 11582 } catch (RemoteException re) { 11583 Log.e(TAG, "Remote exception when getting hardware audio service:", re); 11584 } 11585 } 11586 return null; 11587 } 11588 11589 /** see AudioManager.hasRegisteredDynamicPolicy */ hasRegisteredDynamicPolicy()11590 public boolean hasRegisteredDynamicPolicy() { 11591 synchronized (mAudioPolicies) { 11592 return !mAudioPolicies.isEmpty(); 11593 } 11594 } 11595 11596 private final Object mExtVolumeControllerLock = new Object(); 11597 private IAudioPolicyCallback mExtVolumeController; setExtVolumeController(IAudioPolicyCallback apc)11598 private void setExtVolumeController(IAudioPolicyCallback apc) { 11599 if (!mContext.getResources().getBoolean( 11600 com.android.internal.R.bool.config_handleVolumeKeysInWindowManager)) { 11601 Log.e(TAG, "Cannot set external volume controller: device not set for volume keys" + 11602 " handled in PhoneWindowManager"); 11603 return; 11604 } 11605 synchronized (mExtVolumeControllerLock) { 11606 if (mExtVolumeController != null && !mExtVolumeController.asBinder().pingBinder()) { 11607 Log.e(TAG, "Cannot set external volume controller: existing controller"); 11608 } 11609 mExtVolumeController = apc; 11610 } 11611 } 11612 dumpAudioPolicies(PrintWriter pw)11613 private void dumpAudioPolicies(PrintWriter pw) { 11614 pw.println("\nAudio policies:"); 11615 synchronized (mAudioPolicies) { 11616 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 11617 pw.println(policy.toLogFriendlyString()); 11618 } 11619 } 11620 } 11621 11622 //====================== 11623 // Audio policy callbacks from AudioSystem for dynamic policies 11624 //====================== 11625 private final AudioSystem.DynamicPolicyCallback mDynPolicyCallback = 11626 new AudioSystem.DynamicPolicyCallback() { 11627 public void onDynamicPolicyMixStateUpdate(String regId, int state) { 11628 if (!TextUtils.isEmpty(regId)) { 11629 sendMsg(mAudioHandler, MSG_DYN_POLICY_MIX_STATE_UPDATE, SENDMSG_QUEUE, 11630 state /*arg1*/, 0 /*arg2 ignored*/, regId /*obj*/, 0 /*delay*/); 11631 } 11632 } 11633 }; 11634 onDynPolicyMixStateUpdate(String regId, int state)11635 private void onDynPolicyMixStateUpdate(String regId, int state) { 11636 if (DEBUG_AP) Log.d(TAG, "onDynamicPolicyMixStateUpdate("+ regId + ", " + state +")"); 11637 synchronized (mAudioPolicies) { 11638 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 11639 for (AudioMix mix : policy.getMixes()) { 11640 if (mix.getRegistration().equals(regId)) { 11641 try { 11642 policy.mPolicyCallback.notifyMixStateUpdate(regId, state); 11643 } catch (RemoteException e) { 11644 Log.e(TAG, "Can't call notifyMixStateUpdate() on IAudioPolicyCallback " 11645 + policy.mPolicyCallback.asBinder(), e); 11646 } 11647 return; 11648 } 11649 } 11650 } 11651 } 11652 } 11653 11654 //====================== 11655 // Audio policy callbacks from AudioSystem for recording configuration updates 11656 //====================== 11657 private final RecordingActivityMonitor mRecordMonitor; 11658 registerRecordingCallback(IRecordingConfigDispatcher rcdb)11659 public void registerRecordingCallback(IRecordingConfigDispatcher rcdb) { 11660 final boolean isPrivileged = 11661 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 11662 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 11663 mRecordMonitor.registerRecordingCallback(rcdb, isPrivileged); 11664 } 11665 unregisterRecordingCallback(IRecordingConfigDispatcher rcdb)11666 public void unregisterRecordingCallback(IRecordingConfigDispatcher rcdb) { 11667 mRecordMonitor.unregisterRecordingCallback(rcdb); 11668 } 11669 getActiveRecordingConfigurations()11670 public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() { 11671 final boolean isPrivileged = 11672 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 11673 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 11674 return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged); 11675 } 11676 11677 //====================== 11678 // Audio recording state notification from clients 11679 //====================== 11680 /** 11681 * Track a recorder provided by the client 11682 */ trackRecorder(IBinder recorder)11683 public int trackRecorder(IBinder recorder) { 11684 return mRecordMonitor.trackRecorder(recorder); 11685 } 11686 11687 /** 11688 * Receive an event from the client about a tracked recorder 11689 */ recorderEvent(int riid, int event)11690 public void recorderEvent(int riid, int event) { 11691 mRecordMonitor.recorderEvent(riid, event); 11692 } 11693 11694 /** 11695 * Stop tracking the recorder 11696 */ releaseRecorder(int riid)11697 public void releaseRecorder(int riid) { 11698 mRecordMonitor.releaseRecorder(riid); 11699 } 11700 11701 //====================== 11702 // Audio playback notification 11703 //====================== 11704 private final PlaybackActivityMonitor mPlaybackMonitor; 11705 registerPlaybackCallback(IPlaybackConfigDispatcher pcdb)11706 public void registerPlaybackCallback(IPlaybackConfigDispatcher pcdb) { 11707 final boolean isPrivileged = 11708 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 11709 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 11710 mPlaybackMonitor.registerPlaybackCallback(pcdb, isPrivileged); 11711 } 11712 unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb)11713 public void unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb) { 11714 mPlaybackMonitor.unregisterPlaybackCallback(pcdb); 11715 } 11716 getActivePlaybackConfigurations()11717 public List<AudioPlaybackConfiguration> getActivePlaybackConfigurations() { 11718 final boolean isPrivileged = 11719 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 11720 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 11721 return mPlaybackMonitor.getActivePlaybackConfigurations(isPrivileged); 11722 } 11723 trackPlayer(PlayerBase.PlayerIdCard pic)11724 public int trackPlayer(PlayerBase.PlayerIdCard pic) { 11725 if (pic != null && pic.mAttributes != null) { 11726 validateAudioAttributesUsage(pic.mAttributes); 11727 } 11728 return mPlaybackMonitor.trackPlayer(pic); 11729 } 11730 playerAttributes(int piid, AudioAttributes attr)11731 public void playerAttributes(int piid, AudioAttributes attr) { 11732 if (attr != null) { 11733 validateAudioAttributesUsage(attr); 11734 } 11735 mPlaybackMonitor.playerAttributes(piid, attr, Binder.getCallingUid()); 11736 } 11737 11738 /** 11739 * Update player session ID 11740 * @param piid Player id to update 11741 * @param sessionId The new audio session ID 11742 */ playerSessionId(int piid, int sessionId)11743 public void playerSessionId(int piid, int sessionId) { 11744 if (sessionId <= AudioSystem.AUDIO_SESSION_ALLOCATE) { 11745 throw new IllegalArgumentException("invalid session Id " + sessionId); 11746 } 11747 mPlaybackMonitor.playerSessionId(piid, sessionId, Binder.getCallingUid()); 11748 } 11749 11750 /** 11751 * Update player event 11752 * @param piid Player id to update 11753 * @param event The new player event 11754 * @param deviceId The new player device id 11755 */ playerEvent(int piid, int event, int deviceId)11756 public void playerEvent(int piid, int event, int deviceId) { 11757 mPlaybackMonitor.playerEvent(piid, event, deviceId, Binder.getCallingUid()); 11758 } 11759 playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio)11760 public void playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio) { 11761 mPlaybackMonitor.playerHasOpPlayAudio(piid, hasOpPlayAudio, Binder.getCallingUid()); 11762 } 11763 releasePlayer(int piid)11764 public void releasePlayer(int piid) { 11765 mPlaybackMonitor.releasePlayer(piid, Binder.getCallingUid()); 11766 } 11767 11768 /** 11769 * Specifies whether the audio played by this app may or may not be captured by other apps or 11770 * the system. 11771 * 11772 * @param capturePolicy one of 11773 * {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}, 11774 * {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM}, 11775 * {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}. 11776 * @return AudioSystem.AUDIO_STATUS_OK if set allowed capture policy succeed. 11777 * @throws IllegalArgumentException if the argument is not a valid value. 11778 */ setAllowedCapturePolicy(int capturePolicy)11779 public int setAllowedCapturePolicy(int capturePolicy) { 11780 int callingUid = Binder.getCallingUid(); 11781 int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0); 11782 final long identity = Binder.clearCallingIdentity(); 11783 synchronized (mPlaybackMonitor) { 11784 int result = mAudioSystem.setAllowedCapturePolicy(callingUid, flags); 11785 if (result == AudioSystem.AUDIO_STATUS_OK) { 11786 mPlaybackMonitor.setAllowedCapturePolicy(callingUid, capturePolicy); 11787 } 11788 Binder.restoreCallingIdentity(identity); 11789 return result; 11790 } 11791 } 11792 11793 /** 11794 * Return the capture policy. 11795 * @return the cached capture policy for the calling uid. 11796 */ getAllowedCapturePolicy()11797 public int getAllowedCapturePolicy() { 11798 int callingUid = Binder.getCallingUid(); 11799 final long identity = Binder.clearCallingIdentity(); 11800 int capturePolicy = mPlaybackMonitor.getAllowedCapturePolicy(callingUid); 11801 Binder.restoreCallingIdentity(identity); 11802 return capturePolicy; 11803 } 11804 11805 //====================== 11806 // Audio device management 11807 //====================== 11808 private final AudioDeviceBroker mDeviceBroker; 11809 11810 //====================== 11811 // Audio policy proxy 11812 //====================== 11813 private static final class AudioDeviceArray { 11814 final @NonNull int[] mDeviceTypes; 11815 final @NonNull String[] mDeviceAddresses; AudioDeviceArray(@onNull int[] types, @NonNull String[] addresses)11816 AudioDeviceArray(@NonNull int[] types, @NonNull String[] addresses) { 11817 mDeviceTypes = types; 11818 mDeviceAddresses = addresses; 11819 } 11820 } 11821 11822 /** 11823 * This internal class inherits from AudioPolicyConfig, each instance contains all the 11824 * mixes of an AudioPolicy and their configurations. 11825 */ 11826 public class AudioPolicyProxy extends AudioPolicyConfig implements IBinder.DeathRecipient { 11827 private static final String TAG = "AudioPolicyProxy"; 11828 final IAudioPolicyCallback mPolicyCallback; 11829 final boolean mHasFocusListener; 11830 final boolean mIsVolumeController; 11831 final HashMap<Integer, AudioDeviceArray> mUidDeviceAffinities = 11832 new HashMap<Integer, AudioDeviceArray>(); 11833 11834 final HashMap<Integer, AudioDeviceArray> mUserIdDeviceAffinities = 11835 new HashMap<>(); 11836 11837 final IMediaProjection mProjection; 11838 private final class UnregisterOnStopCallback extends IMediaProjectionCallback.Stub { onStop()11839 public void onStop() { 11840 unregisterAudioPolicyAsync(mPolicyCallback); 11841 } 11842 }; 11843 UnregisterOnStopCallback mProjectionCallback; 11844 11845 /** 11846 * Audio focus ducking behavior for an audio policy. 11847 * This variable reflects the value that was successfully set in 11848 * {@link AudioService#setFocusPropertiesForPolicy(int, IAudioPolicyCallback)}. This 11849 * implies that a value of FOCUS_POLICY_DUCKING_IN_POLICY means the corresponding policy 11850 * is handling ducking for audio focus. 11851 */ 11852 int mFocusDuckBehavior = AudioPolicy.FOCUS_POLICY_DUCKING_DEFAULT; 11853 boolean mIsFocusPolicy = false; 11854 boolean mIsTestFocusPolicy = false; 11855 AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)11856 AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, 11857 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, 11858 boolean isVolumeController, IMediaProjection projection) { 11859 super(config); 11860 setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++)); 11861 mPolicyCallback = token; 11862 mHasFocusListener = hasFocusListener; 11863 mIsVolumeController = isVolumeController; 11864 mProjection = projection; 11865 if (mHasFocusListener) { 11866 mMediaFocusControl.addFocusFollower(mPolicyCallback); 11867 // can only ever be true if there is a focus listener 11868 if (isFocusPolicy) { 11869 mIsFocusPolicy = true; 11870 mIsTestFocusPolicy = isTestFocusPolicy; 11871 mMediaFocusControl.setFocusPolicy(mPolicyCallback, mIsTestFocusPolicy); 11872 } 11873 } 11874 if (mIsVolumeController) { 11875 setExtVolumeController(mPolicyCallback); 11876 } 11877 if (mProjection != null) { 11878 mProjectionCallback = new UnregisterOnStopCallback(); 11879 try { 11880 mProjection.registerCallback(mProjectionCallback); 11881 } catch (RemoteException e) { 11882 release(); 11883 throw new IllegalStateException("MediaProjection callback registration failed, " 11884 + "could not link to " + projection + " binder death", e); 11885 } 11886 } 11887 int status = connectMixes(); 11888 if (status != AudioSystem.SUCCESS) { 11889 release(); 11890 throw new IllegalStateException("Could not connect mix, error: " + status); 11891 } 11892 } 11893 binderDied()11894 public void binderDied() { 11895 mDynPolicyLogger.log((new AudioEventLogger.StringEvent("AudioPolicy " 11896 + mPolicyCallback.asBinder() + " died").printLog(TAG))); 11897 release(); 11898 } 11899 getRegistrationId()11900 String getRegistrationId() { 11901 return getRegistration(); 11902 } 11903 release()11904 void release() { 11905 if (mIsFocusPolicy) { 11906 mMediaFocusControl.unsetFocusPolicy(mPolicyCallback, mIsTestFocusPolicy); 11907 } 11908 if (mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 11909 mMediaFocusControl.setDuckingInExtPolicyAvailable(false); 11910 } 11911 if (mHasFocusListener) { 11912 mMediaFocusControl.removeFocusFollower(mPolicyCallback); 11913 } 11914 if (mProjectionCallback != null) { 11915 try { 11916 mProjection.unregisterCallback(mProjectionCallback); 11917 } catch (RemoteException e) { 11918 Log.e(TAG, "Fail to unregister Audiopolicy callback from MediaProjection"); 11919 } 11920 } 11921 if (mIsVolumeController) { 11922 synchronized (mExtVolumeControllerLock) { 11923 mExtVolumeController = null; 11924 } 11925 } 11926 final long identity = Binder.clearCallingIdentity(); 11927 mAudioSystem.registerPolicyMixes(mMixes, false); 11928 Binder.restoreCallingIdentity(identity); 11929 synchronized (mAudioPolicies) { 11930 mAudioPolicies.remove(mPolicyCallback.asBinder()); 11931 } 11932 try { 11933 mPolicyCallback.notifyUnregistration(); 11934 } catch (RemoteException e) { } 11935 } 11936 hasMixAffectingUsage(int usage, int excludedFlags)11937 boolean hasMixAffectingUsage(int usage, int excludedFlags) { 11938 for (AudioMix mix : mMixes) { 11939 if (mix.isAffectingUsage(usage) 11940 && ((mix.getRouteFlags() & excludedFlags) != excludedFlags)) { 11941 return true; 11942 } 11943 } 11944 return false; 11945 } 11946 11947 // Verify all the devices in the array are served by mixes defined in this policy hasMixRoutedToDevices(@onNull int[] deviceTypes, @NonNull String[] deviceAddresses)11948 boolean hasMixRoutedToDevices(@NonNull int[] deviceTypes, 11949 @NonNull String[] deviceAddresses) { 11950 for (int i = 0; i < deviceTypes.length; i++) { 11951 boolean hasDevice = false; 11952 for (AudioMix mix : mMixes) { 11953 // this will check both that the mix has ROUTE_FLAG_RENDER and the device 11954 // is reached by this mix 11955 if (mix.isRoutedToDevice(deviceTypes[i], deviceAddresses[i])) { 11956 hasDevice = true; 11957 break; 11958 } 11959 } 11960 if (!hasDevice) { 11961 return false; 11962 } 11963 } 11964 return true; 11965 } 11966 addMixes(@onNull ArrayList<AudioMix> mixes)11967 int addMixes(@NonNull ArrayList<AudioMix> mixes) { 11968 // TODO optimize to not have to unregister the mixes already in place 11969 synchronized (mMixes) { 11970 mAudioSystem.registerPolicyMixes(mMixes, false); 11971 this.add(mixes); 11972 return mAudioSystem.registerPolicyMixes(mMixes, true); 11973 } 11974 } 11975 removeMixes(@onNull ArrayList<AudioMix> mixes)11976 int removeMixes(@NonNull ArrayList<AudioMix> mixes) { 11977 // TODO optimize to not have to unregister the mixes already in place 11978 synchronized (mMixes) { 11979 mAudioSystem.registerPolicyMixes(mMixes, false); 11980 this.remove(mixes); 11981 return mAudioSystem.registerPolicyMixes(mMixes, true); 11982 } 11983 } 11984 connectMixes()11985 @AudioSystem.AudioSystemError int connectMixes() { 11986 final long identity = Binder.clearCallingIdentity(); 11987 int status = mAudioSystem.registerPolicyMixes(mMixes, true); 11988 Binder.restoreCallingIdentity(identity); 11989 return status; 11990 } 11991 setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses)11992 int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) { 11993 final Integer Uid = new Integer(uid); 11994 if (mUidDeviceAffinities.remove(Uid) != null) { 11995 if (removeUidDeviceAffinitiesFromSystem(uid) != AudioSystem.SUCCESS) { 11996 Log.e(TAG, "AudioSystem. removeUidDeviceAffinities(" + uid + ") failed, " 11997 + " cannot call AudioSystem.setUidDeviceAffinities"); 11998 return AudioManager.ERROR; 11999 } 12000 } 12001 AudioDeviceArray deviceArray = new AudioDeviceArray(types, addresses); 12002 if (setUidDeviceAffinitiesOnSystem(uid, deviceArray) == AudioSystem.SUCCESS) { 12003 mUidDeviceAffinities.put(Uid, deviceArray); 12004 return AudioManager.SUCCESS; 12005 } 12006 Log.e(TAG, "AudioSystem. setUidDeviceAffinities(" + uid + ") failed"); 12007 return AudioManager.ERROR; 12008 } 12009 removeUidDeviceAffinities(int uid)12010 int removeUidDeviceAffinities(int uid) { 12011 if (mUidDeviceAffinities.remove(new Integer(uid)) != null) { 12012 if (removeUidDeviceAffinitiesFromSystem(uid) == AudioSystem.SUCCESS) { 12013 return AudioManager.SUCCESS; 12014 } 12015 } 12016 Log.e(TAG, "AudioSystem. removeUidDeviceAffinities failed"); 12017 return AudioManager.ERROR; 12018 } 12019 removeUidDeviceAffinitiesFromSystem(int uid)12020 @AudioSystem.AudioSystemError private int removeUidDeviceAffinitiesFromSystem(int uid) { 12021 final long identity = Binder.clearCallingIdentity(); 12022 try { 12023 return mAudioSystem.removeUidDeviceAffinities(uid); 12024 } finally { 12025 Binder.restoreCallingIdentity(identity); 12026 } 12027 } 12028 setUidDeviceAffinitiesOnSystem(int uid, AudioDeviceArray deviceArray)12029 @AudioSystem.AudioSystemError private int setUidDeviceAffinitiesOnSystem(int uid, 12030 AudioDeviceArray deviceArray) { 12031 final long identity = Binder.clearCallingIdentity(); 12032 try { 12033 return mAudioSystem.setUidDeviceAffinities(uid, deviceArray.mDeviceTypes, 12034 deviceArray.mDeviceAddresses); 12035 } finally { 12036 Binder.restoreCallingIdentity(identity); 12037 } 12038 } 12039 setUserIdDeviceAffinities(int userId, @NonNull int[] types, @NonNull String[] addresses)12040 int setUserIdDeviceAffinities(int userId, 12041 @NonNull int[] types, @NonNull String[] addresses) { 12042 final Integer UserId = new Integer(userId); 12043 if (mUserIdDeviceAffinities.remove(UserId) != null) { 12044 if (removeUserIdDeviceAffinitiesFromSystem(userId) != AudioSystem.SUCCESS) { 12045 Log.e(TAG, "AudioSystem. removeUserIdDeviceAffinities(" 12046 + UserId + ") failed, " 12047 + " cannot call AudioSystem.setUserIdDeviceAffinities"); 12048 return AudioManager.ERROR; 12049 } 12050 } 12051 AudioDeviceArray audioDeviceArray = new AudioDeviceArray(types, addresses); 12052 if (setUserIdDeviceAffinitiesOnSystem(userId, audioDeviceArray) 12053 == AudioSystem.SUCCESS) { 12054 mUserIdDeviceAffinities.put(UserId, audioDeviceArray); 12055 return AudioManager.SUCCESS; 12056 } 12057 Log.e(TAG, "AudioSystem.setUserIdDeviceAffinities(" + userId + ") failed"); 12058 return AudioManager.ERROR; 12059 } 12060 removeUserIdDeviceAffinities(int userId)12061 int removeUserIdDeviceAffinities(int userId) { 12062 if (mUserIdDeviceAffinities.remove(new Integer(userId)) != null) { 12063 if (removeUserIdDeviceAffinitiesFromSystem(userId) == AudioSystem.SUCCESS) { 12064 return AudioManager.SUCCESS; 12065 } 12066 } 12067 Log.e(TAG, "AudioSystem.removeUserIdDeviceAffinities failed"); 12068 return AudioManager.ERROR; 12069 } 12070 removeUserIdDeviceAffinitiesFromSystem( @serIdInt int userId)12071 @AudioSystem.AudioSystemError private int removeUserIdDeviceAffinitiesFromSystem( 12072 @UserIdInt int userId) { 12073 final long identity = Binder.clearCallingIdentity(); 12074 try { 12075 return mAudioSystem.removeUserIdDeviceAffinities(userId); 12076 } finally { 12077 Binder.restoreCallingIdentity(identity); 12078 } 12079 } 12080 setUserIdDeviceAffinitiesOnSystem( @serIdInt int userId, AudioDeviceArray deviceArray)12081 @AudioSystem.AudioSystemError private int setUserIdDeviceAffinitiesOnSystem( 12082 @UserIdInt int userId, AudioDeviceArray deviceArray) { 12083 final long identity = Binder.clearCallingIdentity(); 12084 try { 12085 return mAudioSystem.setUserIdDeviceAffinities(userId, deviceArray.mDeviceTypes, 12086 deviceArray.mDeviceAddresses); 12087 } finally { 12088 Binder.restoreCallingIdentity(identity); 12089 } 12090 } 12091 setupDeviceAffinities()12092 @AudioSystem.AudioSystemError int setupDeviceAffinities() { 12093 for (Map.Entry<Integer, AudioDeviceArray> uidEntry : mUidDeviceAffinities.entrySet()) { 12094 int uidStatus = removeUidDeviceAffinitiesFromSystem(uidEntry.getKey()); 12095 if (uidStatus != AudioSystem.SUCCESS) { 12096 Log.e(TAG, 12097 "setupDeviceAffinities failed to remove device affinity for uid " 12098 + uidEntry.getKey()); 12099 return uidStatus; 12100 } 12101 uidStatus = setUidDeviceAffinitiesOnSystem(uidEntry.getKey(), uidEntry.getValue()); 12102 if (uidStatus != AudioSystem.SUCCESS) { 12103 Log.e(TAG, 12104 "setupDeviceAffinities failed to set device affinity for uid " 12105 + uidEntry.getKey()); 12106 return uidStatus; 12107 } 12108 } 12109 12110 for (Map.Entry<Integer, AudioDeviceArray> userIdEntry : 12111 mUserIdDeviceAffinities.entrySet()) { 12112 int userIdStatus = removeUserIdDeviceAffinitiesFromSystem(userIdEntry.getKey()); 12113 if (userIdStatus != AudioSystem.SUCCESS) { 12114 Log.e(TAG, 12115 "setupDeviceAffinities failed to remove device affinity for userId " 12116 + userIdEntry.getKey()); 12117 return userIdStatus; 12118 } 12119 userIdStatus = setUserIdDeviceAffinitiesOnSystem(userIdEntry.getKey(), 12120 userIdEntry.getValue()); 12121 if (userIdStatus != AudioSystem.SUCCESS) { 12122 Log.e(TAG, 12123 "setupDeviceAffinities failed to set device affinity for userId " 12124 + userIdEntry.getKey()); 12125 return userIdStatus; 12126 } 12127 } 12128 return AudioSystem.SUCCESS; 12129 } 12130 12131 /** @return human readable debug informations summarizing the state of the object. */ toLogFriendlyString()12132 public String toLogFriendlyString() { 12133 String textDump = super.toLogFriendlyString(); 12134 textDump += " Uid Device Affinities:\n"; 12135 String spacer = " "; 12136 textDump += logFriendlyAttributeDeviceArrayMap("Uid", 12137 mUidDeviceAffinities, spacer); 12138 textDump += " UserId Device Affinities:\n"; 12139 textDump += logFriendlyAttributeDeviceArrayMap("UserId", 12140 mUserIdDeviceAffinities, spacer); 12141 textDump += " Proxy:\n"; 12142 textDump += " is focus policy= " + mIsFocusPolicy + "\n"; 12143 if (mIsFocusPolicy) { 12144 textDump += " focus duck behaviour= " + mFocusDuckBehavior + "\n"; 12145 textDump += " is test focus policy= " + mIsTestFocusPolicy + "\n"; 12146 textDump += " has focus listener= " + mHasFocusListener + "\n"; 12147 } 12148 textDump += " media projection= " + mProjection + "\n"; 12149 return textDump; 12150 } 12151 logFriendlyAttributeDeviceArrayMap(String attribute, Map<Integer, AudioDeviceArray> map, String spacer)12152 private String logFriendlyAttributeDeviceArrayMap(String attribute, 12153 Map<Integer, AudioDeviceArray> map, String spacer) { 12154 final StringBuilder stringBuilder = new StringBuilder(); 12155 for (Map.Entry<Integer, AudioDeviceArray> mapEntry : map.entrySet()) { 12156 stringBuilder.append(spacer).append(attribute).append(": ") 12157 .append(mapEntry.getKey()).append("\n"); 12158 AudioDeviceArray deviceArray = mapEntry.getValue(); 12159 String deviceSpacer = spacer + " "; 12160 for (int i = 0; i < deviceArray.mDeviceTypes.length; i++) { 12161 stringBuilder.append(deviceSpacer).append("Type: 0x") 12162 .append(Integer.toHexString(deviceArray.mDeviceTypes[i])) 12163 .append(" Address: ").append(deviceArray.mDeviceAddresses[i]) 12164 .append("\n"); 12165 } 12166 } 12167 return stringBuilder.toString(); 12168 } 12169 }; 12170 12171 //====================== 12172 // Audio policy: focus 12173 //====================== 12174 /** */ dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb)12175 public int dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb) { 12176 if (afi == null) { 12177 throw new IllegalArgumentException("Illegal null AudioFocusInfo"); 12178 } 12179 if (pcb == null) { 12180 throw new IllegalArgumentException("Illegal null AudioPolicy callback"); 12181 } 12182 synchronized (mAudioPolicies) { 12183 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 12184 throw new IllegalStateException("Unregistered AudioPolicy for focus dispatch"); 12185 } 12186 return mMediaFocusControl.dispatchFocusChange(afi, focusChange); 12187 } 12188 } 12189 setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, IAudioPolicyCallback pcb)12190 public void setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, 12191 IAudioPolicyCallback pcb) { 12192 if (afi == null) { 12193 throw new IllegalArgumentException("Illegal null AudioFocusInfo"); 12194 } 12195 if (pcb == null) { 12196 throw new IllegalArgumentException("Illegal null AudioPolicy callback"); 12197 } 12198 synchronized (mAudioPolicies) { 12199 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 12200 throw new IllegalStateException("Unregistered AudioPolicy for external focus"); 12201 } 12202 mMediaFocusControl.setFocusRequestResultFromExtPolicy(afi, requestResult); 12203 } 12204 } 12205 12206 12207 //====================== 12208 // Audioserver state dispatch 12209 //====================== 12210 private class AsdProxy implements IBinder.DeathRecipient { 12211 private final IAudioServerStateDispatcher mAsd; 12212 AsdProxy(IAudioServerStateDispatcher asd)12213 AsdProxy(IAudioServerStateDispatcher asd) { 12214 mAsd = asd; 12215 } 12216 binderDied()12217 public void binderDied() { 12218 synchronized (mAudioServerStateListeners) { 12219 mAudioServerStateListeners.remove(mAsd.asBinder()); 12220 } 12221 } 12222 callback()12223 IAudioServerStateDispatcher callback() { 12224 return mAsd; 12225 } 12226 } 12227 12228 private final HashMap<IBinder, AsdProxy> mAudioServerStateListeners = 12229 new HashMap<IBinder, AsdProxy>(); 12230 checkMonitorAudioServerStatePermission()12231 private void checkMonitorAudioServerStatePermission() { 12232 if (!(mContext.checkCallingOrSelfPermission( 12233 android.Manifest.permission.MODIFY_PHONE_STATE) == 12234 PackageManager.PERMISSION_GRANTED || 12235 mContext.checkCallingOrSelfPermission( 12236 android.Manifest.permission.MODIFY_AUDIO_ROUTING) == 12237 PackageManager.PERMISSION_GRANTED)) { 12238 throw new SecurityException("Not allowed to monitor audioserver state"); 12239 } 12240 } 12241 registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd)12242 public void registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd) { 12243 checkMonitorAudioServerStatePermission(); 12244 synchronized (mAudioServerStateListeners) { 12245 if (mAudioServerStateListeners.containsKey(asd.asBinder())) { 12246 Slog.w(TAG, "Cannot re-register audio server state dispatcher"); 12247 return; 12248 } 12249 AsdProxy asdp = new AsdProxy(asd); 12250 try { 12251 asd.asBinder().linkToDeath(asdp, 0/*flags*/); 12252 } catch (RemoteException e) { 12253 12254 } 12255 mAudioServerStateListeners.put(asd.asBinder(), asdp); 12256 } 12257 } 12258 unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd)12259 public void unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd) { 12260 checkMonitorAudioServerStatePermission(); 12261 synchronized (mAudioServerStateListeners) { 12262 AsdProxy asdp = mAudioServerStateListeners.remove(asd.asBinder()); 12263 if (asdp == null) { 12264 Slog.w(TAG, "Trying to unregister unknown audioserver state dispatcher for pid " 12265 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()); 12266 return; 12267 } else { 12268 asd.asBinder().unlinkToDeath(asdp, 0/*flags*/); 12269 } 12270 } 12271 } 12272 isAudioServerRunning()12273 public boolean isAudioServerRunning() { 12274 checkMonitorAudioServerStatePermission(); 12275 return (AudioSystem.checkAudioFlinger() == AudioSystem.AUDIO_STATUS_OK); 12276 } 12277 12278 //====================== 12279 // Audio HAL process dump 12280 //====================== 12281 12282 private static final String AUDIO_HAL_SERVICE_PREFIX = "android.hardware.audio"; 12283 getAudioHalPids()12284 private Set<Integer> getAudioHalPids() { 12285 try { 12286 IServiceManager serviceManager = IServiceManager.getService(); 12287 ArrayList<IServiceManager.InstanceDebugInfo> dump = 12288 serviceManager.debugDump(); 12289 HashSet<Integer> pids = new HashSet<>(); 12290 for (IServiceManager.InstanceDebugInfo info : dump) { 12291 if (info.pid != IServiceManager.PidConstant.NO_PID 12292 && info.interfaceName != null 12293 && info.interfaceName.startsWith(AUDIO_HAL_SERVICE_PREFIX)) { 12294 pids.add(info.pid); 12295 } 12296 } 12297 return pids; 12298 } catch (RemoteException e) { 12299 return new HashSet<Integer>(); 12300 } 12301 } 12302 updateAudioHalPids()12303 private void updateAudioHalPids() { 12304 Set<Integer> pidsSet = getAudioHalPids(); 12305 if (pidsSet.isEmpty()) { 12306 Slog.w(TAG, "Could not retrieve audio HAL service pids"); 12307 return; 12308 } 12309 int[] pidsArray = pidsSet.stream().mapToInt(Integer::intValue).toArray(); 12310 AudioSystem.setAudioHalPids(pidsArray); 12311 } 12312 12313 //====================== 12314 // Multi Audio Focus 12315 //====================== setMultiAudioFocusEnabled(boolean enabled)12316 public void setMultiAudioFocusEnabled(boolean enabled) { 12317 enforceModifyAudioRoutingPermission(); 12318 if (mMediaFocusControl != null) { 12319 boolean mafEnabled = mMediaFocusControl.getMultiAudioFocusEnabled(); 12320 if (mafEnabled != enabled) { 12321 mMediaFocusControl.updateMultiAudioFocus(enabled); 12322 if (!enabled) { 12323 mDeviceBroker.postBroadcastBecomingNoisy(); 12324 } 12325 } 12326 } 12327 } 12328 12329 /** 12330 * @hide 12331 * Sets an additional audio output device delay in milliseconds. 12332 * 12333 * The additional output delay is a request to the output device to 12334 * delay audio presentation (generally with respect to video presentation for better 12335 * synchronization). 12336 * It may not be supported by all output devices, 12337 * and typically increases the audio latency by the amount of additional 12338 * audio delay requested. 12339 * 12340 * If additional audio delay is supported by an audio output device, 12341 * it is expected to be supported for all output streams (and configurations) 12342 * opened on that device. 12343 * 12344 * @param deviceType 12345 * @param address 12346 * @param delayMillis delay in milliseconds desired. This should be in range of {@code 0} 12347 * to the value returned by {@link #getMaxAdditionalOutputDeviceDelay()}. 12348 * @return true if successful, false if the device does not support output device delay 12349 * or the delay is not in range of {@link #getMaxAdditionalOutputDeviceDelay()}. 12350 */ 12351 @Override 12352 //@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) setAdditionalOutputDeviceDelay( @onNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis)12353 public boolean setAdditionalOutputDeviceDelay( 12354 @NonNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis) { 12355 Objects.requireNonNull(device, "device must not be null"); 12356 enforceModifyAudioRoutingPermission(); 12357 final String getterKey = "additional_output_device_delay=" 12358 + device.getInternalType() + "," + device.getAddress(); // "getter" key as an id. 12359 final String setterKey = getterKey + "," + delayMillis; // append the delay for setter 12360 return mRestorableParameters.setParameters(getterKey, setterKey) 12361 == AudioSystem.AUDIO_STATUS_OK; 12362 } 12363 12364 /** 12365 * @hide 12366 * Returns the current additional audio output device delay in milliseconds. 12367 * 12368 * @param deviceType 12369 * @param address 12370 * @return the additional output device delay. This is a non-negative number. 12371 * {@code 0} is returned if unsupported. 12372 */ 12373 @Override 12374 @IntRange(from = 0) getAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)12375 public long getAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) { 12376 Objects.requireNonNull(device, "device must not be null"); 12377 final String key = "additional_output_device_delay"; 12378 final String reply = AudioSystem.getParameters( 12379 key + "=" + device.getInternalType() + "," + device.getAddress()); 12380 long delayMillis; 12381 try { 12382 delayMillis = Long.parseLong(reply.substring(key.length() + 1)); 12383 } catch (NullPointerException e) { 12384 delayMillis = 0; 12385 } 12386 return delayMillis; 12387 } 12388 12389 /** 12390 * @hide 12391 * Returns the maximum additional audio output device delay in milliseconds. 12392 * 12393 * @param deviceType 12394 * @param address 12395 * @return the maximum output device delay in milliseconds that can be set. 12396 * This is a non-negative number 12397 * representing the additional audio delay supported for the device. 12398 * {@code 0} is returned if unsupported. 12399 */ 12400 @Override 12401 @IntRange(from = 0) getMaxAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)12402 public long getMaxAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) { 12403 Objects.requireNonNull(device, "device must not be null"); 12404 final String key = "max_additional_output_device_delay"; 12405 final String reply = AudioSystem.getParameters( 12406 key + "=" + device.getInternalType() + "," + device.getAddress()); 12407 long delayMillis; 12408 try { 12409 delayMillis = Long.parseLong(reply.substring(key.length() + 1)); 12410 } catch (NullPointerException e) { 12411 delayMillis = 0; 12412 } 12413 return delayMillis; 12414 } 12415 12416 /** @see AudioManager#addAssistantServicesUids(int []) */ 12417 @Override addAssistantServicesUids(int [] assistantUids)12418 public void addAssistantServicesUids(int [] assistantUids) { 12419 enforceModifyAudioRoutingPermission(); 12420 Objects.requireNonNull(assistantUids); 12421 12422 synchronized (mSettingsLock) { 12423 addAssistantServiceUidsLocked(assistantUids); 12424 } 12425 } 12426 12427 /** @see AudioManager#removeAssistantServicesUids(int []) */ 12428 @Override removeAssistantServicesUids(int [] assistantUids)12429 public void removeAssistantServicesUids(int [] assistantUids) { 12430 enforceModifyAudioRoutingPermission(); 12431 Objects.requireNonNull(assistantUids); 12432 synchronized (mSettingsLock) { 12433 removeAssistantServiceUidsLocked(assistantUids); 12434 } 12435 } 12436 12437 /** @see AudioManager#getAssistantServicesUids() */ 12438 @Override getAssistantServicesUids()12439 public int[] getAssistantServicesUids() { 12440 enforceModifyAudioRoutingPermission(); 12441 int [] assistantUids; 12442 synchronized (mSettingsLock) { 12443 assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray(); 12444 } 12445 return assistantUids; 12446 } 12447 12448 /** @see AudioManager#setActiveAssistantServiceUids(int []) */ 12449 @Override setActiveAssistantServiceUids(int [] activeAssistantUids)12450 public void setActiveAssistantServiceUids(int [] activeAssistantUids) { 12451 enforceModifyAudioRoutingPermission(); 12452 Objects.requireNonNull(activeAssistantUids); 12453 synchronized (mSettingsLock) { 12454 mActiveAssistantServiceUids = activeAssistantUids; 12455 } 12456 updateActiveAssistantServiceUids(); 12457 } 12458 12459 /** @see AudioManager#getActiveAssistantServiceUids() */ 12460 @Override getActiveAssistantServiceUids()12461 public int[] getActiveAssistantServiceUids() { 12462 enforceModifyAudioRoutingPermission(); 12463 int [] activeAssistantUids; 12464 synchronized (mSettingsLock) { 12465 activeAssistantUids = mActiveAssistantServiceUids.clone(); 12466 } 12467 return activeAssistantUids; 12468 } 12469 getDeviceSensorUuid(AudioDeviceAttributes device)12470 UUID getDeviceSensorUuid(AudioDeviceAttributes device) { 12471 return mDeviceBroker.getDeviceSensorUuid(device); 12472 } 12473 12474 //====================== 12475 // misc 12476 //====================== 12477 private final HashMap<IBinder, AudioPolicyProxy> mAudioPolicies = 12478 new HashMap<IBinder, AudioPolicyProxy>(); 12479 @GuardedBy("mAudioPolicies") 12480 private int mAudioPolicyCounter = 0; 12481 12482 //====================== 12483 // Helper functions for full and fixed volume device 12484 //====================== isFixedVolumeDevice(int deviceType)12485 private boolean isFixedVolumeDevice(int deviceType) { 12486 if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX 12487 && mRecordMonitor.isLegacyRemoteSubmixActive()) { 12488 return false; 12489 } 12490 return mFixedVolumeDevices.contains(deviceType); 12491 } 12492 isFullVolumeDevice(int deviceType)12493 private boolean isFullVolumeDevice(int deviceType) { 12494 if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX 12495 && mRecordMonitor.isLegacyRemoteSubmixActive()) { 12496 return false; 12497 } 12498 return mFullVolumeDevices.contains(deviceType); 12499 } 12500 12501 /** 12502 * Returns whether the input device uses absolute volume behavior. This is distinct 12503 * from Bluetooth A2DP absolute volume behavior ({@link #isA2dpAbsoluteVolumeDevice}). 12504 */ isAbsoluteVolumeDevice(int deviceType)12505 private boolean isAbsoluteVolumeDevice(int deviceType) { 12506 return mAbsoluteVolumeDeviceInfoMap.containsKey(deviceType); 12507 } 12508 12509 /** 12510 * Returns whether the input device is a Bluetooth A2dp device that uses absolute volume 12511 * behavior. This is distinct from the general implementation of absolute volume behavior 12512 * ({@link #isAbsoluteVolumeDevice}). 12513 */ isA2dpAbsoluteVolumeDevice(int deviceType)12514 private boolean isA2dpAbsoluteVolumeDevice(int deviceType) { 12515 return mAvrcpAbsVolSupported && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType); 12516 } 12517 12518 //==================== 12519 // Helper functions for {set,get}DeviceVolumeBehavior 12520 //==================== getSettingsNameForDeviceVolumeBehavior(int deviceType)12521 private static String getSettingsNameForDeviceVolumeBehavior(int deviceType) { 12522 return "AudioService_DeviceVolumeBehavior_" + AudioSystem.getOutputDeviceName(deviceType); 12523 } 12524 persistDeviceVolumeBehavior(int deviceType, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior)12525 private void persistDeviceVolumeBehavior(int deviceType, 12526 @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) { 12527 if (DEBUG_VOL) { 12528 Log.d(TAG, "Persisting Volume Behavior for DeviceType: " + deviceType); 12529 } 12530 final long callingIdentity = Binder.clearCallingIdentity(); 12531 try { 12532 mSettings.putSystemIntForUser(mContentResolver, 12533 getSettingsNameForDeviceVolumeBehavior(deviceType), 12534 deviceVolumeBehavior, 12535 UserHandle.USER_CURRENT); 12536 } finally { 12537 Binder.restoreCallingIdentity(callingIdentity); 12538 } 12539 } 12540 12541 @AudioManager.DeviceVolumeBehaviorState retrieveStoredDeviceVolumeBehavior(int deviceType)12542 private int retrieveStoredDeviceVolumeBehavior(int deviceType) { 12543 return mSettings.getSystemIntForUser(mContentResolver, 12544 getSettingsNameForDeviceVolumeBehavior(deviceType), 12545 AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET, 12546 UserHandle.USER_CURRENT); 12547 } 12548 restoreDeviceVolumeBehavior()12549 private void restoreDeviceVolumeBehavior() { 12550 for (int deviceType : AudioSystem.DEVICE_OUT_ALL_SET) { 12551 if (DEBUG_VOL) { 12552 Log.d(TAG, "Retrieving Volume Behavior for DeviceType: " + deviceType); 12553 } 12554 int deviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(deviceType); 12555 if (deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) { 12556 if (DEBUG_VOL) { 12557 Log.d(TAG, "Skipping Setting Volume Behavior for DeviceType: " + deviceType); 12558 } 12559 continue; 12560 } 12561 12562 setDeviceVolumeBehaviorInternal(new AudioDeviceAttributes(deviceType, ""), 12563 deviceVolumeBehavior, "AudioService.restoreDeviceVolumeBehavior()"); 12564 } 12565 } 12566 12567 /** 12568 * @param audioSystemDeviceOut one of AudioSystem.DEVICE_OUT_* 12569 * @return whether {@code audioSystemDeviceOut} has previously been set to a specific volume 12570 * behavior 12571 */ hasDeviceVolumeBehavior( int audioSystemDeviceOut)12572 private boolean hasDeviceVolumeBehavior( 12573 int audioSystemDeviceOut) { 12574 return retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut) 12575 != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET; 12576 } 12577 addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut)12578 private boolean addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut) { 12579 if (DEBUG_VOL) { 12580 Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 12581 + " to mFixedVolumeDevices"); 12582 } 12583 return mFixedVolumeDevices.add(audioSystemDeviceOut); 12584 } 12585 removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut)12586 private boolean removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut) { 12587 if (DEBUG_VOL) { 12588 Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 12589 + " from mFixedVolumeDevices"); 12590 } 12591 return mFixedVolumeDevices.remove(audioSystemDeviceOut); 12592 } 12593 addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut)12594 private boolean addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut) { 12595 if (DEBUG_VOL) { 12596 Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 12597 + " to mFullVolumeDevices"); 12598 } 12599 return mFullVolumeDevices.add(audioSystemDeviceOut); 12600 } 12601 removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut)12602 private boolean removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut) { 12603 if (DEBUG_VOL) { 12604 Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 12605 + " from mFullVolumeDevices"); 12606 } 12607 return mFullVolumeDevices.remove(audioSystemDeviceOut); 12608 } 12609 addAudioSystemDeviceOutToAbsVolumeDevices( int audioSystemDeviceOut, AbsoluteVolumeDeviceInfo info)12610 private AbsoluteVolumeDeviceInfo addAudioSystemDeviceOutToAbsVolumeDevices( 12611 int audioSystemDeviceOut, AbsoluteVolumeDeviceInfo info) { 12612 if (DEBUG_VOL) { 12613 Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 12614 + " from mAbsoluteVolumeDeviceInfoMap"); 12615 } 12616 return mAbsoluteVolumeDeviceInfoMap.put(audioSystemDeviceOut, info); 12617 } 12618 removeAudioSystemDeviceOutFromAbsVolumeDevices( int audioSystemDeviceOut)12619 private AbsoluteVolumeDeviceInfo removeAudioSystemDeviceOutFromAbsVolumeDevices( 12620 int audioSystemDeviceOut) { 12621 if (DEBUG_VOL) { 12622 Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 12623 + " from mAbsoluteVolumeDeviceInfoMap"); 12624 } 12625 return mAbsoluteVolumeDeviceInfoMap.remove(audioSystemDeviceOut); 12626 } 12627 12628 //==================== 12629 // Helper functions for app ops 12630 //==================== 12631 /** 12632 * Validates, and notes an app op for a given uid and package name. 12633 * Validation comes from exception catching: a security exception indicates the package 12634 * doesn't exist, an IAE indicates the uid and package don't match. The code only checks 12635 * if exception was thrown for robustness to code changes in op validation 12636 * @param op the app op to check 12637 * @param uid the uid of the caller 12638 * @param packageName the package to check 12639 * @return true if the origin of the call is valid (no uid / package mismatch) and the caller 12640 * is allowed to perform the operation 12641 */ checkNoteAppOp(int op, int uid, String packageName, String attributionTag)12642 private boolean checkNoteAppOp(int op, int uid, String packageName, String attributionTag) { 12643 try { 12644 if (mAppOps.noteOp(op, uid, packageName, attributionTag, null) 12645 != AppOpsManager.MODE_ALLOWED) { 12646 return false; 12647 } 12648 } catch (Exception e) { 12649 Log.e(TAG, "Error noting op:" + op + " on uid:" + uid + " for package:" 12650 + packageName, e); 12651 return false; 12652 } 12653 return true; 12654 } 12655 } 12656