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.provider.Settings.Secure.VOLUME_HUSH_MUTE; 26 import static android.provider.Settings.Secure.VOLUME_HUSH_OFF; 27 import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE; 28 29 import static com.android.server.audio.AudioEventLogger.Event.ALOGE; 30 import static com.android.server.audio.AudioEventLogger.Event.ALOGI; 31 import static com.android.server.audio.AudioEventLogger.Event.ALOGW; 32 33 import android.Manifest; 34 import android.annotation.IntDef; 35 import android.annotation.IntRange; 36 import android.annotation.NonNull; 37 import android.annotation.Nullable; 38 import android.annotation.UserIdInt; 39 import android.app.ActivityManager; 40 import android.app.ActivityManagerInternal; 41 import android.app.AppGlobals; 42 import android.app.AppOpsManager; 43 import android.app.IUidObserver; 44 import android.app.NotificationManager; 45 import android.app.role.OnRoleHoldersChangedListener; 46 import android.app.role.RoleManager; 47 import android.bluetooth.BluetoothAdapter; 48 import android.bluetooth.BluetoothDevice; 49 import android.bluetooth.BluetoothHeadset; 50 import android.bluetooth.BluetoothProfile; 51 import android.content.BroadcastReceiver; 52 import android.content.ComponentName; 53 import android.content.ContentResolver; 54 import android.content.Context; 55 import android.content.Intent; 56 import android.content.IntentFilter; 57 import android.content.pm.ApplicationInfo; 58 import android.content.pm.PackageInfo; 59 import android.content.pm.PackageManager; 60 import android.content.pm.ResolveInfo; 61 import android.content.pm.UserInfo; 62 import android.content.res.Configuration; 63 import android.database.ContentObserver; 64 import android.hardware.SensorPrivacyManager; 65 import android.hardware.SensorPrivacyManagerInternal; 66 import android.hardware.hdmi.HdmiAudioSystemClient; 67 import android.hardware.hdmi.HdmiControlManager; 68 import android.hardware.hdmi.HdmiPlaybackClient; 69 import android.hardware.hdmi.HdmiTvClient; 70 import android.hardware.input.InputManager; 71 import android.hardware.usb.UsbManager; 72 import android.hidl.manager.V1_0.IServiceManager; 73 import android.media.AudioAttributes; 74 import android.media.AudioAttributes.AttributeSystemUsage; 75 import android.media.AudioDeviceAttributes; 76 import android.media.AudioDeviceInfo; 77 import android.media.AudioFocusInfo; 78 import android.media.AudioFocusRequest; 79 import android.media.AudioFormat; 80 import android.media.AudioManager; 81 import android.media.AudioManagerInternal; 82 import android.media.AudioPlaybackConfiguration; 83 import android.media.AudioRecordingConfiguration; 84 import android.media.AudioRoutesInfo; 85 import android.media.AudioSystem; 86 import android.media.IAudioFocusDispatcher; 87 import android.media.IAudioModeDispatcher; 88 import android.media.IAudioRoutesObserver; 89 import android.media.IAudioServerStateDispatcher; 90 import android.media.IAudioService; 91 import android.media.ICapturePresetDevicesRoleDispatcher; 92 import android.media.ICommunicationDeviceDispatcher; 93 import android.media.IPlaybackConfigDispatcher; 94 import android.media.IRecordingConfigDispatcher; 95 import android.media.IRingtonePlayer; 96 import android.media.IStrategyPreferredDevicesDispatcher; 97 import android.media.IVolumeController; 98 import android.media.MediaMetrics; 99 import android.media.MediaRecorder.AudioSource; 100 import android.media.PlayerBase; 101 import android.media.VolumePolicy; 102 import android.media.audiofx.AudioEffect; 103 import android.media.audiopolicy.AudioMix; 104 import android.media.audiopolicy.AudioPolicy; 105 import android.media.audiopolicy.AudioPolicyConfig; 106 import android.media.audiopolicy.AudioProductStrategy; 107 import android.media.audiopolicy.AudioVolumeGroup; 108 import android.media.audiopolicy.IAudioPolicyCallback; 109 import android.media.projection.IMediaProjection; 110 import android.media.projection.IMediaProjectionCallback; 111 import android.media.projection.IMediaProjectionManager; 112 import android.net.Uri; 113 import android.os.Binder; 114 import android.os.Build; 115 import android.os.Bundle; 116 import android.os.Handler; 117 import android.os.IBinder; 118 import android.os.Looper; 119 import android.os.Message; 120 import android.os.PowerManager; 121 import android.os.Process; 122 import android.os.RemoteCallbackList; 123 import android.os.RemoteException; 124 import android.os.ServiceManager; 125 import android.os.SystemClock; 126 import android.os.SystemProperties; 127 import android.os.UserHandle; 128 import android.os.UserManager; 129 import android.os.VibrationEffect; 130 import android.os.Vibrator; 131 import android.os.VibratorManager; 132 import android.provider.Settings; 133 import android.provider.Settings.System; 134 import android.service.notification.ZenModeConfig; 135 import android.telecom.TelecomManager; 136 import android.text.TextUtils; 137 import android.util.AndroidRuntimeException; 138 import android.util.IntArray; 139 import android.util.Log; 140 import android.util.MathUtils; 141 import android.util.PrintWriterPrinter; 142 import android.util.Slog; 143 import android.util.SparseArray; 144 import android.util.SparseIntArray; 145 import android.view.KeyEvent; 146 import android.view.accessibility.AccessibilityManager; 147 import android.widget.Toast; 148 149 import com.android.internal.annotations.GuardedBy; 150 import com.android.internal.annotations.VisibleForTesting; 151 import com.android.internal.util.DumpUtils; 152 import com.android.internal.util.Preconditions; 153 import com.android.server.EventLogTags; 154 import com.android.server.LocalServices; 155 import com.android.server.SystemService; 156 import com.android.server.audio.AudioServiceEvents.PhoneStateEvent; 157 import com.android.server.audio.AudioServiceEvents.VolumeEvent; 158 import com.android.server.pm.UserManagerInternal; 159 import com.android.server.pm.UserManagerInternal.UserRestrictionsListener; 160 import com.android.server.pm.UserManagerService; 161 import com.android.server.wm.ActivityTaskManagerInternal; 162 163 import java.io.FileDescriptor; 164 import java.io.PrintWriter; 165 import java.lang.annotation.Retention; 166 import java.lang.annotation.RetentionPolicy; 167 import java.text.SimpleDateFormat; 168 import java.util.ArrayList; 169 import java.util.Arrays; 170 import java.util.Collection; 171 import java.util.Date; 172 import java.util.HashMap; 173 import java.util.HashSet; 174 import java.util.Iterator; 175 import java.util.LinkedHashMap; 176 import java.util.List; 177 import java.util.Map; 178 import java.util.NoSuchElementException; 179 import java.util.Objects; 180 import java.util.Set; 181 import java.util.concurrent.Executor; 182 import java.util.concurrent.atomic.AtomicBoolean; 183 import java.util.concurrent.atomic.AtomicInteger; 184 import java.util.function.BooleanSupplier; 185 import java.util.stream.Collectors; 186 187 /** 188 * The implementation of the audio service for volume, audio focus, device management... 189 * <p> 190 * This implementation focuses on delivering a responsive UI. Most methods are 191 * asynchronous to external calls. For example, the task of setting a volume 192 * will update our internal state, but in a separate thread will set the system 193 * volume and later persist to the database. Similarly, setting the ringer mode 194 * will update the state and broadcast a change and in a separate thread later 195 * persist the ringer mode. 196 * 197 * @hide 198 */ 199 public class AudioService extends IAudioService.Stub 200 implements AccessibilityManager.TouchExplorationStateChangeListener, 201 AccessibilityManager.AccessibilityServicesStateChangeListener { 202 203 private static final String TAG = "AS.AudioService"; 204 205 private final AudioSystemAdapter mAudioSystem; 206 private final SystemServerAdapter mSystemServer; 207 208 /** Debug audio mode */ 209 protected static final boolean DEBUG_MODE = false; 210 211 /** Debug audio policy feature */ 212 protected static final boolean DEBUG_AP = false; 213 214 /** Debug volumes */ 215 protected static final boolean DEBUG_VOL = false; 216 217 /** debug calls to devices APIs */ 218 protected static final boolean DEBUG_DEVICES = false; 219 220 /** Debug communication route */ 221 protected static final boolean DEBUG_COMM_RTE = false; 222 223 /** How long to delay before persisting a change in volume/ringer mode. */ 224 private static final int PERSIST_DELAY = 500; 225 226 /** How long to delay after a volume down event before unmuting a stream */ 227 private static final int UNMUTE_STREAM_DELAY = 350; 228 229 /** 230 * Delay before disconnecting a device that would cause BECOMING_NOISY intent to be sent, 231 * to give a chance to applications to pause. 232 */ 233 @VisibleForTesting 234 public static final int BECOMING_NOISY_DELAY_MS = 1000; 235 236 /** 237 * Only used in the result from {@link #checkForRingerModeChange(int, int, int)} 238 */ 239 private static final int FLAG_ADJUST_VOLUME = 1; 240 241 private final Context mContext; 242 private final ContentResolver mContentResolver; 243 private final AppOpsManager mAppOps; 244 245 // the platform type affects volume and silent mode behavior 246 private final int mPlatformType; 247 248 // indicates whether the system maps all streams to a single stream. 249 private final boolean mIsSingleVolume; 250 isPlatformVoice()251 /*package*/ boolean isPlatformVoice() { 252 return mPlatformType == AudioSystem.PLATFORM_VOICE; 253 } 254 isPlatformTelevision()255 /*package*/ boolean isPlatformTelevision() { 256 return mPlatformType == AudioSystem.PLATFORM_TELEVISION; 257 } 258 isPlatformAutomotive()259 /*package*/ boolean isPlatformAutomotive() { 260 return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); 261 } 262 263 /** The controller for the volume UI. */ 264 private final VolumeController mVolumeController = new VolumeController(); 265 266 // sendMsg() flags 267 /** If the msg is already queued, replace it with this one. */ 268 private static final int SENDMSG_REPLACE = 0; 269 /** If the msg is already queued, ignore this one and leave the old. */ 270 private static final int SENDMSG_NOOP = 1; 271 /** If the msg is already queued, queue this one and leave the old. */ 272 private static final int SENDMSG_QUEUE = 2; 273 274 // AudioHandler messages 275 private static final int MSG_SET_DEVICE_VOLUME = 0; 276 private static final int MSG_PERSIST_VOLUME = 1; 277 private static final int MSG_PERSIST_VOLUME_GROUP = 2; 278 private static final int MSG_PERSIST_RINGER_MODE = 3; 279 private static final int MSG_AUDIO_SERVER_DIED = 4; 280 private static final int MSG_PLAY_SOUND_EFFECT = 5; 281 private static final int MSG_LOAD_SOUND_EFFECTS = 7; 282 private static final int MSG_SET_FORCE_USE = 8; 283 private static final int MSG_BT_HEADSET_CNCT_FAILED = 9; 284 private static final int MSG_SET_ALL_VOLUMES = 10; 285 private static final int MSG_CHECK_MUSIC_ACTIVE = 11; 286 private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 12; 287 private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 13; 288 private static final int MSG_PERSIST_SAFE_VOLUME_STATE = 14; 289 private static final int MSG_UNLOAD_SOUND_EFFECTS = 15; 290 private static final int MSG_SYSTEM_READY = 16; 291 private static final int MSG_PERSIST_MUSIC_ACTIVE_MS = 17; 292 private static final int MSG_UNMUTE_STREAM = 18; 293 private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 19; 294 private static final int MSG_INDICATE_SYSTEM_READY = 20; 295 private static final int MSG_ACCESSORY_PLUG_MEDIA_UNMUTE = 21; 296 private static final int MSG_NOTIFY_VOL_EVENT = 22; 297 private static final int MSG_DISPATCH_AUDIO_SERVER_STATE = 23; 298 private static final int MSG_ENABLE_SURROUND_FORMATS = 24; 299 private static final int MSG_UPDATE_RINGER_MODE = 25; 300 private static final int MSG_SET_DEVICE_STREAM_VOLUME = 26; 301 private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27; 302 private static final int MSG_HDMI_VOLUME_CHECK = 28; 303 private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29; 304 private static final int MSG_BROADCAST_MICROPHONE_MUTE = 30; 305 private static final int MSG_CHECK_MODE_FOR_UID = 31; 306 private static final int MSG_STREAM_DEVICES_CHANGED = 32; 307 private static final int MSG_UPDATE_VOLUME_STATES_FOR_DEVICE = 33; 308 private static final int MSG_REINIT_VOLUMES = 34; 309 private static final int MSG_UPDATE_A11Y_SERVICE_UIDS = 35; 310 private static final int MSG_UPDATE_AUDIO_MODE = 36; 311 private static final int MSG_RECORDING_CONFIG_CHANGE = 37; 312 private static final int MSG_SET_A2DP_DEV_CONNECTION_STATE = 38; 313 private static final int MSG_A2DP_DEV_CONFIG_CHANGE = 39; 314 private static final int MSG_DISPATCH_AUDIO_MODE = 40; 315 316 // start of messages handled under wakelock 317 // these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(), 318 // and not with sendMsg(..., ..., SENDMSG_QUEUE, ...) 319 private static final int MSG_DISABLE_AUDIO_FOR_UID = 100; 320 private static final int MSG_INIT_STREAMS_VOLUMES = 101; 321 // end of messages handled under wakelock 322 323 // retry delay in case of failure to indicate system ready to AudioFlinger 324 private static final int INDICATE_SYSTEM_READY_RETRY_DELAY_MS = 1000; 325 326 /** @see AudioSystemThread */ 327 private AudioSystemThread mAudioSystemThread; 328 /** @see AudioHandler */ 329 private AudioHandler mAudioHandler; 330 /** @see VolumeStreamState */ 331 private VolumeStreamState[] mStreamStates; 332 getVssVolumeForDevice(int stream, int device)333 /*package*/ int getVssVolumeForDevice(int stream, int device) { 334 return mStreamStates[stream].getIndex(device); 335 } 336 337 private SettingsObserver mSettingsObserver; 338 339 private AtomicInteger mMode = new AtomicInteger(AudioSystem.MODE_NORMAL); 340 341 // protects mRingerMode 342 private final Object mSettingsLock = new Object(); 343 344 /** Maximum volume index values for audio streams */ 345 protected static int[] MAX_STREAM_VOLUME = new int[] { 346 5, // STREAM_VOICE_CALL 347 7, // STREAM_SYSTEM 348 7, // STREAM_RING 349 15, // STREAM_MUSIC 350 7, // STREAM_ALARM 351 7, // STREAM_NOTIFICATION 352 15, // STREAM_BLUETOOTH_SCO 353 7, // STREAM_SYSTEM_ENFORCED 354 15, // STREAM_DTMF 355 15, // STREAM_TTS 356 15, // STREAM_ACCESSIBILITY 357 15 // STREAM_ASSISTANT 358 }; 359 360 /** Minimum volume index values for audio streams */ 361 protected static int[] MIN_STREAM_VOLUME = new int[] { 362 1, // STREAM_VOICE_CALL 363 0, // STREAM_SYSTEM 364 0, // STREAM_RING 365 0, // STREAM_MUSIC 366 1, // STREAM_ALARM 367 0, // STREAM_NOTIFICATION 368 0, // STREAM_BLUETOOTH_SCO 369 0, // STREAM_SYSTEM_ENFORCED 370 0, // STREAM_DTMF 371 0, // STREAM_TTS 372 1, // STREAM_ACCESSIBILITY 373 0 // STREAM_ASSISTANT 374 }; 375 376 /* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings 377 * of another stream: This avoids multiplying the volume settings for hidden 378 * stream types that follow other stream behavior for volume settings 379 * NOTE: do not create loops in aliases! 380 * Some streams alias to different streams according to device category (phone or tablet) or 381 * use case (in call vs off call...). See updateStreamVolumeAlias() for more details. 382 * mStreamVolumeAlias contains STREAM_VOLUME_ALIAS_VOICE aliases for a voice capable device 383 * (phone), STREAM_VOLUME_ALIAS_TELEVISION for a television or set-top box and 384 * STREAM_VOLUME_ALIAS_DEFAULT for other devices (e.g. tablets).*/ 385 private final int[] STREAM_VOLUME_ALIAS_VOICE = new int[] { 386 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 387 AudioSystem.STREAM_RING, // STREAM_SYSTEM 388 AudioSystem.STREAM_RING, // STREAM_RING 389 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 390 AudioSystem.STREAM_ALARM, // STREAM_ALARM 391 AudioSystem.STREAM_RING, // STREAM_NOTIFICATION 392 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 393 AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED 394 AudioSystem.STREAM_RING, // STREAM_DTMF 395 AudioSystem.STREAM_MUSIC, // STREAM_TTS 396 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 397 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 398 }; 399 private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] { 400 AudioSystem.STREAM_MUSIC, // STREAM_VOICE_CALL 401 AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM 402 AudioSystem.STREAM_MUSIC, // STREAM_RING 403 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 404 AudioSystem.STREAM_MUSIC, // STREAM_ALARM 405 AudioSystem.STREAM_MUSIC, // STREAM_NOTIFICATION 406 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 407 AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM_ENFORCED 408 AudioSystem.STREAM_MUSIC, // STREAM_DTMF 409 AudioSystem.STREAM_MUSIC, // STREAM_TTS 410 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 411 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 412 }; 413 /** 414 * Using Volume groups configuration allows to control volume per attributes 415 * and group definition may differ from stream aliases. 416 * So, do not alias any stream on one another when using volume groups. 417 * TODO(b/181140246): volume group definition hosting alias definition. 418 */ 419 private final int[] STREAM_VOLUME_ALIAS_NONE = new int[] { 420 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 421 AudioSystem.STREAM_SYSTEM, // STREAM_SYSTEM 422 AudioSystem.STREAM_RING, // STREAM_RING 423 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 424 AudioSystem.STREAM_ALARM, // STREAM_ALARM 425 AudioSystem.STREAM_NOTIFICATION, // STREAM_NOTIFICATION 426 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 427 AudioSystem.STREAM_SYSTEM_ENFORCED, // STREAM_SYSTEM_ENFORCED 428 AudioSystem.STREAM_DTMF, // STREAM_DTMF 429 AudioSystem.STREAM_TTS, // STREAM_TTS 430 AudioSystem.STREAM_ACCESSIBILITY, // STREAM_ACCESSIBILITY 431 AudioSystem.STREAM_ASSISTANT // STREAM_ASSISTANT 432 }; 433 private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] { 434 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 435 AudioSystem.STREAM_RING, // STREAM_SYSTEM 436 AudioSystem.STREAM_RING, // STREAM_RING 437 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 438 AudioSystem.STREAM_ALARM, // STREAM_ALARM 439 AudioSystem.STREAM_RING, // STREAM_NOTIFICATION 440 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 441 AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED 442 AudioSystem.STREAM_RING, // STREAM_DTMF 443 AudioSystem.STREAM_MUSIC, // STREAM_TTS 444 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 445 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 446 }; 447 protected static int[] mStreamVolumeAlias; 448 private static final int UNSET_INDEX = -1; 449 450 /** 451 * Map AudioSystem.STREAM_* constants to app ops. This should be used 452 * after mapping through mStreamVolumeAlias. 453 */ 454 private static final int[] STREAM_VOLUME_OPS = new int[] { 455 AppOpsManager.OP_AUDIO_VOICE_VOLUME, // STREAM_VOICE_CALL 456 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_SYSTEM 457 AppOpsManager.OP_AUDIO_RING_VOLUME, // STREAM_RING 458 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_MUSIC 459 AppOpsManager.OP_AUDIO_ALARM_VOLUME, // STREAM_ALARM 460 AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME, // STREAM_NOTIFICATION 461 AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME, // STREAM_BLUETOOTH_SCO 462 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_SYSTEM_ENFORCED 463 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_DTMF 464 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_TTS 465 AppOpsManager.OP_AUDIO_ACCESSIBILITY_VOLUME, // STREAM_ACCESSIBILITY 466 AppOpsManager.OP_AUDIO_MEDIA_VOLUME // STREAM_ASSISTANT 467 }; 468 469 private final boolean mUseFixedVolume; 470 private final boolean mUseVolumeGroupAliases; 471 472 // If absolute volume is supported in AVRCP device 473 private volatile boolean mAvrcpAbsVolSupported = false; 474 475 /** 476 * Default stream type used for volume control in the absence of playback 477 * e.g. user on homescreen, no app playing anything, presses hardware volume buttons, this 478 * stream type is controlled. 479 */ 480 protected static final int DEFAULT_VOL_STREAM_NO_PLAYBACK = AudioSystem.STREAM_MUSIC; 481 482 private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() { 483 public void onError(int error) { 484 switch (error) { 485 case AudioSystem.AUDIO_STATUS_SERVER_DIED: 486 // check for null in case error callback is called during instance creation 487 if (mRecordMonitor != null) { 488 mRecordMonitor.onAudioServerDied(); 489 } 490 sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, 491 SENDMSG_NOOP, 0, 0, null, 0); 492 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE, 493 SENDMSG_QUEUE, 0, 0, null, 0); 494 break; 495 default: 496 break; 497 } 498 } 499 }; 500 501 /** 502 * Current ringer mode from one of {@link AudioManager#RINGER_MODE_NORMAL}, 503 * {@link AudioManager#RINGER_MODE_SILENT}, or 504 * {@link AudioManager#RINGER_MODE_VIBRATE}. 505 */ 506 @GuardedBy("mSettingsLock") 507 private int mRingerMode; // internal ringer mode, affects muting of underlying streams 508 @GuardedBy("mSettingsLock") 509 private int mRingerModeExternal = -1; // reported ringer mode to outside clients (AudioManager) 510 511 /** @see System#MODE_RINGER_STREAMS_AFFECTED */ 512 private int mRingerModeAffectedStreams = 0; 513 514 private int mZenModeAffectedStreams = 0; 515 516 // Streams currently muted by ringer mode and dnd 517 private int mRingerAndZenModeMutedStreams; 518 519 /** Streams that can be muted. Do not resolve to aliases when checking. 520 * @see System#MUTE_STREAMS_AFFECTED */ 521 private int mMuteAffectedStreams; 522 523 @NonNull 524 private SoundEffectsHelper mSfxHelper; 525 526 /** 527 * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated. 528 * mVibrateSetting is just maintained during deprecation period but vibration policy is 529 * now only controlled by mHasVibrator and mRingerMode 530 */ 531 private int mVibrateSetting; 532 533 // Is there a vibrator 534 private final boolean mHasVibrator; 535 // Used to play vibrations 536 private Vibrator mVibrator; 537 private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() 538 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) 539 .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) 540 .build(); 541 542 // Broadcast receiver for device connections intent broadcasts 543 private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver(); 544 545 private IMediaProjectionManager mProjectionService; // to validate projection token 546 547 /** Interface for UserManagerService. */ 548 private final UserManagerInternal mUserManagerInternal; 549 private final ActivityManagerInternal mActivityManagerInternal; 550 private final SensorPrivacyManagerInternal mSensorPrivacyManagerInternal; 551 552 private final UserRestrictionsListener mUserRestrictionsListener = 553 new AudioServiceUserRestrictionsListener(); 554 555 // List of binder death handlers for setMode() client processes. 556 // The last process to have called setMode() is at the top of the list. 557 // package-private so it can be accessed in AudioDeviceBroker.getSetModeDeathHandlers 558 //TODO candidate to be moved to separate class that handles synchronization 559 @GuardedBy("mDeviceBroker.mSetModeLock") 560 /*package*/ final ArrayList<SetModeDeathHandler> mSetModeDeathHandlers = 561 new ArrayList<SetModeDeathHandler>(); 562 563 // true if boot sequence has been completed 564 private boolean mSystemReady; 565 // true if Intent.ACTION_USER_SWITCHED has ever been received 566 private boolean mUserSwitchedReceived; 567 // previous volume adjustment direction received by checkForRingerModeChange() 568 private int mPrevVolDirection = AudioManager.ADJUST_SAME; 569 // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume 570 // is controlled by Vol keys. 571 private int mVolumeControlStream = -1; 572 // interpretation of whether the volume stream has been selected by the user by clicking on a 573 // volume slider to change which volume is controlled by the volume keys. Is false 574 // when mVolumeControlStream is -1. 575 private boolean mUserSelectedVolumeControlStream = false; 576 private final Object mForceControlStreamLock = new Object(); 577 // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system 578 // server process so in theory it is not necessary to monitor the client death. 579 // However it is good to be ready for future evolutions. 580 private ForceControlStreamClient mForceControlStreamClient = null; 581 // Used to play ringtones outside system_server 582 private volatile IRingtonePlayer mRingtonePlayer; 583 584 // Devices for which the volume is fixed (volume is either max or muted) 585 Set<Integer> mFixedVolumeDevices = new HashSet<>(Arrays.asList( 586 AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET, 587 AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, 588 AudioSystem.DEVICE_OUT_HDMI_ARC, 589 AudioSystem.DEVICE_OUT_HDMI_EARC, 590 AudioSystem.DEVICE_OUT_AUX_LINE)); 591 // Devices for which the volume is always max, no volume panel 592 Set<Integer> mFullVolumeDevices = new HashSet<>(); 593 // Devices for the which use the "absolute volume" concept (framework sends audio signal 594 // full scale, and volume control separately) and can be used for multiple use cases reflected 595 // by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL). 596 Set<Integer> mAbsVolumeMultiModeCaseDevices = new HashSet<>( 597 Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID)); 598 599 private final boolean mMonitorRotation; 600 601 private boolean mDockAudioMediaEnabled = true; 602 603 /** 604 * RestorableParameters is a thread-safe class used to store a 605 * first-in first-out history of parameters for replay / restoration. 606 * 607 * The idealized implementation of restoration would have a list of setting methods and 608 * values to be called for restoration. Explicitly managing such setters and 609 * values would be tedious - a simpler method is to store the values and the 610 * method implicitly by lambda capture (the values must be immutable or synchronization 611 * needs to be taken). 612 * 613 * We provide queueRestoreWithRemovalIfTrue() to allow 614 * the caller to provide a BooleanSupplier lambda, which conveniently packages 615 * the setter and its parameters needed for restoration. If during restoration, 616 * the BooleanSupplier returns true, e.g. on error, it is removed from the mMap 617 * so as not to be called on a subsequent restore. 618 * 619 * We provide a setParameters() method as an example helper method. 620 */ 621 private static class RestorableParameters { 622 /** 623 * Sets a parameter and queues for restoration if successful. 624 * 625 * @param id a string handle associated with this parameter. 626 * @param parameter the actual parameter string. 627 * @return the result of AudioSystem.setParameters 628 */ setParameters(@onNull String id, @NonNull String parameter)629 public int setParameters(@NonNull String id, @NonNull String parameter) { 630 Objects.requireNonNull(id, "id must not be null"); 631 Objects.requireNonNull(parameter, "parameter must not be null"); 632 synchronized (mMap) { 633 final int status = AudioSystem.setParameters(parameter); 634 if (status == AudioSystem.AUDIO_STATUS_OK) { // Java uses recursive mutexes. 635 queueRestoreWithRemovalIfTrue(id, () -> { // remove me if set fails. 636 return AudioSystem.setParameters(parameter) != AudioSystem.AUDIO_STATUS_OK; 637 }); 638 } 639 // Implementation detail: We do not mMap.remove(id); on failure. 640 return status; 641 } 642 } 643 644 /** 645 * Queues a restore method which is executed on restoreAll(). 646 * 647 * If the supplier null, the id is removed from the restore map. 648 * 649 * Note: When the BooleanSupplier restore method is executed 650 * during restoreAll, if it returns true, it is removed from the 651 * restore map. 652 * 653 * @param id a unique tag associated with the restore method. 654 * @param supplier is a BooleanSupplier lambda. 655 */ queueRestoreWithRemovalIfTrue( @onNull String id, @Nullable BooleanSupplier supplier)656 public void queueRestoreWithRemovalIfTrue( 657 @NonNull String id, @Nullable BooleanSupplier supplier) { 658 Objects.requireNonNull(id, "id must not be null"); 659 synchronized (mMap) { 660 if (supplier != null) { 661 mMap.put(id, supplier); 662 } else { 663 mMap.remove(id); 664 } 665 } 666 } 667 668 /** 669 * Restore all parameters 670 * 671 * During restoration after audioserver death, any BooleanSupplier that returns 672 * true, for example on parameter restoration error, will be removed from mMap 673 * so as not to be executed on a subsequent restoreAll(). 674 */ restoreAll()675 public void restoreAll() { 676 synchronized (mMap) { 677 // Note: removing from values() also removes from the backing map. 678 // TODO: Consider catching exceptions? 679 mMap.values().removeIf(v -> { 680 return v.getAsBoolean(); // this iterates the setters(). 681 }); 682 } 683 } 684 685 /** 686 * mMap is a LinkedHashMap<Key, Value> of parameters restored by restore(). 687 * The Key is a unique id tag for identification. 688 * The Value is a lambda expression which returns true if the entry is to 689 * be removed. 690 * 691 * 1) For memory limitation purposes, mMap keeps the latest MAX_ENTRIES 692 * accessed in the map. 693 * 2) Parameters are restored in order of queuing, first in first out, 694 * from earliest to latest. 695 */ 696 @GuardedBy("mMap") 697 private Map</* @NonNull */ String, /* @NonNull */ BooleanSupplier> mMap = 698 new LinkedHashMap<>() { 699 // TODO: do we need this memory limitation? 700 private static final int MAX_ENTRIES = 1000; // limit our memory for now. 701 @Override 702 protected boolean removeEldestEntry(Map.Entry eldest) { 703 if (size() <= MAX_ENTRIES) return false; 704 Log.w(TAG, "Parameter map exceeds " 705 + MAX_ENTRIES + " removing " + eldest.getKey()); // don't silently remove. 706 return true; 707 } 708 }; 709 } 710 711 // We currently have one instance for mRestorableParameters used for 712 // setAdditionalOutputDeviceDelay(). Other methods requiring restoration could share this 713 // or use their own instance. 714 private RestorableParameters mRestorableParameters = new RestorableParameters(); 715 716 private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; 717 718 // Used when safe volume warning message display is requested by setStreamVolume(). In this 719 // case, the new requested volume, stream type and device are stored in mPendingVolumeCommand 720 // and used later when/if disableSafeMediaVolume() is called. 721 private StreamVolumeCommand mPendingVolumeCommand; 722 723 private PowerManager.WakeLock mAudioEventWakeLock; 724 725 private final MediaFocusControl mMediaFocusControl; 726 727 // Pre-scale for Bluetooth Absolute Volume 728 private float[] mPrescaleAbsoluteVolume = new float[] { 729 0.6f, // Pre-scale for index 1 730 0.8f, // Pre-scale for index 2 731 0.9f, // Pre-scale for index 3 732 }; 733 734 private NotificationManager mNm; 735 private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate; 736 private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT; 737 private long mLoweredFromNormalToVibrateTime; 738 739 // Uid of the active hotword detection service to check if caller is the one or not. 740 @GuardedBy("mHotwordDetectionServiceUidLock") 741 private int mHotwordDetectionServiceUid = android.os.Process.INVALID_UID; 742 private final Object mHotwordDetectionServiceUidLock = new Object(); 743 744 // Array of Uids of valid accessibility services to check if caller is one of them 745 private final Object mAccessibilityServiceUidsLock = new Object(); 746 @GuardedBy("mAccessibilityServiceUidsLock") 747 private int[] mAccessibilityServiceUids; 748 749 // Uid of the active input method service to check if caller is the one or not. 750 private int mInputMethodServiceUid = android.os.Process.INVALID_UID; 751 private final Object mInputMethodServiceUidLock = new Object(); 752 753 private int mEncodedSurroundMode; 754 private String mEnabledSurroundFormats; 755 private boolean mSurroundModeChanged; 756 757 private boolean mSupportsMicPrivacyToggle; 758 759 private boolean mMicMuteFromSwitch; 760 private boolean mMicMuteFromApi; 761 private boolean mMicMuteFromRestrictions; 762 private boolean mMicMuteFromPrivacyToggle; 763 // caches the value returned by AudioSystem.isMicrophoneMuted() 764 private boolean mMicMuteFromSystemCached; 765 766 private boolean mNavigationRepeatSoundEffectsEnabled; 767 private boolean mHomeSoundEffectEnabled; 768 769 @GuardedBy("mSettingsLock") 770 private int mAssistantUid; 771 772 @GuardedBy("mSettingsLock") 773 private int mCurrentImeUid; 774 775 private final Object mSupportedSystemUsagesLock = new Object(); 776 @GuardedBy("mSupportedSystemUsagesLock") 777 private @AttributeSystemUsage int[] mSupportedSystemUsages = 778 new int[]{AudioAttributes.USAGE_CALL_ASSISTANT}; 779 780 // Defines the format for the connection "address" for ALSA devices makeAlsaAddressString(int card, int device)781 public static String makeAlsaAddressString(int card, int device) { 782 return "card=" + card + ";device=" + device + ";"; 783 } 784 785 public static final class Lifecycle extends SystemService { 786 private AudioService mService; 787 Lifecycle(Context context)788 public Lifecycle(Context context) { 789 super(context); 790 mService = new AudioService(context); 791 } 792 793 @Override onStart()794 public void onStart() { 795 publishBinderService(Context.AUDIO_SERVICE, mService); 796 } 797 798 @Override onBootPhase(int phase)799 public void onBootPhase(int phase) { 800 if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { 801 mService.systemReady(); 802 } 803 } 804 } 805 806 final private IUidObserver mUidObserver = new IUidObserver.Stub() { 807 @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, 808 int capability) { 809 } 810 811 @Override public void onUidGone(int uid, boolean disabled) { 812 // Once the uid is no longer running, no need to keep trying to disable its audio. 813 disableAudioForUid(false, uid); 814 } 815 816 @Override public void onUidActive(int uid) throws RemoteException { 817 } 818 819 @Override public void onUidIdle(int uid, boolean disabled) { 820 } 821 822 @Override public void onUidCachedChanged(int uid, boolean cached) { 823 disableAudioForUid(cached, uid); 824 } 825 826 private void disableAudioForUid(boolean disable, int uid) { 827 queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID, 828 disable ? 1 : 0 /* arg1 */, uid /* arg2 */, 829 null /* obj */, 0 /* delay */); 830 } 831 }; 832 833 @GuardedBy("mSettingsLock") 834 private boolean mRttEnabled = false; 835 836 /////////////////////////////////////////////////////////////////////////// 837 // Construction 838 /////////////////////////////////////////////////////////////////////////// 839 840 /** @hide */ AudioService(Context context)841 public AudioService(Context context) { 842 this(context, AudioSystemAdapter.getDefaultAdapter(), 843 SystemServerAdapter.getDefaultAdapter(context)); 844 } 845 AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer)846 public AudioService(Context context, AudioSystemAdapter audioSystem, 847 SystemServerAdapter systemServer) { 848 sLifecycleLogger.log(new AudioEventLogger.StringEvent("AudioService()")); 849 mContext = context; 850 mContentResolver = context.getContentResolver(); 851 mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); 852 853 mAudioSystem = audioSystem; 854 mSystemServer = systemServer; 855 856 mPlatformType = AudioSystem.getPlatformType(context); 857 858 mIsSingleVolume = AudioSystem.isSingleVolume(context); 859 860 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 861 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); 862 mSensorPrivacyManagerInternal = 863 LocalServices.getService(SensorPrivacyManagerInternal.class); 864 865 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 866 mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent"); 867 868 mSfxHelper = new SoundEffectsHelper(mContext); 869 870 mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); 871 mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator(); 872 873 mSupportsMicPrivacyToggle = context.getSystemService(SensorPrivacyManager.class) 874 .supportsSensorToggle(SensorPrivacyManager.Sensors.MICROPHONE); 875 876 mUseVolumeGroupAliases = mContext.getResources().getBoolean( 877 com.android.internal.R.bool.config_handleVolumeAliasesUsingVolumeGroups); 878 879 // Initialize volume 880 // Priority 1 - Android Property 881 // Priority 2 - Audio Policy Service 882 // Priority 3 - Default Value 883 if (AudioProductStrategy.getAudioProductStrategies().size() > 0) { 884 int numStreamTypes = AudioSystem.getNumStreamTypes(); 885 886 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 887 AudioAttributes attr = 888 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType( 889 streamType); 890 int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr); 891 if (maxVolume != -1) { 892 MAX_STREAM_VOLUME[streamType] = maxVolume; 893 } 894 int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr); 895 if (minVolume != -1) { 896 MIN_STREAM_VOLUME[streamType] = minVolume; 897 } 898 } 899 if (mUseVolumeGroupAliases) { 900 // Set all default to uninitialized. 901 for (int stream = 0; stream < AudioSystem.DEFAULT_STREAM_VOLUME.length; stream++) { 902 AudioSystem.DEFAULT_STREAM_VOLUME[stream] = UNSET_INDEX; 903 } 904 } 905 } 906 907 int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1); 908 if (maxCallVolume != -1) { 909 MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume; 910 } 911 912 int defaultCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_default", -1); 913 if (defaultCallVolume != -1 && 914 defaultCallVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] && 915 defaultCallVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) { 916 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume; 917 } else { 918 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = 919 (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4; 920 } 921 922 int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1); 923 if (maxMusicVolume != -1) { 924 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume; 925 } 926 927 int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1); 928 if (defaultMusicVolume != -1 && 929 defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] && 930 defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) { 931 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume; 932 } else { 933 if (isPlatformTelevision()) { 934 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = 935 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4; 936 } else { 937 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = 938 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3; 939 } 940 } 941 942 int maxAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_steps", -1); 943 if (maxAlarmVolume != -1) { 944 MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = maxAlarmVolume; 945 } 946 947 int defaultAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_default", -1); 948 if (defaultAlarmVolume != -1 && 949 defaultAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) { 950 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = defaultAlarmVolume; 951 } else { 952 // Default is 6 out of 7 (default maximum), so scale accordingly. 953 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = 954 6 * MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] / 7; 955 } 956 957 int maxSystemVolume = SystemProperties.getInt("ro.config.system_vol_steps", -1); 958 if (maxSystemVolume != -1) { 959 MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = maxSystemVolume; 960 } 961 962 int defaultSystemVolume = SystemProperties.getInt("ro.config.system_vol_default", -1); 963 if (defaultSystemVolume != -1 && 964 defaultSystemVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]) { 965 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = defaultSystemVolume; 966 } else { 967 // Default is to use maximum. 968 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = 969 MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]; 970 } 971 972 createAudioSystemThread(); 973 974 AudioSystem.setErrorCallback(mAudioSystemCallback); 975 976 updateAudioHalPids(); 977 978 boolean cameraSoundForced = readCameraSoundForced(); 979 mCameraSoundForced = new Boolean(cameraSoundForced); 980 sendMsg(mAudioHandler, 981 MSG_SET_FORCE_USE, 982 SENDMSG_QUEUE, 983 AudioSystem.FOR_SYSTEM, 984 cameraSoundForced ? 985 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE, 986 new String("AudioService ctor"), 987 0); 988 989 mSafeMediaVolumeState = Settings.Global.getInt(mContentResolver, 990 Settings.Global.AUDIO_SAFE_VOLUME_STATE, 991 SAFE_MEDIA_VOLUME_NOT_CONFIGURED); 992 // The default safe volume index read here will be replaced by the actual value when 993 // the mcc is read by onConfigureSafeVolume() 994 mSafeMediaVolumeIndex = mContext.getResources().getInteger( 995 com.android.internal.R.integer.config_safe_media_volume_index) * 10; 996 997 mUseFixedVolume = mContext.getResources().getBoolean( 998 com.android.internal.R.bool.config_useFixedVolume); 999 1000 mDeviceBroker = new AudioDeviceBroker(mContext, this); 1001 1002 mRecordMonitor = new RecordingActivityMonitor(mContext); 1003 mRecordMonitor.registerRecordingCallback(mVoiceRecordingActivityMonitor, true); 1004 1005 // must be called before readPersistedSettings() which needs a valid mStreamVolumeAlias[] 1006 // array initialized by updateStreamVolumeAlias() 1007 updateStreamVolumeAlias(false /*updateVolumes*/, TAG); 1008 readPersistedSettings(); 1009 readUserRestrictions(); 1010 1011 mPlaybackMonitor = 1012 new PlaybackActivityMonitor(context, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]); 1013 mPlaybackMonitor.registerPlaybackCallback(mVoicePlaybackActivityMonitor, true); 1014 1015 mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor); 1016 1017 readAndSetLowRamDevice(); 1018 1019 mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported(); 1020 1021 if (mSystemServer.isPrivileged()) { 1022 LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal()); 1023 1024 mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener); 1025 1026 mRecordMonitor.initMonitor(); 1027 } 1028 1029 mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false); 1030 1031 // done with service initialization, continue additional work in our Handler thread 1032 queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES, 1033 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */); 1034 } 1035 1036 /** 1037 * Called by handling of MSG_INIT_STREAMS_VOLUMES 1038 */ onInitStreamsAndVolumes()1039 private void onInitStreamsAndVolumes() { 1040 createStreamStates(); 1041 1042 // must be called after createStreamStates() as it uses MUSIC volume as default if no 1043 // persistent data 1044 initVolumeGroupStates(); 1045 1046 // mSafeUsbMediaVolumeIndex must be initialized after createStreamStates() because it 1047 // relies on audio policy having correct ranges for volume indexes. 1048 mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex(); 1049 1050 // Call setRingerModeInt() to apply correct mute 1051 // state on streams affected by ringer mode. 1052 mRingerAndZenModeMutedStreams = 0; 1053 setRingerModeInt(getRingerModeInternal(), false); 1054 1055 final float[] preScale = new float[3]; 1056 preScale[0] = mContext.getResources().getFraction( 1057 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1, 1058 1, 1); 1059 preScale[1] = mContext.getResources().getFraction( 1060 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index2, 1061 1, 1); 1062 preScale[2] = mContext.getResources().getFraction( 1063 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index3, 1064 1, 1); 1065 for (int i = 0; i < preScale.length; i++) { 1066 if (0.0f <= preScale[i] && preScale[i] <= 1.0f) { 1067 mPrescaleAbsoluteVolume[i] = preScale[i]; 1068 } 1069 } 1070 1071 initExternalEventReceivers(); 1072 1073 // check on volume initialization 1074 checkVolumeRangeInitialization("AudioService()"); 1075 } 1076 1077 /** 1078 * Initialize intent receives and settings observers for this service. 1079 * Must be called after createStreamStates() as the handling of some events 1080 * may affect or need volumes, e.g. BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED 1081 * (for intent receiver), or Settings.Global.ZEN_MODE (for settings observer) 1082 */ initExternalEventReceivers()1083 private void initExternalEventReceivers() { 1084 mSettingsObserver = new SettingsObserver(); 1085 1086 // Register for device connection intent broadcasts. 1087 IntentFilter intentFilter = 1088 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); 1089 intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED); 1090 intentFilter.addAction(Intent.ACTION_DOCK_EVENT); 1091 intentFilter.addAction(Intent.ACTION_SCREEN_ON); 1092 intentFilter.addAction(Intent.ACTION_SCREEN_OFF); 1093 intentFilter.addAction(Intent.ACTION_USER_SWITCHED); 1094 intentFilter.addAction(Intent.ACTION_USER_BACKGROUND); 1095 intentFilter.addAction(Intent.ACTION_USER_FOREGROUND); 1096 intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); 1097 intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); 1098 intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED); 1099 1100 intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); 1101 if (mMonitorRotation) { 1102 RotationHelper.init(mContext, mAudioHandler); 1103 } 1104 1105 intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION); 1106 intentFilter.addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION); 1107 1108 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null); 1109 1110 } 1111 systemReady()1112 public void systemReady() { 1113 sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE, 1114 0, 0, null, 0); 1115 if (false) { 1116 // This is turned off for now, because it is racy and thus causes apps to break. 1117 // Currently banning a uid means that if an app tries to start playing an audio 1118 // stream, that will be preventing, and unbanning it will not allow that stream 1119 // to resume. However these changes in uid state are racy with what the app is doing, 1120 // so that after taking a process out of the cached state we can't guarantee that 1121 // we will unban the uid before the app actually tries to start playing audio. 1122 // (To do that, the activity manager would need to wait until it knows for sure 1123 // that the ban has been removed, before telling the app to do whatever it is 1124 // supposed to do that caused it to go out of the cached state.) 1125 try { 1126 ActivityManager.getService().registerUidObserver(mUidObserver, 1127 ActivityManager.UID_OBSERVER_CACHED | ActivityManager.UID_OBSERVER_GONE, 1128 ActivityManager.PROCESS_STATE_UNKNOWN, null); 1129 } catch (RemoteException e) { 1130 // ignored; both services live in system_server 1131 } 1132 } 1133 } 1134 updateVibratorInfos()1135 private void updateVibratorInfos() { 1136 VibratorManager vibratorManager = mContext.getSystemService(VibratorManager.class); 1137 if (vibratorManager == null) { 1138 Slog.e(TAG, "Vibrator manager is not found"); 1139 return; 1140 } 1141 int[] vibratorIds = vibratorManager.getVibratorIds(); 1142 if (vibratorIds.length == 0) { 1143 Slog.d(TAG, "No vibrator found"); 1144 return; 1145 } 1146 List<Vibrator> vibrators = new ArrayList<>(vibratorIds.length); 1147 for (int id : vibratorIds) { 1148 Vibrator vibrator = vibratorManager.getVibrator(id); 1149 if (vibrator != null) { 1150 vibrators.add(vibrator); 1151 } else { 1152 Slog.w(TAG, "Vibrator(" + id + ") is not found"); 1153 } 1154 } 1155 if (vibrators.isEmpty()) { 1156 Slog.w(TAG, "Cannot find any available vibrator"); 1157 return; 1158 } 1159 AudioSystem.setVibratorInfos(vibrators); 1160 } 1161 onSystemReady()1162 public void onSystemReady() { 1163 mSystemReady = true; 1164 scheduleLoadSoundEffects(); 1165 1166 mDeviceBroker.onSystemReady(); 1167 1168 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) { 1169 synchronized (mHdmiClientLock) { 1170 mHdmiManager = mContext.getSystemService(HdmiControlManager.class); 1171 if (mHdmiManager != null) { 1172 mHdmiManager.addHdmiControlStatusChangeListener( 1173 mHdmiControlStatusChangeListenerCallback); 1174 mHdmiManager.addHdmiCecVolumeControlFeatureListener(mContext.getMainExecutor(), 1175 mMyHdmiCecVolumeControlFeatureListener); 1176 } 1177 mHdmiTvClient = mHdmiManager.getTvClient(); 1178 if (mHdmiTvClient != null) { 1179 mFixedVolumeDevices.removeAll( 1180 AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET); 1181 } 1182 mHdmiPlaybackClient = mHdmiManager.getPlaybackClient(); 1183 mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient(); 1184 } 1185 } 1186 1187 if (mSupportsMicPrivacyToggle) { 1188 mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers( 1189 SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> { 1190 if (userId == getCurrentUserId()) { 1191 mMicMuteFromPrivacyToggle = enabled; 1192 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); 1193 } 1194 }); 1195 } 1196 1197 mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 1198 1199 sendMsg(mAudioHandler, 1200 MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED, 1201 SENDMSG_REPLACE, 1202 0, 1203 0, 1204 TAG, 1205 SystemProperties.getBoolean("audio.safemedia.bypass", false) ? 1206 0 : SAFE_VOLUME_CONFIGURE_TIMEOUT_MS); 1207 1208 initA11yMonitoring(); 1209 1210 mRoleObserver = new RoleObserver(); 1211 mRoleObserver.register(); 1212 1213 onIndicateSystemReady(); 1214 1215 mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted(); 1216 setMicMuteFromSwitchInput(); 1217 1218 initMinStreamVolumeWithoutModifyAudioSettings(); 1219 1220 updateVibratorInfos(); 1221 } 1222 1223 RoleObserver mRoleObserver; 1224 1225 class RoleObserver implements OnRoleHoldersChangedListener { 1226 private RoleManager mRm; 1227 private final Executor mExecutor; 1228 RoleObserver()1229 RoleObserver() { 1230 mExecutor = mContext.getMainExecutor(); 1231 } 1232 register()1233 public void register() { 1234 mRm = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE); 1235 if (mRm != null) { 1236 mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL); 1237 updateAssistantUId(true); 1238 } 1239 } 1240 1241 @Override onRoleHoldersChanged(@onNull String roleName, @NonNull UserHandle user)1242 public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) { 1243 if (RoleManager.ROLE_ASSISTANT.equals(roleName)) { 1244 updateAssistantUId(false); 1245 } 1246 } 1247 getAssistantRoleHolder()1248 public String getAssistantRoleHolder() { 1249 String assitantPackage = ""; 1250 if (mRm != null) { 1251 List<String> assistants = mRm.getRoleHolders(RoleManager.ROLE_ASSISTANT); 1252 assitantPackage = assistants.size() == 0 ? "" : assistants.get(0); 1253 } 1254 return assitantPackage; 1255 } 1256 } 1257 onIndicateSystemReady()1258 void onIndicateSystemReady() { 1259 if (AudioSystem.systemReady() == AudioSystem.SUCCESS) { 1260 return; 1261 } 1262 sendMsg(mAudioHandler, 1263 MSG_INDICATE_SYSTEM_READY, 1264 SENDMSG_REPLACE, 1265 0, 1266 0, 1267 null, 1268 INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 1269 } 1270 onAudioServerDied()1271 public void onAudioServerDied() { 1272 if (!mSystemReady || 1273 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) { 1274 Log.e(TAG, "Audioserver died."); 1275 sLifecycleLogger.log(new AudioEventLogger.StringEvent( 1276 "onAudioServerDied() audioserver died")); 1277 sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0, 1278 null, 500); 1279 return; 1280 } 1281 Log.i(TAG, "Audioserver started."); 1282 sLifecycleLogger.log(new AudioEventLogger.StringEvent( 1283 "onAudioServerDied() audioserver started")); 1284 1285 updateAudioHalPids(); 1286 1287 // indicate to audio HAL that we start the reconfiguration phase after a media 1288 // server crash 1289 // Note that we only execute this when the media server 1290 // process restarts after a crash, not the first time it is started. 1291 AudioSystem.setParameters("restarting=true"); 1292 1293 readAndSetLowRamDevice(); 1294 1295 mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported(); 1296 1297 // Restore device connection states, BT state 1298 mDeviceBroker.onAudioServerDied(); 1299 1300 // Restore call state 1301 synchronized (mDeviceBroker.mSetModeLock) { 1302 onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(), 1303 mContext.getPackageName(), true /*force*/); 1304 } 1305 final int forSys; 1306 synchronized (mSettingsLock) { 1307 forSys = mCameraSoundForced ? 1308 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE; 1309 } 1310 1311 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, forSys, "onAudioServerDied"); 1312 1313 // Restore stream volumes 1314 onReinitVolumes("after audioserver restart"); 1315 1316 // Restore audio volume groups 1317 restoreVolumeGroups(); 1318 1319 // Restore mono mode 1320 updateMasterMono(mContentResolver); 1321 1322 // Restore audio balance 1323 updateMasterBalance(mContentResolver); 1324 1325 // Restore ringer mode 1326 setRingerModeInt(getRingerModeInternal(), false); 1327 1328 // Reset device rotation (if monitored for this device) 1329 if (mMonitorRotation) { 1330 RotationHelper.updateOrientation(); 1331 } 1332 1333 // Restore setParameters and other queued setters. 1334 mRestorableParameters.restoreAll(); 1335 1336 synchronized (mSettingsLock) { 1337 final int forDock = mDockAudioMediaEnabled ? 1338 AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE; 1339 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, forDock, "onAudioServerDied"); 1340 sendEncodedSurroundMode(mContentResolver, "onAudioServerDied"); 1341 sendEnabledSurroundFormats(mContentResolver, true); 1342 updateAssistantUId(true); 1343 AudioSystem.setRttEnabled(mRttEnabled); 1344 } 1345 synchronized (mHotwordDetectionServiceUidLock) { 1346 AudioSystem.setHotwordDetectionServiceUid(mHotwordDetectionServiceUid); 1347 } 1348 synchronized (mAccessibilityServiceUidsLock) { 1349 AudioSystem.setA11yServicesUids(mAccessibilityServiceUids); 1350 } 1351 synchronized (mInputMethodServiceUidLock) { 1352 mAudioSystem.setCurrentImeUid(mInputMethodServiceUid); 1353 } 1354 synchronized (mHdmiClientLock) { 1355 if (mHdmiManager != null && mHdmiTvClient != null) { 1356 setHdmiSystemAudioSupported(mHdmiSystemAudioSupported); 1357 } 1358 } 1359 1360 synchronized (mSupportedSystemUsagesLock) { 1361 AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages); 1362 } 1363 1364 synchronized (mAudioPolicies) { 1365 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 1366 final int status = policy.connectMixes(); 1367 if (status != AudioSystem.SUCCESS) { 1368 // note that PERMISSION_DENIED may also indicate trouble getting to APService 1369 Log.e(TAG, "onAudioServerDied: error " 1370 + AudioSystem.audioSystemErrorToString(status) 1371 + " when connecting mixes for policy " + policy.toLogFriendlyString()); 1372 policy.release(); 1373 } else { 1374 final int deviceAffinitiesStatus = policy.setupDeviceAffinities(); 1375 if (deviceAffinitiesStatus != AudioSystem.SUCCESS) { 1376 Log.e(TAG, "onAudioServerDied: error " 1377 + AudioSystem.audioSystemErrorToString(deviceAffinitiesStatus) 1378 + " when connecting device affinities for policy " 1379 + policy.toLogFriendlyString()); 1380 policy.release(); 1381 } 1382 } 1383 } 1384 } 1385 1386 // Restore capture policies 1387 synchronized (mPlaybackMonitor) { 1388 HashMap<Integer, Integer> allowedCapturePolicies = 1389 mPlaybackMonitor.getAllAllowedCapturePolicies(); 1390 for (HashMap.Entry<Integer, Integer> entry : allowedCapturePolicies.entrySet()) { 1391 int result = mAudioSystem.setAllowedCapturePolicy( 1392 entry.getKey(), 1393 AudioAttributes.capturePolicyToFlags(entry.getValue(), 0x0)); 1394 if (result != AudioSystem.AUDIO_STATUS_OK) { 1395 Log.e(TAG, "Failed to restore capture policy, uid: " 1396 + entry.getKey() + ", capture policy: " + entry.getValue() 1397 + ", result: " + result); 1398 // When restoring capture policy failed, set the capture policy as 1399 // ALLOW_CAPTURE_BY_ALL, which will result in removing the cached 1400 // capture policy in PlaybackActivityMonitor. 1401 mPlaybackMonitor.setAllowedCapturePolicy( 1402 entry.getKey(), AudioAttributes.ALLOW_CAPTURE_BY_ALL); 1403 } 1404 } 1405 } 1406 1407 onIndicateSystemReady(); 1408 // indicate the end of reconfiguration phase to audio HAL 1409 AudioSystem.setParameters("restarting=false"); 1410 1411 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE, 1412 SENDMSG_QUEUE, 1, 0, null, 0); 1413 1414 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); // will also update the mic mute cache 1415 setMicMuteFromSwitchInput(); 1416 1417 // Restore vibrator info 1418 updateVibratorInfos(); 1419 } 1420 onReinitVolumes(@onNull String caller)1421 private void onReinitVolumes(@NonNull String caller) { 1422 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 1423 // keep track of any error during stream volume initialization 1424 int status = AudioSystem.AUDIO_STATUS_OK; 1425 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 1426 VolumeStreamState streamState = mStreamStates[streamType]; 1427 final int res = AudioSystem.initStreamVolume( 1428 streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10); 1429 if (res != AudioSystem.AUDIO_STATUS_OK) { 1430 status = res; 1431 Log.e(TAG, "Failed to initStreamVolume (" + res + ") for stream " + streamType); 1432 // stream volume initialization failed, no need to try the others, it will be 1433 // attempted again when MSG_REINIT_VOLUMES is handled 1434 break; 1435 } 1436 streamState.applyAllVolumes(); 1437 } 1438 1439 // did it work? check based on status 1440 if (status != AudioSystem.AUDIO_STATUS_OK) { 1441 sLifecycleLogger.log(new AudioEventLogger.StringEvent( 1442 caller + ": initStreamVolume failed with " + status + " will retry") 1443 .printLog(ALOGE, TAG)); 1444 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 1445 caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 1446 return; 1447 } 1448 1449 // did it work? check based on min/max values of some basic streams 1450 if (!checkVolumeRangeInitialization(caller)) { 1451 return; 1452 } 1453 1454 // success 1455 sLifecycleLogger.log(new AudioEventLogger.StringEvent( 1456 caller + ": initStreamVolume succeeded").printLog(ALOGI, TAG)); 1457 } 1458 1459 /** 1460 * Check volume ranges were properly initialized 1461 * @return true if volume ranges were successfully initialized 1462 */ checkVolumeRangeInitialization(String caller)1463 private boolean checkVolumeRangeInitialization(String caller) { 1464 boolean success = true; 1465 final int[] basicStreams = { AudioSystem.STREAM_ALARM, AudioSystem.STREAM_RING, 1466 AudioSystem.STREAM_MUSIC, AudioSystem.STREAM_VOICE_CALL, 1467 AudioSystem.STREAM_ACCESSIBILITY }; 1468 for (int streamType : basicStreams) { 1469 final AudioAttributes aa = new AudioAttributes.Builder() 1470 .setInternalLegacyStreamType(streamType).build(); 1471 if (AudioSystem.getMaxVolumeIndexForAttributes(aa) < 0 1472 || AudioSystem.getMinVolumeIndexForAttributes(aa) < 0) { 1473 success = false; 1474 break; 1475 } 1476 } 1477 if (!success) { 1478 sLifecycleLogger.log(new AudioEventLogger.StringEvent( 1479 caller + ": initStreamVolume succeeded but invalid mix/max levels, will retry") 1480 .printLog(ALOGW, TAG)); 1481 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 1482 caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 1483 } 1484 return success; 1485 } 1486 onDispatchAudioServerStateChange(boolean state)1487 private void onDispatchAudioServerStateChange(boolean state) { 1488 synchronized (mAudioServerStateListeners) { 1489 for (AsdProxy asdp : mAudioServerStateListeners.values()) { 1490 try { 1491 asdp.callback().dispatchAudioServerStateChange(state); 1492 } catch (RemoteException e) { 1493 Log.w(TAG, "Could not call dispatchAudioServerStateChange()", e); 1494 } 1495 } 1496 } 1497 } 1498 createAudioSystemThread()1499 private void createAudioSystemThread() { 1500 mAudioSystemThread = new AudioSystemThread(); 1501 mAudioSystemThread.start(); 1502 waitForAudioHandlerCreation(); 1503 } 1504 1505 /** Waits for the volume handler to be created by the other thread. */ waitForAudioHandlerCreation()1506 private void waitForAudioHandlerCreation() { 1507 synchronized(this) { 1508 while (mAudioHandler == null) { 1509 try { 1510 // Wait for mAudioHandler to be set by the other thread 1511 wait(); 1512 } catch (InterruptedException e) { 1513 Log.e(TAG, "Interrupted while waiting on volume handler."); 1514 } 1515 } 1516 } 1517 } 1518 1519 /** 1520 * @see AudioManager#setSupportedSystemUsages(int[]) 1521 */ setSupportedSystemUsages(@onNull @ttributeSystemUsage int[] systemUsages)1522 public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) { 1523 enforceModifyAudioRoutingPermission(); 1524 verifySystemUsages(systemUsages); 1525 1526 synchronized (mSupportedSystemUsagesLock) { 1527 AudioSystem.setSupportedSystemUsages(systemUsages); 1528 mSupportedSystemUsages = systemUsages; 1529 } 1530 } 1531 1532 /** 1533 * @see AudioManager#getSupportedSystemUsages() 1534 */ getSupportedSystemUsages()1535 public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() { 1536 enforceModifyAudioRoutingPermission(); 1537 synchronized (mSupportedSystemUsagesLock) { 1538 return Arrays.copyOf(mSupportedSystemUsages, mSupportedSystemUsages.length); 1539 } 1540 } 1541 verifySystemUsages(@onNull int[] systemUsages)1542 private void verifySystemUsages(@NonNull int[] systemUsages) { 1543 for (int i = 0; i < systemUsages.length; i++) { 1544 if (!AudioAttributes.isSystemUsage(systemUsages[i])) { 1545 throw new IllegalArgumentException("Non-system usage provided: " + systemUsages[i]); 1546 } 1547 } 1548 } 1549 1550 /** 1551 * @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the 1552 * platform configuration file. 1553 */ 1554 @NonNull getAudioProductStrategies()1555 public List<AudioProductStrategy> getAudioProductStrategies() { 1556 // verify permissions 1557 enforceModifyAudioRoutingPermission(); 1558 return AudioProductStrategy.getAudioProductStrategies(); 1559 } 1560 1561 /** 1562 * @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the 1563 * platform configuration file. 1564 */ 1565 @NonNull getAudioVolumeGroups()1566 public List<AudioVolumeGroup> getAudioVolumeGroups() { 1567 // verify permissions 1568 enforceModifyAudioRoutingPermission(); 1569 return AudioVolumeGroup.getAudioVolumeGroups(); 1570 } 1571 checkAllAliasStreamVolumes()1572 private void checkAllAliasStreamVolumes() { 1573 synchronized (mSettingsLock) { 1574 synchronized (VolumeStreamState.class) { 1575 int numStreamTypes = AudioSystem.getNumStreamTypes(); 1576 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 1577 mStreamStates[streamType] 1578 .setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]], TAG); 1579 // apply stream volume 1580 if (!mStreamStates[streamType].mIsMuted) { 1581 mStreamStates[streamType].applyAllVolumes(); 1582 } 1583 } 1584 } 1585 } 1586 } 1587 1588 1589 /** 1590 * Called from AudioDeviceBroker when DEVICE_OUT_HDMI is connected or disconnected. 1591 */ postCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)1592 /*package*/ void postCheckVolumeCecOnHdmiConnection( 1593 @AudioService.ConnectionState int state, String caller) { 1594 sendMsg(mAudioHandler, MSG_HDMI_VOLUME_CHECK, SENDMSG_REPLACE, 1595 state /*arg1*/, 0 /*arg2 ignored*/, caller /*obj*/, 0 /*delay*/); 1596 } 1597 onCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)1598 private void onCheckVolumeCecOnHdmiConnection( 1599 @AudioService.ConnectionState int state, String caller) { 1600 if (state == AudioService.CONNECTION_STATE_CONNECTED) { 1601 // DEVICE_OUT_HDMI is now connected 1602 if (mSafeMediaVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)) { 1603 sendMsg(mAudioHandler, 1604 MSG_CHECK_MUSIC_ACTIVE, 1605 SENDMSG_REPLACE, 1606 0, 1607 0, 1608 caller, 1609 MUSIC_ACTIVE_POLL_PERIOD_MS); 1610 } 1611 1612 if (isPlatformTelevision()) { 1613 synchronized (mHdmiClientLock) { 1614 if (mHdmiManager != null && mHdmiPlaybackClient != null) { 1615 updateHdmiCecSinkLocked( 1616 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)); 1617 } 1618 } 1619 } 1620 sendEnabledSurroundFormats(mContentResolver, true); 1621 } else { 1622 // DEVICE_OUT_HDMI disconnected 1623 if (isPlatformTelevision()) { 1624 synchronized (mHdmiClientLock) { 1625 if (mHdmiManager != null) { 1626 updateHdmiCecSinkLocked( 1627 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)); 1628 } 1629 } 1630 } 1631 } 1632 } 1633 1634 /** 1635 * Asynchronously update volume states for the given device. 1636 * 1637 * @param device a single audio device, ensure that this is not a devices bitmask 1638 * @param caller caller of this method 1639 */ postUpdateVolumeStatesForAudioDevice(int device, String caller)1640 private void postUpdateVolumeStatesForAudioDevice(int device, String caller) { 1641 sendMsg(mAudioHandler, 1642 MSG_UPDATE_VOLUME_STATES_FOR_DEVICE, 1643 SENDMSG_QUEUE, device /*arg1*/, 0 /*arg2*/, caller /*obj*/, 1644 0 /*delay*/); 1645 } 1646 1647 /** 1648 * Update volume states for the given device. 1649 * 1650 * This will initialize the volume index if no volume index is available. 1651 * If the device is the currently routed device, fixed/full volume policies will be applied. 1652 * 1653 * @param device a single audio device, ensure that this is not a devices bitmask 1654 * @param caller caller of this method 1655 */ onUpdateVolumeStatesForAudioDevice(int device, String caller)1656 private void onUpdateVolumeStatesForAudioDevice(int device, String caller) { 1657 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 1658 synchronized (mSettingsLock) { 1659 synchronized (VolumeStreamState.class) { 1660 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 1661 updateVolumeStates(device, streamType, caller); 1662 } 1663 } 1664 } 1665 } 1666 1667 /** 1668 * Update volume states for the given device and given stream. 1669 * 1670 * This will initialize the volume index if no volume index is available. 1671 * If the device is the currently routed device, fixed/full volume policies will be applied. 1672 * 1673 * @param device a single audio device, ensure that this is not a devices bitmask 1674 * @param streamType streamType to be updated 1675 * @param caller caller of this method 1676 */ updateVolumeStates(int device, int streamType, String caller)1677 private void updateVolumeStates(int device, int streamType, String caller) { 1678 if (!mStreamStates[streamType].hasIndexForDevice(device)) { 1679 // set the default value, if device is affected by a full/fix/abs volume rule, it 1680 // will taken into account in checkFixedVolumeDevices() 1681 mStreamStates[streamType].setIndex( 1682 mStreamStates[mStreamVolumeAlias[streamType]] 1683 .getIndex(AudioSystem.DEVICE_OUT_DEFAULT), 1684 device, caller, true /*hasModifyAudioSettings*/); 1685 } 1686 1687 // Check if device to be updated is routed for the given audio stream 1688 List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributesInt( 1689 new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build()); 1690 for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) { 1691 if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType( 1692 device)) { 1693 mStreamStates[streamType].checkFixedVolumeDevices(); 1694 1695 // Unmute streams if required and device is full volume 1696 if (isStreamMute(streamType) && mFullVolumeDevices.contains(device)) { 1697 mStreamStates[streamType].mute(false); 1698 } 1699 } 1700 } 1701 } 1702 checkAllFixedVolumeDevices()1703 private void checkAllFixedVolumeDevices() 1704 { 1705 int numStreamTypes = AudioSystem.getNumStreamTypes(); 1706 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 1707 mStreamStates[streamType].checkFixedVolumeDevices(); 1708 } 1709 } 1710 checkAllFixedVolumeDevices(int streamType)1711 private void checkAllFixedVolumeDevices(int streamType) { 1712 mStreamStates[streamType].checkFixedVolumeDevices(); 1713 } 1714 checkMuteAffectedStreams()1715 private void checkMuteAffectedStreams() { 1716 // any stream with a min level > 0 is not muteable by definition 1717 // STREAM_VOICE_CALL and STREAM_BLUETOOTH_SCO can be muted by applications 1718 // that has the the MODIFY_PHONE_STATE permission. 1719 for (int i = 0; i < mStreamStates.length; i++) { 1720 final VolumeStreamState vss = mStreamStates[i]; 1721 if (vss.mIndexMin > 0 && 1722 (vss.mStreamType != AudioSystem.STREAM_VOICE_CALL && 1723 vss.mStreamType != AudioSystem.STREAM_BLUETOOTH_SCO)) { 1724 mMuteAffectedStreams &= ~(1 << vss.mStreamType); 1725 } 1726 } 1727 } 1728 createStreamStates()1729 private void createStreamStates() { 1730 int numStreamTypes = AudioSystem.getNumStreamTypes(); 1731 VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes]; 1732 1733 for (int i = 0; i < numStreamTypes; i++) { 1734 streams[i] = 1735 new VolumeStreamState(System.VOLUME_SETTINGS_INT[mStreamVolumeAlias[i]], i); 1736 } 1737 1738 checkAllFixedVolumeDevices(); 1739 checkAllAliasStreamVolumes(); 1740 checkMuteAffectedStreams(); 1741 updateDefaultVolumes(); 1742 } 1743 1744 /** 1745 * Update default indexes from aliased streams. Must be called after mStreamStates is created 1746 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for default 1747 * index. Need to make default index configurable and independent of streams. 1748 * Fallback on music stream for default initialization to take benefit of property based default 1749 * initialization. 1750 * For other volume groups not linked to any streams, default music stream index is considered. 1751 */ updateDefaultVolumes()1752 private void updateDefaultVolumes() { 1753 for (int stream = 0; stream < mStreamStates.length; stream++) { 1754 int streamVolumeAlias = mStreamVolumeAlias[stream]; 1755 if (mUseVolumeGroupAliases) { 1756 if (AudioSystem.DEFAULT_STREAM_VOLUME[stream] != UNSET_INDEX) { 1757 // Already initialized through default property based mecanism. 1758 continue; 1759 } 1760 streamVolumeAlias = AudioSystem.STREAM_MUSIC; 1761 int defaultAliasVolume = getUiDefaultRescaledIndex(streamVolumeAlias, stream); 1762 if ((defaultAliasVolume >= MIN_STREAM_VOLUME[stream]) 1763 && (defaultAliasVolume <= MAX_STREAM_VOLUME[stream])) { 1764 AudioSystem.DEFAULT_STREAM_VOLUME[stream] = defaultAliasVolume; 1765 continue; 1766 } 1767 } 1768 if (stream != streamVolumeAlias) { 1769 AudioSystem.DEFAULT_STREAM_VOLUME[stream] = 1770 getUiDefaultRescaledIndex(streamVolumeAlias, stream); 1771 } 1772 } 1773 } 1774 getUiDefaultRescaledIndex(int srcStream, int dstStream)1775 private int getUiDefaultRescaledIndex(int srcStream, int dstStream) { 1776 return (rescaleIndex(AudioSystem.DEFAULT_STREAM_VOLUME[srcStream] * 10, 1777 srcStream, dstStream) + 5) / 10; 1778 } 1779 dumpStreamStates(PrintWriter pw)1780 private void dumpStreamStates(PrintWriter pw) { 1781 pw.println("\nStream volumes (device: index)"); 1782 int numStreamTypes = AudioSystem.getNumStreamTypes(); 1783 for (int i = 0; i < numStreamTypes; i++) { 1784 pw.println("- " + AudioSystem.STREAM_NAMES[i] + ":"); 1785 mStreamStates[i].dump(pw); 1786 pw.println(""); 1787 } 1788 pw.print("\n- mute affected streams = 0x"); 1789 pw.println(Integer.toHexString(mMuteAffectedStreams)); 1790 } 1791 updateStreamVolumeAlias(boolean updateVolumes, String caller)1792 private void updateStreamVolumeAlias(boolean updateVolumes, String caller) { 1793 int dtmfStreamAlias; 1794 final int a11yStreamAlias = sIndependentA11yVolume ? 1795 AudioSystem.STREAM_ACCESSIBILITY : AudioSystem.STREAM_MUSIC; 1796 final int assistantStreamAlias = mContext.getResources().getBoolean( 1797 com.android.internal.R.bool.config_useAssistantVolume) ? 1798 AudioSystem.STREAM_ASSISTANT : AudioSystem.STREAM_MUSIC; 1799 1800 if (mIsSingleVolume) { 1801 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION; 1802 dtmfStreamAlias = AudioSystem.STREAM_MUSIC; 1803 } else if (mUseVolumeGroupAliases) { 1804 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_NONE; 1805 dtmfStreamAlias = AudioSystem.STREAM_DTMF; 1806 } else { 1807 switch (mPlatformType) { 1808 case AudioSystem.PLATFORM_VOICE: 1809 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_VOICE; 1810 dtmfStreamAlias = AudioSystem.STREAM_RING; 1811 break; 1812 default: 1813 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_DEFAULT; 1814 dtmfStreamAlias = AudioSystem.STREAM_MUSIC; 1815 } 1816 } 1817 1818 if (mIsSingleVolume) { 1819 mRingerModeAffectedStreams = 0; 1820 } else { 1821 if (isInCommunication()) { 1822 dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL; 1823 mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF); 1824 } else { 1825 mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF); 1826 } 1827 } 1828 1829 mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias; 1830 mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias; 1831 mStreamVolumeAlias[AudioSystem.STREAM_ASSISTANT] = assistantStreamAlias; 1832 1833 if (updateVolumes && mStreamStates != null) { 1834 updateDefaultVolumes(); 1835 1836 synchronized (mSettingsLock) { 1837 synchronized (VolumeStreamState.class) { 1838 mStreamStates[AudioSystem.STREAM_DTMF] 1839 .setAllIndexes(mStreamStates[dtmfStreamAlias], caller); 1840 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].mVolumeIndexSettingName = 1841 System.VOLUME_SETTINGS_INT[a11yStreamAlias]; 1842 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setAllIndexes( 1843 mStreamStates[a11yStreamAlias], caller); 1844 } 1845 } 1846 if (sIndependentA11yVolume) { 1847 // restore the a11y values from the settings 1848 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].readSettings(); 1849 } 1850 1851 // apply stream mute states according to new value of mRingerModeAffectedStreams 1852 setRingerModeInt(getRingerModeInternal(), false); 1853 sendMsg(mAudioHandler, 1854 MSG_SET_ALL_VOLUMES, 1855 SENDMSG_QUEUE, 1856 0, 1857 0, 1858 mStreamStates[AudioSystem.STREAM_DTMF], 0); 1859 sendMsg(mAudioHandler, 1860 MSG_SET_ALL_VOLUMES, 1861 SENDMSG_QUEUE, 1862 0, 1863 0, 1864 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY], 0); 1865 } 1866 } 1867 readDockAudioSettings(ContentResolver cr)1868 private void readDockAudioSettings(ContentResolver cr) 1869 { 1870 mDockAudioMediaEnabled = Settings.Global.getInt( 1871 cr, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED, 0) == 1; 1872 1873 sendMsg(mAudioHandler, 1874 MSG_SET_FORCE_USE, 1875 SENDMSG_QUEUE, 1876 AudioSystem.FOR_DOCK, 1877 mDockAudioMediaEnabled ? 1878 AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE, 1879 new String("readDockAudioSettings"), 1880 0); 1881 } 1882 1883 updateMasterMono(ContentResolver cr)1884 private void updateMasterMono(ContentResolver cr) 1885 { 1886 final boolean masterMono = System.getIntForUser( 1887 cr, System.MASTER_MONO, 0 /* default */, UserHandle.USER_CURRENT) == 1; 1888 if (DEBUG_VOL) { 1889 Log.d(TAG, String.format("Master mono %b", masterMono)); 1890 } 1891 AudioSystem.setMasterMono(masterMono); 1892 } 1893 updateMasterBalance(ContentResolver cr)1894 private void updateMasterBalance(ContentResolver cr) { 1895 final float masterBalance = System.getFloatForUser( 1896 cr, System.MASTER_BALANCE, 0.f /* default */, UserHandle.USER_CURRENT); 1897 if (DEBUG_VOL) { 1898 Log.d(TAG, String.format("Master balance %f", masterBalance)); 1899 } 1900 if (AudioSystem.setMasterBalance(masterBalance) != 0) { 1901 Log.e(TAG, String.format("setMasterBalance failed for %f", masterBalance)); 1902 } 1903 } 1904 sendEncodedSurroundMode(ContentResolver cr, String eventSource)1905 private void sendEncodedSurroundMode(ContentResolver cr, String eventSource) 1906 { 1907 final int encodedSurroundMode = Settings.Global.getInt( 1908 cr, Settings.Global.ENCODED_SURROUND_OUTPUT, 1909 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 1910 sendEncodedSurroundMode(encodedSurroundMode, eventSource); 1911 } 1912 sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)1913 private void sendEncodedSurroundMode(int encodedSurroundMode, String eventSource) 1914 { 1915 // initialize to guaranteed bad value 1916 int forceSetting = AudioSystem.NUM_FORCE_CONFIG; 1917 switch (encodedSurroundMode) { 1918 case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO: 1919 forceSetting = AudioSystem.FORCE_NONE; 1920 break; 1921 case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER: 1922 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_NEVER; 1923 break; 1924 case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS: 1925 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_ALWAYS; 1926 break; 1927 case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL: 1928 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_MANUAL; 1929 break; 1930 default: 1931 Log.e(TAG, "updateSurroundSoundSettings: illegal value " 1932 + encodedSurroundMode); 1933 break; 1934 } 1935 if (forceSetting != AudioSystem.NUM_FORCE_CONFIG) { 1936 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_ENCODED_SURROUND, forceSetting, 1937 eventSource); 1938 } 1939 } 1940 1941 /** @see AudioManager#getSurroundFormats() */ 1942 @Override getSurroundFormats()1943 public Map<Integer, Boolean> getSurroundFormats() { 1944 Map<Integer, Boolean> surroundFormats = new HashMap<>(); 1945 int status = AudioSystem.getSurroundFormats(surroundFormats); 1946 if (status != AudioManager.SUCCESS) { 1947 // fail and bail! 1948 Log.e(TAG, "getSurroundFormats failed:" + status); 1949 return new HashMap<>(); // Always return a map. 1950 } 1951 return surroundFormats; 1952 } 1953 1954 /** @see AudioManager#getReportedSurroundFormats() */ 1955 @Override getReportedSurroundFormats()1956 public List<Integer> getReportedSurroundFormats() { 1957 ArrayList<Integer> reportedSurroundFormats = new ArrayList<>(); 1958 int status = AudioSystem.getReportedSurroundFormats(reportedSurroundFormats); 1959 if (status != AudioManager.SUCCESS) { 1960 // fail and bail! 1961 Log.e(TAG, "getReportedSurroundFormats failed:" + status); 1962 return new ArrayList<>(); // Always return a list. 1963 } 1964 return reportedSurroundFormats; 1965 } 1966 1967 /** @see AudioManager#isSurroundFormatEnabled(int) */ 1968 @Override isSurroundFormatEnabled(int audioFormat)1969 public boolean isSurroundFormatEnabled(int audioFormat) { 1970 if (!isSurroundFormat(audioFormat)) { 1971 Log.w(TAG, "audioFormat to enable is not a surround format."); 1972 return false; 1973 } 1974 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS) 1975 != PackageManager.PERMISSION_GRANTED) { 1976 throw new SecurityException("Missing WRITE_SETTINGS permission"); 1977 } 1978 1979 final long token = Binder.clearCallingIdentity(); 1980 try { 1981 synchronized (mSettingsLock) { 1982 HashSet<Integer> enabledFormats = getEnabledFormats(); 1983 return enabledFormats.contains(audioFormat); 1984 } 1985 } finally { 1986 Binder.restoreCallingIdentity(token); 1987 } 1988 } 1989 1990 /** @see AudioManager#setSurroundFormatEnabled(int, boolean) */ 1991 @Override setSurroundFormatEnabled(int audioFormat, boolean enabled)1992 public boolean setSurroundFormatEnabled(int audioFormat, boolean enabled) { 1993 if (!isSurroundFormat(audioFormat)) { 1994 Log.w(TAG, "audioFormat to enable is not a surround format."); 1995 return false; 1996 } 1997 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS) 1998 != PackageManager.PERMISSION_GRANTED) { 1999 throw new SecurityException("Missing WRITE_SETTINGS permission"); 2000 } 2001 2002 HashSet<Integer> enabledFormats = getEnabledFormats(); 2003 if (enabled) { 2004 enabledFormats.add(audioFormat); 2005 } else { 2006 enabledFormats.remove(audioFormat); 2007 } 2008 final long token = Binder.clearCallingIdentity(); 2009 try { 2010 synchronized (mSettingsLock) { 2011 Settings.Global.putString(mContentResolver, 2012 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS, 2013 TextUtils.join(",", enabledFormats)); 2014 } 2015 } finally { 2016 Binder.restoreCallingIdentity(token); 2017 } 2018 return true; 2019 } 2020 2021 /** @see AudioManager#setEncodedSurroundMode(int) */ 2022 @Override setEncodedSurroundMode(@udioManager.EncodedSurroundOutputMode int mode)2023 public boolean setEncodedSurroundMode(@AudioManager.EncodedSurroundOutputMode int mode) { 2024 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS) 2025 != PackageManager.PERMISSION_GRANTED) { 2026 throw new SecurityException("Missing WRITE_SETTINGS permission"); 2027 } 2028 2029 final long token = Binder.clearCallingIdentity(); 2030 try { 2031 synchronized (mSettingsLock) { 2032 Settings.Global.putInt(mContentResolver, 2033 Settings.Global.ENCODED_SURROUND_OUTPUT, 2034 toEncodedSurroundSetting(mode)); 2035 } 2036 } finally { 2037 Binder.restoreCallingIdentity(token); 2038 } 2039 return true; 2040 } 2041 2042 /** @see AudioManager#getEncodedSurroundMode() */ 2043 @Override getEncodedSurroundMode(int targetSdkVersion)2044 public int getEncodedSurroundMode(int targetSdkVersion) { 2045 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS) 2046 != PackageManager.PERMISSION_GRANTED) { 2047 throw new SecurityException("Missing WRITE_SETTINGS permission"); 2048 } 2049 2050 final long token = Binder.clearCallingIdentity(); 2051 try { 2052 synchronized (mSettingsLock) { 2053 int encodedSurroundSetting = Settings.Global.getInt(mContentResolver, 2054 Settings.Global.ENCODED_SURROUND_OUTPUT, 2055 AudioManager.ENCODED_SURROUND_OUTPUT_AUTO); 2056 return toEncodedSurroundOutputMode(encodedSurroundSetting, targetSdkVersion); 2057 } 2058 } finally { 2059 Binder.restoreCallingIdentity(token); 2060 } 2061 } 2062 2063 /** @return the formats that are enabled in global settings */ getEnabledFormats()2064 private HashSet<Integer> getEnabledFormats() { 2065 HashSet<Integer> formats = new HashSet<>(); 2066 String enabledFormats = Settings.Global.getString(mContentResolver, 2067 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 2068 if (enabledFormats != null) { 2069 try { 2070 Arrays.stream(TextUtils.split(enabledFormats, ",")) 2071 .mapToInt(Integer::parseInt) 2072 .forEach(formats::add); 2073 } catch (NumberFormatException e) { 2074 Log.w(TAG, "ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS misformatted.", e); 2075 } 2076 } 2077 return formats; 2078 } 2079 2080 @SuppressWarnings("AndroidFrameworkCompatChange") 2081 @AudioManager.EncodedSurroundOutputMode toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion)2082 private int toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion) { 2083 if (targetSdkVersion <= Build.VERSION_CODES.S 2084 && encodedSurroundSetting > Settings.Global.ENCODED_SURROUND_SC_MAX) { 2085 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN; 2086 } 2087 switch (encodedSurroundSetting) { 2088 case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO: 2089 return AudioManager.ENCODED_SURROUND_OUTPUT_AUTO; 2090 case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER: 2091 return AudioManager.ENCODED_SURROUND_OUTPUT_NEVER; 2092 case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS: 2093 return AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS; 2094 case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL: 2095 return AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL; 2096 default: 2097 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN; 2098 } 2099 } 2100 toEncodedSurroundSetting( @udioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode)2101 private int toEncodedSurroundSetting( 2102 @AudioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode) { 2103 switch (encodedSurroundOutputMode) { 2104 case AudioManager.ENCODED_SURROUND_OUTPUT_NEVER: 2105 return Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER; 2106 case AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS: 2107 return Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS; 2108 case AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL: 2109 return Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL; 2110 default: 2111 return Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO; 2112 } 2113 } 2114 isSurroundFormat(int audioFormat)2115 private boolean isSurroundFormat(int audioFormat) { 2116 for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) { 2117 if (sf == audioFormat) { 2118 return true; 2119 } 2120 } 2121 return false; 2122 } 2123 sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate)2124 private void sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate) { 2125 if (mEncodedSurroundMode != Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL) { 2126 // Manually enable surround formats only when the setting is in manual mode. 2127 return; 2128 } 2129 String enabledSurroundFormats = Settings.Global.getString( 2130 cr, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 2131 if (enabledSurroundFormats == null) { 2132 // Never allow enabledSurroundFormats as a null, which could happen when 2133 // ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS is not appear in settings DB. 2134 enabledSurroundFormats = ""; 2135 } 2136 if (!forceUpdate && TextUtils.equals(enabledSurroundFormats, mEnabledSurroundFormats)) { 2137 // Update enabled surround formats to AudioPolicyManager only when forceUpdate 2138 // is true or enabled surround formats changed. 2139 return; 2140 } 2141 2142 mEnabledSurroundFormats = enabledSurroundFormats; 2143 String[] surroundFormats = TextUtils.split(enabledSurroundFormats, ","); 2144 ArrayList<Integer> formats = new ArrayList<>(); 2145 for (String format : surroundFormats) { 2146 try { 2147 int audioFormat = Integer.valueOf(format); 2148 if (isSurroundFormat(audioFormat) && !formats.contains(audioFormat)) { 2149 formats.add(audioFormat); 2150 } 2151 } catch (Exception e) { 2152 Log.e(TAG, "Invalid enabled surround format:" + format); 2153 } 2154 } 2155 // Set filtered surround formats to settings DB in case 2156 // there are invalid surround formats in original settings. 2157 Settings.Global.putString(mContext.getContentResolver(), 2158 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS, 2159 TextUtils.join(",", formats)); 2160 sendMsg(mAudioHandler, MSG_ENABLE_SURROUND_FORMATS, SENDMSG_QUEUE, 0, 0, formats, 0); 2161 } 2162 onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats)2163 private void onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats) { 2164 // Set surround format enabled accordingly. 2165 for (int surroundFormat : AudioFormat.SURROUND_SOUND_ENCODING) { 2166 boolean enabled = enabledSurroundFormats.contains(surroundFormat); 2167 int ret = AudioSystem.setSurroundFormatEnabled(surroundFormat, enabled); 2168 Log.i(TAG, "enable surround format:" + surroundFormat + " " + enabled + " " + ret); 2169 } 2170 } 2171 2172 @GuardedBy("mSettingsLock") updateAssistantUId(boolean forceUpdate)2173 private void updateAssistantUId(boolean forceUpdate) { 2174 int assistantUid = 0; 2175 2176 // Consider assistants in the following order of priority: 2177 // 1) apk in assistant role 2178 // 2) voice interaction service 2179 // 3) assistant service 2180 2181 String packageName = ""; 2182 if (mRoleObserver != null) { 2183 packageName = mRoleObserver.getAssistantRoleHolder(); 2184 } 2185 if (TextUtils.isEmpty(packageName)) { 2186 String assistantName = Settings.Secure.getStringForUser( 2187 mContentResolver, 2188 Settings.Secure.VOICE_INTERACTION_SERVICE, UserHandle.USER_CURRENT); 2189 if (TextUtils.isEmpty(assistantName)) { 2190 assistantName = Settings.Secure.getStringForUser( 2191 mContentResolver, 2192 Settings.Secure.ASSISTANT, UserHandle.USER_CURRENT); 2193 } 2194 if (!TextUtils.isEmpty(assistantName)) { 2195 ComponentName componentName = ComponentName.unflattenFromString(assistantName); 2196 if (componentName == null) { 2197 Slog.w(TAG, "Invalid service name for " 2198 + Settings.Secure.VOICE_INTERACTION_SERVICE + ": " + assistantName); 2199 return; 2200 } 2201 packageName = componentName.getPackageName(); 2202 } 2203 } 2204 if (!TextUtils.isEmpty(packageName)) { 2205 PackageManager pm = mContext.getPackageManager(); 2206 ActivityManager am = 2207 (ActivityManager) mContext.getSystemService(mContext.ACTIVITY_SERVICE); 2208 2209 if (pm.checkPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD, packageName) 2210 == PackageManager.PERMISSION_GRANTED) { 2211 try { 2212 assistantUid = pm.getPackageUidAsUser(packageName, am.getCurrentUser()); 2213 } catch (PackageManager.NameNotFoundException e) { 2214 Log.e(TAG, 2215 "updateAssistantUId() could not find UID for package: " + packageName); 2216 } 2217 } 2218 } 2219 2220 if (assistantUid != mAssistantUid || forceUpdate) { 2221 AudioSystem.setAssistantUid(assistantUid); 2222 mAssistantUid = assistantUid; 2223 } 2224 } 2225 readPersistedSettings()2226 private void readPersistedSettings() { 2227 if (!mSystemServer.isPrivileged()) { 2228 return; 2229 } 2230 final ContentResolver cr = mContentResolver; 2231 2232 int ringerModeFromSettings = 2233 Settings.Global.getInt( 2234 cr, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL); 2235 int ringerMode = ringerModeFromSettings; 2236 // validity check in case the settings are restored from a device with incompatible 2237 // ringer modes 2238 if (!isValidRingerMode(ringerMode)) { 2239 ringerMode = AudioManager.RINGER_MODE_NORMAL; 2240 } 2241 if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { 2242 ringerMode = AudioManager.RINGER_MODE_SILENT; 2243 } 2244 if (ringerMode != ringerModeFromSettings) { 2245 Settings.Global.putInt(cr, Settings.Global.MODE_RINGER, ringerMode); 2246 } 2247 if (mUseFixedVolume || mIsSingleVolume) { 2248 ringerMode = AudioManager.RINGER_MODE_NORMAL; 2249 } 2250 synchronized(mSettingsLock) { 2251 mRingerMode = ringerMode; 2252 if (mRingerModeExternal == -1) { 2253 mRingerModeExternal = mRingerMode; 2254 } 2255 2256 // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting 2257 // are still needed while setVibrateSetting() and getVibrateSetting() are being 2258 // deprecated. 2259 mVibrateSetting = AudioSystem.getValueForVibrateSetting(0, 2260 AudioManager.VIBRATE_TYPE_NOTIFICATION, 2261 mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT 2262 : AudioManager.VIBRATE_SETTING_OFF); 2263 mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, 2264 AudioManager.VIBRATE_TYPE_RINGER, 2265 mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT 2266 : AudioManager.VIBRATE_SETTING_OFF); 2267 2268 updateRingerAndZenModeAffectedStreams(); 2269 readDockAudioSettings(cr); 2270 sendEncodedSurroundMode(cr, "readPersistedSettings"); 2271 sendEnabledSurroundFormats(cr, true); 2272 updateAssistantUId(true); 2273 AudioSystem.setRttEnabled(mRttEnabled); 2274 } 2275 2276 mMuteAffectedStreams = System.getIntForUser(cr, 2277 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED, 2278 UserHandle.USER_CURRENT); 2279 2280 updateMasterMono(cr); 2281 2282 updateMasterBalance(cr); 2283 2284 // Each stream will read its own persisted settings 2285 2286 // Broadcast the sticky intents 2287 broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal); 2288 broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode); 2289 2290 // Broadcast vibrate settings 2291 broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER); 2292 broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION); 2293 2294 // Load settings for the volume controller 2295 mVolumeController.loadSettings(cr); 2296 } 2297 readUserRestrictions()2298 private void readUserRestrictions() { 2299 if (!mSystemServer.isPrivileged()) { 2300 return; 2301 } 2302 final int currentUser = getCurrentUserId(); 2303 2304 // Check the current user restriction. 2305 boolean masterMute = 2306 mUserManagerInternal.getUserRestriction(currentUser, 2307 UserManager.DISALLOW_UNMUTE_DEVICE) 2308 || mUserManagerInternal.getUserRestriction(currentUser, 2309 UserManager.DISALLOW_ADJUST_VOLUME); 2310 if (mUseFixedVolume) { 2311 masterMute = false; 2312 AudioSystem.setMasterVolume(1.0f); 2313 } 2314 if (DEBUG_VOL) { 2315 Log.d(TAG, String.format("Master mute %s, user=%d", masterMute, currentUser)); 2316 } 2317 setSystemAudioMute(masterMute); 2318 AudioSystem.setMasterMute(masterMute); 2319 broadcastMasterMuteStatus(masterMute); 2320 2321 mMicMuteFromRestrictions = mUserManagerInternal.getUserRestriction( 2322 currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE); 2323 if (DEBUG_VOL) { 2324 Log.d(TAG, String.format("Mic mute %b, user=%d", mMicMuteFromRestrictions, 2325 currentUser)); 2326 } 2327 setMicrophoneMuteNoCallerCheck(currentUser); 2328 } 2329 getIndexRange(int streamType)2330 private int getIndexRange(int streamType) { 2331 return (mStreamStates[streamType].getMaxIndex() - mStreamStates[streamType].getMinIndex()); 2332 } 2333 rescaleIndex(int index, int srcStream, int dstStream)2334 private int rescaleIndex(int index, int srcStream, int dstStream) { 2335 int srcRange = getIndexRange(srcStream); 2336 int dstRange = getIndexRange(dstStream); 2337 if (srcRange == 0) { 2338 Log.e(TAG, "rescaleIndex : index range should not be zero"); 2339 return mStreamStates[dstStream].getMinIndex(); 2340 } 2341 2342 return mStreamStates[dstStream].getMinIndex() 2343 + ((index - mStreamStates[srcStream].getMinIndex()) * dstRange + srcRange / 2) 2344 / srcRange; 2345 } 2346 rescaleStep(int step, int srcStream, int dstStream)2347 private int rescaleStep(int step, int srcStream, int dstStream) { 2348 int srcRange = getIndexRange(srcStream); 2349 int dstRange = getIndexRange(dstStream); 2350 if (srcRange == 0) { 2351 Log.e(TAG, "rescaleStep : index range should not be zero"); 2352 return 0; 2353 } 2354 2355 return ((step * dstRange + srcRange / 2) / srcRange); 2356 } 2357 2358 /////////////////////////////////////////////////////////////////////////// 2359 // IPC methods 2360 /////////////////////////////////////////////////////////////////////////// 2361 /** 2362 * @see AudioManager#setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes) 2363 * @see AudioManager#setPreferredDevicesForStrategy(AudioProductStrategy, 2364 * List<AudioDeviceAttributes>) 2365 */ setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices)2366 public int setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices) { 2367 if (devices == null) { 2368 return AudioSystem.ERROR; 2369 } 2370 enforceModifyAudioRoutingPermission(); 2371 final String logString = String.format( 2372 "setPreferredDeviceForStrategy u/pid:%d/%d strat:%d dev:%s", 2373 Binder.getCallingUid(), Binder.getCallingPid(), strategy, 2374 devices.stream().map(e -> e.toString()).collect(Collectors.joining(","))); 2375 sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG)); 2376 if (devices.stream().anyMatch(device -> 2377 device.getRole() == AudioDeviceAttributes.ROLE_INPUT)) { 2378 Log.e(TAG, "Unsupported input routing in " + logString); 2379 return AudioSystem.ERROR; 2380 } 2381 2382 final int status = mDeviceBroker.setPreferredDevicesForStrategySync(strategy, devices); 2383 if (status != AudioSystem.SUCCESS) { 2384 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 2385 } 2386 2387 return status; 2388 } 2389 2390 /** @see AudioManager#removePreferredDeviceForStrategy(AudioProductStrategy) */ removePreferredDevicesForStrategy(int strategy)2391 public int removePreferredDevicesForStrategy(int strategy) { 2392 enforceModifyAudioRoutingPermission(); 2393 final String logString = 2394 String.format("removePreferredDeviceForStrategy strat:%d", strategy); 2395 sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG)); 2396 2397 final int status = mDeviceBroker.removePreferredDevicesForStrategySync(strategy); 2398 if (status != AudioSystem.SUCCESS) { 2399 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 2400 } 2401 return status; 2402 } 2403 2404 /** 2405 * @see AudioManager#getPreferredDeviceForStrategy(AudioProductStrategy) 2406 * @see AudioManager#getPreferredDevicesForStrategy(AudioProductStrategy) 2407 */ getPreferredDevicesForStrategy(int strategy)2408 public List<AudioDeviceAttributes> getPreferredDevicesForStrategy(int strategy) { 2409 enforceModifyAudioRoutingPermission(); 2410 List<AudioDeviceAttributes> devices = new ArrayList<>(); 2411 final long identity = Binder.clearCallingIdentity(); 2412 final int status = AudioSystem.getDevicesForRoleAndStrategy( 2413 strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices); 2414 Binder.restoreCallingIdentity(identity); 2415 if (status != AudioSystem.SUCCESS) { 2416 Log.e(TAG, String.format("Error %d in getPreferredDeviceForStrategy(%d)", 2417 status, strategy)); 2418 return new ArrayList<AudioDeviceAttributes>(); 2419 } else { 2420 return devices; 2421 } 2422 } 2423 2424 /** @see AudioManager#addOnPreferredDevicesForStrategyChangedListener( 2425 * Executor, AudioManager.OnPreferredDevicesForStrategyChangedListener) 2426 */ registerStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)2427 public void registerStrategyPreferredDevicesDispatcher( 2428 @Nullable IStrategyPreferredDevicesDispatcher dispatcher) { 2429 if (dispatcher == null) { 2430 return; 2431 } 2432 enforceModifyAudioRoutingPermission(); 2433 mDeviceBroker.registerStrategyPreferredDevicesDispatcher(dispatcher); 2434 } 2435 2436 /** @see AudioManager#removeOnPreferredDevicesForStrategyChangedListener( 2437 * AudioManager.OnPreferredDevicesForStrategyChangedListener) 2438 */ unregisterStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)2439 public void unregisterStrategyPreferredDevicesDispatcher( 2440 @Nullable IStrategyPreferredDevicesDispatcher dispatcher) { 2441 if (dispatcher == null) { 2442 return; 2443 } 2444 enforceModifyAudioRoutingPermission(); 2445 mDeviceBroker.unregisterStrategyPreferredDevicesDispatcher(dispatcher); 2446 } 2447 2448 /** 2449 * @see AudioManager#setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes) 2450 */ setPreferredDevicesForCapturePreset( int capturePreset, List<AudioDeviceAttributes> devices)2451 public int setPreferredDevicesForCapturePreset( 2452 int capturePreset, List<AudioDeviceAttributes> devices) { 2453 if (devices == null) { 2454 return AudioSystem.ERROR; 2455 } 2456 enforceModifyAudioRoutingPermission(); 2457 final String logString = String.format( 2458 "setPreferredDevicesForCapturePreset u/pid:%d/%d source:%d dev:%s", 2459 Binder.getCallingUid(), Binder.getCallingPid(), capturePreset, 2460 devices.stream().map(e -> e.toString()).collect(Collectors.joining(","))); 2461 sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG)); 2462 if (devices.stream().anyMatch(device -> 2463 device.getRole() == AudioDeviceAttributes.ROLE_OUTPUT)) { 2464 Log.e(TAG, "Unsupported output routing in " + logString); 2465 return AudioSystem.ERROR; 2466 } 2467 2468 final int status = mDeviceBroker.setPreferredDevicesForCapturePresetSync( 2469 capturePreset, devices); 2470 if (status != AudioSystem.SUCCESS) { 2471 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 2472 } 2473 2474 return status; 2475 } 2476 2477 /** @see AudioManager#clearPreferredDevicesForCapturePreset(int) */ clearPreferredDevicesForCapturePreset(int capturePreset)2478 public int clearPreferredDevicesForCapturePreset(int capturePreset) { 2479 enforceModifyAudioRoutingPermission(); 2480 final String logString = String.format( 2481 "removePreferredDeviceForCapturePreset source:%d", capturePreset); 2482 sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG)); 2483 2484 final int status = mDeviceBroker.clearPreferredDevicesForCapturePresetSync(capturePreset); 2485 if (status != AudioSystem.SUCCESS) { 2486 Log.e(TAG, String.format("Error %d in %s", status, logString)); 2487 } 2488 return status; 2489 } 2490 2491 /** 2492 * @see AudioManager#getPreferredDevicesForCapturePreset(int) 2493 */ getPreferredDevicesForCapturePreset(int capturePreset)2494 public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) { 2495 enforceModifyAudioRoutingPermission(); 2496 List<AudioDeviceAttributes> devices = new ArrayList<>(); 2497 final long identity = Binder.clearCallingIdentity(); 2498 final int status = AudioSystem.getDevicesForRoleAndCapturePreset( 2499 capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices); 2500 Binder.restoreCallingIdentity(identity); 2501 if (status != AudioSystem.SUCCESS) { 2502 Log.e(TAG, String.format("Error %d in getPreferredDeviceForCapturePreset(%d)", 2503 status, capturePreset)); 2504 return new ArrayList<AudioDeviceAttributes>(); 2505 } else { 2506 return devices; 2507 } 2508 } 2509 2510 /** 2511 * @see AudioManager#addOnPreferredDevicesForCapturePresetChangedListener( 2512 * Executor, OnPreferredDevicesForCapturePresetChangedListener) 2513 */ registerCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)2514 public void registerCapturePresetDevicesRoleDispatcher( 2515 @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) { 2516 if (dispatcher == null) { 2517 return; 2518 } 2519 enforceModifyAudioRoutingPermission(); 2520 mDeviceBroker.registerCapturePresetDevicesRoleDispatcher(dispatcher); 2521 } 2522 2523 /** 2524 * @see AudioManager#removeOnPreferredDevicesForCapturePresetChangedListener( 2525 * AudioManager.OnPreferredDevicesForCapturePresetChangedListener) 2526 */ unregisterCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)2527 public void unregisterCapturePresetDevicesRoleDispatcher( 2528 @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) { 2529 if (dispatcher == null) { 2530 return; 2531 } 2532 enforceModifyAudioRoutingPermission(); 2533 mDeviceBroker.unregisterCapturePresetDevicesRoleDispatcher(dispatcher); 2534 } 2535 2536 /** @see AudioManager#getDevicesForAttributes(AudioAttributes) */ getDevicesForAttributes( @onNull AudioAttributes attributes)2537 public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes( 2538 @NonNull AudioAttributes attributes) { 2539 enforceQueryStateOrModifyRoutingPermission(); 2540 return getDevicesForAttributesInt(attributes); 2541 } 2542 2543 /** 2544 * @see AudioManager#isMusicActive() 2545 * @param remotely true if query is for remote playback (cast), false for local playback. 2546 */ isMusicActive(boolean remotely)2547 public boolean isMusicActive(boolean remotely) { 2548 // no permission required 2549 final long token = Binder.clearCallingIdentity(); 2550 try { 2551 if (remotely) { 2552 return AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, 0); 2553 } else { 2554 return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0); 2555 } 2556 } finally { 2557 Binder.restoreCallingIdentity(token); 2558 } 2559 } 2560 getDevicesForAttributesInt( @onNull AudioAttributes attributes)2561 protected @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesInt( 2562 @NonNull AudioAttributes attributes) { 2563 Objects.requireNonNull(attributes); 2564 return mAudioSystem.getDevicesForAttributes(attributes); 2565 } 2566 2567 /** Indicates no special treatment in the handling of the volume adjustement */ 2568 private static final int VOL_ADJUST_NORMAL = 0; 2569 /** Indicates the start of a volume adjustement */ 2570 private static final int VOL_ADJUST_START = 1; 2571 /** Indicates the end of a volume adjustment */ 2572 private static final int VOL_ADJUST_END = 2; 2573 2574 // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP, 2575 // KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE handleVolumeKey(@onNull KeyEvent event, boolean isOnTv, @NonNull String callingPackage, @NonNull String caller)2576 public void handleVolumeKey(@NonNull KeyEvent event, boolean isOnTv, 2577 @NonNull String callingPackage, @NonNull String caller) { 2578 int keyEventMode = VOL_ADJUST_NORMAL; 2579 if (isOnTv) { 2580 if (event.getAction() == KeyEvent.ACTION_DOWN) { 2581 keyEventMode = VOL_ADJUST_START; 2582 } else { // may catch more than ACTION_UP, but will end vol adjustement 2583 // the vol key is either released (ACTION_UP), or multiple keys are pressed 2584 // (ACTION_MULTIPLE) and we don't know what to do for volume control on CEC, end 2585 // the repeated volume adjustement 2586 keyEventMode = VOL_ADJUST_END; 2587 } 2588 } else if (event.getAction() != KeyEvent.ACTION_DOWN) { 2589 return; 2590 } 2591 2592 int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND 2593 | AudioManager.FLAG_FROM_KEY; 2594 2595 switch (event.getKeyCode()) { 2596 case KeyEvent.KEYCODE_VOLUME_UP: 2597 adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE, 2598 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 2599 Binder.getCallingUid(), true, keyEventMode); 2600 break; 2601 case KeyEvent.KEYCODE_VOLUME_DOWN: 2602 adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER, 2603 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 2604 Binder.getCallingUid(), true, keyEventMode); 2605 break; 2606 case KeyEvent.KEYCODE_VOLUME_MUTE: 2607 if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 2608 adjustSuggestedStreamVolume(AudioManager.ADJUST_TOGGLE_MUTE, 2609 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 2610 Binder.getCallingUid(), true, VOL_ADJUST_NORMAL); 2611 } 2612 break; 2613 default: 2614 Log.e(TAG, "Invalid key code " + event.getKeyCode() + " sent by " + callingPackage); 2615 return; // not needed but added if code gets added below this switch statement 2616 } 2617 } 2618 2619 /** @see AudioManager#adjustVolume(int, int) */ adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, String callingPackage, String caller)2620 public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, 2621 String callingPackage, String caller) { 2622 adjustSuggestedStreamVolume(direction, suggestedStreamType, flags, callingPackage, 2623 caller, Binder.getCallingUid(), callingHasAudioSettingsPermission(), 2624 VOL_ADJUST_NORMAL); 2625 } 2626 setNavigationRepeatSoundEffectsEnabled(boolean enabled)2627 public void setNavigationRepeatSoundEffectsEnabled(boolean enabled) { 2628 mNavigationRepeatSoundEffectsEnabled = enabled; 2629 } 2630 2631 /** 2632 * @return true if the fast scroll sound effects are enabled 2633 */ areNavigationRepeatSoundEffectsEnabled()2634 public boolean areNavigationRepeatSoundEffectsEnabled() { 2635 return mNavigationRepeatSoundEffectsEnabled; 2636 } 2637 setHomeSoundEffectEnabled(boolean enabled)2638 public void setHomeSoundEffectEnabled(boolean enabled) { 2639 mHomeSoundEffectEnabled = enabled; 2640 } 2641 2642 /** 2643 * @return true if the home sound effect is enabled 2644 */ isHomeSoundEffectEnabled()2645 public boolean isHomeSoundEffectEnabled() { 2646 return mHomeSoundEffectEnabled; 2647 } 2648 adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, String callingPackage, String caller, int uid, boolean hasModifyAudioSettings, int keyEventMode)2649 private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, 2650 String callingPackage, String caller, int uid, boolean hasModifyAudioSettings, 2651 int keyEventMode) { 2652 if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType 2653 + ", flags=" + flags + ", caller=" + caller 2654 + ", volControlStream=" + mVolumeControlStream 2655 + ", userSelect=" + mUserSelectedVolumeControlStream); 2656 if (direction != AudioManager.ADJUST_SAME) { 2657 sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType, 2658 direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage) 2659 .append("/").append(caller).append(" uid:").append(uid).toString())); 2660 } 2661 2662 boolean hasExternalVolumeController = notifyExternalVolumeController(direction); 2663 2664 new MediaMetrics.Item(mMetricsId + "adjustSuggestedStreamVolume") 2665 .setUid(Binder.getCallingUid()) 2666 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage) 2667 .set(MediaMetrics.Property.CLIENT_NAME, caller) 2668 .set(MediaMetrics.Property.DIRECTION, direction > 0 2669 ? MediaMetrics.Value.UP : MediaMetrics.Value.DOWN) 2670 .set(MediaMetrics.Property.EXTERNAL, hasExternalVolumeController 2671 ? MediaMetrics.Value.YES : MediaMetrics.Value.NO) 2672 .set(MediaMetrics.Property.FLAGS, flags) 2673 .record(); 2674 2675 if (hasExternalVolumeController) { 2676 return; 2677 } 2678 2679 final int streamType; 2680 synchronized (mForceControlStreamLock) { 2681 // Request lock in case mVolumeControlStream is changed by other thread. 2682 if (mUserSelectedVolumeControlStream) { // implies mVolumeControlStream != -1 2683 streamType = mVolumeControlStream; 2684 } else { 2685 final int maybeActiveStreamType = getActiveStreamType(suggestedStreamType); 2686 final boolean activeForReal; 2687 if (maybeActiveStreamType == AudioSystem.STREAM_RING 2688 || maybeActiveStreamType == AudioSystem.STREAM_NOTIFICATION) { 2689 activeForReal = wasStreamActiveRecently(maybeActiveStreamType, 0); 2690 } else { 2691 activeForReal = mAudioSystem.isStreamActive(maybeActiveStreamType, 0); 2692 } 2693 if (activeForReal || mVolumeControlStream == -1) { 2694 streamType = maybeActiveStreamType; 2695 } else { 2696 streamType = mVolumeControlStream; 2697 } 2698 } 2699 } 2700 2701 final boolean isMute = isMuteAdjust(direction); 2702 2703 ensureValidStreamType(streamType); 2704 final int resolvedStream = mStreamVolumeAlias[streamType]; 2705 2706 // Play sounds on STREAM_RING only. 2707 if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 && 2708 resolvedStream != AudioSystem.STREAM_RING) { 2709 flags &= ~AudioManager.FLAG_PLAY_SOUND; 2710 } 2711 2712 // For notifications/ring, show the ui before making any adjustments 2713 // Don't suppress mute/unmute requests 2714 // Don't suppress adjustments for single volume device 2715 if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute) 2716 && !mIsSingleVolume) { 2717 direction = 0; 2718 flags &= ~AudioManager.FLAG_PLAY_SOUND; 2719 flags &= ~AudioManager.FLAG_VIBRATE; 2720 if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment"); 2721 } 2722 2723 adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid, 2724 hasModifyAudioSettings, keyEventMode); 2725 } 2726 notifyExternalVolumeController(int direction)2727 private boolean notifyExternalVolumeController(int direction) { 2728 final IAudioPolicyCallback externalVolumeController; 2729 synchronized (mExtVolumeControllerLock) { 2730 externalVolumeController = mExtVolumeController; 2731 } 2732 if (externalVolumeController == null) { 2733 return false; 2734 } 2735 2736 sendMsg(mAudioHandler, MSG_NOTIFY_VOL_EVENT, SENDMSG_QUEUE, 2737 direction, 0 /*ignored*/, 2738 externalVolumeController, 0 /*delay*/); 2739 return true; 2740 } 2741 2742 /** @see AudioManager#adjustStreamVolume(int, int, int) 2743 * Part of service interface, check permissions here */ adjustStreamVolume(int streamType, int direction, int flags, String callingPackage)2744 public void adjustStreamVolume(int streamType, int direction, int flags, 2745 String callingPackage) { 2746 if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { 2747 Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without" 2748 + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage); 2749 return; 2750 } 2751 2752 sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType, 2753 direction/*val1*/, flags/*val2*/, callingPackage)); 2754 adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage, 2755 Binder.getCallingUid(), callingHasAudioSettingsPermission(), 2756 VOL_ADJUST_NORMAL); 2757 } 2758 adjustStreamVolume(int streamType, int direction, int flags, String callingPackage, String caller, int uid, boolean hasModifyAudioSettings, int keyEventMode)2759 protected void adjustStreamVolume(int streamType, int direction, int flags, 2760 String callingPackage, String caller, int uid, boolean hasModifyAudioSettings, 2761 int keyEventMode) { 2762 if (mUseFixedVolume) { 2763 return; 2764 } 2765 if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction 2766 + ", flags=" + flags + ", caller=" + caller); 2767 2768 ensureValidDirection(direction); 2769 ensureValidStreamType(streamType); 2770 2771 boolean isMuteAdjust = isMuteAdjust(direction); 2772 2773 if (isMuteAdjust && !isStreamAffectedByMute(streamType)) { 2774 return; 2775 } 2776 2777 // If adjust is mute and the stream is STREAM_VOICE_CALL or STREAM_BLUETOOTH_SCO, make sure 2778 // that the calling app have the MODIFY_PHONE_STATE permission. 2779 if (isMuteAdjust && 2780 (streamType == AudioSystem.STREAM_VOICE_CALL || 2781 streamType == AudioSystem.STREAM_BLUETOOTH_SCO) && 2782 mContext.checkCallingOrSelfPermission( 2783 android.Manifest.permission.MODIFY_PHONE_STATE) 2784 != PackageManager.PERMISSION_GRANTED) { 2785 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: adjustStreamVolume from pid=" 2786 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 2787 return; 2788 } 2789 2790 // If the stream is STREAM_ASSISTANT, 2791 // make sure that the calling app have the MODIFY_AUDIO_ROUTING permission. 2792 if (streamType == AudioSystem.STREAM_ASSISTANT && 2793 mContext.checkCallingOrSelfPermission( 2794 android.Manifest.permission.MODIFY_AUDIO_ROUTING) 2795 != PackageManager.PERMISSION_GRANTED) { 2796 Log.w(TAG, "MODIFY_AUDIO_ROUTING Permission Denial: adjustStreamVolume from pid=" 2797 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 2798 return; 2799 } 2800 2801 // use stream type alias here so that streams with same alias have the same behavior, 2802 // including with regard to silent mode control (e.g the use of STREAM_RING below and in 2803 // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION) 2804 int streamTypeAlias = mStreamVolumeAlias[streamType]; 2805 2806 VolumeStreamState streamState = mStreamStates[streamTypeAlias]; 2807 2808 final int device = getDeviceForStream(streamTypeAlias); 2809 2810 int aliasIndex = streamState.getIndex(device); 2811 boolean adjustVolume = true; 2812 int step; 2813 2814 // skip a2dp absolute volume control request when the device 2815 // is not an a2dp device 2816 if (!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 2817 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { 2818 return; 2819 } 2820 2821 // If we are being called by the system (e.g. hardware keys) check for current user 2822 // so we handle user restrictions correctly. 2823 if (uid == android.os.Process.SYSTEM_UID) { 2824 uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); 2825 } 2826 if (mAppOps.noteOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage) 2827 != AppOpsManager.MODE_ALLOWED) { 2828 return; 2829 } 2830 2831 // reset any pending volume command 2832 synchronized (mSafeMediaVolumeStateLock) { 2833 mPendingVolumeCommand = null; 2834 } 2835 2836 flags &= ~AudioManager.FLAG_FIXED_VOLUME; 2837 if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) { 2838 flags |= AudioManager.FLAG_FIXED_VOLUME; 2839 2840 // Always toggle between max safe volume and 0 for fixed volume devices where safe 2841 // volume is enforced, and max and 0 for the others. 2842 // This is simulated by stepping by the full allowed volume range 2843 if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE && 2844 mSafeMediaVolumeDevices.contains(device)) { 2845 step = safeMediaVolumeIndex(device); 2846 } else { 2847 step = streamState.getMaxIndex(); 2848 } 2849 if (aliasIndex != 0) { 2850 aliasIndex = step; 2851 } 2852 } else { 2853 // convert one UI step (+/-1) into a number of internal units on the stream alias 2854 step = rescaleStep(10, streamType, streamTypeAlias); 2855 } 2856 2857 // If either the client forces allowing ringer modes for this adjustment, 2858 // or the stream type is one that is affected by ringer modes 2859 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 2860 (isUiSoundsStreamType(streamTypeAlias))) { 2861 int ringerMode = getRingerModeInternal(); 2862 // do not vibrate if already in vibrate mode 2863 if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { 2864 flags &= ~AudioManager.FLAG_VIBRATE; 2865 } 2866 // Check if the ringer mode handles this adjustment. If it does we don't 2867 // need to adjust the volume further. 2868 final int result = checkForRingerModeChange(aliasIndex, direction, step, 2869 streamState.mIsMuted, callingPackage, flags); 2870 adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0; 2871 // If suppressing a volume adjustment in silent mode, display the UI hint 2872 if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) { 2873 flags |= AudioManager.FLAG_SHOW_SILENT_HINT; 2874 } 2875 // If suppressing a volume down adjustment in vibrate mode, display the UI hint 2876 if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) { 2877 flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT; 2878 } 2879 } 2880 2881 // If the ringer mode or zen is muting the stream, do not change stream unless 2882 // it'll cause us to exit dnd 2883 if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) { 2884 adjustVolume = false; 2885 } 2886 int oldIndex = mStreamStates[streamType].getIndex(device); 2887 2888 if (adjustVolume 2889 && (direction != AudioManager.ADJUST_SAME) && (keyEventMode != VOL_ADJUST_END)) { 2890 mAudioHandler.removeMessages(MSG_UNMUTE_STREAM); 2891 2892 if (isMuteAdjust && !mFullVolumeDevices.contains(device)) { 2893 boolean state; 2894 if (direction == AudioManager.ADJUST_TOGGLE_MUTE) { 2895 state = !streamState.mIsMuted; 2896 } else { 2897 state = direction == AudioManager.ADJUST_MUTE; 2898 } 2899 if (streamTypeAlias == AudioSystem.STREAM_MUSIC) { 2900 setSystemAudioMute(state); 2901 } 2902 for (int stream = 0; stream < mStreamStates.length; stream++) { 2903 if (streamTypeAlias == mStreamVolumeAlias[stream]) { 2904 if (!(readCameraSoundForced() 2905 && (mStreamStates[stream].getStreamType() 2906 == AudioSystem.STREAM_SYSTEM_ENFORCED))) { 2907 mStreamStates[stream].mute(state); 2908 } 2909 } 2910 } 2911 } else if ((direction == AudioManager.ADJUST_RAISE) && 2912 !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) { 2913 Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex); 2914 mVolumeController.postDisplaySafeVolumeWarning(flags); 2915 } else if (!isFullVolumeDevice(device) 2916 && (streamState.adjustIndex(direction * step, device, caller, 2917 hasModifyAudioSettings) 2918 || streamState.mIsMuted)) { 2919 // Post message to set system volume (it in turn will post a 2920 // message to persist). 2921 if (streamState.mIsMuted) { 2922 // Unmute the stream if it was previously muted 2923 if (direction == AudioManager.ADJUST_RAISE) { 2924 // unmute immediately for volume up 2925 streamState.mute(false); 2926 } else if (direction == AudioManager.ADJUST_LOWER) { 2927 if (mIsSingleVolume) { 2928 sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE, 2929 streamTypeAlias, flags, null, UNMUTE_STREAM_DELAY); 2930 } 2931 } 2932 } 2933 sendMsg(mAudioHandler, 2934 MSG_SET_DEVICE_VOLUME, 2935 SENDMSG_QUEUE, 2936 device, 2937 0, 2938 streamState, 2939 0); 2940 } 2941 2942 int newIndex = mStreamStates[streamType].getIndex(device); 2943 2944 // Check if volume update should be send to AVRCP 2945 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 2946 && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 2947 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 2948 if (DEBUG_VOL) { 2949 Log.d(TAG, "adjustSreamVolume: postSetAvrcpAbsoluteVolumeIndex index=" 2950 + newIndex + "stream=" + streamType); 2951 } 2952 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10); 2953 } 2954 2955 // Check if volume update should be send to Hearing Aid 2956 if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 2957 // only modify the hearing aid attenuation when the stream to modify matches 2958 // the one expected by the hearing aid 2959 if (streamType == getHearingAidStreamType()) { 2960 if (DEBUG_VOL) { 2961 Log.d(TAG, "adjustSreamVolume postSetHearingAidVolumeIndex index=" 2962 + newIndex + " stream=" + streamType); 2963 } 2964 mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType); 2965 } 2966 } 2967 2968 // Check if volume update should be sent to Hdmi system audio. 2969 if (streamTypeAlias == AudioSystem.STREAM_MUSIC) { 2970 setSystemAudioVolume(oldIndex, newIndex, getStreamMaxVolume(streamType), flags); 2971 } 2972 } 2973 2974 final int newIndex = mStreamStates[streamType].getIndex(device); 2975 2976 if (adjustVolume) { 2977 synchronized (mHdmiClientLock) { 2978 if (mHdmiManager != null) { 2979 if (mHdmiPlaybackClient != null 2980 && mHdmiCecVolumeControlEnabled 2981 && streamTypeAlias == AudioSystem.STREAM_MUSIC 2982 // vol change on a full volume device 2983 && isFullVolumeDevice(device)) { 2984 int keyCode = KeyEvent.KEYCODE_UNKNOWN; 2985 switch (direction) { 2986 case AudioManager.ADJUST_RAISE: 2987 keyCode = KeyEvent.KEYCODE_VOLUME_UP; 2988 break; 2989 case AudioManager.ADJUST_LOWER: 2990 keyCode = KeyEvent.KEYCODE_VOLUME_DOWN; 2991 break; 2992 case AudioManager.ADJUST_TOGGLE_MUTE: 2993 keyCode = KeyEvent.KEYCODE_VOLUME_MUTE; 2994 break; 2995 default: 2996 break; 2997 } 2998 if (keyCode != KeyEvent.KEYCODE_UNKNOWN) { 2999 final long ident = Binder.clearCallingIdentity(); 3000 try { 3001 final long time = java.lang.System.currentTimeMillis(); 3002 switch (keyEventMode) { 3003 case VOL_ADJUST_NORMAL: 3004 mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, true); 3005 mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, false); 3006 break; 3007 case VOL_ADJUST_START: 3008 mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, true); 3009 break; 3010 case VOL_ADJUST_END: 3011 mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, false); 3012 break; 3013 default: 3014 Log.e(TAG, "Invalid keyEventMode " + keyEventMode); 3015 } 3016 } finally { 3017 Binder.restoreCallingIdentity(ident); 3018 } 3019 } 3020 } 3021 3022 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 3023 && (oldIndex != newIndex || isMuteAdjust)) { 3024 maybeSendSystemAudioStatusCommand(isMuteAdjust); 3025 } 3026 } 3027 } 3028 } 3029 sendVolumeUpdate(streamType, oldIndex, newIndex, flags, device); 3030 } 3031 3032 // Called after a delay when volume down is pressed while muted onUnmuteStream(int stream, int flags)3033 private void onUnmuteStream(int stream, int flags) { 3034 boolean wasMuted; 3035 synchronized (VolumeStreamState.class) { 3036 final VolumeStreamState streamState = mStreamStates[stream]; 3037 wasMuted = streamState.mute(false); // if unmuting causes a change, it was muted 3038 3039 final int device = getDeviceForStream(stream); 3040 final int index = streamState.getIndex(device); 3041 sendVolumeUpdate(stream, index, index, flags, device); 3042 } 3043 if (stream == AudioSystem.STREAM_MUSIC && wasMuted) { 3044 synchronized (mHdmiClientLock) { 3045 maybeSendSystemAudioStatusCommand(true); 3046 } 3047 } 3048 } 3049 3050 @GuardedBy("mHdmiClientLock") maybeSendSystemAudioStatusCommand(boolean isMuteAdjust)3051 private void maybeSendSystemAudioStatusCommand(boolean isMuteAdjust) { 3052 if (mHdmiAudioSystemClient == null 3053 || !mHdmiSystemAudioSupported 3054 || !mHdmiCecVolumeControlEnabled) { 3055 return; 3056 } 3057 3058 final long identity = Binder.clearCallingIdentity(); 3059 mHdmiAudioSystemClient.sendReportAudioStatusCecCommand( 3060 isMuteAdjust, getStreamVolume(AudioSystem.STREAM_MUSIC), 3061 getStreamMaxVolume(AudioSystem.STREAM_MUSIC), 3062 isStreamMute(AudioSystem.STREAM_MUSIC)); 3063 Binder.restoreCallingIdentity(identity); 3064 } 3065 setSystemAudioVolume(int oldVolume, int newVolume, int maxVolume, int flags)3066 private void setSystemAudioVolume(int oldVolume, int newVolume, int maxVolume, int flags) { 3067 // Sets the audio volume of AVR when we are in system audio mode. The new volume info 3068 // is tranformed to HDMI-CEC commands and passed through CEC bus. 3069 synchronized (mHdmiClientLock) { 3070 if (mHdmiManager == null 3071 || mHdmiTvClient == null 3072 || oldVolume == newVolume 3073 || (flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) != 0 3074 || !mHdmiSystemAudioSupported 3075 || !mHdmiCecVolumeControlEnabled) { 3076 return; 3077 } 3078 final long token = Binder.clearCallingIdentity(); 3079 try { 3080 mHdmiTvClient.setSystemAudioVolume(oldVolume, newVolume, maxVolume); 3081 } finally { 3082 Binder.restoreCallingIdentity(token); 3083 } 3084 } 3085 } 3086 3087 // StreamVolumeCommand contains the information needed to defer the process of 3088 // setStreamVolume() in case the user has to acknowledge the safe volume warning message. 3089 static class StreamVolumeCommand { 3090 public final int mStreamType; 3091 public final int mIndex; 3092 public final int mFlags; 3093 public final int mDevice; 3094 StreamVolumeCommand(int streamType, int index, int flags, int device)3095 StreamVolumeCommand(int streamType, int index, int flags, int device) { 3096 mStreamType = streamType; 3097 mIndex = index; 3098 mFlags = flags; 3099 mDevice = device; 3100 } 3101 3102 @Override toString()3103 public String toString() { 3104 return new StringBuilder().append("{streamType=").append(mStreamType).append(",index=") 3105 .append(mIndex).append(",flags=").append(mFlags).append(",device=") 3106 .append(mDevice).append('}').toString(); 3107 } 3108 } 3109 getNewRingerMode(int stream, int index, int flags)3110 private int getNewRingerMode(int stream, int index, int flags) { 3111 // setRingerMode does nothing if the device is single volume,so the value would be unchanged 3112 if (mIsSingleVolume) { 3113 return getRingerModeExternal(); 3114 } 3115 3116 // setting volume on ui sounds stream type also controls silent mode 3117 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 3118 (stream == getUiSoundsStreamType())) { 3119 int newRingerMode; 3120 if (index == 0) { 3121 newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE 3122 : mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT 3123 : AudioManager.RINGER_MODE_NORMAL; 3124 } else { 3125 newRingerMode = AudioManager.RINGER_MODE_NORMAL; 3126 } 3127 return newRingerMode; 3128 } 3129 return getRingerModeExternal(); 3130 } 3131 isAndroidNPlus(String caller)3132 private boolean isAndroidNPlus(String caller) { 3133 try { 3134 final ApplicationInfo applicationInfo = 3135 mContext.getPackageManager().getApplicationInfoAsUser( 3136 caller, 0, UserHandle.getUserId(Binder.getCallingUid())); 3137 if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) { 3138 return true; 3139 } 3140 return false; 3141 } catch (PackageManager.NameNotFoundException e) { 3142 return true; 3143 } 3144 } 3145 wouldToggleZenMode(int newMode)3146 private boolean wouldToggleZenMode(int newMode) { 3147 if (getRingerModeExternal() == AudioManager.RINGER_MODE_SILENT 3148 && newMode != AudioManager.RINGER_MODE_SILENT) { 3149 return true; 3150 } else if (getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT 3151 && newMode == AudioManager.RINGER_MODE_SILENT) { 3152 return true; 3153 } 3154 return false; 3155 } 3156 onSetStreamVolume(int streamType, int index, int flags, int device, String caller, boolean hasModifyAudioSettings)3157 private void onSetStreamVolume(int streamType, int index, int flags, int device, 3158 String caller, boolean hasModifyAudioSettings) { 3159 final int stream = mStreamVolumeAlias[streamType]; 3160 setStreamVolumeInt(stream, index, device, false, caller, hasModifyAudioSettings); 3161 // setting volume on ui sounds stream type also controls silent mode 3162 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 3163 (stream == getUiSoundsStreamType())) { 3164 setRingerMode(getNewRingerMode(stream, index, flags), 3165 TAG + ".onSetStreamVolume", false /*external*/); 3166 } 3167 // setting non-zero volume for a muted stream unmutes the stream and vice versa, 3168 // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements 3169 if (streamType != AudioSystem.STREAM_BLUETOOTH_SCO) { 3170 mStreamStates[stream].mute(index == 0); 3171 } 3172 } 3173 enforceModifyAudioRoutingPermission()3174 private void enforceModifyAudioRoutingPermission() { 3175 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 3176 != PackageManager.PERMISSION_GRANTED) { 3177 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission"); 3178 } 3179 } 3180 enforceQueryStateOrModifyRoutingPermission()3181 private void enforceQueryStateOrModifyRoutingPermission() { 3182 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) 3183 != PackageManager.PERMISSION_GRANTED 3184 && mContext.checkCallingOrSelfPermission(Manifest.permission.QUERY_AUDIO_STATE) 3185 != PackageManager.PERMISSION_GRANTED) { 3186 throw new SecurityException( 3187 "Missing MODIFY_AUDIO_ROUTING or QUERY_AUDIO_STATE permissions"); 3188 } 3189 } 3190 3191 /** @see AudioManager#setVolumeIndexForAttributes(attr, int, int) */ setVolumeIndexForAttributes(@onNull AudioAttributes attr, int index, int flags, String callingPackage)3192 public void setVolumeIndexForAttributes(@NonNull AudioAttributes attr, int index, int flags, 3193 String callingPackage) { 3194 enforceModifyAudioRoutingPermission(); 3195 Objects.requireNonNull(attr, "attr must not be null"); 3196 final int volumeGroup = getVolumeGroupIdForAttributes(attr); 3197 if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) { 3198 Log.e(TAG, ": no volume group found for attributes " + attr.toString()); 3199 return; 3200 } 3201 final VolumeGroupState vgs = sVolumeGroupStates.get(volumeGroup); 3202 3203 sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, attr, vgs.name(), 3204 index/*val1*/, flags/*val2*/, callingPackage)); 3205 3206 vgs.setVolumeIndex(index, flags); 3207 3208 // For legacy reason, propagate to all streams associated to this volume group 3209 for (final int groupedStream : vgs.getLegacyStreamTypes()) { 3210 try { 3211 ensureValidStreamType(groupedStream); 3212 } catch (IllegalArgumentException e) { 3213 Log.d(TAG, "volume group " + volumeGroup + " has internal streams (" + groupedStream 3214 + "), do not change associated stream volume"); 3215 continue; 3216 } 3217 setStreamVolume(groupedStream, index, flags, callingPackage, callingPackage, 3218 Binder.getCallingUid(), true /*hasModifyAudioSettings*/); 3219 } 3220 } 3221 3222 @Nullable getAudioVolumeGroupById(int volumeGroupId)3223 private AudioVolumeGroup getAudioVolumeGroupById(int volumeGroupId) { 3224 for (final AudioVolumeGroup avg : AudioVolumeGroup.getAudioVolumeGroups()) { 3225 if (avg.getId() == volumeGroupId) { 3226 return avg; 3227 } 3228 } 3229 3230 Log.e(TAG, ": invalid volume group id: " + volumeGroupId + " requested"); 3231 return null; 3232 } 3233 3234 /** @see AudioManager#getVolumeIndexForAttributes(attr) */ getVolumeIndexForAttributes(@onNull AudioAttributes attr)3235 public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) { 3236 enforceModifyAudioRoutingPermission(); 3237 Objects.requireNonNull(attr, "attr must not be null"); 3238 final int volumeGroup = getVolumeGroupIdForAttributes(attr); 3239 if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) { 3240 throw new IllegalArgumentException("No volume group for attributes " + attr); 3241 } 3242 final VolumeGroupState vgs = sVolumeGroupStates.get(volumeGroup); 3243 return vgs.getVolumeIndex(); 3244 } 3245 3246 /** @see AudioManager#getMaxVolumeIndexForAttributes(attr) */ getMaxVolumeIndexForAttributes(@onNull AudioAttributes attr)3247 public int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attr) { 3248 enforceModifyAudioRoutingPermission(); 3249 Objects.requireNonNull(attr, "attr must not be null"); 3250 return AudioSystem.getMaxVolumeIndexForAttributes(attr); 3251 } 3252 3253 /** @see AudioManager#getMinVolumeIndexForAttributes(attr) */ getMinVolumeIndexForAttributes(@onNull AudioAttributes attr)3254 public int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attr) { 3255 enforceModifyAudioRoutingPermission(); 3256 Objects.requireNonNull(attr, "attr must not be null"); 3257 return AudioSystem.getMinVolumeIndexForAttributes(attr); 3258 } 3259 3260 /** @see AudioManager#setStreamVolume(int, int, int) 3261 * Part of service interface, check permissions here */ setStreamVolume(int streamType, int index, int flags, String callingPackage)3262 public void setStreamVolume(int streamType, int index, int flags, String callingPackage) { 3263 if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { 3264 Log.w(TAG, "Trying to call setStreamVolume() for a11y without" 3265 + " CHANGE_ACCESSIBILITY_VOLUME callingPackage=" + callingPackage); 3266 return; 3267 } 3268 if ((streamType == AudioManager.STREAM_VOICE_CALL) && (index == 0) 3269 && (mContext.checkCallingOrSelfPermission( 3270 android.Manifest.permission.MODIFY_PHONE_STATE) 3271 != PackageManager.PERMISSION_GRANTED)) { 3272 Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL and index 0 without" 3273 + " MODIFY_PHONE_STATE callingPackage=" + callingPackage); 3274 return; 3275 } 3276 if ((streamType == AudioManager.STREAM_ASSISTANT) 3277 && (mContext.checkCallingOrSelfPermission( 3278 android.Manifest.permission.MODIFY_AUDIO_ROUTING) 3279 != PackageManager.PERMISSION_GRANTED)) { 3280 Log.w(TAG, "Trying to call setStreamVolume() for STREAM_ASSISTANT without" 3281 + " MODIFY_AUDIO_ROUTING callingPackage=" + callingPackage); 3282 return; 3283 } 3284 3285 sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType, 3286 index/*val1*/, flags/*val2*/, callingPackage)); 3287 setStreamVolume(streamType, index, flags, callingPackage, callingPackage, 3288 Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission()); 3289 } 3290 canChangeAccessibilityVolume()3291 private boolean canChangeAccessibilityVolume() { 3292 synchronized (mAccessibilityServiceUidsLock) { 3293 if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 3294 android.Manifest.permission.CHANGE_ACCESSIBILITY_VOLUME)) { 3295 return true; 3296 } 3297 if (mAccessibilityServiceUids != null) { 3298 int callingUid = Binder.getCallingUid(); 3299 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 3300 if (mAccessibilityServiceUids[i] == callingUid) { 3301 return true; 3302 } 3303 } 3304 } 3305 return false; 3306 } 3307 } 3308 getHearingAidStreamType()3309 /*package*/ int getHearingAidStreamType() { 3310 return getHearingAidStreamType(mMode.get()); 3311 } 3312 getHearingAidStreamType(int mode)3313 private int getHearingAidStreamType(int mode) { 3314 switch (mode) { 3315 case AudioSystem.MODE_IN_COMMUNICATION: 3316 case AudioSystem.MODE_IN_CALL: 3317 return AudioSystem.STREAM_VOICE_CALL; 3318 case AudioSystem.MODE_NORMAL: 3319 default: 3320 // other conditions will influence the stream type choice, read on... 3321 break; 3322 } 3323 if (mVoicePlaybackActive.get()) { 3324 return AudioSystem.STREAM_VOICE_CALL; 3325 } 3326 return AudioSystem.STREAM_MUSIC; 3327 } 3328 3329 private AtomicBoolean mVoicePlaybackActive = new AtomicBoolean(false); 3330 3331 private final IPlaybackConfigDispatcher mVoicePlaybackActivityMonitor = 3332 new IPlaybackConfigDispatcher.Stub() { 3333 @Override 3334 public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs, 3335 boolean flush) { 3336 sendMsg(mAudioHandler, MSG_PLAYBACK_CONFIG_CHANGE, SENDMSG_REPLACE, 3337 0 /*arg1 ignored*/, 0 /*arg2 ignored*/, 3338 configs /*obj*/, 0 /*delay*/); 3339 } 3340 }; 3341 onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs)3342 private void onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) { 3343 boolean voiceActive = false; 3344 for (AudioPlaybackConfiguration config : configs) { 3345 final int usage = config.getAudioAttributes().getUsage(); 3346 if ((usage == AudioAttributes.USAGE_VOICE_COMMUNICATION 3347 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) 3348 && config.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) { 3349 voiceActive = true; 3350 break; 3351 } 3352 } 3353 if (mVoicePlaybackActive.getAndSet(voiceActive) != voiceActive) { 3354 updateHearingAidVolumeOnVoiceActivityUpdate(); 3355 } 3356 3357 // Update playback active state for all apps in audio mode stack. 3358 // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE 3359 // and request an audio mode update immediately. Upon any other change, queue the message 3360 // and request an audio mode update after a grace period. 3361 synchronized (mDeviceBroker.mSetModeLock) { 3362 boolean updateAudioMode = false; 3363 int existingMsgPolicy = SENDMSG_QUEUE; 3364 int delay = CHECK_MODE_FOR_UID_PERIOD_MS; 3365 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 3366 boolean wasActive = h.isActive(); 3367 h.setPlaybackActive(false); 3368 for (AudioPlaybackConfiguration config : configs) { 3369 final int usage = config.getAudioAttributes().getUsage(); 3370 if (config.getClientUid() == h.getUid() 3371 && (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION 3372 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) 3373 && config.getPlayerState() 3374 == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) { 3375 h.setPlaybackActive(true); 3376 break; 3377 } 3378 } 3379 if (wasActive != h.isActive()) { 3380 updateAudioMode = true; 3381 if (h.isActive() && h == getAudioModeOwnerHandler()) { 3382 existingMsgPolicy = SENDMSG_REPLACE; 3383 delay = 0; 3384 } 3385 } 3386 } 3387 if (updateAudioMode) { 3388 sendMsg(mAudioHandler, 3389 MSG_UPDATE_AUDIO_MODE, 3390 existingMsgPolicy, 3391 AudioSystem.MODE_CURRENT, 3392 android.os.Process.myPid(), 3393 mContext.getPackageName(), 3394 delay); 3395 } 3396 } 3397 } 3398 3399 private final IRecordingConfigDispatcher mVoiceRecordingActivityMonitor = 3400 new IRecordingConfigDispatcher.Stub() { 3401 @Override 3402 public void dispatchRecordingConfigChange(List<AudioRecordingConfiguration> configs) { 3403 sendMsg(mAudioHandler, MSG_RECORDING_CONFIG_CHANGE, SENDMSG_REPLACE, 3404 0 /*arg1 ignored*/, 0 /*arg2 ignored*/, 3405 configs /*obj*/, 0 /*delay*/); 3406 } 3407 }; 3408 onRecordingConfigChange(List<AudioRecordingConfiguration> configs)3409 private void onRecordingConfigChange(List<AudioRecordingConfiguration> configs) { 3410 // Update recording active state for all apps in audio mode stack. 3411 // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE 3412 // and request an audio mode update immediately. Upon any other change, queue the message 3413 // and request an audio mode update after a grace period. 3414 synchronized (mDeviceBroker.mSetModeLock) { 3415 boolean updateAudioMode = false; 3416 int existingMsgPolicy = SENDMSG_QUEUE; 3417 int delay = CHECK_MODE_FOR_UID_PERIOD_MS; 3418 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 3419 boolean wasActive = h.isActive(); 3420 h.setRecordingActive(false); 3421 for (AudioRecordingConfiguration config : configs) { 3422 if (config.getClientUid() == h.getUid() 3423 && config.getAudioSource() == AudioSource.VOICE_COMMUNICATION) { 3424 h.setRecordingActive(true); 3425 break; 3426 } 3427 } 3428 if (wasActive != h.isActive()) { 3429 updateAudioMode = true; 3430 if (h.isActive() && h == getAudioModeOwnerHandler()) { 3431 existingMsgPolicy = SENDMSG_REPLACE; 3432 delay = 0; 3433 } 3434 } 3435 } 3436 if (updateAudioMode) { 3437 sendMsg(mAudioHandler, 3438 MSG_UPDATE_AUDIO_MODE, 3439 existingMsgPolicy, 3440 AudioSystem.MODE_CURRENT, 3441 android.os.Process.myPid(), 3442 mContext.getPackageName(), 3443 delay); 3444 } 3445 } 3446 } 3447 dumpAudioMode(PrintWriter pw)3448 private void dumpAudioMode(PrintWriter pw) { 3449 pw.println("\nAudio mode: "); 3450 pw.println("- Requested mode = " + AudioSystem.modeToString(getMode())); 3451 pw.println("- Actual mode = " + AudioSystem.modeToString(mMode.get())); 3452 pw.println("- Mode owner: "); 3453 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 3454 if (hdlr != null) { 3455 hdlr.dump(pw, -1); 3456 } else { 3457 pw.println(" None"); 3458 } 3459 pw.println("- Mode owner stack: "); 3460 if (mSetModeDeathHandlers.isEmpty()) { 3461 pw.println(" Empty"); 3462 } else { 3463 for (int i = 0; i < mSetModeDeathHandlers.size(); i++) { 3464 mSetModeDeathHandlers.get(i).dump(pw, i); 3465 } 3466 } 3467 } 3468 updateHearingAidVolumeOnVoiceActivityUpdate()3469 private void updateHearingAidVolumeOnVoiceActivityUpdate() { 3470 final int streamType = getHearingAidStreamType(); 3471 final int index = getStreamVolume(streamType); 3472 sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_HEARING_AID, 3473 mVoicePlaybackActive.get(), streamType, index)); 3474 mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType); 3475 3476 } 3477 3478 /** 3479 * Manage an audio mode change for audio devices that use an "absolute volume" model, 3480 * i.e. the framework sends the full scale signal, and the actual volume for the use case 3481 * is communicated separately. 3482 */ updateAbsVolumeMultiModeDevices(int oldMode, int newMode)3483 void updateAbsVolumeMultiModeDevices(int oldMode, int newMode) { 3484 if (oldMode == newMode) { 3485 return; 3486 } 3487 switch (newMode) { 3488 case AudioSystem.MODE_IN_COMMUNICATION: 3489 case AudioSystem.MODE_IN_CALL: 3490 case AudioSystem.MODE_NORMAL: 3491 break; 3492 case AudioSystem.MODE_RINGTONE: 3493 // not changing anything for ringtone 3494 return; 3495 case AudioSystem.MODE_CURRENT: 3496 case AudioSystem.MODE_INVALID: 3497 default: 3498 // don't know what to do in this case, better bail 3499 return; 3500 } 3501 3502 int streamType = getHearingAidStreamType(newMode); 3503 3504 final Set<Integer> deviceTypes = AudioSystem.generateAudioDeviceTypesSet( 3505 mAudioSystem.getDevicesForStream(streamType)); 3506 final Set<Integer> absVolumeMultiModeCaseDevices = AudioSystem.intersectionAudioDeviceTypes( 3507 mAbsVolumeMultiModeCaseDevices, deviceTypes); 3508 if (absVolumeMultiModeCaseDevices.isEmpty()) { 3509 return; 3510 } 3511 3512 // handling of specific interfaces goes here: 3513 if (AudioSystem.isSingleAudioDeviceType( 3514 absVolumeMultiModeCaseDevices, AudioSystem.DEVICE_OUT_HEARING_AID)) { 3515 final int index = getStreamVolume(streamType); 3516 sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID, 3517 newMode, streamType, index)); 3518 mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType); 3519 } 3520 } 3521 setStreamVolume(int streamType, int index, int flags, String callingPackage, String caller, int uid, boolean hasModifyAudioSettings)3522 private void setStreamVolume(int streamType, int index, int flags, String callingPackage, 3523 String caller, int uid, boolean hasModifyAudioSettings) { 3524 if (DEBUG_VOL) { 3525 Log.d(TAG, "setStreamVolume(stream=" + streamType+", index=" + index 3526 + ", calling=" + callingPackage + ")"); 3527 } 3528 if (mUseFixedVolume) { 3529 return; 3530 } 3531 3532 ensureValidStreamType(streamType); 3533 int streamTypeAlias = mStreamVolumeAlias[streamType]; 3534 VolumeStreamState streamState = mStreamStates[streamTypeAlias]; 3535 3536 final int device = getDeviceForStream(streamType); 3537 int oldIndex; 3538 3539 // skip a2dp absolute volume control request when the device 3540 // is not an a2dp device 3541 if (!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 3542 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { 3543 return; 3544 } 3545 // If we are being called by the system (e.g. hardware keys) check for current user 3546 // so we handle user restrictions correctly. 3547 if (uid == android.os.Process.SYSTEM_UID) { 3548 uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); 3549 } 3550 if (mAppOps.noteOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage) 3551 != AppOpsManager.MODE_ALLOWED) { 3552 return; 3553 } 3554 3555 if (isAndroidNPlus(callingPackage) 3556 && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags)) 3557 && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) { 3558 throw new SecurityException("Not allowed to change Do Not Disturb state"); 3559 } 3560 3561 if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) { 3562 return; 3563 } 3564 3565 synchronized (mSafeMediaVolumeStateLock) { 3566 // reset any pending volume command 3567 mPendingVolumeCommand = null; 3568 3569 oldIndex = streamState.getIndex(device); 3570 3571 index = rescaleIndex(index * 10, streamType, streamTypeAlias); 3572 3573 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 3574 && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 3575 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 3576 if (DEBUG_VOL) { 3577 Log.d(TAG, "setStreamVolume postSetAvrcpAbsoluteVolumeIndex index=" + index 3578 + "stream=" + streamType); 3579 } 3580 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10); 3581 } 3582 3583 if (device == AudioSystem.DEVICE_OUT_HEARING_AID 3584 && streamType == getHearingAidStreamType()) { 3585 Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index 3586 + " stream=" + streamType); 3587 mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType); 3588 } 3589 3590 if (streamTypeAlias == AudioSystem.STREAM_MUSIC) { 3591 setSystemAudioVolume(oldIndex, index, getStreamMaxVolume(streamType), flags); 3592 } 3593 3594 flags &= ~AudioManager.FLAG_FIXED_VOLUME; 3595 if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) { 3596 flags |= AudioManager.FLAG_FIXED_VOLUME; 3597 3598 // volume is either 0 or max allowed for fixed volume devices 3599 if (index != 0) { 3600 if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE && 3601 mSafeMediaVolumeDevices.contains(device)) { 3602 index = safeMediaVolumeIndex(device); 3603 } else { 3604 index = streamState.getMaxIndex(); 3605 } 3606 } 3607 } 3608 3609 if (!checkSafeMediaVolume(streamTypeAlias, index, device)) { 3610 mVolumeController.postDisplaySafeVolumeWarning(flags); 3611 mPendingVolumeCommand = new StreamVolumeCommand( 3612 streamType, index, flags, device); 3613 } else { 3614 onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings); 3615 index = mStreamStates[streamType].getIndex(device); 3616 } 3617 } 3618 synchronized (mHdmiClientLock) { 3619 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 3620 && (oldIndex != index)) { 3621 maybeSendSystemAudioStatusCommand(false); 3622 } 3623 } 3624 sendVolumeUpdate(streamType, oldIndex, index, flags, device); 3625 } 3626 3627 3628 getVolumeGroupIdForAttributes(@onNull AudioAttributes attributes)3629 private int getVolumeGroupIdForAttributes(@NonNull AudioAttributes attributes) { 3630 Objects.requireNonNull(attributes, "attributes must not be null"); 3631 int volumeGroupId = getVolumeGroupIdForAttributesInt(attributes); 3632 if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) { 3633 return volumeGroupId; 3634 } 3635 // The default volume group is the one hosted by default product strategy, i.e. 3636 // supporting Default Attributes 3637 return getVolumeGroupIdForAttributesInt(AudioProductStrategy.sDefaultAttributes); 3638 } 3639 getVolumeGroupIdForAttributesInt(@onNull AudioAttributes attributes)3640 private int getVolumeGroupIdForAttributesInt(@NonNull AudioAttributes attributes) { 3641 Objects.requireNonNull(attributes, "attributes must not be null"); 3642 for (final AudioProductStrategy productStrategy : 3643 AudioProductStrategy.getAudioProductStrategies()) { 3644 int volumeGroupId = productStrategy.getVolumeGroupIdForAudioAttributes(attributes); 3645 if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) { 3646 return volumeGroupId; 3647 } 3648 } 3649 return AudioVolumeGroup.DEFAULT_VOLUME_GROUP; 3650 } 3651 3652 3653 // No ringer or zen muted stream volumes can be changed unless it'll exit dnd volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags)3654 private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) { 3655 switch (mNm.getZenMode()) { 3656 case Settings.Global.ZEN_MODE_OFF: 3657 return true; 3658 case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: 3659 case Settings.Global.ZEN_MODE_ALARMS: 3660 case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: 3661 return !isStreamMutedByRingerOrZenMode(streamTypeAlias) 3662 || isUiSoundsStreamType(streamTypeAlias) 3663 || (flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0; 3664 } 3665 3666 return true; 3667 } 3668 3669 /** @see AudioManager#forceVolumeControlStream(int) */ forceVolumeControlStream(int streamType, IBinder cb)3670 public void forceVolumeControlStream(int streamType, IBinder cb) { 3671 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) 3672 != PackageManager.PERMISSION_GRANTED) { 3673 return; 3674 } 3675 if (DEBUG_VOL) { Log.d(TAG, String.format("forceVolumeControlStream(%d)", streamType)); } 3676 synchronized(mForceControlStreamLock) { 3677 if (mVolumeControlStream != -1 && streamType != -1) { 3678 mUserSelectedVolumeControlStream = true; 3679 } 3680 mVolumeControlStream = streamType; 3681 if (mVolumeControlStream == -1) { 3682 if (mForceControlStreamClient != null) { 3683 mForceControlStreamClient.release(); 3684 mForceControlStreamClient = null; 3685 } 3686 mUserSelectedVolumeControlStream = false; 3687 } else { 3688 if (null == mForceControlStreamClient) { 3689 mForceControlStreamClient = new ForceControlStreamClient(cb); 3690 } else { 3691 if (mForceControlStreamClient.getBinder() == cb) { 3692 Log.d(TAG, "forceVolumeControlStream cb:" + cb + " is already linked."); 3693 } else { 3694 mForceControlStreamClient.release(); 3695 mForceControlStreamClient = new ForceControlStreamClient(cb); 3696 } 3697 } 3698 } 3699 } 3700 } 3701 3702 private class ForceControlStreamClient implements IBinder.DeathRecipient { 3703 private IBinder mCb; // To be notified of client's death 3704 ForceControlStreamClient(IBinder cb)3705 ForceControlStreamClient(IBinder cb) { 3706 if (cb != null) { 3707 try { 3708 cb.linkToDeath(this, 0); 3709 } catch (RemoteException e) { 3710 // Client has died! 3711 Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death"); 3712 cb = null; 3713 } 3714 } 3715 mCb = cb; 3716 } 3717 binderDied()3718 public void binderDied() { 3719 synchronized(mForceControlStreamLock) { 3720 Log.w(TAG, "SCO client died"); 3721 if (mForceControlStreamClient != this) { 3722 Log.w(TAG, "unregistered control stream client died"); 3723 } else { 3724 mForceControlStreamClient = null; 3725 mVolumeControlStream = -1; 3726 mUserSelectedVolumeControlStream = false; 3727 } 3728 } 3729 } 3730 release()3731 public void release() { 3732 if (mCb != null) { 3733 mCb.unlinkToDeath(this, 0); 3734 mCb = null; 3735 } 3736 } 3737 getBinder()3738 public IBinder getBinder() { 3739 return mCb; 3740 } 3741 } 3742 sendBroadcastToAll(Intent intent)3743 private void sendBroadcastToAll(Intent intent) { 3744 if (!mSystemServer.isPrivileged()) { 3745 return; 3746 } 3747 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 3748 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 3749 final long ident = Binder.clearCallingIdentity(); 3750 try { 3751 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 3752 } finally { 3753 Binder.restoreCallingIdentity(ident); 3754 } 3755 } 3756 sendStickyBroadcastToAll(Intent intent)3757 private void sendStickyBroadcastToAll(Intent intent) { 3758 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 3759 final long ident = Binder.clearCallingIdentity(); 3760 try { 3761 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 3762 } finally { 3763 Binder.restoreCallingIdentity(ident); 3764 } 3765 } 3766 getCurrentUserId()3767 private int getCurrentUserId() { 3768 final long ident = Binder.clearCallingIdentity(); 3769 try { 3770 UserInfo currentUser = ActivityManager.getService().getCurrentUser(); 3771 return currentUser.id; 3772 } catch (RemoteException e) { 3773 // Activity manager not running, nothing we can do assume user 0. 3774 } finally { 3775 Binder.restoreCallingIdentity(ident); 3776 } 3777 return UserHandle.USER_SYSTEM; 3778 } 3779 3780 // UI update and Broadcast Intent sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)3781 protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device) 3782 { 3783 streamType = mStreamVolumeAlias[streamType]; 3784 3785 if (streamType == AudioSystem.STREAM_MUSIC) { 3786 flags = updateFlagsForTvPlatform(flags); 3787 if (isFullVolumeDevice(device)) { 3788 flags &= ~AudioManager.FLAG_SHOW_UI; 3789 } 3790 } 3791 mVolumeController.postVolumeChanged(streamType, flags); 3792 } 3793 3794 // Don't show volume UI when: 3795 // - Hdmi-CEC system audio mode is on and we are a TV panel updateFlagsForTvPlatform(int flags)3796 private int updateFlagsForTvPlatform(int flags) { 3797 synchronized (mHdmiClientLock) { 3798 if (mHdmiTvClient != null && mHdmiSystemAudioSupported 3799 && mHdmiCecVolumeControlEnabled) { 3800 flags &= ~AudioManager.FLAG_SHOW_UI; 3801 } 3802 } 3803 return flags; 3804 } 3805 // UI update and Broadcast Intent sendMasterMuteUpdate(boolean muted, int flags)3806 private void sendMasterMuteUpdate(boolean muted, int flags) { 3807 mVolumeController.postMasterMuteChanged(updateFlagsForTvPlatform(flags)); 3808 broadcastMasterMuteStatus(muted); 3809 } 3810 broadcastMasterMuteStatus(boolean muted)3811 private void broadcastMasterMuteStatus(boolean muted) { 3812 Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION); 3813 intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, muted); 3814 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 3815 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 3816 sendStickyBroadcastToAll(intent); 3817 } 3818 3819 /** 3820 * Sets the stream state's index, and posts a message to set system volume. 3821 * This will not call out to the UI. Assumes a valid stream type. 3822 * 3823 * @param streamType Type of the stream 3824 * @param index Desired volume index of the stream 3825 * @param device the device whose volume must be changed 3826 * @param force If true, set the volume even if the desired volume is same 3827 * @param caller 3828 * @param hasModifyAudioSettings true if the caller is granted MODIFY_AUDIO_SETTINGS or 3829 * MODIFY_AUDIO_ROUTING permission 3830 * as the current volume. 3831 */ setStreamVolumeInt(int streamType, int index, int device, boolean force, String caller, boolean hasModifyAudioSettings)3832 private void setStreamVolumeInt(int streamType, 3833 int index, 3834 int device, 3835 boolean force, 3836 String caller, boolean hasModifyAudioSettings) { 3837 if (isFullVolumeDevice(device)) { 3838 return; 3839 } 3840 VolumeStreamState streamState = mStreamStates[streamType]; 3841 3842 if (streamState.setIndex(index, device, caller, hasModifyAudioSettings) || force) { 3843 // Post message to set system volume (it in turn will post a message 3844 // to persist). 3845 sendMsg(mAudioHandler, 3846 MSG_SET_DEVICE_VOLUME, 3847 SENDMSG_QUEUE, 3848 device, 3849 0, 3850 streamState, 3851 0); 3852 } 3853 } 3854 setSystemAudioMute(boolean state)3855 private void setSystemAudioMute(boolean state) { 3856 synchronized (mHdmiClientLock) { 3857 if (mHdmiManager == null || mHdmiTvClient == null || !mHdmiSystemAudioSupported) return; 3858 final long token = Binder.clearCallingIdentity(); 3859 try { 3860 mHdmiTvClient.setSystemAudioMute(state); 3861 } finally { 3862 Binder.restoreCallingIdentity(token); 3863 } 3864 } 3865 } 3866 3867 /** get stream mute state. */ isStreamMute(int streamType)3868 public boolean isStreamMute(int streamType) { 3869 if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 3870 streamType = getActiveStreamType(streamType); 3871 } 3872 synchronized (VolumeStreamState.class) { 3873 ensureValidStreamType(streamType); 3874 return mStreamStates[streamType].mIsMuted; 3875 } 3876 } 3877 3878 private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient { 3879 private IBinder mICallback; // To be notified of client's death 3880 RmtSbmxFullVolDeathHandler(IBinder cb)3881 RmtSbmxFullVolDeathHandler(IBinder cb) { 3882 mICallback = cb; 3883 try { 3884 cb.linkToDeath(this, 0/*flags*/); 3885 } catch (RemoteException e) { 3886 Log.e(TAG, "can't link to death", e); 3887 } 3888 } 3889 isHandlerFor(IBinder cb)3890 boolean isHandlerFor(IBinder cb) { 3891 return mICallback.equals(cb); 3892 } 3893 forget()3894 void forget() { 3895 try { 3896 mICallback.unlinkToDeath(this, 0/*flags*/); 3897 } catch (NoSuchElementException e) { 3898 Log.e(TAG, "error unlinking to death", e); 3899 } 3900 } 3901 binderDied()3902 public void binderDied() { 3903 Log.w(TAG, "Recorder with remote submix at full volume died " + mICallback); 3904 forceRemoteSubmixFullVolume(false, mICallback); 3905 } 3906 } 3907 3908 /** 3909 * call must be synchronized on mRmtSbmxFullVolDeathHandlers 3910 * @return true if there is a registered death handler, false otherwise */ discardRmtSbmxFullVolDeathHandlerFor(IBinder cb)3911 private boolean discardRmtSbmxFullVolDeathHandlerFor(IBinder cb) { 3912 Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator(); 3913 while (it.hasNext()) { 3914 final RmtSbmxFullVolDeathHandler handler = it.next(); 3915 if (handler.isHandlerFor(cb)) { 3916 handler.forget(); 3917 mRmtSbmxFullVolDeathHandlers.remove(handler); 3918 return true; 3919 } 3920 } 3921 return false; 3922 } 3923 3924 /** call synchronized on mRmtSbmxFullVolDeathHandlers */ hasRmtSbmxFullVolDeathHandlerFor(IBinder cb)3925 private boolean hasRmtSbmxFullVolDeathHandlerFor(IBinder cb) { 3926 Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator(); 3927 while (it.hasNext()) { 3928 if (it.next().isHandlerFor(cb)) { 3929 return true; 3930 } 3931 } 3932 return false; 3933 } 3934 3935 private int mRmtSbmxFullVolRefCount = 0; 3936 private final ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers = 3937 new ArrayList<RmtSbmxFullVolDeathHandler>(); 3938 forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb)3939 public void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb) { 3940 if (cb == null) { 3941 return; 3942 } 3943 if ((PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 3944 android.Manifest.permission.CAPTURE_AUDIO_OUTPUT))) { 3945 Log.w(TAG, "Trying to call forceRemoteSubmixFullVolume() without CAPTURE_AUDIO_OUTPUT"); 3946 return; 3947 } 3948 synchronized(mRmtSbmxFullVolDeathHandlers) { 3949 boolean applyRequired = false; 3950 if (startForcing) { 3951 if (!hasRmtSbmxFullVolDeathHandlerFor(cb)) { 3952 mRmtSbmxFullVolDeathHandlers.add(new RmtSbmxFullVolDeathHandler(cb)); 3953 if (mRmtSbmxFullVolRefCount == 0) { 3954 mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 3955 mFixedVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 3956 applyRequired = true; 3957 } 3958 mRmtSbmxFullVolRefCount++; 3959 } 3960 } else { 3961 if (discardRmtSbmxFullVolDeathHandlerFor(cb) && (mRmtSbmxFullVolRefCount > 0)) { 3962 mRmtSbmxFullVolRefCount--; 3963 if (mRmtSbmxFullVolRefCount == 0) { 3964 mFullVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 3965 mFixedVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 3966 applyRequired = true; 3967 } 3968 } 3969 } 3970 if (applyRequired) { 3971 // Assumes only STREAM_MUSIC going through DEVICE_OUT_REMOTE_SUBMIX 3972 checkAllFixedVolumeDevices(AudioSystem.STREAM_MUSIC); 3973 mStreamStates[AudioSystem.STREAM_MUSIC].applyAllVolumes(); 3974 } 3975 } 3976 } 3977 setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, int userId)3978 private void setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, 3979 int userId) { 3980 // If we are being called by the system check for user we are going to change 3981 // so we handle user restrictions correctly. 3982 if (uid == android.os.Process.SYSTEM_UID) { 3983 uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 3984 } 3985 // If OP_AUDIO_MASTER_VOLUME is set, disallow unmuting. 3986 if (!mute && mAppOps.noteOp(AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage) 3987 != AppOpsManager.MODE_ALLOWED) { 3988 return; 3989 } 3990 if (userId != UserHandle.getCallingUserId() && 3991 mContext.checkCallingOrSelfPermission( 3992 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 3993 != PackageManager.PERMISSION_GRANTED) { 3994 return; 3995 } 3996 setMasterMuteInternalNoCallerCheck(mute, flags, userId); 3997 } 3998 setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId)3999 private void setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId) { 4000 if (DEBUG_VOL) { 4001 Log.d(TAG, String.format("Master mute %s, %d, user=%d", mute, flags, userId)); 4002 } 4003 if (!isPlatformAutomotive() && mUseFixedVolume) { 4004 // If using fixed volume, we don't mute. 4005 // TODO: remove the isPlatformAutomotive check here. 4006 // The isPlatformAutomotive check is added for safety but may not be necessary. 4007 return; 4008 } 4009 // For automotive, 4010 // - the car service is always running as system user 4011 // - foreground users are non-system users 4012 // Car service is in charge of dispatching the key event include global mute to Android. 4013 // Therefore, the getCurrentUser() is always different to the foreground user. 4014 if ((isPlatformAutomotive() && userId == UserHandle.USER_SYSTEM) 4015 || (getCurrentUserId() == userId)) { 4016 if (mute != AudioSystem.getMasterMute()) { 4017 setSystemAudioMute(mute); 4018 AudioSystem.setMasterMute(mute); 4019 sendMasterMuteUpdate(mute, flags); 4020 } 4021 } 4022 } 4023 4024 /** get global mute state. */ isMasterMute()4025 public boolean isMasterMute() { 4026 return AudioSystem.getMasterMute(); 4027 } 4028 setMasterMute(boolean mute, int flags, String callingPackage, int userId)4029 public void setMasterMute(boolean mute, int flags, String callingPackage, int userId) { 4030 enforceModifyAudioRoutingPermission(); 4031 setMasterMuteInternal(mute, flags, callingPackage, Binder.getCallingUid(), 4032 userId); 4033 } 4034 4035 /** @see AudioManager#getStreamVolume(int) */ getStreamVolume(int streamType)4036 public int getStreamVolume(int streamType) { 4037 ensureValidStreamType(streamType); 4038 int device = getDeviceForStream(streamType); 4039 synchronized (VolumeStreamState.class) { 4040 int index = mStreamStates[streamType].getIndex(device); 4041 4042 // by convention getStreamVolume() returns 0 when a stream is muted. 4043 if (mStreamStates[streamType].mIsMuted) { 4044 index = 0; 4045 } 4046 if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) && 4047 isFixedVolumeDevice(device)) { 4048 index = mStreamStates[streamType].getMaxIndex(); 4049 } 4050 return (index + 5) / 10; 4051 } 4052 } 4053 4054 /** @see AudioManager#getStreamMaxVolume(int) */ getStreamMaxVolume(int streamType)4055 public int getStreamMaxVolume(int streamType) { 4056 ensureValidStreamType(streamType); 4057 return (mStreamStates[streamType].getMaxIndex() + 5) / 10; 4058 } 4059 4060 /** @see AudioManager#getStreamMinVolumeInt(int) 4061 * Part of service interface, check permissions here */ getStreamMinVolume(int streamType)4062 public int getStreamMinVolume(int streamType) { 4063 ensureValidStreamType(streamType); 4064 final boolean isPrivileged = 4065 Binder.getCallingUid() == Process.SYSTEM_UID 4066 || callingHasAudioSettingsPermission() 4067 || (mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_ROUTING) 4068 == PackageManager.PERMISSION_GRANTED); 4069 return (mStreamStates[streamType].getMinIndex(isPrivileged) + 5) / 10; 4070 } 4071 4072 /** Get last audible volume before stream was muted. */ getLastAudibleStreamVolume(int streamType)4073 public int getLastAudibleStreamVolume(int streamType) { 4074 ensureValidStreamType(streamType); 4075 int device = getDeviceForStream(streamType); 4076 return (mStreamStates[streamType].getIndex(device) + 5) / 10; 4077 } 4078 4079 /** @see AudioManager#getUiSoundsStreamType() 4080 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for 4081 * UI Sounds identification. 4082 * Fallback on Voice configuration to ensure correct behavior of DnD feature. 4083 */ getUiSoundsStreamType()4084 public int getUiSoundsStreamType() { 4085 return mUseVolumeGroupAliases ? STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM] 4086 : mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM]; 4087 } 4088 4089 /** 4090 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for 4091 * UI Sounds identification. 4092 * Fallback on Voice configuration to ensure correct behavior of DnD feature. 4093 */ isUiSoundsStreamType(int aliasStreamType)4094 private boolean isUiSoundsStreamType(int aliasStreamType) { 4095 return mUseVolumeGroupAliases 4096 ? STREAM_VOLUME_ALIAS_VOICE[aliasStreamType] 4097 == STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM] 4098 : aliasStreamType == mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM]; 4099 } 4100 4101 /** @see AudioManager#setMicrophoneMute(boolean) */ 4102 @Override setMicrophoneMute(boolean on, String callingPackage, int userId)4103 public void setMicrophoneMute(boolean on, String callingPackage, int userId) { 4104 // If we are being called by the system check for user we are going to change 4105 // so we handle user restrictions correctly. 4106 int uid = Binder.getCallingUid(); 4107 if (uid == android.os.Process.SYSTEM_UID) { 4108 uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 4109 } 4110 MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 4111 .setUid(uid) 4112 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage) 4113 .set(MediaMetrics.Property.EVENT, "setMicrophoneMute") 4114 .set(MediaMetrics.Property.REQUEST, on 4115 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE); 4116 4117 // If OP_MUTE_MICROPHONE is set, disallow unmuting. 4118 if (!on && mAppOps.noteOp(AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage) 4119 != AppOpsManager.MODE_ALLOWED) { 4120 mmi.set(MediaMetrics.Property.EARLY_RETURN, "disallow unmuting").record(); 4121 return; 4122 } 4123 if (!checkAudioSettingsPermission("setMicrophoneMute()")) { 4124 mmi.set(MediaMetrics.Property.EARLY_RETURN, "!checkAudioSettingsPermission").record(); 4125 return; 4126 } 4127 if (userId != UserHandle.getCallingUserId() && 4128 mContext.checkCallingOrSelfPermission( 4129 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 4130 != PackageManager.PERMISSION_GRANTED) { 4131 mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission").record(); 4132 return; 4133 } 4134 mMicMuteFromApi = on; 4135 mmi.record(); // record now, the no caller check will set the mute state. 4136 setMicrophoneMuteNoCallerCheck(userId); 4137 } 4138 4139 /** @see AudioManager#setMicrophoneMuteFromSwitch(boolean) */ setMicrophoneMuteFromSwitch(boolean on)4140 public void setMicrophoneMuteFromSwitch(boolean on) { 4141 int userId = Binder.getCallingUid(); 4142 if (userId != android.os.Process.SYSTEM_UID) { 4143 Log.e(TAG, "setMicrophoneMuteFromSwitch() called from non system user!"); 4144 return; 4145 } 4146 mMicMuteFromSwitch = on; 4147 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 4148 .setUid(userId) 4149 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteFromSwitch") 4150 .set(MediaMetrics.Property.REQUEST, on 4151 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE) 4152 .record(); 4153 setMicrophoneMuteNoCallerCheck(userId); 4154 } 4155 setMicMuteFromSwitchInput()4156 private void setMicMuteFromSwitchInput() { 4157 InputManager im = mContext.getSystemService(InputManager.class); 4158 final int isMicMuted = im.isMicMuted(); 4159 if (isMicMuted != InputManager.SWITCH_STATE_UNKNOWN) { 4160 setMicrophoneMuteFromSwitch(im.isMicMuted() != InputManager.SWITCH_STATE_OFF); 4161 } 4162 } 4163 4164 /** 4165 * Returns the microphone mute state as seen from the native audio system 4166 * @return true if microphone is reported as muted by primary HAL 4167 */ isMicrophoneMuted()4168 public boolean isMicrophoneMuted() { 4169 return mMicMuteFromSystemCached 4170 && (!mMicMuteFromPrivacyToggle 4171 || mMicMuteFromApi || mMicMuteFromRestrictions || mMicMuteFromSwitch); 4172 } 4173 isMicrophoneSupposedToBeMuted()4174 private boolean isMicrophoneSupposedToBeMuted() { 4175 return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi 4176 || mMicMuteFromPrivacyToggle; 4177 } 4178 setMicrophoneMuteNoCallerCheck(int userId)4179 private void setMicrophoneMuteNoCallerCheck(int userId) { 4180 final boolean muted = isMicrophoneSupposedToBeMuted(); 4181 if (DEBUG_VOL) { 4182 Log.d(TAG, String.format("Mic mute %b, user=%d", muted, userId)); 4183 } 4184 // only mute for the current user 4185 if (getCurrentUserId() == userId || userId == android.os.Process.SYSTEM_UID) { 4186 final boolean currentMute = mAudioSystem.isMicrophoneMuted(); 4187 final long identity = Binder.clearCallingIdentity(); 4188 final int ret = mAudioSystem.muteMicrophone(muted); 4189 4190 // update cache with the real state independently from what was set 4191 mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted(); 4192 if (ret != AudioSystem.AUDIO_STATUS_OK) { 4193 Log.e(TAG, "Error changing mic mute state to " + muted + " current:" 4194 + mMicMuteFromSystemCached); 4195 } 4196 4197 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 4198 .setUid(userId) 4199 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteNoCallerCheck") 4200 .set(MediaMetrics.Property.MUTE, mMicMuteFromSystemCached 4201 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 4202 .set(MediaMetrics.Property.REQUEST, muted 4203 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE) 4204 .set(MediaMetrics.Property.STATUS, ret) 4205 .record(); 4206 4207 try { 4208 // send the intent even if there was a failure to change the actual mute state: 4209 // the AudioManager.setMicrophoneMute API doesn't have a return value to 4210 // indicate if the call failed to successfully change the mute state, and receiving 4211 // the intent may be the only time an application can resynchronize its mic mute 4212 // state with the actual system mic mute state 4213 if (muted != currentMute) { 4214 sendMsg(mAudioHandler, MSG_BROADCAST_MICROPHONE_MUTE, 4215 SENDMSG_NOOP, 0, 0, null, 0); 4216 } 4217 } finally { 4218 Binder.restoreCallingIdentity(identity); 4219 } 4220 } 4221 } 4222 4223 @Override getRingerModeExternal()4224 public int getRingerModeExternal() { 4225 synchronized(mSettingsLock) { 4226 return mRingerModeExternal; 4227 } 4228 } 4229 4230 @Override getRingerModeInternal()4231 public int getRingerModeInternal() { 4232 synchronized(mSettingsLock) { 4233 return mRingerMode; 4234 } 4235 } 4236 ensureValidRingerMode(int ringerMode)4237 private void ensureValidRingerMode(int ringerMode) { 4238 if (!isValidRingerMode(ringerMode)) { 4239 throw new IllegalArgumentException("Bad ringer mode " + ringerMode); 4240 } 4241 } 4242 4243 /** @see AudioManager#isValidRingerMode(int) */ isValidRingerMode(int ringerMode)4244 public boolean isValidRingerMode(int ringerMode) { 4245 return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX; 4246 } 4247 setRingerModeExternal(int ringerMode, String caller)4248 public void setRingerModeExternal(int ringerMode, String caller) { 4249 if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode) 4250 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)) { 4251 throw new SecurityException("Not allowed to change Do Not Disturb state"); 4252 } 4253 4254 setRingerMode(ringerMode, caller, true /*external*/); 4255 } 4256 setRingerModeInternal(int ringerMode, String caller)4257 public void setRingerModeInternal(int ringerMode, String caller) { 4258 enforceVolumeController("setRingerModeInternal"); 4259 setRingerMode(ringerMode, caller, false /*external*/); 4260 } 4261 silenceRingerModeInternal(String reason)4262 public void silenceRingerModeInternal(String reason) { 4263 VibrationEffect effect = null; 4264 int ringerMode = AudioManager.RINGER_MODE_SILENT; 4265 int toastText = 0; 4266 4267 int silenceRingerSetting = Settings.Secure.VOLUME_HUSH_OFF; 4268 if (mContext.getResources() 4269 .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) { 4270 silenceRingerSetting = Settings.Secure.getIntForUser(mContentResolver, 4271 Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF, 4272 UserHandle.USER_CURRENT); 4273 } 4274 4275 switch(silenceRingerSetting) { 4276 case VOLUME_HUSH_MUTE: 4277 effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK); 4278 ringerMode = AudioManager.RINGER_MODE_SILENT; 4279 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent; 4280 break; 4281 case VOLUME_HUSH_VIBRATE: 4282 effect = VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK); 4283 ringerMode = AudioManager.RINGER_MODE_VIBRATE; 4284 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate; 4285 break; 4286 } 4287 maybeVibrate(effect, reason); 4288 setRingerModeInternal(ringerMode, reason); 4289 Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT).show(); 4290 } 4291 maybeVibrate(VibrationEffect effect, String reason)4292 private boolean maybeVibrate(VibrationEffect effect, String reason) { 4293 if (!mHasVibrator) { 4294 return false; 4295 } 4296 final boolean hapticsDisabled = Settings.System.getIntForUser(mContext.getContentResolver(), 4297 Settings.System.HAPTIC_FEEDBACK_ENABLED, 0, UserHandle.USER_CURRENT) == 0; 4298 if (hapticsDisabled) { 4299 return false; 4300 } 4301 4302 if (effect == null) { 4303 return false; 4304 } 4305 mVibrator.vibrate(Binder.getCallingUid(), mContext.getOpPackageName(), effect, 4306 reason, VIBRATION_ATTRIBUTES); 4307 return true; 4308 } 4309 setRingerMode(int ringerMode, String caller, boolean external)4310 private void setRingerMode(int ringerMode, String caller, boolean external) { 4311 if (mUseFixedVolume || mIsSingleVolume) { 4312 return; 4313 } 4314 if (caller == null || caller.length() == 0) { 4315 throw new IllegalArgumentException("Bad caller: " + caller); 4316 } 4317 ensureValidRingerMode(ringerMode); 4318 if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { 4319 ringerMode = AudioManager.RINGER_MODE_SILENT; 4320 } 4321 final long identity = Binder.clearCallingIdentity(); 4322 try { 4323 synchronized (mSettingsLock) { 4324 final int ringerModeInternal = getRingerModeInternal(); 4325 final int ringerModeExternal = getRingerModeExternal(); 4326 if (external) { 4327 setRingerModeExt(ringerMode); 4328 if (mRingerModeDelegate != null) { 4329 ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal, 4330 ringerMode, caller, ringerModeInternal, mVolumePolicy); 4331 } 4332 if (ringerMode != ringerModeInternal) { 4333 setRingerModeInt(ringerMode, true /*persist*/); 4334 } 4335 } else /*internal*/ { 4336 if (ringerMode != ringerModeInternal) { 4337 setRingerModeInt(ringerMode, true /*persist*/); 4338 } 4339 if (mRingerModeDelegate != null) { 4340 ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal, 4341 ringerMode, caller, ringerModeExternal, mVolumePolicy); 4342 } 4343 setRingerModeExt(ringerMode); 4344 } 4345 } 4346 } finally { 4347 Binder.restoreCallingIdentity(identity); 4348 } 4349 } 4350 setRingerModeExt(int ringerMode)4351 private void setRingerModeExt(int ringerMode) { 4352 synchronized(mSettingsLock) { 4353 if (ringerMode == mRingerModeExternal) return; 4354 mRingerModeExternal = ringerMode; 4355 } 4356 // Send sticky broadcast 4357 broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode); 4358 } 4359 4360 @GuardedBy("mSettingsLock") muteRingerModeStreams()4361 private void muteRingerModeStreams() { 4362 // Mute stream if not previously muted by ringer mode and (ringer mode 4363 // is not RINGER_MODE_NORMAL OR stream is zen muted) and stream is affected by ringer mode. 4364 // Unmute stream if previously muted by ringer/zen mode and ringer mode 4365 // is RINGER_MODE_NORMAL or stream is not affected by ringer mode. 4366 int numStreamTypes = AudioSystem.getNumStreamTypes(); 4367 4368 if (mNm == null) { 4369 mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 4370 } 4371 4372 final int ringerMode = mRingerMode; // Read ringer mode as reading primitives is atomic 4373 final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE 4374 || ringerMode == AudioManager.RINGER_MODE_SILENT; 4375 final boolean shouldRingSco = ringerMode == AudioManager.RINGER_MODE_VIBRATE 4376 && mDeviceBroker.isBluetoothScoActive(); 4377 // Ask audio policy engine to force use Bluetooth SCO channel if needed 4378 final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid() 4379 + "/" + Binder.getCallingPid(); 4380 sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, AudioSystem.FOR_VIBRATE_RINGING, 4381 shouldRingSco ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE, eventSource, 0); 4382 4383 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 4384 final boolean isMuted = isStreamMutedByRingerOrZenMode(streamType); 4385 final boolean muteAllowedBySco = 4386 !(shouldRingSco && streamType == AudioSystem.STREAM_RING); 4387 final boolean shouldZenMute = shouldZenMuteStream(streamType); 4388 final boolean shouldMute = shouldZenMute || (ringerModeMute 4389 && isStreamAffectedByRingerMode(streamType) && muteAllowedBySco); 4390 if (isMuted == shouldMute) continue; 4391 if (!shouldMute) { 4392 // unmute 4393 // ring and notifications volume should never be 0 when not silenced 4394 if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) { 4395 synchronized (VolumeStreamState.class) { 4396 final VolumeStreamState vss = mStreamStates[streamType]; 4397 for (int i = 0; i < vss.mIndexMap.size(); i++) { 4398 int device = vss.mIndexMap.keyAt(i); 4399 int value = vss.mIndexMap.valueAt(i); 4400 if (value == 0) { 4401 vss.setIndex(10, device, TAG, true /*hasModifyAudioSettings*/); 4402 } 4403 } 4404 // Persist volume for stream ring when it is changed here 4405 final int device = getDeviceForStream(streamType); 4406 sendMsg(mAudioHandler, 4407 MSG_PERSIST_VOLUME, 4408 SENDMSG_QUEUE, 4409 device, 4410 0, 4411 mStreamStates[streamType], 4412 PERSIST_DELAY); 4413 } 4414 } 4415 mStreamStates[streamType].mute(false); 4416 mRingerAndZenModeMutedStreams &= ~(1 << streamType); 4417 } else { 4418 // mute 4419 mStreamStates[streamType].mute(true); 4420 mRingerAndZenModeMutedStreams |= (1 << streamType); 4421 } 4422 } 4423 } 4424 isAlarm(int streamType)4425 private boolean isAlarm(int streamType) { 4426 return streamType == AudioSystem.STREAM_ALARM; 4427 } 4428 isNotificationOrRinger(int streamType)4429 private boolean isNotificationOrRinger(int streamType) { 4430 return streamType == AudioSystem.STREAM_NOTIFICATION 4431 || streamType == AudioSystem.STREAM_RING; 4432 } 4433 isMedia(int streamType)4434 private boolean isMedia(int streamType) { 4435 return streamType == AudioSystem.STREAM_MUSIC; 4436 } 4437 4438 isSystem(int streamType)4439 private boolean isSystem(int streamType) { 4440 return streamType == AudioSystem.STREAM_SYSTEM; 4441 } 4442 setRingerModeInt(int ringerMode, boolean persist)4443 private void setRingerModeInt(int ringerMode, boolean persist) { 4444 final boolean change; 4445 synchronized(mSettingsLock) { 4446 change = mRingerMode != ringerMode; 4447 mRingerMode = ringerMode; 4448 muteRingerModeStreams(); 4449 } 4450 4451 // Post a persist ringer mode msg 4452 if (persist) { 4453 sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE, 4454 SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY); 4455 } 4456 if (change) { 4457 // Send sticky broadcast 4458 broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, ringerMode); 4459 } 4460 } 4461 postUpdateRingerModeServiceInt()4462 /*package*/ void postUpdateRingerModeServiceInt() { 4463 sendMsg(mAudioHandler, MSG_UPDATE_RINGER_MODE, SENDMSG_QUEUE, 0, 0, null, 0); 4464 } 4465 onUpdateRingerModeServiceInt()4466 private void onUpdateRingerModeServiceInt() { 4467 setRingerModeInt(getRingerModeInternal(), false); 4468 } 4469 4470 /** @see AudioManager#shouldVibrate(int) */ shouldVibrate(int vibrateType)4471 public boolean shouldVibrate(int vibrateType) { 4472 if (!mHasVibrator) return false; 4473 4474 switch (getVibrateSetting(vibrateType)) { 4475 4476 case AudioManager.VIBRATE_SETTING_ON: 4477 return getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT; 4478 4479 case AudioManager.VIBRATE_SETTING_ONLY_SILENT: 4480 return getRingerModeExternal() == AudioManager.RINGER_MODE_VIBRATE; 4481 4482 case AudioManager.VIBRATE_SETTING_OFF: 4483 // return false, even for incoming calls 4484 return false; 4485 4486 default: 4487 return false; 4488 } 4489 } 4490 4491 /** @see AudioManager#getVibrateSetting(int) */ getVibrateSetting(int vibrateType)4492 public int getVibrateSetting(int vibrateType) { 4493 if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF; 4494 return (mVibrateSetting >> (vibrateType * 2)) & 3; 4495 } 4496 4497 /** @see AudioManager#setVibrateSetting(int, int) */ setVibrateSetting(int vibrateType, int vibrateSetting)4498 public void setVibrateSetting(int vibrateType, int vibrateSetting) { 4499 4500 if (!mHasVibrator) return; 4501 4502 mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, vibrateType, 4503 vibrateSetting); 4504 4505 // Broadcast change 4506 broadcastVibrateSetting(vibrateType); 4507 4508 } 4509 4510 private class SetModeDeathHandler implements IBinder.DeathRecipient { 4511 private final IBinder mCb; // To be notified of client's death 4512 private final int mPid; 4513 private final int mUid; 4514 private final boolean mIsPrivileged; 4515 private final String mPackage; 4516 private int mMode; 4517 private long mUpdateTime; 4518 private boolean mPlaybackActive = false; 4519 private boolean mRecordingActive = false; 4520 SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, String caller, int mode)4521 SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, 4522 String caller, int mode) { 4523 mMode = mode; 4524 mCb = cb; 4525 mPid = pid; 4526 mUid = uid; 4527 mPackage = caller; 4528 mIsPrivileged = isPrivileged; 4529 mUpdateTime = java.lang.System.currentTimeMillis(); 4530 } 4531 binderDied()4532 public void binderDied() { 4533 synchronized (mDeviceBroker.mSetModeLock) { 4534 Log.w(TAG, "SetModeDeathHandler client died"); 4535 int index = mSetModeDeathHandlers.indexOf(this); 4536 if (index < 0) { 4537 Log.w(TAG, "unregistered SetModeDeathHandler client died"); 4538 } else { 4539 SetModeDeathHandler h = mSetModeDeathHandlers.get(index); 4540 mSetModeDeathHandlers.remove(index); 4541 sendMsg(mAudioHandler, 4542 MSG_UPDATE_AUDIO_MODE, 4543 SENDMSG_QUEUE, 4544 AudioSystem.MODE_CURRENT, 4545 android.os.Process.myPid(), 4546 mContext.getPackageName(), 4547 0); 4548 } 4549 } 4550 } 4551 getPid()4552 public int getPid() { 4553 return mPid; 4554 } 4555 setMode(int mode)4556 public void setMode(int mode) { 4557 mMode = mode; 4558 mUpdateTime = java.lang.System.currentTimeMillis(); 4559 } 4560 getMode()4561 public int getMode() { 4562 return mMode; 4563 } 4564 getBinder()4565 public IBinder getBinder() { 4566 return mCb; 4567 } 4568 getUid()4569 public int getUid() { 4570 return mUid; 4571 } 4572 getPackage()4573 public String getPackage() { 4574 return mPackage; 4575 } 4576 isPrivileged()4577 public boolean isPrivileged() { 4578 return mIsPrivileged; 4579 } 4580 getUpdateTime()4581 public long getUpdateTime() { 4582 return mUpdateTime; 4583 } 4584 setPlaybackActive(boolean active)4585 public void setPlaybackActive(boolean active) { 4586 mPlaybackActive = active; 4587 } 4588 setRecordingActive(boolean active)4589 public void setRecordingActive(boolean active) { 4590 mRecordingActive = active; 4591 } 4592 4593 /** 4594 * An app is considered active if: 4595 * - It is privileged (has MODIFY_PHONE_STATE permission) 4596 * or 4597 * - It requests mode MODE_IN_COMMUNICATION, and it is either playing 4598 * or recording for VOICE_COMMUNICATION. 4599 * or 4600 * - It requests a mode different from MODE_IN_COMMUNICATION or MODE_NORMAL 4601 */ isActive()4602 public boolean isActive() { 4603 return mIsPrivileged 4604 || ((mMode == AudioSystem.MODE_IN_COMMUNICATION) 4605 && (mRecordingActive || mPlaybackActive)) 4606 || mMode == AudioSystem.MODE_IN_CALL 4607 || mMode == AudioSystem.MODE_RINGTONE 4608 || mMode == AudioSystem.MODE_CALL_SCREENING; 4609 } 4610 dump(PrintWriter pw, int index)4611 public void dump(PrintWriter pw, int index) { 4612 SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss:SSS"); 4613 4614 if (index >= 0) { 4615 pw.println(" Requester # " + (index + 1) + ":"); 4616 } 4617 pw.println(" - Mode: " + AudioSystem.modeToString(mMode)); 4618 pw.println(" - Binder: " + mCb); 4619 pw.println(" - Pid: " + mPid); 4620 pw.println(" - Uid: " + mUid); 4621 pw.println(" - Package: " + mPackage); 4622 pw.println(" - Privileged: " + mIsPrivileged); 4623 pw.println(" - Active: " + isActive()); 4624 pw.println(" Playback active: " + mPlaybackActive); 4625 pw.println(" Recording active: " + mRecordingActive); 4626 pw.println(" - update time: " + format.format(new Date(mUpdateTime))); 4627 } 4628 } 4629 4630 @GuardedBy("mDeviceBroker.mSetModeLock") getAudioModeOwnerHandler()4631 private SetModeDeathHandler getAudioModeOwnerHandler() { 4632 // The Audio mode owner is: 4633 // 1) the most recent privileged app in the stack 4634 // 2) the most recent active app in the tack 4635 SetModeDeathHandler modeOwner = null; 4636 SetModeDeathHandler privilegedModeOwner = null; 4637 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 4638 if (h.isActive()) { 4639 // privileged apps are always active 4640 if (h.isPrivileged()) { 4641 if (privilegedModeOwner == null 4642 || h.getUpdateTime() > privilegedModeOwner.getUpdateTime()) { 4643 privilegedModeOwner = h; 4644 } 4645 } else { 4646 if (modeOwner == null 4647 || h.getUpdateTime() > modeOwner.getUpdateTime()) { 4648 modeOwner = h; 4649 } 4650 } 4651 } 4652 } 4653 return privilegedModeOwner != null ? privilegedModeOwner : modeOwner; 4654 } 4655 4656 /** 4657 * Return the pid of the current audio mode owner 4658 * @return 0 if nobody owns the mode 4659 */ 4660 @GuardedBy("mDeviceBroker.mSetModeLock") getModeOwnerPid()4661 /*package*/ int getModeOwnerPid() { 4662 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 4663 if (hdlr != null) { 4664 return hdlr.getPid(); 4665 } 4666 return 0; 4667 } 4668 4669 /** 4670 * Return the uid of the current audio mode owner 4671 * @return 0 if nobody owns the mode 4672 */ 4673 @GuardedBy("mDeviceBroker.mSetModeLock") getModeOwnerUid()4674 /*package*/ int getModeOwnerUid() { 4675 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 4676 if (hdlr != null) { 4677 return hdlr.getUid(); 4678 } 4679 return 0; 4680 } 4681 4682 /** @see AudioManager#setMode(int) */ setMode(int mode, IBinder cb, String callingPackage)4683 public void setMode(int mode, IBinder cb, String callingPackage) { 4684 int pid = Binder.getCallingPid(); 4685 int uid = Binder.getCallingUid(); 4686 if (DEBUG_MODE) { 4687 Log.v(TAG, "setMode(mode=" + mode + ", pid=" + pid 4688 + ", uid=" + uid + ", caller=" + callingPackage + ")"); 4689 } 4690 if (!checkAudioSettingsPermission("setMode()")) { 4691 return; 4692 } 4693 if (cb == null) { 4694 Log.e(TAG, "setMode() called with null binder"); 4695 return; 4696 } 4697 if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) { 4698 Log.w(TAG, "setMode() invalid mode: " + mode); 4699 return; 4700 } 4701 4702 if (mode == AudioSystem.MODE_CURRENT) { 4703 mode = getMode(); 4704 } 4705 4706 if (mode == AudioSystem.MODE_CALL_SCREENING && !mIsCallScreeningModeSupported) { 4707 Log.w(TAG, "setMode(MODE_CALL_SCREENING) not permitted " 4708 + "when call screening is not supported"); 4709 return; 4710 } 4711 4712 final boolean hasModifyPhoneStatePermission = mContext.checkCallingOrSelfPermission( 4713 android.Manifest.permission.MODIFY_PHONE_STATE) 4714 == PackageManager.PERMISSION_GRANTED; 4715 if ((mode == AudioSystem.MODE_IN_CALL) && !hasModifyPhoneStatePermission) { 4716 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setMode(MODE_IN_CALL) from pid=" 4717 + pid + ", uid=" + Binder.getCallingUid()); 4718 return; 4719 } 4720 4721 SetModeDeathHandler currentModeHandler = null; 4722 synchronized (mDeviceBroker.mSetModeLock) { 4723 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 4724 if (h.getPid() == pid) { 4725 currentModeHandler = h; 4726 break; 4727 } 4728 } 4729 4730 if (mode == AudioSystem.MODE_NORMAL) { 4731 if (currentModeHandler != null) { 4732 if (!currentModeHandler.isPrivileged() 4733 && currentModeHandler.getMode() == AudioSystem.MODE_IN_COMMUNICATION) { 4734 mAudioHandler.removeEqualMessages( 4735 MSG_CHECK_MODE_FOR_UID, currentModeHandler); 4736 } 4737 mSetModeDeathHandlers.remove(currentModeHandler); 4738 if (DEBUG_MODE) { 4739 Log.v(TAG, "setMode(" + mode + ") removing hldr for pid: " + pid); 4740 } 4741 try { 4742 currentModeHandler.getBinder().unlinkToDeath(currentModeHandler, 0); 4743 } catch (NoSuchElementException e) { 4744 Log.w(TAG, "setMode link does not exist ..."); 4745 } 4746 } 4747 } else { 4748 if (currentModeHandler != null) { 4749 currentModeHandler.setMode(mode); 4750 if (DEBUG_MODE) { 4751 Log.v(TAG, "setMode(" + mode + ") updating hldr for pid: " + pid); 4752 } 4753 } else { 4754 currentModeHandler = new SetModeDeathHandler(cb, pid, uid, 4755 hasModifyPhoneStatePermission, callingPackage, mode); 4756 // Register for client death notification 4757 try { 4758 cb.linkToDeath(currentModeHandler, 0); 4759 } catch (RemoteException e) { 4760 // Client has died! 4761 Log.w(TAG, "setMode() could not link to " + cb + " binder death"); 4762 return; 4763 } 4764 mSetModeDeathHandlers.add(currentModeHandler); 4765 if (DEBUG_MODE) { 4766 Log.v(TAG, "setMode(" + mode + ") adding handler for pid=" + pid); 4767 } 4768 } 4769 if (mode == AudioSystem.MODE_IN_COMMUNICATION) { 4770 // Force active state when entering/updating the stack to avoid glitches when 4771 // an app starts playing/recording after settng the audio mode, 4772 // and send a reminder to check activity after a grace period. 4773 if (!currentModeHandler.isPrivileged()) { 4774 currentModeHandler.setPlaybackActive(true); 4775 currentModeHandler.setRecordingActive(true); 4776 sendMsg(mAudioHandler, 4777 MSG_CHECK_MODE_FOR_UID, 4778 SENDMSG_QUEUE, 4779 0, 4780 0, 4781 currentModeHandler, 4782 CHECK_MODE_FOR_UID_PERIOD_MS); 4783 } 4784 } 4785 } 4786 4787 sendMsg(mAudioHandler, 4788 MSG_UPDATE_AUDIO_MODE, 4789 SENDMSG_REPLACE, 4790 mode, 4791 pid, 4792 callingPackage, 4793 0); 4794 } 4795 } 4796 4797 @GuardedBy("mDeviceBroker.mSetModeLock") onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, boolean force)4798 void onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, 4799 boolean force) { 4800 if (requestedMode == AudioSystem.MODE_CURRENT) { 4801 requestedMode = getMode(); 4802 } 4803 int mode = AudioSystem.MODE_NORMAL; 4804 int uid = 0; 4805 int pid = 0; 4806 SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler(); 4807 if (currentModeHandler != null) { 4808 mode = currentModeHandler.getMode(); 4809 uid = currentModeHandler.getUid(); 4810 pid = currentModeHandler.getPid(); 4811 } 4812 if (DEBUG_MODE) { 4813 Log.v(TAG, "onUpdateAudioMode() new mode: " + mode + ", current mode: " 4814 + mMode.get() + " requested mode: " + requestedMode); 4815 } 4816 if (mode != mMode.get() || force) { 4817 final long identity = Binder.clearCallingIdentity(); 4818 int status = mAudioSystem.setPhoneState(mode, uid); 4819 Binder.restoreCallingIdentity(identity); 4820 if (status == AudioSystem.AUDIO_STATUS_OK) { 4821 if (DEBUG_MODE) { 4822 Log.v(TAG, "onUpdateAudioMode: mode successfully set to " + mode); 4823 } 4824 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_MODE, SENDMSG_REPLACE, mode, 0, 4825 /*obj*/ null, /*delay*/ 0); 4826 int previousMode = mMode.getAndSet(mode); 4827 // Note: newModeOwnerPid is always 0 when actualMode is MODE_NORMAL 4828 mModeLogger.log(new PhoneStateEvent(requesterPackage, requesterPid, 4829 requestedMode, pid, mode)); 4830 4831 int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE); 4832 int device = getDeviceForStream(streamType); 4833 int index = mStreamStates[mStreamVolumeAlias[streamType]].getIndex(device); 4834 setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, true, 4835 requesterPackage, true /*hasModifyAudioSettings*/); 4836 4837 updateStreamVolumeAlias(true /*updateVolumes*/, requesterPackage); 4838 4839 // change of mode may require volume to be re-applied on some devices 4840 updateAbsVolumeMultiModeDevices(previousMode, mode); 4841 4842 // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO 4843 // connections not started by the application changing the mode when pid changes 4844 mDeviceBroker.postSetModeOwnerPid(pid, mode); 4845 } else { 4846 Log.w(TAG, "onUpdateAudioMode: failed to set audio mode to: " + mode); 4847 } 4848 } 4849 } 4850 4851 /** @see AudioManager#getMode() */ getMode()4852 public int getMode() { 4853 synchronized (mDeviceBroker.mSetModeLock) { 4854 SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler(); 4855 if (currentModeHandler != null) { 4856 return currentModeHandler.getMode(); 4857 } 4858 return AudioSystem.MODE_NORMAL; 4859 } 4860 } 4861 4862 /** cached value read from audiopolicy manager after initialization. */ 4863 private boolean mIsCallScreeningModeSupported = false; 4864 4865 /** @see AudioManager#isCallScreeningModeSupported() */ isCallScreeningModeSupported()4866 public boolean isCallScreeningModeSupported() { 4867 return mIsCallScreeningModeSupported; 4868 } 4869 dispatchMode(int mode)4870 protected void dispatchMode(int mode) { 4871 final int nbDispatchers = mModeDispatchers.beginBroadcast(); 4872 for (int i = 0; i < nbDispatchers; i++) { 4873 try { 4874 mModeDispatchers.getBroadcastItem(i).dispatchAudioModeChanged(mode); 4875 } catch (RemoteException e) { 4876 } 4877 } 4878 mModeDispatchers.finishBroadcast(); 4879 } 4880 4881 final RemoteCallbackList<IAudioModeDispatcher> mModeDispatchers = 4882 new RemoteCallbackList<IAudioModeDispatcher>(); 4883 4884 /** 4885 * @see {@link AudioManager#addOnModeChangedListener(Executor, AudioManager.OnModeChangedListener)} 4886 * @param dispatcher 4887 */ registerModeDispatcher( @onNull IAudioModeDispatcher dispatcher)4888 public void registerModeDispatcher( 4889 @NonNull IAudioModeDispatcher dispatcher) { 4890 mModeDispatchers.register(dispatcher); 4891 } 4892 4893 /** 4894 * @see {@link AudioManager#removeOnModeChangedListener(AudioManager.OnModeChangedListener)} 4895 * @param dispatcher 4896 */ unregisterModeDispatcher( @onNull IAudioModeDispatcher dispatcher)4897 public void unregisterModeDispatcher( 4898 @NonNull IAudioModeDispatcher dispatcher) { 4899 mModeDispatchers.unregister(dispatcher); 4900 } 4901 4902 /** @see AudioManager#setRttEnabled() */ 4903 @Override setRttEnabled(boolean rttEnabled)4904 public void setRttEnabled(boolean rttEnabled) { 4905 if (mContext.checkCallingOrSelfPermission( 4906 android.Manifest.permission.MODIFY_PHONE_STATE) 4907 != PackageManager.PERMISSION_GRANTED) { 4908 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setRttEnabled from pid=" 4909 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 4910 return; 4911 } 4912 synchronized (mSettingsLock) { 4913 mRttEnabled = rttEnabled; 4914 final long identity = Binder.clearCallingIdentity(); 4915 try { 4916 AudioSystem.setRttEnabled(rttEnabled); 4917 } finally { 4918 Binder.restoreCallingIdentity(identity); 4919 } 4920 } 4921 } 4922 4923 /** @see AudioManager#adjustSuggestedStreamVolumeForUid(int, int, int, String, int, int, int) */ 4924 @Override adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)4925 public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, 4926 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 4927 int targetSdkVersion) { 4928 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 4929 throw new SecurityException("Should only be called from system process"); 4930 } 4931 4932 // direction and stream type swap here because the public 4933 // adjustSuggested has a different order than the other methods. 4934 adjustSuggestedStreamVolume(direction, streamType, flags, packageName, packageName, uid, 4935 hasAudioSettingsPermission(uid, pid), VOL_ADJUST_NORMAL); 4936 } 4937 4938 /** @see AudioManager#adjustStreamVolumeForUid(int, int, int, String, int, int, int) */ 4939 @Override adjustStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)4940 public void adjustStreamVolumeForUid(int streamType, int direction, int flags, 4941 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 4942 int targetSdkVersion) { 4943 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 4944 throw new SecurityException("Should only be called from system process"); 4945 } 4946 4947 if (direction != AudioManager.ADJUST_SAME) { 4948 sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType, 4949 direction/*val1*/, flags/*val2*/, 4950 new StringBuilder(packageName).append(" uid:").append(uid) 4951 .toString())); 4952 } 4953 4954 adjustStreamVolume(streamType, direction, flags, packageName, packageName, uid, 4955 hasAudioSettingsPermission(uid, pid), VOL_ADJUST_NORMAL); 4956 } 4957 4958 /** @see AudioManager#setStreamVolumeForUid(int, int, int, String, int, int, int) */ 4959 @Override setStreamVolumeForUid(int streamType, int index, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)4960 public void setStreamVolumeForUid(int streamType, int index, int flags, 4961 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 4962 int targetSdkVersion) { 4963 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 4964 throw new SecurityException("Should only be called from system process"); 4965 } 4966 4967 setStreamVolume(streamType, index, flags, packageName, packageName, uid, 4968 hasAudioSettingsPermission(uid, pid)); 4969 } 4970 4971 //========================================================================================== 4972 // Sound Effects 4973 //========================================================================================== 4974 private static final class LoadSoundEffectReply 4975 implements SoundEffectsHelper.OnEffectsLoadCompleteHandler { 4976 private static final int SOUND_EFFECTS_LOADING = 1; 4977 private static final int SOUND_EFFECTS_LOADED = 0; 4978 private static final int SOUND_EFFECTS_ERROR = -1; 4979 private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000; 4980 4981 private int mStatus = SOUND_EFFECTS_LOADING; 4982 4983 @Override run(boolean success)4984 public synchronized void run(boolean success) { 4985 mStatus = success ? SOUND_EFFECTS_LOADED : SOUND_EFFECTS_ERROR; 4986 notify(); 4987 } 4988 waitForLoaded(int attempts)4989 public synchronized boolean waitForLoaded(int attempts) { 4990 while ((mStatus == SOUND_EFFECTS_LOADING) && (attempts-- > 0)) { 4991 try { 4992 wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS); 4993 } catch (InterruptedException e) { 4994 Log.w(TAG, "Interrupted while waiting sound pool loaded."); 4995 } 4996 } 4997 return mStatus == SOUND_EFFECTS_LOADED; 4998 } 4999 } 5000 5001 /** @see AudioManager#playSoundEffect(int) */ playSoundEffect(int effectType)5002 public void playSoundEffect(int effectType) { 5003 playSoundEffectVolume(effectType, -1.0f); 5004 } 5005 5006 /** @see AudioManager#playSoundEffect(int, float) */ playSoundEffectVolume(int effectType, float volume)5007 public void playSoundEffectVolume(int effectType, float volume) { 5008 // do not try to play the sound effect if the system stream is muted 5009 if (isStreamMute(STREAM_SYSTEM)) { 5010 return; 5011 } 5012 5013 if (effectType >= AudioManager.NUM_SOUND_EFFECTS || effectType < 0) { 5014 Log.w(TAG, "AudioService effectType value " + effectType + " out of range"); 5015 return; 5016 } 5017 5018 sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE, 5019 effectType, (int) (volume * 1000), null, 0); 5020 } 5021 5022 /** 5023 * Loads samples into the soundpool. 5024 * This method must be called at first when sound effects are enabled 5025 */ loadSoundEffects()5026 public boolean loadSoundEffects() { 5027 LoadSoundEffectReply reply = new LoadSoundEffectReply(); 5028 sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0); 5029 return reply.waitForLoaded(3 /*attempts*/); 5030 } 5031 5032 /** 5033 * Schedule loading samples into the soundpool. 5034 * This method can be overridden to schedule loading at a later time. 5035 */ scheduleLoadSoundEffects()5036 protected void scheduleLoadSoundEffects() { 5037 sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0); 5038 } 5039 5040 /** 5041 * Unloads samples from the sound pool. 5042 * This method can be called to free some memory when 5043 * sound effects are disabled. 5044 */ unloadSoundEffects()5045 public void unloadSoundEffects() { 5046 sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0); 5047 } 5048 5049 /** @see AudioManager#reloadAudioSettings() */ reloadAudioSettings()5050 public void reloadAudioSettings() { 5051 readAudioSettings(false /*userSwitch*/); 5052 } 5053 readAudioSettings(boolean userSwitch)5054 private void readAudioSettings(boolean userSwitch) { 5055 // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings 5056 readPersistedSettings(); 5057 readUserRestrictions(); 5058 5059 // restore volume settings 5060 int numStreamTypes = AudioSystem.getNumStreamTypes(); 5061 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 5062 VolumeStreamState streamState = mStreamStates[streamType]; 5063 5064 if (userSwitch && mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) { 5065 continue; 5066 } 5067 5068 streamState.readSettings(); 5069 synchronized (VolumeStreamState.class) { 5070 // unmute stream that was muted but is not affect by mute anymore 5071 if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) && 5072 !isStreamMutedByRingerOrZenMode(streamType)) || mUseFixedVolume)) { 5073 streamState.mIsMuted = false; 5074 } 5075 } 5076 } 5077 5078 // apply new ringer mode before checking volume for alias streams so that streams 5079 // muted by ringer mode have the correct volume 5080 setRingerModeInt(getRingerModeInternal(), false); 5081 5082 checkAllFixedVolumeDevices(); 5083 checkAllAliasStreamVolumes(); 5084 checkMuteAffectedStreams(); 5085 5086 synchronized (mSafeMediaVolumeStateLock) { 5087 mMusicActiveMs = MathUtils.constrain(Settings.Secure.getIntForUser(mContentResolver, 5088 Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS, 0, UserHandle.USER_CURRENT), 5089 0, UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX); 5090 if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) { 5091 enforceSafeMediaVolume(TAG); 5092 } 5093 } 5094 5095 readVolumeGroupsSettings(); 5096 5097 if (DEBUG_VOL) { 5098 Log.d(TAG, "Restoring device volume behavior"); 5099 } 5100 restoreDeviceVolumeBehavior(); 5101 } 5102 5103 private static final int[] VALID_COMMUNICATION_DEVICE_TYPES = { 5104 AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, 5105 AudioDeviceInfo.TYPE_BLUETOOTH_SCO, 5106 AudioDeviceInfo.TYPE_WIRED_HEADSET, 5107 AudioDeviceInfo.TYPE_USB_HEADSET, 5108 AudioDeviceInfo.TYPE_BUILTIN_EARPIECE, 5109 AudioDeviceInfo.TYPE_WIRED_HEADPHONES, 5110 AudioDeviceInfo.TYPE_HEARING_AID, 5111 AudioDeviceInfo.TYPE_BLE_HEADSET, 5112 AudioDeviceInfo.TYPE_USB_DEVICE, 5113 AudioDeviceInfo.TYPE_BLE_SPEAKER, 5114 AudioDeviceInfo.TYPE_LINE_ANALOG, 5115 AudioDeviceInfo.TYPE_HDMI, 5116 AudioDeviceInfo.TYPE_AUX_LINE 5117 }; 5118 isValidCommunicationDevice(AudioDeviceInfo device)5119 private boolean isValidCommunicationDevice(AudioDeviceInfo device) { 5120 for (int type : VALID_COMMUNICATION_DEVICE_TYPES) { 5121 if (device.getType() == type) { 5122 return true; 5123 } 5124 } 5125 return false; 5126 } 5127 5128 /** @see AudioManager#getAvailableCommunicationDevices(int) */ getAvailableCommunicationDeviceIds()5129 public int[] getAvailableCommunicationDeviceIds() { 5130 ArrayList<Integer> deviceIds = new ArrayList<>(); 5131 AudioDeviceInfo[] devices = AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_OUTPUTS); 5132 for (AudioDeviceInfo device : devices) { 5133 if (isValidCommunicationDevice(device)) { 5134 deviceIds.add(device.getId()); 5135 } 5136 } 5137 return deviceIds.stream().mapToInt(Integer::intValue).toArray(); 5138 } 5139 /** @see AudioManager#setCommunicationDevice(int) */ setCommunicationDevice(IBinder cb, int portId)5140 public boolean setCommunicationDevice(IBinder cb, int portId) { 5141 final int uid = Binder.getCallingUid(); 5142 final int pid = Binder.getCallingPid(); 5143 5144 AudioDeviceInfo device = null; 5145 if (portId != 0) { 5146 device = AudioManager.getDeviceForPortId(portId, AudioManager.GET_DEVICES_OUTPUTS); 5147 if (device == null) { 5148 throw new IllegalArgumentException("invalid portID " + portId); 5149 } 5150 if (!isValidCommunicationDevice(device)) { 5151 throw new IllegalArgumentException("invalid device type " + device.getType()); 5152 } 5153 } 5154 final String eventSource = new StringBuilder("setCommunicationDevice(") 5155 .append(") from u/pid:").append(uid).append("/") 5156 .append(pid).toString(); 5157 5158 int deviceType = AudioSystem.DEVICE_OUT_DEFAULT; 5159 String deviceAddress = null; 5160 if (device != null) { 5161 deviceType = device.getPort().type(); 5162 deviceAddress = device.getAddress(); 5163 } else { 5164 AudioDeviceInfo curDevice = mDeviceBroker.getCommunicationDevice(); 5165 if (curDevice != null) { 5166 deviceType = curDevice.getPort().type(); 5167 deviceAddress = curDevice.getAddress(); 5168 } 5169 } 5170 // do not log metrics if clearing communication device while no communication device 5171 // was selected 5172 if (deviceType != AudioSystem.DEVICE_OUT_DEFAULT) { 5173 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 5174 + MediaMetrics.SEPARATOR + "setCommunicationDevice") 5175 .set(MediaMetrics.Property.DEVICE, 5176 AudioSystem.getDeviceName(deviceType)) 5177 .set(MediaMetrics.Property.ADDRESS, deviceAddress) 5178 .set(MediaMetrics.Property.STATE, device != null 5179 ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED) 5180 .record(); 5181 } 5182 5183 final long ident = Binder.clearCallingIdentity(); 5184 boolean status = 5185 mDeviceBroker.setCommunicationDevice(cb, pid, device, eventSource); 5186 Binder.restoreCallingIdentity(ident); 5187 return status; 5188 } 5189 5190 /** @see AudioManager#getCommunicationDevice() */ getCommunicationDevice()5191 public int getCommunicationDevice() { 5192 final long ident = Binder.clearCallingIdentity(); 5193 AudioDeviceInfo device = mDeviceBroker.getCommunicationDevice(); 5194 Binder.restoreCallingIdentity(ident); 5195 if (device == null) { 5196 return 0; 5197 } 5198 return device.getId(); 5199 } 5200 5201 /** @see AudioManager#addOnCommunicationDeviceChangedListener( 5202 * Executor, AudioManager.OnCommunicationDeviceChangedListener) 5203 */ registerCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)5204 public void registerCommunicationDeviceDispatcher( 5205 @Nullable ICommunicationDeviceDispatcher dispatcher) { 5206 if (dispatcher == null) { 5207 return; 5208 } 5209 mDeviceBroker.registerCommunicationDeviceDispatcher(dispatcher); 5210 } 5211 5212 /** @see AudioManager#removeOnCommunicationDeviceChangedListener( 5213 * AudioManager.OnCommunicationDeviceChangedListener) 5214 */ unregisterCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)5215 public void unregisterCommunicationDeviceDispatcher( 5216 @Nullable ICommunicationDeviceDispatcher dispatcher) { 5217 if (dispatcher == null) { 5218 return; 5219 } 5220 mDeviceBroker.unregisterCommunicationDeviceDispatcher(dispatcher); 5221 } 5222 5223 /** @see AudioManager#setSpeakerphoneOn(boolean) */ setSpeakerphoneOn(IBinder cb, boolean on)5224 public void setSpeakerphoneOn(IBinder cb, boolean on) { 5225 if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) { 5226 return; 5227 } 5228 5229 // for logging only 5230 final int uid = Binder.getCallingUid(); 5231 final int pid = Binder.getCallingPid(); 5232 5233 final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on) 5234 .append(") from u/pid:").append(uid).append("/") 5235 .append(pid).toString(); 5236 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 5237 + MediaMetrics.SEPARATOR + "setSpeakerphoneOn") 5238 .setUid(uid) 5239 .setPid(pid) 5240 .set(MediaMetrics.Property.STATE, on 5241 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 5242 .record(); 5243 final long ident = Binder.clearCallingIdentity(); 5244 mDeviceBroker.setSpeakerphoneOn(cb, pid, on, eventSource); 5245 Binder.restoreCallingIdentity(ident); 5246 } 5247 5248 /** @see AudioManager#isSpeakerphoneOn() */ isSpeakerphoneOn()5249 public boolean isSpeakerphoneOn() { 5250 return mDeviceBroker.isSpeakerphoneOn(); 5251 } 5252 5253 5254 /** BT SCO audio state seen by apps using the deprecated API setBluetoothScoOn(). 5255 * @see isBluetoothScoOn() */ 5256 private boolean mBtScoOnByApp; 5257 5258 /** @see AudioManager#setBluetoothScoOn(boolean) */ setBluetoothScoOn(boolean on)5259 public void setBluetoothScoOn(boolean on) { 5260 if (!checkAudioSettingsPermission("setBluetoothScoOn()")) { 5261 return; 5262 } 5263 5264 // Only enable calls from system components 5265 if (UserHandle.getCallingAppId() >= FIRST_APPLICATION_UID) { 5266 mBtScoOnByApp = on; 5267 return; 5268 } 5269 5270 // for logging only 5271 final int uid = Binder.getCallingUid(); 5272 final int pid = Binder.getCallingPid(); 5273 final String eventSource = new StringBuilder("setBluetoothScoOn(").append(on) 5274 .append(") from u/pid:").append(uid).append("/").append(pid).toString(); 5275 5276 //bt sco 5277 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 5278 + MediaMetrics.SEPARATOR + "setBluetoothScoOn") 5279 .setUid(uid) 5280 .setPid(pid) 5281 .set(MediaMetrics.Property.STATE, on 5282 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 5283 .record(); 5284 5285 mDeviceBroker.setBluetoothScoOn(on, eventSource); 5286 } 5287 5288 /** @see AudioManager#isBluetoothScoOn() 5289 * Note that it doesn't report internal state, but state seen by apps (which may have 5290 * called setBluetoothScoOn() */ isBluetoothScoOn()5291 public boolean isBluetoothScoOn() { 5292 return mBtScoOnByApp || mDeviceBroker.isBluetoothScoOn(); 5293 } 5294 5295 // TODO investigate internal users due to deprecation of SDK API 5296 /** @see AudioManager#setBluetoothA2dpOn(boolean) */ setBluetoothA2dpOn(boolean on)5297 public void setBluetoothA2dpOn(boolean on) { 5298 // for logging only 5299 final int uid = Binder.getCallingUid(); 5300 final int pid = Binder.getCallingPid(); 5301 final String eventSource = new StringBuilder("setBluetoothA2dpOn(").append(on) 5302 .append(") from u/pid:").append(uid).append("/") 5303 .append(pid).toString(); 5304 5305 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 5306 + MediaMetrics.SEPARATOR + "setBluetoothA2dpOn") 5307 .setUid(uid) 5308 .setPid(pid) 5309 .set(MediaMetrics.Property.STATE, on 5310 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 5311 .record(); 5312 5313 mDeviceBroker.setBluetoothA2dpOn_Async(on, eventSource); 5314 } 5315 5316 /** @see AudioManager#isBluetoothA2dpOn() */ isBluetoothA2dpOn()5317 public boolean isBluetoothA2dpOn() { 5318 return mDeviceBroker.isBluetoothA2dpOn(); 5319 } 5320 5321 /** @see AudioManager#startBluetoothSco() */ startBluetoothSco(IBinder cb, int targetSdkVersion)5322 public void startBluetoothSco(IBinder cb, int targetSdkVersion) { 5323 final int uid = Binder.getCallingUid(); 5324 final int pid = Binder.getCallingPid(); 5325 final int scoAudioMode = 5326 (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ? 5327 BtHelper.SCO_MODE_VIRTUAL_CALL : BtHelper.SCO_MODE_UNDEFINED; 5328 final String eventSource = new StringBuilder("startBluetoothSco()") 5329 .append(") from u/pid:").append(uid).append("/") 5330 .append(pid).toString(); 5331 5332 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 5333 .setUid(uid) 5334 .setPid(pid) 5335 .set(MediaMetrics.Property.EVENT, "startBluetoothSco") 5336 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 5337 BtHelper.scoAudioModeToString(scoAudioMode)) 5338 .record(); 5339 startBluetoothScoInt(cb, pid, scoAudioMode, eventSource); 5340 5341 } 5342 5343 /** @see AudioManager#startBluetoothScoVirtualCall() */ startBluetoothScoVirtualCall(IBinder cb)5344 public void startBluetoothScoVirtualCall(IBinder cb) { 5345 final int uid = Binder.getCallingUid(); 5346 final int pid = Binder.getCallingPid(); 5347 final String eventSource = new StringBuilder("startBluetoothScoVirtualCall()") 5348 .append(") from u/pid:").append(uid).append("/") 5349 .append(pid).toString(); 5350 5351 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 5352 .setUid(uid) 5353 .setPid(pid) 5354 .set(MediaMetrics.Property.EVENT, "startBluetoothScoVirtualCall") 5355 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 5356 BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_VIRTUAL_CALL)) 5357 .record(); 5358 startBluetoothScoInt(cb, pid, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource); 5359 } 5360 startBluetoothScoInt(IBinder cb, int pid, int scoAudioMode, @NonNull String eventSource)5361 void startBluetoothScoInt(IBinder cb, int pid, int scoAudioMode, @NonNull String eventSource) { 5362 MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 5363 .set(MediaMetrics.Property.EVENT, "startBluetoothScoInt") 5364 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 5365 BtHelper.scoAudioModeToString(scoAudioMode)); 5366 5367 if (!checkAudioSettingsPermission("startBluetoothSco()") || 5368 !mSystemReady) { 5369 mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission or systemReady").record(); 5370 return; 5371 } 5372 final long ident = Binder.clearCallingIdentity(); 5373 mDeviceBroker.startBluetoothScoForClient(cb, pid, scoAudioMode, eventSource); 5374 Binder.restoreCallingIdentity(ident); 5375 mmi.record(); 5376 } 5377 5378 /** @see AudioManager#stopBluetoothSco() */ stopBluetoothSco(IBinder cb)5379 public void stopBluetoothSco(IBinder cb){ 5380 if (!checkAudioSettingsPermission("stopBluetoothSco()") || 5381 !mSystemReady) { 5382 return; 5383 } 5384 final int uid = Binder.getCallingUid(); 5385 final int pid = Binder.getCallingPid(); 5386 final String eventSource = new StringBuilder("stopBluetoothSco()") 5387 .append(") from u/pid:").append(uid).append("/") 5388 .append(pid).toString(); 5389 final long ident = Binder.clearCallingIdentity(); 5390 mDeviceBroker.stopBluetoothScoForClient(cb, pid, eventSource); 5391 Binder.restoreCallingIdentity(ident); 5392 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 5393 .setUid(uid) 5394 .setPid(pid) 5395 .set(MediaMetrics.Property.EVENT, "stopBluetoothSco") 5396 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 5397 BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_UNDEFINED)) 5398 .record(); 5399 } 5400 5401 getContentResolver()5402 /*package*/ ContentResolver getContentResolver() { 5403 return mContentResolver; 5404 } 5405 onCheckMusicActive(String caller)5406 private void onCheckMusicActive(String caller) { 5407 synchronized (mSafeMediaVolumeStateLock) { 5408 if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) { 5409 int device = getDeviceForStream(AudioSystem.STREAM_MUSIC); 5410 5411 if (mSafeMediaVolumeDevices.contains(device)) { 5412 sendMsg(mAudioHandler, 5413 MSG_CHECK_MUSIC_ACTIVE, 5414 SENDMSG_REPLACE, 5415 0, 5416 0, 5417 caller, 5418 MUSIC_ACTIVE_POLL_PERIOD_MS); 5419 int index = mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(device); 5420 if (mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0) 5421 && (index > safeMediaVolumeIndex(device))) { 5422 // Approximate cumulative active music time 5423 mMusicActiveMs += MUSIC_ACTIVE_POLL_PERIOD_MS; 5424 if (mMusicActiveMs > UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX) { 5425 setSafeMediaVolumeEnabled(true, caller); 5426 mMusicActiveMs = 0; 5427 } 5428 saveMusicActiveMs(); 5429 } 5430 } 5431 } 5432 } 5433 } 5434 saveMusicActiveMs()5435 private void saveMusicActiveMs() { 5436 mAudioHandler.obtainMessage(MSG_PERSIST_MUSIC_ACTIVE_MS, mMusicActiveMs, 0).sendToTarget(); 5437 } 5438 getSafeUsbMediaVolumeIndex()5439 private int getSafeUsbMediaVolumeIndex() { 5440 // determine UI volume index corresponding to the wanted safe gain in dBFS 5441 int min = MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]; 5442 int max = MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]; 5443 5444 mSafeUsbMediaVolumeDbfs = mContext.getResources().getInteger( 5445 com.android.internal.R.integer.config_safe_media_volume_usb_mB) / 100.0f; 5446 5447 while (Math.abs(max - min) > 1) { 5448 int index = (max + min) / 2; 5449 float gainDB = AudioSystem.getStreamVolumeDB( 5450 AudioSystem.STREAM_MUSIC, index, AudioSystem.DEVICE_OUT_USB_HEADSET); 5451 if (Float.isNaN(gainDB)) { 5452 //keep last min in case of read error 5453 break; 5454 } else if (gainDB == mSafeUsbMediaVolumeDbfs) { 5455 min = index; 5456 break; 5457 } else if (gainDB < mSafeUsbMediaVolumeDbfs) { 5458 min = index; 5459 } else { 5460 max = index; 5461 } 5462 } 5463 return min * 10; 5464 } 5465 onConfigureSafeVolume(boolean force, String caller)5466 private void onConfigureSafeVolume(boolean force, String caller) { 5467 synchronized (mSafeMediaVolumeStateLock) { 5468 int mcc = mContext.getResources().getConfiguration().mcc; 5469 if ((mMcc != mcc) || ((mMcc == 0) && force)) { 5470 mSafeMediaVolumeIndex = mContext.getResources().getInteger( 5471 com.android.internal.R.integer.config_safe_media_volume_index) * 10; 5472 5473 mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex(); 5474 5475 boolean safeMediaVolumeEnabled = 5476 SystemProperties.getBoolean("audio.safemedia.force", false) 5477 || mContext.getResources().getBoolean( 5478 com.android.internal.R.bool.config_safe_media_volume_enabled); 5479 5480 boolean safeMediaVolumeBypass = 5481 SystemProperties.getBoolean("audio.safemedia.bypass", false); 5482 5483 // The persisted state is either "disabled" or "active": this is the state applied 5484 // next time we boot and cannot be "inactive" 5485 int persistedState; 5486 if (safeMediaVolumeEnabled && !safeMediaVolumeBypass) { 5487 persistedState = SAFE_MEDIA_VOLUME_ACTIVE; 5488 // The state can already be "inactive" here if the user has forced it before 5489 // the 30 seconds timeout for forced configuration. In this case we don't reset 5490 // it to "active". 5491 if (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_INACTIVE) { 5492 if (mMusicActiveMs == 0) { 5493 mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE; 5494 enforceSafeMediaVolume(caller); 5495 } else { 5496 // We have existing playback time recorded, already confirmed. 5497 mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE; 5498 } 5499 } 5500 } else { 5501 persistedState = SAFE_MEDIA_VOLUME_DISABLED; 5502 mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED; 5503 } 5504 mMcc = mcc; 5505 sendMsg(mAudioHandler, 5506 MSG_PERSIST_SAFE_VOLUME_STATE, 5507 SENDMSG_QUEUE, 5508 persistedState, 5509 0, 5510 null, 5511 0); 5512 } 5513 } 5514 } 5515 5516 /////////////////////////////////////////////////////////////////////////// 5517 // Internal methods 5518 /////////////////////////////////////////////////////////////////////////// 5519 5520 /** 5521 * Checks if the adjustment should change ringer mode instead of just 5522 * adjusting volume. If so, this will set the proper ringer mode and volume 5523 * indices on the stream states. 5524 */ checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, String caller, int flags)5525 private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, 5526 String caller, int flags) { 5527 int result = FLAG_ADJUST_VOLUME; 5528 if (isPlatformTelevision() || mIsSingleVolume) { 5529 return result; 5530 } 5531 5532 int ringerMode = getRingerModeInternal(); 5533 5534 switch (ringerMode) { 5535 case RINGER_MODE_NORMAL: 5536 if (direction == AudioManager.ADJUST_LOWER) { 5537 if (mHasVibrator) { 5538 // "step" is the delta in internal index units corresponding to a 5539 // change of 1 in UI index units. 5540 // Because of rounding when rescaling from one stream index range to its alias 5541 // index range, we cannot simply test oldIndex == step: 5542 // (step <= oldIndex < 2 * step) is equivalent to: (old UI index == 1) 5543 if (step <= oldIndex && oldIndex < 2 * step) { 5544 ringerMode = RINGER_MODE_VIBRATE; 5545 mLoweredFromNormalToVibrateTime = SystemClock.uptimeMillis(); 5546 } 5547 } else { 5548 if (oldIndex == step && mVolumePolicy.volumeDownToEnterSilent) { 5549 ringerMode = RINGER_MODE_SILENT; 5550 } 5551 } 5552 } else if (mIsSingleVolume && (direction == AudioManager.ADJUST_TOGGLE_MUTE 5553 || direction == AudioManager.ADJUST_MUTE)) { 5554 if (mHasVibrator) { 5555 ringerMode = RINGER_MODE_VIBRATE; 5556 } else { 5557 ringerMode = RINGER_MODE_SILENT; 5558 } 5559 // Setting the ringer mode will toggle mute 5560 result &= ~FLAG_ADJUST_VOLUME; 5561 } 5562 break; 5563 case RINGER_MODE_VIBRATE: 5564 if (!mHasVibrator) { 5565 Log.e(TAG, "checkForRingerModeChange() current ringer mode is vibrate" + 5566 "but no vibrator is present"); 5567 break; 5568 } 5569 if ((direction == AudioManager.ADJUST_LOWER)) { 5570 // This is the case we were muted with the volume turned up 5571 if (mIsSingleVolume && oldIndex >= 2 * step && isMuted) { 5572 ringerMode = RINGER_MODE_NORMAL; 5573 } else if (mPrevVolDirection != AudioManager.ADJUST_LOWER) { 5574 if (mVolumePolicy.volumeDownToEnterSilent) { 5575 final long diff = SystemClock.uptimeMillis() 5576 - mLoweredFromNormalToVibrateTime; 5577 if (diff > mVolumePolicy.vibrateToSilentDebounce 5578 && mRingerModeDelegate.canVolumeDownEnterSilent()) { 5579 ringerMode = RINGER_MODE_SILENT; 5580 } 5581 } else { 5582 result |= AudioManager.FLAG_SHOW_VIBRATE_HINT; 5583 } 5584 } 5585 } else if (direction == AudioManager.ADJUST_RAISE 5586 || direction == AudioManager.ADJUST_TOGGLE_MUTE 5587 || direction == AudioManager.ADJUST_UNMUTE) { 5588 ringerMode = RINGER_MODE_NORMAL; 5589 } 5590 result &= ~FLAG_ADJUST_VOLUME; 5591 break; 5592 case RINGER_MODE_SILENT: 5593 if (mIsSingleVolume && direction == AudioManager.ADJUST_LOWER && oldIndex >= 2 * step && isMuted) { 5594 // This is the case we were muted with the volume turned up 5595 ringerMode = RINGER_MODE_NORMAL; 5596 } else if (direction == AudioManager.ADJUST_RAISE 5597 || direction == AudioManager.ADJUST_TOGGLE_MUTE 5598 || direction == AudioManager.ADJUST_UNMUTE) { 5599 if (!mVolumePolicy.volumeUpToExitSilent) { 5600 result |= AudioManager.FLAG_SHOW_SILENT_HINT; 5601 } else { 5602 if (mHasVibrator && direction == AudioManager.ADJUST_RAISE) { 5603 ringerMode = RINGER_MODE_VIBRATE; 5604 } else { 5605 // If we don't have a vibrator or they were toggling mute 5606 // go straight back to normal. 5607 ringerMode = RINGER_MODE_NORMAL; 5608 } 5609 } 5610 } 5611 result &= ~FLAG_ADJUST_VOLUME; 5612 break; 5613 default: 5614 Log.e(TAG, "checkForRingerModeChange() wrong ringer mode: "+ringerMode); 5615 break; 5616 } 5617 5618 if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode) 5619 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller) 5620 && (flags & AudioManager.FLAG_FROM_KEY) == 0) { 5621 throw new SecurityException("Not allowed to change Do Not Disturb state"); 5622 } 5623 5624 setRingerMode(ringerMode, TAG + ".checkForRingerModeChange", false /*external*/); 5625 5626 mPrevVolDirection = direction; 5627 5628 return result; 5629 } 5630 5631 @Override isStreamAffectedByRingerMode(int streamType)5632 public boolean isStreamAffectedByRingerMode(int streamType) { 5633 return (mRingerModeAffectedStreams & (1 << streamType)) != 0; 5634 } 5635 shouldZenMuteStream(int streamType)5636 private boolean shouldZenMuteStream(int streamType) { 5637 if (mNm.getZenMode() != Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { 5638 return false; 5639 } 5640 5641 NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy(); 5642 final boolean muteAlarms = (zenPolicy.priorityCategories 5643 & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0; 5644 final boolean muteMedia = (zenPolicy.priorityCategories 5645 & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0; 5646 final boolean muteSystem = (zenPolicy.priorityCategories 5647 & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0; 5648 final boolean muteNotificationAndRing = ZenModeConfig 5649 .areAllPriorityOnlyRingerSoundsMuted(zenPolicy); 5650 return muteAlarms && isAlarm(streamType) 5651 || muteMedia && isMedia(streamType) 5652 || muteSystem && isSystem(streamType) 5653 || muteNotificationAndRing && isNotificationOrRinger(streamType); 5654 } 5655 isStreamMutedByRingerOrZenMode(int streamType)5656 private boolean isStreamMutedByRingerOrZenMode(int streamType) { 5657 return (mRingerAndZenModeMutedStreams & (1 << streamType)) != 0; 5658 } 5659 5660 /** 5661 * Notifications, ringer and system sounds are controlled by the ringer: 5662 * {@link ZenModeHelper.RingerModeDelegate#getRingerModeAffectedStreams(int)} but can 5663 * also be muted by DND based on the DND mode: 5664 * DND total silence: media and alarms streams can be muted by DND 5665 * DND alarms only: no streams additionally controlled by DND 5666 * DND priority only: alarms, media, system, ringer and notification streams can be muted by 5667 * DND. The current applied zenPolicy determines which streams will be muted by DND. 5668 * @return true if changed, else false 5669 */ updateZenModeAffectedStreams()5670 private boolean updateZenModeAffectedStreams() { 5671 if (!mSystemReady) { 5672 return false; 5673 } 5674 5675 int zenModeAffectedStreams = 0; 5676 final int zenMode = mNm.getZenMode(); 5677 5678 if (zenMode == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS) { 5679 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM; 5680 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC; 5681 } else if (zenMode == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { 5682 NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy(); 5683 if ((zenPolicy.priorityCategories 5684 & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0) { 5685 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM; 5686 } 5687 5688 if ((zenPolicy.priorityCategories 5689 & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0) { 5690 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC; 5691 } 5692 5693 // even if zen isn't muting the system stream, the ringer mode can still mute 5694 // the system stream 5695 if ((zenPolicy.priorityCategories 5696 & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) { 5697 zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM; 5698 } 5699 5700 if (ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(zenPolicy)) { 5701 zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION; 5702 zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING; 5703 } 5704 } 5705 5706 if (mZenModeAffectedStreams != zenModeAffectedStreams) { 5707 mZenModeAffectedStreams = zenModeAffectedStreams; 5708 return true; 5709 } 5710 5711 return false; 5712 } 5713 5714 @GuardedBy("mSettingsLock") updateRingerAndZenModeAffectedStreams()5715 private boolean updateRingerAndZenModeAffectedStreams() { 5716 boolean updatedZenModeAffectedStreams = updateZenModeAffectedStreams(); 5717 int ringerModeAffectedStreams = Settings.System.getIntForUser(mContentResolver, 5718 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 5719 ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)| 5720 (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)), 5721 UserHandle.USER_CURRENT); 5722 5723 if (mIsSingleVolume) { 5724 ringerModeAffectedStreams = 0; 5725 } else if (mRingerModeDelegate != null) { 5726 ringerModeAffectedStreams = mRingerModeDelegate 5727 .getRingerModeAffectedStreams(ringerModeAffectedStreams); 5728 } 5729 if (mCameraSoundForced) { 5730 ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 5731 } else { 5732 ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 5733 } 5734 if (mStreamVolumeAlias[AudioSystem.STREAM_DTMF] == AudioSystem.STREAM_RING) { 5735 ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF); 5736 } else { 5737 ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF); 5738 } 5739 5740 if (ringerModeAffectedStreams != mRingerModeAffectedStreams) { 5741 Settings.System.putIntForUser(mContentResolver, 5742 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 5743 ringerModeAffectedStreams, 5744 UserHandle.USER_CURRENT); 5745 mRingerModeAffectedStreams = ringerModeAffectedStreams; 5746 return true; 5747 } 5748 return updatedZenModeAffectedStreams; 5749 } 5750 5751 @Override isStreamAffectedByMute(int streamType)5752 public boolean isStreamAffectedByMute(int streamType) { 5753 return (mMuteAffectedStreams & (1 << streamType)) != 0; 5754 } 5755 ensureValidDirection(int direction)5756 private void ensureValidDirection(int direction) { 5757 switch (direction) { 5758 case AudioManager.ADJUST_LOWER: 5759 case AudioManager.ADJUST_RAISE: 5760 case AudioManager.ADJUST_SAME: 5761 case AudioManager.ADJUST_MUTE: 5762 case AudioManager.ADJUST_UNMUTE: 5763 case AudioManager.ADJUST_TOGGLE_MUTE: 5764 break; 5765 default: 5766 throw new IllegalArgumentException("Bad direction " + direction); 5767 } 5768 } 5769 ensureValidStreamType(int streamType)5770 private void ensureValidStreamType(int streamType) { 5771 if (streamType < 0 || streamType >= mStreamStates.length) { 5772 throw new IllegalArgumentException("Bad stream type " + streamType); 5773 } 5774 } 5775 isMuteAdjust(int adjust)5776 private boolean isMuteAdjust(int adjust) { 5777 return adjust == AudioManager.ADJUST_MUTE || adjust == AudioManager.ADJUST_UNMUTE 5778 || adjust == AudioManager.ADJUST_TOGGLE_MUTE; 5779 } 5780 5781 /** only public for mocking/spying, do not call outside of AudioService */ 5782 @VisibleForTesting isInCommunication()5783 public boolean isInCommunication() { 5784 boolean IsInCall = false; 5785 5786 TelecomManager telecomManager = 5787 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 5788 5789 final long ident = Binder.clearCallingIdentity(); 5790 IsInCall = telecomManager.isInCall(); 5791 Binder.restoreCallingIdentity(ident); 5792 5793 int mode = mMode.get(); 5794 return (IsInCall 5795 || mode == AudioManager.MODE_IN_COMMUNICATION 5796 || mode == AudioManager.MODE_IN_CALL); 5797 } 5798 5799 /** 5800 * For code clarity for getActiveStreamType(int) 5801 * @param delay_ms max time since last stream activity to consider 5802 * @return true if stream is active in streams handled by AudioFlinger now or 5803 * in the last "delay_ms" ms. 5804 */ wasStreamActiveRecently(int stream, int delay_ms)5805 private boolean wasStreamActiveRecently(int stream, int delay_ms) { 5806 return mAudioSystem.isStreamActive(stream, delay_ms) 5807 || mAudioSystem.isStreamActiveRemotely(stream, delay_ms); 5808 } 5809 getActiveStreamType(int suggestedStreamType)5810 private int getActiveStreamType(int suggestedStreamType) { 5811 if (mIsSingleVolume 5812 && suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 5813 return AudioSystem.STREAM_MUSIC; 5814 } 5815 5816 switch (mPlatformType) { 5817 case AudioSystem.PLATFORM_VOICE: 5818 if (isInCommunication()) { 5819 if (mDeviceBroker.isBluetoothScoActive()) { 5820 // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO..."); 5821 return AudioSystem.STREAM_BLUETOOTH_SCO; 5822 } else { 5823 // Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL..."); 5824 return AudioSystem.STREAM_VOICE_CALL; 5825 } 5826 } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 5827 if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 5828 if (DEBUG_VOL) 5829 Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active"); 5830 return AudioSystem.STREAM_RING; 5831 } else if (wasStreamActiveRecently( 5832 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 5833 if (DEBUG_VOL) 5834 Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active"); 5835 return AudioSystem.STREAM_NOTIFICATION; 5836 } else { 5837 if (DEBUG_VOL) { 5838 Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK(" 5839 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default"); 5840 } 5841 return DEFAULT_VOL_STREAM_NO_PLAYBACK; 5842 } 5843 } else if ( 5844 wasStreamActiveRecently(AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 5845 if (DEBUG_VOL) 5846 Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active"); 5847 return AudioSystem.STREAM_NOTIFICATION; 5848 } else if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 5849 if (DEBUG_VOL) 5850 Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active"); 5851 return AudioSystem.STREAM_RING; 5852 } 5853 default: 5854 if (isInCommunication()) { 5855 if (mDeviceBroker.isBluetoothScoActive()) { 5856 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO"); 5857 return AudioSystem.STREAM_BLUETOOTH_SCO; 5858 } else { 5859 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL"); 5860 return AudioSystem.STREAM_VOICE_CALL; 5861 } 5862 } else if (mAudioSystem.isStreamActive( 5863 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 5864 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION"); 5865 return AudioSystem.STREAM_NOTIFICATION; 5866 } else if (mAudioSystem.isStreamActive( 5867 AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 5868 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING"); 5869 return AudioSystem.STREAM_RING; 5870 } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 5871 if (mAudioSystem.isStreamActive( 5872 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 5873 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION"); 5874 return AudioSystem.STREAM_NOTIFICATION; 5875 } 5876 if (mAudioSystem.isStreamActive( 5877 AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 5878 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING"); 5879 return AudioSystem.STREAM_RING; 5880 } 5881 if (DEBUG_VOL) { 5882 Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK(" 5883 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default"); 5884 } 5885 return DEFAULT_VOL_STREAM_NO_PLAYBACK; 5886 } 5887 break; 5888 } 5889 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Returning suggested type " 5890 + suggestedStreamType); 5891 return suggestedStreamType; 5892 } 5893 broadcastRingerMode(String action, int ringerMode)5894 private void broadcastRingerMode(String action, int ringerMode) { 5895 if (!mSystemServer.isPrivileged()) { 5896 return; 5897 } 5898 // Send sticky broadcast 5899 Intent broadcast = new Intent(action); 5900 broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, ringerMode); 5901 broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 5902 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 5903 sendStickyBroadcastToAll(broadcast); 5904 } 5905 broadcastVibrateSetting(int vibrateType)5906 private void broadcastVibrateSetting(int vibrateType) { 5907 if (!mSystemServer.isPrivileged()) { 5908 return; 5909 } 5910 // Send broadcast 5911 if (mActivityManagerInternal.isSystemReady()) { 5912 Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION); 5913 broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType); 5914 broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType)); 5915 sendBroadcastToAll(broadcast); 5916 } 5917 } 5918 5919 // Message helper methods 5920 /** 5921 * Queue a message on the given handler's message queue, after acquiring the service wake lock. 5922 * Note that the wake lock needs to be released after the message has been handled. 5923 */ queueMsgUnderWakeLock(Handler handler, int msg, int arg1, int arg2, Object obj, int delay)5924 private void queueMsgUnderWakeLock(Handler handler, int msg, 5925 int arg1, int arg2, Object obj, int delay) { 5926 final long ident = Binder.clearCallingIdentity(); 5927 // Always acquire the wake lock as AudioService because it is released by the 5928 // message handler. 5929 mAudioEventWakeLock.acquire(); 5930 Binder.restoreCallingIdentity(ident); 5931 sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay); 5932 } 5933 sendMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, int delay)5934 private static void sendMsg(Handler handler, int msg, 5935 int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) { 5936 if (existingMsgPolicy == SENDMSG_REPLACE) { 5937 handler.removeMessages(msg); 5938 } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) { 5939 return; 5940 } 5941 5942 final long time = SystemClock.uptimeMillis() + delay; 5943 handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time); 5944 } 5945 checkAudioSettingsPermission(String method)5946 boolean checkAudioSettingsPermission(String method) { 5947 if (callingOrSelfHasAudioSettingsPermission()) { 5948 return true; 5949 } 5950 String msg = "Audio Settings Permission Denial: " + method + " from pid=" 5951 + Binder.getCallingPid() 5952 + ", uid=" + Binder.getCallingUid(); 5953 Log.w(TAG, msg); 5954 return false; 5955 } 5956 callingOrSelfHasAudioSettingsPermission()5957 private boolean callingOrSelfHasAudioSettingsPermission() { 5958 return mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS) 5959 == PackageManager.PERMISSION_GRANTED; 5960 } 5961 callingHasAudioSettingsPermission()5962 private boolean callingHasAudioSettingsPermission() { 5963 return mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS) 5964 == PackageManager.PERMISSION_GRANTED; 5965 } 5966 hasAudioSettingsPermission(int uid, int pid)5967 private boolean hasAudioSettingsPermission(int uid, int pid) { 5968 return mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid) 5969 == PackageManager.PERMISSION_GRANTED; 5970 } 5971 5972 /** 5973 * Minimum attenuation that can be set for alarms over speaker by an application that 5974 * doesn't have the MODIFY_AUDIO_SETTINGS permission. 5975 */ 5976 protected static final float MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB = -36.0f; 5977 5978 /** 5979 * Configures the VolumeStreamState instances for minimum stream index that can be accessed 5980 * without MODIFY_AUDIO_SETTINGS permission. 5981 * Can only be done successfully once audio policy has finished reading its configuration files 5982 * for the volume curves. If not, getStreamVolumeDB will return NaN, and the min value will 5983 * remain at the stream min index value. 5984 */ initMinStreamVolumeWithoutModifyAudioSettings()5985 protected void initMinStreamVolumeWithoutModifyAudioSettings() { 5986 int idx; 5987 int deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER_SAFE; 5988 if (Float.isNaN(AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, 5989 MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM], deviceForAlarm))) { 5990 deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER; 5991 } 5992 for (idx = MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; 5993 idx >= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; idx--) { 5994 if (AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, idx, deviceForAlarm) 5995 < MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB) { 5996 break; 5997 } 5998 } 5999 final int safeIndex = idx <= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM] 6000 ? MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM] 6001 : Math.min(idx + 1, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]); 6002 // update the VolumeStreamState for STREAM_ALARM and its aliases 6003 for (int stream : mStreamVolumeAlias) { 6004 if (mStreamVolumeAlias[stream] == AudioSystem.STREAM_ALARM) { 6005 mStreamStates[stream].updateNoPermMinIndex(safeIndex); 6006 } 6007 } 6008 } 6009 6010 /** only public for mocking/spying, do not call outside of AudioService */ 6011 @VisibleForTesting getDeviceForStream(int stream)6012 public int getDeviceForStream(int stream) { 6013 int device = getDevicesForStreamInt(stream); 6014 if ((device & (device - 1)) != 0) { 6015 // Multiple device selection is either: 6016 // - speaker + one other device: give priority to speaker in this case. 6017 // - one A2DP device + another device: happens with duplicated output. In this case 6018 // retain the device on the A2DP output as the other must not correspond to an active 6019 // selection if not the speaker. 6020 // - HDMI-CEC system audio mode only output: give priority to available item in order. 6021 // FIXME: Haven't applied audio device type refactor to this API 6022 // as it is going to be deprecated. 6023 if ((device & AudioSystem.DEVICE_OUT_SPEAKER) != 0) { 6024 device = AudioSystem.DEVICE_OUT_SPEAKER; 6025 } else if ((device & AudioSystem.DEVICE_OUT_HDMI_ARC) != 0) { 6026 // FIXME(b/184944421): DEVICE_OUT_HDMI_EARC has two bits set, 6027 // so it must be handled correctly as it aliases 6028 // with DEVICE_OUT_HDMI_ARC | DEVICE_OUT_EARPIECE. 6029 device = AudioSystem.DEVICE_OUT_HDMI_ARC; 6030 } else if ((device & AudioSystem.DEVICE_OUT_SPDIF) != 0) { 6031 device = AudioSystem.DEVICE_OUT_SPDIF; 6032 } else if ((device & AudioSystem.DEVICE_OUT_AUX_LINE) != 0) { 6033 device = AudioSystem.DEVICE_OUT_AUX_LINE; 6034 } else { 6035 for (int deviceType : AudioSystem.DEVICE_OUT_ALL_A2DP_SET) { 6036 if ((deviceType & device) == deviceType) { 6037 return deviceType; 6038 } 6039 } 6040 } 6041 } 6042 return device; 6043 } 6044 6045 /** 6046 * @see AudioManager#getDevicesForStream(int) 6047 */ getDevicesForStream(int streamType)6048 public int getDevicesForStream(int streamType) { 6049 ensureValidStreamType(streamType); 6050 final long token = Binder.clearCallingIdentity(); 6051 try { 6052 return mAudioSystem.getDevicesForStream(streamType); 6053 } finally { 6054 Binder.restoreCallingIdentity(token); 6055 } 6056 } 6057 getDevicesForStreamInt(int stream)6058 private int getDevicesForStreamInt(int stream) { 6059 ensureValidStreamType(stream); 6060 synchronized (VolumeStreamState.class) { 6061 return mStreamStates[stream].observeDevicesForStream_syncVSS(true); 6062 } 6063 } 6064 onObserveDevicesForAllStreams(int skipStream)6065 private void onObserveDevicesForAllStreams(int skipStream) { 6066 synchronized (mSettingsLock) { 6067 synchronized (VolumeStreamState.class) { 6068 for (int stream = 0; stream < mStreamStates.length; stream++) { 6069 if (stream != skipStream) { 6070 int devices = mStreamStates[stream].observeDevicesForStream_syncVSS( 6071 false /*checkOthers*/); 6072 6073 Set<Integer> devicesSet = AudioSystem.generateAudioDeviceTypesSet(devices); 6074 for (Integer device : devicesSet) { 6075 // Update volume states for devices routed for the stream 6076 updateVolumeStates(device, stream, 6077 "AudioService#onObserveDevicesForAllStreams"); 6078 } 6079 } 6080 } 6081 } 6082 } 6083 } 6084 6085 /** only public for mocking/spying, do not call outside of AudioService */ 6086 @VisibleForTesting postObserveDevicesForAllStreams()6087 public void postObserveDevicesForAllStreams() { 6088 postObserveDevicesForAllStreams(-1); 6089 } 6090 6091 /** only public for mocking/spying, do not call outside of AudioService */ 6092 @VisibleForTesting postObserveDevicesForAllStreams(int skipStream)6093 public void postObserveDevicesForAllStreams(int skipStream) { 6094 sendMsg(mAudioHandler, 6095 MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS, 6096 SENDMSG_QUEUE, skipStream /*arg1*/, 0 /*arg2*/, null /*obj*/, 6097 0 /*delay*/); 6098 } 6099 6100 /** 6101 * @see AudioManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int) 6102 * @param device the audio device to be affected 6103 * @param deviceVolumeBehavior one of the device behaviors 6104 */ setDeviceVolumeBehavior(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName)6105 public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device, 6106 @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName) { 6107 // verify permissions 6108 enforceModifyAudioRoutingPermission(); 6109 // verify arguments 6110 Objects.requireNonNull(device); 6111 AudioManager.enforceValidVolumeBehavior(deviceVolumeBehavior); 6112 if (pkgName == null) { 6113 pkgName = ""; 6114 } 6115 6116 int audioSystemDeviceOut = AudioDeviceInfo.convertDeviceTypeToInternalDevice( 6117 device.getType()); 6118 setDeviceVolumeBehaviorInternal(audioSystemDeviceOut, deviceVolumeBehavior, pkgName); 6119 6120 persistDeviceVolumeBehavior(audioSystemDeviceOut, deviceVolumeBehavior); 6121 } 6122 setDeviceVolumeBehaviorInternal(int audioSystemDeviceOut, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller)6123 private void setDeviceVolumeBehaviorInternal(int audioSystemDeviceOut, 6124 @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller) { 6125 // update device masks based on volume behavior 6126 switch (deviceVolumeBehavior) { 6127 case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE: 6128 removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut); 6129 removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut); 6130 break; 6131 case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED: 6132 removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut); 6133 addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut); 6134 break; 6135 case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL: 6136 addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut); 6137 removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut); 6138 break; 6139 case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE: 6140 case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE: 6141 throw new IllegalArgumentException("Absolute volume unsupported for now"); 6142 } 6143 6144 // log event and caller 6145 sDeviceLogger.log(new AudioEventLogger.StringEvent( 6146 "Volume behavior " + deviceVolumeBehavior + " for dev=0x" 6147 + Integer.toHexString(audioSystemDeviceOut) + " from:" + caller)); 6148 // make sure we have a volume entry for this device, and that volume is updated according 6149 // to volume behavior 6150 postUpdateVolumeStatesForAudioDevice(audioSystemDeviceOut, 6151 "setDeviceVolumeBehavior:" + caller); 6152 } 6153 6154 /** 6155 * @see AudioManager#getDeviceVolumeBehavior(AudioDeviceAttributes) 6156 * @param device the audio output device type 6157 * @return the volume behavior for the device 6158 */ 6159 public @AudioManager.DeviceVolumeBehavior getDeviceVolumeBehavior(@onNull AudioDeviceAttributes device)6160 int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) { 6161 // verify permissions 6162 enforceQueryStateOrModifyRoutingPermission(); 6163 6164 // translate Java device type to native device type (for the devices masks for full / fixed) 6165 final int audioSystemDeviceOut = AudioDeviceInfo.convertDeviceTypeToInternalDevice( 6166 device.getType()); 6167 6168 int setDeviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut); 6169 if (setDeviceVolumeBehavior != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) { 6170 return setDeviceVolumeBehavior; 6171 } 6172 6173 // setDeviceVolumeBehavior has not been explicitly called for the device type. Deduce the 6174 // current volume behavior. 6175 if ((mFullVolumeDevices.contains(audioSystemDeviceOut))) { 6176 return AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL; 6177 } 6178 if ((mFixedVolumeDevices.contains(audioSystemDeviceOut))) { 6179 return AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED; 6180 } 6181 if ((mAbsVolumeMultiModeCaseDevices.contains(audioSystemDeviceOut))) { 6182 return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE; 6183 } 6184 if (audioSystemDeviceOut == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP 6185 && mAvrcpAbsVolSupported) { 6186 return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE; 6187 } 6188 return AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE; 6189 } 6190 6191 /*package*/ static final int CONNECTION_STATE_DISCONNECTED = 0; 6192 /*package*/ static final int CONNECTION_STATE_CONNECTED = 1; 6193 /** 6194 * The states that can be used with AudioService.setWiredDeviceConnectionState() 6195 * Attention: those values differ from those in BluetoothProfile, follow annotations to 6196 * distinguish between @ConnectionState and @BtProfileConnectionState 6197 */ 6198 @IntDef({ 6199 CONNECTION_STATE_DISCONNECTED, 6200 CONNECTION_STATE_CONNECTED, 6201 }) 6202 @Retention(RetentionPolicy.SOURCE) 6203 public @interface ConnectionState {} 6204 6205 /** 6206 * see AudioManager.setWiredDeviceConnectionState() 6207 */ setWiredDeviceConnectionState(int type, @ConnectionState int state, String address, String name, String caller)6208 public void setWiredDeviceConnectionState(int type, 6209 @ConnectionState int state, String address, String name, 6210 String caller) { 6211 enforceModifyAudioRoutingPermission(); 6212 if (state != CONNECTION_STATE_CONNECTED 6213 && state != CONNECTION_STATE_DISCONNECTED) { 6214 throw new IllegalArgumentException("Invalid state " + state); 6215 } 6216 new MediaMetrics.Item(mMetricsId + "setWiredDeviceConnectionState") 6217 .set(MediaMetrics.Property.ADDRESS, address) 6218 .set(MediaMetrics.Property.CLIENT_NAME, caller) 6219 .set(MediaMetrics.Property.DEVICE, AudioSystem.getDeviceName(type)) 6220 .set(MediaMetrics.Property.NAME, name) 6221 .set(MediaMetrics.Property.STATE, 6222 state == CONNECTION_STATE_CONNECTED ? "connected" : "disconnected") 6223 .record(); 6224 mDeviceBroker.setWiredDeviceConnectionState(type, state, address, name, caller); 6225 } 6226 6227 /** 6228 * @hide 6229 * The states that can be used with AudioService.setBluetoothHearingAidDeviceConnectionState() 6230 * and AudioService.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent() 6231 */ 6232 @IntDef({ 6233 BluetoothProfile.STATE_DISCONNECTED, 6234 BluetoothProfile.STATE_CONNECTED, 6235 }) 6236 @Retention(RetentionPolicy.SOURCE) 6237 public @interface BtProfileConnectionState {} 6238 6239 /** 6240 * See AudioManager.setBluetoothHearingAidDeviceConnectionState() 6241 */ setBluetoothHearingAidDeviceConnectionState( @onNull BluetoothDevice device, @BtProfileConnectionState int state, boolean suppressNoisyIntent, int musicDevice)6242 public void setBluetoothHearingAidDeviceConnectionState( 6243 @NonNull BluetoothDevice device, @BtProfileConnectionState int state, 6244 boolean suppressNoisyIntent, int musicDevice) 6245 { 6246 if (device == null) { 6247 throw new IllegalArgumentException("Illegal null device"); 6248 } 6249 if (state != BluetoothProfile.STATE_CONNECTED 6250 && state != BluetoothProfile.STATE_DISCONNECTED) { 6251 throw new IllegalArgumentException("Illegal BluetoothProfile state for device " 6252 + " (dis)connection, got " + state); 6253 } 6254 mDeviceBroker.postBluetoothHearingAidDeviceConnectionState( 6255 device, state, suppressNoisyIntent, musicDevice, "AudioService"); 6256 } 6257 6258 /** 6259 * See AudioManager.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent() 6260 */ setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent( @onNull BluetoothDevice device, @BtProfileConnectionState int state, int profile, boolean suppressNoisyIntent, int a2dpVolume)6261 public void setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent( 6262 @NonNull BluetoothDevice device, @BtProfileConnectionState int state, 6263 int profile, boolean suppressNoisyIntent, int a2dpVolume) { 6264 if (device == null) { 6265 throw new IllegalArgumentException("Illegal null device"); 6266 } 6267 if (state != BluetoothProfile.STATE_CONNECTED 6268 && state != BluetoothProfile.STATE_DISCONNECTED) { 6269 throw new IllegalArgumentException("Illegal BluetoothProfile state for device " 6270 + " (dis)connection, got " + state); 6271 } 6272 6273 AudioDeviceBroker.BtDeviceConnectionInfo info = 6274 new AudioDeviceBroker.BtDeviceConnectionInfo(device, state, 6275 profile, suppressNoisyIntent, a2dpVolume); 6276 sendMsg(mAudioHandler, MSG_SET_A2DP_DEV_CONNECTION_STATE, SENDMSG_QUEUE, 6277 0 /*arg1*/, 0 /*arg2*/, 6278 /*obj*/ info, 0 /*delay*/); 6279 } 6280 6281 /** only public for mocking/spying, do not call outside of AudioService */ 6282 @VisibleForTesting setMusicMute(boolean mute)6283 public void setMusicMute(boolean mute) { 6284 mStreamStates[AudioSystem.STREAM_MUSIC].muteInternally(mute); 6285 } 6286 6287 /** 6288 * See AudioManager.handleBluetoothA2dpDeviceConfigChange() 6289 * @param device 6290 */ handleBluetoothA2dpDeviceConfigChange(BluetoothDevice device)6291 public void handleBluetoothA2dpDeviceConfigChange(BluetoothDevice device) 6292 { 6293 if (device == null) { 6294 throw new IllegalArgumentException("Illegal null device"); 6295 } 6296 sendMsg(mAudioHandler, MSG_A2DP_DEV_CONFIG_CHANGE, SENDMSG_QUEUE, 0, 0, 6297 /*obj*/ device, /*delay*/ 0); 6298 } 6299 6300 private static final Set<Integer> DEVICE_MEDIA_UNMUTED_ON_PLUG_SET; 6301 static { 6302 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET = new HashSet<>(); 6303 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADSET); 6304 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE); 6305 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_LINE); 6306 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_A2DP_SET); 6307 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_USB_SET); 6308 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_HDMI); 6309 } 6310 6311 /** only public for mocking/spying, do not call outside of AudioService */ 6312 @VisibleForTesting postAccessoryPlugMediaUnmute(int newDevice)6313 public void postAccessoryPlugMediaUnmute(int newDevice) { 6314 sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE, 6315 newDevice, 0, null, 0); 6316 } 6317 onAccessoryPlugMediaUnmute(int newDevice)6318 private void onAccessoryPlugMediaUnmute(int newDevice) { 6319 if (DEBUG_VOL) { 6320 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute newDevice=%d [%s]", 6321 newDevice, AudioSystem.getOutputDeviceName(newDevice))); 6322 } 6323 6324 if (mNm.getZenMode() != Settings.Global.ZEN_MODE_NO_INTERRUPTIONS 6325 && !isStreamMutedByRingerOrZenMode(AudioSystem.STREAM_MUSIC) 6326 && DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.contains(newDevice) 6327 && mStreamStates[AudioSystem.STREAM_MUSIC].mIsMuted 6328 && mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(newDevice) != 0 6329 && (newDevice & mAudioSystem.getDevicesForStream(AudioSystem.STREAM_MUSIC)) != 0) { 6330 if (DEBUG_VOL) { 6331 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute unmuting device=%d [%s]", 6332 newDevice, AudioSystem.getOutputDeviceName(newDevice))); 6333 } 6334 mStreamStates[AudioSystem.STREAM_MUSIC].mute(false); 6335 } 6336 } 6337 6338 /** 6339 * See AudioManager.hasHapticChannels(Context, Uri). 6340 */ hasHapticChannels(Uri uri)6341 public boolean hasHapticChannels(Uri uri) { 6342 return AudioManager.hasHapticChannelsImpl(mContext, uri); 6343 } 6344 6345 /////////////////////////////////////////////////////////////////////////// 6346 // Inner classes 6347 /////////////////////////////////////////////////////////////////////////// 6348 /** 6349 * Key is the AudioManager VolumeGroupId 6350 * Value is the VolumeGroupState 6351 */ 6352 private static final SparseArray<VolumeGroupState> sVolumeGroupStates = new SparseArray<>(); 6353 initVolumeGroupStates()6354 private void initVolumeGroupStates() { 6355 for (final AudioVolumeGroup avg : getAudioVolumeGroups()) { 6356 try { 6357 // if no valid attributes, this volume group is not controllable, throw exception 6358 ensureValidAttributes(avg); 6359 } catch (IllegalArgumentException e) { 6360 // Volume Groups without attributes are not controllable through set/get volume 6361 // using attributes. Do not append them. 6362 if (DEBUG_VOL) { 6363 Log.d(TAG, "volume group " + avg.name() + " for internal policy needs"); 6364 } 6365 continue; 6366 } 6367 sVolumeGroupStates.append(avg.getId(), new VolumeGroupState(avg)); 6368 } 6369 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 6370 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 6371 vgs.applyAllVolumes(); 6372 } 6373 } 6374 ensureValidAttributes(AudioVolumeGroup avg)6375 private void ensureValidAttributes(AudioVolumeGroup avg) { 6376 boolean hasAtLeastOneValidAudioAttributes = avg.getAudioAttributes().stream() 6377 .anyMatch(aa -> !aa.equals(AudioProductStrategy.sDefaultAttributes)); 6378 if (!hasAtLeastOneValidAudioAttributes) { 6379 throw new IllegalArgumentException("Volume Group " + avg.name() 6380 + " has no valid audio attributes"); 6381 } 6382 } 6383 readVolumeGroupsSettings()6384 private void readVolumeGroupsSettings() { 6385 if (DEBUG_VOL) { 6386 Log.v(TAG, "readVolumeGroupsSettings"); 6387 } 6388 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 6389 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 6390 vgs.readSettings(); 6391 vgs.applyAllVolumes(); 6392 } 6393 } 6394 6395 // Called upon crash of AudioServer restoreVolumeGroups()6396 private void restoreVolumeGroups() { 6397 if (DEBUG_VOL) { 6398 Log.v(TAG, "restoreVolumeGroups"); 6399 } 6400 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 6401 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 6402 vgs.applyAllVolumes(); 6403 } 6404 } 6405 dumpVolumeGroups(PrintWriter pw)6406 private void dumpVolumeGroups(PrintWriter pw) { 6407 pw.println("\nVolume Groups (device: index)"); 6408 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 6409 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 6410 vgs.dump(pw); 6411 pw.println(""); 6412 } 6413 } 6414 6415 // NOTE: Locking order for synchronized objects related to volume management: 6416 // 1 mSettingsLock 6417 // 2 VolumeGroupState.class 6418 private class VolumeGroupState { 6419 private final AudioVolumeGroup mAudioVolumeGroup; 6420 private final SparseIntArray mIndexMap = new SparseIntArray(8); 6421 private int mIndexMin; 6422 private int mIndexMax; 6423 private int mLegacyStreamType = AudioSystem.STREAM_DEFAULT; 6424 private int mPublicStreamType = AudioSystem.STREAM_MUSIC; 6425 private AudioAttributes mAudioAttributes = AudioProductStrategy.sDefaultAttributes; 6426 6427 // No API in AudioSystem to get a device from strategy or from attributes. 6428 // Need a valid public stream type to use current API getDeviceForStream getDeviceForVolume()6429 private int getDeviceForVolume() { 6430 return getDeviceForStream(mPublicStreamType); 6431 } 6432 VolumeGroupState(AudioVolumeGroup avg)6433 private VolumeGroupState(AudioVolumeGroup avg) { 6434 mAudioVolumeGroup = avg; 6435 if (DEBUG_VOL) { 6436 Log.v(TAG, "VolumeGroupState for " + avg.toString()); 6437 } 6438 for (final AudioAttributes aa : avg.getAudioAttributes()) { 6439 if (!aa.equals(AudioProductStrategy.sDefaultAttributes)) { 6440 mAudioAttributes = aa; 6441 break; 6442 } 6443 } 6444 final int[] streamTypes = mAudioVolumeGroup.getLegacyStreamTypes(); 6445 if (streamTypes.length != 0) { 6446 // Uses already initialized MIN / MAX if a stream type is attached to group 6447 mLegacyStreamType = streamTypes[0]; 6448 for (final int streamType : streamTypes) { 6449 if (streamType != AudioSystem.STREAM_DEFAULT 6450 && streamType < AudioSystem.getNumStreamTypes()) { 6451 mPublicStreamType = streamType; 6452 break; 6453 } 6454 } 6455 mIndexMin = MIN_STREAM_VOLUME[mPublicStreamType]; 6456 mIndexMax = MAX_STREAM_VOLUME[mPublicStreamType]; 6457 } else if (!avg.getAudioAttributes().isEmpty()) { 6458 mIndexMin = AudioSystem.getMinVolumeIndexForAttributes(mAudioAttributes); 6459 mIndexMax = AudioSystem.getMaxVolumeIndexForAttributes(mAudioAttributes); 6460 } else { 6461 Log.e(TAG, "volume group: " + mAudioVolumeGroup.name() 6462 + " has neither valid attributes nor valid stream types assigned"); 6463 return; 6464 } 6465 // Load volume indexes from data base 6466 readSettings(); 6467 } 6468 getLegacyStreamTypes()6469 public @NonNull int[] getLegacyStreamTypes() { 6470 return mAudioVolumeGroup.getLegacyStreamTypes(); 6471 } 6472 name()6473 public String name() { 6474 return mAudioVolumeGroup.name(); 6475 } 6476 getVolumeIndex()6477 public int getVolumeIndex() { 6478 return getIndex(getDeviceForVolume()); 6479 } 6480 setVolumeIndex(int index, int flags)6481 public void setVolumeIndex(int index, int flags) { 6482 if (mUseFixedVolume) { 6483 return; 6484 } 6485 setVolumeIndex(index, getDeviceForVolume(), flags); 6486 } 6487 setVolumeIndex(int index, int device, int flags)6488 private void setVolumeIndex(int index, int device, int flags) { 6489 // Set the volume index 6490 setVolumeIndexInt(index, device, flags); 6491 6492 // Update local cache 6493 mIndexMap.put(device, index); 6494 6495 // update data base - post a persist volume group msg 6496 sendMsg(mAudioHandler, 6497 MSG_PERSIST_VOLUME_GROUP, 6498 SENDMSG_QUEUE, 6499 device, 6500 0, 6501 this, 6502 PERSIST_DELAY); 6503 } 6504 setVolumeIndexInt(int index, int device, int flags)6505 private void setVolumeIndexInt(int index, int device, int flags) { 6506 // Reflect mute state of corresponding stream by forcing index to 0 if muted 6507 // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted. 6508 // This allows RX path muting by the audio HAL only when explicitly muted but not when 6509 // index is just set to 0 to repect BT requirements 6510 if (mStreamStates[mPublicStreamType].isFullyMuted()) { 6511 index = 0; 6512 } else if (mPublicStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0) { 6513 index = 1; 6514 } 6515 // Set the volume index 6516 AudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, device); 6517 } 6518 getIndex(int device)6519 public int getIndex(int device) { 6520 synchronized (VolumeGroupState.class) { 6521 int index = mIndexMap.get(device, -1); 6522 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT 6523 return (index != -1) ? index : mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); 6524 } 6525 } 6526 hasIndexForDevice(int device)6527 public boolean hasIndexForDevice(int device) { 6528 synchronized (VolumeGroupState.class) { 6529 return (mIndexMap.get(device, -1) != -1); 6530 } 6531 } 6532 getMaxIndex()6533 public int getMaxIndex() { 6534 return mIndexMax; 6535 } 6536 getMinIndex()6537 public int getMinIndex() { 6538 return mIndexMin; 6539 } 6540 isValidLegacyStreamType()6541 private boolean isValidLegacyStreamType() { 6542 return (mLegacyStreamType != AudioSystem.STREAM_DEFAULT) 6543 && (mLegacyStreamType < mStreamStates.length); 6544 } 6545 applyAllVolumes()6546 public void applyAllVolumes() { 6547 synchronized (VolumeGroupState.class) { 6548 int deviceForStream = AudioSystem.DEVICE_NONE; 6549 int volumeIndexForStream = 0; 6550 if (isValidLegacyStreamType()) { 6551 // Prevent to apply settings twice when group is associated to public stream 6552 deviceForStream = getDeviceForStream(mLegacyStreamType); 6553 volumeIndexForStream = getStreamVolume(mLegacyStreamType); 6554 } 6555 // apply device specific volumes first 6556 int index; 6557 for (int i = 0; i < mIndexMap.size(); i++) { 6558 final int device = mIndexMap.keyAt(i); 6559 if (device != AudioSystem.DEVICE_OUT_DEFAULT) { 6560 index = mIndexMap.valueAt(i); 6561 if (device == deviceForStream && volumeIndexForStream == index) { 6562 continue; 6563 } 6564 if (DEBUG_VOL) { 6565 Log.v(TAG, "applyAllVolumes: restore index " + index + " for group " 6566 + mAudioVolumeGroup.name() + " and device " 6567 + AudioSystem.getOutputDeviceName(device)); 6568 } 6569 setVolumeIndexInt(index, device, 0 /*flags*/); 6570 } 6571 } 6572 // apply default volume last: by convention , default device volume will be used 6573 // by audio policy manager if no explicit volume is present for a given device type 6574 index = getIndex(AudioSystem.DEVICE_OUT_DEFAULT); 6575 if (DEBUG_VOL) { 6576 Log.v(TAG, "applyAllVolumes: restore default device index " + index 6577 + " for group " + mAudioVolumeGroup.name()); 6578 } 6579 if (isValidLegacyStreamType()) { 6580 int defaultStreamIndex = (mStreamStates[mLegacyStreamType] 6581 .getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5) / 10; 6582 if (defaultStreamIndex == index) { 6583 return; 6584 } 6585 } 6586 setVolumeIndexInt(index, AudioSystem.DEVICE_OUT_DEFAULT, 0 /*flags*/); 6587 } 6588 } 6589 persistVolumeGroup(int device)6590 private void persistVolumeGroup(int device) { 6591 if (mUseFixedVolume) { 6592 return; 6593 } 6594 if (DEBUG_VOL) { 6595 Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) + " for group " 6596 + mAudioVolumeGroup.name() 6597 + ", device " + AudioSystem.getOutputDeviceName(device) 6598 + " and User=" + ActivityManager.getCurrentUser()); 6599 } 6600 boolean success = Settings.System.putIntForUser(mContentResolver, 6601 getSettingNameForDevice(device), 6602 getIndex(device), 6603 UserHandle.USER_CURRENT); 6604 if (!success) { 6605 Log.e(TAG, "persistVolumeGroup failed for group " + mAudioVolumeGroup.name()); 6606 } 6607 } 6608 readSettings()6609 public void readSettings() { 6610 synchronized (VolumeGroupState.class) { 6611 // First clear previously loaded (previous user?) settings 6612 mIndexMap.clear(); 6613 // force maximum volume on all streams if fixed volume property is set 6614 if (mUseFixedVolume) { 6615 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax); 6616 return; 6617 } 6618 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 6619 // retrieve current volume for device 6620 // if no volume stored for current volume group and device, use default volume 6621 // if default device, continue otherwise 6622 int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) 6623 ? AudioSystem.DEFAULT_STREAM_VOLUME[mPublicStreamType] : -1; 6624 int index; 6625 String name = getSettingNameForDevice(device); 6626 index = Settings.System.getIntForUser( 6627 mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT); 6628 if (index == -1) { 6629 continue; 6630 } 6631 if (mPublicStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED 6632 && mCameraSoundForced) { 6633 index = mIndexMax; 6634 } 6635 if (DEBUG_VOL) { 6636 Log.v(TAG, "readSettings: found stored index " + getValidIndex(index) 6637 + " for group " + mAudioVolumeGroup.name() + ", device: " + name 6638 + ", User=" + ActivityManager.getCurrentUser()); 6639 } 6640 mIndexMap.put(device, getValidIndex(index)); 6641 } 6642 } 6643 } 6644 getValidIndex(int index)6645 private int getValidIndex(int index) { 6646 if (index < mIndexMin) { 6647 return mIndexMin; 6648 } else if (mUseFixedVolume || index > mIndexMax) { 6649 return mIndexMax; 6650 } 6651 return index; 6652 } 6653 getSettingNameForDevice(int device)6654 public @NonNull String getSettingNameForDevice(int device) { 6655 final String suffix = AudioSystem.getOutputDeviceName(device); 6656 if (suffix.isEmpty()) { 6657 return mAudioVolumeGroup.name(); 6658 } 6659 return mAudioVolumeGroup.name() + "_" + AudioSystem.getOutputDeviceName(device); 6660 } 6661 dump(PrintWriter pw)6662 private void dump(PrintWriter pw) { 6663 pw.println("- VOLUME GROUP " + mAudioVolumeGroup.name() + ":"); 6664 pw.print(" Min: "); 6665 pw.println(mIndexMin); 6666 pw.print(" Max: "); 6667 pw.println(mIndexMax); 6668 pw.print(" Current: "); 6669 for (int i = 0; i < mIndexMap.size(); i++) { 6670 if (i > 0) { 6671 pw.print(", "); 6672 } 6673 final int device = mIndexMap.keyAt(i); 6674 pw.print(Integer.toHexString(device)); 6675 final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 6676 : AudioSystem.getOutputDeviceName(device); 6677 if (!deviceName.isEmpty()) { 6678 pw.print(" ("); 6679 pw.print(deviceName); 6680 pw.print(")"); 6681 } 6682 pw.print(": "); 6683 pw.print(mIndexMap.valueAt(i)); 6684 } 6685 pw.println(); 6686 pw.print(" Devices: "); 6687 int n = 0; 6688 final int devices = getDeviceForVolume(); 6689 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 6690 if ((devices & device) == device) { 6691 if (n++ > 0) { 6692 pw.print(", "); 6693 } 6694 pw.print(AudioSystem.getOutputDeviceName(device)); 6695 } 6696 } 6697 } 6698 } 6699 6700 6701 // NOTE: Locking order for synchronized objects related to volume or ringer mode management: 6702 // 1 mScoclient OR mSafeMediaVolumeState 6703 // 2 mSetModeLock 6704 // 3 mSettingsLock 6705 // 4 VolumeStreamState.class 6706 private class VolumeStreamState { 6707 private final int mStreamType; 6708 private int mIndexMin; 6709 // min index when user doesn't have permission to change audio settings 6710 private int mIndexMinNoPerm; 6711 private int mIndexMax; 6712 6713 private boolean mIsMuted; 6714 private boolean mIsMutedInternally; 6715 private String mVolumeIndexSettingName; 6716 private int mObservedDevices; 6717 6718 private final SparseIntArray mIndexMap = new SparseIntArray(8) { 6719 @Override 6720 public void put(int key, int value) { 6721 super.put(key, value); 6722 record("put", key, value); 6723 } 6724 @Override 6725 public void setValueAt(int index, int value) { 6726 super.setValueAt(index, value); 6727 record("setValueAt", keyAt(index), value); 6728 } 6729 6730 // Record all changes in the VolumeStreamState 6731 private void record(String event, int key, int value) { 6732 final String device = key == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 6733 : AudioSystem.getOutputDeviceName(key); 6734 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME + MediaMetrics.SEPARATOR 6735 + AudioSystem.streamToString(mStreamType) 6736 + "." + device) 6737 .set(MediaMetrics.Property.EVENT, event) 6738 .set(MediaMetrics.Property.INDEX, value) 6739 .set(MediaMetrics.Property.MIN_INDEX, mIndexMin) 6740 .set(MediaMetrics.Property.MAX_INDEX, mIndexMax) 6741 .record(); 6742 } 6743 }; 6744 private final Intent mVolumeChanged; 6745 private final Intent mStreamDevicesChanged; 6746 VolumeStreamState(String settingName, int streamType)6747 private VolumeStreamState(String settingName, int streamType) { 6748 mVolumeIndexSettingName = settingName; 6749 6750 mStreamType = streamType; 6751 mIndexMin = MIN_STREAM_VOLUME[streamType] * 10; 6752 mIndexMinNoPerm = mIndexMin; // may be overwritten later in updateNoPermMinIndex() 6753 mIndexMax = MAX_STREAM_VOLUME[streamType] * 10; 6754 final int status = AudioSystem.initStreamVolume( 6755 streamType, mIndexMin / 10, mIndexMax / 10); 6756 if (status != AudioSystem.AUDIO_STATUS_OK) { 6757 sLifecycleLogger.log(new AudioEventLogger.StringEvent( 6758 "VSS() stream:" + streamType + " initStreamVolume=" + status) 6759 .printLog(ALOGE, TAG)); 6760 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 6761 "VSS()" /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 6762 } 6763 6764 readSettings(); 6765 mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION); 6766 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 6767 mStreamDevicesChanged = new Intent(AudioManager.STREAM_DEVICES_CHANGED_ACTION); 6768 mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 6769 } 6770 6771 /** 6772 * Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission 6773 * @param index minimum index expressed in "UI units", i.e. no 10x factor 6774 */ updateNoPermMinIndex(int index)6775 public void updateNoPermMinIndex(int index) { 6776 mIndexMinNoPerm = index * 10; 6777 if (mIndexMinNoPerm < mIndexMin) { 6778 Log.e(TAG, "Invalid mIndexMinNoPerm for stream " + mStreamType); 6779 mIndexMinNoPerm = mIndexMin; 6780 } 6781 } 6782 6783 @GuardedBy("VolumeStreamState.class") observeDevicesForStream_syncVSS(boolean checkOthers)6784 public int observeDevicesForStream_syncVSS(boolean checkOthers) { 6785 if (!mSystemServer.isPrivileged()) { 6786 return AudioSystem.DEVICE_NONE; 6787 } 6788 final int devices = mAudioSystem.getDevicesForStream(mStreamType); 6789 if (devices == mObservedDevices) { 6790 return devices; 6791 } 6792 final int prevDevices = mObservedDevices; 6793 mObservedDevices = devices; 6794 if (checkOthers) { 6795 // one stream's devices have changed, check the others 6796 postObserveDevicesForAllStreams(mStreamType); 6797 } 6798 // log base stream changes to the event log 6799 if (mStreamVolumeAlias[mStreamType] == mStreamType) { 6800 EventLogTags.writeStreamDevicesChanged(mStreamType, prevDevices, devices); 6801 } 6802 // send STREAM_DEVICES_CHANGED_ACTION on the message handler so it is scheduled after 6803 // the postObserveDevicesForStreams is handled 6804 sendMsg(mAudioHandler, 6805 MSG_STREAM_DEVICES_CHANGED, 6806 SENDMSG_QUEUE, prevDevices /*arg1*/, devices /*arg2*/, 6807 // ok to send reference to this object, it is final 6808 mStreamDevicesChanged /*obj*/, 0 /*delay*/); 6809 return devices; 6810 } 6811 getSettingNameForDevice(int device)6812 public @Nullable String getSettingNameForDevice(int device) { 6813 if (!hasValidSettingsName()) { 6814 return null; 6815 } 6816 final String suffix = AudioSystem.getOutputDeviceName(device); 6817 if (suffix.isEmpty()) { 6818 return mVolumeIndexSettingName; 6819 } 6820 return mVolumeIndexSettingName + "_" + suffix; 6821 } 6822 hasValidSettingsName()6823 private boolean hasValidSettingsName() { 6824 return (mVolumeIndexSettingName != null && !mVolumeIndexSettingName.isEmpty()); 6825 } 6826 readSettings()6827 public void readSettings() { 6828 synchronized (mSettingsLock) { 6829 synchronized (VolumeStreamState.class) { 6830 // force maximum volume on all streams if fixed volume property is set 6831 if (mUseFixedVolume) { 6832 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax); 6833 return; 6834 } 6835 // do not read system stream volume from settings: this stream is always aliased 6836 // to another stream type and its volume is never persisted. Values in settings can 6837 // only be stale values 6838 if ((mStreamType == AudioSystem.STREAM_SYSTEM) || 6839 (mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)) { 6840 int index = 10 * AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType]; 6841 if (mCameraSoundForced) { 6842 index = mIndexMax; 6843 } 6844 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, index); 6845 return; 6846 } 6847 } 6848 } 6849 synchronized (VolumeStreamState.class) { 6850 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 6851 6852 // retrieve current volume for device 6853 // if no volume stored for current stream and device, use default volume if default 6854 // device, continue otherwise 6855 int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ? 6856 AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType] : -1; 6857 int index; 6858 if (!hasValidSettingsName()) { 6859 index = defaultIndex; 6860 } else { 6861 String name = getSettingNameForDevice(device); 6862 index = Settings.System.getIntForUser( 6863 mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT); 6864 } 6865 if (index == -1) { 6866 continue; 6867 } 6868 6869 mIndexMap.put(device, getValidIndex(10 * index, 6870 true /*hasModifyAudioSettings*/)); 6871 } 6872 } 6873 } 6874 getAbsoluteVolumeIndex(int index)6875 private int getAbsoluteVolumeIndex(int index) { 6876 /* Special handling for Bluetooth Absolute Volume scenario 6877 * If we send full audio gain, some accessories are too loud even at its lowest 6878 * volume. We are not able to enumerate all such accessories, so here is the 6879 * workaround from phone side. 6880 * Pre-scale volume at lowest volume steps 1 2 and 3. 6881 * For volume step 0, set audio gain to 0 as some accessories won't mute on their end. 6882 */ 6883 if (index == 0) { 6884 // 0% for volume 0 6885 index = 0; 6886 } else if (index > 0 && index <= 3) { 6887 // Pre-scale for volume steps 1 2 and 3 6888 index = (int) (mIndexMax * mPrescaleAbsoluteVolume[index - 1]) / 10; 6889 } else { 6890 // otherwise, full gain 6891 index = (mIndexMax + 5) / 10; 6892 } 6893 return index; 6894 } 6895 setStreamVolumeIndex(int index, int device)6896 private void setStreamVolumeIndex(int index, int device) { 6897 // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted. 6898 // This allows RX path muting by the audio HAL only when explicitly muted but not when 6899 // index is just set to 0 to repect BT requirements 6900 if (mStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0 6901 && !isFullyMuted()) { 6902 index = 1; 6903 } 6904 AudioSystem.setStreamVolumeIndexAS(mStreamType, index, device); 6905 } 6906 6907 // must be called while synchronized VolumeStreamState.class applyDeviceVolume_syncVSS(int device)6908 /*package*/ void applyDeviceVolume_syncVSS(int device) { 6909 int index; 6910 if (isFullyMuted()) { 6911 index = 0; 6912 } else if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 6913 && mAvrcpAbsVolSupported) { 6914 index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10); 6915 } else if (isFullVolumeDevice(device)) { 6916 index = (mIndexMax + 5)/10; 6917 } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 6918 index = (mIndexMax + 5)/10; 6919 } else { 6920 index = (getIndex(device) + 5)/10; 6921 } 6922 setStreamVolumeIndex(index, device); 6923 } 6924 applyAllVolumes()6925 public void applyAllVolumes() { 6926 synchronized (VolumeStreamState.class) { 6927 // apply device specific volumes first 6928 int index; 6929 for (int i = 0; i < mIndexMap.size(); i++) { 6930 final int device = mIndexMap.keyAt(i); 6931 if (device != AudioSystem.DEVICE_OUT_DEFAULT) { 6932 if (isFullyMuted()) { 6933 index = 0; 6934 } else if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 6935 && mAvrcpAbsVolSupported) { 6936 index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10); 6937 } else if (isFullVolumeDevice(device)) { 6938 index = (mIndexMax + 5)/10; 6939 } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 6940 index = (mIndexMax + 5)/10; 6941 } else { 6942 index = (mIndexMap.valueAt(i) + 5)/10; 6943 } 6944 setStreamVolumeIndex(index, device); 6945 } 6946 } 6947 // apply default volume last: by convention , default device volume will be used 6948 // by audio policy manager if no explicit volume is present for a given device type 6949 if (isFullyMuted()) { 6950 index = 0; 6951 } else { 6952 index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10; 6953 } 6954 setStreamVolumeIndex(index, AudioSystem.DEVICE_OUT_DEFAULT); 6955 } 6956 } 6957 adjustIndex(int deltaIndex, int device, String caller, boolean hasModifyAudioSettings)6958 public boolean adjustIndex(int deltaIndex, int device, String caller, 6959 boolean hasModifyAudioSettings) { 6960 return setIndex(getIndex(device) + deltaIndex, device, caller, 6961 hasModifyAudioSettings); 6962 } 6963 setIndex(int index, int device, String caller, boolean hasModifyAudioSettings)6964 public boolean setIndex(int index, int device, String caller, 6965 boolean hasModifyAudioSettings) { 6966 boolean changed; 6967 int oldIndex; 6968 synchronized (mSettingsLock) { 6969 synchronized (VolumeStreamState.class) { 6970 oldIndex = getIndex(device); 6971 index = getValidIndex(index, hasModifyAudioSettings); 6972 if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) && mCameraSoundForced) { 6973 index = mIndexMax; 6974 } 6975 mIndexMap.put(device, index); 6976 6977 changed = oldIndex != index; 6978 // Apply change to all streams using this one as alias if: 6979 // - the index actually changed OR 6980 // - there is no volume index stored for this device on alias stream. 6981 // If changing volume of current device, also change volume of current 6982 // device on aliased stream 6983 final boolean isCurrentDevice = (device == getDeviceForStream(mStreamType)); 6984 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 6985 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 6986 final VolumeStreamState aliasStreamState = mStreamStates[streamType]; 6987 if (streamType != mStreamType && 6988 mStreamVolumeAlias[streamType] == mStreamType && 6989 (changed || !aliasStreamState.hasIndexForDevice(device))) { 6990 final int scaledIndex = rescaleIndex(index, mStreamType, streamType); 6991 aliasStreamState.setIndex(scaledIndex, device, caller, 6992 hasModifyAudioSettings); 6993 if (isCurrentDevice) { 6994 aliasStreamState.setIndex(scaledIndex, 6995 getDeviceForStream(streamType), caller, 6996 hasModifyAudioSettings); 6997 } 6998 } 6999 } 7000 // Mirror changes in SPEAKER ringtone volume on SCO when 7001 if (changed && mStreamType == AudioSystem.STREAM_RING 7002 && device == AudioSystem.DEVICE_OUT_SPEAKER) { 7003 for (int i = 0; i < mIndexMap.size(); i++) { 7004 int otherDevice = mIndexMap.keyAt(i); 7005 if (AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(otherDevice)) { 7006 mIndexMap.put(otherDevice, index); 7007 } 7008 } 7009 } 7010 } 7011 } 7012 if (changed) { 7013 oldIndex = (oldIndex + 5) / 10; 7014 index = (index + 5) / 10; 7015 // log base stream changes to the event log 7016 if (mStreamVolumeAlias[mStreamType] == mStreamType) { 7017 if (caller == null) { 7018 Log.w(TAG, "No caller for volume_changed event", new Throwable()); 7019 } 7020 EventLogTags.writeVolumeChanged(mStreamType, oldIndex, index, mIndexMax / 10, 7021 caller); 7022 } 7023 // fire changed intents for all streams 7024 if (index != oldIndex) { 7025 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index); 7026 mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex); 7027 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS, 7028 mStreamVolumeAlias[mStreamType]); 7029 sendBroadcastToAll(mVolumeChanged); 7030 } 7031 } 7032 return changed; 7033 } 7034 getIndex(int device)7035 public int getIndex(int device) { 7036 synchronized (VolumeStreamState.class) { 7037 int index = mIndexMap.get(device, -1); 7038 if (index == -1) { 7039 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT 7040 index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); 7041 } 7042 return index; 7043 } 7044 } 7045 hasIndexForDevice(int device)7046 public boolean hasIndexForDevice(int device) { 7047 synchronized (VolumeStreamState.class) { 7048 return (mIndexMap.get(device, -1) != -1); 7049 } 7050 } 7051 getMaxIndex()7052 public int getMaxIndex() { 7053 return mIndexMax; 7054 } 7055 7056 /** 7057 * @return the lowest index regardless of permissions 7058 */ getMinIndex()7059 public int getMinIndex() { 7060 return mIndexMin; 7061 } 7062 7063 /** 7064 * @param isPrivileged true if the caller is privileged and not subject to minimum 7065 * volume index thresholds 7066 * @return the lowest index that this caller can set or adjust to 7067 */ getMinIndex(boolean isPrivileged)7068 public int getMinIndex(boolean isPrivileged) { 7069 return isPrivileged ? mIndexMin : mIndexMinNoPerm; 7070 } 7071 7072 /** 7073 * Copies all device/index pairs from the given VolumeStreamState after initializing 7074 * them with the volume for DEVICE_OUT_DEFAULT. No-op if the source VolumeStreamState 7075 * has the same stream type as this instance. 7076 * @param srcStream 7077 * @param caller 7078 */ 7079 // must be sync'd on mSettingsLock before VolumeStreamState.class 7080 @GuardedBy("VolumeStreamState.class") setAllIndexes(VolumeStreamState srcStream, String caller)7081 public void setAllIndexes(VolumeStreamState srcStream, String caller) { 7082 if (mStreamType == srcStream.mStreamType) { 7083 return; 7084 } 7085 int srcStreamType = srcStream.getStreamType(); 7086 // apply default device volume from source stream to all devices first in case 7087 // some devices are present in this stream state but not in source stream state 7088 int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT); 7089 index = rescaleIndex(index, srcStreamType, mStreamType); 7090 for (int i = 0; i < mIndexMap.size(); i++) { 7091 mIndexMap.put(mIndexMap.keyAt(i), index); 7092 } 7093 // Now apply actual volume for devices in source stream state 7094 SparseIntArray srcMap = srcStream.mIndexMap; 7095 for (int i = 0; i < srcMap.size(); i++) { 7096 int device = srcMap.keyAt(i); 7097 index = srcMap.valueAt(i); 7098 index = rescaleIndex(index, srcStreamType, mStreamType); 7099 7100 setIndex(index, device, caller, true /*hasModifyAudioSettings*/); 7101 } 7102 } 7103 7104 // must be sync'd on mSettingsLock before VolumeStreamState.class 7105 @GuardedBy("VolumeStreamState.class") setAllIndexesToMax()7106 public void setAllIndexesToMax() { 7107 for (int i = 0; i < mIndexMap.size(); i++) { 7108 mIndexMap.put(mIndexMap.keyAt(i), mIndexMax); 7109 } 7110 } 7111 7112 /** 7113 * Mute/unmute the stream 7114 * @param state the new mute state 7115 * @return true if the mute state was changed 7116 */ mute(boolean state)7117 public boolean mute(boolean state) { 7118 boolean changed = false; 7119 synchronized (VolumeStreamState.class) { 7120 if (state != mIsMuted) { 7121 changed = true; 7122 mIsMuted = state; 7123 7124 // Set the new mute volume. This propagates the values to 7125 // the audio system, otherwise the volume won't be changed 7126 // at the lower level. 7127 sendMsg(mAudioHandler, 7128 MSG_SET_ALL_VOLUMES, 7129 SENDMSG_QUEUE, 7130 0, 7131 0, 7132 this, 0); 7133 } 7134 } 7135 if (changed) { 7136 // Stream mute changed, fire the intent. 7137 Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION); 7138 intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 7139 intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, state); 7140 sendBroadcastToAll(intent); 7141 } 7142 return changed; 7143 } 7144 7145 /** 7146 * Mute/unmute the stream by AudioService 7147 * @param state the new mute state 7148 * @return true if the mute state was changed 7149 */ muteInternally(boolean state)7150 public boolean muteInternally(boolean state) { 7151 boolean changed = false; 7152 synchronized (VolumeStreamState.class) { 7153 if (state != mIsMutedInternally) { 7154 changed = true; 7155 mIsMutedInternally = state; 7156 // mute immediately to avoid delay and preemption when using a message. 7157 applyAllVolumes(); 7158 } 7159 } 7160 if (changed) { 7161 sVolumeLogger.log(new VolumeEvent( 7162 VolumeEvent.VOL_MUTE_STREAM_INT, mStreamType, state)); 7163 } 7164 return changed; 7165 } 7166 7167 @GuardedBy("VolumeStreamState.class") isFullyMuted()7168 public boolean isFullyMuted() { 7169 return mIsMuted || mIsMutedInternally; 7170 } 7171 getStreamType()7172 public int getStreamType() { 7173 return mStreamType; 7174 } 7175 checkFixedVolumeDevices()7176 public void checkFixedVolumeDevices() { 7177 synchronized (VolumeStreamState.class) { 7178 // ignore settings for fixed volume devices: volume should always be at max or 0 7179 if (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_MUSIC) { 7180 for (int i = 0; i < mIndexMap.size(); i++) { 7181 int device = mIndexMap.keyAt(i); 7182 int index = mIndexMap.valueAt(i); 7183 if (isFullVolumeDevice(device) 7184 || (isFixedVolumeDevice(device) && index != 0)) { 7185 mIndexMap.put(device, mIndexMax); 7186 } 7187 applyDeviceVolume_syncVSS(device); 7188 } 7189 } 7190 } 7191 } 7192 getValidIndex(int index, boolean hasModifyAudioSettings)7193 private int getValidIndex(int index, boolean hasModifyAudioSettings) { 7194 final int indexMin = hasModifyAudioSettings ? mIndexMin : mIndexMinNoPerm; 7195 if (index < indexMin) { 7196 return indexMin; 7197 } else if (mUseFixedVolume || index > mIndexMax) { 7198 return mIndexMax; 7199 } 7200 7201 return index; 7202 } 7203 dump(PrintWriter pw)7204 private void dump(PrintWriter pw) { 7205 pw.print(" Muted: "); 7206 pw.println(mIsMuted); 7207 pw.print(" Muted Internally: "); 7208 pw.println(mIsMutedInternally); 7209 pw.print(" Min: "); 7210 pw.print((mIndexMin + 5) / 10); 7211 if (mIndexMin != mIndexMinNoPerm) { 7212 pw.print(" w/o perm:"); 7213 pw.println((mIndexMinNoPerm + 5) / 10); 7214 } else { 7215 pw.println(); 7216 } 7217 pw.print(" Max: "); 7218 pw.println((mIndexMax + 5) / 10); 7219 pw.print(" streamVolume:"); pw.println(getStreamVolume(mStreamType)); 7220 pw.print(" Current: "); 7221 for (int i = 0; i < mIndexMap.size(); i++) { 7222 if (i > 0) { 7223 pw.print(", "); 7224 } 7225 final int device = mIndexMap.keyAt(i); 7226 pw.print(Integer.toHexString(device)); 7227 final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 7228 : AudioSystem.getOutputDeviceName(device); 7229 if (!deviceName.isEmpty()) { 7230 pw.print(" ("); 7231 pw.print(deviceName); 7232 pw.print(")"); 7233 } 7234 pw.print(": "); 7235 final int index = (mIndexMap.valueAt(i) + 5) / 10; 7236 pw.print(index); 7237 } 7238 pw.println(); 7239 pw.print(" Devices: "); 7240 final int devices = getDevicesForStreamInt(mStreamType); 7241 int device, i = 0, n = 0; 7242 // iterate all devices from 1 to DEVICE_OUT_DEFAULT exclusive 7243 // (the default device is not returned by getDevicesForStreamInt) 7244 while ((device = 1 << i) != AudioSystem.DEVICE_OUT_DEFAULT) { 7245 if ((devices & device) != 0) { 7246 if (n++ > 0) { 7247 pw.print(", "); 7248 } 7249 pw.print(AudioSystem.getOutputDeviceName(device)); 7250 } 7251 i++; 7252 } 7253 } 7254 } 7255 7256 /** Thread that handles native AudioSystem control. */ 7257 private class AudioSystemThread extends Thread { AudioSystemThread()7258 AudioSystemThread() { 7259 super("AudioService"); 7260 } 7261 7262 @Override run()7263 public void run() { 7264 // Set this thread up so the handler will work on it 7265 Looper.prepare(); 7266 7267 synchronized(AudioService.this) { 7268 mAudioHandler = new AudioHandler(); 7269 7270 // Notify that the handler has been created 7271 AudioService.this.notify(); 7272 } 7273 7274 // Listen for volume change requests that are set by VolumePanel 7275 Looper.loop(); 7276 } 7277 } 7278 7279 private static final class DeviceVolumeUpdate { 7280 final int mStreamType; 7281 final int mDevice; 7282 final @NonNull String mCaller; 7283 private static final int NO_NEW_INDEX = -2049; 7284 private final int mVssVolIndex; 7285 7286 // Constructor with volume index, meant to cause this volume to be set and applied for the 7287 // given stream type on the given device DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller)7288 DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller) { 7289 mStreamType = streamType; 7290 mVssVolIndex = vssVolIndex; 7291 mDevice = device; 7292 mCaller = caller; 7293 } 7294 7295 // Constructor with no volume index, meant to cause re-apply of volume for the given 7296 // stream type on the given device DeviceVolumeUpdate(int streamType, int device, @NonNull String caller)7297 DeviceVolumeUpdate(int streamType, int device, @NonNull String caller) { 7298 mStreamType = streamType; 7299 mVssVolIndex = NO_NEW_INDEX; 7300 mDevice = device; 7301 mCaller = caller; 7302 } 7303 hasVolumeIndex()7304 boolean hasVolumeIndex() { 7305 return mVssVolIndex != NO_NEW_INDEX; 7306 } 7307 getVolumeIndex()7308 int getVolumeIndex() throws IllegalStateException { 7309 Preconditions.checkState(mVssVolIndex != NO_NEW_INDEX); 7310 return mVssVolIndex; 7311 } 7312 } 7313 7314 /** only public for mocking/spying, do not call outside of AudioService */ 7315 @VisibleForTesting postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, String caller)7316 public void postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, 7317 String caller) { 7318 sendMsg(mAudioHandler, 7319 MSG_SET_DEVICE_STREAM_VOLUME, 7320 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/, 7321 new DeviceVolumeUpdate(streamType, vssVolIndex, device, caller), 7322 0 /*delay*/); 7323 } 7324 postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller)7325 /*package*/ void postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller) { 7326 sendMsg(mAudioHandler, 7327 MSG_SET_DEVICE_STREAM_VOLUME, 7328 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/, 7329 new DeviceVolumeUpdate(streamType, device, caller), 7330 0 /*delay*/); 7331 } 7332 onSetVolumeIndexOnDevice(@onNull DeviceVolumeUpdate update)7333 private void onSetVolumeIndexOnDevice(@NonNull DeviceVolumeUpdate update) { 7334 final VolumeStreamState streamState = mStreamStates[update.mStreamType]; 7335 if (update.hasVolumeIndex()) { 7336 int index = update.getVolumeIndex(); 7337 if (!checkSafeMediaVolume(update.mStreamType, index, update.mDevice)) { 7338 index = safeMediaVolumeIndex(update.mDevice); 7339 } 7340 streamState.setIndex(index, update.mDevice, update.mCaller, 7341 // trusted as index is always validated before message is posted 7342 true /*hasModifyAudioSettings*/); 7343 sVolumeLogger.log(new AudioEventLogger.StringEvent(update.mCaller + " dev:0x" 7344 + Integer.toHexString(update.mDevice) + " volIdx:" + index)); 7345 } else { 7346 sVolumeLogger.log(new AudioEventLogger.StringEvent(update.mCaller 7347 + " update vol on dev:0x" + Integer.toHexString(update.mDevice))); 7348 } 7349 setDeviceVolume(streamState, update.mDevice); 7350 } 7351 setDeviceVolume(VolumeStreamState streamState, int device)7352 /*package*/ void setDeviceVolume(VolumeStreamState streamState, int device) { 7353 7354 synchronized (VolumeStreamState.class) { 7355 // Apply volume 7356 streamState.applyDeviceVolume_syncVSS(device); 7357 7358 // Apply change to all streams using this one as alias 7359 int numStreamTypes = AudioSystem.getNumStreamTypes(); 7360 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 7361 if (streamType != streamState.mStreamType && 7362 mStreamVolumeAlias[streamType] == streamState.mStreamType) { 7363 // Make sure volume is also maxed out on A2DP device for aliased stream 7364 // that may have a different device selected 7365 int streamDevice = getDeviceForStream(streamType); 7366 if ((device != streamDevice) && mAvrcpAbsVolSupported 7367 && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)) { 7368 mStreamStates[streamType].applyDeviceVolume_syncVSS(device); 7369 } 7370 mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice); 7371 } 7372 } 7373 } 7374 // Post a persist volume msg 7375 sendMsg(mAudioHandler, 7376 MSG_PERSIST_VOLUME, 7377 SENDMSG_QUEUE, 7378 device, 7379 0, 7380 streamState, 7381 PERSIST_DELAY); 7382 7383 } 7384 7385 /** Handles internal volume messages in separate volume thread. */ 7386 private class AudioHandler extends Handler { 7387 setAllVolumes(VolumeStreamState streamState)7388 private void setAllVolumes(VolumeStreamState streamState) { 7389 7390 // Apply volume 7391 streamState.applyAllVolumes(); 7392 7393 // Apply change to all streams using this one as alias 7394 int numStreamTypes = AudioSystem.getNumStreamTypes(); 7395 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 7396 if (streamType != streamState.mStreamType && 7397 mStreamVolumeAlias[streamType] == streamState.mStreamType) { 7398 mStreamStates[streamType].applyAllVolumes(); 7399 } 7400 } 7401 } 7402 persistVolume(VolumeStreamState streamState, int device)7403 private void persistVolume(VolumeStreamState streamState, int device) { 7404 if (mUseFixedVolume) { 7405 return; 7406 } 7407 if (mIsSingleVolume && (streamState.mStreamType != AudioSystem.STREAM_MUSIC)) { 7408 return; 7409 } 7410 if (streamState.hasValidSettingsName()) { 7411 System.putIntForUser(mContentResolver, 7412 streamState.getSettingNameForDevice(device), 7413 (streamState.getIndex(device) + 5)/ 10, 7414 UserHandle.USER_CURRENT); 7415 } 7416 } 7417 persistRingerMode(int ringerMode)7418 private void persistRingerMode(int ringerMode) { 7419 if (mUseFixedVolume) { 7420 return; 7421 } 7422 Settings.Global.putInt(mContentResolver, Settings.Global.MODE_RINGER, ringerMode); 7423 } 7424 onPersistSafeVolumeState(int state)7425 private void onPersistSafeVolumeState(int state) { 7426 Settings.Global.putInt(mContentResolver, 7427 Settings.Global.AUDIO_SAFE_VOLUME_STATE, 7428 state); 7429 } 7430 onNotifyVolumeEvent(@onNull IAudioPolicyCallback apc, @AudioManager.VolumeAdjustment int direction)7431 private void onNotifyVolumeEvent(@NonNull IAudioPolicyCallback apc, 7432 @AudioManager.VolumeAdjustment int direction) { 7433 try { 7434 apc.notifyVolumeAdjust(direction); 7435 } catch(Exception e) { 7436 // nothing we can do about this. Do not log error, too much potential for spam 7437 } 7438 } 7439 7440 @Override handleMessage(Message msg)7441 public void handleMessage(Message msg) { 7442 switch (msg.what) { 7443 7444 case MSG_SET_DEVICE_VOLUME: 7445 setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1); 7446 break; 7447 7448 case MSG_SET_ALL_VOLUMES: 7449 setAllVolumes((VolumeStreamState) msg.obj); 7450 break; 7451 7452 case MSG_PERSIST_VOLUME: 7453 persistVolume((VolumeStreamState) msg.obj, msg.arg1); 7454 break; 7455 7456 case MSG_PERSIST_VOLUME_GROUP: 7457 final VolumeGroupState vgs = (VolumeGroupState) msg.obj; 7458 vgs.persistVolumeGroup(msg.arg1); 7459 break; 7460 7461 case MSG_PERSIST_RINGER_MODE: 7462 // note that the value persisted is the current ringer mode, not the 7463 // value of ringer mode as of the time the request was made to persist 7464 persistRingerMode(getRingerModeInternal()); 7465 break; 7466 7467 case MSG_AUDIO_SERVER_DIED: 7468 onAudioServerDied(); 7469 break; 7470 7471 case MSG_DISPATCH_AUDIO_SERVER_STATE: 7472 onDispatchAudioServerStateChange(msg.arg1 == 1); 7473 break; 7474 7475 case MSG_UNLOAD_SOUND_EFFECTS: 7476 mSfxHelper.unloadSoundEffects(); 7477 break; 7478 7479 case MSG_LOAD_SOUND_EFFECTS: 7480 { 7481 LoadSoundEffectReply reply = (LoadSoundEffectReply) msg.obj; 7482 if (mSystemReady) { 7483 mSfxHelper.loadSoundEffects(reply); 7484 } else { 7485 Log.w(TAG, "[schedule]loadSoundEffects() called before boot complete"); 7486 if (reply != null) { 7487 reply.run(false); 7488 } 7489 } 7490 } 7491 break; 7492 7493 case MSG_PLAY_SOUND_EFFECT: 7494 mSfxHelper.playSoundEffect(msg.arg1, msg.arg2); 7495 break; 7496 7497 case MSG_SET_FORCE_USE: 7498 { 7499 final String eventSource = (String) msg.obj; 7500 final int useCase = msg.arg1; 7501 final int config = msg.arg2; 7502 if (useCase == AudioSystem.FOR_MEDIA) { 7503 Log.wtf(TAG, "Invalid force use FOR_MEDIA in AudioService from " 7504 + eventSource); 7505 break; 7506 } 7507 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE 7508 + MediaMetrics.SEPARATOR + AudioSystem.forceUseUsageToString(useCase)) 7509 .set(MediaMetrics.Property.EVENT, "setForceUse") 7510 .set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource) 7511 .set(MediaMetrics.Property.FORCE_USE_MODE, 7512 AudioSystem.forceUseConfigToString(config)) 7513 .record(); 7514 sForceUseLogger.log( 7515 new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource)); 7516 mAudioSystem.setForceUse(useCase, config); 7517 } 7518 break; 7519 7520 case MSG_DISABLE_AUDIO_FOR_UID: 7521 mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */, 7522 msg.arg2 /* uid */); 7523 mAudioEventWakeLock.release(); 7524 break; 7525 7526 case MSG_INIT_STREAMS_VOLUMES: 7527 onInitStreamsAndVolumes(); 7528 mAudioEventWakeLock.release(); 7529 break; 7530 7531 case MSG_CHECK_MUSIC_ACTIVE: 7532 onCheckMusicActive((String) msg.obj); 7533 break; 7534 7535 case MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED: 7536 case MSG_CONFIGURE_SAFE_MEDIA_VOLUME: 7537 onConfigureSafeVolume((msg.what == MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED), 7538 (String) msg.obj); 7539 break; 7540 case MSG_PERSIST_SAFE_VOLUME_STATE: 7541 onPersistSafeVolumeState(msg.arg1); 7542 break; 7543 7544 case MSG_SYSTEM_READY: 7545 onSystemReady(); 7546 break; 7547 7548 case MSG_INDICATE_SYSTEM_READY: 7549 onIndicateSystemReady(); 7550 break; 7551 7552 case MSG_ACCESSORY_PLUG_MEDIA_UNMUTE: 7553 onAccessoryPlugMediaUnmute(msg.arg1); 7554 break; 7555 7556 case MSG_PERSIST_MUSIC_ACTIVE_MS: 7557 final int musicActiveMs = msg.arg1; 7558 Settings.Secure.putIntForUser(mContentResolver, 7559 Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS, musicActiveMs, 7560 UserHandle.USER_CURRENT); 7561 break; 7562 7563 case MSG_UNMUTE_STREAM: 7564 onUnmuteStream(msg.arg1, msg.arg2); 7565 break; 7566 7567 case MSG_DYN_POLICY_MIX_STATE_UPDATE: 7568 onDynPolicyMixStateUpdate((String) msg.obj, msg.arg1); 7569 break; 7570 7571 case MSG_NOTIFY_VOL_EVENT: 7572 onNotifyVolumeEvent((IAudioPolicyCallback) msg.obj, msg.arg1); 7573 break; 7574 7575 case MSG_ENABLE_SURROUND_FORMATS: 7576 onEnableSurroundFormats((ArrayList<Integer>) msg.obj); 7577 break; 7578 7579 case MSG_UPDATE_RINGER_MODE: 7580 onUpdateRingerModeServiceInt(); 7581 break; 7582 7583 case MSG_SET_DEVICE_STREAM_VOLUME: 7584 onSetVolumeIndexOnDevice((DeviceVolumeUpdate) msg.obj); 7585 break; 7586 7587 case MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS: 7588 onObserveDevicesForAllStreams(/*skipStream*/ msg.arg1); 7589 break; 7590 7591 case MSG_HDMI_VOLUME_CHECK: 7592 onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj); 7593 break; 7594 7595 case MSG_PLAYBACK_CONFIG_CHANGE: 7596 onPlaybackConfigChange((List<AudioPlaybackConfiguration>) msg.obj); 7597 break; 7598 case MSG_RECORDING_CONFIG_CHANGE: 7599 onRecordingConfigChange((List<AudioRecordingConfiguration>) msg.obj); 7600 break; 7601 7602 case MSG_BROADCAST_MICROPHONE_MUTE: 7603 mSystemServer.sendMicrophoneMuteChangedIntent(); 7604 break; 7605 7606 case MSG_CHECK_MODE_FOR_UID: 7607 synchronized (mDeviceBroker.mSetModeLock) { 7608 if (msg.obj == null) { 7609 break; 7610 } 7611 // Update active playback/recording for apps requesting IN_COMMUNICATION 7612 // mode after a grace period following the mode change 7613 SetModeDeathHandler h = (SetModeDeathHandler) msg.obj; 7614 if (mSetModeDeathHandlers.indexOf(h) < 0) { 7615 break; 7616 } 7617 boolean wasActive = h.isActive(); 7618 h.setPlaybackActive(mPlaybackMonitor.isPlaybackActiveForUid(h.getUid())); 7619 h.setRecordingActive(mRecordMonitor.isRecordingActiveForUid(h.getUid())); 7620 if (wasActive != h.isActive()) { 7621 onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(), 7622 mContext.getPackageName(), false /*force*/); 7623 } 7624 } 7625 break; 7626 7627 case MSG_STREAM_DEVICES_CHANGED: 7628 sendBroadcastToAll(((Intent) msg.obj) 7629 .putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_DEVICES, msg.arg1) 7630 .putExtra(AudioManager.EXTRA_VOLUME_STREAM_DEVICES, msg.arg2)); 7631 break; 7632 7633 case MSG_UPDATE_VOLUME_STATES_FOR_DEVICE: 7634 onUpdateVolumeStatesForAudioDevice(msg.arg1, (String) msg.obj); 7635 break; 7636 7637 case MSG_REINIT_VOLUMES: 7638 onReinitVolumes((String) msg.obj); 7639 break; 7640 7641 case MSG_UPDATE_A11Y_SERVICE_UIDS: 7642 onUpdateAccessibilityServiceUids(); 7643 break; 7644 7645 case MSG_UPDATE_AUDIO_MODE: 7646 synchronized (mDeviceBroker.mSetModeLock) { 7647 onUpdateAudioMode(msg.arg1, msg.arg2, (String) msg.obj, false /*force*/); 7648 } 7649 break; 7650 7651 case MSG_SET_A2DP_DEV_CONNECTION_STATE: 7652 mDeviceBroker.queueBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent( 7653 (AudioDeviceBroker.BtDeviceConnectionInfo) msg.obj); 7654 break; 7655 7656 case MSG_A2DP_DEV_CONFIG_CHANGE: 7657 mDeviceBroker.postBluetoothA2dpDeviceConfigChange((BluetoothDevice) msg.obj); 7658 break; 7659 7660 case MSG_DISPATCH_AUDIO_MODE: 7661 dispatchMode(msg.arg1); 7662 break; 7663 } 7664 } 7665 } 7666 7667 private class SettingsObserver extends ContentObserver { 7668 SettingsObserver()7669 SettingsObserver() { 7670 super(new Handler()); 7671 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 7672 Settings.Global.ZEN_MODE), false, this); 7673 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 7674 Settings.Global.ZEN_MODE_CONFIG_ETAG), false, this); 7675 mContentResolver.registerContentObserver(Settings.System.getUriFor( 7676 Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this); 7677 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 7678 Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this); 7679 mContentResolver.registerContentObserver(Settings.System.getUriFor( 7680 Settings.System.MASTER_MONO), false, this); 7681 mContentResolver.registerContentObserver(Settings.System.getUriFor( 7682 Settings.System.MASTER_BALANCE), false, this); 7683 7684 mEncodedSurroundMode = Settings.Global.getInt( 7685 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT, 7686 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 7687 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 7688 Settings.Global.ENCODED_SURROUND_OUTPUT), false, this); 7689 mEnabledSurroundFormats = Settings.Global.getString( 7690 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 7691 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 7692 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS), false, this); 7693 7694 mContentResolver.registerContentObserver(Settings.Secure.getUriFor( 7695 Settings.Secure.VOICE_INTERACTION_SERVICE), false, this); 7696 } 7697 7698 @Override onChange(boolean selfChange)7699 public void onChange(boolean selfChange) { 7700 super.onChange(selfChange); 7701 // FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode. 7702 // However there appear to be some missing locks around mRingerAndZenModeMutedStreams 7703 // and mRingerModeAffectedStreams, so will leave this synchronized for now. 7704 // mRingerAndZenModeMutedStreams and mMuteAffectedStreams are safe (only accessed once). 7705 synchronized (mSettingsLock) { 7706 if (updateRingerAndZenModeAffectedStreams()) { 7707 /* 7708 * Ensure all stream types that should be affected by ringer mode 7709 * are in the proper state. 7710 */ 7711 setRingerModeInt(getRingerModeInternal(), false); 7712 } 7713 readDockAudioSettings(mContentResolver); 7714 updateMasterMono(mContentResolver); 7715 updateMasterBalance(mContentResolver); 7716 updateEncodedSurroundOutput(); 7717 sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged); 7718 updateAssistantUId(false); 7719 } 7720 } 7721 updateEncodedSurroundOutput()7722 private void updateEncodedSurroundOutput() { 7723 int newSurroundMode = Settings.Global.getInt( 7724 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT, 7725 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 7726 // Did it change? 7727 if (mEncodedSurroundMode != newSurroundMode) { 7728 // Send to AudioPolicyManager 7729 sendEncodedSurroundMode(newSurroundMode, "SettingsObserver"); 7730 mDeviceBroker.toggleHdmiIfConnected_Async(); 7731 mEncodedSurroundMode = newSurroundMode; 7732 mSurroundModeChanged = true; 7733 } else { 7734 mSurroundModeChanged = false; 7735 } 7736 } 7737 } 7738 avrcpSupportsAbsoluteVolume(String address, boolean support)7739 public void avrcpSupportsAbsoluteVolume(String address, boolean support) { 7740 // address is not used for now, but may be used when multiple a2dp devices are supported 7741 sVolumeLogger.log(new AudioEventLogger.StringEvent("avrcpSupportsAbsoluteVolume addr=" 7742 + address + " support=" + support)); 7743 mDeviceBroker.setAvrcpAbsoluteVolumeSupported(support); 7744 setAvrcpAbsoluteVolumeSupported(support); 7745 } 7746 setAvrcpAbsoluteVolumeSupported(boolean support)7747 /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean support) { 7748 mAvrcpAbsVolSupported = support; 7749 sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE, 7750 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, 7751 mStreamStates[AudioSystem.STREAM_MUSIC], 0); 7752 } 7753 7754 /** 7755 * @return true if there is currently a registered dynamic mixing policy that affects media 7756 * and is not a render + loopback policy 7757 */ 7758 // only public for mocking/spying 7759 @VisibleForTesting hasMediaDynamicPolicy()7760 public boolean hasMediaDynamicPolicy() { 7761 synchronized (mAudioPolicies) { 7762 if (mAudioPolicies.isEmpty()) { 7763 return false; 7764 } 7765 final Collection<AudioPolicyProxy> appColl = mAudioPolicies.values(); 7766 for (AudioPolicyProxy app : appColl) { 7767 if (app.hasMixAffectingUsage(AudioAttributes.USAGE_MEDIA, 7768 AudioMix.ROUTE_FLAG_LOOP_BACK_RENDER)) { 7769 return true; 7770 } 7771 } 7772 return false; 7773 } 7774 } 7775 7776 /** only public for mocking/spying, do not call outside of AudioService */ 7777 @VisibleForTesting checkMusicActive(int deviceType, String caller)7778 public void checkMusicActive(int deviceType, String caller) { 7779 if (mSafeMediaVolumeDevices.contains(deviceType)) { 7780 sendMsg(mAudioHandler, 7781 MSG_CHECK_MUSIC_ACTIVE, 7782 SENDMSG_REPLACE, 7783 0, 7784 0, 7785 caller, 7786 MUSIC_ACTIVE_POLL_PERIOD_MS); 7787 } 7788 } 7789 7790 /** 7791 * Receiver for misc intent broadcasts the Phone app cares about. 7792 */ 7793 private class AudioServiceBroadcastReceiver extends BroadcastReceiver { 7794 @Override onReceive(Context context, Intent intent)7795 public void onReceive(Context context, Intent intent) { 7796 final String action = intent.getAction(); 7797 int outDevice; 7798 int inDevice; 7799 int state; 7800 7801 if (action.equals(Intent.ACTION_DOCK_EVENT)) { 7802 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 7803 Intent.EXTRA_DOCK_STATE_UNDOCKED); 7804 int config; 7805 switch (dockState) { 7806 case Intent.EXTRA_DOCK_STATE_DESK: 7807 config = AudioSystem.FORCE_BT_DESK_DOCK; 7808 break; 7809 case Intent.EXTRA_DOCK_STATE_CAR: 7810 config = AudioSystem.FORCE_BT_CAR_DOCK; 7811 break; 7812 case Intent.EXTRA_DOCK_STATE_LE_DESK: 7813 config = AudioSystem.FORCE_ANALOG_DOCK; 7814 break; 7815 case Intent.EXTRA_DOCK_STATE_HE_DESK: 7816 config = AudioSystem.FORCE_DIGITAL_DOCK; 7817 break; 7818 case Intent.EXTRA_DOCK_STATE_UNDOCKED: 7819 default: 7820 config = AudioSystem.FORCE_NONE; 7821 } 7822 // Low end docks have a menu to enable or disable audio 7823 // (see mDockAudioMediaEnabled) 7824 if (!((dockState == Intent.EXTRA_DOCK_STATE_LE_DESK) 7825 || ((dockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) 7826 && (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK)))) { 7827 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, config, 7828 "ACTION_DOCK_EVENT intent"); 7829 } 7830 mDockState = dockState; 7831 } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED) 7832 || action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { 7833 mDeviceBroker.receiveBtEvent(intent); 7834 } else if (action.equals(Intent.ACTION_SCREEN_ON)) { 7835 if (mMonitorRotation) { 7836 RotationHelper.enable(); 7837 } 7838 AudioSystem.setParameters("screen_state=on"); 7839 } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { 7840 if (mMonitorRotation) { 7841 //reduce wakeups (save current) by only listening when display is on 7842 RotationHelper.disable(); 7843 } 7844 AudioSystem.setParameters("screen_state=off"); 7845 } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) { 7846 handleConfigurationChanged(context); 7847 } else if (action.equals(Intent.ACTION_USER_SWITCHED)) { 7848 if (mUserSwitchedReceived) { 7849 // attempt to stop music playback for background user except on first user 7850 // switch (i.e. first boot) 7851 mDeviceBroker.postBroadcastBecomingNoisy(); 7852 } 7853 mUserSwitchedReceived = true; 7854 // the current audio focus owner is no longer valid 7855 mMediaFocusControl.discardAudioFocusOwner(); 7856 7857 if (mSupportsMicPrivacyToggle) { 7858 mMicMuteFromPrivacyToggle = mSensorPrivacyManagerInternal 7859 .isSensorPrivacyEnabled(getCurrentUserId(), 7860 SensorPrivacyManager.Sensors.MICROPHONE); 7861 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); 7862 } 7863 7864 // load volume settings for new user 7865 readAudioSettings(true /*userSwitch*/); 7866 // preserve STREAM_MUSIC volume from one user to the next. 7867 sendMsg(mAudioHandler, 7868 MSG_SET_ALL_VOLUMES, 7869 SENDMSG_QUEUE, 7870 0, 7871 0, 7872 mStreamStates[AudioSystem.STREAM_MUSIC], 0); 7873 } else if (action.equals(Intent.ACTION_USER_BACKGROUND)) { 7874 // Disable audio recording for the background user/profile 7875 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 7876 if (userId >= 0) { 7877 // TODO Kill recording streams instead of killing processes holding permission 7878 UserInfo userInfo = UserManagerService.getInstance().getUserInfo(userId); 7879 killBackgroundUserProcessesWithRecordAudioPermission(userInfo); 7880 } 7881 UserManagerService.getInstance().setUserRestriction( 7882 UserManager.DISALLOW_RECORD_AUDIO, true, userId); 7883 } else if (action.equals(Intent.ACTION_USER_FOREGROUND)) { 7884 // Enable audio recording for foreground user/profile 7885 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 7886 UserManagerService.getInstance().setUserRestriction( 7887 UserManager.DISALLOW_RECORD_AUDIO, false, userId); 7888 } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { 7889 state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); 7890 if (state == BluetoothAdapter.STATE_OFF || 7891 state == BluetoothAdapter.STATE_TURNING_OFF) { 7892 mDeviceBroker.disconnectAllBluetoothProfiles(); 7893 } 7894 } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) || 7895 action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) { 7896 handleAudioEffectBroadcast(context, intent); 7897 } else if (action.equals(Intent.ACTION_PACKAGES_SUSPENDED)) { 7898 final int[] suspendedUids = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST); 7899 final String[] suspendedPackages = 7900 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 7901 if (suspendedPackages == null || suspendedUids == null 7902 || suspendedPackages.length != suspendedUids.length) { 7903 return; 7904 } 7905 for (int i = 0; i < suspendedUids.length; i++) { 7906 if (!TextUtils.isEmpty(suspendedPackages[i])) { 7907 mMediaFocusControl.noFocusForSuspendedApp( 7908 suspendedPackages[i], suspendedUids[i]); 7909 } 7910 } 7911 } 7912 } 7913 } // end class AudioServiceBroadcastReceiver 7914 7915 private class AudioServiceUserRestrictionsListener implements UserRestrictionsListener { 7916 7917 @Override onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions)7918 public void onUserRestrictionsChanged(int userId, Bundle newRestrictions, 7919 Bundle prevRestrictions) { 7920 // Update mic mute state. 7921 { 7922 final boolean wasRestricted = 7923 prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE); 7924 final boolean isRestricted = 7925 newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE); 7926 if (wasRestricted != isRestricted) { 7927 mMicMuteFromRestrictions = isRestricted; 7928 setMicrophoneMuteNoCallerCheck(userId); 7929 } 7930 } 7931 7932 // Update speaker mute state. 7933 { 7934 final boolean wasRestricted = 7935 prevRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME) 7936 || prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE); 7937 final boolean isRestricted = 7938 newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME) 7939 || newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE); 7940 if (wasRestricted != isRestricted) { 7941 setMasterMuteInternalNoCallerCheck(isRestricted, /* flags =*/ 0, userId); 7942 } 7943 } 7944 } 7945 } // end class AudioServiceUserRestrictionsListener 7946 handleAudioEffectBroadcast(Context context, Intent intent)7947 private void handleAudioEffectBroadcast(Context context, Intent intent) { 7948 String target = intent.getPackage(); 7949 if (target != null) { 7950 Log.w(TAG, "effect broadcast already targeted to " + target); 7951 return; 7952 } 7953 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 7954 // TODO this should target a user-selected panel 7955 List<ResolveInfo> ril = context.getPackageManager().queryBroadcastReceivers( 7956 intent, 0 /* flags */); 7957 if (ril != null && ril.size() != 0) { 7958 ResolveInfo ri = ril.get(0); 7959 if (ri != null && ri.activityInfo != null && ri.activityInfo.packageName != null) { 7960 intent.setPackage(ri.activityInfo.packageName); 7961 context.sendBroadcastAsUser(intent, UserHandle.ALL); 7962 return; 7963 } 7964 } 7965 Log.w(TAG, "couldn't find receiver package for effect intent"); 7966 } 7967 killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser)7968 private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) { 7969 PackageManager pm = mContext.getPackageManager(); 7970 // Find the home activity of the user. It should not be killed to avoid expensive restart, 7971 // when the user switches back. For managed profiles, we should kill all recording apps 7972 ComponentName homeActivityName = null; 7973 if (!oldUser.isManagedProfile()) { 7974 homeActivityName = LocalServices.getService( 7975 ActivityTaskManagerInternal.class).getHomeActivityForUser(oldUser.id); 7976 } 7977 final String[] permissions = { Manifest.permission.RECORD_AUDIO }; 7978 List<PackageInfo> packages; 7979 try { 7980 packages = AppGlobals.getPackageManager() 7981 .getPackagesHoldingPermissions(permissions, 0, oldUser.id).getList(); 7982 } catch (RemoteException e) { 7983 throw new AndroidRuntimeException(e); 7984 } 7985 for (int j = packages.size() - 1; j >= 0; j--) { 7986 PackageInfo pkg = packages.get(j); 7987 // Skip system processes 7988 if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) { 7989 continue; 7990 } 7991 // Skip packages that have permission to interact across users 7992 if (pm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS, pkg.packageName) 7993 == PackageManager.PERMISSION_GRANTED) { 7994 continue; 7995 } 7996 if (homeActivityName != null 7997 && pkg.packageName.equals(homeActivityName.getPackageName()) 7998 && pkg.applicationInfo.isSystemApp()) { 7999 continue; 8000 } 8001 try { 8002 final int uid = pkg.applicationInfo.uid; 8003 ActivityManager.getService().killUid(UserHandle.getAppId(uid), 8004 UserHandle.getUserId(uid), 8005 "killBackgroundUserProcessesWithAudioRecordPermission"); 8006 } catch (RemoteException e) { 8007 Log.w(TAG, "Error calling killUid", e); 8008 } 8009 } 8010 } 8011 8012 8013 //========================================================================================== 8014 // Audio Focus 8015 //========================================================================================== 8016 /** 8017 * Returns whether a focus request is eligible to force ducking. 8018 * Will return true if: 8019 * - the AudioAttributes have a usage of USAGE_ASSISTANCE_ACCESSIBILITY, 8020 * - the focus request is AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 8021 * - the associated Bundle has KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING set to true, 8022 * - the uid of the requester is a known accessibility service or root. 8023 * @param aa AudioAttributes of the focus request 8024 * @param uid uid of the focus requester 8025 * @return true if ducking is to be forced 8026 */ forceFocusDuckingForAccessibility(@ullable AudioAttributes aa, int request, int uid)8027 private boolean forceFocusDuckingForAccessibility(@Nullable AudioAttributes aa, 8028 int request, int uid) { 8029 if (aa == null || aa.getUsage() != AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY 8030 || request != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) { 8031 return false; 8032 } 8033 final Bundle extraInfo = aa.getBundle(); 8034 if (extraInfo == null || 8035 !extraInfo.getBoolean(AudioFocusRequest.KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING)) { 8036 return false; 8037 } 8038 if (uid == 0) { 8039 return true; 8040 } 8041 synchronized (mAccessibilityServiceUidsLock) { 8042 if (mAccessibilityServiceUids != null) { 8043 int callingUid = Binder.getCallingUid(); 8044 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 8045 if (mAccessibilityServiceUids[i] == callingUid) { 8046 return true; 8047 } 8048 } 8049 } 8050 } 8051 return false; 8052 } 8053 isSupportedSystemUsage(@udioAttributes.AttributeUsage int usage)8054 private boolean isSupportedSystemUsage(@AudioAttributes.AttributeUsage int usage) { 8055 synchronized (mSupportedSystemUsagesLock) { 8056 for (int i = 0; i < mSupportedSystemUsages.length; i++) { 8057 if (mSupportedSystemUsages[i] == usage) { 8058 return true; 8059 } 8060 } 8061 return false; 8062 } 8063 } 8064 validateAudioAttributesUsage(@onNull AudioAttributes audioAttributes)8065 private void validateAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) { 8066 @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage(); 8067 if (AudioAttributes.isSystemUsage(usage)) { 8068 if (callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)) { 8069 if (!isSupportedSystemUsage(usage)) { 8070 throw new IllegalArgumentException( 8071 "Unsupported usage " + AudioAttributes.usageToString(usage)); 8072 } 8073 } else { 8074 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission"); 8075 } 8076 } 8077 } 8078 isValidAudioAttributesUsage(@onNull AudioAttributes audioAttributes)8079 private boolean isValidAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) { 8080 @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage(); 8081 if (AudioAttributes.isSystemUsage(usage)) { 8082 return callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING) 8083 && isSupportedSystemUsage(usage); 8084 } 8085 return true; 8086 } 8087 requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags, IAudioPolicyCallback pcb, int sdk)8088 public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, 8089 IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags, 8090 IAudioPolicyCallback pcb, int sdk) { 8091 final int uid = Binder.getCallingUid(); 8092 MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus") 8093 .setUid(uid) 8094 //.putInt("durationHint", durationHint) 8095 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) 8096 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 8097 .set(MediaMetrics.Property.EVENT, "requestAudioFocus") 8098 .set(MediaMetrics.Property.FLAGS, flags); 8099 8100 // permission checks 8101 if (aa != null && !isValidAudioAttributesUsage(aa)) { 8102 final String reason = "Request using unsupported usage"; 8103 Log.w(TAG, reason); 8104 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 8105 .record(); 8106 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 8107 } 8108 if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) { 8109 if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) { 8110 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 8111 android.Manifest.permission.MODIFY_PHONE_STATE)) { 8112 final String reason = "Invalid permission to (un)lock audio focus"; 8113 Log.e(TAG, reason, new Exception()); 8114 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 8115 .record(); 8116 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 8117 } 8118 } else { 8119 // only a registered audio policy can be used to lock focus 8120 synchronized (mAudioPolicies) { 8121 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 8122 final String reason = 8123 "Invalid unregistered AudioPolicy to (un)lock audio focus"; 8124 Log.e(TAG, reason); 8125 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 8126 .record(); 8127 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 8128 } 8129 } 8130 } 8131 } 8132 8133 if (callingPackageName == null || clientId == null || aa == null) { 8134 final String reason = "Invalid null parameter to request audio focus"; 8135 Log.e(TAG, reason); 8136 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 8137 .record(); 8138 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 8139 } 8140 mmi.record(); 8141 return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd, 8142 clientId, callingPackageName, flags, sdk, 8143 forceFocusDuckingForAccessibility(aa, durationHint, uid), -1 /*testUid, ignored*/); 8144 } 8145 8146 /** see {@link AudioManager#requestAudioFocusForTest(AudioFocusRequest, String, int, int)} */ requestAudioFocusForTest(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, int fakeUid, int sdk)8147 public int requestAudioFocusForTest(AudioAttributes aa, int durationHint, IBinder cb, 8148 IAudioFocusDispatcher fd, String clientId, String callingPackageName, 8149 int fakeUid, int sdk) { 8150 if (!enforceQueryAudioStateForTest("focus request")) { 8151 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 8152 } 8153 if (callingPackageName == null || clientId == null || aa == null) { 8154 final String reason = "Invalid null parameter to request audio focus"; 8155 Log.e(TAG, reason); 8156 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 8157 } 8158 return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd, 8159 clientId, callingPackageName, AudioManager.AUDIOFOCUS_FLAG_TEST, 8160 sdk, false /*forceDuck*/, fakeUid); 8161 } 8162 abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)8163 public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, 8164 String callingPackageName) { 8165 MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus") 8166 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) 8167 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 8168 .set(MediaMetrics.Property.EVENT, "abandonAudioFocus"); 8169 8170 if (aa != null && !isValidAudioAttributesUsage(aa)) { 8171 Log.w(TAG, "Request using unsupported usage."); 8172 mmi.set(MediaMetrics.Property.EARLY_RETURN, "unsupported usage").record(); 8173 8174 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 8175 } 8176 mmi.record(); 8177 return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName); 8178 } 8179 8180 /** see {@link AudioManager#abandonAudioFocusForTest(AudioFocusRequest, String)} */ abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)8181 public int abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, 8182 AudioAttributes aa, String callingPackageName) { 8183 if (!enforceQueryAudioStateForTest("focus abandon")) { 8184 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 8185 } 8186 return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName); 8187 } 8188 unregisterAudioFocusClient(String clientId)8189 public void unregisterAudioFocusClient(String clientId) { 8190 new MediaMetrics.Item(mMetricsId + "focus") 8191 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 8192 .set(MediaMetrics.Property.EVENT, "unregisterAudioFocusClient") 8193 .record(); 8194 mMediaFocusControl.unregisterAudioFocusClient(clientId); 8195 } 8196 getCurrentAudioFocus()8197 public int getCurrentAudioFocus() { 8198 return mMediaFocusControl.getCurrentAudioFocus(); 8199 } 8200 getFocusRampTimeMs(int focusGain, AudioAttributes attr)8201 public int getFocusRampTimeMs(int focusGain, AudioAttributes attr) { 8202 return mMediaFocusControl.getFocusRampTimeMs(focusGain, attr); 8203 } 8204 8205 /** only public for mocking/spying, do not call outside of AudioService */ 8206 @VisibleForTesting hasAudioFocusUsers()8207 public boolean hasAudioFocusUsers() { 8208 return mMediaFocusControl.hasAudioFocusUsers(); 8209 } 8210 8211 /** see {@link AudioManager#getFadeOutDurationOnFocusLossMillis(AudioAttributes)} */ getFadeOutDurationOnFocusLossMillis(AudioAttributes aa)8212 public long getFadeOutDurationOnFocusLossMillis(AudioAttributes aa) { 8213 if (!enforceQueryAudioStateForTest("fade out duration")) { 8214 return 0; 8215 } 8216 return mMediaFocusControl.getFadeOutDurationOnFocusLossMillis(aa); 8217 } 8218 enforceQueryAudioStateForTest(String mssg)8219 private boolean enforceQueryAudioStateForTest(String mssg) { 8220 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 8221 Manifest.permission.QUERY_AUDIO_STATE)) { 8222 final String reason = "Doesn't have QUERY_AUDIO_STATE permission for " 8223 + mssg + " test API"; 8224 Log.e(TAG, reason, new Exception()); 8225 return false; 8226 } 8227 return true; 8228 } 8229 8230 //========================================================================================== readCameraSoundForced()8231 private boolean readCameraSoundForced() { 8232 return SystemProperties.getBoolean("audio.camerasound.force", false) || 8233 mContext.getResources().getBoolean( 8234 com.android.internal.R.bool.config_camera_sound_forced); 8235 } 8236 8237 //========================================================================================== 8238 // Device orientation 8239 //========================================================================================== 8240 /** 8241 * Handles device configuration changes that may map to a change in rotation. 8242 * Monitoring rotation is optional, and is defined by the definition and value 8243 * of the "ro.audio.monitorRotation" system property. 8244 */ handleConfigurationChanged(Context context)8245 private void handleConfigurationChanged(Context context) { 8246 try { 8247 // reading new configuration "safely" (i.e. under try catch) in case anything 8248 // goes wrong. 8249 Configuration config = context.getResources().getConfiguration(); 8250 sendMsg(mAudioHandler, 8251 MSG_CONFIGURE_SAFE_MEDIA_VOLUME, 8252 SENDMSG_REPLACE, 8253 0, 8254 0, 8255 TAG, 8256 0); 8257 8258 boolean cameraSoundForced = readCameraSoundForced(); 8259 synchronized (mSettingsLock) { 8260 final boolean cameraSoundForcedChanged = (cameraSoundForced != mCameraSoundForced); 8261 mCameraSoundForced = cameraSoundForced; 8262 if (cameraSoundForcedChanged) { 8263 if (!mIsSingleVolume) { 8264 synchronized (VolumeStreamState.class) { 8265 VolumeStreamState s = mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED]; 8266 if (cameraSoundForced) { 8267 s.setAllIndexesToMax(); 8268 mRingerModeAffectedStreams &= 8269 ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 8270 } else { 8271 s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM], TAG); 8272 mRingerModeAffectedStreams |= 8273 (1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 8274 } 8275 } 8276 // take new state into account for streams muted by ringer mode 8277 setRingerModeInt(getRingerModeInternal(), false); 8278 } 8279 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, 8280 cameraSoundForced ? 8281 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE, 8282 "handleConfigurationChanged"); 8283 sendMsg(mAudioHandler, 8284 MSG_SET_ALL_VOLUMES, 8285 SENDMSG_QUEUE, 8286 0, 8287 0, 8288 mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED], 0); 8289 8290 } 8291 } 8292 mVolumeController.setLayoutDirection(config.getLayoutDirection()); 8293 } catch (Exception e) { 8294 Log.e(TAG, "Error handling configuration change: ", e); 8295 } 8296 } 8297 8298 @Override setRingtonePlayer(IRingtonePlayer player)8299 public void setRingtonePlayer(IRingtonePlayer player) { 8300 mContext.enforceCallingOrSelfPermission(REMOTE_AUDIO_PLAYBACK, null); 8301 mRingtonePlayer = player; 8302 } 8303 8304 @Override getRingtonePlayer()8305 public IRingtonePlayer getRingtonePlayer() { 8306 return mRingtonePlayer; 8307 } 8308 8309 @Override startWatchingRoutes(IAudioRoutesObserver observer)8310 public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) { 8311 return mDeviceBroker.startWatchingRoutes(observer); 8312 } 8313 8314 8315 //========================================================================================== 8316 // Safe media volume management. 8317 // MUSIC stream volume level is limited when headphones are connected according to safety 8318 // regulation. When the user attempts to raise the volume above the limit, a warning is 8319 // displayed and the user has to acknowlegde before the volume is actually changed. 8320 // The volume index corresponding to the limit is stored in config_safe_media_volume_index 8321 // property. Platforms with a different limit must set this property accordingly in their 8322 // overlay. 8323 //========================================================================================== 8324 8325 // mSafeMediaVolumeState indicates whether the media volume is limited over headphones. 8326 // It is SAFE_MEDIA_VOLUME_NOT_CONFIGURED at boot time until a network service is connected 8327 // or the configure time is elapsed. It is then set to SAFE_MEDIA_VOLUME_ACTIVE or 8328 // SAFE_MEDIA_VOLUME_DISABLED according to country option. If not SAFE_MEDIA_VOLUME_DISABLED, it 8329 // can be set to SAFE_MEDIA_VOLUME_INACTIVE by calling AudioService.disableSafeMediaVolume() 8330 // (when user opts out). 8331 private static final int SAFE_MEDIA_VOLUME_NOT_CONFIGURED = 0; 8332 private static final int SAFE_MEDIA_VOLUME_DISABLED = 1; 8333 private static final int SAFE_MEDIA_VOLUME_INACTIVE = 2; // confirmed 8334 private static final int SAFE_MEDIA_VOLUME_ACTIVE = 3; // unconfirmed 8335 private int mSafeMediaVolumeState; 8336 private final Object mSafeMediaVolumeStateLock = new Object(); 8337 8338 private int mMcc = 0; 8339 // mSafeMediaVolumeIndex is the cached value of config_safe_media_volume_index property 8340 private int mSafeMediaVolumeIndex; 8341 // mSafeUsbMediaVolumeDbfs is the cached value of the config_safe_media_volume_usb_mB 8342 // property, divided by 100.0. 8343 private float mSafeUsbMediaVolumeDbfs; 8344 // mSafeUsbMediaVolumeIndex is used for USB Headsets and is the music volume UI index 8345 // corresponding to a gain of mSafeUsbMediaVolumeDbfs (defaulting to -37dB) in audio 8346 // flinger mixer. 8347 // We remove -22 dBs from the theoretical -15dB to account for the EQ + bass boost 8348 // amplification when both effects are on with all band gains at maximum. 8349 // This level corresponds to a loudness of 85 dB SPL for the warning to be displayed when 8350 // the headset is compliant to EN 60950 with a max loudness of 100dB SPL. 8351 private int mSafeUsbMediaVolumeIndex; 8352 // mSafeMediaVolumeDevices lists the devices for which safe media volume is enforced, 8353 /*package*/ final Set<Integer> mSafeMediaVolumeDevices = new HashSet<>( 8354 Arrays.asList(AudioSystem.DEVICE_OUT_WIRED_HEADSET, 8355 AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, AudioSystem.DEVICE_OUT_USB_HEADSET)); 8356 // mMusicActiveMs is the cumulative time of music activity since safe volume was disabled. 8357 // When this time reaches UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX, the safe media volume is re-enabled 8358 // automatically. mMusicActiveMs is rounded to a multiple of MUSIC_ACTIVE_POLL_PERIOD_MS. 8359 private int mMusicActiveMs; 8360 private static final int UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX = (20 * 3600 * 1000); // 20 hours 8361 private static final int MUSIC_ACTIVE_POLL_PERIOD_MS = 60000; // 1 minute polling interval 8362 private static final int SAFE_VOLUME_CONFIGURE_TIMEOUT_MS = 30000; // 30s after boot completed 8363 // check playback or record activity every 6 seconds for UIDs owning mode IN_COMMUNICATION 8364 private static final int CHECK_MODE_FOR_UID_PERIOD_MS = 6000; 8365 safeMediaVolumeIndex(int device)8366 private int safeMediaVolumeIndex(int device) { 8367 if (!mSafeMediaVolumeDevices.contains(device)) { 8368 return MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]; 8369 } 8370 if (device == AudioSystem.DEVICE_OUT_USB_HEADSET) { 8371 return mSafeUsbMediaVolumeIndex; 8372 } else { 8373 return mSafeMediaVolumeIndex; 8374 } 8375 } 8376 setSafeMediaVolumeEnabled(boolean on, String caller)8377 private void setSafeMediaVolumeEnabled(boolean on, String caller) { 8378 synchronized (mSafeMediaVolumeStateLock) { 8379 if ((mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_NOT_CONFIGURED) && 8380 (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_DISABLED)) { 8381 if (on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE)) { 8382 mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE; 8383 enforceSafeMediaVolume(caller); 8384 } else if (!on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE)) { 8385 mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE; 8386 mMusicActiveMs = 1; // nonzero = confirmed 8387 saveMusicActiveMs(); 8388 sendMsg(mAudioHandler, 8389 MSG_CHECK_MUSIC_ACTIVE, 8390 SENDMSG_REPLACE, 8391 0, 8392 0, 8393 caller, 8394 MUSIC_ACTIVE_POLL_PERIOD_MS); 8395 } 8396 } 8397 } 8398 } 8399 enforceSafeMediaVolume(String caller)8400 private void enforceSafeMediaVolume(String caller) { 8401 VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC]; 8402 Set<Integer> devices = mSafeMediaVolumeDevices; 8403 8404 for (int device : devices) { 8405 int index = streamState.getIndex(device); 8406 if (index > safeMediaVolumeIndex(device)) { 8407 streamState.setIndex(safeMediaVolumeIndex(device), device, caller, 8408 true /*hasModifyAudioSettings*/); 8409 sendMsg(mAudioHandler, 8410 MSG_SET_DEVICE_VOLUME, 8411 SENDMSG_QUEUE, 8412 device, 8413 0, 8414 streamState, 8415 0); 8416 } 8417 } 8418 } 8419 checkSafeMediaVolume(int streamType, int index, int device)8420 private boolean checkSafeMediaVolume(int streamType, int index, int device) { 8421 synchronized (mSafeMediaVolumeStateLock) { 8422 if ((mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) 8423 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) 8424 && (mSafeMediaVolumeDevices.contains(device)) 8425 && (index > safeMediaVolumeIndex(device))) { 8426 return false; 8427 } 8428 return true; 8429 } 8430 } 8431 8432 @Override disableSafeMediaVolume(String callingPackage)8433 public void disableSafeMediaVolume(String callingPackage) { 8434 enforceVolumeController("disable the safe media volume"); 8435 synchronized (mSafeMediaVolumeStateLock) { 8436 setSafeMediaVolumeEnabled(false, callingPackage); 8437 if (mPendingVolumeCommand != null) { 8438 onSetStreamVolume(mPendingVolumeCommand.mStreamType, 8439 mPendingVolumeCommand.mIndex, 8440 mPendingVolumeCommand.mFlags, 8441 mPendingVolumeCommand.mDevice, 8442 callingPackage, true /*hasModifyAudioSettings*/); 8443 mPendingVolumeCommand = null; 8444 } 8445 } 8446 } 8447 8448 //========================================================================================== 8449 // Hdmi CEC: 8450 // - System audio mode: 8451 // If Hdmi Cec's system audio mode is on, audio service should send the volume change 8452 // to HdmiControlService so that the audio receiver can handle it. 8453 // - CEC sink: 8454 // OUT_HDMI becomes a "full volume device", i.e. output is always at maximum level 8455 // and volume changes won't be taken into account on this device. Volume adjustments 8456 // are transformed into key events for the HDMI playback client. 8457 //========================================================================================== 8458 8459 @GuardedBy("mHdmiClientLock") updateHdmiCecSinkLocked(boolean hdmiCecSink)8460 private void updateHdmiCecSinkLocked(boolean hdmiCecSink) { 8461 if (!hasDeviceVolumeBehavior(AudioSystem.DEVICE_OUT_HDMI)) { 8462 if (hdmiCecSink) { 8463 if (DEBUG_VOL) { 8464 Log.d(TAG, "CEC sink: setting HDMI as full vol device"); 8465 } 8466 addAudioSystemDeviceOutToFullVolumeDevices(AudioSystem.DEVICE_OUT_HDMI); 8467 } else { 8468 if (DEBUG_VOL) { 8469 Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device"); 8470 } 8471 // Android TV devices without CEC service apply software volume on 8472 // HDMI output 8473 removeAudioSystemDeviceOutFromFullVolumeDevices(AudioSystem.DEVICE_OUT_HDMI); 8474 } 8475 postUpdateVolumeStatesForAudioDevice(AudioSystem.DEVICE_OUT_HDMI, 8476 "HdmiPlaybackClient.DisplayStatusCallback"); 8477 } 8478 } 8479 8480 private class MyHdmiControlStatusChangeListenerCallback 8481 implements HdmiControlManager.HdmiControlStatusChangeListener { onStatusChange(@dmiControlManager.HdmiCecControl int isCecEnabled, boolean isCecAvailable)8482 public void onStatusChange(@HdmiControlManager.HdmiCecControl int isCecEnabled, 8483 boolean isCecAvailable) { 8484 synchronized (mHdmiClientLock) { 8485 if (mHdmiManager == null) return; 8486 boolean cecEnabled = isCecEnabled == HdmiControlManager.HDMI_CEC_CONTROL_ENABLED; 8487 updateHdmiCecSinkLocked(cecEnabled ? isCecAvailable : false); 8488 } 8489 } 8490 }; 8491 8492 private class MyHdmiCecVolumeControlFeatureListener 8493 implements HdmiControlManager.HdmiCecVolumeControlFeatureListener { onHdmiCecVolumeControlFeature( @dmiControlManager.VolumeControl int hdmiCecVolumeControl)8494 public void onHdmiCecVolumeControlFeature( 8495 @HdmiControlManager.VolumeControl int hdmiCecVolumeControl) { 8496 synchronized (mHdmiClientLock) { 8497 if (mHdmiManager == null) return; 8498 mHdmiCecVolumeControlEnabled = 8499 hdmiCecVolumeControl == HdmiControlManager.VOLUME_CONTROL_ENABLED; 8500 } 8501 } 8502 }; 8503 8504 private final Object mHdmiClientLock = new Object(); 8505 8506 // If HDMI-CEC system audio is supported 8507 // Note that for CEC volume commands mHdmiCecVolumeControlEnabled will play a role on volume 8508 // commands 8509 private boolean mHdmiSystemAudioSupported = false; 8510 // Set only when device is tv. 8511 @GuardedBy("mHdmiClientLock") 8512 private HdmiTvClient mHdmiTvClient; 8513 // true if the device has system feature PackageManager.FEATURE_LEANBACK. 8514 // cached HdmiControlManager interface 8515 @GuardedBy("mHdmiClientLock") 8516 private HdmiControlManager mHdmiManager; 8517 // Set only when device is a set-top box. 8518 @GuardedBy("mHdmiClientLock") 8519 private HdmiPlaybackClient mHdmiPlaybackClient; 8520 // Set only when device is an audio system. 8521 @GuardedBy("mHdmiClientLock") 8522 private HdmiAudioSystemClient mHdmiAudioSystemClient; 8523 // True when volume control over HDMI CEC is used when CEC is enabled (meaningless otherwise) 8524 @GuardedBy("mHdmiClientLock") 8525 private boolean mHdmiCecVolumeControlEnabled; 8526 8527 private MyHdmiControlStatusChangeListenerCallback mHdmiControlStatusChangeListenerCallback = 8528 new MyHdmiControlStatusChangeListenerCallback(); 8529 8530 private MyHdmiCecVolumeControlFeatureListener mMyHdmiCecVolumeControlFeatureListener = 8531 new MyHdmiCecVolumeControlFeatureListener(); 8532 8533 @Override setHdmiSystemAudioSupported(boolean on)8534 public int setHdmiSystemAudioSupported(boolean on) { 8535 int device = AudioSystem.DEVICE_NONE; 8536 synchronized (mHdmiClientLock) { 8537 if (mHdmiManager != null) { 8538 if (mHdmiTvClient == null && mHdmiAudioSystemClient == null) { 8539 Log.w(TAG, "Only Hdmi-Cec enabled TV or audio system device supports" 8540 + "system audio mode."); 8541 return device; 8542 } 8543 if (mHdmiSystemAudioSupported != on) { 8544 mHdmiSystemAudioSupported = on; 8545 final int config = on ? AudioSystem.FORCE_HDMI_SYSTEM_AUDIO_ENFORCED : 8546 AudioSystem.FORCE_NONE; 8547 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_HDMI_SYSTEM_AUDIO, config, 8548 "setHdmiSystemAudioSupported"); 8549 } 8550 device = getDevicesForStreamInt(AudioSystem.STREAM_MUSIC); 8551 } 8552 } 8553 return device; 8554 } 8555 8556 @Override isHdmiSystemAudioSupported()8557 public boolean isHdmiSystemAudioSupported() { 8558 return mHdmiSystemAudioSupported; 8559 } 8560 8561 //========================================================================================== 8562 // Accessibility 8563 initA11yMonitoring()8564 private void initA11yMonitoring() { 8565 final AccessibilityManager accessibilityManager = 8566 (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); 8567 updateDefaultStreamOverrideDelay(accessibilityManager.isTouchExplorationEnabled()); 8568 updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive()); 8569 accessibilityManager.addTouchExplorationStateChangeListener(this, null); 8570 accessibilityManager.addAccessibilityServicesStateChangeListener(this, null); 8571 } 8572 8573 //--------------------------------------------------------------------------------- 8574 // A11y: taking touch exploration into account for selecting the default 8575 // stream override timeout when adjusting volume 8576 //--------------------------------------------------------------------------------- 8577 8578 // - STREAM_NOTIFICATION on tablets during this period after a notification stopped 8579 // - STREAM_RING on phones during this period after a notification stopped 8580 // - STREAM_MUSIC otherwise 8581 8582 private static final int DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS = 0; 8583 private static final int TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS = 1000; 8584 8585 private static int sStreamOverrideDelayMs; 8586 8587 @Override onTouchExplorationStateChanged(boolean enabled)8588 public void onTouchExplorationStateChanged(boolean enabled) { 8589 updateDefaultStreamOverrideDelay(enabled); 8590 } 8591 updateDefaultStreamOverrideDelay(boolean touchExploreEnabled)8592 private void updateDefaultStreamOverrideDelay(boolean touchExploreEnabled) { 8593 if (touchExploreEnabled) { 8594 sStreamOverrideDelayMs = TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS; 8595 } else { 8596 sStreamOverrideDelayMs = DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS; 8597 } 8598 if (DEBUG_VOL) Log.d(TAG, "Touch exploration enabled=" + touchExploreEnabled 8599 + " stream override delay is now " + sStreamOverrideDelayMs + " ms"); 8600 } 8601 8602 //--------------------------------------------------------------------------------- 8603 // A11y: taking a11y state into account for the handling of a11y prompts volume 8604 //--------------------------------------------------------------------------------- 8605 8606 private static boolean sIndependentA11yVolume = false; 8607 8608 // implementation of AccessibilityServicesStateChangeListener 8609 @Override onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager)8610 public void onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager) { 8611 updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive()); 8612 } 8613 updateA11yVolumeAlias(boolean a11VolEnabled)8614 private void updateA11yVolumeAlias(boolean a11VolEnabled) { 8615 if (DEBUG_VOL) Log.d(TAG, "Accessibility volume enabled = " + a11VolEnabled); 8616 if (sIndependentA11yVolume != a11VolEnabled) { 8617 sIndependentA11yVolume = a11VolEnabled; 8618 // update the volume mapping scheme 8619 updateStreamVolumeAlias(true /*updateVolumes*/, TAG); 8620 // update the volume controller behavior 8621 mVolumeController.setA11yMode(sIndependentA11yVolume ? 8622 VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME : 8623 VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME); 8624 mVolumeController.postVolumeChanged(AudioManager.STREAM_ACCESSIBILITY, 0); 8625 } 8626 } 8627 8628 //========================================================================================== 8629 // Camera shutter sound policy. 8630 // config_camera_sound_forced configuration option in config.xml defines if the camera shutter 8631 // sound is forced (sound even if the device is in silent mode) or not. This option is false by 8632 // default and can be overridden by country specific overlay in values-mccXXX/config.xml. 8633 //========================================================================================== 8634 8635 // cached value of com.android.internal.R.bool.config_camera_sound_forced 8636 @GuardedBy("mSettingsLock") 8637 private boolean mCameraSoundForced; 8638 8639 // called by android.hardware.Camera to populate CameraInfo.canDisableShutterSound isCameraSoundForced()8640 public boolean isCameraSoundForced() { 8641 synchronized (mSettingsLock) { 8642 return mCameraSoundForced; 8643 } 8644 } 8645 8646 //========================================================================================== 8647 // AudioService logging and dumpsys 8648 //========================================================================================== 8649 static final int LOG_NB_EVENTS_LIFECYCLE = 20; 8650 static final int LOG_NB_EVENTS_PHONE_STATE = 20; 8651 static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 30; 8652 static final int LOG_NB_EVENTS_FORCE_USE = 20; 8653 static final int LOG_NB_EVENTS_VOLUME = 40; 8654 static final int LOG_NB_EVENTS_DYN_POLICY = 10; 8655 8656 static final AudioEventLogger sLifecycleLogger = new AudioEventLogger(LOG_NB_EVENTS_LIFECYCLE, 8657 "audio services lifecycle"); 8658 8659 final private AudioEventLogger mModeLogger = new AudioEventLogger(LOG_NB_EVENTS_PHONE_STATE, 8660 "phone state (logged after successful call to AudioSystem.setPhoneState(int, int))"); 8661 8662 // logs for wired + A2DP device connections: 8663 // - wired: logged before onSetWiredDeviceConnectionState() is executed 8664 // - A2DP: logged at reception of method call 8665 /*package*/ static final AudioEventLogger sDeviceLogger = new AudioEventLogger( 8666 LOG_NB_EVENTS_DEVICE_CONNECTION, "wired/A2DP/hearing aid device connection"); 8667 8668 static final AudioEventLogger sForceUseLogger = new AudioEventLogger( 8669 LOG_NB_EVENTS_FORCE_USE, 8670 "force use (logged before setForceUse() is executed)"); 8671 8672 static final AudioEventLogger sVolumeLogger = new AudioEventLogger(LOG_NB_EVENTS_VOLUME, 8673 "volume changes (logged when command received by AudioService)"); 8674 8675 final private AudioEventLogger mDynPolicyLogger = new AudioEventLogger(LOG_NB_EVENTS_DYN_POLICY, 8676 "dynamic policy events (logged when command received by AudioService)"); 8677 8678 private static final String[] RINGER_MODE_NAMES = new String[] { 8679 "SILENT", 8680 "VIBRATE", 8681 "NORMAL" 8682 }; 8683 dumpRingerMode(PrintWriter pw)8684 private void dumpRingerMode(PrintWriter pw) { 8685 pw.println("\nRinger mode: "); 8686 pw.println("- mode (internal) = " + RINGER_MODE_NAMES[mRingerMode]); 8687 pw.println("- mode (external) = " + RINGER_MODE_NAMES[mRingerModeExternal]); 8688 pw.println("- zen mode:" + Settings.Global.zenModeToString(mNm.getZenMode())); 8689 dumpRingerModeStreams(pw, "affected", mRingerModeAffectedStreams); 8690 dumpRingerModeStreams(pw, "muted", mRingerAndZenModeMutedStreams); 8691 pw.print("- delegate = "); pw.println(mRingerModeDelegate); 8692 } 8693 dumpRingerModeStreams(PrintWriter pw, String type, int streams)8694 private void dumpRingerModeStreams(PrintWriter pw, String type, int streams) { 8695 pw.print("- ringer mode "); pw.print(type); pw.print(" streams = 0x"); 8696 pw.print(Integer.toHexString(streams)); 8697 if (streams != 0) { 8698 pw.print(" ("); 8699 boolean first = true; 8700 for (int i = 0; i < AudioSystem.STREAM_NAMES.length; i++) { 8701 final int stream = (1 << i); 8702 if ((streams & stream) != 0) { 8703 if (!first) pw.print(','); 8704 pw.print(AudioSystem.STREAM_NAMES[i]); 8705 streams &= ~stream; 8706 first = false; 8707 } 8708 } 8709 if (streams != 0) { 8710 if (!first) pw.print(','); 8711 pw.print(streams); 8712 } 8713 pw.print(')'); 8714 } 8715 pw.println(); 8716 } 8717 dumpDeviceTypes(@onNull Set<Integer> deviceTypes)8718 private String dumpDeviceTypes(@NonNull Set<Integer> deviceTypes) { 8719 Iterator<Integer> it = deviceTypes.iterator(); 8720 if (!it.hasNext()) { 8721 return ""; 8722 } 8723 final StringBuilder sb = new StringBuilder(); 8724 sb.append("0x" + Integer.toHexString(it.next())); 8725 while (it.hasNext()) { 8726 sb.append("," + "0x" + Integer.toHexString(it.next())); 8727 } 8728 return sb.toString(); 8729 } 8730 8731 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)8732 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8733 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 8734 8735 mAudioSystem.dump(pw); 8736 8737 sLifecycleLogger.dump(pw); 8738 if (mAudioHandler != null) { 8739 pw.println("\nMessage handler (watch for unhandled messages):"); 8740 mAudioHandler.dump(new PrintWriterPrinter(pw), " "); 8741 } else { 8742 pw.println("\nMessage handler is null"); 8743 } 8744 mMediaFocusControl.dump(pw); 8745 dumpStreamStates(pw); 8746 dumpVolumeGroups(pw); 8747 dumpRingerMode(pw); 8748 dumpAudioMode(pw); 8749 pw.println("\nAudio routes:"); 8750 pw.print(" mMainType=0x"); pw.println(Integer.toHexString( 8751 mDeviceBroker.getCurAudioRoutes().mainType)); 8752 pw.print(" mBluetoothName="); pw.println(mDeviceBroker.getCurAudioRoutes().bluetoothName); 8753 8754 pw.println("\nOther state:"); 8755 pw.print(" mVolumeController="); pw.println(mVolumeController); 8756 pw.print(" mSafeMediaVolumeState="); 8757 pw.println(safeMediaVolumeStateToString(mSafeMediaVolumeState)); 8758 pw.print(" mSafeMediaVolumeIndex="); pw.println(mSafeMediaVolumeIndex); 8759 pw.print(" mSafeUsbMediaVolumeIndex="); pw.println(mSafeUsbMediaVolumeIndex); 8760 pw.print(" mSafeUsbMediaVolumeDbfs="); pw.println(mSafeUsbMediaVolumeDbfs); 8761 pw.print(" sIndependentA11yVolume="); pw.println(sIndependentA11yVolume); 8762 pw.print(" mPendingVolumeCommand="); pw.println(mPendingVolumeCommand); 8763 pw.print(" mMusicActiveMs="); pw.println(mMusicActiveMs); 8764 pw.print(" mMcc="); pw.println(mMcc); 8765 pw.print(" mCameraSoundForced="); pw.println(mCameraSoundForced); 8766 pw.print(" mHasVibrator="); pw.println(mHasVibrator); 8767 pw.print(" mVolumePolicy="); pw.println(mVolumePolicy); 8768 pw.print(" mAvrcpAbsVolSupported="); pw.println(mAvrcpAbsVolSupported); 8769 pw.print(" mBtScoOnByApp="); pw.println(mBtScoOnByApp); 8770 pw.print(" mIsSingleVolume="); pw.println(mIsSingleVolume); 8771 pw.print(" mUseFixedVolume="); pw.println(mUseFixedVolume); 8772 pw.print(" mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices)); 8773 pw.print(" mFullVolumeDevices="); pw.println(dumpDeviceTypes(mFullVolumeDevices)); 8774 pw.print(" mExtVolumeController="); pw.println(mExtVolumeController); 8775 pw.print(" mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient); 8776 pw.print(" mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient); 8777 pw.print(" mHdmiTvClient="); pw.println(mHdmiTvClient); 8778 pw.print(" mHdmiSystemAudioSupported="); pw.println(mHdmiSystemAudioSupported); 8779 pw.print(" mHdmiCecVolumeControlEnabled="); pw.println(mHdmiCecVolumeControlEnabled); 8780 pw.print(" mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported); 8781 pw.print(" mic mute FromSwitch=" + mMicMuteFromSwitch 8782 + " FromRestrictions=" + mMicMuteFromRestrictions 8783 + " FromApi=" + mMicMuteFromApi 8784 + " from system=" + mMicMuteFromSystemCached); 8785 pw.print("\n mAssistantUid="); pw.println(mAssistantUid); 8786 pw.print(" mCurrentImeUid="); pw.println(mCurrentImeUid); 8787 dumpAccessibilityServiceUids(pw); 8788 8789 dumpAudioPolicies(pw); 8790 mDynPolicyLogger.dump(pw); 8791 mPlaybackMonitor.dump(pw); 8792 mRecordMonitor.dump(pw); 8793 8794 pw.println("\nAudioDeviceBroker:"); 8795 mDeviceBroker.dump(pw, " "); 8796 pw.println("\nSoundEffects:"); 8797 mSfxHelper.dump(pw, " "); 8798 8799 pw.println("\n"); 8800 pw.println("\nEvent logs:"); 8801 mModeLogger.dump(pw); 8802 pw.println("\n"); 8803 sDeviceLogger.dump(pw); 8804 pw.println("\n"); 8805 sForceUseLogger.dump(pw); 8806 pw.println("\n"); 8807 sVolumeLogger.dump(pw); 8808 pw.println("\n"); 8809 dumpSupportedSystemUsage(pw); 8810 } 8811 dumpSupportedSystemUsage(PrintWriter pw)8812 private void dumpSupportedSystemUsage(PrintWriter pw) { 8813 pw.println("Supported System Usages:"); 8814 synchronized (mSupportedSystemUsagesLock) { 8815 for (int i = 0; i < mSupportedSystemUsages.length; i++) { 8816 pw.printf("\t%s\n", AudioAttributes.usageToString(mSupportedSystemUsages[i])); 8817 } 8818 } 8819 } 8820 dumpAccessibilityServiceUids(PrintWriter pw)8821 private void dumpAccessibilityServiceUids(PrintWriter pw) { 8822 synchronized (mSupportedSystemUsagesLock) { 8823 if (mAccessibilityServiceUids != null && mAccessibilityServiceUids.length > 0) { 8824 pw.println(" Accessibility service Uids:"); 8825 for (int uid : mAccessibilityServiceUids) { 8826 pw.println(" - " + uid); 8827 } 8828 } else { 8829 pw.println(" No accessibility service Uids."); 8830 } 8831 } 8832 } 8833 8834 /** 8835 * Audio Analytics ids. 8836 */ 8837 private static final String mMetricsId = MediaMetrics.Name.AUDIO_SERVICE 8838 + MediaMetrics.SEPARATOR; 8839 safeMediaVolumeStateToString(int state)8840 private static String safeMediaVolumeStateToString(int state) { 8841 switch(state) { 8842 case SAFE_MEDIA_VOLUME_NOT_CONFIGURED: return "SAFE_MEDIA_VOLUME_NOT_CONFIGURED"; 8843 case SAFE_MEDIA_VOLUME_DISABLED: return "SAFE_MEDIA_VOLUME_DISABLED"; 8844 case SAFE_MEDIA_VOLUME_INACTIVE: return "SAFE_MEDIA_VOLUME_INACTIVE"; 8845 case SAFE_MEDIA_VOLUME_ACTIVE: return "SAFE_MEDIA_VOLUME_ACTIVE"; 8846 } 8847 return null; 8848 } 8849 8850 // Inform AudioFlinger of our device's low RAM attribute readAndSetLowRamDevice()8851 private static void readAndSetLowRamDevice() 8852 { 8853 boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic(); 8854 long totalMemory = 1024 * 1024 * 1024; // 1GB is the default if ActivityManager fails. 8855 8856 try { 8857 final ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo(); 8858 ActivityManager.getService().getMemoryInfo(info); 8859 totalMemory = info.totalMem; 8860 } catch (RemoteException e) { 8861 Log.w(TAG, "Cannot obtain MemoryInfo from ActivityManager, assume low memory device"); 8862 isLowRamDevice = true; 8863 } 8864 8865 final int status = AudioSystem.setLowRamDevice(isLowRamDevice, totalMemory); 8866 if (status != 0) { 8867 Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status); 8868 } 8869 } 8870 enforceVolumeController(String action)8871 private void enforceVolumeController(String action) { 8872 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE, 8873 "Only SystemUI can " + action); 8874 } 8875 8876 @Override setVolumeController(final IVolumeController controller)8877 public void setVolumeController(final IVolumeController controller) { 8878 enforceVolumeController("set the volume controller"); 8879 8880 // return early if things are not actually changing 8881 if (mVolumeController.isSameBinder(controller)) { 8882 return; 8883 } 8884 8885 // dismiss the old volume controller 8886 mVolumeController.postDismiss(); 8887 if (controller != null) { 8888 // we are about to register a new controller, listen for its death 8889 try { 8890 controller.asBinder().linkToDeath(new DeathRecipient() { 8891 @Override 8892 public void binderDied() { 8893 if (mVolumeController.isSameBinder(controller)) { 8894 Log.w(TAG, "Current remote volume controller died, unregistering"); 8895 setVolumeController(null); 8896 } 8897 } 8898 }, 0); 8899 } catch (RemoteException e) { 8900 // noop 8901 } 8902 } 8903 mVolumeController.setController(controller); 8904 if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController); 8905 } 8906 8907 @Override notifyVolumeControllerVisible(final IVolumeController controller, boolean visible)8908 public void notifyVolumeControllerVisible(final IVolumeController controller, boolean visible) { 8909 enforceVolumeController("notify about volume controller visibility"); 8910 8911 // return early if the controller is not current 8912 if (!mVolumeController.isSameBinder(controller)) { 8913 return; 8914 } 8915 8916 mVolumeController.setVisible(visible); 8917 if (DEBUG_VOL) Log.d(TAG, "Volume controller visible: " + visible); 8918 } 8919 8920 @Override setVolumePolicy(VolumePolicy policy)8921 public void setVolumePolicy(VolumePolicy policy) { 8922 enforceVolumeController("set volume policy"); 8923 if (policy != null && !policy.equals(mVolumePolicy)) { 8924 mVolumePolicy = policy; 8925 if (DEBUG_VOL) Log.d(TAG, "Volume policy changed: " + mVolumePolicy); 8926 } 8927 } 8928 8929 public class VolumeController { 8930 private static final String TAG = "VolumeController"; 8931 8932 private IVolumeController mController; 8933 private boolean mVisible; 8934 private long mNextLongPress; 8935 private int mLongPressTimeout; 8936 setController(IVolumeController controller)8937 public void setController(IVolumeController controller) { 8938 mController = controller; 8939 mVisible = false; 8940 } 8941 loadSettings(ContentResolver cr)8942 public void loadSettings(ContentResolver cr) { 8943 mLongPressTimeout = Settings.Secure.getIntForUser(cr, 8944 Settings.Secure.LONG_PRESS_TIMEOUT, 500, UserHandle.USER_CURRENT); 8945 } 8946 suppressAdjustment(int resolvedStream, int flags, boolean isMute)8947 public boolean suppressAdjustment(int resolvedStream, int flags, boolean isMute) { 8948 if (isMute) { 8949 return false; 8950 } 8951 boolean suppress = false; 8952 // Intended behavior: 8953 // 1/ if the stream is not the default UI stream, do not suppress (as it is not involved 8954 // in bringing up the UI) 8955 // 2/ if the resolved and default stream is MUSIC, and media is playing, do not suppress 8956 // 3/ otherwise suppress the first adjustments that occur during the "long press 8957 // timeout" interval. Note this is true regardless of whether this is a "real long 8958 // press" (where the user keeps pressing on the volume button), or repeated single 8959 // presses (here we don't know if we are in a real long press, or repeated fast 8960 // button presses). 8961 // Once the long press timeout occurs (mNextLongPress reset to 0), do not suppress. 8962 // Example: for a default and resolved stream of MUSIC, this allows modifying rapidly 8963 // the volume when media is playing (whether by long press or repeated individual 8964 // presses), or to bring up the volume UI when media is not playing, in order to make 8965 // another change (e.g. switch ringer modes) without changing media volume. 8966 if (resolvedStream == DEFAULT_VOL_STREAM_NO_PLAYBACK && mController != null) { 8967 // never suppress media vol adjustement during media playback 8968 if (resolvedStream == AudioSystem.STREAM_MUSIC 8969 && mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, mLongPressTimeout)) 8970 { 8971 // media is playing, adjust the volume right away 8972 return false; 8973 } 8974 8975 final long now = SystemClock.uptimeMillis(); 8976 if ((flags & AudioManager.FLAG_SHOW_UI) != 0 && !mVisible) { 8977 // UI is not visible yet, adjustment is ignored 8978 if (mNextLongPress < now) { 8979 mNextLongPress = now + mLongPressTimeout; 8980 } 8981 suppress = true; 8982 } else if (mNextLongPress > 0) { // in a long-press 8983 if (now > mNextLongPress) { 8984 // long press triggered, no more suppression 8985 mNextLongPress = 0; 8986 } else { 8987 // keep suppressing until the long press triggers 8988 suppress = true; 8989 } 8990 } 8991 } 8992 return suppress; 8993 } 8994 setVisible(boolean visible)8995 public void setVisible(boolean visible) { 8996 mVisible = visible; 8997 } 8998 isSameBinder(IVolumeController controller)8999 public boolean isSameBinder(IVolumeController controller) { 9000 return Objects.equals(asBinder(), binder(controller)); 9001 } 9002 asBinder()9003 public IBinder asBinder() { 9004 return binder(mController); 9005 } 9006 binder(IVolumeController controller)9007 private IBinder binder(IVolumeController controller) { 9008 return controller == null ? null : controller.asBinder(); 9009 } 9010 9011 @Override toString()9012 public String toString() { 9013 return "VolumeController(" + asBinder() + ",mVisible=" + mVisible + ")"; 9014 } 9015 postDisplaySafeVolumeWarning(int flags)9016 public void postDisplaySafeVolumeWarning(int flags) { 9017 if (mController == null) 9018 return; 9019 flags = flags | AudioManager.FLAG_SHOW_UI; 9020 try { 9021 mController.displaySafeVolumeWarning(flags); 9022 } catch (RemoteException e) { 9023 Log.w(TAG, "Error calling displaySafeVolumeWarning", e); 9024 } 9025 } 9026 postVolumeChanged(int streamType, int flags)9027 public void postVolumeChanged(int streamType, int flags) { 9028 if (mController == null) 9029 return; 9030 try { 9031 mController.volumeChanged(streamType, flags); 9032 } catch (RemoteException e) { 9033 Log.w(TAG, "Error calling volumeChanged", e); 9034 } 9035 } 9036 postMasterMuteChanged(int flags)9037 public void postMasterMuteChanged(int flags) { 9038 if (mController == null) 9039 return; 9040 try { 9041 mController.masterMuteChanged(flags); 9042 } catch (RemoteException e) { 9043 Log.w(TAG, "Error calling masterMuteChanged", e); 9044 } 9045 } 9046 setLayoutDirection(int layoutDirection)9047 public void setLayoutDirection(int layoutDirection) { 9048 if (mController == null) 9049 return; 9050 try { 9051 mController.setLayoutDirection(layoutDirection); 9052 } catch (RemoteException e) { 9053 Log.w(TAG, "Error calling setLayoutDirection", e); 9054 } 9055 } 9056 postDismiss()9057 public void postDismiss() { 9058 if (mController == null) 9059 return; 9060 try { 9061 mController.dismiss(); 9062 } catch (RemoteException e) { 9063 Log.w(TAG, "Error calling dismiss", e); 9064 } 9065 } 9066 setA11yMode(int a11yMode)9067 public void setA11yMode(int a11yMode) { 9068 if (mController == null) 9069 return; 9070 try { 9071 mController.setA11yMode(a11yMode); 9072 } catch (RemoteException e) { 9073 Log.w(TAG, "Error calling setA11Mode", e); 9074 } 9075 } 9076 } 9077 9078 /** 9079 * Interface for system components to get some extra functionality through 9080 * LocalServices. 9081 */ 9082 final class AudioServiceInternal extends AudioManagerInternal { 9083 @Override setRingerModeDelegate(RingerModeDelegate delegate)9084 public void setRingerModeDelegate(RingerModeDelegate delegate) { 9085 mRingerModeDelegate = delegate; 9086 if (mRingerModeDelegate != null) { 9087 synchronized (mSettingsLock) { 9088 updateRingerAndZenModeAffectedStreams(); 9089 } 9090 setRingerModeInternal(getRingerModeInternal(), TAG + ".setRingerModeDelegate"); 9091 } 9092 } 9093 9094 @Override getRingerModeInternal()9095 public int getRingerModeInternal() { 9096 return AudioService.this.getRingerModeInternal(); 9097 } 9098 9099 @Override setRingerModeInternal(int ringerMode, String caller)9100 public void setRingerModeInternal(int ringerMode, String caller) { 9101 AudioService.this.setRingerModeInternal(ringerMode, caller); 9102 } 9103 9104 @Override silenceRingerModeInternal(String caller)9105 public void silenceRingerModeInternal(String caller) { 9106 AudioService.this.silenceRingerModeInternal(caller); 9107 } 9108 9109 @Override updateRingerModeAffectedStreamsInternal()9110 public void updateRingerModeAffectedStreamsInternal() { 9111 synchronized (mSettingsLock) { 9112 if (updateRingerAndZenModeAffectedStreams()) { 9113 setRingerModeInt(getRingerModeInternal(), false); 9114 } 9115 } 9116 } 9117 9118 @Override setHotwordDetectionServiceUid(int uid)9119 public void setHotwordDetectionServiceUid(int uid) { 9120 synchronized (mHotwordDetectionServiceUidLock) { 9121 if (mHotwordDetectionServiceUid != uid) { 9122 mHotwordDetectionServiceUid = uid; 9123 AudioSystem.setHotwordDetectionServiceUid(mHotwordDetectionServiceUid); 9124 } 9125 } 9126 } 9127 9128 @Override setAccessibilityServiceUids(IntArray uids)9129 public void setAccessibilityServiceUids(IntArray uids) { 9130 synchronized (mAccessibilityServiceUidsLock) { 9131 if (uids.size() == 0) { 9132 mAccessibilityServiceUids = null; 9133 } else { 9134 boolean changed = (mAccessibilityServiceUids == null) 9135 || (mAccessibilityServiceUids.length != uids.size()); 9136 if (!changed) { 9137 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 9138 if (uids.get(i) != mAccessibilityServiceUids[i]) { 9139 changed = true; 9140 break; 9141 } 9142 } 9143 } 9144 if (changed) { 9145 mAccessibilityServiceUids = uids.toArray(); 9146 } 9147 } 9148 sendMsg(mAudioHandler, MSG_UPDATE_A11Y_SERVICE_UIDS, SENDMSG_REPLACE, 9149 0, 0, null, 0); 9150 } 9151 } 9152 9153 /** 9154 * {@inheritDoc} 9155 */ 9156 @Override setInputMethodServiceUid(int uid)9157 public void setInputMethodServiceUid(int uid) { 9158 synchronized (mInputMethodServiceUidLock) { 9159 if (mInputMethodServiceUid != uid) { 9160 mAudioSystem.setCurrentImeUid(uid); 9161 mInputMethodServiceUid = uid; 9162 } 9163 } 9164 } 9165 } 9166 onUpdateAccessibilityServiceUids()9167 private void onUpdateAccessibilityServiceUids() { 9168 int[] accessibilityServiceUids; 9169 synchronized (mAccessibilityServiceUidsLock) { 9170 accessibilityServiceUids = mAccessibilityServiceUids; 9171 } 9172 AudioSystem.setA11yServicesUids(accessibilityServiceUids); 9173 } 9174 9175 //========================================================================================== 9176 // Audio policy management 9177 //========================================================================================== registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)9178 public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, 9179 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, 9180 boolean isVolumeController, IMediaProjection projection) { 9181 AudioSystem.setDynamicPolicyCallback(mDynPolicyCallback); 9182 9183 if (!isPolicyRegisterAllowed(policyConfig, 9184 isFocusPolicy || isTestFocusPolicy || hasFocusListener, 9185 isVolumeController, 9186 projection)) { 9187 Slog.w(TAG, "Permission denied to register audio policy for pid " 9188 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid() 9189 + ", need MODIFY_AUDIO_ROUTING or MediaProjection that can project audio"); 9190 return null; 9191 } 9192 9193 String regId = null; 9194 synchronized (mAudioPolicies) { 9195 if (mAudioPolicies.containsKey(pcb.asBinder())) { 9196 Slog.e(TAG, "Cannot re-register policy"); 9197 return null; 9198 } 9199 try { 9200 AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, pcb, hasFocusListener, 9201 isFocusPolicy, isTestFocusPolicy, isVolumeController, projection); 9202 pcb.asBinder().linkToDeath(app, 0/*flags*/); 9203 9204 // logging after registration so we have the registration id 9205 mDynPolicyLogger.log((new AudioEventLogger.StringEvent("registerAudioPolicy for " 9206 + pcb.asBinder() + " u/pid:" + Binder.getCallingUid() + "/" 9207 + Binder.getCallingPid() + " with config:" + app.toCompactLogString())) 9208 .printLog(TAG)); 9209 9210 regId = app.getRegistrationId(); 9211 mAudioPolicies.put(pcb.asBinder(), app); 9212 } catch (RemoteException e) { 9213 // audio policy owner has already died! 9214 Slog.w(TAG, "Audio policy registration failed, could not link to " + pcb + 9215 " binder death", e); 9216 return null; 9217 } catch (IllegalStateException e) { 9218 Slog.w(TAG, "Audio policy registration failed for binder " + pcb, e); 9219 return null; 9220 } 9221 } 9222 return regId; 9223 } 9224 9225 /** 9226 * Apps with MODIFY_AUDIO_ROUTING can register any policy. 9227 * Apps with an audio capable MediaProjection are allowed to register a RENDER|LOOPBACK policy 9228 * as those policy do not modify the audio routing. 9229 */ isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, boolean hasFocusAccess, boolean isVolumeController, IMediaProjection projection)9230 private boolean isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, 9231 boolean hasFocusAccess, 9232 boolean isVolumeController, 9233 IMediaProjection projection) { 9234 9235 boolean requireValidProjection = false; 9236 boolean requireCaptureAudioOrMediaOutputPerm = false; 9237 boolean requireModifyRouting = false; 9238 ArrayList<AudioMix> voiceCommunicationCaptureMixes = null; 9239 9240 9241 if (hasFocusAccess || isVolumeController) { 9242 requireModifyRouting |= true; 9243 } else if (policyConfig.getMixes().isEmpty()) { 9244 // An empty policy could be used to lock the focus or add mixes later 9245 requireModifyRouting |= true; 9246 } 9247 for (AudioMix mix : policyConfig.getMixes()) { 9248 // If mix is requesting privileged capture 9249 if (mix.getRule().allowPrivilegedMediaPlaybackCapture()) { 9250 // then its format must be low quality enough 9251 String privilegedMediaCaptureError = 9252 mix.canBeUsedForPrivilegedMediaCapture(mix.getFormat()); 9253 if (privilegedMediaCaptureError != null) { 9254 Log.e(TAG, privilegedMediaCaptureError); 9255 return false; 9256 } 9257 // and it must have CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT permission 9258 requireCaptureAudioOrMediaOutputPerm |= true; 9259 9260 } 9261 // If mix is trying to explicitly capture USAGE_VOICE_COMMUNICATION 9262 if (mix.containsMatchAttributeRuleForUsage( 9263 AudioAttributes.USAGE_VOICE_COMMUNICATION) 9264 && (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER)) { 9265 // It must have CAPTURE_USAGE_VOICE_COMMUNICATION_OUTPUT permission 9266 // Note that for UID, USERID or EXCLDUE rules, the capture will be silenced 9267 // in AudioPolicyMix 9268 if (voiceCommunicationCaptureMixes == null) { 9269 voiceCommunicationCaptureMixes = new ArrayList<AudioMix>(); 9270 } 9271 voiceCommunicationCaptureMixes.add(mix); 9272 } 9273 9274 // If mix is RENDER|LOOPBACK, then an audio MediaProjection is enough 9275 // otherwise MODIFY_AUDIO_ROUTING permission is required 9276 if (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER && projection != null) { 9277 requireValidProjection |= true; 9278 } else { 9279 requireModifyRouting |= true; 9280 } 9281 } 9282 9283 if (requireCaptureAudioOrMediaOutputPerm 9284 && !callerHasPermission(android.Manifest.permission.CAPTURE_MEDIA_OUTPUT) 9285 && !callerHasPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT)) { 9286 Log.e(TAG, "Privileged audio capture requires CAPTURE_MEDIA_OUTPUT or " 9287 + "CAPTURE_AUDIO_OUTPUT system permission"); 9288 return false; 9289 } 9290 9291 if (voiceCommunicationCaptureMixes != null && voiceCommunicationCaptureMixes.size() > 0) { 9292 if (!callerHasPermission( 9293 android.Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT)) { 9294 Log.e(TAG, "Audio capture for voice communication requires " 9295 + "CAPTURE_VOICE_COMMUNICATION_OUTPUT system permission"); 9296 return false; 9297 } 9298 9299 // If permission check succeeded, we set the flag in each of the mixing rules 9300 for (AudioMix mix : voiceCommunicationCaptureMixes) { 9301 mix.getRule().setVoiceCommunicationCaptureAllowed(true); 9302 } 9303 } 9304 9305 if (requireValidProjection && !canProjectAudio(projection)) { 9306 return false; 9307 } 9308 9309 if (requireModifyRouting 9310 && !callerHasPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)) { 9311 Log.e(TAG, "Can not capture audio without MODIFY_AUDIO_ROUTING"); 9312 return false; 9313 } 9314 9315 return true; 9316 } 9317 callerHasPermission(String permission)9318 private boolean callerHasPermission(String permission) { 9319 return mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED; 9320 } 9321 9322 /** @return true if projection is a valid MediaProjection that can project audio. */ canProjectAudio(IMediaProjection projection)9323 private boolean canProjectAudio(IMediaProjection projection) { 9324 if (projection == null) { 9325 Log.e(TAG, "MediaProjection is null"); 9326 return false; 9327 } 9328 9329 IMediaProjectionManager projectionService = getProjectionService(); 9330 if (projectionService == null) { 9331 Log.e(TAG, "Can't get service IMediaProjectionManager"); 9332 return false; 9333 } 9334 9335 try { 9336 if (!projectionService.isValidMediaProjection(projection)) { 9337 Log.w(TAG, "App passed invalid MediaProjection token"); 9338 return false; 9339 } 9340 } catch (RemoteException e) { 9341 Log.e(TAG, "Can't call .isValidMediaProjection() on IMediaProjectionManager" 9342 + projectionService.asBinder(), e); 9343 return false; 9344 } 9345 9346 try { 9347 if (!projection.canProjectAudio()) { 9348 Log.w(TAG, "App passed MediaProjection that can not project audio"); 9349 return false; 9350 } 9351 } catch (RemoteException e) { 9352 Log.e(TAG, "Can't call .canProjectAudio() on valid IMediaProjection" 9353 + projection.asBinder(), e); 9354 return false; 9355 } 9356 9357 return true; 9358 } 9359 getProjectionService()9360 private IMediaProjectionManager getProjectionService() { 9361 if (mProjectionService == null) { 9362 IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE); 9363 mProjectionService = IMediaProjectionManager.Stub.asInterface(b); 9364 } 9365 return mProjectionService; 9366 } 9367 9368 /** 9369 * See {@link AudioManager#unregisterAudioPolicyAsync(AudioPolicy)} 9370 * Declared oneway 9371 * @param pcb nullable because on service interface 9372 */ unregisterAudioPolicyAsync(@ullable IAudioPolicyCallback pcb)9373 public void unregisterAudioPolicyAsync(@Nullable IAudioPolicyCallback pcb) { 9374 if (pcb == null) { 9375 return; 9376 } 9377 unregisterAudioPolicyInt(pcb, "unregisterAudioPolicyAsync"); 9378 } 9379 9380 /** 9381 * See {@link AudioManager#unregisterAudioPolicy(AudioPolicy)} 9382 * @param pcb nullable because on service interface 9383 */ unregisterAudioPolicy(@ullable IAudioPolicyCallback pcb)9384 public void unregisterAudioPolicy(@Nullable IAudioPolicyCallback pcb) { 9385 if (pcb == null) { 9386 return; 9387 } 9388 unregisterAudioPolicyInt(pcb, "unregisterAudioPolicy"); 9389 } 9390 9391 unregisterAudioPolicyInt(@onNull IAudioPolicyCallback pcb, String operationName)9392 private void unregisterAudioPolicyInt(@NonNull IAudioPolicyCallback pcb, String operationName) { 9393 mDynPolicyLogger.log((new AudioEventLogger.StringEvent(operationName + " for " 9394 + pcb.asBinder()).printLog(TAG))); 9395 synchronized (mAudioPolicies) { 9396 AudioPolicyProxy app = mAudioPolicies.remove(pcb.asBinder()); 9397 if (app == null) { 9398 Slog.w(TAG, "Trying to unregister unknown audio policy for pid " 9399 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()); 9400 return; 9401 } else { 9402 pcb.asBinder().unlinkToDeath(app, 0/*flags*/); 9403 } 9404 app.release(); 9405 } 9406 // TODO implement clearing mix attribute matching info in native audio policy 9407 } 9408 9409 /** 9410 * Checks whether caller has MODIFY_AUDIO_ROUTING permission, and the policy is registered. 9411 * @param errorMsg log warning if permission check failed. 9412 * @return null if the operation on the audio mixes should be cancelled. 9413 */ 9414 @GuardedBy("mAudioPolicies") checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg)9415 private AudioPolicyProxy checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg) { 9416 // permission check 9417 final boolean hasPermissionForPolicy = 9418 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 9419 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 9420 if (!hasPermissionForPolicy) { 9421 Slog.w(TAG, errorMsg + " for pid " + 9422 + Binder.getCallingPid() + " / uid " 9423 + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING"); 9424 return null; 9425 } 9426 // policy registered? 9427 final AudioPolicyProxy app = mAudioPolicies.get(pcb.asBinder()); 9428 if (app == null) { 9429 Slog.w(TAG, errorMsg + " for pid " + 9430 + Binder.getCallingPid() + " / uid " 9431 + Binder.getCallingUid() + ", unregistered policy"); 9432 return null; 9433 } 9434 return app; 9435 } 9436 addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)9437 public int addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) { 9438 if (DEBUG_AP) { Log.d(TAG, "addMixForPolicy for " + pcb.asBinder() 9439 + " with config:" + policyConfig); } 9440 synchronized (mAudioPolicies) { 9441 final AudioPolicyProxy app = 9442 checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy"); 9443 if (app == null){ 9444 return AudioManager.ERROR; 9445 } 9446 return app.addMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS 9447 ? AudioManager.SUCCESS : AudioManager.ERROR; 9448 } 9449 } 9450 removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)9451 public int removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) { 9452 if (DEBUG_AP) { Log.d(TAG, "removeMixForPolicy for " + pcb.asBinder() 9453 + " with config:" + policyConfig); } 9454 synchronized (mAudioPolicies) { 9455 final AudioPolicyProxy app = 9456 checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy"); 9457 if (app == null) { 9458 return AudioManager.ERROR; 9459 } 9460 return app.removeMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS 9461 ? AudioManager.SUCCESS : AudioManager.ERROR; 9462 } 9463 } 9464 9465 /** see AudioPolicy.setUidDeviceAffinity() */ setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)9466 public int setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, 9467 @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) { 9468 if (DEBUG_AP) { 9469 Log.d(TAG, "setUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid); 9470 } 9471 synchronized (mAudioPolicies) { 9472 final AudioPolicyProxy app = 9473 checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy"); 9474 if (app == null) { 9475 return AudioManager.ERROR; 9476 } 9477 if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) { 9478 return AudioManager.ERROR; 9479 } 9480 return app.setUidDeviceAffinities(uid, deviceTypes, deviceAddresses); 9481 } 9482 } 9483 9484 /** see AudioPolicy.setUserIdDeviceAffinity() */ setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)9485 public int setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, 9486 @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) { 9487 if (DEBUG_AP) { 9488 Log.d(TAG, "setUserIdDeviceAffinity for " + pcb.asBinder() + " user:" + userId); 9489 } 9490 9491 synchronized (mAudioPolicies) { 9492 final AudioPolicyProxy app = 9493 checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy"); 9494 if (app == null) { 9495 return AudioManager.ERROR; 9496 } 9497 if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) { 9498 return AudioManager.ERROR; 9499 } 9500 return app.setUserIdDeviceAffinities(userId, deviceTypes, deviceAddresses); 9501 } 9502 } 9503 9504 /** see AudioPolicy.removeUidDeviceAffinity() */ removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid)9505 public int removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid) { 9506 if (DEBUG_AP) { 9507 Log.d(TAG, "removeUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid); 9508 } 9509 synchronized (mAudioPolicies) { 9510 final AudioPolicyProxy app = 9511 checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy"); 9512 if (app == null) { 9513 return AudioManager.ERROR; 9514 } 9515 return app.removeUidDeviceAffinities(uid); 9516 } 9517 } 9518 9519 /** see AudioPolicy.removeUserIdDeviceAffinity() */ removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId)9520 public int removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId) { 9521 if (DEBUG_AP) { 9522 Log.d(TAG, "removeUserIdDeviceAffinity for " + pcb.asBinder() 9523 + " userId:" + userId); 9524 } 9525 synchronized (mAudioPolicies) { 9526 final AudioPolicyProxy app = 9527 checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy"); 9528 if (app == null) { 9529 return AudioManager.ERROR; 9530 } 9531 return app.removeUserIdDeviceAffinities(userId); 9532 } 9533 } 9534 setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb)9535 public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) { 9536 if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior 9537 + " policy " + pcb.asBinder()); 9538 synchronized (mAudioPolicies) { 9539 final AudioPolicyProxy app = 9540 checkUpdateForPolicy(pcb, "Cannot change audio policy focus properties"); 9541 if (app == null){ 9542 return AudioManager.ERROR; 9543 } 9544 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 9545 Slog.e(TAG, "Cannot change audio policy focus properties, unregistered policy"); 9546 return AudioManager.ERROR; 9547 } 9548 if (duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 9549 // is there already one policy managing ducking? 9550 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 9551 if (policy.mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 9552 Slog.e(TAG, "Cannot change audio policy ducking behavior, already handled"); 9553 return AudioManager.ERROR; 9554 } 9555 } 9556 } 9557 app.mFocusDuckBehavior = duckingBehavior; 9558 mMediaFocusControl.setDuckingInExtPolicyAvailable( 9559 duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY); 9560 } 9561 return AudioManager.SUCCESS; 9562 } 9563 9564 /** see AudioManager.hasRegisteredDynamicPolicy */ hasRegisteredDynamicPolicy()9565 public boolean hasRegisteredDynamicPolicy() { 9566 synchronized (mAudioPolicies) { 9567 return !mAudioPolicies.isEmpty(); 9568 } 9569 } 9570 9571 private final Object mExtVolumeControllerLock = new Object(); 9572 private IAudioPolicyCallback mExtVolumeController; setExtVolumeController(IAudioPolicyCallback apc)9573 private void setExtVolumeController(IAudioPolicyCallback apc) { 9574 if (!mContext.getResources().getBoolean( 9575 com.android.internal.R.bool.config_handleVolumeKeysInWindowManager)) { 9576 Log.e(TAG, "Cannot set external volume controller: device not set for volume keys" + 9577 " handled in PhoneWindowManager"); 9578 return; 9579 } 9580 synchronized (mExtVolumeControllerLock) { 9581 if (mExtVolumeController != null && !mExtVolumeController.asBinder().pingBinder()) { 9582 Log.e(TAG, "Cannot set external volume controller: existing controller"); 9583 } 9584 mExtVolumeController = apc; 9585 } 9586 } 9587 dumpAudioPolicies(PrintWriter pw)9588 private void dumpAudioPolicies(PrintWriter pw) { 9589 pw.println("\nAudio policies:"); 9590 synchronized (mAudioPolicies) { 9591 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 9592 pw.println(policy.toLogFriendlyString()); 9593 } 9594 } 9595 } 9596 9597 //====================== 9598 // Audio policy callbacks from AudioSystem for dynamic policies 9599 //====================== 9600 private final AudioSystem.DynamicPolicyCallback mDynPolicyCallback = 9601 new AudioSystem.DynamicPolicyCallback() { 9602 public void onDynamicPolicyMixStateUpdate(String regId, int state) { 9603 if (!TextUtils.isEmpty(regId)) { 9604 sendMsg(mAudioHandler, MSG_DYN_POLICY_MIX_STATE_UPDATE, SENDMSG_QUEUE, 9605 state /*arg1*/, 0 /*arg2 ignored*/, regId /*obj*/, 0 /*delay*/); 9606 } 9607 } 9608 }; 9609 onDynPolicyMixStateUpdate(String regId, int state)9610 private void onDynPolicyMixStateUpdate(String regId, int state) { 9611 if (DEBUG_AP) Log.d(TAG, "onDynamicPolicyMixStateUpdate("+ regId + ", " + state +")"); 9612 synchronized (mAudioPolicies) { 9613 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 9614 for (AudioMix mix : policy.getMixes()) { 9615 if (mix.getRegistration().equals(regId)) { 9616 try { 9617 policy.mPolicyCallback.notifyMixStateUpdate(regId, state); 9618 } catch (RemoteException e) { 9619 Log.e(TAG, "Can't call notifyMixStateUpdate() on IAudioPolicyCallback " 9620 + policy.mPolicyCallback.asBinder(), e); 9621 } 9622 return; 9623 } 9624 } 9625 } 9626 } 9627 } 9628 9629 //====================== 9630 // Audio policy callbacks from AudioSystem for recording configuration updates 9631 //====================== 9632 private final RecordingActivityMonitor mRecordMonitor; 9633 registerRecordingCallback(IRecordingConfigDispatcher rcdb)9634 public void registerRecordingCallback(IRecordingConfigDispatcher rcdb) { 9635 final boolean isPrivileged = 9636 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 9637 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 9638 mRecordMonitor.registerRecordingCallback(rcdb, isPrivileged); 9639 } 9640 unregisterRecordingCallback(IRecordingConfigDispatcher rcdb)9641 public void unregisterRecordingCallback(IRecordingConfigDispatcher rcdb) { 9642 mRecordMonitor.unregisterRecordingCallback(rcdb); 9643 } 9644 getActiveRecordingConfigurations()9645 public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() { 9646 final boolean isPrivileged = 9647 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 9648 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 9649 return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged); 9650 } 9651 9652 //====================== 9653 // Audio recording state notification from clients 9654 //====================== 9655 /** 9656 * Track a recorder provided by the client 9657 */ trackRecorder(IBinder recorder)9658 public int trackRecorder(IBinder recorder) { 9659 return mRecordMonitor.trackRecorder(recorder); 9660 } 9661 9662 /** 9663 * Receive an event from the client about a tracked recorder 9664 */ recorderEvent(int riid, int event)9665 public void recorderEvent(int riid, int event) { 9666 mRecordMonitor.recorderEvent(riid, event); 9667 } 9668 9669 /** 9670 * Stop tracking the recorder 9671 */ releaseRecorder(int riid)9672 public void releaseRecorder(int riid) { 9673 mRecordMonitor.releaseRecorder(riid); 9674 } 9675 disableRingtoneSync(final int userId)9676 public void disableRingtoneSync(final int userId) { 9677 final int callingUserId = UserHandle.getCallingUserId(); 9678 if (callingUserId != userId) { 9679 mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, 9680 "disable sound settings syncing for another profile"); 9681 } 9682 final long token = Binder.clearCallingIdentity(); 9683 try { 9684 // Disable the sync setting so the profile uses its own sound settings. 9685 Settings.Secure.putIntForUser(mContentResolver, Settings.Secure.SYNC_PARENT_SOUNDS, 9686 0 /* false */, userId); 9687 } finally { 9688 Binder.restoreCallingIdentity(token); 9689 } 9690 } 9691 9692 //====================== 9693 // Audio playback notification 9694 //====================== 9695 private final PlaybackActivityMonitor mPlaybackMonitor; 9696 registerPlaybackCallback(IPlaybackConfigDispatcher pcdb)9697 public void registerPlaybackCallback(IPlaybackConfigDispatcher pcdb) { 9698 final boolean isPrivileged = 9699 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 9700 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 9701 mPlaybackMonitor.registerPlaybackCallback(pcdb, isPrivileged); 9702 } 9703 unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb)9704 public void unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb) { 9705 mPlaybackMonitor.unregisterPlaybackCallback(pcdb); 9706 } 9707 getActivePlaybackConfigurations()9708 public List<AudioPlaybackConfiguration> getActivePlaybackConfigurations() { 9709 final boolean isPrivileged = 9710 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 9711 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 9712 return mPlaybackMonitor.getActivePlaybackConfigurations(isPrivileged); 9713 } 9714 trackPlayer(PlayerBase.PlayerIdCard pic)9715 public int trackPlayer(PlayerBase.PlayerIdCard pic) { 9716 if (pic != null && pic.mAttributes != null) { 9717 validateAudioAttributesUsage(pic.mAttributes); 9718 } 9719 return mPlaybackMonitor.trackPlayer(pic); 9720 } 9721 playerAttributes(int piid, AudioAttributes attr)9722 public void playerAttributes(int piid, AudioAttributes attr) { 9723 if (attr != null) { 9724 validateAudioAttributesUsage(attr); 9725 } 9726 mPlaybackMonitor.playerAttributes(piid, attr, Binder.getCallingUid()); 9727 } 9728 9729 /** 9730 * Update player session ID 9731 * @param piid Player id to update 9732 * @param sessionId The new audio session ID 9733 */ playerSessionId(int piid, int sessionId)9734 public void playerSessionId(int piid, int sessionId) { 9735 if (sessionId <= AudioSystem.AUDIO_SESSION_ALLOCATE) { 9736 throw new IllegalArgumentException("invalid session Id " + sessionId); 9737 } 9738 mPlaybackMonitor.playerSessionId(piid, sessionId, Binder.getCallingUid()); 9739 } 9740 9741 /** 9742 * Update player event 9743 * @param piid Player id to update 9744 * @param event The new player event 9745 * @param deviceId The new player device id 9746 */ playerEvent(int piid, int event, int deviceId)9747 public void playerEvent(int piid, int event, int deviceId) { 9748 mPlaybackMonitor.playerEvent(piid, event, deviceId, Binder.getCallingUid()); 9749 } 9750 playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio)9751 public void playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio) { 9752 mPlaybackMonitor.playerHasOpPlayAudio(piid, hasOpPlayAudio, Binder.getCallingUid()); 9753 } 9754 releasePlayer(int piid)9755 public void releasePlayer(int piid) { 9756 mPlaybackMonitor.releasePlayer(piid, Binder.getCallingUid()); 9757 } 9758 9759 /** 9760 * Specifies whether the audio played by this app may or may not be captured by other apps or 9761 * the system. 9762 * 9763 * @param capturePolicy one of 9764 * {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}, 9765 * {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM}, 9766 * {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}. 9767 * @return AudioSystem.AUDIO_STATUS_OK if set allowed capture policy succeed. 9768 * @throws IllegalArgumentException if the argument is not a valid value. 9769 */ setAllowedCapturePolicy(int capturePolicy)9770 public int setAllowedCapturePolicy(int capturePolicy) { 9771 int callingUid = Binder.getCallingUid(); 9772 int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0); 9773 final long identity = Binder.clearCallingIdentity(); 9774 synchronized (mPlaybackMonitor) { 9775 int result = mAudioSystem.setAllowedCapturePolicy(callingUid, flags); 9776 if (result == AudioSystem.AUDIO_STATUS_OK) { 9777 mPlaybackMonitor.setAllowedCapturePolicy(callingUid, capturePolicy); 9778 } 9779 Binder.restoreCallingIdentity(identity); 9780 return result; 9781 } 9782 } 9783 9784 /** 9785 * Return the capture policy. 9786 * @return the cached capture policy for the calling uid. 9787 */ getAllowedCapturePolicy()9788 public int getAllowedCapturePolicy() { 9789 int callingUid = Binder.getCallingUid(); 9790 final long identity = Binder.clearCallingIdentity(); 9791 int capturePolicy = mPlaybackMonitor.getAllowedCapturePolicy(callingUid); 9792 Binder.restoreCallingIdentity(identity); 9793 return capturePolicy; 9794 } 9795 9796 //====================== 9797 // Audio device management 9798 //====================== 9799 private final AudioDeviceBroker mDeviceBroker; 9800 9801 //====================== 9802 // Audio policy proxy 9803 //====================== 9804 private static final class AudioDeviceArray { 9805 final @NonNull int[] mDeviceTypes; 9806 final @NonNull String[] mDeviceAddresses; AudioDeviceArray(@onNull int[] types, @NonNull String[] addresses)9807 AudioDeviceArray(@NonNull int[] types, @NonNull String[] addresses) { 9808 mDeviceTypes = types; 9809 mDeviceAddresses = addresses; 9810 } 9811 } 9812 9813 /** 9814 * This internal class inherits from AudioPolicyConfig, each instance contains all the 9815 * mixes of an AudioPolicy and their configurations. 9816 */ 9817 public class AudioPolicyProxy extends AudioPolicyConfig implements IBinder.DeathRecipient { 9818 private static final String TAG = "AudioPolicyProxy"; 9819 final IAudioPolicyCallback mPolicyCallback; 9820 final boolean mHasFocusListener; 9821 final boolean mIsVolumeController; 9822 final HashMap<Integer, AudioDeviceArray> mUidDeviceAffinities = 9823 new HashMap<Integer, AudioDeviceArray>(); 9824 9825 final HashMap<Integer, AudioDeviceArray> mUserIdDeviceAffinities = 9826 new HashMap<>(); 9827 9828 final IMediaProjection mProjection; 9829 private final class UnregisterOnStopCallback extends IMediaProjectionCallback.Stub { onStop()9830 public void onStop() { 9831 unregisterAudioPolicyAsync(mPolicyCallback); 9832 } 9833 }; 9834 UnregisterOnStopCallback mProjectionCallback; 9835 9836 /** 9837 * Audio focus ducking behavior for an audio policy. 9838 * This variable reflects the value that was successfully set in 9839 * {@link AudioService#setFocusPropertiesForPolicy(int, IAudioPolicyCallback)}. This 9840 * implies that a value of FOCUS_POLICY_DUCKING_IN_POLICY means the corresponding policy 9841 * is handling ducking for audio focus. 9842 */ 9843 int mFocusDuckBehavior = AudioPolicy.FOCUS_POLICY_DUCKING_DEFAULT; 9844 boolean mIsFocusPolicy = false; 9845 boolean mIsTestFocusPolicy = false; 9846 AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)9847 AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, 9848 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, 9849 boolean isVolumeController, IMediaProjection projection) { 9850 super(config); 9851 setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++)); 9852 mPolicyCallback = token; 9853 mHasFocusListener = hasFocusListener; 9854 mIsVolumeController = isVolumeController; 9855 mProjection = projection; 9856 if (mHasFocusListener) { 9857 mMediaFocusControl.addFocusFollower(mPolicyCallback); 9858 // can only ever be true if there is a focus listener 9859 if (isFocusPolicy) { 9860 mIsFocusPolicy = true; 9861 mIsTestFocusPolicy = isTestFocusPolicy; 9862 mMediaFocusControl.setFocusPolicy(mPolicyCallback, mIsTestFocusPolicy); 9863 } 9864 } 9865 if (mIsVolumeController) { 9866 setExtVolumeController(mPolicyCallback); 9867 } 9868 if (mProjection != null) { 9869 mProjectionCallback = new UnregisterOnStopCallback(); 9870 try { 9871 mProjection.registerCallback(mProjectionCallback); 9872 } catch (RemoteException e) { 9873 release(); 9874 throw new IllegalStateException("MediaProjection callback registration failed, " 9875 + "could not link to " + projection + " binder death", e); 9876 } 9877 } 9878 int status = connectMixes(); 9879 if (status != AudioSystem.SUCCESS) { 9880 release(); 9881 throw new IllegalStateException("Could not connect mix, error: " + status); 9882 } 9883 } 9884 binderDied()9885 public void binderDied() { 9886 mDynPolicyLogger.log((new AudioEventLogger.StringEvent("AudioPolicy " 9887 + mPolicyCallback.asBinder() + " died").printLog(TAG))); 9888 release(); 9889 } 9890 getRegistrationId()9891 String getRegistrationId() { 9892 return getRegistration(); 9893 } 9894 release()9895 void release() { 9896 if (mIsFocusPolicy) { 9897 mMediaFocusControl.unsetFocusPolicy(mPolicyCallback, mIsTestFocusPolicy); 9898 } 9899 if (mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 9900 mMediaFocusControl.setDuckingInExtPolicyAvailable(false); 9901 } 9902 if (mHasFocusListener) { 9903 mMediaFocusControl.removeFocusFollower(mPolicyCallback); 9904 } 9905 if (mProjectionCallback != null) { 9906 try { 9907 mProjection.unregisterCallback(mProjectionCallback); 9908 } catch (RemoteException e) { 9909 Log.e(TAG, "Fail to unregister Audiopolicy callback from MediaProjection"); 9910 } 9911 } 9912 if (mIsVolumeController) { 9913 synchronized (mExtVolumeControllerLock) { 9914 mExtVolumeController = null; 9915 } 9916 } 9917 final long identity = Binder.clearCallingIdentity(); 9918 mAudioSystem.registerPolicyMixes(mMixes, false); 9919 Binder.restoreCallingIdentity(identity); 9920 synchronized (mAudioPolicies) { 9921 mAudioPolicies.remove(mPolicyCallback.asBinder()); 9922 } 9923 try { 9924 mPolicyCallback.notifyUnregistration(); 9925 } catch (RemoteException e) { } 9926 } 9927 hasMixAffectingUsage(int usage, int excludedFlags)9928 boolean hasMixAffectingUsage(int usage, int excludedFlags) { 9929 for (AudioMix mix : mMixes) { 9930 if (mix.isAffectingUsage(usage) 9931 && ((mix.getRouteFlags() & excludedFlags) != excludedFlags)) { 9932 return true; 9933 } 9934 } 9935 return false; 9936 } 9937 9938 // Verify all the devices in the array are served by mixes defined in this policy hasMixRoutedToDevices(@onNull int[] deviceTypes, @NonNull String[] deviceAddresses)9939 boolean hasMixRoutedToDevices(@NonNull int[] deviceTypes, 9940 @NonNull String[] deviceAddresses) { 9941 for (int i = 0; i < deviceTypes.length; i++) { 9942 boolean hasDevice = false; 9943 for (AudioMix mix : mMixes) { 9944 // this will check both that the mix has ROUTE_FLAG_RENDER and the device 9945 // is reached by this mix 9946 if (mix.isRoutedToDevice(deviceTypes[i], deviceAddresses[i])) { 9947 hasDevice = true; 9948 break; 9949 } 9950 } 9951 if (!hasDevice) { 9952 return false; 9953 } 9954 } 9955 return true; 9956 } 9957 addMixes(@onNull ArrayList<AudioMix> mixes)9958 int addMixes(@NonNull ArrayList<AudioMix> mixes) { 9959 // TODO optimize to not have to unregister the mixes already in place 9960 synchronized (mMixes) { 9961 mAudioSystem.registerPolicyMixes(mMixes, false); 9962 this.add(mixes); 9963 return mAudioSystem.registerPolicyMixes(mMixes, true); 9964 } 9965 } 9966 removeMixes(@onNull ArrayList<AudioMix> mixes)9967 int removeMixes(@NonNull ArrayList<AudioMix> mixes) { 9968 // TODO optimize to not have to unregister the mixes already in place 9969 synchronized (mMixes) { 9970 mAudioSystem.registerPolicyMixes(mMixes, false); 9971 this.remove(mixes); 9972 return mAudioSystem.registerPolicyMixes(mMixes, true); 9973 } 9974 } 9975 connectMixes()9976 @AudioSystem.AudioSystemError int connectMixes() { 9977 final long identity = Binder.clearCallingIdentity(); 9978 int status = mAudioSystem.registerPolicyMixes(mMixes, true); 9979 Binder.restoreCallingIdentity(identity); 9980 return status; 9981 } 9982 setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses)9983 int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) { 9984 final Integer Uid = new Integer(uid); 9985 if (mUidDeviceAffinities.remove(Uid) != null) { 9986 if (removeUidDeviceAffinitiesFromSystem(uid) != AudioSystem.SUCCESS) { 9987 Log.e(TAG, "AudioSystem. removeUidDeviceAffinities(" + uid + ") failed, " 9988 + " cannot call AudioSystem.setUidDeviceAffinities"); 9989 return AudioManager.ERROR; 9990 } 9991 } 9992 AudioDeviceArray deviceArray = new AudioDeviceArray(types, addresses); 9993 if (setUidDeviceAffinitiesOnSystem(uid, deviceArray) == AudioSystem.SUCCESS) { 9994 mUidDeviceAffinities.put(Uid, deviceArray); 9995 return AudioManager.SUCCESS; 9996 } 9997 Log.e(TAG, "AudioSystem. setUidDeviceAffinities(" + uid + ") failed"); 9998 return AudioManager.ERROR; 9999 } 10000 removeUidDeviceAffinities(int uid)10001 int removeUidDeviceAffinities(int uid) { 10002 if (mUidDeviceAffinities.remove(new Integer(uid)) != null) { 10003 if (removeUidDeviceAffinitiesFromSystem(uid) == AudioSystem.SUCCESS) { 10004 return AudioManager.SUCCESS; 10005 } 10006 } 10007 Log.e(TAG, "AudioSystem. removeUidDeviceAffinities failed"); 10008 return AudioManager.ERROR; 10009 } 10010 removeUidDeviceAffinitiesFromSystem(int uid)10011 @AudioSystem.AudioSystemError private int removeUidDeviceAffinitiesFromSystem(int uid) { 10012 final long identity = Binder.clearCallingIdentity(); 10013 try { 10014 return mAudioSystem.removeUidDeviceAffinities(uid); 10015 } finally { 10016 Binder.restoreCallingIdentity(identity); 10017 } 10018 } 10019 setUidDeviceAffinitiesOnSystem(int uid, AudioDeviceArray deviceArray)10020 @AudioSystem.AudioSystemError private int setUidDeviceAffinitiesOnSystem(int uid, 10021 AudioDeviceArray deviceArray) { 10022 final long identity = Binder.clearCallingIdentity(); 10023 try { 10024 return mAudioSystem.setUidDeviceAffinities(uid, deviceArray.mDeviceTypes, 10025 deviceArray.mDeviceAddresses); 10026 } finally { 10027 Binder.restoreCallingIdentity(identity); 10028 } 10029 } 10030 setUserIdDeviceAffinities(int userId, @NonNull int[] types, @NonNull String[] addresses)10031 int setUserIdDeviceAffinities(int userId, 10032 @NonNull int[] types, @NonNull String[] addresses) { 10033 final Integer UserId = new Integer(userId); 10034 if (mUserIdDeviceAffinities.remove(UserId) != null) { 10035 if (removeUserIdDeviceAffinitiesFromSystem(userId) != AudioSystem.SUCCESS) { 10036 Log.e(TAG, "AudioSystem. removeUserIdDeviceAffinities(" 10037 + UserId + ") failed, " 10038 + " cannot call AudioSystem.setUserIdDeviceAffinities"); 10039 return AudioManager.ERROR; 10040 } 10041 } 10042 AudioDeviceArray audioDeviceArray = new AudioDeviceArray(types, addresses); 10043 if (setUserIdDeviceAffinitiesOnSystem(userId, audioDeviceArray) 10044 == AudioSystem.SUCCESS) { 10045 mUserIdDeviceAffinities.put(UserId, audioDeviceArray); 10046 return AudioManager.SUCCESS; 10047 } 10048 Log.e(TAG, "AudioSystem.setUserIdDeviceAffinities(" + userId + ") failed"); 10049 return AudioManager.ERROR; 10050 } 10051 removeUserIdDeviceAffinities(int userId)10052 int removeUserIdDeviceAffinities(int userId) { 10053 if (mUserIdDeviceAffinities.remove(new Integer(userId)) != null) { 10054 if (removeUserIdDeviceAffinitiesFromSystem(userId) == AudioSystem.SUCCESS) { 10055 return AudioManager.SUCCESS; 10056 } 10057 } 10058 Log.e(TAG, "AudioSystem.removeUserIdDeviceAffinities failed"); 10059 return AudioManager.ERROR; 10060 } 10061 removeUserIdDeviceAffinitiesFromSystem( @serIdInt int userId)10062 @AudioSystem.AudioSystemError private int removeUserIdDeviceAffinitiesFromSystem( 10063 @UserIdInt int userId) { 10064 final long identity = Binder.clearCallingIdentity(); 10065 try { 10066 return mAudioSystem.removeUserIdDeviceAffinities(userId); 10067 } finally { 10068 Binder.restoreCallingIdentity(identity); 10069 } 10070 } 10071 setUserIdDeviceAffinitiesOnSystem( @serIdInt int userId, AudioDeviceArray deviceArray)10072 @AudioSystem.AudioSystemError private int setUserIdDeviceAffinitiesOnSystem( 10073 @UserIdInt int userId, AudioDeviceArray deviceArray) { 10074 final long identity = Binder.clearCallingIdentity(); 10075 try { 10076 return mAudioSystem.setUserIdDeviceAffinities(userId, deviceArray.mDeviceTypes, 10077 deviceArray.mDeviceAddresses); 10078 } finally { 10079 Binder.restoreCallingIdentity(identity); 10080 } 10081 } 10082 setupDeviceAffinities()10083 @AudioSystem.AudioSystemError int setupDeviceAffinities() { 10084 for (Map.Entry<Integer, AudioDeviceArray> uidEntry : mUidDeviceAffinities.entrySet()) { 10085 int uidStatus = removeUidDeviceAffinitiesFromSystem(uidEntry.getKey()); 10086 if (uidStatus != AudioSystem.SUCCESS) { 10087 Log.e(TAG, 10088 "setupDeviceAffinities failed to remove device affinity for uid " 10089 + uidEntry.getKey()); 10090 return uidStatus; 10091 } 10092 uidStatus = setUidDeviceAffinitiesOnSystem(uidEntry.getKey(), uidEntry.getValue()); 10093 if (uidStatus != AudioSystem.SUCCESS) { 10094 Log.e(TAG, 10095 "setupDeviceAffinities failed to set device affinity for uid " 10096 + uidEntry.getKey()); 10097 return uidStatus; 10098 } 10099 } 10100 10101 for (Map.Entry<Integer, AudioDeviceArray> userIdEntry : 10102 mUserIdDeviceAffinities.entrySet()) { 10103 int userIdStatus = removeUserIdDeviceAffinitiesFromSystem(userIdEntry.getKey()); 10104 if (userIdStatus != AudioSystem.SUCCESS) { 10105 Log.e(TAG, 10106 "setupDeviceAffinities failed to remove device affinity for userId " 10107 + userIdEntry.getKey()); 10108 return userIdStatus; 10109 } 10110 userIdStatus = setUserIdDeviceAffinitiesOnSystem(userIdEntry.getKey(), 10111 userIdEntry.getValue()); 10112 if (userIdStatus != AudioSystem.SUCCESS) { 10113 Log.e(TAG, 10114 "setupDeviceAffinities failed to set device affinity for userId " 10115 + userIdEntry.getKey()); 10116 return userIdStatus; 10117 } 10118 } 10119 return AudioSystem.SUCCESS; 10120 } 10121 10122 /** @return human readable debug informations summarizing the state of the object. */ toLogFriendlyString()10123 public String toLogFriendlyString() { 10124 String textDump = super.toLogFriendlyString(); 10125 textDump += " Uid Device Affinities:\n"; 10126 String spacer = " "; 10127 textDump += logFriendlyAttributeDeviceArrayMap("Uid", 10128 mUidDeviceAffinities, spacer); 10129 textDump += " UserId Device Affinities:\n"; 10130 textDump += logFriendlyAttributeDeviceArrayMap("UserId", 10131 mUserIdDeviceAffinities, spacer); 10132 textDump += " Proxy:\n"; 10133 textDump += " is focus policy= " + mIsFocusPolicy + "\n"; 10134 if (mIsFocusPolicy) { 10135 textDump += " focus duck behaviour= " + mFocusDuckBehavior + "\n"; 10136 textDump += " is test focus policy= " + mIsTestFocusPolicy + "\n"; 10137 textDump += " has focus listener= " + mHasFocusListener + "\n"; 10138 } 10139 textDump += " media projection= " + mProjection + "\n"; 10140 return textDump; 10141 } 10142 logFriendlyAttributeDeviceArrayMap(String attribute, Map<Integer, AudioDeviceArray> map, String spacer)10143 private String logFriendlyAttributeDeviceArrayMap(String attribute, 10144 Map<Integer, AudioDeviceArray> map, String spacer) { 10145 final StringBuilder stringBuilder = new StringBuilder(); 10146 for (Map.Entry<Integer, AudioDeviceArray> mapEntry : map.entrySet()) { 10147 stringBuilder.append(spacer).append(attribute).append(": ") 10148 .append(mapEntry.getKey()).append("\n"); 10149 AudioDeviceArray deviceArray = mapEntry.getValue(); 10150 String deviceSpacer = spacer + " "; 10151 for (int i = 0; i < deviceArray.mDeviceTypes.length; i++) { 10152 stringBuilder.append(deviceSpacer).append("Type: 0x") 10153 .append(Integer.toHexString(deviceArray.mDeviceTypes[i])) 10154 .append(" Address: ").append(deviceArray.mDeviceAddresses[i]) 10155 .append("\n"); 10156 } 10157 } 10158 return stringBuilder.toString(); 10159 } 10160 }; 10161 10162 //====================== 10163 // Audio policy: focus 10164 //====================== 10165 /** */ dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb)10166 public int dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb) { 10167 if (afi == null) { 10168 throw new IllegalArgumentException("Illegal null AudioFocusInfo"); 10169 } 10170 if (pcb == null) { 10171 throw new IllegalArgumentException("Illegal null AudioPolicy callback"); 10172 } 10173 synchronized (mAudioPolicies) { 10174 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 10175 throw new IllegalStateException("Unregistered AudioPolicy for focus dispatch"); 10176 } 10177 return mMediaFocusControl.dispatchFocusChange(afi, focusChange); 10178 } 10179 } 10180 setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, IAudioPolicyCallback pcb)10181 public void setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, 10182 IAudioPolicyCallback pcb) { 10183 if (afi == null) { 10184 throw new IllegalArgumentException("Illegal null AudioFocusInfo"); 10185 } 10186 if (pcb == null) { 10187 throw new IllegalArgumentException("Illegal null AudioPolicy callback"); 10188 } 10189 synchronized (mAudioPolicies) { 10190 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 10191 throw new IllegalStateException("Unregistered AudioPolicy for external focus"); 10192 } 10193 mMediaFocusControl.setFocusRequestResultFromExtPolicy(afi, requestResult); 10194 } 10195 } 10196 10197 10198 //====================== 10199 // Audioserver state dispatch 10200 //====================== 10201 private class AsdProxy implements IBinder.DeathRecipient { 10202 private final IAudioServerStateDispatcher mAsd; 10203 AsdProxy(IAudioServerStateDispatcher asd)10204 AsdProxy(IAudioServerStateDispatcher asd) { 10205 mAsd = asd; 10206 } 10207 binderDied()10208 public void binderDied() { 10209 synchronized (mAudioServerStateListeners) { 10210 mAudioServerStateListeners.remove(mAsd.asBinder()); 10211 } 10212 } 10213 callback()10214 IAudioServerStateDispatcher callback() { 10215 return mAsd; 10216 } 10217 } 10218 10219 private final HashMap<IBinder, AsdProxy> mAudioServerStateListeners = 10220 new HashMap<IBinder, AsdProxy>(); 10221 checkMonitorAudioServerStatePermission()10222 private void checkMonitorAudioServerStatePermission() { 10223 if (!(mContext.checkCallingOrSelfPermission( 10224 android.Manifest.permission.MODIFY_PHONE_STATE) == 10225 PackageManager.PERMISSION_GRANTED || 10226 mContext.checkCallingOrSelfPermission( 10227 android.Manifest.permission.MODIFY_AUDIO_ROUTING) == 10228 PackageManager.PERMISSION_GRANTED)) { 10229 throw new SecurityException("Not allowed to monitor audioserver state"); 10230 } 10231 } 10232 registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd)10233 public void registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd) { 10234 checkMonitorAudioServerStatePermission(); 10235 synchronized (mAudioServerStateListeners) { 10236 if (mAudioServerStateListeners.containsKey(asd.asBinder())) { 10237 Slog.w(TAG, "Cannot re-register audio server state dispatcher"); 10238 return; 10239 } 10240 AsdProxy asdp = new AsdProxy(asd); 10241 try { 10242 asd.asBinder().linkToDeath(asdp, 0/*flags*/); 10243 } catch (RemoteException e) { 10244 10245 } 10246 mAudioServerStateListeners.put(asd.asBinder(), asdp); 10247 } 10248 } 10249 unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd)10250 public void unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd) { 10251 checkMonitorAudioServerStatePermission(); 10252 synchronized (mAudioServerStateListeners) { 10253 AsdProxy asdp = mAudioServerStateListeners.remove(asd.asBinder()); 10254 if (asdp == null) { 10255 Slog.w(TAG, "Trying to unregister unknown audioserver state dispatcher for pid " 10256 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()); 10257 return; 10258 } else { 10259 asd.asBinder().unlinkToDeath(asdp, 0/*flags*/); 10260 } 10261 } 10262 } 10263 isAudioServerRunning()10264 public boolean isAudioServerRunning() { 10265 checkMonitorAudioServerStatePermission(); 10266 return (AudioSystem.checkAudioFlinger() == AudioSystem.AUDIO_STATUS_OK); 10267 } 10268 10269 //====================== 10270 // Audio HAL process dump 10271 //====================== 10272 10273 private static final String AUDIO_HAL_SERVICE_PREFIX = "android.hardware.audio"; 10274 getAudioHalPids()10275 private Set<Integer> getAudioHalPids() { 10276 try { 10277 IServiceManager serviceManager = IServiceManager.getService(); 10278 ArrayList<IServiceManager.InstanceDebugInfo> dump = 10279 serviceManager.debugDump(); 10280 HashSet<Integer> pids = new HashSet<>(); 10281 for (IServiceManager.InstanceDebugInfo info : dump) { 10282 if (info.pid != IServiceManager.PidConstant.NO_PID 10283 && info.interfaceName != null 10284 && info.interfaceName.startsWith(AUDIO_HAL_SERVICE_PREFIX)) { 10285 pids.add(info.pid); 10286 } 10287 } 10288 return pids; 10289 } catch (RemoteException e) { 10290 return new HashSet<Integer>(); 10291 } 10292 } 10293 updateAudioHalPids()10294 private void updateAudioHalPids() { 10295 Set<Integer> pidsSet = getAudioHalPids(); 10296 if (pidsSet.isEmpty()) { 10297 Slog.w(TAG, "Could not retrieve audio HAL service pids"); 10298 return; 10299 } 10300 int[] pidsArray = pidsSet.stream().mapToInt(Integer::intValue).toArray(); 10301 AudioSystem.setAudioHalPids(pidsArray); 10302 } 10303 10304 //====================== 10305 // Multi Audio Focus 10306 //====================== setMultiAudioFocusEnabled(boolean enabled)10307 public void setMultiAudioFocusEnabled(boolean enabled) { 10308 enforceModifyAudioRoutingPermission(); 10309 if (mMediaFocusControl != null) { 10310 boolean mafEnabled = mMediaFocusControl.getMultiAudioFocusEnabled(); 10311 if (mafEnabled != enabled) { 10312 mMediaFocusControl.updateMultiAudioFocus(enabled); 10313 if (!enabled) { 10314 mDeviceBroker.postBroadcastBecomingNoisy(); 10315 } 10316 } 10317 } 10318 } 10319 10320 /** 10321 * @hide 10322 * Sets an additional audio output device delay in milliseconds. 10323 * 10324 * The additional output delay is a request to the output device to 10325 * delay audio presentation (generally with respect to video presentation for better 10326 * synchronization). 10327 * It may not be supported by all output devices, 10328 * and typically increases the audio latency by the amount of additional 10329 * audio delay requested. 10330 * 10331 * If additional audio delay is supported by an audio output device, 10332 * it is expected to be supported for all output streams (and configurations) 10333 * opened on that device. 10334 * 10335 * @param deviceType 10336 * @param address 10337 * @param delayMillis delay in milliseconds desired. This should be in range of {@code 0} 10338 * to the value returned by {@link #getMaxAdditionalOutputDeviceDelay()}. 10339 * @return true if successful, false if the device does not support output device delay 10340 * or the delay is not in range of {@link #getMaxAdditionalOutputDeviceDelay()}. 10341 */ 10342 @Override 10343 //@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) setAdditionalOutputDeviceDelay( @onNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis)10344 public boolean setAdditionalOutputDeviceDelay( 10345 @NonNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis) { 10346 Objects.requireNonNull(device, "device must not be null"); 10347 enforceModifyAudioRoutingPermission(); 10348 final String getterKey = "additional_output_device_delay=" 10349 + device.getInternalType() + "," + device.getAddress(); // "getter" key as an id. 10350 final String setterKey = getterKey + "," + delayMillis; // append the delay for setter 10351 return mRestorableParameters.setParameters(getterKey, setterKey) 10352 == AudioSystem.AUDIO_STATUS_OK; 10353 } 10354 10355 /** 10356 * @hide 10357 * Returns the current additional audio output device delay in milliseconds. 10358 * 10359 * @param deviceType 10360 * @param address 10361 * @return the additional output device delay. This is a non-negative number. 10362 * {@code 0} is returned if unsupported. 10363 */ 10364 @Override 10365 @IntRange(from = 0) getAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)10366 public long getAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) { 10367 Objects.requireNonNull(device, "device must not be null"); 10368 final String key = "additional_output_device_delay"; 10369 final String reply = AudioSystem.getParameters( 10370 key + "=" + device.getInternalType() + "," + device.getAddress()); 10371 long delayMillis; 10372 try { 10373 delayMillis = Long.parseLong(reply.substring(key.length() + 1)); 10374 } catch (NullPointerException e) { 10375 delayMillis = 0; 10376 } 10377 return delayMillis; 10378 } 10379 10380 /** 10381 * @hide 10382 * Returns the maximum additional audio output device delay in milliseconds. 10383 * 10384 * @param deviceType 10385 * @param address 10386 * @return the maximum output device delay in milliseconds that can be set. 10387 * This is a non-negative number 10388 * representing the additional audio delay supported for the device. 10389 * {@code 0} is returned if unsupported. 10390 */ 10391 @Override 10392 @IntRange(from = 0) getMaxAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)10393 public long getMaxAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) { 10394 Objects.requireNonNull(device, "device must not be null"); 10395 final String key = "max_additional_output_device_delay"; 10396 final String reply = AudioSystem.getParameters( 10397 key + "=" + device.getInternalType() + "," + device.getAddress()); 10398 long delayMillis; 10399 try { 10400 delayMillis = Long.parseLong(reply.substring(key.length() + 1)); 10401 } catch (NullPointerException e) { 10402 delayMillis = 0; 10403 } 10404 return delayMillis; 10405 } 10406 10407 //====================== 10408 // misc 10409 //====================== 10410 private final HashMap<IBinder, AudioPolicyProxy> mAudioPolicies = 10411 new HashMap<IBinder, AudioPolicyProxy>(); 10412 @GuardedBy("mAudioPolicies") 10413 private int mAudioPolicyCounter = 0; 10414 10415 //====================== 10416 // Helper functions for full and fixed volume device 10417 //====================== isFixedVolumeDevice(int deviceType)10418 private boolean isFixedVolumeDevice(int deviceType) { 10419 if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX 10420 && mRecordMonitor.isLegacyRemoteSubmixActive()) { 10421 return false; 10422 } 10423 return mFixedVolumeDevices.contains(deviceType); 10424 } 10425 isFullVolumeDevice(int deviceType)10426 private boolean isFullVolumeDevice(int deviceType) { 10427 if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX 10428 && mRecordMonitor.isLegacyRemoteSubmixActive()) { 10429 return false; 10430 } 10431 return mFullVolumeDevices.contains(deviceType); 10432 } 10433 10434 //==================== 10435 // Helper functions for {set,get}DeviceVolumeBehavior 10436 //==================== getSettingsNameForDeviceVolumeBehavior(int deviceType)10437 private static String getSettingsNameForDeviceVolumeBehavior(int deviceType) { 10438 return "AudioService_DeviceVolumeBehavior_" + AudioSystem.getOutputDeviceName(deviceType); 10439 } 10440 persistDeviceVolumeBehavior(int deviceType, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior)10441 private void persistDeviceVolumeBehavior(int deviceType, 10442 @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) { 10443 if (DEBUG_VOL) { 10444 Log.d(TAG, "Persisting Volume Behavior for DeviceType: " + deviceType); 10445 } 10446 final long callingIdentity = Binder.clearCallingIdentity(); 10447 try { 10448 System.putIntForUser(mContentResolver, 10449 getSettingsNameForDeviceVolumeBehavior(deviceType), 10450 deviceVolumeBehavior, 10451 UserHandle.USER_CURRENT); 10452 } finally { 10453 Binder.restoreCallingIdentity(callingIdentity); 10454 } 10455 } 10456 10457 @AudioManager.DeviceVolumeBehaviorState retrieveStoredDeviceVolumeBehavior(int deviceType)10458 private int retrieveStoredDeviceVolumeBehavior(int deviceType) { 10459 return System.getIntForUser(mContentResolver, 10460 getSettingsNameForDeviceVolumeBehavior(deviceType), 10461 AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET, 10462 UserHandle.USER_CURRENT); 10463 } 10464 restoreDeviceVolumeBehavior()10465 private void restoreDeviceVolumeBehavior() { 10466 for (int deviceType : AudioSystem.DEVICE_OUT_ALL_SET) { 10467 if (DEBUG_VOL) { 10468 Log.d(TAG, "Retrieving Volume Behavior for DeviceType: " + deviceType); 10469 } 10470 int deviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(deviceType); 10471 if (deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) { 10472 if (DEBUG_VOL) { 10473 Log.d(TAG, "Skipping Setting Volume Behavior for DeviceType: " + deviceType); 10474 } 10475 continue; 10476 } 10477 10478 setDeviceVolumeBehaviorInternal(deviceType, deviceVolumeBehavior, 10479 "AudioService.restoreDeviceVolumeBehavior()"); 10480 } 10481 } 10482 10483 /** 10484 * @param audioSystemDeviceOut one of AudioSystem.DEVICE_OUT_* 10485 * @return whether {@code audioSystemDeviceOut} has previously been set to a specific volume 10486 * behavior 10487 */ hasDeviceVolumeBehavior( int audioSystemDeviceOut)10488 private boolean hasDeviceVolumeBehavior( 10489 int audioSystemDeviceOut) { 10490 return retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut) 10491 != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET; 10492 } 10493 addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut)10494 private void addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut) { 10495 if (DEBUG_VOL) { 10496 Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 10497 + " to mFixedVolumeDevices"); 10498 } 10499 mFixedVolumeDevices.add(audioSystemDeviceOut); 10500 } 10501 removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut)10502 private void removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut) { 10503 if (DEBUG_VOL) { 10504 Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 10505 + " from mFixedVolumeDevices"); 10506 } 10507 mFixedVolumeDevices.remove(audioSystemDeviceOut); 10508 } 10509 addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut)10510 private void addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut) { 10511 if (DEBUG_VOL) { 10512 Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 10513 + " to mFullVolumeDevices"); 10514 } 10515 mFullVolumeDevices.add(audioSystemDeviceOut); 10516 } 10517 removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut)10518 private void removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut) { 10519 if (DEBUG_VOL) { 10520 Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 10521 + " from mFullVolumeDevices"); 10522 } 10523 mFullVolumeDevices.remove(audioSystemDeviceOut); 10524 } 10525 } 10526