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